Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 181)
+++ /trunk/include/regfi.h	(revision 182)
@@ -81,7 +81,10 @@
 
 /* regfi library error message types */
-#define REGFI_MSG_INFO  0x0001
-#define REGFI_MSG_WARN  0x0004
-#define REGFI_MSG_ERROR 0x0010
+#define REGFI_LOG_INFO  0x0001
+#define REGFI_LOG_WARN  0x0004
+#define REGFI_LOG_ERROR 0x0010
+
+/* For internal use */
+pthread_key_t REGFI_LOG_KEY;
 
 typedef uint8_t REGFI_ENCODING;
@@ -240,4 +243,15 @@
 
 
+typedef struct _regfi_log
+{
+  /* Error/warning/info messages returned by lower layer functions */
+  char* messages;
+
+  /* Mask for error message types that will be stored. */
+  uint16_t msg_mask;
+
+} REGFI_LOG;
+
+
 /** HBIN block information
  * @ingroup regfiMiddleLayer
@@ -695,11 +709,4 @@
   pthread_mutex_t* sk_lock;
 
-  /* Error/warning/info messages returned by lower layer functions */
-  char* last_message;
-
-  /* Mask for error message types that will be stored. */
-  uint16_t msg_mask;
-
-
   /* Data parsed from file header */
   /********************************/
@@ -849,14 +856,21 @@
 
 
+/** Enables regfi library logging for the current thread.
+ *
+ * XXX: finish documenting
+ *
+ * @ingroup regfiBase
+ */
+void regfi_log_start(uint16_t mask);
+
+
 /** Get errors, warnings, and/or verbose information relating to processing of
  *  the given registry file.
  *
- * @param file the structure for the registry file
- *
  * @return A newly allocated char* which must be free()d by the caller.
  *
  * @ingroup regfiBase
  */
-char*                 regfi_get_messages(REGFI_FILE* file);
+char* regfi_log_get_str();
 
 
@@ -865,6 +879,4 @@
  *
  * This may be called at any time and will take effect immediately.
- *
- * @param file   the structure for the registry file
  *
  * @param mask   an integer representing the types of messages desired.
@@ -883,5 +895,14 @@
  * @ingroup regfiBase
  */
-void                  regfi_set_message_mask(REGFI_FILE* file, uint16_t mask);
+void regfi_log_set_mask(uint16_t mask);
+
+
+/** Disables regfi library logging for the current thread.
+ *
+ * XXX: finish documenting
+ *
+ * @ingroup regfiBase
+ */
+void regfi_log_stop();
 
 
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 181)
+++ /trunk/lib/regfi.c	(revision 182)
@@ -45,51 +45,89 @@
 
 
+
 /******************************************************************************
  ******************************************************************************/
-void regfi_add_message(REGFI_FILE* file, uint16_t msg_type, const char* fmt, ...)
-{
-  /* XXX: This function is not particularly efficient,
-   *      but then it is mostly used during errors. 
+void regfi_log_start(uint16_t msg_mask)
+{
+  REGFI_LOG* log_info = talloc(NULL, REGFI_LOG);
+  if(log_info == NULL)
+    return;
+
+  log_info->msg_mask = msg_mask;
+  log_info->messages = NULL;
+
+  /* XXX: Should we bother with a destructor here? */
+  if(pthread_key_create(&REGFI_LOG_KEY, NULL) != 0)
+  {
+    fprintf(stderr, "ERROR: key_create\n");
+    goto fail;
+  }
+
+  if(pthread_setspecific(REGFI_LOG_KEY, log_info) != 0)
+  {
+    fprintf(stderr, "ERROR: setspecific\n");
+    goto fail;
+  }
+
+  return;
+
+ fail:
+  talloc_free(log_info);
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+void regfi_log_add(uint16_t msg_type, const char* fmt, ...)
+{
+  /* XXX: Switch internal storage over to a linked list or stack.
+   *      Then add a regfi_log_get function that returns the list in some
+   *      convenient, user-friendly data structure.  regfi_log_get_str should
+   *      stick around and will simply smush the list into a big string when 
+   *      it's called, rather than having messages smushed when they're first
+   *      written to the log.
    */
   uint32_t buf_size, buf_used;
   char* new_msg;
+  REGFI_LOG* log_info;
   va_list args;
 
-  if((file->msg_mask & msg_type) != 0)
-  {
-    if(file->last_message == NULL)
-      buf_used = 0;
-    else
-      buf_used = strlen(file->last_message);
-    
-    buf_size = buf_used+strlen(fmt)+160;
-    new_msg = realloc(file->last_message, buf_size);
-    if(new_msg == NULL)
-      /* XXX: should we report this? */
-      return;
-
-    switch (msg_type)
-    {
-    case REGFI_MSG_INFO:
-      strcpy(new_msg+buf_used, "INFO: ");
-      buf_used += 6;
-      break;
-    case REGFI_MSG_WARN:
-      strcpy(new_msg+buf_used, "WARN: ");
-      buf_used += 6;
-      break;
-    case REGFI_MSG_ERROR:
-      strcpy(new_msg+buf_used, "ERROR: ");
-      buf_used += 7;
-      break;
-    }
-
-    va_start(args, fmt);
-    vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args);
-    va_end(args);
-    strncat(new_msg, "\n", buf_size-1);
-    
-    file->last_message = new_msg;
-  }
+  log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
+  if(log_info == NULL || (log_info->msg_mask & msg_type) == 0)
+    return;
+
+  if(log_info->messages == NULL)
+    buf_used = 0;
+  else
+    buf_used = strlen(log_info->messages);
+  
+  buf_size = buf_used+strlen(fmt)+160;
+  new_msg = realloc(log_info->messages, buf_size);
+  if(new_msg == NULL)
+    /* XXX: should we report this? */
+    return;
+  
+  switch (msg_type)
+  {
+  case REGFI_LOG_INFO:
+    strcpy(new_msg+buf_used, "INFO: ");
+    buf_used += 6;
+    break;
+  case REGFI_LOG_WARN:
+    strcpy(new_msg+buf_used, "WARN: ");
+    buf_used += 6;
+    break;
+  case REGFI_LOG_ERROR:
+    strcpy(new_msg+buf_used, "ERROR: ");
+    buf_used += 7;
+    break;
+  }
+  
+  va_start(args, fmt);
+  vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args);
+  va_end(args);
+  strncat(new_msg, "\n", buf_size-1);
+  
+  log_info->messages = new_msg;
 }
 
@@ -97,8 +135,13 @@
 /******************************************************************************
  ******************************************************************************/
-char* regfi_get_messages(REGFI_FILE* file)
-{
-  char* ret_val = file->last_message;
-  file->last_message = NULL;
+char* regfi_log_get_str()
+{
+  char* ret_val;
+  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
+  if(log_info == NULL)
+    return NULL;
+
+  ret_val = log_info->messages;
+  log_info->messages = NULL;
 
   return ret_val;
@@ -106,7 +149,29 @@
 
 
-void regfi_set_message_mask(REGFI_FILE* file, uint16_t mask)
-{
-  file->msg_mask = mask;
+/******************************************************************************
+ ******************************************************************************/
+void regfi_log_set_mask(uint16_t msg_mask)
+{
+  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
+  if(log_info == NULL)
+    return;
+
+  log_info->msg_mask = msg_mask;
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+void regfi_log_stop()
+{
+  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
+  if(log_info == NULL)
+    return;
+  
+  if(log_info->messages != NULL)
+    free(log_info->messages);
+
+  pthread_key_delete(REGFI_LOG_KEY);
+  talloc_free(log_info);
 }
 
@@ -427,5 +492,5 @@
   if(lock_ret != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining read lock in"
+    regfi_log_add(REGFI_LOG_ERROR, "Error obtaining read lock in"
 		      "%s due to: %s\n", context, strerror(lock_ret));
     return false;
@@ -441,5 +506,5 @@
   if(lock_ret != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining write lock in"
+    regfi_log_add(REGFI_LOG_ERROR, "Error obtaining write lock in"
 		      "%s due to: %s\n", context, strerror(lock_ret));
     return false;
@@ -455,5 +520,5 @@
   if(lock_ret != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Error releasing lock in"
+    regfi_log_add(REGFI_LOG_ERROR, "Error releasing lock in"
 		      "%s due to: %s\n", context, strerror(lock_ret));
     return false;
@@ -469,5 +534,5 @@
   if(lock_ret != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Error obtaining mutex lock in"
+    regfi_log_add(REGFI_LOG_ERROR, "Error obtaining mutex lock in"
 		      "%s due to: %s\n", context, strerror(lock_ret));
     return false;
@@ -483,5 +548,5 @@
   if(lock_ret != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Error releasing mutex lock in"
+    regfi_log_add(REGFI_LOG_ERROR, "Error releasing mutex lock in"
 		      "%s due to: %s\n", context, strerror(lock_ret));
     return false;
@@ -644,5 +709,5 @@
   if(ret_val == NULL)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Failed to load subkey list at"
+    regfi_log_add(REGFI_LOG_WARN, "Failed to load subkey list at"
 		      " offset 0x%.8X.", offset);
     return NULL;
@@ -655,5 +720,5 @@
      *  now if they don't match.
      */
-    regfi_add_message(file, REGFI_MSG_WARN, "Number of subkeys listed in parent"
+    regfi_log_add(REGFI_LOG_WARN, "Number of subkeys listed in parent"
 		      " (%d) did not match number found in subkey list/tree (%d)"
 		      " while parsing subkey list/tree at offset 0x%.8X.", 
@@ -678,5 +743,5 @@
   if(depth_left == 0)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Maximum depth reached"
+    regfi_log_add(REGFI_LOG_WARN, "Maximum depth reached"
 		      " while parsing subkey list/tree at offset 0x%.8X.", 
 		      offset);
@@ -731,5 +796,5 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while "
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while "
 		      "parsing subkey-list at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -738,5 +803,5 @@
   if(cell_length > max_size)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Cell size longer than max_size"
+    regfi_log_add(REGFI_LOG_WARN, "Cell size longer than max_size"
 		      " while parsing subkey-list at offset 0x%.8X.", offset);
     if(strict)
@@ -757,5 +822,5 @@
   else
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Unknown magic number"
+    regfi_log_add(REGFI_LOG_ERROR, "Unknown magic number"
 		      " (0x%.2X, 0x%.2X) encountered while parsing"
 		      " subkey-list at offset 0x%.8X.", buf[0], buf[1], offset);
@@ -780,5 +845,5 @@
   if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32_t) < length)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Number of elements too large for"
+    regfi_log_add(REGFI_LOG_WARN, "Number of elements too large for"
 		      " cell while parsing subkey-list at offset 0x%.8X.", 
 		      offset);
@@ -907,5 +972,5 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse SK record cell"
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse SK record cell"
 		      " at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -914,5 +979,5 @@
   if(sk_header[0] != 's' || sk_header[1] != 'k')
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"
+    regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch in parsing"
 		      " SK record at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -934,5 +999,5 @@
      || (strict && (ret_val->cell_size & 0x00000007) != 0))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size found while"
+    regfi_log_add(REGFI_LOG_WARN, "Invalid cell size found while"
 		      " parsing SK record at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -951,5 +1016,5 @@
      || (ret_val->next_sk_off & 0x00000007) != 0)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "SK record's next/previous offsets"
+    regfi_log_add(REGFI_LOG_WARN, "SK record's next/previous offsets"
 		      " are not a multiple of 8 while parsing SK record at"
 		      " offset 0x%.8X.", offset);
@@ -959,5 +1024,5 @@
   if(ret_val->desc_size + REGFI_SK_MIN_LENGTH > ret_val->cell_size)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Security descriptor too large for"
+    regfi_log_add(REGFI_LOG_WARN, "Security descriptor too large for"
 		      " cell while parsing SK record at offset 0x%.8X.", 
 		      offset);
@@ -973,5 +1038,5 @@
      || length != ret_val->desc_size)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read security"
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to read security"
 		      " descriptor while parsing SK record at offset 0x%.8X.",
 		      offset);
@@ -985,5 +1050,5 @@
 						   ret_val->desc_size)))
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to parse security"
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to parse security"
 		      " descriptor while parsing SK record at offset 0x%.8X.",
 		      offset);
@@ -1016,5 +1081,5 @@
   if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read cell header"
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to read cell header"
 		      " while parsing value list at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -1023,5 +1088,5 @@
   if((cell_length & 0x00000007) != 0)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Cell length not a multiple of 8"
+    regfi_log_add(REGFI_LOG_WARN, "Cell length not a multiple of 8"
 		      " while parsing value list at offset 0x%.8X.", offset);
     if(strict)
@@ -1032,5 +1097,5 @@
   if((num_values * sizeof(uint32_t)) > cell_length-sizeof(uint32_t))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Too many values found"
+    regfi_log_add(REGFI_LOG_WARN, "Too many values found"
 		      " while parsing value list at offset 0x%.8X.", offset);
     if(strict)
@@ -1054,5 +1119,5 @@
      || length != read_len)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read value pointers"
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to read value pointers"
 		      " while parsing value list at offset 0x%.8X.", offset);
     goto fail_locked;
@@ -1075,5 +1140,5 @@
 	 || ((ret_val->elements[i] & 0x00000007) != 0))
       {
-	regfi_add_message(file, REGFI_MSG_WARN, "Invalid value pointer"
+	regfi_log_add(REGFI_LOG_WARN, "Invalid value pointer"
 			  " (0x%.8X) found while parsing value list at offset"
 			  " 0x%.8X.", ret_val->elements[i], offset);
@@ -1130,5 +1195,5 @@
     if(tmp_size < 0)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Error occurred while converting"
+      regfi_log_add(REGFI_LOG_WARN, "Error occurred while converting"
 			" valuename to encoding %s.  Error message: %s",
 			regfi_encoding_int2str(output_encoding), 
@@ -1174,5 +1239,5 @@
   if((num_values+1) * sizeof(uint32_t) > max_size)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Number of values indicated by"
+    regfi_log_add(REGFI_LOG_WARN, "Number of values indicated by"
 		      " parent key (%d) would cause cell to straddle HBIN"
 		      " boundary while loading value list at offset"
@@ -1224,5 +1289,5 @@
     if(tmp_size < 0)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Error occurred while converting"
+      regfi_log_add(REGFI_LOG_WARN, "Error occurred while converting"
 			" keyname to encoding %s.  Error message: %s",
 			regfi_encoding_int2str(output_encoding), 
@@ -1252,6 +1317,6 @@
   if((nk = regfi_parse_nk(file, offset, max_size, true)) == NULL)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Could not load NK record at"
-		      " offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Could not load NK record at"
+		  " offset 0x%.8X.", offset);
     return NULL;
   }
@@ -1281,6 +1346,6 @@
       if(nk->values == NULL)
       {
-	regfi_add_message(file, REGFI_MSG_WARN, "Could not load value list"
-			  " for NK record at offset 0x%.8X.", offset);
+	regfi_log_add(REGFI_LOG_WARN, "Could not load value list"
+		      " for NK record at offset 0x%.8X.", offset);
 	if(strict)
 	{
@@ -1315,6 +1380,6 @@
       if(nk->subkeys == NULL)
       {
-	regfi_add_message(file, REGFI_MSG_WARN, "Could not load subkey list"
-			  " while parsing NK record at offset 0x%.8X.", offset);
+	regfi_log_add(REGFI_LOG_WARN, "Could not load subkey list"
+		      " while parsing NK record at offset 0x%.8X.", offset);
 	nk->num_subkeys = 0;
       }
@@ -1392,6 +1457,6 @@
     if(!regfi_parse_cell(file->cb, cur_offset, NULL, 0, &cell_length, &unalloc))
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell at offset"
-			" 0x%.8X while searching for root key.", cur_offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not parse cell at offset"
+		    " 0x%.8X while searching for root key.", cur_offset);
       return NULL;
     }
@@ -1465,11 +1530,15 @@
   file_length = file_cb->seek(file_cb, 0, SEEK_END);
   if(file_length < REGFI_REGF_SIZE+REGFI_HBIN_ALLOC)
-    return NULL;
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "File length (%d) too short to contain a"
+		  " header and at least one HBIN.", file_length);
+    return NULL;
+  }
   file_cb->seek(file_cb, 0, SEEK_SET);
 
   /* Read file header */
-  if ((rb = regfi_parse_regf(file_cb, true)) == NULL) 
-  {
-    /* fprintf(stderr, "regfi_alloc_cb: Failed to read initial REGF block\n");*/
+  if ((rb = regfi_parse_regf(file_cb, false)) == NULL) 
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to read REGF block.");
     return NULL;
   }
@@ -1482,17 +1551,29 @@
   rb->cb_lock = talloc(rb, pthread_mutex_t);
   if(rb->cb_lock == NULL || pthread_mutex_init(rb->cb_lock, NULL) != 0)
-    goto fail;
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to create cb_lock mutex.");
+    goto fail;
+  }
 
   rb->hbins_lock = talloc(rb, pthread_rwlock_t);
   if(rb->hbins_lock == NULL || pthread_rwlock_init(rb->hbins_lock, NULL) != 0)
-    goto fail;
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to create hbins_lock rwlock.");
+    goto fail;
+  }
 
   rb->sk_lock = talloc(rb, pthread_mutex_t);
   if(rb->sk_lock == NULL || pthread_mutex_init(rb->sk_lock, NULL) != 0)
-    goto fail;
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to create sk_lock mutex.");
+    goto fail;
+  }
 
   rb->hbins = range_list_new();
   if(rb->hbins == NULL)
-    goto fail;
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to create HBIN range_list.");
+    goto fail;
+  }
   talloc_steal(rb, rb->hbins);
 
@@ -1518,7 +1599,4 @@
   /* Cache an unlimited number of SK records.  Typically there are very few. */
   rb->sk_cache = lru_cache_create_ctx(rb, 0, cache_secret, true);
-
-  /* Default message mask */
-  rb->msg_mask = REGFI_MSG_ERROR|REGFI_MSG_WARN;
 
   /* success */
@@ -1545,7 +1623,4 @@
 void regfi_free(REGFI_FILE *file)
 {
-  if(file->last_message != NULL)
-    free(file->last_message);
-
   pthread_mutex_destroy(file->cb_lock);
   pthread_rwlock_destroy(file->hbins_lock);
@@ -1576,7 +1651,7 @@
   }
 
-  regfi_add_message(file, REGFI_MSG_WARN, "File header indicated root key at"
-		    " location 0x%.8X, but no root key found."
-		    " Searching rest of file...", root_offset);
+  regfi_log_add(REGFI_LOG_WARN, "File header indicated root key at"
+		" location 0x%.8X, but no root key found."
+		" Searching rest of file...", root_offset);
   
   /* If the file header gives bad info, scan through the file one HBIN
@@ -1640,6 +1715,6 @@
      && output_encoding != REGFI_ENCODING_ASCII)
   { 
-    regfi_add_message(file, REGFI_MSG_ERROR, "Invalid output_encoding supplied"
-		      " in creation of regfi iterator.");
+    regfi_log_add(REGFI_LOG_ERROR, "Invalid output_encoding supplied"
+		  " in creation of regfi iterator.");
     return NULL;
   }
@@ -1984,7 +2059,7 @@
   if(raw == NULL)
   {
-    regfi_add_message(i->f, REGFI_MSG_WARN, "Could not parse class"
-		      " name at offset 0x%.8X for key record at offset 0x%.8X.",
-		      offset, key->offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse class"
+		  " name at offset 0x%.8X for key record at offset 0x%.8X.",
+		  offset, key->offset);
     return NULL;
   }
@@ -2006,7 +2081,7 @@
   if(conv_size < 0)
   {
-    regfi_add_message(i->f, REGFI_MSG_WARN, "Error occurred while"
-		      " converting classname to charset %s.  Error message: %s",
-		      i->string_encoding, strerror(-conv_size));
+    regfi_log_add(REGFI_LOG_WARN, "Error occurred while"
+		  " converting classname to charset %s.  Error message: %s",
+		  i->string_encoding, strerror(-conv_size));
     talloc_free(interpreted);
     ret_val->interpreted = NULL;
@@ -2037,7 +2112,7 @@
     if(raw_data.buf == NULL)
     {
-      regfi_add_message(i->f, REGFI_MSG_WARN, "Could not parse data record"
-			" while parsing VK record at offset 0x%.8X.",
-			value->offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not parse data record"
+		    " while parsing VK record at offset 0x%.8X.",
+		    value->offset);
     }
     else
@@ -2047,8 +2122,8 @@
       if(ret_val == NULL)
       {
-	regfi_add_message(i->f, REGFI_MSG_WARN, "Error occurred in converting"
-			  " data buffer to data structure while interpreting "
-			  "data for VK record at offset 0x%.8X.",
-			  value->offset);
+	regfi_log_add(REGFI_LOG_WARN, "Error occurred in converting"
+		      " data buffer to data structure while interpreting "
+		      "data for VK record at offset 0x%.8X.",
+		      value->offset);
 	talloc_free(raw_data.buf);
 	return NULL;
@@ -2057,7 +2132,7 @@
       if(!regfi_interpret_data(i->f, i->string_encoding, value->type, ret_val))
       {
-	regfi_add_message(i->f, REGFI_MSG_INFO, "Error occurred while"
-			  " interpreting data for VK record at offset 0x%.8X.",
-			  value->offset);
+	regfi_log_add(REGFI_LOG_INFO, "Error occurred while"
+		      " interpreting data for VK record at offset 0x%.8X.",
+		      value->offset);
       }
     }
@@ -2139,7 +2214,7 @@
     if(tmp_size < 0)
     {
-      regfi_add_message(file, REGFI_MSG_INFO, "Error occurred while"
-			" converting data of type %d to %s.  Error message: %s",
-			type, string_encoding, strerror(-tmp_size));
+      regfi_log_add(REGFI_LOG_INFO, "Error occurred while"
+		    " converting data of type %d to %s.  Error message: %s",
+		    type, string_encoding, strerror(-tmp_size));
       talloc_free(tmp_str);
       data->interpreted.string = NULL;
@@ -2206,7 +2281,7 @@
     if(tmp_size < 0)
     {
-      regfi_add_message(file, REGFI_MSG_INFO, "Error occurred while"
-			" converting data of type %d to %s.  Error message: %s",
-			type, string_encoding, strerror(-tmp_size));
+      regfi_log_add(REGFI_LOG_INFO, "Error occurred while"
+		    " converting data of type %d to %s.  Error message: %s",
+		    type, string_encoding, strerror(-tmp_size));
       talloc_free(tmp_str);
       data->interpreted.multiple_string = NULL;
@@ -2337,5 +2412,4 @@
 
 /*******************************************************************
- * XXX: Add way to return more detailed error information.
  *******************************************************************/
 REGFI_FILE* regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict)
@@ -2350,5 +2424,4 @@
 
   ret_val->sk_cache = NULL;
-  ret_val->last_message = NULL;
   ret_val->hbins = NULL;
 
@@ -2356,20 +2429,28 @@
   if((regfi_read(file_cb, file_header, &length)) != 0 
      || length != REGFI_REGF_SIZE)
-    goto fail;
-  
+  {
+    regfi_log_add(REGFI_LOG_WARN, "Read failed while parsing REGF structure.");
+    goto fail;
+  }
+
   ret_val->checksum = IVAL(file_header, 0x1FC);
   ret_val->computed_checksum = regfi_compute_header_checksum(file_header);
   if (strict && (ret_val->checksum != ret_val->computed_checksum))
-    goto fail;
+  {
+    regfi_log_add(REGFI_LOG_WARN, "Stored header checksum (%.8X) did not equal"
+		  " computed checksum (%.8X).",
+		  ret_val->checksum, ret_val->computed_checksum);
+    if(strict)
+      goto fail;
+  }
 
   memcpy(ret_val->magic, file_header, REGFI_REGF_MAGIC_SIZE);
   if(memcmp(ret_val->magic, "regf", REGFI_REGF_MAGIC_SIZE) != 0)
   {
-    if(strict)
-      goto fail;
-    regfi_add_message(ret_val, REGFI_MSG_WARN, "Magic number mismatch "
-		      "(%.2X %.2X %.2X %.2X) while parsing hive header",
-		      ret_val->magic[0], ret_val->magic[1], 
-		      ret_val->magic[2], ret_val->magic[3]);
+    regfi_log_add(REGFI_LOG_ERROR, "Magic number mismatch "
+		  "(%.2X %.2X %.2X %.2X) while parsing hive header",
+		  ret_val->magic[0], ret_val->magic[1], 
+		  ret_val->magic[2], ret_val->magic[3]);
+    goto fail;
   }
 
@@ -2384,5 +2465,4 @@
   ret_val->root_cell = IVAL(file_header, 0x24);
   ret_val->last_block = IVAL(file_header, 0x28);
-
   ret_val->cluster = IVAL(file_header, 0x2C);
 
@@ -2432,6 +2512,6 @@
   if(regfi_seek(file->cb, offset, SEEK_SET) == -1)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
-		      " while parsing hbin at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Seek failed"
+		  " while parsing hbin at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2440,5 +2520,9 @@
   if((regfi_read(file->cb, hbin_header, &length) != 0) 
      || length != REGFI_HBIN_HEADER_SIZE)
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Read failed"
+		  " while parsing hbin at offset 0x%.8X.", offset);
     goto fail_locked;
+  }
 
   if(!regfi_unlock(file, file->cb_lock, "regfi_parse_hbin"))
@@ -2453,8 +2537,11 @@
   if(strict && (memcmp(hbin->magic, "hbin", 4) != 0))
   {
-    regfi_add_message(file, REGFI_MSG_INFO, "Magic number mismatch "
-		      "(%.2X %.2X %.2X %.2X) while parsing hbin at offset"
-		      " 0x%.8X.", hbin->magic[0], hbin->magic[1], 
-		      hbin->magic[2], hbin->magic[3], offset);
+    /* This always seems to happen at the end of a file, so we make it an INFO
+     * message, rather than something more serious.
+     */
+    regfi_log_add(REGFI_LOG_INFO, "Magic number mismatch "
+		  "(%.2X %.2X %.2X %.2X) while parsing hbin at offset"
+		  " 0x%.8X.", hbin->magic[0], hbin->magic[1], 
+		  hbin->magic[2], hbin->magic[3], offset);
     goto fail;
   }
@@ -2462,5 +2549,5 @@
   hbin->first_hbin_off = IVAL(hbin_header, 0x4);
   hbin->block_size = IVAL(hbin_header, 0x8);
-  /* this should be the same thing as hbin->block_size but just in case */
+  /* this should be the same thing as hbin->block_size, but just in case */
   hbin->next_block = IVAL(hbin_header, 0x1C);
 
@@ -2475,7 +2562,7 @@
      || (hbin->block_size & 0xFFFFF000) != hbin->block_size)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "The hbin offset is not aligned"
-		      " or runs off the end of the file"
-		      " while parsing hbin at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "The hbin offset is not aligned"
+		  " or runs off the end of the file"
+		  " while parsing hbin at offset 0x%.8X.", offset);
     goto fail;
   }
@@ -2504,6 +2591,6 @@
   if(ret_val == NULL)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to allocate memory while"
-		      " parsing NK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to allocate memory while"
+		  " parsing NK record at offset 0x%.8X.", offset);
     goto fail;
   }
@@ -2515,6 +2602,6 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
-		      " while parsing NK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header"
+		  " while parsing NK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2522,6 +2609,6 @@
   if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k'))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"
-		      " NK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch in parsing"
+		  " NK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2537,6 +2624,6 @@
      || (strict && (ret_val->cell_size & 0x00000007) != 0))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "A length check failed while"
-		      " parsing NK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "A length check failed while"
+		  " parsing NK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2548,7 +2635,7 @@
   if((ret_val->flags & ~REGFI_NK_KNOWN_FLAGS) != 0)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Unknown key flags (0x%.4X) while"
-		      " parsing NK record at offset 0x%.8X.", 
-		      (ret_val->flags & ~REGFI_NK_KNOWN_FLAGS), offset);
+    regfi_log_add(REGFI_LOG_WARN, "Unknown key flags (0x%.4X) while"
+		  " parsing NK record at offset 0x%.8X.", 
+		  (ret_val->flags & ~REGFI_NK_KNOWN_FLAGS), offset);
   }
 
@@ -2589,6 +2676,6 @@
     if(strict)
     {
-      regfi_add_message(file, REGFI_MSG_ERROR, "Contents too large for cell"
-			" while parsing NK record at offset 0x%.8X.", offset);
+      regfi_log_add(REGFI_LOG_ERROR, "Contents too large for cell"
+		    " while parsing NK record at offset 0x%.8X.", offset);
       goto fail_locked;
     }
@@ -2617,6 +2704,6 @@
      || length != ret_val->name_length)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read key name"
-		      " while parsing NK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to read key name"
+		  " while parsing NK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2652,6 +2739,6 @@
   if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
-		      " while parsing class name at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header"
+		  " while parsing class name at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2659,6 +2746,6 @@
   if((cell_length & 0x0000007) != 0)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Cell length not a multiple of 8"
-		      " while parsing class name at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Cell length not a multiple of 8"
+		  " while parsing class name at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2666,7 +2753,7 @@
   if(cell_length > max_size)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Cell stretches past hbin "
-		      "boundary while parsing class name at offset 0x%.8X.",
-		      offset);
+    regfi_log_add(REGFI_LOG_WARN, "Cell stretches past hbin "
+		  "boundary while parsing class name at offset 0x%.8X.",
+		  offset);
     if(strict)
       goto fail_locked;
@@ -2676,7 +2763,7 @@
   if((cell_length - 4) < *name_length)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Class name is larger than"
-		      " cell_length while parsing class name at offset"
-		      " 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Class name is larger than"
+		  " cell_length while parsing class name at offset"
+		  " 0x%.8X.", offset);
     if(strict)
       goto fail_locked;
@@ -2691,6 +2778,6 @@
        || length != *name_length)
     {
-      regfi_add_message(file, REGFI_MSG_ERROR, "Could not read class name"
-			" while parsing class name at offset 0x%.8X.", offset);
+      regfi_log_add(REGFI_LOG_ERROR, "Could not read class name"
+		    " while parsing class name at offset 0x%.8X.", offset);
       goto fail_locked;
     }
@@ -2730,6 +2817,6 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
-		      " while parsing VK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header"
+		  " while parsing VK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2745,6 +2832,6 @@
      || (ret_val->cell_size & 0x00000007) != 0)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size encountered"
-		      " while parsing VK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Invalid cell size encountered"
+		  " while parsing VK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2758,6 +2845,6 @@
      *      0xFFFF. 
      */
-    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch"
-		      " while parsing VK record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch"
+		  " while parsing VK record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2779,7 +2866,7 @@
     if(ret_val->name_length + REGFI_VK_MIN_LENGTH + 4 > ret_val->cell_size)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Name too long for remaining cell"
-			" space while parsing VK record at offset 0x%.8X.",
-			offset);
+      regfi_log_add(REGFI_LOG_WARN, "Name too long for remaining cell"
+		    " space while parsing VK record at offset 0x%.8X.",
+		    offset);
       if(strict)
 	goto fail_locked;
@@ -2801,6 +2888,6 @@
        || length != ret_val->name_length)
     {
-      regfi_add_message(file, REGFI_MSG_ERROR, "Could not read value name"
-			" while parsing VK record at offset 0x%.8X.", offset);
+      regfi_log_add(REGFI_LOG_ERROR, "Could not read value name"
+		    " while parsing VK record at offset 0x%.8X.", offset);
       goto fail_locked;
     }
@@ -2856,6 +2943,6 @@
   if(length > REGFI_VK_MAX_DATA_LENGTH)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Value data size %d larger than "
-		      "%d, truncating...", length, REGFI_VK_MAX_DATA_LENGTH);
+    regfi_log_add(REGFI_LOG_WARN, "Value data size %d larger than "
+		  "%d, truncating...", length, REGFI_VK_MAX_DATA_LENGTH);
     length = REGFI_VK_MAX_DATA_LENGTH;
   }
@@ -2869,6 +2956,6 @@
     if(max_size < 0)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not find HBIN for data"
-			" at offset 0x%.8X.", offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not find HBIN for data"
+		    " at offset 0x%.8X.", offset);
       goto fail;
     }
@@ -2880,6 +2967,6 @@
 			 &cell_length, &unalloc))
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
-			" parsing data record at offset 0x%.8X.", offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while"
+		    " parsing data record at offset 0x%.8X.", offset);
       goto fail_locked;
     }
@@ -2890,7 +2977,7 @@
     if((cell_length & 0x00000007) != 0)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Cell length not multiple of 8"
-			" while parsing data record at offset 0x%.8X.",
-			offset);
+      regfi_log_add(REGFI_LOG_WARN, "Cell length not multiple of 8"
+		    " while parsing data record at offset 0x%.8X.",
+		    offset);
       goto fail;
     }
@@ -2898,7 +2985,7 @@
     if(cell_length > max_size)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Cell extends past HBIN boundary"
-			" while parsing data record at offset 0x%.8X.",
-			offset);
+      regfi_log_add(REGFI_LOG_WARN, "Cell extends past HBIN boundary"
+		    " while parsing data record at offset 0x%.8X.",
+		    offset);
       goto fail;
     }
@@ -2918,8 +3005,8 @@
       else
       {
-	regfi_add_message(file, REGFI_MSG_WARN, "Data length (0x%.8X) larger than"
-			  " remaining cell length (0x%.8X)"
-			  " while parsing data record at offset 0x%.8X.", 
-			  length, cell_length - 4, offset);
+	regfi_log_add(REGFI_LOG_WARN, "Data length (0x%.8X) larger than"
+		      " remaining cell length (0x%.8X)"
+		      " while parsing data record at offset 0x%.8X.", 
+		      length, cell_length - 4, offset);
 	if(strict)
 	  goto fail;
@@ -2964,6 +3051,6 @@
   if(regfi_seek(file->cb, offset+4, SEEK_SET) == -1)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not seek while "
-		      "reading data at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not seek while "
+		  "reading data at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -2973,6 +3060,6 @@
      || read_length != length)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Could not read data block while"
-		      " parsing data record at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_ERROR, "Could not read data block while"
+		  " parsing data record at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -3008,7 +3095,7 @@
   if(length > 4)
   {
-    regfi_add_message(file, REGFI_MSG_ERROR, "Data in offset but length > 4"
-		      " while parsing data record. (voffset=0x%.8X, length=%d)",
-		      voffset, length);
+    regfi_log_add(REGFI_LOG_ERROR, "Data in offset but length > 4"
+		  " while parsing data record. (voffset=0x%.8X, length=%d)",
+		  voffset, length);
     return ret_val;
   }
@@ -3040,6 +3127,6 @@
   if(REGFI_BIG_DATA_MIN_LENGTH > max_size)
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Big data header exceeded max_size "
-		      "while parsing big data header at offset 0x%.8X.",offset);
+    regfi_log_add(REGFI_LOG_WARN, "Big data header exceeded max_size "
+		  "while parsing big data header at offset 0x%.8X.",offset);
     goto fail;
   }
@@ -3052,6 +3139,6 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
-		      " parsing big data header at offset 0x%.8X.", offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while"
+		  " parsing big data header at offset 0x%.8X.", offset);
     goto fail_locked;
   }
@@ -3062,8 +3149,8 @@
   if((ret_val.buf[0] != 'd') || (ret_val.buf[1] != 'b'))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Unknown magic number"
-		      " (0x%.2X, 0x%.2X) encountered while parsing"
-		      " big data header at offset 0x%.8X.", 
-		      ret_val.buf[0], ret_val.buf[1], offset);
+    regfi_log_add(REGFI_LOG_WARN, "Unknown magic number"
+		  " (0x%.2X, 0x%.2X) encountered while parsing"
+		  " big data header at offset 0x%.8X.", 
+		  ret_val.buf[0], ret_val.buf[1], offset);
     goto fail;
   }
@@ -3112,7 +3199,7 @@
 		       &indirect_length, &unalloc))
   {
-    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
-		      " parsing big data indirect record at offset 0x%.8X.", 
-		      offset);
+    regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while"
+		  " parsing big data indirect record at offset 0x%.8X.", 
+		  offset);
     goto fail_locked;
   }
@@ -3173,7 +3260,7 @@
 			 &cell_length, &unalloc))
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
-			" parsing big data chunk at offset 0x%.8X.", 
-			chunk_offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while"
+		    " parsing big data chunk at offset 0x%.8X.", 
+		    chunk_offset);
       goto fail_locked;
     }
@@ -3265,7 +3352,7 @@
       if(i+1 != num_chunks)
       {
-	regfi_add_message(file, REGFI_MSG_WARN, "Left over chunks detected "
-			  "while constructing big data at offset 0x%.8X "
-			  "(chunk offset 0x%.8X).", offset, cell_info->offset);
+	regfi_log_add(REGFI_LOG_WARN, "Left over chunks detected "
+		      "while constructing big data at offset 0x%.8X "
+		      "(chunk offset 0x%.8X).", offset, cell_info->offset);
       }
       read_length = data_left;
@@ -3277,7 +3364,7 @@
     if(read_length > regfi_calc_maxsize(file, cell_info->offset))
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "A chunk exceeded the maxsize "
-			"while constructing big data at offset 0x%.8X "
-			"(chunk offset 0x%.8X).", offset, cell_info->offset);
+      regfi_log_add(REGFI_LOG_WARN, "A chunk exceeded the maxsize "
+		    "while constructing big data at offset 0x%.8X "
+		    "(chunk offset 0x%.8X).", offset, cell_info->offset);
       goto fail;
     }
@@ -3288,7 +3375,7 @@
     if(regfi_seek(file->cb, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1)
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not seek to chunk while "
-			"constructing big data at offset 0x%.8X "
-			"(chunk offset 0x%.8X).", offset, cell_info->offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not seek to chunk while "
+		    "constructing big data at offset 0x%.8X "
+		    "(chunk offset 0x%.8X).", offset, cell_info->offset);
       goto fail_locked;
     }
@@ -3298,7 +3385,7 @@
 		  &read_length) != 0 || (read_length != tmp_len))
     {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not read data chunk while"
-			" constructing big data at offset 0x%.8X"
-			" (chunk offset 0x%.8X).", offset, cell_info->offset);
+      regfi_log_add(REGFI_LOG_WARN, "Could not read data chunk while"
+		    " constructing big data at offset 0x%.8X"
+		    " (chunk offset 0x%.8X).", offset, cell_info->offset);
       goto fail_locked;
     }
@@ -3375,7 +3462,7 @@
       if((cell_len == 0) || ((cell_len & 0x00000007) != 0))
       {
-	regfi_add_message(file, REGFI_MSG_ERROR, "Bad cell length encountered"
-			  " while parsing unallocated cells at offset 0x%.8X.",
-			  hbin->file_off+curr_off);
+	regfi_log_add(REGFI_LOG_ERROR, "Bad cell length encountered"
+		      " while parsing unallocated cells at offset 0x%.8X.",
+		      hbin->file_off+curr_off);
 	break;
       }
Index: /trunk/src/common.c
===================================================================
--- /trunk/src/common.c	(revision 181)
+++ /trunk/src/common.c	(revision 182)
@@ -29,5 +29,5 @@
 const char* common_special_chars = ",\"\\";
 
-#define REGLOOKUP_VERSION "0.12.0"
+#define REGLOOKUP_VERSION "0.1?.0"
 
 #define REGLOOKUP_EXIT_OK       0
@@ -49,10 +49,11 @@
 {
   fprintf(stderr, message);
+  regfi_log_stop();
   exit(code);
 }
 
-void printMsgs(REGFI_FILE* f)
-{
-  char* msgs = regfi_get_messages(f);
+void printMsgs()
+{
+  char* msgs = regfi_log_get_str();
   if(msgs != NULL)
   {
@@ -62,7 +63,7 @@
 }
 
-void clearMsgs(REGFI_FILE* f)
-{
-  char* msgs = regfi_get_messages(f);
+void clearMsgs()
+{
+  char* msgs = regfi_log_get_str();
   if(msgs != NULL)
     free(msgs);
Index: /trunk/src/reglookup-recover.c
===================================================================
--- /trunk/src/reglookup-recover.c	(revision 181)
+++ /trunk/src/reglookup-recover.c	(revision 182)
@@ -827,4 +827,9 @@
   }
 
+  if(print_verbose)
+    regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN|REGFI_LOG_INFO);
+  else
+    regfi_log_start(REGFI_LOG_ERROR);
+
   f = regfi_alloc(fd);
   if(f == NULL)
@@ -833,9 +838,4 @@
     bailOut(REGLOOKUP_EXIT_NOINPUT, "ERROR: Failed to create REGFI_FILE structure.\n");
   }
-
-  if(print_verbose)
-    regfi_set_message_mask(f, REGFI_MSG_ERROR|REGFI_MSG_WARN|REGFI_MSG_INFO);
-  else
-    regfi_set_message_mask(f, REGFI_MSG_ERROR);
 
   if(print_header)
@@ -994,4 +994,5 @@
 
   regfi_free(f);
+  regfi_log_stop();
   close(fd);
 
Index: /trunk/src/reglookup.c
===================================================================
--- /trunk/src/reglookup.c	(revision 181)
+++ /trunk/src/reglookup.c	(revision 182)
@@ -619,4 +619,9 @@
   registry_file = argv[argi];
 
+  if(print_verbose)
+    regfi_log_start(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
+  else
+    regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN);
+
   fd = openHive(registry_file);
   if(fd < 0)
@@ -625,5 +630,5 @@
     bailOut(REGLOOKUP_EXIT_NOINPUT, "");
   }
-
+    
   f = regfi_alloc(fd);
   if(f == NULL)
@@ -633,6 +638,4 @@
   }
 
-  if(print_verbose)
-    regfi_set_message_mask(f, REGFI_MSG_INFO|REGFI_MSG_WARN|REGFI_MSG_ERROR);
 
   /* XXX: add command line option to choose output encoding */
@@ -678,4 +681,5 @@
   regfi_iterator_free(iter);
   regfi_free(f);
+  regfi_log_stop();
   close(fd);
 
