Index: trunk/src/reglookup-recover.c
===================================================================
--- trunk/src/reglookup-recover.c	(revision 114)
+++ trunk/src/reglookup-recover.c	(revision 115)
@@ -422,5 +422,5 @@
   int32 rm_idx;
   const range_list_element* cur_elem;
-  
+
   rm_idx = range_list_find(rl, offset);
   if(rm_idx < 0)
@@ -474,8 +474,9 @@
   {
     cur_elem = range_list_get(unalloc_cells, i);
-    for(j=0; j <= cur_elem->length; j+=8)
-    {
-      key = regfi_parse_nk(f, cur_elem->offset+j, 
-			       cur_elem->length-j, false);
+    for(j=0; cur_elem->length > REGFI_NK_MIN_LENGTH 
+	  && j <= cur_elem->length-REGFI_NK_MIN_LENGTH; j+=8)
+    {
+      key = regfi_parse_nk(f, cur_elem->offset+j,
+			   cur_elem->length-j, false);
       if(key != NULL)
       {
@@ -487,5 +488,14 @@
 	}
 	
-	if(!removeRange(unalloc_cells, key->offset, key->cell_size))
+	if(removeRange(unalloc_cells, key->offset, key->cell_size))
+	{
+	  /* TODO: This ugly hack is needed because unalloc_cells is changing
+	   *       underneath us when we find things.  Need a better approach
+	   *       so we can parse things single-pass.
+	   */
+	  i=0;
+	  break;
+	}
+	else
 	  return 30;
       }
@@ -531,8 +541,11 @@
 	nk->values = regfi_load_valuelist(f, off, nk->num_values, max_length,
 					  false);
+	values_length = (nk->num_values+1)*sizeof(uint32);
+	if(values_length != (values_length & 0xFFFFFFF8))
+	  values_length = (values_length & 0xFFFFFFF8) + 8;
 
 	if(nk->values != NULL)
 	{
-	  if(!range_list_has_range(unalloc_cells, off, nk->cell_size))
+	  if(!range_list_has_range(unalloc_cells, off, values_length))
 	  { /* We've parsed a values-list which isn't in the unallocated list,
 	     * so prune it. 
@@ -545,8 +558,8 @@
 		  free(nk->values[j]->data);
 		free(nk->values[j]);
-		free(nk->values);
-		nk->values = NULL;
 	      }
 	    }
+	    free(nk->values);
+	    nk->values = NULL;
 	  }
 	  else
@@ -554,8 +567,4 @@
 	     * inspect values. 
 	     */
-	    values_length = (nk->num_values+1)*sizeof(uint32);
-	    if(values_length != (values_length & 0xFFFFFFF8))
-	      values_length = (values_length & 0xFFFFFFF8) + 8;
-
 	    if(!removeRange(unalloc_cells, off, values_length))
 	      return 20;
@@ -625,5 +634,5 @@
   const range_list_element* cur_elem;
   REGF_VK_REC* vk;
-  uint32 i, j;
+  uint32 i, j, off;
 
   for(i=0; i < range_list_size(unalloc_cells); i++)
@@ -645,4 +654,29 @@
 	if(!removeRange(unalloc_cells, vk->offset, vk->cell_size))
 	  return 30;
+
+	if(vk->data != NULL && !vk->data_in_offset)
+	{
+	  off = vk->data_off+REGF_BLOCKSIZE;
+	  if(!range_list_has_range(unalloc_cells, off, 
+				   vk->data_size))
+	  { /* We've parsed a data cell which isn't in the unallocated 
+	     * list, so prune it.
+	     */
+	    free(vk->data);
+	    vk->data = NULL;
+	  }
+	  else
+	  { /*A data record was recovered. Remove from unalloc_cells.*/
+	    if(!removeRange(unalloc_cells, off, vk->data_size))
+	      return 40;
+	  }
+	}
+
+	/* TODO: This ugly hack is needed because unalloc_cells is changing
+	 *       underneath us when we find things.  Need a better approach
+	 *       so we can parse things single-pass.
+	 */
+	i=0;
+	break;
       }
     }
@@ -677,5 +711,14 @@
 	}
 	
-	if(!removeRange(unalloc_cells, sk->offset, sk->cell_size))
+	if(removeRange(unalloc_cells, sk->offset, sk->cell_size))
+	{
+	  /* TODO: This ugly hack is needed because unalloc_cells is changing
+	   *       underneath us when we find things.  Need a better approach
+	   *       so we can parse things single-pass.
+	   */
+	  i = 0;
+	  break;
+	}
+	else
 	  return 30;
       }
@@ -700,5 +743,5 @@
   REGF_NK_REC* tmp_key;
   REGF_VK_REC* tmp_value;
-  uint32 argi, arge, i, j, ret, num_unalloc_keys;
+  uint32 argi, arge, i, j, k, ret, num_unalloc_keys;
   /* uint32 test_offset;*/
   
@@ -758,4 +801,14 @@
   }
 
+  /*XXX
+  for(i=0,k=0; i < range_list_size(unalloc_cells); i++)
+  {
+    cur_elem = range_list_get(unalloc_cells, i);
+    k+=cur_elem->length;
+  }
+  printf("UNALLOC=%d\n", k);
+  printf("UNALLOC_CELL_COUNT=%d\n", range_list_size(unalloc_cells));
+  XXX*/
+
   unalloc_keys = range_list_new();
   if(unalloc_keys == NULL)
@@ -858,4 +911,13 @@
   }
   
+  /*XXX
+  for(i=0,j=0; i < range_list_size(unalloc_cells); i++)
+  {
+    cur_elem = range_list_get(unalloc_cells, i);
+    j+=cur_elem->length;
+  }
+  printf("PARSED_UNALLOC=%d\n", k-j);
+  XXX*/
+
   if(print_leftover)
   {
@@ -863,6 +925,4 @@
     {
       cur_elem = range_list_get(unalloc_cells, i);
-      printf("0x%X,%d,", cur_elem->offset, cur_elem->length);
-      
       printCell(f, cur_elem->offset);
     }
