Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 159)
+++ /trunk/include/regfi.h	(revision 160)
@@ -251,4 +251,17 @@
 
 
+typedef struct _regfi_classname
+{
+  /* As converted to requested character encoding. */
+  char* interpreted;
+
+  /* Represents raw buffer read from classname cell. */
+  uint8* raw;
+
+  /* Length of the raw data. May be shorter than that indicated by parent key.*/
+  uint16 size;
+} REGFI_CLASSNAME;
+
+
 typedef struct _regfi_data
 {
@@ -299,4 +312,5 @@
 
   char*  valuename;
+  uint8* valuename_raw;
   uint16 name_length;
   uint32 hbin_off;	/* offset from beginning of this hbin block */
@@ -351,6 +365,6 @@
   uint16 name_length;
   uint16 classname_length;
-  char* classname;
   char* keyname;
+  uint8* keyname_raw;
   uint32 parent_off;	            /* pointer to parent key */
   uint32 classname_off;
@@ -554,4 +568,6 @@
 						const char* value_name);
 
+REGFI_CLASSNAME*      regfi_iterator_fetch_classname(REGFI_ITERATOR* i, 
+						     const REGFI_NK_REC* key);
 REGFI_DATA*           regfi_iterator_fetch_data(REGFI_ITERATOR* i, 
 						const REGFI_VK_REC* value);
@@ -583,5 +599,7 @@
 					   const char* string_encoding,
 					   uint32 type, REGFI_DATA* data);
+void                  regfi_free_classname(REGFI_CLASSNAME* classname);
 void                  regfi_free_data(REGFI_DATA* data);
+
 
 /* These are cached so return values don't need to be freed. */
@@ -628,5 +646,5 @@
 				       uint32* cell_length, bool* unalloc);
 
-char*                 regfi_parse_classname(REGFI_FILE* file, uint32 offset,
+uint8*                regfi_parse_classname(REGFI_FILE* file, uint32 offset,
 					    uint16* name_length, 
 					    uint32 max_size, bool strict);
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 159)
+++ /trunk/lib/regfi.c	(revision 160)
@@ -1086,33 +1086,4 @@
   }
 
-  /* Get classname if it exists */
-  if(nk->classname_off != REGFI_OFFSET_NONE)
-  {
-    off = nk->classname_off + REGFI_REGF_SIZE;
-    max_size = regfi_calc_maxsize(file, off);
-    if(max_size >= 0)
-    {
-      nk->classname
-	= regfi_parse_classname(file, off, &nk->classname_length, 
-				max_size, strict);
-    }
-    else
-    {
-      nk->classname = NULL;
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not find hbin for class"
-			" name while parsing NK record at offset 0x%.8X.", 
-			offset);
-    }
-
-    if(nk->classname == NULL)
-    {
-      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse class"
-			" name while parsing NK record at offset 0x%.8X.", 
-			offset);
-    }
-    else
-      talloc_steal(nk, nk->classname);
-  }
-
   return nk;
 }
@@ -1685,4 +1656,67 @@
 /******************************************************************************
  *****************************************************************************/
+REGFI_CLASSNAME* regfi_iterator_fetch_classname(REGFI_ITERATOR* i, 
+						const REGFI_NK_REC* key)
+{
+  REGFI_CLASSNAME* ret_val;
+  uint8* raw;
+  char* interpreted;
+  uint32 offset;
+  int32 conv_size, max_size;
+  uint16 parse_length;
+
+  if(key->classname_off == REGFI_OFFSET_NONE || key->classname_length == 0)
+    return NULL;
+
+  offset = key->classname_off + REGFI_REGF_SIZE;
+  max_size = regfi_calc_maxsize(i->f, offset);
+  if(max_size <= 0)
+    return NULL;
+
+  parse_length = key->classname_length;
+  raw = regfi_parse_classname(i->f, offset, &parse_length, max_size, true);
+  
+  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);
+    return NULL;
+  }
+
+  ret_val = talloc(NULL, REGFI_CLASSNAME);
+  if(ret_val == NULL)
+    return NULL;
+
+  ret_val->raw = raw;
+  ret_val->size = parse_length;
+  talloc_steal(ret_val, raw);
+
+  interpreted = talloc_array(NULL, char, parse_length);
+
+  conv_size = regfi_conv_charset(i->string_encoding, 
+				 raw, interpreted,
+				 parse_length, parse_length);
+  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));
+    talloc_free(interpreted);
+    ret_val->interpreted = NULL;
+  }
+  else
+  {
+    interpreted = talloc_realloc(NULL, interpreted, char, conv_size);
+    ret_val->interpreted = interpreted;
+    talloc_steal(ret_val, interpreted);
+  }
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ *****************************************************************************/
 REGFI_DATA* regfi_iterator_fetch_data(REGFI_ITERATOR* i, 
 				      const REGFI_VK_REC* value)
@@ -1727,4 +1761,11 @@
 }
 
+
+/******************************************************************************
+ *****************************************************************************/
+void regfi_free_classname(REGFI_CLASSNAME* classname)
+{
+  talloc_free(classname);
+}
 
 /******************************************************************************
@@ -2275,8 +2316,8 @@
 
 
-char* regfi_parse_classname(REGFI_FILE* file, uint32 offset, 
-			    uint16* name_length, uint32 max_size, bool strict)
-{
-  char* ret_val = NULL;
+uint8* regfi_parse_classname(REGFI_FILE* file, uint32 offset, 
+			     uint16* name_length, uint32 max_size, bool strict)
+{
+  uint8* ret_val = NULL;
   uint32 length;
   uint32 cell_length;
@@ -2320,9 +2361,9 @@
     }
     
-    ret_val = talloc_array(NULL, char, *name_length);
+    ret_val = talloc_array(NULL, uint8, *name_length);
     if(ret_val != NULL)
     {
       length = *name_length;
-      if((regfi_read(file->fd, (uint8*)ret_val, &length) != 0)
+      if((regfi_read(file->fd, ret_val, &length) != 0)
 	 || length != *name_length)
       {
@@ -2475,18 +2516,11 @@
    *   http://msdn2.microsoft.com/en-us/library/ms724872.aspx
    */
-  /*
-XXX
-  if(size > REGFI_VK_MAX_DATA_LENGTH)
-  {
-    *error_msg = (char*)malloc(82);
-    if(*error_msg == NULL)
-      return NULL;
-    
-    sprintf(*error_msg, "WARN: value data size %d larger than "
-	    "%d, truncating...", size, REGFI_VK_MAX_DATA_LENGTH);
-    size = REGFI_VK_MAX_DATA_LENGTH;
-  }
-
-  */
+  /* XXX: add way to skip this check at user discression. */
+  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);
+    length = REGFI_VK_MAX_DATA_LENGTH;
+  }
 
   if(data_in_offset)
Index: /trunk/src/common.c
===================================================================
--- /trunk/src/common.c	(revision 159)
+++ /trunk/src/common.c	(revision 160)
@@ -145,78 +145,4 @@
 
 /*
- * Convert from UTF-16LE to ASCII.  Accepts a Unicode buffer, uni, and
- * it's length, uni_max.  Writes ASCII to the buffer ascii, whose size
- * is ascii_max.  Writes at most (ascii_max-1) bytes to ascii, and null
- * terminates the string.  Returns the length of the data written to
- * ascii.  On error, returns a negative errno code.
- */
-static int uni_to_ascii(unsigned char* uni, char* ascii, 
-			uint32 uni_max, uint32 ascii_max)
-{
-  char* inbuf = (char*)uni;
-  char* outbuf = ascii;
-  size_t in_len = (size_t)uni_max;
-  size_t out_len = (size_t)(ascii_max-1);
-  int ret;
-
-  conv_desc = iconv_open("US-ASCII//TRANSLIT", "UTF-16LE");
-
-  ret = iconv(conv_desc, &inbuf, &in_len, &outbuf, &out_len);
-  if(ret == -1)
-  {
-    iconv_close(conv_desc);
-    return -errno;
-  }
-  *outbuf = '\0';
-
-  iconv_close(conv_desc);  
-  return ascii_max-out_len-1;
-}
-
-
-static char* quote_unicode(unsigned char* uni, uint32 length, 
-			   const char* special, char** error_msg)
-{
-  char* ret_val;
-  char* ascii = NULL;
-  char* tmp_err;
-  int ret_err;
-  *error_msg = NULL;
-
-  if(length+1 > 0)
-    ascii = malloc(length+1);
-  if(ascii == NULL)
-  {
-    *error_msg = (char*)malloc(27);
-    if(*error_msg == NULL)
-      return NULL;
-    strcpy(*error_msg, "Memory allocation failure.");
-    return NULL;
-  }
-  
-  ret_err = uni_to_ascii(uni, ascii, length, length+1);
-  if(ret_err < 0)
-  {
-    free(ascii);
-    tmp_err = strerror(-ret_err);
-    *error_msg = (char*)malloc(61+strlen(tmp_err));
-    if(*error_msg == NULL)
-      return NULL;
-
-    sprintf(*error_msg, 
-	    "Unicode conversion failed with '%s'. Quoting as binary.", tmp_err);
-    ret_val = quote_buffer(uni, length, special);
-  }
-  else
-  {
-    ret_val = quote_string(ascii, special);
-    free(ascii);
-  }
-  
-  return ret_val;
-}
-
-
-/*
  * Convert a data value to a string for display.  Returns NULL on error,
  * and the string to display if there is no error, or a non-fatal
Index: /trunk/src/reglookup-recover.c
===================================================================
--- /trunk/src/reglookup-recover.c	(revision 159)
+++ /trunk/src/reglookup-recover.c	(revision 160)
@@ -66,5 +66,5 @@
 }
 
-
+/* XXX: Somewhere in here, need to start looking for and handling classnames */
 void printKey(REGFI_FILE* f, REGFI_NK_REC* nk, const char* prefix)
 {
Index: /trunk/src/reglookup.c
===================================================================
--- /trunk/src/reglookup.c	(revision 159)
+++ /trunk/src/reglookup.c	(revision 160)
@@ -282,5 +282,4 @@
   char* dacl = NULL;
   char* quoted_classname;
-  char* error_msg = NULL;
   char mtime[20];
   time_t tmp_time[1];
@@ -288,4 +287,5 @@
   const REGFI_SK_REC* sk;
   const REGFI_NK_REC* k = regfi_iterator_cur_key(iter);
+  REGFI_CLASSNAME* classname;
 
   *tmp_time = nt_time_to_unix(&k->mtime);
@@ -308,30 +308,29 @@
       dacl = empty_str;
 
-    if(k->classname != NULL)
-    {
-      quoted_classname = quote_unicode((uint8*)k->classname, k->classname_length,
-				       key_special_chars, &error_msg);
+    classname = regfi_iterator_fetch_classname(iter, k);
+    printMsgs(iter->f);
+    if(classname != NULL)
+    {
+      if(classname->interpreted == NULL)
+      {
+	fprintf(stderr, "WARN: Could not convert class name"
+		" charset for key '%s'.  Quoting raw...\n", full_path);
+	quoted_classname = quote_buffer(classname->raw, classname->size,
+					key_special_chars);
+      }
+      else
+	quoted_classname = quote_string(classname->interpreted, 
+					key_special_chars);
+
       if(quoted_classname == NULL)
       {
-	if(error_msg == NULL)
-	  fprintf(stderr, "ERROR: Could not quote classname"
-		  " for key '%s' due to unknown error.\n", full_path);
-	else
-	{
-	  fprintf(stderr, "ERROR: Could not quote classname"
-		  " for key '%s' due to error: %s\n", full_path, error_msg);
-	  free(error_msg);
-	}
-      }
-      else if (error_msg != NULL)
-      {
-	if(print_verbose)
-	  fprintf(stderr, "INFO: While converting classname"
-		  " for key '%s': %s.\n", full_path, error_msg);
-	free(error_msg);
+	fprintf(stderr, "ERROR: Could not quote classname"
+		" for key '%s' due to unknown error.\n", full_path);
+	quoted_classname = empty_str;
       }
     }
     else
       quoted_classname = empty_str;
+    regfi_free_classname(classname);
 
     printMsgs(iter->f);
