Index: /doc/Doxyfile.regfi
===================================================================
--- /doc/Doxyfile.regfi	(revision 168)
+++ /doc/Doxyfile.regfi	(revision 169)
@@ -626,5 +626,5 @@
 # AClass::ANamespace, ANamespace::*Test
 
-EXCLUDE_SYMBOLS        = talloc* REGFI_DATA::*
+EXCLUDE_SYMBOLS        = talloc*
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or
Index: /doc/references.txt
===================================================================
--- /doc/references.txt	(revision 168)
+++ /doc/references.txt	(revision 169)
@@ -10,4 +10,8 @@
   (The file 'winntreg.txt' included in this distribution is derived from this.)
   http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt
+
+- Nigel Williams.  Much of the same information as provided in 'winntreg.txt',
+  but with some code:
+  http://www.wednesday.demon.co.uk/dosreg.html
 
 - Some useful information on how Windows reads from and writes to registry
Index: /trunk/include/lru_cache.h
===================================================================
--- /trunk/include/lru_cache.h	(revision 168)
+++ /trunk/include/lru_cache.h	(revision 169)
@@ -1,6 +1,4 @@
-/**
- * @file
- *
- * Copyright (C) 2008-2009 Timothy D. Morgan
+/*
+ * Copyright (C) 2008-2010 Timothy D. Morgan
  *
  * This program is free software; you can redistribute it and/or modify
@@ -19,4 +17,12 @@
  * $Id$
  */
+
+/**
+ * @file
+ *
+ * A data structure which approximates a least recently used (LRU) cache.
+ * Implemented as a basic randomized hash table.
+ */
+
 
 #ifndef LRU_CACHE_H
@@ -44,4 +50,6 @@
 };
 
+
+/** XXX: document this. */
 typedef struct _lru_cache
 {
@@ -57,24 +65,45 @@
 
 
+/**
+ * XXX: finish documenting.
+ */
 lru_cache* lru_cache_create(uint32_t max_keys, uint32_t secret);
+
+
+/**
+ * XXX: finish documenting.
+ */
 lru_cache* lru_cache_create_ctx(void* talloc_ctx, uint32_t max_keys, 
 				uint32_t secret, bool talloc_data);
+
+
+/**
+ * XXX: finish documenting.
+ */
 void lru_cache_destroy(lru_cache* ht);
 
-/* 
- * 
+
+/**
+ * XXX: finish documenting.
  */
 bool lru_cache_update(lru_cache* ht, const void* index, 
 		      uint32_t index_len, void* data);
 
-/* Returns pointer to data previously stored at index.
- * If no data was found at index, NULL is returned.
+/**
+ * XXX: finish documenting.
+ *
+ * @return A pointer to data previously stored at index.
+ *         If no data was found at index, NULL is returned.
  */
 void* lru_cache_find(lru_cache* ht, const void* index, 
 		     uint32_t index_len);
 
-/* Removes entry from table at index.
- * Returns pointer to data that was there previously.  
- * Returns NULL if no entry is at index.
+/**
+ * XXX: finish documenting.
+ *
+ * Removes entry from table at index.
+ *
+ * @return A pointer to data that was there previously or NULL if no entry is
+ *         at index.
  */
 bool lru_cache_remove(lru_cache* ht, const void* index, 
Index: /trunk/include/range_list.h
===================================================================
--- /trunk/include/range_list.h	(revision 168)
+++ /trunk/include/range_list.h	(revision 169)
@@ -1,6 +1,4 @@
-/**
- * @file 
- *
- * Copyright (C) 2008-2009 Timothy D. Morgan
+/*
+ * Copyright (C) 2008-2010 Timothy D. Morgan
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,4 +16,14 @@
  *
  * $Id$
+ */
+
+/**
+ * @file 
+ *
+ * A data structure which stores a list of address ranges.
+ * 
+ * range_lists support basic in-place modifications and maintain the address
+ * space in sorted order.  Looking up a range_list_element is implemented 
+ * through binary search.
  */
 
@@ -38,4 +46,5 @@
 
 
+/** XXX: document this. */
 typedef struct _range_list
 {
@@ -46,107 +55,91 @@
 
 
-/* range_list_new(): 
- *  Allocates a new range_list.
+/** Allocates a new range_list.
  *
- * Returns: 
- *  A newly allocated range_list, or NULL if an error occurred.
+ * @return A newly allocated range_list, or NULL if an error occurred.
  */
 range_list* range_list_new();
 
 
-/* range_list_free(): 
- *  Frees the memory associated with a range_list, including the elements, but
- *  not any data parameters referenced by those elements.  If rl is NULL, does
- *  nothing.
+/** Frees the memory associated with a range_list, including the elements, but
+ *  not any data parameters referenced by those elements.  
  *
- * Arguments:
- *  rl -- the range_list to be free()d.
+ * If rl is NULL, does nothing.
+ *
+ * @param rl the range_list to be free()d.
  */
 void range_list_free(range_list* rl);
 
 
-/* range_list_size(): 
- *  Query the current number of elements on a range_list
+/** Query the current number of elements on a range_list
  *
- * Arguments:
- *  rl -- the range_list to query
+ * @param rl the range_list to query
  *
- * Returns:
- *  The number of elements currently in the list.
+ * @return The number of elements currently in the list.
  */
 uint32_t range_list_size(const range_list* rl);
 
 
-/* range_list_add():
- *  Adds an element to the range_list.  
- *  The new element must not overlap with others.
- *  NOTE: this is a slow operation.
+/** Adds an element to the range_list.  
  *
- * Arguments:
- *  rl     -- the range list to update
- *  offset -- the starting point for the range
- *  length -- the length of the range
- *  data   -- misc data associated with this range element
- * Returns:
- *  true on success, false on failure.
- *  Failures can occur due to memory limitations, max_size limitations,
- *  or if the submitted range overlaps with an existing element.  Other
- *  errors may also be possible.
+ * The new element must not overlap with others.
+ * NOTE: this is a slow operation.
+ *
+ * @param rl     the range list to update
+ * @param offset the starting point for the range
+ * @param length the length of the range
+ * @param data   misc data associated with this range element
+ *
+ * @return  true on success, false on failure.
+ *
+ * Failures can occur due to memory limitations, max_size limitations,
+ * or if the submitted range overlaps with an existing element.  Other
+ * errors may also be possible.
  */
 bool range_list_add(range_list* rl, uint32_t offset, uint32_t length, void* data);
 
 
-/* range_list_remove():
- *  Removes an element from the list.  The element data structure will be 
- *  freed, but the data property will not be.
+/** Removes an element from the list.  
  *
- * Arguments:
- *  rl     -- the range_list to modify
- *  index  -- the element index to remove
+ * The element data structure will be freed, but the data property will not be.
  *
- * Returns:
- *  true if the element was successfully removed, false otherwise.
+ * @param rl    the range_list to modify
+ * @param index the element index to remove
+ *
+ * @return true if the element was successfully removed, false otherwise.
  */
 bool range_list_remove(range_list* rl, uint32_t index);
 
 
-/* range_list_get():
- *  Retrieves the element for a given index.
+/** Retrieves the element for a given index.
  *
- * Arguments:
- *  rl    -- the range_list being queried.
- *  index -- the element index desired.
+ * @param rl    the range_list being queried.
+ * @param index the element index desired.
  * 
- * Returns:
- *  The element for a given index, or NULL if the element is not available.
+ * @return The element for a given index, or NULL if the element is not 
+ *         available.
  */
 const range_list_element* range_list_get(const range_list* rl, uint32_t index);
 
 
-/* range_list_find():
- *  Attempts to find the unique element whose range encompasses offset.
+/** Attempts to find the unique element whose range encompasses offset.
  *
- * Arguments:
- *  rl     -- the range_list being queried.
- *  offset -- the location for which an element is desired.
+ * @param rl     the range_list being queried.
+ * @param offset the location for which an element is desired.
  *
- * Returns:
- *  A matching element index or a negative value if none could be found.
+ * @return A matching element index or a negative value if none could be found.
  */
 int32_t range_list_find(const range_list* rl, uint32_t offset);
 
 
-/* range_list_find_data():
- *  Same as range_list_find(), but returns the data associated with an element.
+/** Same as range_list_find(), but returns the data associated with an element.
  *
- * Arguments:
- *  rl     -- the range_list being queried.
- *  offset -- the address to search for in the ranges
+ * @param rl     the range_list being queried.
+ * @param offset the address to search for in the ranges
  *
- * Returns:
- *  The data element of the matching element index or NULL if none could
- *  be found.
+ * @return The data element of the matching element index or NULL if none could
+ *         be found.
  *
- *  NOTE: May also return NULL if an element matched but if the data
+ *  NOTE: May also return NULL if an element matched but the data
  *        element was never set.
  */
@@ -154,41 +147,33 @@
 
 
-/* range_list_split_element():
- *  Splits an existing element into two elements in place.
+/**  Splits an existing element into two elements in place.
  *
- *  The resulting list will contain an additional element whose offset 
- *  is the one provided and whose length extends to the end of the old element
- *  (the one identified by the index).  The original element's offset will 
- *  remain the same while it's length is shortened such that it is contiguous
- *  with the newly created element.  The newly created element will have an index 
- *  of one more than the current element.
+ * The resulting list will contain an additional element whose offset 
+ * is the one provided and whose length extends to the end of the old element
+ * (the one identified by the index).  The original element's offset will 
+ * remain the same while it's length is shortened such that it is contiguous
+ * with the newly created element.  The newly created element will have an index 
+ * of one more than the current element.
  *
- *  Both the original element and the newly created element will reference the 
- *  original element's data.
+ * Both the original element and the newly created element will reference the 
+ * original element's data.
  *
- * Arguments:
- *  rl     -- the range_list to modify
- *  index  -- the index of the element to be split
- *  offset -- the at which the element will be split
+ * @param rl     the range_list to modify
+ * @param index  the index of the element to be split
+ * @param offset the at which the element will be split
  *
- * Returns:
- *  true if the element was successfully split, false otherwise.
- *   
- *
+ * @return true if the element was successfully split, false otherwise.
  */
 bool range_list_split_element(range_list* rl, uint32_t index, uint32_t offset);
 
 
-/* range_list_has_range():
- *  Determines whether or not a specified range exists contiguously within the
+/** Determines whether or not a specified range exists contiguously within the
  *  range_list.
  *
- * Arguments:
- *  rl     -- the range_list to search
- *  start  -- the offset at the beginning of the range
- *  length -- the length of the range
+ * @param rl     the range_list to search
+ * @param start  the offset at the beginning of the range
+ * @param length the length of the range
  *
- * Returns:
- *  true if the specified range exists and is complete, false otherwise.
+ * @return true if the specified range exists and is complete, false otherwise.
  */
 bool range_list_has_range(range_list* rl, uint32_t start, uint32_t length);
Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 168)
+++ /trunk/include/regfi.h	(revision 169)
@@ -1,8 +1,3 @@
-/** @file
- * Windows NT (and later) registry parsing library
- *
- * Branched from Samba project Subversion repository, version #6903:
- *   http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/include/regfio.h?rev=6903&view=auto
- *
+/*
  * Copyright (C) 2005-2010 Timothy D. Morgan
  * Copyright (C) 2005 Gerald (Jerry) Carter
@@ -24,15 +19,39 @@
  */
 
-/************************************************************
- * Most of this information was obtained from 
- * http://www.wednesday.demon.co.uk/dosreg.html
- * Thanks Nigel!
- ***********************************************************/
+/**
+ * @file
+ * Windows NT (and later) read-only registry library
+ *
+ * This library is intended for use in digital forensics investigations, but 
+ * is likely useful in other applications.
+ *
+ * Branched from Samba project Subversion repository, version #6903:
+ *   http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/include/regfio.h?rev=6903&view=auto
+ *
+ * Since then, it has been heavily rewritten, simplified, and improved.
+ */
 
 /**
  * @mainpage Home
  *
- * See \ref regfiTopLayer
- */
+ * The regfi library is a read-only NT registry library which serves as the main
+ * engine behind the reglookup tool.  It is designed with digital forensic 
+ * analysis in mind, but it should also be useful in other tools which need to 
+ * efficiently traverse and query registry data structures.
+ *
+ * The library is broken down into four main parts, the 
+ * @ref regfiBase "Base Layer", which any code dependent on the library will 
+ * likely need to rely on, as well as three main functional layers: 
+ * @li @ref regfiIteratorLayer
+ * @li @ref regfiGlueLayer
+ * @li @ref regfiParseLayer
+ *
+ * Most users will find that a combination of the Base Layer and the Iterator Layer 
+ * will be sufficient for accessing registry hive files.  Those who are wiling
+ * to dive deep into registry data structures, for instance to recover deleted
+ * data structures or to research Windows registry behavior in detail, will 
+ * find the Parse Layer to be quite useful.
+ */
+
 
 #ifndef _REGFI_H
@@ -42,5 +61,4 @@
 #include <stdio.h>
 #include <stdbool.h>
-#include <stdarg.h>
 #include <string.h>
 #include <errno.h>
@@ -50,5 +68,4 @@
 #include <sys/types.h>
 #include <unistd.h>
-#include <assert.h>
 #include <iconv.h>
 
@@ -230,21 +247,29 @@
 
 
-/* HBIN block */
+/** HBIN block information
+ * @ingroup regfiMiddleLayer
+ */
 typedef struct _regfi_hbin 
 {
-  uint32_t file_off;       /* my offset in the registry file */
-  uint32_t ref_count;      /* how many active records are pointing to this
-                          * block (not used currently) 
-			  */
-  
-  uint32_t first_hbin_off; /* offset from first hbin block */
-  uint32_t block_size;     /* block size of this block 
-                          * Should be a multiple of 4096 (0x1000)
-			  */
-  uint32_t next_block;     /* relative offset to next block.  
-			  * NOTE: This value may be unreliable!
-			  */
-
-  uint8_t magic[REGFI_HBIN_MAGIC_SIZE]; /* "hbin" */
+  /** Offset of this HBIN in the registry file */
+  uint32_t file_off;
+
+  /** Number of active records pointing to this block (not used currently) */
+  uint32_t ref_count;
+
+  /** Offset from first hbin block */
+  uint32_t first_hbin_off;
+
+  /** Block size of this block Should be a multiple of 4096 (0x1000) */
+  uint32_t block_size;
+
+  /** Relative offset to next block.  
+   * 
+   * @note This value may be unreliable!
+   */
+  uint32_t next_block;
+
+  /** Magic number for the HBIN (should be "hbin"). */
+  uint8_t magic[REGFI_HBIN_MAGIC_SIZE];
 } REGFI_HBIN;
 
@@ -262,4 +287,7 @@
 
 
+/** Subkey-list structure
+ * @ingroup regfiMiddleLayer
+ */
 typedef struct _regfi_subkey_list
 {
@@ -284,4 +312,7 @@
 
 typedef uint32_t REGFI_VALUE_LIST_ELEM;
+/** Value-list structure
+ * @ingroup regfiMiddleLayer
+ */
 typedef struct _regfi_value_list
 {
@@ -295,44 +326,100 @@
 
 
+/** Class name structure (used in storing SysKeys)
+ * @ingroup regfiBase
+ */
 typedef struct _regfi_classname
 {
-  /* As converted to requested character encoding. */
+  /** As converted to requested REGFI_ENCODING */
   char* interpreted;
 
-  /* Represents raw buffer read from classname cell. */
+  /** Represents raw buffer read from classname cell.
+   *
+   * Length of this item is specified in the size field.
+   */
   uint8_t* raw;
 
-  /* Length of the raw data. May be shorter than that indicated by parent key.*/
+  /** Length of the raw data.
+   *
+   * May be shorter than that indicated by parent key.
+   */
   uint16_t size;
 } REGFI_CLASSNAME;
 
 
+/** Data record structure
+ * @ingroup regfiBase
+ */
 typedef struct _regfi_data
 {
+  /** Data type of this data, as indicated by the referencing VK record. */
   uint32_t type;
 
-  /* Length of the raw data. */
+  /** Length of the raw data. */
   uint32_t size;
 
-  /* This is always present, representing the raw data cell contents. */
+  /** This is always present, representing the raw data cell contents. */
   uint8_t* raw;
 
-  /* Represents the length of the interpreted value. Meaning is type-specific.*/
+  /** Represents the length of the interpreted value. Meaning is type-specific. */
   uint32_t interpreted_size;
 
-  /* These items represent interpreted versions of the raw attribute above. 
-   * Only use the appropriate member according to the type field.  
-   * In the event of an unknown type, use only the raw field.
+  /** These items represent interpreted versions of the REGFI_DATA::raw field.
+   *
+   * Only use the appropriate member according to the REGFI_DATA::type field.
+   * In the event of an unknown type, use only the REGFI_DATA::raw field.
    */
   union _regfi_data_interpreted
   {
-    uint8_t* none; /* */
+    /** REG_NONE 
+     *
+     * Stored as a raw buffer.  Use REGFI_DATA::interpreted_size to determine
+     * length.
+     */
+    uint8_t* none; 
+
+    /** REG_SZ 
+     *
+     * Stored as a NUL terminated string.  Converted to the specified
+     * REGFI_ENCODING.
+     */
     uint8_t* string;
+
+    /** REG_EXPAND_SZ 
+     *
+     * Stored as a NUL terminated string.  Converted to the specified
+     * REGFI_ENCODING.
+     */
     uint8_t* expand_string;
-    uint8_t* binary; /* */
+
+    /** REG_BINARY
+     *
+     * Stored as a raw buffer.  Use REGFI_DATA::interpreted_size to determine
+     * length.
+     */
+    uint8_t* binary;
+
+    /** REG_DWORD */
     uint32_t dword;
+
+    /** REG_DWORD_BE */
     uint32_t dword_be;
+
+    /** REG_LINK
+     *
+     * Stored as a NUL terminated string.  Converted to the specified
+     * REGFI_ENCODING.
+     */
     uint8_t* link;
+
+    /** REG_MULTI_SZ 
+     *
+     * Stored as a list of uint8_t* pointers, terminated with a NULL pointer.
+     * Each string element in the list is NUL terminated, and the character set
+     * is determined by the specified REGFI_ENCODING.
+     */
     uint8_t** multiple_string;
+
+    /** REG_QWORD */
     uint64_t qword;
 
@@ -340,6 +427,24 @@
      * the future as the formats become better understood.
      */
+
+    /** REG_RESOURCE_LIST
+     *
+     * Stored as a raw buffer.  Use REGFI_DATA::interpreted_size to determine
+     * length.
+     */
     uint8_t* resource_list;
+
+    /** REG_FULL_RESOURCE_DESCRIPTOR
+     *
+     * Stored as a raw buffer.  Use REGFI_DATA::interpreted_size to determine
+     * length.
+     */
     uint8_t* full_resource_descriptor;
+
+    /** REG_RESOURCE_REQUIREMENTS_LIST
+     *
+     * Stored as a raw buffer.  Use REGFI_DATA::interpreted_size to determine
+     * length.
+     */
     uint8_t* resource_requirements_list;
   } interpreted;
@@ -347,25 +452,63 @@
 
 
-/* Value record */
-typedef struct 
+/** Value structure
+ * @ingroup regfiBase
+ */
+typedef struct
 {
-  uint32_t offset;	/* Real offset of this record's cell in the file */
-  uint32_t cell_size;	/* ((start_offset - end_offset) & 0xfffffff8) */
-
-  REGFI_DATA* data;     /* XXX: deprecated */
-
-  char*  valuename;
+  /** Real offset of this record's cell in the file */
+  uint32_t offset;	
+
+  /** ((start_offset - end_offset) & 0xfffffff8) */
+  uint32_t cell_size;
+
+  /* XXX: deprecated */
+  REGFI_DATA* data;
+
+  /** The name of this value converted to desired REGFI_ENCODING.  
+   *
+   * This conversion typically occurs automatically through REGFI_ITERATOR
+   * settings.  String is NUL terminated.
+   */
+  char*    valuename;
+
+  /** The raw value name
+   *
+   * Length of the buffer is stored in name_length.
+   */
   uint8_t* valuename_raw;
+
+  /** Length of valuename_raw */
   uint16_t name_length;
-  uint32_t hbin_off;	/* offset from beginning of this hbin block */
+
+  /** Offset from beginning of this hbin block */
+  uint32_t hbin_off;
   
-  uint32_t data_size;     /* As reported in the VK record.  May be different than
-			 * That obtained while parsing the data cell itself. */
-  uint32_t data_off;      /* Offset of data cell (virtual) */
+  /** Size of the value's data as reported in the VK record.
+   *
+   * May be different than that obtained while parsing the data cell itself.
+   */
+  uint32_t data_size;
+
+  /** Virtual offset of data cell */
+  uint32_t data_off;
+
+  /** Value's data type */
   uint32_t type;
+
+  /** VK record's magic number (should be "vk") */
   uint8_t  magic[REGFI_CELL_MAGIC_SIZE];
+
+  /** VK record flags */
   uint16_t flags;
+
+  /* XXX: A 2-byte field of unknown purpose stored in the VK record */
   uint16_t unknown1;
-  bool data_in_offset;
+
+  /** Whether or not the data record is stored in the VK record's data_off field. 
+   *
+   * This information is derived from the high bit of the raw data size field.
+   */
+  bool     data_in_offset;
 } REGFI_VK_REC;
 
@@ -374,51 +517,114 @@
 struct _regfi_sk_rec;
 
+/** Security structure
+ * @ingroup regfiBase
+ */
 typedef struct _regfi_sk_rec 
 {
-  uint32_t offset;        /* Real file offset of this record */
-  uint32_t cell_size;	/* ((start_offset - end_offset) & 0xfffffff8) */
-
+  /** Real file offset of this record */
+  uint32_t offset;
+
+  /** ((start_offset - end_offset) & 0xfffffff8) */
+  uint32_t cell_size;
+
+  /** The stored Windows security descriptor for this SK record */
   WINSEC_DESC* sec_desc;
-  uint32_t hbin_off;	/* offset from beginning of this hbin block */
+
+  /** Offset of this record from beginning of this hbin block */
+  uint32_t hbin_off;
   
+  /** Offset of the previous SK record in the linked list of SK records */
   uint32_t prev_sk_off;
+
+  /** Offset of the next SK record in the linked list of SK records */
   uint32_t next_sk_off;
+
+  /** Number of keys referencing this SK record */
   uint32_t ref_count;
-  uint32_t desc_size;     /* size of security descriptor */
+
+  /** Size of security descriptor (sec_desc) */
+  uint32_t desc_size;
+
+  /* XXX: A 2-byte field of unknown purpose */
   uint16_t unknown_tag;
+
+  /** The magic number for this record (should be "sk") */
   uint8_t  magic[REGFI_CELL_MAGIC_SIZE];
 } REGFI_SK_REC;
 
 
-/* Key Name */
+/** Key structure
+ * @ingroup regfiBase
+ */
 typedef struct
 {
-  uint32_t offset;	/* Real offset of this record's cell in the file */
-  uint32_t cell_size;	/* Actual or estimated length of the cell.  
-			 * Always in multiples of 8. 
-			 */
-
-  /* link in the other records here */
+  /** Real offset of this record's cell in the file */
+  uint32_t offset;
+
+  /** Actual or estimated length of the cell.  
+   * Always in multiples of 8. 
+   */
+  uint32_t cell_size;
+
+  /** Preloaded value-list for this key.
+   * This element is loaded automatically when using the iterator interface and
+   * possibly some lower layer interfaces.
+   */
   REGFI_VALUE_LIST* values;
+
+
+  /** Preloaded subkey-list for this key.
+   * This element is loaded automatically when using the iterator interface and
+   * possibly some lower layer interfaces.
+   */
   REGFI_SUBKEY_LIST* subkeys;
   
-  /* header information */
+  /** Key flags */
   uint16_t flags;
+
+  /** Magic number of key (should be "nk") */
   uint8_t  magic[REGFI_CELL_MAGIC_SIZE];
+
+  /** Key's last modification time */
   REGFI_NTTIME mtime;
+
+  /** Length of keyname_raw */
   uint16_t name_length;
+
+  /** Length of referenced classname */
   uint16_t classname_length;
+
+  /** The name of this key converted to desired REGFI_ENCODING.  
+   *
+   * This conversion typically occurs automatically through REGFI_ITERATOR
+   * settings.  String is NUL terminated.
+   */
   char* keyname;
+
+  /** The raw key name
+   *
+   * Length of the buffer is stored in name_length.
+   */
   uint8_t* keyname_raw;
-  uint32_t parent_off;	            /* pointer to parent key */
+
+  /** Virutal offset of parent key */
+  uint32_t parent_off;
+
+  /** Virutal offset of classname key */
   uint32_t classname_off;
   
-  /* max lengths */
-  uint32_t max_bytes_subkeyname;	    /* max subkey name * 2 */
-  uint32_t max_bytes_subkeyclassname; /* max subkey classname length (as if) */
-  uint32_t max_bytes_valuename;	    /* max valuename * 2 */
-  uint32_t max_bytes_value;           /* max value data size */
+  /* XXX: max subkey name * 2 */
+  uint32_t max_bytes_subkeyname;
+
+  /* XXX: max subkey classname length (as if) */
+  uint32_t max_bytes_subkeyclassname;
+
+  /* XXX: max valuename * 2 */
+  uint32_t max_bytes_valuename;
+
+  /* XXX: max value data size */
+  uint32_t max_bytes_value;
   
-  /* unknowns */
+  /* XXX: Fields of unknown purpose */
   uint32_t unknown1;
   uint32_t unknown2;
@@ -426,15 +632,37 @@
   uint32_t unk_index;		    /* nigel says run time index ? */
   
-  /* children */
+  /** Number of subkeys */
   uint32_t num_subkeys;
-  uint32_t subkeys_off;	/* offset of subkey list that points to NK records */
+
+  /** Virtual offset of subkey-list */
+  uint32_t subkeys_off;
+
+  /** Number of values for this key */
   uint32_t num_values;
-  uint32_t values_off;	/* value lists which point to VK records */
-  uint32_t sk_off;	/* offset to SK record */
+
+  /** Virtual offset of value-list */
+  uint32_t values_off;
+
+  /** Virtual offset of SK record */
+  uint32_t sk_off;
 } REGFI_NK_REC;
 
 
 
-/* REGF block */
+/** Registry hive file data structure
+ *
+ * This essential structure stores run-time information about a single open
+ * registry hive as well as file header (REGF block) data.  This structure 
+ * also stores a list of warnings and error messages generated while parsing
+ * the registry hive.  These can be tuned using @ref regfi_set_message_mask.  
+ * Messages may be retrieved using @ref regfi_get_messages.
+ *
+ * @note If the message mask is set to record any messages, dependent code 
+ *       must use @ref regfi_get_messages periodically to clear the message
+ *       queue. Otherwise, this structure will grow in size over time as 
+ *       messages queue up.
+ *
+ * @ingroup regfiBase
+ */ 
 typedef struct 
 {
@@ -513,11 +741,27 @@
 
 
+/** Registry hive iterator
+ * @ingroup regfiIteratorLayer
+ */
 typedef struct _regfi_iterator
 {
+  /** The registry hive this iterator is associated with */
   REGFI_FILE* f;
+
+  /** All current parent keys and associated iterator positions */
   void_stack* key_positions;
+
+  /** The current key */
   REGFI_NK_REC* cur_key;
+
+  /** The encoding that all strings are converted to as set during iterator
+   *  creation.
+   */
   REGFI_ENCODING string_encoding;
+
+  /** Index of the current subkey */
   uint32_t cur_subkey;
+
+  /** Index of the current value */
   uint32_t cur_value;
 } REGFI_ITERATOR;
@@ -534,4 +778,7 @@
 
 
+/** General purpose buffer with stored length
+ * @ingroup regfiBottomLayer
+ */
 typedef struct _regfi_buffer
 {
@@ -541,13 +788,13 @@
 
 
+
 /******************************************************************************/
 /** 
- * @defgroup regfiBase Base Functions: Usable with Any Layer
- *
- * These functions don't fit particularly well in any of the other layers or
- * are intended for use with any of the API layers.
+ * @defgroup regfiBase Base Layer: Essential Functions and Data Structures
+ *
+ * These functions are either necessary for normal use of the regfi API or just
+ * don't fit particularly well in any of the other layers.
  */
 /******************************************************************************/
-
 
 /** Attempts to open a registry hive and allocate related data structures.
@@ -658,5 +905,5 @@
 /******************************************************************************/
 /** 
- * @defgroup regfiTopLayer Top Layer: Primary regfi Library Interface
+ * @defgroup regfiIteratorLayer Iterator Layer: Primary regfi Library Interface
  *
  * This top layer of API functions provides an iterator interface which makes
@@ -681,5 +928,5 @@
  *         Must be free()d with regfi_iterator_free.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_ITERATOR*       regfi_iterator_new(REGFI_FILE* file,
@@ -693,5 +940,5 @@
  * @param i the iterator to be freed
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 void                  regfi_iterator_free(REGFI_ITERATOR* i);
@@ -709,5 +956,5 @@
  *          depth-first iteration particularly easy.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool                  regfi_iterator_down(REGFI_ITERATOR* i);
@@ -721,5 +968,5 @@
  *          associated with the current key is lost.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool                  regfi_iterator_up(REGFI_ITERATOR* i);
@@ -732,5 +979,5 @@
  * @return true on success, false on failure.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool                  regfi_iterator_to_root(REGFI_ITERATOR* i);
@@ -753,5 +1000,5 @@
  *                 in its original position.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool regfi_iterator_walk_path(REGFI_ITERATOR* i, const char** path);
@@ -764,5 +1011,5 @@
  * @return A read-only key structure for the current key, or NULL on failure.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 const REGFI_NK_REC*   regfi_iterator_cur_key(REGFI_ITERATOR* i);
@@ -775,5 +1022,5 @@
  * @return A read-only SK structure, or NULL on failure.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 const REGFI_SK_REC*   regfi_iterator_cur_sk(REGFI_ITERATOR* i);
@@ -790,5 +1037,5 @@
  *         regfi_free_key.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_NK_REC*         regfi_iterator_first_subkey(REGFI_ITERATOR* i);
@@ -803,5 +1050,5 @@
  *         regfi_free_key.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_NK_REC*         regfi_iterator_cur_subkey(REGFI_ITERATOR* i);
@@ -816,5 +1063,5 @@
  *         failure.  Newly allocated keys must be freed with regfi_free_key.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_NK_REC*         regfi_iterator_next_subkey(REGFI_ITERATOR* i);
@@ -830,5 +1077,5 @@
  *         the subkey index remains at the same location as before the call.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool                  regfi_iterator_find_subkey(REGFI_ITERATOR* i, 
@@ -845,5 +1092,5 @@
  *          regfi_free_value.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_VK_REC*         regfi_iterator_first_value(REGFI_ITERATOR* i);
@@ -858,5 +1105,5 @@
  *         regfi_free_value.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_VK_REC*         regfi_iterator_cur_value(REGFI_ITERATOR* i);
@@ -871,5 +1118,5 @@
  *          failure.  Newly allocated keys must be freed with regfi_free_value.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_VK_REC*         regfi_iterator_next_value(REGFI_ITERATOR* i);
@@ -885,5 +1132,5 @@
  *         the value index remains at the same location as before the call.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 bool                  regfi_iterator_find_value(REGFI_ITERATOR* i, 
@@ -898,5 +1145,5 @@
  *         Classname structures must be freed with regfi_free_classname.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_CLASSNAME*      regfi_iterator_fetch_classname(REGFI_ITERATOR* i, 
@@ -912,5 +1159,5 @@
  *         Data structures must be freed with regfi_free_data.
  *
- * @ingroup regfiTopLayer
+ * @ingroup regfiIteratorLayer
  */
 REGFI_DATA*           regfi_iterator_fetch_data(REGFI_ITERATOR* i, 
@@ -921,5 +1168,5 @@
 /******************************************************************************/
 /** 
- * @defgroup regfiMiddleLayer Middle Layer: Logical Data Structure Loading 
+ * @defgroup regfiGlueLayer Glue Layer: Logical Data Structure Loading 
  */
 /******************************************************************************/
@@ -929,5 +1176,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_NK_REC*         regfi_load_key(REGFI_FILE* file, uint32_t offset, 
@@ -940,5 +1187,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_VK_REC*         regfi_load_value(REGFI_FILE* file, uint32_t offset, 
@@ -951,5 +1198,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_SUBKEY_LIST*    regfi_load_subkeylist(REGFI_FILE* file, uint32_t offset,
@@ -962,5 +1209,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_VALUE_LIST*     regfi_load_valuelist(REGFI_FILE* file, uint32_t offset, 
@@ -974,5 +1221,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_BUFFER          regfi_load_data(REGFI_FILE* file, uint32_t voffset,
@@ -985,5 +1232,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 REGFI_BUFFER          regfi_load_big_data(REGFI_FILE* file, uint32_t offset, 
@@ -998,5 +1245,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 bool                  regfi_interpret_data(REGFI_FILE* file, 
@@ -1009,5 +1256,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 void                  regfi_free_classname(REGFI_CLASSNAME* classname);
@@ -1018,5 +1265,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 void                  regfi_free_data(REGFI_DATA* data);
@@ -1029,5 +1276,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 const REGFI_SK_REC*   regfi_load_sk(REGFI_FILE* file, uint32_t offset,
@@ -1039,5 +1286,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiMiddleLayer
+ * @ingroup regfiGlueLayer
  */
 const REGFI_HBIN*     regfi_lookup_hbin(REGFI_FILE* file, uint32_t offset);
@@ -1047,5 +1294,5 @@
 /******************************************************************************/
 /**
- * @defgroup regfiBottomLayer Bottom Layer: Direct Data Structure Access 
+ * @defgroup regfiParseLayer Parsing Layer: Direct Data Structure Access 
  */
 /******************************************************************************/
@@ -1066,5 +1313,5 @@
  * @return A newly allocated NK record structure, or NULL on failure.
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_NK_REC*         regfi_parse_nk(REGFI_FILE* file, uint32_t offset,
@@ -1076,5 +1323,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_SUBKEY_LIST*    regfi_parse_subkeylist(REGFI_FILE* file, uint32_t offset,
@@ -1086,5 +1333,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_VK_REC*         regfi_parse_vk(REGFI_FILE* file, uint32_t offset, 
@@ -1096,5 +1343,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_SK_REC*         regfi_parse_sk(REGFI_FILE* file, uint32_t offset, 
@@ -1109,5 +1356,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 range_list*           regfi_parse_unalloc_cells(REGFI_FILE* file);
@@ -1118,5 +1365,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 bool                  regfi_parse_cell(int fd, uint32_t offset, 
@@ -1129,5 +1376,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 uint8_t*                regfi_parse_classname(REGFI_FILE* file, uint32_t offset,
@@ -1140,5 +1387,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_BUFFER          regfi_parse_data(REGFI_FILE* file, uint32_t offset,
@@ -1151,5 +1398,5 @@
  * XXX: finish documenting
  *
- * @ingroup regfiBottomLayer
+ * @ingroup regfiParseLayer
  */
 REGFI_BUFFER          regfi_parse_little_data(REGFI_FILE* file, uint32_t voffset, 
@@ -1163,5 +1410,5 @@
 				    REGFI_ENCODING output_encoding);
 void                  regfi_subkeylist_free(REGFI_SUBKEY_LIST* list);
-uint32_t                regfi_read(int fd, uint8_t* buf, uint32_t* length);
+uint32_t              regfi_read(int fd, uint8_t* buf, uint32_t* length);
 
 const char*           regfi_type_val2str(unsigned int val);
Index: /trunk/include/void_stack.h
===================================================================
--- /trunk/include/void_stack.h	(revision 168)
+++ /trunk/include/void_stack.h	(revision 169)
@@ -1,6 +1,4 @@
-/**
- * @file
- *
- * Copyright (C) 2005,2007,2009 Timothy D. Morgan
+/*
+ * Copyright (C) 2005,2007,2009-2010 Timothy D. Morgan
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,4 +18,12 @@
  */
 
+/** 
+ *@file
+ * 
+ * This is a very simple implementation of a stack which stores chunks of
+ * memory of any type.
+ */
+
+
 #ifndef _VOID_STACK_H
 #define _VOID_STACK_H
@@ -28,4 +34,5 @@
 #include "talloc.h"
 
+/** XXX: document this. */
 typedef struct _void_stack
 {
@@ -35,4 +42,6 @@
 } void_stack;
 
+
+/** XXX: document this. */
 typedef struct _void_stack_iterator
 {
@@ -42,147 +51,118 @@
 
 
-/* void_stack_new(): 
- *  Allocates a new void_stack.
+/** Allocates a new void_stack.
  *
- * Arguments:
- *  max_size -- the maxiumum number of elements 
- *              which may be pushed onto the stack.
+ * @param max_size the maxiumum number of elements 
+ *                 which may be pushed onto the stack.
  *
- * Returns: 
- *  a pointer to the newly allocated void_stack, or NULL if an error occurred.
+ * @return a pointer to the newly allocated void_stack, 
+ *         or NULL if an error occurred.
  */
 void_stack* void_stack_new(unsigned short max_size);
 
 
-/* void_stack_copy(): 
- *  Makes a shallow copy of void_stack.
+/** Makes a shallow copy of void_stack.
  *
- * Arguments:
- *  v -- the stack to make a copy of.
+ * @param v the stack to make a copy of.
  *
- * Returns:
- *  a pointer to the duplicate void_stack, or NULL If an error occurred.
+ * @return a pointer to the duplicate void_stack, or NULL if an error occurred.
  */
 void_stack* void_stack_copy(const void_stack* v);
 
 
-/* void_stack_copy_reverse(): 
- *  Makes a shallow copy of void_stack in reverse order.
+/** Makes a shallow copy of void_stack in reverse order.
  *
- * Arguments:
- *  v -- the stack to make a copy of.
+ * @param v the stack to make a copy of.
  *
- * Returns:
- *  a pointer to the duplicate void_stack (which will be in reverse order),
- *  or NULL If an error occurred.
+ * @return a pointer to the duplicate void_stack 
+ *         (which will be in reverse order), or NULL if an error occurred.
  */
 void_stack* void_stack_copy_reverse(const void_stack* v);
 
 
-/* void_stack_free(): 
- *  Frees the memory associated with a void_stack, but not the elements held
+/** Frees the memory associated with a void_stack, but not the elements held
  *  on the stack.
  *
- * Arguments:
- *  stack -- the stack to be free()d.
+ * @param stack the stack to be free()d.
  */
 void void_stack_free(void_stack* stack);
 
 
-/* void_stack_free_deep(): 
- *  Frees the memory associated with a void_stack and the elements referenced 
- *  by the stack.  Do not use this function if the elements of the stack 
- *  are also free()d elsewhere, or contain pointers to other memory which 
- *  cannot be otherwise free()d.
+/** Frees the memory associated with a void_stack and the elements referenced 
+ *  by the stack.  
  *
- * Arguments:
- *  stack -- the stack to be free()d.
+ * Do not use this function if the elements of the stack 
+ * are also free()d elsewhere, or contain pointers to other memory which 
+ * cannot be otherwise free()d.
+ *
+ * @param stack the stack to be free()d.
  */
 void void_stack_free_deep(void_stack* stack);
 
 
-/* void_stack_size(): 
- *  Query the current number of elements on a void_stack()
+/** Query the current number of elements on a void_stack()
  *
- * Arguments:
- *  stack -- the void_stack to query
+ * @param stack the void_stack to query
  *
- * Returns:
- *  the number of elements currently on the stack.
+ * @return the number of elements currently on the stack.
  */
 unsigned short void_stack_size(const void_stack* stack);
 
 
-/* void_stack_pop():
- *  Removes the top element on a void_stack and returns a reference to it.
+/** Removes the top element on a void_stack and returns a reference to it.
  *
- * Arguments:
- *  stack -- the void_stack to pop
+ * @param stack the void_stack to pop
  *
- * Returns:
- *  a pointer to the popped stack element, or NULL if no elements exist on 
- *  the stack.
+ * @return a pointer to the popped stack element, or NULL if no elements exist
+ *         on the stack.
  */
 void* void_stack_pop(void_stack* stack);
 
 
-/* void_stack_push():
- *  Puts a new element on the top of a void_stack.
+/** Puts a new element on the top of a void_stack.
  *
- * Arguments:
- *  stack -- the void_stack being modified.
+ * @param stack the void_stack being modified.
+ * @param e the element to be added
  *
- *  e     -- the element to be added
- *
- * Returns:
- *  true if the element was successfully added, false otherwise.
+ * @return true if the element was successfully added, false otherwise.
  */
 bool void_stack_push(void_stack* stack, void* e);
 
 
-/* void_stack_cur():
- *  Returns a pointer to the current element on the top of the stack.
+/** Returns a pointer to the current element on the top of the stack.
  *
- * Arguments:
- *  stack -- the void_stack being queried.
+ * @param stack the void_stack being queried.
  *
- * Returns:
- *  a pointer to the current element on the top of the stack, or NULL if no
- *  elements exist in the stack.
+ * @return a pointer to the current element on the top of the stack, or NULL if
+ *         no elements exist in the stack.
  */
 const void* void_stack_cur(const void_stack* stack);
 
 
-/* void_stack_iterator_new():
- *  Creates a new iterator for the specified void_stack.
+/** Creates a new iterator for the specified void_stack.
  *
- * Arguments:
- *  stack -- the void_stack to be referenced by the new iterator
+ * @param stack the void_stack to be referenced by the new iterator
  *
- * Returns:
- *  a new void_stack_iterator, or NULL if an error occurred.
+ * @return a new void_stack_iterator, or NULL if an error occurred.
  */
 void_stack_iterator* void_stack_iterator_new(const void_stack* stack);
 
 
-/* void_stack_iterator_free():
- *  Frees a void_stack_iterator.  Does not affect the void_stack referenced
- *  by the iterator.
+/** Frees a void_stack_iterator.
  *
- * Arguments:
- *  iter -- the void_stack_iterator to be free()d.
+ * Does not affect the void_stack referenced by the iterator.
+ *
+ * @param iter the void_stack_iterator to be free()d.
  */
 void void_stack_iterator_free(void_stack_iterator* iter);
 
 
-/* void_stack_iterator_next():
- *  Returns a pointer to the the next element in the stack.  Iterates over 
- *  elements starting in order from the oldest element (bottom of the stack).
+/** Returns a pointer to the the next element in the stack.
  *
- * Arguments:
- *  iter -- the void_stack_iterator used to lookup the next element.
+ * Iterates over elements starting in order from the oldest element (bottom of the stack).
  *
- * Returns:
- *  a pointer to the next element.
+ * @param iter the void_stack_iterator used to lookup the next element.
+ *
+ * @return a pointer to the next element.
  */
 const void* void_stack_iterator_next(void_stack_iterator* iter);
Index: /trunk/include/winsec.h
===================================================================
--- /trunk/include/winsec.h	(revision 168)
+++ /trunk/include/winsec.h	(revision 169)
@@ -1,12 +1,4 @@
-/** @file
- * This file contains refactored Samba code used to interpret Windows
- * Security Descriptors. See:
- *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
- *
- * Revisions have been made based on information provided by Microsoft
- * at: 
- *    http://msdn.microsoft.com/en-us/library/cc230366(PROT.10).aspx
- *
- * Copyright (C) 2005,2009 Timothy D. Morgan
+/* 
+ * Copyright (C) 2005,2009-2010 Timothy D. Morgan
  * Copyright (C) 1992-2005 Samba development team 
  * 
@@ -27,4 +19,16 @@
  */
 
+/**
+ * @file
+ *
+ * A small library for interpreting Windows Security Descriptors.
+ * This library was originally based on Samba source from:
+ *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
+ *
+ * The library has been heavily rewritten and improved based on information
+ * provided by Microsoft at: 
+ *    http://msdn.microsoft.com/en-us/library/cc230366%28PROT.10%29.aspx
+ */
+
 #ifndef _WINSEC_H
 #define _WINSEC_H
@@ -70,101 +74,238 @@
 
 
+/** XXX: document this. */
 typedef struct _winsec_uuid
 {
-       uint32_t time_low;
-       uint16_t time_mid;
-       uint16_t time_hi_and_version;
-       uint8_t  clock_seq[2];
-       uint8_t  node[6];
+  /** XXX: document this. */
+  uint32_t time_low;
+
+  /** XXX: document this. */
+  uint16_t time_mid;
+
+  /** XXX: document this. */
+  uint16_t time_hi_and_version;
+
+  /** XXX: document this. */
+  uint8_t  clock_seq[2];
+
+  /** XXX: document this. */
+  uint8_t  node[6];
 } WINSEC_UUID;
 
 
+/** XXX: document this. */
 typedef struct _winsec_sid
 {
-  uint8_t  sid_rev_num;             /* SID revision number */
-  uint8_t  num_auths;               /* Number of sub-authorities */
-  uint8_t  id_auth[6];              /* Identifier Authority */
-  /*
-   *  Pointer to sub-authorities.
-   *
+  /** SID revision number */
+  uint8_t  sid_rev_num;
+
+  /** Number of sub-authorities */
+  uint8_t  num_auths;
+
+  /** Identifier Authority */
+  uint8_t  id_auth[6];
+
+  /** Pointer to sub-authorities.
+   * 
    * @note The values in these uint32_t's are in *native* byteorder, not
    * neccessarily little-endian...... JRA.
    */
-  /* XXX: Make this dynamically allocated? */
-  uint32_t sub_auths[WINSEC_MAX_SUBAUTHS];
+  uint32_t sub_auths[WINSEC_MAX_SUBAUTHS];   /* XXX: Make this dynamically allocated? */
 } WINSEC_DOM_SID;
 
 
+/** XXX: document this. */
 typedef struct _winsec_ace
 {
-	uint8_t type;  /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
-	uint8_t flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
-	uint16_t size;
-	uint32_t access_mask;
-
-	/* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
-	uint32_t  obj_flags;   /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
-	WINSEC_UUID* obj_guid;  /* object GUID */
-	WINSEC_UUID* inh_guid;  /* inherited object GUID */		
-        /* eof object stuff */
-
-	WINSEC_DOM_SID* trustee;
+  /** xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
+  uint8_t type;
+
+  /** xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
+  uint8_t flags;
+
+  /** XXX: finish documenting */
+  uint16_t size;
+
+  /** XXX: finish documenting */
+  uint32_t access_mask;
+  
+  /* This stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
+
+  /** xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
+  uint32_t  obj_flags;
+
+  /** Object GUID */
+  WINSEC_UUID* obj_guid;
+
+  /** Inherited object GUID */
+  WINSEC_UUID* inh_guid;
+
+  /* eof object stuff */
+  
+  /** XXX: finish documenting */
+  WINSEC_DOM_SID* trustee;
 
 } WINSEC_ACE;
 
+
+/** XXX: document this. */
 typedef struct _winsec_acl
 {
-	uint16_t revision; /* 0x0003 */
-	uint16_t size;     /* size in bytes of the entire ACL structure */
-	uint32_t num_aces; /* number of Access Control Entries */
-
-	WINSEC_ACE** aces;
+  /** 0x0003 */
+  uint16_t revision;
+
+  /** Size, in bytes, of the entire ACL structure */
+  uint16_t size;
+
+  /** Number of Access Control Entries */
+  uint32_t num_aces;
+  
+  /** XXX: document this. */
+  WINSEC_ACE** aces;
 
 } WINSEC_ACL;
 
+
+/** XXX: document this. */
 typedef struct _winsec_desc
 {
-	uint8_t revision; /* 0x01 */
-	uint8_t sbz1;     /* "If the Control field has the RM flag set,
-			   *  then this field contains the resource
-			   *  manager (RM) control value. ... Otherwise,
-			   *  this field is reserved and MUST be set to
-			   *  zero." -- Microsoft.  See reference above.
-			   */
-	uint16_t control; /* WINSEC_DESC_* flags */
-
-	uint32_t off_owner_sid; /* offset to owner sid */
-	uint32_t off_grp_sid  ; /* offset to group sid */
-	uint32_t off_sacl     ; /* offset to system list of permissions */
-	uint32_t off_dacl     ; /* offset to list of permissions */
-
-	WINSEC_DOM_SID* owner_sid; 
-	WINSEC_DOM_SID* grp_sid;
-	WINSEC_ACL* sacl;       /* system ACL */
-	WINSEC_ACL* dacl;       /* user ACL */
+  /** 0x01 */
+  uint8_t revision;
+
+  /** XXX: better explain this
+   *
+   * "If the Control field has the RM flag set, then this field contains the
+   *  resource manager (RM) control value. ... Otherwise, this field is reserved
+   *  and MUST be set to zero." -- Microsoft.
+   *  See:
+   *   http://msdn.microsoft.com/en-us/library/cc230371%28PROT.10%29.aspx
+   */
+  uint8_t sbz1;
+
+  /** WINSEC_DESC_* flags */
+  uint16_t control;
+  
+  /** Offset to owner sid */
+  uint32_t off_owner_sid;
+
+  /** Offset to group sid */
+  uint32_t off_grp_sid;
+
+  /** Offset to system list of permissions */
+  uint32_t off_sacl;
+
+  /** Offset to list of permissions */
+  uint32_t off_dacl;
+
+  /** XXX: document this */
+  WINSEC_DOM_SID* owner_sid; 
+
+  /** XXX: document this */
+  WINSEC_DOM_SID* grp_sid;
+
+  /** System ACL */
+  WINSEC_ACL* sacl;
+
+  /** User ACL */
+  WINSEC_ACL* dacl;
 
 } WINSEC_DESC;
 
+
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_DESC* winsec_parse_descriptor(const uint8_t* buf, uint32_t buf_len);
+
+
+/**
+ *
+ * XXX: finish documenting
+ */
 void winsec_free_descriptor(WINSEC_DESC* desc);
 
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_DESC* winsec_parse_desc(void* talloc_ctx,
 			       const uint8_t* buf, uint32_t buf_len);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_ACL* winsec_parse_acl(void* talloc_ctx, 
 			     const uint8_t* buf, uint32_t buf_len);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_ACE* winsec_parse_ace(void* talloc_ctx, 
 			     const uint8_t* buf, uint32_t buf_len);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_DOM_SID* winsec_parse_dom_sid(void* talloc_ctx, 
 				     const uint8_t* buf, uint32_t buf_len);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 WINSEC_UUID* winsec_parse_uuid(void* talloc_ctx, 
 			       const uint8_t* buf, uint32_t buf_len);
 
+
+/**
+ *
+ * XXX: finish documenting
+ */
 size_t winsec_sid_size(const WINSEC_DOM_SID* sid);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 int winsec_sid_compare_auth(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 int winsec_sid_compare(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 bool winsec_sid_equal(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 bool winsec_desc_equal(WINSEC_DESC* s1, WINSEC_DESC* s2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 bool winsec_acl_equal(WINSEC_ACL* s1, WINSEC_ACL* s2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 bool winsec_ace_equal(WINSEC_ACE* s1, WINSEC_ACE* s2);
+
+/**
+ *
+ * XXX: finish documenting
+ */
 bool winsec_ace_object(uint8_t type);
 
Index: /trunk/lib/lru_cache.c
===================================================================
--- /trunk/lib/lru_cache.c	(revision 168)
+++ /trunk/lib/lru_cache.c	(revision 169)
@@ -1,5 +1,3 @@
-/**
- * @file
- *
+/*
  * Copyright (C) 2008-2009 Timothy D. Morgan
  *
@@ -20,4 +18,8 @@
  */
 
+/**
+ * @file
+ */
+
 #include "lru_cache.h"
 
Index: /trunk/lib/range_list.c
===================================================================
--- /trunk/lib/range_list.c	(revision 168)
+++ /trunk/lib/range_list.c	(revision 169)
@@ -1,6 +1,4 @@
-/**
- * @file
- *
- * Copyright (C) 2008-2009 Timothy D. Morgan
+/*
+ * Copyright (C) 2008-2010 Timothy D. Morgan
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,4 +18,8 @@
  */
 
+/**
+ * @file
+ */
+
 #include "range_list.h"
 
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 168)
+++ /trunk/lib/regfi.c	(revision 169)
@@ -1,9 +1,4 @@
 /*
- * Branched from Samba project Subversion repository, version #7470:
- *   http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/registry/regfio.c?rev=7470&view=auto
- *
- * Windows NT (and later) registry parsing library
- *
- * Copyright (C) 2005-2009 Timothy D. Morgan
+ * Copyright (C) 2005-2010 Timothy D. Morgan
  * Copyright (C) 2005 Gerald (Jerry) Carter
  *
@@ -24,5 +19,16 @@
  */
 
-/** @file */
+/** 
+ * @file
+ *
+ * Windows NT (and later) read-only registry library
+ *
+ * See @ref regfi.h for more information.
+ *
+ * Branched from Samba project Subversion repository, version #7470:
+ *   http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/registry/regfio.c?rev=7470&view=auto
+ *
+ * Since then, it has been heavily rewritten, simplified, and improved.
+ */
 
 #include "regfi.h"
@@ -2544,5 +2550,4 @@
   ret_val->offset = offset;
   ret_val->cell_size = cell_length;
-  ret_val->data = NULL;
   ret_val->valuename = NULL;
   ret_val->valuename_raw = NULL;
Index: /trunk/lib/void_stack.c
===================================================================
--- /trunk/lib/void_stack.c	(revision 168)
+++ /trunk/lib/void_stack.c	(revision 169)
@@ -1,9 +1,4 @@
-/**
- * @file
- *
- * This is a really simple implementation of a stack which stores chunks
- * of memory of any type.
- *
- * Copyright (C) 2005,2007,2009 Timothy D. Morgan
+/*
+ * Copyright (C) 2005,2007,2009-2010 Timothy D. Morgan
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,4 +17,9 @@
  * $Id$
  */
+
+/**  
+ * @file
+ */
+
 
 #include "void_stack.h"
Index: /trunk/lib/winsec.c
===================================================================
--- /trunk/lib/winsec.c	(revision 168)
+++ /trunk/lib/winsec.c	(revision 169)
@@ -1,9 +1,5 @@
-/**
- * @file
- * This file contains refactored Samba code used to interpret Windows
- * Security Descriptors. See:
- *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
+/*
  *
- * Copyright (C) 2005-2006,2009 Timothy D. Morgan
+ * Copyright (C) 2005-2006,2009-2010 Timothy D. Morgan
  * Copyright (C) 1992-2005 Samba development team 
  *               (see individual files under Subversion for details.)
@@ -25,4 +21,6 @@
  */
 
+/** @file */
+
 #include "winsec.h"
 
