Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 165)
+++ /trunk/include/regfi.h	(revision 166)
@@ -519,6 +519,52 @@
 /*                         Main iterator API                                  */
 /******************************************************************************/
+
+/* regfi_open: Attempts to open a registry hive and allocate related data
+ *             structures.
+ *
+ * Arguments:
+ *   filename -- A string containing the relative or absolute path of the
+ *               registry hive to be opened.
+ *
+ * Returns:
+ *   A reference to a newly allocated REGFI_FILE structure, if successful. 
+ *   NULL on error.
+ */
 REGFI_FILE*           regfi_open(const char* filename);
-int                   regfi_close(REGFI_FILE* r);
+
+
+/* regfi_alloc: Parses file headers of an already open registry hive file and 
+ *              allocates related structures for further parsing.
+ *
+ * Arguments:
+ *   fd       -- A file descriptor of an already open file.  Must be seekable.
+ *
+ * Returns:
+ *   A reference to a newly allocated REGFI_FILE structure, if successful. 
+ *   NULL on error.
+ */
+REGFI_FILE*           regfi_alloc(int fd);
+
+
+/* regfi_close: Closes and frees an open registry hive.
+ *
+ * Arguments:
+ *   file     -- The registry structure to close.
+ *
+ * Returns:
+ *   0 on success, -1 on failure with errno set.  
+ *   errno codes are similar to those of close(2).
+ */
+int                   regfi_close(REGFI_FILE* file);
+
+
+/* regfi_free: Frees a hive's data structures without closing the underlying
+ *             file.
+ *
+ * Arguments:
+ *   file     -- The registry structure to free.
+ */
+void                  regfi_free(REGFI_FILE* file);
+
 
 /* regfi_get_messages: Get errors, warnings, and/or verbose information
@@ -533,4 +579,26 @@
 char*                 regfi_get_messages(REGFI_FILE* file);
 
+
+/* regfi_set_message_mask: Set the verbosity level of errors and warnings
+ *                         generated by the library 
+ *                         (as accessible via regfi_get_messages).
+ *
+ * Arguments:
+ *   file     -- the structure for the registry file
+ *   mask     -- an integer representing the types of messages desired.
+ *               Acceptable values are created through bitwise ORs of 
+ *               REGFI_MSG_* values.  For instance, if only errors and
+ *               informational messages were desired (but not warnings),
+ *               then one would specify: REGFI_MSG_ERROR|REGFI_MSG_INFO
+ *               New REGFI_FILE structures are created with:
+ *                REGFI_MSG_ERROR|REGFI_MSG_WARN
+ *               Note that error and warning messages will continue to
+ *               accumulate in memory if they are not fetched using
+ *               regfi_get_messages and then freed by the caller.
+ *               To disable error messages entirely, supply 0, which
+ *               will prevent message accumulation.  
+ *
+ * This may be called at any time and will take effect immediately.
+ */
 void                  regfi_set_message_mask(REGFI_FILE* file, uint16 mask);
 
@@ -549,8 +617,4 @@
  *                      REGFI_ENCODING_UTF8
  *
- *                      XXX: This encoding only applies to specific data 
- *                           strings currently, but should apply to key 
- *                           names and value names in the future.
- *
  * Returns:
  *   A newly allocated REGFI_ITERATOR. Must be free()d with regfi_iterator_free.
@@ -558,15 +622,125 @@
 REGFI_ITERATOR*       regfi_iterator_new(REGFI_FILE* file,
 					 REGFI_ENCODING output_encoding);
+
+
+/* regfi_iterator_free: Frees a registry file iterator previously created by 
+ *                      regfi_iterator_new.
+ *
+ * This does not affect the underlying registry file's allocation status.
+ *
+ * Arguments:
+ *   file            -- the iterator to be freed
+ */
 void                  regfi_iterator_free(REGFI_ITERATOR* i);
+
+
+/* regfi_iterator_down: Traverse deeper into the registry tree at the
+ *                      current subkey.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   true on success, false on failure.  Note that subkey and value indexes
+ *   are preserved.  That is, if a regfi_iterator_up call occurs later
+ *   (reversing the effect of this call) then the subkey and value referenced
+ *   prior to the regfi_iterator_down call will still be referenced.  This 
+ *   makes depth-first iteration particularly easy.
+ */
 bool                  regfi_iterator_down(REGFI_ITERATOR* i);
+
+
+/* regfi_iterator_up: Traverse up to the current key's parent key.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   true on success, false on failure.  Any subkey or value state
+ *   associated with the current key is lost.
+ */
 bool                  regfi_iterator_up(REGFI_ITERATOR* i);
+
+
+/* regfi_iterator_to_root: Traverse up to the root key of the hive.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   true on success, false on failure.
+ */
 bool                  regfi_iterator_to_root(REGFI_ITERATOR* i);
 
+
+/* regfi_iterator_walk_path: Traverse down multiple levels in the registry hive.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *   path         -- a list of key names representing the path.  This list must
+ *                   contain NUL terminated strings.  The list itself is
+ *                   terminated with a NULL pointer.  All path elements must be
+ *                   keys; value names are not accepted (even as the last
+ *                   element).
+ *
+ * XXX: This currently only accepts ASCII key names.  Need to look into
+ *      accepting other encodings.
+ *
+ * Returns:
+ *   true on success, false on failure.  If any element of path is not found,
+ *   false will be returned and the iterator will remain in its original
+ *   position.
+ */
 bool                  regfi_iterator_walk_path(REGFI_ITERATOR* i, 
 					       const char** path);
+
+
+/* regfi_iterator_cur_key: Returns the currently referenced key.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   A read-only key structure for the current key, or NULL on failure.
+ */
 const REGFI_NK_REC*   regfi_iterator_cur_key(REGFI_ITERATOR* i);
+
+
+/* regfi_iterator_cur_sk: Returns the SK (security) record referenced by the 
+ *                        current key.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   A read-only SK structure, or NULL on failure.
+ */
 const REGFI_SK_REC*   regfi_iterator_cur_sk(REGFI_ITERATOR* i);
 
+
+/* regfi_iterator_first_subkey: Sets the internal subkey index to the first
+ *                              subkey referenced by the current key.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   A read-only key structure for the newly referenced first subkey, 
+ *   or NULL on failure.  Failure may be due to a lack of any subkeys or other
+ *   errors.
+ */
 REGFI_NK_REC*         regfi_iterator_first_subkey(REGFI_ITERATOR* i);
+
+
+/* regfi_iterator_cur_subkey: Returns the currently indexed subkey.
+ *
+ * Arguments:
+ *   i            -- the iterator
+ *
+ * Returns:
+ *   A newly allocated key structure for the currently referenced subkey,
+ *   or NULL on failure.  Newly allocated keys must be freed with 
+ *   regfi_free_key.
+ */
 REGFI_NK_REC*         regfi_iterator_cur_subkey(REGFI_ITERATOR* i);
 REGFI_NK_REC*         regfi_iterator_next_subkey(REGFI_ITERATOR* i);
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 165)
+++ /trunk/lib/regfi.c	(revision 166)
@@ -1271,9 +1271,30 @@
 
 
-/*******************************************************************
- * Open the registry file and then read in the REGF block to get the
- * first hbin offset.
- *******************************************************************/
+/******************************************************************************
+ ******************************************************************************/
 REGFI_FILE* regfi_open(const char* filename)
+{
+  REGFI_FILE* ret_val;
+  int fd;
+
+  /* open an existing file */
+  if ((fd = open(filename, REGFI_OPEN_FLAGS)) == -1)
+  {
+    /* fprintf(stderr, "regfi_open: failure to open %s (%s)\n", filename, strerror(errno));*/
+    return NULL;
+  }
+
+  ret_val = regfi_alloc(fd);
+
+  if(ret_val == NULL)
+    close(fd);
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+REGFI_FILE* regfi_alloc(int fd)
 {
   struct stat sbuf;
@@ -1281,14 +1302,6 @@
   REGFI_HBIN* hbin = NULL;
   uint32 hbin_off, file_length, cache_secret;
-  int fd;
   bool rla;
 
-  /* open an existing file */
-  if ((fd = open(filename, REGFI_OPEN_FLAGS)) == -1)
-  {
-    /* fprintf(stderr, "regfi_open: failure to open %s (%s)\n", filename, strerror(errno));*/
-    return NULL;
-  }
-  
   /* Determine file length.  Must be at least big enough 
    * for the header and one hbin. 
@@ -1300,9 +1313,8 @@
     return NULL;
 
-  /* read in an existing file */
+  /* Read file header */
   if ((rb = regfi_parse_regf(fd, true)) == NULL) 
   {
-    /* fprintf(stderr, "regfi_open: Failed to read initial REGF block\n"); */
-    close(fd);
+    /* fprintf(stderr, "regfi_alloc: Failed to read initial REGF block\n"); */
     return NULL;
   }
@@ -1312,6 +1324,5 @@
   if(rb->hbins == NULL)
   {
-    /* fprintf(stderr, "regfi_open: Failed to create HBIN list.\n"); */
-    close(fd);
+    /* fprintf(stderr, "regfi_alloc: Failed to create HBIN list.\n"); */
     talloc_free(rb);
     return NULL;
@@ -1350,5 +1361,5 @@
 /******************************************************************************
  ******************************************************************************/
-int regfi_close(REGFI_FILE *file)
+int regfi_close(REGFI_FILE* file)
 {
   int fd;
@@ -1361,11 +1372,18 @@
   file->fd = -1;
 
-  range_list_free(file->hbins);
-
-  if(file->sk_cache != NULL)
-    lru_cache_destroy(file->sk_cache);
+  regfi_free(file);
+
+  return close(fd);
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+void regfi_free(REGFI_FILE *file)
+{
+  if(file->last_message != NULL)
+    free(last_message);
 
   talloc_free(file);
-  return close(fd);
 }
 
@@ -2077,8 +2095,8 @@
 
 
-/*******************************************************************
+/******************************************************************************
  * Convert from UTF-16LE to specified character set. 
  * On error, returns a negative errno code.
- *******************************************************************/
+ *****************************************************************************/
 int32 regfi_conv_charset(const char* input_charset, const char* output_charset,
 			 uint8* input, char* output, 
@@ -2901,5 +2919,5 @@
 				       uint16 num_chunks, bool strict)
 {
-  uint32 cell_length, chunk_offset, data_left;
+  uint32 cell_length, chunk_offset;
   range_list* ret_val;
   uint16 i;
@@ -2911,5 +2929,5 @@
     goto fail;
   
-  for(i=0; (i<num_chunks) && (data_left>0); i++)
+  for(i=0; i<num_chunks; i++)
   {
     chunk_offset = offsets[i]+REGFI_REGF_SIZE;
