From b777c1626f6583d5687a9fb6c5c776df8c524bcf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 28 Sep 2003 23:14:56 +0000 Subject: Add draft about new registry subsystem (This used to be commit 6d310e98e0d8654a95de98fcd4aa55e3c681157d) --- docs/docbook/devdoc/dev-doc.xml | 2 + docs/docbook/devdoc/registry.xml | 209 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 docs/docbook/devdoc/registry.xml diff --git a/docs/docbook/devdoc/dev-doc.xml b/docs/docbook/devdoc/dev-doc.xml index 7000d09c98..e112a0f9e1 100644 --- a/docs/docbook/devdoc/dev-doc.xml +++ b/docs/docbook/devdoc/dev-doc.xml @@ -20,6 +20,7 @@ + ]> @@ -82,6 +83,7 @@ url="http://www.fsf.org/licenses/gpl.txt">http://www.fsf.org/licenses/gpl.txt diff --git a/docs/docbook/devdoc/registry.xml b/docs/docbook/devdoc/registry.xml new file mode 100644 index 0000000000..b331ebce7f --- /dev/null +++ b/docs/docbook/devdoc/registry.xml @@ -0,0 +1,209 @@ + + + &author.jelmer; + 24 September 2003 + + + The registry subsystem + + Planned backends + + + The new registry subsystem will work with several different backends: + + + + NT4 (NT4 registry files) + TDB (Samba TDB files) + RPC (Remote Registry over RPC, reg pipe) + wine (Wine Registry Files) + gconf (The GNOME configuration backend) + + + + +Data structures + + +The following structure describes a registry key: + + + +typedef struct reg_key_s { + char *name; /* Name of the key */ + smb_ucs2_t *class_name; /* Name of key class */ + int type; /* One of REG_ROOT_KEY or REG_SUB_KEY */ + NTTIME last_mod; /* Time last modified */ + struct reg_key_s *owner; + struct key_list_s *sub_keys; /* NULL indicates keys not available in memory, function should be called */ + struct val_list_s *values; /* NULL indicates values not available in memory, function should be called */ + SEC_DESC *security; + REG_HANDLE *handle; /* Pointer to REG_HANDLE this key belongs to */ + void *backend_data; /* Pointer used by the backend */ +} REG_KEY; + + +The following structure describes a registry value: + + +typedef struct val_key_s { + char *name; /* NULL if name not available */ + int data_type; + int data_len; + void *data_blk; /* Might want a separate block */ + REG_HANDLE *handle; /* Pointer to REG_HANDLE this key belongs to */ + void *backend_data; +} REG_VAL; + + +The following structures are used for lists of subkeys or values: + + +/* container for registry subkey names */ +typedef struct key_list_s { + TALLOC_CTX *ctx; + uint32 num_subkeys; + REG_KEY **subkeys; +} REG_KEY_LIST; + +/* container for registry values */ +typedef struct val_list_s { + TALLOC_CTX *ctx; + uint32 num_vals; + REG_VAL **vals; +} REG_VAL_LIST; + + + +And this structure is used for an instance of a registry (a registry file that's opened, a remote registry pipe we're connected to, etc). + + + +typedef struct reg_handle_s { + REGISTRY_OPS *functions; + REG_KEY *root; /* NULL if not available */ + void *backend_data; +} REG_HANDLE; + + + + + + External interface + + +REG_HANDLE *reg_open(char *backend, char *location, BOOL try_full_load); +REG_KEY *reg_open_key(REG_KEY *parent, char *name); +REG_VAL *reg_key_get_val(REG_KEY *key, char *name); +REG_VAL_LIST *reg_key_get_vals(REG_KEY *key); +REG_KEY_LIST *reg_key_get_subkeys(REG_KEY *key); +BOOL reg_key_del(REG_KEY *key); +BOOL reg_val_del(REG_VAL *val); +BOOL reg_key_add(REG_KEY *parent, REG_KEY *key); +BOOL reg_val_add(REG_KEY *parent, REG_VAL *val): +BOOL reg_val_update(REG_VAL *val); +BOOL reg_key_update(REG_KEY *key); +void reg_free_key(REG_KEY *key); +void reg_free_val(REG_VAL *val); +void reg_free(REG_HANDLE *h); +void reg_free_key_list(REG_KEY_LIST *list): +void reg_free_val_list(REG_VAL_LIST *list): + + + + + + Utility functions + + The following helper functions are available: + + +void reg_key_list_init( REG_KEY_LIST *ctr ); +int reg_key_list_addkey( REG_KEY_LIST *ctr, const char *keyname ); +int reg_key_list_numkeys( REG_KEY_LIST *ctr ); +char* reg_key_list_specific_key( REG_KEY_LIST *ctr, uint32 key_index ); +void reg_key_list_destroy( REG_KEY_LIST *ctr ); +void reg_val_list_init( REG_VAL_LIST *ctr ); +int reg_val_list_numvals( REG_VAL_LIST *ctr ); +void free_registry_value( REG_VAL *val ); +uint8* regval_data_p( REG_VAL *val ); +int regval_size( REG_VAL *val ); +char* regval_name( REG_VAL *val ); +uint32 regval_type( REG_VAL *val ); +TALLOC_CTX* reg_val_list_getctx( REG_VAL_LIST *val ); +int reg_val_list_addvalue( REG_VAL_LIST *ctr, const char *name, uint16 type, + const char *data_p, size_t size ); +int reg_val_list_copyvalue( REG_VAL_LIST *ctr, REG_VAL *val ); +int reg_val_list_delvalue( REG_VAL_LIST *ctr, const char *name ); +void reg_val_list_destroy( REG_VAL_LIST *ctr ); + + + + + + Writing backends + +There are basically two ways of reading data from the registry: loading +it all into memory and then working in this copy in memory, or +re-reading/re-opening it every time necessary. + +This interface aims to support both types. + +A registry backend should provide the following functions: + + +typedef struct { + REG_HANDLE *(*open_registry) (const char *location, BOOL try_complete_load); + REG_KEY *(*open_root_key) (REG_HANDLE *); + REG_KEY *(*open_key_rel) (REG_KEY *parent, const char *name); + /* if open_key_abs is set to NULL, a default implementation will be provided. */ + REG_KEY *(*open_key_abs) (REG_HANDLE *, const char *name); + REG_KEY_LIST *(*get_subkeys) (REG_KEY *); + REG_VAL_LIST *(*get_values) (REG_KEY *); + BOOL (*add_key)(REG_KEY *, REG_KEY *); + BOOL (*update_key)(REG_KEY *); + BOOL (*del_key)(REG_KEY *); + BOOL (*add_value)(REG_KEY *, REG_VAL *); + BOOL (*update_value)(REG_VAL *); + BOOL (*del_value)(REG_VAL *); + REG_VAL *(*get_value) (REG_KEY *, const char *name); + /* It is not guaranteed that no data has been stored before save() + * has been called. This function is only useful for backends that + * store the data in memory and then write out the whole registry at once */ + BOOL (*save)(REG_HANDLE *, const char *location); + BOOL (*close_registry) (REG_HANDLE *); + void (*free_key)(REG_KEY *); + void (*free_value)(REG_VAL *); +} REGISTRY_OPS; + + +open_root_key() is optional. It's only called if the + root field of the REG_HANDLE struct is NULL. + +open_key_abs() is optional. If it's NULL, the frontend will + provide a replacement, using open_key_rel(). + +get_values() and get_value() are optional. They're only called if +the values field of the REG_KEY struct is NULL. + +get_subkeys() and get_key() are optional. THey're only called + if the subkeys field of the REG_KEY struct is NULL. + + + +Memory allocation + +Okay, so who's responsible for what parts of the memory? + +The memory is basically maintained by the backends. When the user +is finished using a particular structure, it should call the related free +function for the structure it's freeing. + +The backend should then decide what to do with the structure. It may +choose to free it, or, if it's maintaining single copies of everything in +memory, may choose to ignore the free and free it when the registry is closed. + + + + + -- cgit