Index: trunk/lib/regfi.c
===================================================================
--- trunk/lib/regfi.c	(revision 148)
+++ trunk/lib/regfi.c	(revision 150)
@@ -560,5 +560,5 @@
   {
     num_sublists = ret_val->num_children;
-    sublists = (REGFI_SUBKEY_LIST**)zalloc(num_sublists 
+    sublists = (REGFI_SUBKEY_LIST**)malloc(num_sublists 
 					   * sizeof(REGFI_SUBKEY_LIST*));
     for(i=0; i < num_sublists; i++)
@@ -575,5 +575,5 @@
       }
     }
-    free(ret_val);
+    talloc_free(ret_val);
 
     return regfi_merge_subkeylists(num_sublists, sublists, strict);
@@ -590,6 +590,6 @@
 {
   REGFI_SUBKEY_LIST* ret_val;
-  uint32 i, cell_length, length, elem_size;
-  uint8* elements;
+  uint32 i, cell_length, length, elem_size, read_len;
+  uint8* elements = NULL;
   uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN];
   bool unalloc;
@@ -631,5 +631,5 @@
   }
 
-  ret_val = (REGFI_SUBKEY_LIST*)zalloc(sizeof(REGFI_SUBKEY_LIST));
+  ret_val = talloc(NULL, REGFI_SUBKEY_LIST);
   if(ret_val == NULL)
     return NULL;
@@ -652,35 +652,20 @@
 		      offset);
     if(strict)
-    {
-      free(ret_val);
-      return NULL;
-    }
+      goto fail;
     length = cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32);
   }
 
-  ret_val->elements 
-    = (REGFI_SUBKEY_LIST_ELEM*)zalloc(ret_val->num_children
-				      * sizeof(REGFI_SUBKEY_LIST_ELEM));
+  ret_val->elements = talloc_array(ret_val, REGFI_SUBKEY_LIST_ELEM, 
+				   ret_val->num_children);
   if(ret_val->elements == NULL)
-  {
-    free(ret_val);
-    return NULL;
-  }
-
-  elements = (uint8*)zalloc(length);
+    goto fail;
+
+  elements = (uint8*)malloc(length);
   if(elements == NULL)
-  {
-    free(ret_val->elements);
-    free(ret_val);
-    return NULL;
-  }
-
-  if(regfi_read(file->fd, elements, &length) != 0
-     || length != elem_size*ret_val->num_children)
-  {
-    free(ret_val->elements);
-    free(ret_val);
-    return NULL;
-  }
+    goto fail;
+
+  read_len = length;
+  if(regfi_read(file->fd, elements, &read_len) != 0 || read_len != length)
+    goto fail;
 
   if(elem_size == sizeof(uint32))
@@ -703,4 +688,10 @@
 
   return ret_val;
+
+ fail:
+  if(elements != NULL)
+    free(elements);
+  talloc_free(ret_val);
+  return NULL;
 }
 
@@ -717,5 +708,5 @@
   if(lists == NULL)
     return NULL;
-  ret_val = (REGFI_SUBKEY_LIST*)zalloc(sizeof(REGFI_SUBKEY_LIST));
+  ret_val = talloc(NULL, REGFI_SUBKEY_LIST);
 
   if(ret_val == NULL)
@@ -733,7 +724,6 @@
   if(ret_val->num_keys > 0)
   {
-    ret_val->elements = 
-      (REGFI_SUBKEY_LIST_ELEM*)zalloc(sizeof(REGFI_SUBKEY_LIST_ELEM)
-				     * ret_val->num_keys);
+    ret_val->elements = talloc_array(ret_val, REGFI_SUBKEY_LIST_ELEM,
+				     ret_val->num_keys);
     k=0;
 
@@ -746,6 +736,6 @@
 	  for(j=0; j < lists[i]->num_keys; j++)
 	  {
-	    ret_val->elements[k].hash=lists[i]->elements[j].hash;
-	    ret_val->elements[k++].offset=lists[i]->elements[j].offset;
+	    ret_val->elements[k].hash = lists[i]->elements[j].hash;
+	    ret_val->elements[k++].offset = lists[i]->elements[j].offset;
 	  }
 	}
@@ -789,5 +779,4 @@
   }
 
-  /*  ret_val = (REGFI_SK_REC*)zalloc(sizeof(REGFI_SK_REC));*/
   ret_val = talloc(NULL, REGFI_SK_REC);
   if(ret_val == NULL)
@@ -903,12 +892,12 @@
 
   read_len = num_values*sizeof(uint32);
-  ret_val = (REGFI_VALUE_LIST*)malloc(sizeof(REGFI_VALUE_LIST));
+  ret_val = talloc(NULL, REGFI_VALUE_LIST);
   if(ret_val == NULL)
     return NULL;
 
-  ret_val->elements = (REGFI_VALUE_LIST_ELEM*)malloc(read_len);
+  ret_val->elements = (REGFI_VALUE_LIST_ELEM*)talloc_size(ret_val, read_len);
   if(ret_val->elements == NULL)
   {
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -921,6 +910,5 @@
     regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read value pointers"
 		      " while parsing value list at offset 0x%.8X.", offset);
-    free(ret_val->elements);
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -942,6 +930,5 @@
 			  " (0x%.8X) found while parsing value list at offset"
 			  " 0x%.8X.", ret_val->elements[i], offset);
-	free(ret_val->elements);
-	free(ret_val);
+	talloc_free(ret_val);
 	return NULL;
       }
@@ -956,6 +943,5 @@
 /******************************************************************************
  ******************************************************************************/
-REGFI_VK_REC* regfi_load_value(REGFI_FILE* file, uint32 offset, 
-			       bool strict)
+REGFI_VK_REC* regfi_load_value(REGFI_FILE* file, uint32 offset, bool strict)
 {
   REGFI_VK_REC* ret_val = NULL;
@@ -1009,4 +995,6 @@
 			ret_val->offset);
     }
+    else
+      talloc_steal(ret_val, ret_val->data);
   }
 
@@ -1076,5 +1064,5 @@
       if(strict)
       {
-	free(nk);
+	regfi_free_key(nk);
 	return NULL;
       }
@@ -1095,8 +1083,9 @@
 	if(strict)
 	{
-	  free(nk);
+	  regfi_free_key(nk);
 	  return NULL;
 	}
       }
+      talloc_steal(nk, nk->values);
     }
   }
@@ -1109,9 +1098,9 @@
       sub_hbin = regfi_lookup_hbin(file, nk->subkeys_off);
 
-    if (sub_hbin == NULL) 
+    if(sub_hbin == NULL) 
     {
       if(strict)
       {
-	regfi_key_free(nk);
+	regfi_free_key(nk);
 	return NULL;
       }
@@ -1132,4 +1121,5 @@
 	nk->num_subkeys = 0;
       }
+      talloc_steal(nk, nk->subkeys);
     }
   }
@@ -1214,5 +1204,5 @@
 	  *root_offset = nk->offset;
 	}
-	free(nk);
+	regfi_free_key(nk);
       }
     }
@@ -1267,10 +1257,10 @@
   {
     /* fprintf(stderr, "regfi_open: Failed to create HBIN list.\n"); */
-    range_list_free(rb->hbins);
     close(fd);
-    free(rb);
-    return NULL;
-  }
-  
+    talloc_free(rb);
+    return NULL;
+  }
+  talloc_steal(rb, rb->hbins);
+
   rla = true;
   hbin_off = REGFI_REGF_SIZE;
@@ -1292,5 +1282,5 @@
 
   /* Cache an unlimited number of SK records.  Typically there are very few. */
-  rb->sk_cache = lru_cache_create_ctx(NULL, 0, cache_secret, true);
+  rb->sk_cache = lru_cache_create_ctx(rb, 0, cache_secret, true);
 
   /* Default message mask */
@@ -1320,5 +1310,5 @@
     lru_cache_destroy(file->sk_cache);
 
-  free(file);
+  talloc_free(file);
   return close(fd);
 }
@@ -1361,22 +1351,16 @@
 /******************************************************************************
  *****************************************************************************/
-void regfi_key_free(REGFI_NK_REC* nk)
-{
-  if((nk->values != NULL) && (nk->values_off!=REGFI_OFFSET_NONE))
-  {
-    if(nk->values->elements != NULL)
-      free(nk->values->elements);
-    free(nk->values);
-  }
-
+void regfi_free_key(REGFI_NK_REC* nk)
+{
   regfi_subkeylist_free(nk->subkeys);
-
-  if(nk->keyname != NULL)
-    free(nk->keyname);
-  if(nk->classname != NULL)
-    free(nk->classname);
-
-  /* XXX: not freeing sec_desc because these are cached.  This needs to be reviewed. */
-  free(nk);
+  talloc_free(nk);
+}
+
+
+/******************************************************************************
+ *****************************************************************************/
+void regfi_free_value(REGFI_VK_REC* vk)
+{
+  talloc_free(vk);
 }
 
@@ -1388,6 +1372,5 @@
   if(list != NULL)
   {
-    free(list->elements);
-    free(list);
+    talloc_free(list);
   }
 }
@@ -1399,5 +1382,5 @@
 {
   REGFI_NK_REC* root;
-  REGFI_ITERATOR* ret_val = (REGFI_ITERATOR*)malloc(sizeof(REGFI_ITERATOR));
+  REGFI_ITERATOR* ret_val = talloc(NULL, REGFI_ITERATOR);
   if(ret_val == NULL)
     return NULL;
@@ -1406,5 +1389,5 @@
   if(root == NULL)
   {
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -1413,7 +1396,8 @@
   if(ret_val->key_positions == NULL)
   {
-    free(ret_val);
-    return NULL;
-  }
+    talloc_free(ret_val);
+    return NULL;
+  }
+  talloc_steal(ret_val, ret_val->key_positions);
 
   ret_val->f = fh;
@@ -1430,17 +1414,5 @@
 void regfi_iterator_free(REGFI_ITERATOR* i)
 {
-  REGFI_ITER_POSITION* cur;
-
-  if(i->cur_key != NULL)
-    regfi_key_free(i->cur_key);
-
-  while((cur = (REGFI_ITER_POSITION*)void_stack_pop(i->key_positions)) != NULL)
-  {
-    regfi_key_free(cur->nk);
-    free(cur);
-  }
-  
-  void_stack_free(i->key_positions);
-  free(i);
+  talloc_free(i);
 }
 
@@ -1455,5 +1427,5 @@
   REGFI_ITER_POSITION* pos;
 
-  pos = (REGFI_ITER_POSITION*)malloc(sizeof(REGFI_ITER_POSITION));
+  pos = talloc(i->key_positions, REGFI_ITER_POSITION);
   if(pos == NULL)
     return false;
@@ -1462,5 +1434,5 @@
   if(subkey == NULL)
   {
-    free(pos);
+    talloc_free(pos);
     return false;
   }
@@ -1470,8 +1442,9 @@
   if(!void_stack_push(i->key_positions, pos))
   {
-    free(pos);
-    regfi_key_free(subkey);
+    talloc_free(pos);
+    regfi_free_key(subkey);
     return false;
   }
+  talloc_steal(i, subkey);
 
   i->cur_key = subkey;
@@ -1493,9 +1466,9 @@
     return false;
 
-  regfi_key_free(i->cur_key);
+  regfi_free_key(i->cur_key);
   i->cur_key = pos->nk;
   i->cur_subkey = pos->cur_subkey;
   i->cur_value = 0;
-  free(pos);
+  talloc_free(pos);
 
   return true;
@@ -1534,5 +1507,5 @@
     else
     {
-      regfi_key_free(subkey);
+      regfi_free_key(subkey);
       subkey = (REGFI_NK_REC*)regfi_iterator_next_subkey(i);
     }
@@ -1545,5 +1518,5 @@
   }
 
-  regfi_key_free(subkey);
+  regfi_free_key(subkey);
   return true;
 }
@@ -1596,5 +1569,5 @@
 /******************************************************************************
  *****************************************************************************/
-const REGFI_NK_REC* regfi_iterator_first_subkey(REGFI_ITERATOR* i)
+REGFI_NK_REC* regfi_iterator_first_subkey(REGFI_ITERATOR* i)
 {
   i->cur_subkey = 0;
@@ -1605,5 +1578,5 @@
 /******************************************************************************
  *****************************************************************************/
-const REGFI_NK_REC* regfi_iterator_cur_subkey(REGFI_ITERATOR* i)
+REGFI_NK_REC* regfi_iterator_cur_subkey(REGFI_ITERATOR* i)
 {
   uint32 nk_offset;
@@ -1623,7 +1596,7 @@
  *****************************************************************************/
 /* XXX: some way of indicating reason for failure should be added. */
-const REGFI_NK_REC* regfi_iterator_next_subkey(REGFI_ITERATOR* i)
-{
-  const REGFI_NK_REC* subkey;
+REGFI_NK_REC* regfi_iterator_next_subkey(REGFI_ITERATOR* i)
+{
+  REGFI_NK_REC* subkey;
 
   i->cur_subkey++;
@@ -1641,5 +1614,5 @@
 bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* value_name)
 {
-  const REGFI_VK_REC* cur;
+  REGFI_VK_REC* cur;
   bool found = false;
 
@@ -1657,5 +1630,8 @@
       found = true;
     else
+    {
+      regfi_free_value(cur);
       cur = regfi_iterator_next_value(i);
+    }
   }
 
@@ -1666,5 +1642,5 @@
 /******************************************************************************
  *****************************************************************************/
-const REGFI_VK_REC* regfi_iterator_first_value(REGFI_ITERATOR* i)
+REGFI_VK_REC* regfi_iterator_first_value(REGFI_ITERATOR* i)
 {
   i->cur_value = 0;
@@ -1675,7 +1651,7 @@
 /******************************************************************************
  *****************************************************************************/
-const REGFI_VK_REC* regfi_iterator_cur_value(REGFI_ITERATOR* i)
-{
-  const REGFI_VK_REC* ret_val = NULL;
+REGFI_VK_REC* regfi_iterator_cur_value(REGFI_ITERATOR* i)
+{
+  REGFI_VK_REC* ret_val = NULL;
   uint32 voffset;
 
@@ -1695,7 +1671,7 @@
 /******************************************************************************
  *****************************************************************************/
-const REGFI_VK_REC* regfi_iterator_next_value(REGFI_ITERATOR* i)
-{
-  const REGFI_VK_REC* ret_val;
+REGFI_VK_REC* regfi_iterator_next_value(REGFI_ITERATOR* i)
+{
+  REGFI_VK_REC* ret_val;
 
   i->cur_value++;
@@ -1739,31 +1715,31 @@
   REGFI_FILE* ret_val;
 
-  ret_val = (REGFI_FILE*)zalloc(sizeof(REGFI_FILE));
+  ret_val = talloc(NULL, REGFI_FILE);
   if(ret_val == NULL)
     return NULL;
 
   ret_val->fd = fd;
-
+  ret_val->sk_cache = NULL;
+  ret_val->last_message = NULL;
+  ret_val->hbins = NULL;
+  
   length = REGFI_REGF_SIZE;
-  if((regfi_read(fd, file_header, &length)) != 0 
-     || length != REGFI_REGF_SIZE)
-  {
-    free(ret_val);
-    return NULL;
-  }
-
+  if((regfi_read(fd, file_header, &length)) != 0 || length != REGFI_REGF_SIZE)
+    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))
-  {
-    free(ret_val);
-    return NULL;
-  }
+    goto fail;
 
   memcpy(ret_val->magic, file_header, REGFI_REGF_MAGIC_SIZE);
-  if(strict && (memcmp(ret_val->magic, "regf", REGFI_REGF_MAGIC_SIZE) != 0))
-  {
-    free(ret_val);
-    return NULL;
+  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]);
   }
   
@@ -1785,4 +1761,8 @@
 
   return ret_val;
+
+ fail:
+  talloc_free(ret_val);
+  return NULL;
 }
 
@@ -1891,5 +1871,5 @@
   }
 
-  ret_val = (REGFI_NK_REC*)zalloc(sizeof(REGFI_NK_REC));
+  ret_val = talloc(NULL, REGFI_NK_REC);
   if(ret_val == NULL)
   {
@@ -1899,4 +1879,6 @@
   }
 
+  ret_val->values = NULL;
+  ret_val->subkeys = NULL;
   ret_val->offset = offset;
   ret_val->cell_size = cell_length;
@@ -1909,5 +1891,5 @@
     regfi_add_message(file, REGFI_MSG_WARN, "A length check failed while"
 		      " parsing NK record at offset 0x%.8X.", offset);
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -1969,5 +1951,5 @@
       regfi_add_message(file, REGFI_MSG_ERROR, "Contents too large for cell"
 			" while parsing NK record at offset 0x%.8X.", offset);
-      free(ret_val);
+      talloc_free(ret_val);
       return NULL;
     }
@@ -1987,8 +1969,8 @@
   }
 
-  ret_val->keyname = (char*)zalloc(sizeof(char)*(ret_val->name_length+1));
+  ret_val->keyname = talloc_array(ret_val, char, ret_val->name_length+1);
   if(ret_val->keyname == NULL)
   {
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -2001,10 +1983,10 @@
     regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read key name"
 		      " while parsing NK record at offset 0x%.8X.", offset);
-    free(ret_val->keyname);
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
   ret_val->keyname[ret_val->name_length] = '\0';
 
+  /* XXX: This linking should be moved up to regfi_load_key */
   if(ret_val->classname_off != REGFI_OFFSET_NONE)
   {
@@ -2031,6 +2013,7 @@
 			" name while parsing NK record at offset 0x%.8X.", 
 			offset);
-      return NULL;
-    }
+    }
+    else
+      talloc_steal(ret_val, ret_val->classname);
   }
 
@@ -2084,5 +2067,5 @@
     }
     
-    ret_val = (char*)zalloc(*name_length);
+    ret_val = talloc_array(NULL, char, *name_length);
     if(ret_val != NULL)
     {
@@ -2093,5 +2076,5 @@
 	regfi_add_message(file, REGFI_MSG_ERROR, "Could not read class name"
 			  " while parsing class name at offset 0x%.8X.", offset);
-	free(ret_val);
+	talloc_free(ret_val);
 	return NULL;
       }
@@ -2121,5 +2104,5 @@
   }
 
-  ret_val = (REGFI_VK_REC*)zalloc(sizeof(REGFI_VK_REC));
+  ret_val = talloc(NULL, REGFI_VK_REC);
   if(ret_val == NULL)
     return NULL;
@@ -2127,5 +2110,7 @@
   ret_val->offset = offset;
   ret_val->cell_size = cell_length;
-
+  ret_val->data = NULL;
+  ret_val->valuename = NULL;
+  
   if(ret_val->cell_size > max_size)
     ret_val->cell_size = max_size & 0xFFFFFFF8;
@@ -2135,5 +2120,5 @@
     regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size encountered"
 		      " while parsing VK record at offset 0x%.8X.", offset);
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -2149,5 +2134,5 @@
     regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch"
 		      " while parsing VK record at offset 0x%.8X.", offset);
-    free(ret_val);
+    talloc_free(ret_val);
     return NULL;
   }
@@ -2171,5 +2156,5 @@
       if(strict)
       {
-	free(ret_val);
+	talloc_free(ret_val);
 	return NULL;
       }
@@ -2183,8 +2168,8 @@
       cell_length+=8;
 
-    ret_val->valuename = (char*)zalloc(sizeof(char)*(ret_val->name_length+1));
+    ret_val->valuename = talloc_array(ret_val, char, ret_val->name_length+1);
     if(ret_val->valuename == NULL)
     {
-      free(ret_val);
+      talloc_free(ret_val);
       return NULL;
     }
@@ -2196,6 +2181,5 @@
       regfi_add_message(file, REGFI_MSG_ERROR, "Could not read value name"
 			" while parsing VK record at offset 0x%.8X.", offset);
-      free(ret_val->valuename);
-      free(ret_val);
+      talloc_free(ret_val);
       return NULL;
     }
@@ -2238,5 +2222,5 @@
     }
 
-    if((ret_val = (uint8*)zalloc(sizeof(uint8)*length)) == NULL)
+    if((ret_val = talloc_array(NULL, uint8_t, length)) == NULL)
       return NULL;
 
@@ -2289,5 +2273,5 @@
     }
 
-    if((ret_val = (uint8*)zalloc(sizeof(uint8)*length)) == NULL)
+    if((ret_val = talloc_array(NULL, uint8_t, length)) == NULL)
       return NULL;
 
@@ -2298,5 +2282,5 @@
       regfi_add_message(file, REGFI_MSG_ERROR, "Could not read data block while"
 			" parsing data record at offset 0x%.8X.", offset);
-      free(ret_val);
+      talloc_free(ret_val);
       return NULL;
     }
