Reading of ri blocks.
Better error handling.

diff --git a/misc/registry.c b/misc/registry.c
index 5c7751e..5533a14 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -674,10 +674,14 @@
 
 #define NT_REG_HEADER_BLOCK_ID       0x66676572	/* regf */
 #define NT_REG_POOL_BLOCK_ID         0x6E696268	/* hbin */
-#define NT_REG_KEY_BLOCK_ID          0x6b6e
-#define NT_REG_VALUE_BLOCK_ID        0x6b76
-#define NT_REG_HASH_BLOCK_ID         0x666c
-#define NT_REG_NOHASH_BLOCK_ID       0x696c
+#define NT_REG_KEY_BLOCK_ID          0x6b6e /* nk */
+#define NT_REG_VALUE_BLOCK_ID        0x6b76 /* vk */
+
+/* subblocks of nk */
+#define NT_REG_HASH_BLOCK_ID         0x666c /* lf */
+#define NT_REG_NOHASH_BLOCK_ID       0x696c /* li */
+#define NT_REG_RI_BLOCK_ID	     0x6972 /* ri */
+
 #define NT_REG_KEY_BLOCK_TYPE        0x20
 #define NT_REG_ROOT_KEY_BLOCK_TYPE   0x2c
 
@@ -757,12 +761,37 @@
 	hash_rec	hash_rec[1];
 } nt_lf;
 
+/*
+ list of subkeys without hash
+
+ li --+-->nk
+      |
+      +-->nk
+ */
 typedef struct
 {
 	WORD	id;		/* 0x00 0x696c */
 	WORD	nr_keys;
 	DWORD	off_nk[1];
-} nt_il;
+} nt_li;
+
+/*
+ this is a intermediate node
+
+ ri --+-->li--+-->nk
+      |       +
+      |       +-->nk
+      |
+      +-->li--+-->nk
+              +
+	      +-->nk
+ */
+typedef struct
+{
+	WORD	id;		/* 0x00 0x6972 */
+	WORD	nr_li;		/* 0x02 number off offsets */
+	DWORD	off_li[1];	/* 0x04 points to li */
+} nt_ri;
 
 typedef struct
 {
@@ -789,7 +818,7 @@
 
 static int _nt_parse_nk(HKEY hkey, char * base, nt_nk * nk, int level);
 static int _nt_parse_vk(HKEY hkey, char * base, nt_vk * vk);
-static int _nt_parse_lf(HKEY hkey, char * base, nt_lf * lf, int level);
+static int _nt_parse_lf(HKEY hkey, char * base, int subkeys, nt_lf * lf, int level);
 
 
 /*
@@ -822,7 +851,7 @@
 	if (ret) ERR("RegSetValueEx failed (0x%08lx)\n", ret);
 	return TRUE;
 error:
-	ERR_(reg)("vk block invalid\n");
+	ERR_(reg)("unknown block found (0x%04x), please report!\n", vk->id);
 	return FALSE;
 }
 
@@ -835,27 +864,64 @@
  * exception: if the id is 'il' there are no hash values and every 
  * dword is a offset
  */
-static int _nt_parse_lf(HKEY hkey, char * base, nt_lf * lf, int level)
+static int _nt_parse_lf(HKEY hkey, char * base, int subkeys, nt_lf * lf, int level)
 {
 	int i;
 
 	if (lf->id == NT_REG_HASH_BLOCK_ID)
 	{
+	  if (subkeys != lf->nr_keys) goto error1;
+
 	  for (i=0; i<lf->nr_keys; i++)
 	  {
 	    if (!_nt_parse_nk(hkey, base, (nt_nk*)(base+lf->hash_rec[i].off_nk+4), level)) goto error;
 	  }
-	  
 	}
 	else if (lf->id == NT_REG_NOHASH_BLOCK_ID)
 	{
-	  for (i=0; i<lf->nr_keys; i++)
+	  nt_li * li = (nt_li*)lf;
+	  if (subkeys != li->nr_keys) goto error1;
+
+	  for (i=0; i<li->nr_keys; i++)
 	  {
-	    if (!_nt_parse_nk(hkey, base, (nt_nk*)(base+((nt_il*)lf)->off_nk[i]+4), level)) goto error;
+	    if (!_nt_parse_nk(hkey, base, (nt_nk*)(base+li->off_nk[i]+4), level)) goto error;
 	  }
 	}
+	else if (lf->id == NT_REG_RI_BLOCK_ID) /* ri */
+	{
+	  nt_ri * ri = (nt_ri*)lf;
+	  int li_subkeys = 0;
+
+	  /* count all subkeys */
+	  for (i=0; i<ri->nr_li; i++)
+	  {
+	    nt_li * li = (nt_li*)(base+ri->off_li[i]+4);
+	    if(li->id != NT_REG_NOHASH_BLOCK_ID) goto error2;
+	    li_subkeys += li->nr_keys;
+	  }
+
+	  /* check number */
+	  if (subkeys != li_subkeys) goto error1;
+
+	  /* loop through the keys */
+	  for (i=0; i<ri->nr_li; i++)
+	  {
+	    nt_li * li = (nt_li*)(base+ri->off_li[i]+4);
+	    if (!_nt_parse_lf(hkey, base, li->nr_keys, (nt_lf*)li, level)) goto error;
+	  }
+	}
+	else 
+	{
+	  goto error2;
+	}
+	return TRUE;
+
+error2: ERR("unknown node id 0x%04x, please report!\n", lf->id);
 	return TRUE;
 	
+error1:	ERR_(reg)("registry file corrupt! (inconsistent number of subkeys)\n");
+	return FALSE;
+
 error:	ERR_(reg)("error reading lf block\n");
 	return FALSE;
 }
@@ -867,9 +933,18 @@
 	DWORD * vl;
 	HKEY subkey = hkey;
 
-	if(nk->SubBlockId != NT_REG_KEY_BLOCK_ID) goto error;
+	if(nk->SubBlockId != NT_REG_KEY_BLOCK_ID)
+	{
+	  ERR("unknown node id 0x%04x, please report!\n", nk->SubBlockId);
+	  goto error;
+	}
+
 	if((nk->Type!=NT_REG_ROOT_KEY_BLOCK_TYPE) &&
-	   (((nt_nk*)(base+nk->parent_off+4))->SubBlockId != NT_REG_KEY_BLOCK_ID)) goto error;
+	   (((nt_nk*)(base+nk->parent_off+4))->SubBlockId != NT_REG_KEY_BLOCK_ID))
+	{
+	  ERR_(reg)("registry file corrupt!\n");
+	  goto error;
+	}
 
 	/* create the new key */
 	if(level <= 0)
@@ -883,8 +958,7 @@
 	if (nk->nr_subkeys)
 	{
 	  nt_lf * lf = (nt_lf*)(base+nk->lf_off+4);
-	  if (nk->nr_subkeys != lf->nr_keys) goto error1;
-	  if (!_nt_parse_lf(subkey, base, lf, level-1)) goto error1;
+	  if (!_nt_parse_lf(subkey, base, nk->nr_subkeys, lf, level-1)) goto error1;
 	}
 
 	/* loop trough the value list */
@@ -899,8 +973,7 @@
 	return TRUE;
 	
 error1:	RegCloseKey(subkey);
-error:	ERR_(reg)("error reading nk block\n");
-	return FALSE;
+error:	return FALSE;
 }
 
 /* end nt loader */