Reading of ri blocks.

Better error handling.
This commit is contained in:
Juergen Schmied 2000-02-13 15:05:39 +00:00 committed by Alexandre Julliard
parent c448c5cf53
commit bd1dcd7520

View File

@ -674,10 +674,14 @@ static void _wine_loadreg( HKEY hkey, char *fn )
#define NT_REG_HEADER_BLOCK_ID 0x66676572 /* regf */ #define NT_REG_HEADER_BLOCK_ID 0x66676572 /* regf */
#define NT_REG_POOL_BLOCK_ID 0x6E696268 /* hbin */ #define NT_REG_POOL_BLOCK_ID 0x6E696268 /* hbin */
#define NT_REG_KEY_BLOCK_ID 0x6b6e #define NT_REG_KEY_BLOCK_ID 0x6b6e /* nk */
#define NT_REG_VALUE_BLOCK_ID 0x6b76 #define NT_REG_VALUE_BLOCK_ID 0x6b76 /* vk */
#define NT_REG_HASH_BLOCK_ID 0x666c
#define NT_REG_NOHASH_BLOCK_ID 0x696c /* 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_KEY_BLOCK_TYPE 0x20
#define NT_REG_ROOT_KEY_BLOCK_TYPE 0x2c #define NT_REG_ROOT_KEY_BLOCK_TYPE 0x2c
@ -757,12 +761,37 @@ typedef struct
hash_rec hash_rec[1]; hash_rec hash_rec[1];
} nt_lf; } nt_lf;
/*
list of subkeys without hash
li --+-->nk
|
+-->nk
*/
typedef struct typedef struct
{ {
WORD id; /* 0x00 0x696c */ WORD id; /* 0x00 0x696c */
WORD nr_keys; WORD nr_keys;
DWORD off_nk[1]; 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 typedef struct
{ {
@ -789,7 +818,7 @@ LPSTR _strdupnA( LPCSTR str, int len )
static int _nt_parse_nk(HKEY hkey, char * base, nt_nk * nk, int level); 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_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 @@ static int _nt_parse_vk(HKEY hkey, char * base, nt_vk * vk)
if (ret) ERR("RegSetValueEx failed (0x%08lx)\n", ret); if (ret) ERR("RegSetValueEx failed (0x%08lx)\n", ret);
return TRUE; return TRUE;
error: error:
ERR_(reg)("vk block invalid\n"); ERR_(reg)("unknown block found (0x%04x), please report!\n", vk->id);
return FALSE; return FALSE;
} }
@ -835,27 +864,64 @@ error:
* exception: if the id is 'il' there are no hash values and every * exception: if the id is 'il' there are no hash values and every
* dword is a offset * 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; int i;
if (lf->id == NT_REG_HASH_BLOCK_ID) if (lf->id == NT_REG_HASH_BLOCK_ID)
{ {
if (subkeys != lf->nr_keys) goto error1;
for (i=0; i<lf->nr_keys; i++) 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; 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) 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; return TRUE;
error1: ERR_(reg)("registry file corrupt! (inconsistent number of subkeys)\n");
return FALSE;
error: ERR_(reg)("error reading lf block\n"); error: ERR_(reg)("error reading lf block\n");
return FALSE; return FALSE;
} }
@ -867,9 +933,18 @@ static int _nt_parse_nk(HKEY hkey, char * base, nt_nk * nk, int level)
DWORD * vl; DWORD * vl;
HKEY subkey = hkey; 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) && 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 */ /* create the new key */
if(level <= 0) if(level <= 0)
@ -883,8 +958,7 @@ static int _nt_parse_nk(HKEY hkey, char * base, nt_nk * nk, int level)
if (nk->nr_subkeys) if (nk->nr_subkeys)
{ {
nt_lf * lf = (nt_lf*)(base+nk->lf_off+4); 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, nk->nr_subkeys, lf, level-1)) goto error1;
if (!_nt_parse_lf(subkey, base, lf, level-1)) goto error1;
} }
/* loop trough the value list */ /* loop trough the value list */
@ -899,8 +973,7 @@ static int _nt_parse_nk(HKEY hkey, char * base, nt_nk * nk, int level)
return TRUE; return TRUE;
error1: RegCloseKey(subkey); error1: RegCloseKey(subkey);
error: ERR_(reg)("error reading nk block\n"); error: return FALSE;
return FALSE;
} }
/* end nt loader */ /* end nt loader */