summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2003-09-28 23:14:56 +0000
committerJelmer Vernooij <jelmer@samba.org>2003-09-28 23:14:56 +0000
commitb777c1626f6583d5687a9fb6c5c776df8c524bcf (patch)
tree93b4f6247f2112ed0c398972b31db59e4f01cf9c /docs
parent8efca15a8b45692f27ab783e4759646dee612eae (diff)
downloadsamba-b777c1626f6583d5687a9fb6c5c776df8c524bcf.tar.gz
samba-b777c1626f6583d5687a9fb6c5c776df8c524bcf.tar.bz2
samba-b777c1626f6583d5687a9fb6c5c776df8c524bcf.zip
Add draft about new registry subsystem
(This used to be commit 6d310e98e0d8654a95de98fcd4aa55e3c681157d)
Diffstat (limited to 'docs')
-rw-r--r--docs/docbook/devdoc/dev-doc.xml2
-rw-r--r--docs/docbook/devdoc/registry.xml209
2 files changed, 211 insertions, 0 deletions
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 @@
<!ENTITY contributing SYSTEM "contributing.xml">
<!ENTITY vfs SYSTEM "vfs.xml">
<!ENTITY windows-deb SYSTEM "windows-debug.xml">
+<!ENTITY registry SYSTEM "registry.xml">
]>
<book id="Samba-Developers-Guide">
@@ -82,6 +83,7 @@ url="http://www.fsf.org/licenses/gpl.txt">http://www.fsf.org/licenses/gpl.txt</u
&rpc-plugin;
&vfs;
&packagers;
+&registry;
&contributing;
</book>
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 @@
+<chapter id="registry">
+ <chapterinfo>
+ &author.jelmer;
+ <pubdate>24 September 2003</pubdate>
+ </chapterinfo>
+
+ <title>The registry subsystem</title>
+
+ <sect1><title>Planned backends</title>
+
+<para>
+ The new registry subsystem will work with several different backends:
+</para>
+
+<itemizedlist>
+ <listitem><para>NT4 (NT4 registry files)</para></listitem>
+ <listitem><para>TDB (Samba TDB files)</para></listitem>
+ <listitem><para>RPC (Remote Registry over RPC, reg pipe)</para></listitem>
+ <listitem><para>wine (Wine Registry Files)</para></listitem>
+ <listitem><para>gconf (The GNOME configuration backend)</para></listitem>
+</itemizedlist>
+
+</sect1>
+
+<sect1><title>Data structures</title>
+
+<para>
+The following structure describes a registry key:
+</para>
+
+<programlisting>
+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;
+</programlisting>
+
+<para>The following structure describes a registry value:</para>
+
+<programlisting>
+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;
+</programlisting>
+
+<para>The following structures are used for lists of subkeys or values:</para>
+
+<programlisting>
+/* 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;
+</programlisting>
+
+<para>
+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).
+</para>
+
+<programlisting>
+typedef struct reg_handle_s {
+ REGISTRY_OPS *functions;
+ REG_KEY *root; /* NULL if not available */
+ void *backend_data;
+} REG_HANDLE;
+</programlisting>
+
+</sect1>
+
+<sect1>
+ <title>External interface</title>
+
+<programlisting>
+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):
+</programlisting>
+
+</sect1>
+
+<sect1>
+ <title>Utility functions</title>
+
+ <para>The following helper functions are available:</para>
+
+ <programlisting>
+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 );
+</programlisting>
+
+</sect1>
+
+<sect1>
+ <title>Writing backends</title>
+
+<para>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.</para>
+
+<para>This interface aims to support both types. </para>
+
+<para>A registry backend should provide the following functions:</para>
+
+<programlisting>
+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;
+</programlisting>
+
+<para>open_root_key() is optional. It's only called if the
+ <parameter>root</parameter> field of the REG_HANDLE struct is NULL.</para>
+
+<para>open_key_abs() is optional. If it's NULL, the frontend will
+ provide a replacement, using open_key_rel().</para>
+
+<para>get_values() and get_value() are optional. They're only called if
+the <parameter>values</parameter> field of the REG_KEY struct is NULL.</para>
+
+<para>get_subkeys() and get_key() are optional. THey're only called
+ if the <parameter>subkeys</parameter> field of the REG_KEY struct is NULL.</para>
+
+</sect1>
+
+<sect1><title>Memory allocation</title>
+
+<para>Okay, so who's responsible for what parts of the memory? </para>
+
+<para>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.</para>
+
+<para>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.
+</para>
+
+</sect1>
+
+</chapter>