Index: trunk/include/regfi.h
===================================================================
--- trunk/include/regfi.h	(revision 247)
+++ trunk/include/regfi.h	(revision 249)
@@ -653,5 +653,5 @@
   REGFI_NTTIME mtime;
 
-  /** Length of keyname_raw */
+  /** Length of name_raw */
   uint16_t name_length;
 
@@ -827,4 +827,24 @@
 
 
+typedef struct _regfi_iter_position
+{
+  /* key offset */
+  uint32_t offset;
+
+  /* Index of the current subkey */
+  uint32_t cur_subkey;
+
+  /* Index of the current value */
+  uint32_t cur_value;
+
+  /* The number of subkeys of this key */
+  uint32_t num_subkeys;
+
+  /* The number of values of this key */
+  uint32_t num_values;
+
+} REGFI_ITER_POSITION;
+
+
 /** Registry hive iterator
  * @ingroup regfiIteratorLayer
@@ -838,23 +858,7 @@
   void_stack* key_positions;
 
-  /** The current key */
-  REGFI_NK* cur_key;
-
-  /** Index of the current subkey */
-  uint32_t cur_subkey;
-
-  /** Index of the current value */
-  uint32_t cur_value;
+  REGFI_ITER_POSITION* cur;
 } REGFI_ITERATOR;
 
-
-typedef struct _regfi_iter_position
-{
-  REGFI_NK* nk;
-  uint32_t cur_subkey;
-  /* We could store a cur_value here as well, but didn't see 
-   * the use in it right now.
-   */
-} REGFI_ITER_POSITION;
 
 
@@ -1405,4 +1409,24 @@
 _EXPORT()
 bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* name);
+
+
+/** Returns the full path where the iterator is currently located as a list 
+ *  of NK records
+ *
+ * @param i     the iterator
+ *
+ * @return An array of NK record pointers terminated by a NULL pointer.  
+ *         This array may be passed directly to regfi_free_record to free
+ *         the entire array.  
+ *
+ * @note In order to use an element of the array independently from the 
+ *       array (that is, to hold a pointer to an individual NK record while 
+ *       freeing the remaining array), callers must first use 
+ *       regfi_reference_record on the elements to be kept.
+ *
+ * @ingroup regfiIteratorLayer
+ */
+_EXPORT()
+const REGFI_NK** regfi_iterator_cur_path(REGFI_ITERATOR* i);
 
 
Index: trunk/lib/regfi.c
===================================================================
--- trunk/lib/regfi.c	(revision 247)
+++ trunk/lib/regfi.c	(revision 249)
@@ -1823,4 +1823,19 @@
   if(ret_val == NULL)
     return NULL;
+  
+  ret_val->cur = talloc(ret_val, REGFI_ITER_POSITION);
+  if(ret_val->cur == NULL)
+  {
+    talloc_free(ret_val);
+    return NULL;
+  }
+
+  ret_val->key_positions = void_stack_new(REGFI_MAX_DEPTH);
+  if(ret_val->key_positions == NULL)
+  {
+    talloc_free(ret_val);
+    return NULL;
+  }
+  talloc_reparent(NULL, ret_val, ret_val->key_positions);
 
   root = (REGFI_NK*)regfi_get_rootkey(file);
@@ -1830,19 +1845,21 @@
     return NULL;
   }
-  ret_val->cur_key = root;
-  talloc_reparent(NULL, ret_val, root);
-
-  ret_val->key_positions = void_stack_new(REGFI_MAX_DEPTH);
-  if(ret_val->key_positions == NULL)
-  {
-    talloc_free(ret_val);
-    return NULL;
-  }
-  talloc_reparent(NULL, ret_val, ret_val->key_positions);
-
+
+  ret_val->cur->offset = root->offset;
+  if(root->subkeys_off == REGFI_OFFSET_NONE)
+    ret_val->cur->num_subkeys = 0;
+  else
+    ret_val->cur->num_subkeys = regfi_fetch_num_subkeys(root);
+  
+  if(root->values_off == REGFI_OFFSET_NONE)
+    ret_val->cur->num_values = 0;
+  else
+    ret_val->cur->num_values = regfi_fetch_num_values(root);
+
+  ret_val->cur->cur_subkey = 0;
+  ret_val->cur->cur_value = 0;
   ret_val->f = file;
-  ret_val->cur_subkey = 0;
-  ret_val->cur_value = 0;
-    
+
+  regfi_free_record(ret_val->f, root);
   return ret_val;
 }
@@ -1855,5 +1872,4 @@
   talloc_unlink(NULL, i);
 }
-
 
 
@@ -1864,7 +1880,5 @@
 {
   REGFI_NK* subkey;
-  REGFI_ITER_POSITION* pos;
-
-  pos = talloc(i->key_positions, REGFI_ITER_POSITION);
+  REGFI_ITER_POSITION* pos = talloc(i, REGFI_ITER_POSITION);
   if(pos == NULL)
     return false;
@@ -1873,22 +1887,34 @@
   if(subkey == NULL)
   {
+    regfi_log_add(REGFI_LOG_WARN, "Could not obtain cur_subkey during"
+                  " iterator_down with subkey index (%d) and key offset=%.8X\n",
+                  i->cur->cur_subkey, i->cur->offset);
     talloc_free(pos);
     return false;
   }
 
-  pos->nk = i->cur_key;
-  pos->cur_subkey = i->cur_subkey;
-  if(!void_stack_push(i->key_positions, pos))
+  if(!void_stack_push(i->key_positions, i->cur))
   {
     talloc_free(pos);
-    talloc_unlink(NULL, subkey);
+    regfi_free_record(i->f, subkey);
     return false;
-  }  
-  talloc_reparent(NULL, i, subkey);
-
-  i->cur_key = subkey;
-  i->cur_subkey = 0;
-  i->cur_value = 0;
-
+  }
+
+  pos->offset = subkey->offset;
+  if(subkey->subkeys_off == REGFI_OFFSET_NONE)
+    pos->num_subkeys = 0;
+  else
+    pos->num_subkeys = regfi_fetch_num_subkeys(subkey);
+
+  if(subkey->values_off == REGFI_OFFSET_NONE)
+    pos->num_values = 0;
+  else
+    pos->num_values = regfi_fetch_num_values(subkey);
+
+  pos->cur_subkey = 0;
+  pos->cur_value = 0;
+  i->cur = pos;
+
+  regfi_free_record(i->f, subkey);
   return true;
 }
@@ -1908,12 +1934,9 @@
     return false;
   
-  talloc_unlink(i, i->cur_key);
+  talloc_unlink(i, i->cur);
+
   regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_up");
 
-  i->cur_key = pos->nk;
-  i->cur_subkey = pos->cur_subkey;
-  i->cur_value = 0;
-  talloc_free(pos);
-
+  i->cur = pos;
   return true;
 }
@@ -1935,13 +1958,21 @@
 bool regfi_iterator_find_subkey(REGFI_ITERATOR* i, const char* name)
 {
+  const REGFI_NK* cur_key;
   uint32_t new_index;
-
-  if(regfi_find_subkey(i->f, i->cur_key, name, &new_index))
-  {
-    i->cur_subkey = new_index;
-    return true;
-  }
-
-  return false;
+  bool ret_val = false;
+
+  cur_key = regfi_iterator_cur_key(i);
+  if(cur_key == NULL)
+    /* XXX: report error */
+    return ret_val;
+
+  if(regfi_find_subkey(i->f, cur_key, name, &new_index))
+  {
+    i->cur->cur_subkey = new_index;
+    ret_val = true;
+  }
+
+  regfi_free_record(i->f, cur_key);
+  return ret_val;
 }
 
@@ -1982,5 +2013,5 @@
     return ret_val;
 
-  ret_val = talloc_reference(NULL, i->cur_key);
+  ret_val = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
 
   regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key");  
@@ -2004,8 +2035,6 @@
 bool regfi_iterator_first_subkey(REGFI_ITERATOR* i)
 {
-  i->cur_subkey = 0;
-  
-  return ((i->cur_key != NULL) && (i->cur_key->subkeys_off!=REGFI_OFFSET_NONE) 
-	  && (i->cur_subkey < regfi_fetch_num_subkeys(i->cur_key)));
+  i->cur->cur_subkey = 0;
+  return (i->cur->cur_subkey < i->cur->num_subkeys);
 }
 
@@ -2015,5 +2044,16 @@
 const REGFI_NK* regfi_iterator_cur_subkey(REGFI_ITERATOR* i)
 {
-  return regfi_get_subkey(i->f, i->cur_key, i->cur_subkey);
+  const REGFI_NK* cur_key;
+  const REGFI_NK* ret_val;
+  
+  cur_key = regfi_iterator_cur_key(i);
+  if(cur_key == NULL)
+    /* XXX: report error */
+    return NULL;
+
+  ret_val = regfi_get_subkey(i->f, cur_key, i->cur->cur_subkey);
+
+  regfi_free_record(i->f, cur_key);
+  return ret_val;
 }
 
@@ -2023,8 +2063,6 @@
 bool regfi_iterator_next_subkey(REGFI_ITERATOR* i)
 {
-  i->cur_subkey++;
-
-  return ((i->cur_key != NULL) && (i->cur_key->subkeys_off!=REGFI_OFFSET_NONE) 
-	  && (i->cur_subkey < regfi_fetch_num_subkeys(i->cur_key))); 
+  i->cur->cur_subkey++;
+  return (i->cur->cur_subkey < i->cur->num_subkeys);
 }
 
@@ -2034,13 +2072,21 @@
 bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* name)
 {
+  const REGFI_NK* cur_key;
   uint32_t new_index;
-
-  if(regfi_find_value(i->f, i->cur_key, name, &new_index))
-  {
-    i->cur_value = new_index;
-    return true;
-  }
-
-  return false;
+  bool ret_val = false;
+
+  cur_key = regfi_iterator_cur_key(i);
+  if(cur_key == NULL)
+    /* XXX: report error */
+    return ret_val;
+
+  if(regfi_find_value(i->f, cur_key, name, &new_index))
+  {
+    i->cur->cur_value = new_index;
+    ret_val = true;
+  }
+
+  regfi_free_record(i->f, cur_key);
+  return ret_val;
 }
 
@@ -2050,7 +2096,6 @@
 bool regfi_iterator_first_value(REGFI_ITERATOR* i)
 {
-  i->cur_value = 0;
-  return (i->cur_key->values != NULL && i->cur_key->values->elements != NULL 
-	  && (i->cur_value < regfi_fetch_num_values(i->cur_key)));
+  i->cur->cur_value = 0;
+  return (i->cur->cur_value < i->cur->num_values);
 }
 
@@ -2060,5 +2105,16 @@
 const REGFI_VK* regfi_iterator_cur_value(REGFI_ITERATOR* i)
 {
-  return regfi_get_value(i->f, i->cur_key, i->cur_value);
+  const REGFI_NK* cur_key;
+  const REGFI_VK* ret_val = NULL;
+
+  cur_key = regfi_iterator_cur_key(i);
+  if(cur_key == NULL)
+    /* XXX: report error */
+    return ret_val;
+
+  ret_val = regfi_get_value(i->f, cur_key, i->cur->cur_value);
+  
+  regfi_free_record(i->f, cur_key);
+  return ret_val;
 }
 
@@ -2068,7 +2124,51 @@
 bool regfi_iterator_next_value(REGFI_ITERATOR* i)
 {
-  i->cur_value++;
-  return (i->cur_key->values != NULL && i->cur_key->values->elements != NULL 
-	  && (i->cur_value < regfi_fetch_num_values(i->cur_key)));
+  i->cur->cur_value++;
+  return (i->cur->cur_value < i->cur->num_values);
+}
+
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+const REGFI_NK** regfi_iterator_cur_path(REGFI_ITERATOR* i)
+{
+  REGFI_NK** ret_val;
+  void_stack_iterator* iter;
+  const REGFI_ITER_POSITION* cur;
+  uint16_t k;
+
+  ret_val = talloc_array(NULL, REGFI_NK*, void_stack_size(i->key_positions)+2);
+  if(ret_val == NULL)
+    return NULL;
+
+  iter = void_stack_iterator_new(i->key_positions);
+  if (iter == NULL)
+  {
+    talloc_free(ret_val);
+    return NULL;
+  }
+  
+  if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_cur_path"))
+  {
+    talloc_free(ret_val);
+    return NULL;
+  }
+
+  for(cur=void_stack_iterator_next(iter), k=0; 
+      cur != NULL; cur=void_stack_iterator_next(iter), k++)
+  {
+    ret_val[k] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true);
+    talloc_reparent(NULL, ret_val, ret_val[k]);
+  }
+  ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
+  talloc_reparent(NULL, ret_val, ret_val[k]);
+
+  regfi_unlock(i->f, &i->f->mem_lock, "regfi_cur_path");
+  void_stack_iterator_free(iter);
+
+  ret_val[++k] = NULL;
+  return (const REGFI_NK**)ret_val;
 }
 
Index: trunk/src/reglookup.c
===================================================================
--- trunk/src/reglookup.c	(revision 247)
+++ trunk/src/reglookup.c	(revision 249)
@@ -52,6 +52,12 @@
 
 
+static bool keysEqual(const REGFI_NK* x, const REGFI_NK* y)
+{
+  return (x != NULL && y != NULL && x->offset == y->offset);
+}
+
 void printValue(REGFI_ITERATOR* iter, const REGFI_VK* vk, char* prefix)
 {
+  const REGFI_NK* cur_key;
   const REGFI_DATA* data;
   char* quoted_value = NULL;
@@ -100,7 +106,9 @@
   if(print_value_mtime)
   {
-    *tmp_time = regfi_nt2unix_time(&iter->cur_key->mtime);
+    cur_key = regfi_iterator_cur_key(iter);
+    *tmp_time = regfi_nt2unix_time(&cur_key->mtime);
     tmp_time_s = gmtime(tmp_time);
     strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
+    regfi_free_record(iter->f, cur_key);
   }
   else
@@ -201,9 +209,9 @@
 
 
-/* Returns a quoted path from an iterator's stack */
+/* Returns a quoted path of the current iterator's position */
 char* iter2Path(REGFI_ITERATOR* i)
 {
-  const REGFI_ITER_POSITION* cur;
-  const REGFI_NK* tmp_key;
+  const REGFI_NK** path;
+  uint32_t k;
   uint32_t buf_left = 127;
   uint32_t buf_len = buf_left+1;
@@ -213,5 +221,4 @@
   char* new_buf;
   char* name;
-  void_stack_iterator* iter;
   
   buf = (char*)malloc((buf_len)*sizeof(char));
@@ -220,6 +227,6 @@
   buf[0] = '\0';
 
-  iter = void_stack_iterator_new(i->key_positions);
-  if (iter == NULL)
+  path = regfi_iterator_cur_path(i);
+  if(path == NULL)
   {
     free(buf);
@@ -227,46 +234,41 @@
   }
 
-  /* skip root element */
-  if(void_stack_size(i->key_positions) < 1)
-  {
-    buf[0] = '/';
-    buf[1] = '\0';
-    return buf;
-  }
-  cur = void_stack_iterator_next(iter);
-
-  do
-  {
-    cur = void_stack_iterator_next(iter);
-    if (cur == NULL)
-      tmp_key = i->cur_key;
+  for(k=0; path[k] != NULL; k++)
+  {
+    /* skip root element's name */
+    if(k == 0)
+    {
+      buf[0] = '/';
+      buf[1] = '\0';
+    }
     else
-      tmp_key = cur->nk;
-
-    name = get_quoted_keyname(tmp_key);
-
-    buf[buf_len-buf_left-1] = '/';
-    buf_left -= 1;
-    name_len = strlen(name);
-    if(name_len+1 > buf_left)
-    {
-      grow_amt = (uint32_t)(buf_len/2);
-      buf_len += name_len+1+grow_amt-buf_left;
-      if((new_buf = realloc(buf, buf_len)) == NULL)
+    {
+      name = get_quoted_keyname(path[k]);
+
+      buf[buf_len-buf_left-1] = '/';
+      buf_left -= 1;
+      name_len = strlen(name);
+      if(name_len+1 > buf_left)
       {
-	free(name);
-	free(buf);
-	free(iter);
-	return NULL;
+        grow_amt = (uint32_t)(buf_len/2);
+        buf_len += name_len+1+grow_amt-buf_left;
+        if((new_buf = realloc(buf, buf_len)) == NULL)
+        {
+          regfi_free_record(i->f, path);
+          free(name);
+          free(buf);
+          return NULL;
+        }
+        buf = new_buf;
+        buf_left = grow_amt + name_len + 1;
       }
-      buf = new_buf;
-      buf_left = grow_amt + name_len + 1;
-    }
-    strncpy(buf+(buf_len-buf_left-1), name, name_len);
-    buf_left -= name_len;
-    buf[buf_len-buf_left-1] = '\0';
-    free(name);
-  } while(cur != NULL);
-
+      strncpy(buf+(buf_len-buf_left-1), name, name_len);
+      buf_left -= name_len;
+      buf[buf_len-buf_left-1] = '\0';
+      free(name);
+    }
+  }
+
+  regfi_free_record(i->f, path);
   return buf;
 }
@@ -378,5 +380,7 @@
   bool print_this = true;
 
-  root = cur = regfi_iterator_cur_key(iter);
+  root = regfi_iterator_cur_key(iter);
+  regfi_reference_record(iter->f, root);
+  cur = root;
   regfi_iterator_first_subkey(iter);
   sub = regfi_iterator_cur_subkey(iter);
@@ -404,7 +408,8 @@
     if(sub == NULL)
     {
-      if(cur != root)
+      if(!keysEqual(cur, root))
       {
         regfi_free_record(iter->f, cur);
+        cur = NULL;
 	/* We're done with this sub-tree, going up and hitting other branches. */
 	if(!regfi_iterator_up(iter))
@@ -431,4 +436,5 @@
        */
       regfi_free_record(iter->f, cur);
+      cur = NULL;
       if(!regfi_iterator_down(iter))
       {
@@ -444,5 +450,7 @@
     }
     printMsgs(iter->f);
-  } while(!((cur == root) && (sub == NULL)));
+  } while(!(keysEqual(cur, root) && (sub == NULL)));
+  if(cur != NULL)
+    regfi_free_record(iter->f, cur);
   regfi_free_record(iter->f, root);
 
