Index: trunk/include/void_stack.h
===================================================================
--- trunk/include/void_stack.h	(revision 32)
+++ trunk/include/void_stack.h	(revision 33)
@@ -44,3 +44,3 @@
 void_stack_iterator* void_stack_iterator_new(void_stack* stack);
 void void_stack_iterator_destroy(void_stack_iterator* iter);
-void* void_stack_iterator_next(void_stack_iterator* iter);
+const void* void_stack_iterator_next(void_stack_iterator* iter);
Index: trunk/lib/regfio.c
===================================================================
--- trunk/lib/regfio.c	(revision 32)
+++ trunk/lib/regfio.c	(revision 33)
@@ -254,5 +254,6 @@
 /*******************************************************************
  *******************************************************************/
-static bool prs_nk_rec( const char *desc, prs_struct *ps, int depth, REGF_NK_REC *nk )
+static bool prs_nk_rec( const char *desc, prs_struct *ps, 
+			int depth, REGF_NK_REC *nk )
 {
   uint16 class_length, name_length;
@@ -266,6 +267,5 @@
   depth++;
 	
-  /* back up and get the data_size */
-	
+  /* back up and get the data_size */	
   if ( !prs_set_offset( ps, ps->data_offset-sizeof(uint32)) )
     return false;
@@ -274,5 +274,5 @@
     return false;
 	
-  if ( !prs_uint8s( true, "header", ps, depth, nk->header, sizeof( nk->header )) )
+  if (!prs_uint8s(true, "header", ps, depth, nk->header, sizeof(nk->header)))
     return false;
 		
@@ -307,8 +307,9 @@
     return false;
 
-  if ( !prs_uint32( "max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname))
-    return false;
-  if ( !prs_uint32( "max_bytes_subkeyclassname", ps, depth, &nk->max_bytes_subkeyclassname))
-    return false;
+  if (!prs_uint32("max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname))
+    return false;
+  if ( !prs_uint32( "max_bytes_subkeyclassname", ps, 
+		    depth, &nk->max_bytes_subkeyclassname))
+  { return false; }
   if ( !prs_uint32( "max_bytes_valuename", ps, depth, &nk->max_bytes_valuename))
     return false;
@@ -325,13 +326,13 @@
     return false;	
 		
-  if ( class_length ) {
+  if ( class_length ) 
+  {
     ;;
   }
 	
-  if ( name_length ) {
-    if ( ps->io ) {
-      if ( !(nk->keyname = (char*)zcalloc(sizeof(char), name_length+1 )) )
+  if ( name_length ) 
+  {
+    if(ps->io && !(nk->keyname = (char*)zcalloc(sizeof(char), name_length+1)))
 	return false;
-    }
 
     if ( !prs_uint8s( true, "name", ps, depth, nk->keyname, name_length) )
@@ -344,13 +345,15 @@
   end_off = ps->data_offset;
 
-  /* data_size must be divisible by 8 and large enough to hold the original record */
+  /* data_size must be divisible by 8 and large enough to hold 
+     the original record */
 
   data_size = ((start_off - end_off) & 0xfffffff8 );
-  if ( data_size > nk->rec_size )
-    /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size));*/
-
-    if ( !ps->io )
-      nk->hbin->dirty = true;
-
+  /*if ( data_size > nk->rec_size )
+      DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size));*/
+
+  if ( !ps->io )
+    nk->hbin->dirty = true;
+  
+  nk->subkey_index = 0;
   return true;
 }
@@ -627,9 +630,9 @@
 
   data_size = ((start_off - end_off) & 0xfffffff8 );
-  if ( data_size > lf->rec_size )
+  /*  if ( data_size > lf->rec_size )*/
     /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size));*/
 
-    if ( !hbin->ps.io )
-      hbin->dirty = true;
+  if ( !hbin->ps.io )
+    hbin->dirty = true;
 
   return true;
@@ -681,9 +684,9 @@
 
   data_size = ((start_off - end_off) & 0xfffffff8 );
-  if ( data_size > sk->rec_size )
+  /*  if ( data_size > sk->rec_size )*/
     /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size));*/
 
-    if ( !hbin->ps.io )
-      hbin->dirty = true;
+  if ( !hbin->ps.io )
+    hbin->dirty = true;
 
   return true;
@@ -937,10 +940,8 @@
 
   /* get the initial nk record */
-	
-  if ( !prs_nk_rec( "nk_rec", &hbin->ps, depth, nk ))
+  if (!prs_nk_rec("nk_rec", &hbin->ps, depth, nk))
     return false;
 
   /* fill in values */
-	
   if ( nk->num_values && (nk->values_off!=REGF_OFFSET_NONE) ) 
   {
@@ -1224,4 +1225,8 @@
 
 
+/* XXX: An interator struct should be used instead, and this function
+ *   should operate on it, so the state of iteration isn't stored in the
+ * REGF_NK_REC struct itself.
+ */
 /*******************************************************************
  This acts as an interator over the subkeys defined for a given 
Index: trunk/lib/void_stack.c
===================================================================
--- trunk/lib/void_stack.c	(revision 32)
+++ trunk/lib/void_stack.c	(revision 33)
@@ -56,4 +56,10 @@
     free(stack->elements[i]);
   free(stack);
+}
+
+
+unsigned short void_stack_size(void_stack* stack)
+{
+  return stack->top;
 }
 
@@ -121,5 +127,5 @@
 
 
-void* void_stack_iterator_next(void_stack_iterator* iter)
+const void* void_stack_iterator_next(void_stack_iterator* iter)
 {
   if(iter->cur < iter->stack->top)
Index: trunk/test/lib-regfio.c
===================================================================
--- trunk/test/lib-regfio.c	(revision 32)
+++ trunk/test/lib-regfio.c	(revision 33)
@@ -24,11 +24,31 @@
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include "../include/regfio.h"
 #include "../include/void_stack.h"
 
 
-char* getStackPath(void_stack* nk_stack)
-{
-  REGF_NK_REC* cur;
+void_stack* path2Stack(const char* s)
+{
+  void_stack* ret_val = void_stack_new(1024);
+  char* cur = strdup(s);
+  char* next = NULL;
+  
+  while((next = strrchr(cur, '/')) != NULL)
+  {
+    next[0] = '\0';
+    if(strlen(next+1) > 0)
+      void_stack_push(ret_val, next+1);
+  }
+  if(strlen(cur) > 0)
+    void_stack_push(ret_val, cur);
+
+  return ret_val;
+}
+
+
+char* stack2Path(void_stack* nk_stack)
+{
+  const REGF_NK_REC* cur;
   unsigned int buf_left = 127;
   unsigned int buf_len = buf_left+1;
@@ -51,10 +71,15 @@
   }
 
+  /* skip root element */
+  cur = void_stack_iterator_next(iter);
+
   while((cur = void_stack_iterator_next(iter)) != NULL)
   {
+    buf[buf_len-buf_left-1] = '/';
+    buf_left -= 1;
     name_len = strlen(cur->keyname);
     if(name_len+1 > buf_left)
     {
-      grow_amt = (unsigned int)(buf_len/3);
+      grow_amt = (unsigned int)(buf_len/2);
       buf_len += name_len+1+grow_amt-buf_left;
       if((new_buf = realloc(buf, buf_len)) == NULL)
@@ -69,49 +94,58 @@
     strncpy(buf+(buf_len-buf_left-1), cur->keyname, name_len);
     buf_left -= name_len;
-    buf[buf_len-buf_left-1] = '/';
-    buf_left -= 1;
     buf[buf_len-buf_left-1] = '\0';
   }
 
-  /* Cut trailing slash */  
-  if(buf[buf_len-buf_left-2] == '/')
-    buf[buf_len-buf_left-2] = '\0';
-
   return buf;
 }
 
 
-void printKeyList(REGF_NK_REC* nk, char* prefix)
+void printValue(REGF_VK_REC* vk, char* prefix)
+{
+  const char* str_type;
+  
+  str_type = type_val2str(vk->type);
+  printf("%s/%s:%s=\n", prefix, vk->valuename, str_type);
+}
+
+
+void printValueList(REGF_NK_REC* nk, char* prefix)
 {
   unsigned int i;
-  const char* str_type;
   
   for(i=0; i < nk->num_values; i++)
-  {
-    str_type = type_val2str(nk->values[i].type);
-    printf("%s/%s:%s=\n", prefix, nk->values[i].valuename, str_type);
-  }
-}
-
-
-void printKeyTree(REGF_FILE* f, void_stack* nk_stack)
+    printValue(&nk->values[i], prefix);
+}
+
+/* XXX: this function is god-awful.  Needs to be re-designed. */
+void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
 {
   REGF_NK_REC* cur;
   REGF_NK_REC* sub;
   char* path;
+  char* val_path;
 
   if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
   {
-    printf("%s:KEY\n", cur->keyname);
+    cur->subkey_index = 0;
+    path = stack2Path(nk_stack);
+    
+    if(strlen(path) > 0)
+      printf("%s%s:KEY\n", prefix, path);
+    printValueList(cur, path);
     while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
     {
       if((sub = regfio_fetch_subkey(f, cur)) != NULL)
       {
+	sub->subkey_index = 0;
 	void_stack_push(nk_stack, sub);
-	path = getStackPath(nk_stack);
+	path = stack2Path(nk_stack);
 	if(path != NULL)
 	{
-	  printKeyList(cur, path);
-	  printf("%s:KEY\n", path);
+	  val_path = (char*)malloc(strlen(prefix)+strlen(path)+1);
+	  sprintf(val_path, "%s%s", prefix, path);
+	  printf("%s:KEY\n", val_path);
+	  printValueList(sub, val_path);
+	  free(val_path);
 	  free(path);
 	}
@@ -123,9 +157,86 @@
 	 * routines to replace the Samba code for this. 
 	 */ 
-	if(cur != NULL)
-	  free(cur);
-      }
-    }
-  }
+	/*	if(cur != NULL)
+	  free(cur);*/
+      }
+    }
+  }
+}
+
+
+/*
+ * Returns 0 if path was found.
+ * Returns 1 if path was not found.
+ * Returns less than 0 on other error.
+ */
+int retrievePath(REGF_FILE* f, void_stack* nk_stack,
+		 void_stack* path_stack)
+{
+  REGF_NK_REC* sub; 
+  REGF_NK_REC* cur;
+  void_stack* sub_nk_stack;
+  char* prefix;
+  char* cur_str = NULL;
+  bool found_cur = true;
+  unsigned int i;
+  unsigned short path_depth;
+  if(path_stack == NULL)
+    return -1;
+
+  path_depth = void_stack_size(path_stack);
+  if(path_depth < 1)
+    return -2;
+
+  if(void_stack_size(nk_stack) < 1)
+    return -3;
+  cur = (REGF_NK_REC*)void_stack_cur(nk_stack);
+
+  while(void_stack_size(path_stack) > 1)
+  {
+    /* Search key records only */
+    cur_str = (char*)void_stack_pop(path_stack);
+
+    found_cur = false;
+    while(!found_cur &&
+	  (sub = regfio_fetch_subkey(f, cur)) != NULL)
+    {
+      if(strcasecmp(sub->keyname, cur_str) == 0)
+      {
+	cur = sub;
+	void_stack_push(nk_stack, sub);
+	found_cur = true;
+      }
+    }
+
+    if(!found_cur)
+      return 0;
+  }
+
+  /* Last round, search value and key records */
+  cur_str = (char*)void_stack_pop(path_stack);
+
+  for(i=0; (i < cur->num_values); i++)
+  {
+    if(strcasecmp(sub->values[i].valuename, cur_str) == 0)
+    {
+      printValue(&sub->values[i], stack2Path(nk_stack));
+      return 0;
+    }
+  }
+
+  while((sub = regfio_fetch_subkey(f, cur)) != NULL)
+  {
+    if(strcasecmp(sub->keyname, cur_str) == 0)
+    {
+      sub_nk_stack = void_stack_new(1024);
+      void_stack_push(sub_nk_stack, sub);
+      void_stack_push(nk_stack, sub);
+      prefix = stack2Path(nk_stack);
+      printKeyTree(f, sub_nk_stack, prefix);
+      return 0;
+    }
+  }
+
+  return 1;
 }
 
@@ -134,6 +245,9 @@
 {
   void_stack* nk_stack;
+  void_stack* path_stack;
   REGF_FILE* f;
   REGF_NK_REC* root;
+  int retr_path_ret;
+  char* path = "/ControlSet002/Services/Eventlog/";
 
   if(argc < 2)
@@ -148,12 +262,21 @@
   nk_stack = void_stack_new(1024);
   if(void_stack_push(nk_stack, root))
-    printKeyTree(f, nk_stack);
+  {
+    path_stack = path2Stack(path);
+    if(void_stack_size(path_stack) < 1)
+      printKeyTree(f, nk_stack, "");
+    else
+    {
+      retr_path_ret = retrievePath(f, nk_stack, 
+				   path_stack);
+      if(retr_path_ret == 1)
+	printf("WARNING: specified path not found.\n");
+      else if(retr_path_ret != 0)
+	printf("ERROR\n");
+    }
+  }
   void_stack_destroy(nk_stack);
 
   regfio_close(f);
-/*
-REGF_NK_REC*  regfio_rootkey( REGF_FILE *file );
-REGF_NK_REC*  regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk );
-*/
 
   return 0;
