type of Name in KEY_BLOCK corrected

svn path=/trunk/; revision=1367
This commit is contained in:
jean 2000-09-18 09:39:18 +00:00
parent 37d6d2f97f
commit 56cd5f816c

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.34 2000/09/14 14:45:06 jean Exp $ /* $Id: registry.c,v 1.35 2000/09/18 09:39:18 jean Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -86,6 +86,7 @@ typedef struct _FREE_SUB_BLOCK
typedef struct _KEY_BLOCK typedef struct _KEY_BLOCK
{ {
DWORD SubBlockSize;
WORD SubBlockId; WORD SubBlockId;
WORD Type; WORD Type;
LARGE_INTEGER LastWriteTime; LARGE_INTEGER LastWriteTime;
@ -102,8 +103,7 @@ typedef struct _KEY_BLOCK
DWORD Unused4[5]; DWORD Unused4[5];
WORD NameSize; WORD NameSize;
WORD ClassSize; WORD ClassSize;
// FIXME : Name is char, not wchar UCHAR Name[0]; /* warning : not zero terminated */
WCHAR Name[0];
} KEY_BLOCK, *PKEY_BLOCK; } KEY_BLOCK, *PKEY_BLOCK;
// hash record : // hash record :
@ -116,6 +116,7 @@ typedef struct _HASH_RECORD
typedef struct _HASH_TABLE_BLOCK typedef struct _HASH_TABLE_BLOCK
{ {
DWORD SubBlockSize;
WORD SubBlockId; WORD SubBlockId;
WORD HashTableSize; WORD HashTableSize;
HASH_RECORD Table[0]; HASH_RECORD Table[0];
@ -123,11 +124,13 @@ typedef struct _HASH_TABLE_BLOCK
typedef struct _VALUE_LIST_BLOCK typedef struct _VALUE_LIST_BLOCK
{ {
DWORD SubBlockSize;
BLOCK_OFFSET Values[0]; BLOCK_OFFSET Values[0];
} VALUE_LIST_BLOCK, *PVALUE_LIST_BLOCK; } VALUE_LIST_BLOCK, *PVALUE_LIST_BLOCK;
typedef struct _VALUE_BLOCK typedef struct _VALUE_BLOCK
{ {
DWORD SubBlockSize;
WORD SubBlockId; // "kv" WORD SubBlockId; // "kv"
WORD NameSize; // length of Name WORD NameSize; // length of Name
DWORD DataSize; // length of datas in the subblock pinted by DataOffset DWORD DataSize; // length of datas in the subblock pinted by DataOffset
@ -136,7 +139,7 @@ typedef struct _VALUE_BLOCK
WORD Flags; WORD Flags;
WORD Unused1; WORD Unused1;
// FIXME : Name is char, not wchar // FIXME : Name is char, not wchar
WCHAR Name[0]; WCHAR Name[0]; /* warning : not zero terminated */
} VALUE_BLOCK, *PVALUE_BLOCK; } VALUE_BLOCK, *PVALUE_BLOCK;
typedef struct _IN_MEMORY_BLOCK typedef struct _IN_MEMORY_BLOCK
@ -222,12 +225,12 @@ static ULONG CmiGetMaxValueDataLength(PREGISTRY_FILE RegistryFile,
static NTSTATUS CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock, IN PKEY_BLOCK KeyBlock,
OUT PKEY_BLOCK *SubKeyBlock, OUT PKEY_BLOCK *SubKeyBlock,
IN PWSTR KeyName, IN PCHAR KeyName,
IN ACCESS_MASK DesiredAccess); IN ACCESS_MASK DesiredAccess);
static NTSTATUS CmiAddSubKey(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAddSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK CurKeyBlock, IN PKEY_BLOCK CurKeyBlock,
OUT PKEY_BLOCK *SubKeyBlock, OUT PKEY_BLOCK *SubKeyBlock,
IN PWSTR NewSubKeyName, IN PCHAR NewSubKeyName,
IN ULONG TitleIndex, IN ULONG TitleIndex,
IN PWSTR Class, IN PWSTR Class,
IN ULONG CreateOptions); IN ULONG CreateOptions);
@ -250,7 +253,7 @@ static NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
IN PWSTR ValueName); IN PWSTR ValueName);
static NTSTATUS CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
OUT PKEY_BLOCK *KeyBlock, OUT PKEY_BLOCK *KeyBlock,
IN PWSTR NewSubKeyName, IN PCHAR NewSubKeyName,
IN ULONG TitleIndex, IN ULONG TitleIndex,
IN PWSTR Class, IN PWSTR Class,
IN ULONG CreateOptions); IN ULONG CreateOptions);
@ -388,7 +391,6 @@ CmInitializeRegistry2(VOID)
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
/* FIXME : delete temporary \Registry\Machine\System */ /* FIXME : delete temporary \Registry\Machine\System */
/* load the SYSTEM Hive */ /* load the SYSTEM Hive */
CHECKPOINT;
CmiSystemFile = CmiCreateRegistry(SYSTEM_REG_FILE); CmiSystemFile = CmiCreateRegistry(SYSTEM_REG_FILE);
if( CmiSystemFile ) if( CmiSystemFile )
{ {
@ -400,14 +402,14 @@ CHECKPOINT;
CmiKeyType); CmiKeyType);
NewKey->RegistryFile = CmiSystemFile; NewKey->RegistryFile = CmiSystemFile;
NewKey->KeyBlock = CmiGetBlock(CmiSystemFile,32); NewKey->KeyBlock = CmiGetBlock(CmiSystemFile,32);
DPRINT("root : id = %x\n",NewKey->KeyBlock->SubBlockId);
DPRINT("root : hashOffset = %x\n",NewKey->KeyBlock->HashTableOffset);
DPRINT("root : nom = %6.6s\n",NewKey->KeyBlock->Name);
NewKey->Flags = 0; NewKey->Flags = 0;
NewKey->NextKey = NULL; NewKey->NextKey = NULL;
NewKey->Name = NewKey->KeyBlock->Name;
}
CHECKPOINT;
/* tests :*/ /* tests :*/
{ {
// HANDLE HKey; HANDLE HKey;
NTSTATUS Status; NTSTATUS Status;
PKEY_BLOCK SubKeyBlock; PKEY_BLOCK SubKeyBlock;
Status = CmiScanForSubKey(CmiSystemFile, Status = CmiScanForSubKey(CmiSystemFile,
@ -429,11 +431,12 @@ else
DPRINT("not found subkey ControlSet001\n"); DPRINT("not found subkey ControlSet001\n");
} }
//RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\Windows"); //RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\Windows");
//RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\ControlSet001"); RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\ControlSet001");
// InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
// Status = NtOpenKey ( &HKey, KEY_READ , &ObjectAttributes); Status = NtOpenKey ( &HKey, KEY_READ , &ObjectAttributes);
DPRINT(" NtOpenKey = %x, HKey=%x\n",Status,HKey);
} }
}
#endif #endif
} }
@ -638,7 +641,7 @@ NtEnumerateKey (
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime; BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
BasicInformation->TitleIndex = Index; BasicInformation->TitleIndex = Index;
BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR); BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
wcsncpy(BasicInformation->Name, mbstowcs(BasicInformation->Name,
SubKeyBlock->Name, SubKeyBlock->Name,
SubKeyBlock->NameSize); SubKeyBlock->NameSize);
BasicInformation->Name[SubKeyBlock->NameSize] = 0; BasicInformation->Name[SubKeyBlock->NameSize] = 0;
@ -665,14 +668,14 @@ NtEnumerateKey (
SubKeyBlock->NameSize * sizeof(WCHAR); SubKeyBlock->NameSize * sizeof(WCHAR);
NodeInformation->ClassLength = SubKeyBlock->ClassSize; NodeInformation->ClassLength = SubKeyBlock->ClassSize;
NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR); NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
wcsncpy(NodeInformation->Name, mbstowcs(NodeInformation->Name,
SubKeyBlock->Name, SubKeyBlock->Name,
SubKeyBlock->NameSize); SubKeyBlock->NameSize);
NodeInformation->Name[SubKeyBlock->NameSize] = 0; NodeInformation->Name[SubKeyBlock->NameSize] = 0;
if (SubKeyBlock->ClassSize != 0) if (SubKeyBlock->ClassSize != 0)
{ {
wcsncpy(NodeInformation->Name + SubKeyBlock->NameSize + 1, wcsncpy(NodeInformation->Name + SubKeyBlock->NameSize + 1,
&SubKeyBlock->Name[SubKeyBlock->NameSize + 1], (PWSTR)&SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
SubKeyBlock->ClassSize); SubKeyBlock->ClassSize);
NodeInformation-> NodeInformation->
Name[SubKeyBlock->NameSize + 1 + SubKeyBlock->ClassSize] = 0; Name[SubKeyBlock->NameSize + 1 + SubKeyBlock->ClassSize] = 0;
@ -710,7 +713,7 @@ NtEnumerateKey (
FullInformation->MaxValueDataLen = FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, SubKeyBlock); CmiGetMaxValueDataLength(RegistryFile, SubKeyBlock);
wcsncpy(FullInformation->Class, wcsncpy(FullInformation->Class,
&SubKeyBlock->Name[SubKeyBlock->NameSize + 1], (PWSTR)&SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
SubKeyBlock->ClassSize); SubKeyBlock->ClassSize);
FullInformation->Class[SubKeyBlock->ClassSize] = 0; FullInformation->Class[SubKeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) + *ResultLength = sizeof(KEY_FULL_INFORMATION) +
@ -1009,7 +1012,7 @@ NtQueryKey (
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime; BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
BasicInformation->TitleIndex = 0; BasicInformation->TitleIndex = 0;
BasicInformation->NameLength = KeyBlock->NameSize; BasicInformation->NameLength = KeyBlock->NameSize;
wcsncpy(BasicInformation->Name, mbstowcs(BasicInformation->Name,
KeyBlock->Name, KeyBlock->Name,
KeyBlock->NameSize); KeyBlock->NameSize);
BasicInformation->Name[KeyBlock->NameSize] = 0; BasicInformation->Name[KeyBlock->NameSize] = 0;
@ -1036,14 +1039,14 @@ NtQueryKey (
KeyBlock->NameSize * sizeof(WCHAR); KeyBlock->NameSize * sizeof(WCHAR);
NodeInformation->ClassLength = KeyBlock->ClassSize; NodeInformation->ClassLength = KeyBlock->ClassSize;
NodeInformation->NameLength = KeyBlock->NameSize; NodeInformation->NameLength = KeyBlock->NameSize;
wcsncpy(NodeInformation->Name, mbstowcs(NodeInformation->Name,
KeyBlock->Name, KeyBlock->Name,
KeyBlock->NameSize); KeyBlock->NameSize);
NodeInformation->Name[KeyBlock->NameSize] = 0; NodeInformation->Name[KeyBlock->NameSize] = 0;
if (KeyBlock->ClassSize != 0) if (KeyBlock->ClassSize != 0)
{ {
wcsncpy(NodeInformation->Name + KeyBlock->NameSize + 1, wcsncpy(NodeInformation->Name + KeyBlock->NameSize + 1,
&KeyBlock->Name[KeyBlock->NameSize + 1], (PWSTR)&KeyBlock->Name[KeyBlock->NameSize + 1],
KeyBlock->ClassSize); KeyBlock->ClassSize);
NodeInformation-> NodeInformation->
Name[KeyBlock->NameSize + 1 + KeyBlock->ClassSize] = 0; Name[KeyBlock->NameSize + 1 + KeyBlock->ClassSize] = 0;
@ -1081,7 +1084,7 @@ NtQueryKey (
FullInformation->MaxValueDataLen = FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, KeyBlock); CmiGetMaxValueDataLength(RegistryFile, KeyBlock);
wcsncpy(FullInformation->Class, wcsncpy(FullInformation->Class,
&KeyBlock->Name[KeyBlock->NameSize + 1], (PWSTR)&KeyBlock->Name[KeyBlock->NameSize + 1],
KeyBlock->ClassSize); KeyBlock->ClassSize);
FullInformation->Class[KeyBlock->ClassSize] = 0; FullInformation->Class[KeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) + *ResultLength = sizeof(KEY_FULL_INFORMATION) +
@ -1521,7 +1524,7 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
{ {
NTSTATUS Status; NTSTATUS Status;
/* FIXME: this should be allocated based on the largest subkey name */ /* FIXME: this should be allocated based on the largest subkey name */
WCHAR CurKeyName[260]; CHAR CurKeyName[260];
PWSTR Remainder, NextSlash; PWSTR Remainder, NextSlash;
PREGISTRY_FILE RegistryFile; PREGISTRY_FILE RegistryFile;
PKEY_OBJECT NewKeyObject; PKEY_OBJECT NewKeyObject;
@ -1561,12 +1564,12 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
/* Copy just the current subkey name to a buffer */ /* Copy just the current subkey name to a buffer */
if (NextSlash != NULL) if (NextSlash != NULL)
{ {
wcsncpy(CurKeyName, Remainder, NextSlash - Remainder); wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0; CurKeyName[NextSlash - Remainder] = 0;
} }
else else
{ {
wcscpy(CurKeyName, Remainder); wcstombs(CurKeyName, Remainder, wcslen(Remainder) + 1);
} }
/* Verify existance of CurKeyName */ /* Verify existance of CurKeyName */
@ -1902,14 +1905,13 @@ CmiCreateRegistry(PWSTR Filename)
ZwQuerySystemTime((PTIME) &RootKeyBlock->LastWriteTime); ZwQuerySystemTime((PTIME) &RootKeyBlock->LastWriteTime);
RootKeyBlock->ParentKeyOffset = 0; RootKeyBlock->ParentKeyOffset = 0;
RootKeyBlock->NumberOfSubKeys = 0; RootKeyBlock->NumberOfSubKeys = 0;
RootKeyBlock->HashTableOffset = 0; RootKeyBlock->HashTableOffset = -1;
RootKeyBlock->NumberOfValues = 0; RootKeyBlock->NumberOfValues = 0;
RootKeyBlock->ValuesOffset = 0; RootKeyBlock->ValuesOffset = -1;
RootKeyBlock->SecurityKeyOffset = 0; RootKeyBlock->SecurityKeyOffset = 0;
RootKeyBlock->ClassNameOffset = sizeof(KEY_BLOCK); RootKeyBlock->ClassNameOffset = -1;
RootKeyBlock->NameSize = 0; RootKeyBlock->NameSize = 0;
RootKeyBlock->ClassSize = 0; RootKeyBlock->ClassSize = 0;
RootKeyBlock->Name[0] = 0;
RegistryFile->HeaderBlock->RootKeyBlock = (BLOCK_OFFSET) RootKeyBlock; RegistryFile->HeaderBlock->RootKeyBlock = (BLOCK_OFFSET) RootKeyBlock;
} }
@ -1928,7 +1930,7 @@ CmiCreateKey(IN PREGISTRY_FILE RegistryFile,
{ {
/* FIXME: this should be allocated based on the largest subkey name */ /* FIXME: this should be allocated based on the largest subkey name */
NTSTATUS Status; NTSTATUS Status;
WCHAR CurKeyName[256]; CHAR CurKeyName[256];
PWSTR ClassName; PWSTR ClassName;
PWSTR Remainder, NextSlash; PWSTR Remainder, NextSlash;
PKEY_BLOCK CurKeyBlock, SubKeyBlock; PKEY_BLOCK CurKeyBlock, SubKeyBlock;
@ -1947,7 +1949,7 @@ CHECKPOINT;
(NextSlash = wcschr(Remainder, L'\\')) != NULL) (NextSlash = wcschr(Remainder, L'\\')) != NULL)
{ {
/* Copy just the current subkey name to a buffer */ /* Copy just the current subkey name to a buffer */
wcsncpy(CurKeyName, Remainder, NextSlash - Remainder); wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0; CurKeyName[NextSlash - Remainder] = 0;
/* Verify existance of/Create CurKeyName */ /* Verify existance of/Create CurKeyName */
@ -2000,10 +2002,12 @@ CHECKPOINT;
{ {
ClassName = NULL; ClassName = NULL;
} }
wcstombs(CurKeyName, Remainder, wcslen(Remainder)+1 );
CurKeyName[ wcslen(Remainder)] = 0;
Status = CmiAddSubKey(RegistryFile, Status = CmiAddSubKey(RegistryFile,
CurKeyBlock, CurKeyBlock,
&SubKeyBlock, &SubKeyBlock,
Remainder, CurKeyName,
TitleIndex, TitleIndex,
ClassName, ClassName,
CreateOptions); CreateOptions);
@ -2038,7 +2042,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile,
{ {
/* FIXME: this should be allocated based on the largest subkey name */ /* FIXME: this should be allocated based on the largest subkey name */
NTSTATUS Status; NTSTATUS Status;
WCHAR CurKeyName[256]; CHAR CurKeyName[MAX_PATH];
PWSTR Remainder, NextSlash; PWSTR Remainder, NextSlash;
PKEY_BLOCK CurKeyBlock, SubKeyBlock; PKEY_BLOCK CurKeyBlock, SubKeyBlock;
@ -2052,12 +2056,12 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile,
/* FIXME: this access of RootKeyBlock should be guarded by spinlock */ /* FIXME: this access of RootKeyBlock should be guarded by spinlock */
CurKeyBlock = CmiGetBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock); CurKeyBlock = CmiGetBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock);
Remainder = KeyNameBuf; Remainder = KeyNameBuf;
wcscpy(CurKeyName, Remainder); wcstombs(CurKeyName, Remainder, wcslen(Remainder) + 1 );
while (NT_SUCCESS(Status) && while (NT_SUCCESS(Status) &&
(NextSlash = wcschr(Remainder, L'\\')) != NULL) (NextSlash = wcschr(Remainder, L'\\')) != NULL)
{ {
/* Copy just the current subkey name to a buffer */ /* Copy just the current subkey name to a buffer */
wcsncpy(CurKeyName, Remainder, NextSlash - Remainder); wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0; CurKeyName[NextSlash - Remainder] = 0;
/* Verify existance of CurKeyName */ /* Verify existance of CurKeyName */
@ -2238,27 +2242,34 @@ static NTSTATUS
CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile, CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock, IN PKEY_BLOCK KeyBlock,
OUT PKEY_BLOCK *SubKeyBlock, OUT PKEY_BLOCK *SubKeyBlock,
IN PWSTR KeyName, IN PCHAR KeyName,
IN ACCESS_MASK DesiredAccess) IN ACCESS_MASK DesiredAccess)
{ {
ULONG Idx; ULONG Idx;
PHASH_TABLE_BLOCK HashBlock; PHASH_TABLE_BLOCK HashBlock;
PKEY_BLOCK CurSubKeyBlock; PKEY_BLOCK CurSubKeyBlock;
WORD KeyLength = strlen(KeyName);
HashBlock = CmiGetBlock(RegistryFile, KeyBlock->HashTableOffset); HashBlock = CmiGetBlock(RegistryFile, KeyBlock->HashTableOffset);
*SubKeyBlock = NULL; *SubKeyBlock = NULL;
if (HashBlock == 0) if (HashBlock == NULL)
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
for (Idx = 0; Idx < HashBlock->HashTableSize; Idx++) DPRINT("hash=%x,hash.id=%x\n",HashBlock,HashBlock->SubBlockId);
// for (Idx = 0; Idx < HashBlock->HashTableSize; Idx++)
for (Idx = 0; Idx < KeyBlock->NumberOfSubKeys; Idx++)
{ {
DPRINT("&hash=%x,hash=%4.4s\n",&HashBlock->Table[Idx].HashValue,&HashBlock->Table[Idx].HashValue);
if (HashBlock->Table[Idx].KeyOffset != 0 && if (HashBlock->Table[Idx].KeyOffset != 0 &&
!wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 2)) HashBlock->Table[Idx].KeyOffset != -1 &&
!strncmp(KeyName, (PCHAR) &HashBlock->Table[Idx].HashValue, 4))
{ {
CHECKPOINT;
CurSubKeyBlock = CmiGetBlock(RegistryFile, CurSubKeyBlock = CmiGetBlock(RegistryFile,
HashBlock->Table[Idx].KeyOffset); HashBlock->Table[Idx].KeyOffset);
if (!wcscmp(KeyName, CurSubKeyBlock->Name)) if ( CurSubKeyBlock->NameSize == KeyLength
&& !memcmp(KeyName, CurSubKeyBlock->Name, KeyLength))
{ {
*SubKeyBlock = CurSubKeyBlock; *SubKeyBlock = CurSubKeyBlock;
break; break;
@ -2269,6 +2280,7 @@ CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
} }
} }
} }
CHECKPOINT;
CmiReleaseBlock(RegistryFile, HashBlock); CmiReleaseBlock(RegistryFile, HashBlock);
@ -2279,7 +2291,7 @@ static NTSTATUS
CmiAddSubKey(PREGISTRY_FILE RegistryFile, CmiAddSubKey(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock, PKEY_BLOCK KeyBlock,
PKEY_BLOCK *SubKeyBlock, PKEY_BLOCK *SubKeyBlock,
PWSTR NewSubKeyName, PCHAR NewSubKeyName,
ULONG TitleIndex, ULONG TitleIndex,
PWSTR Class, PWSTR Class,
ULONG CreateOptions) ULONG CreateOptions)
@ -2298,7 +2310,7 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
{ {
return Status; return Status;
} }
if (KeyBlock->HashTableOffset == 0) if (KeyBlock->HashTableOffset == -1)
{ {
Status = CmiAllocateHashTableBlock(RegistryFile, Status = CmiAllocateHashTableBlock(RegistryFile,
&HashBlock, &HashBlock,
@ -2534,29 +2546,24 @@ CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
static NTSTATUS static NTSTATUS
CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile, CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
OUT PKEY_BLOCK *KeyBlock, OUT PKEY_BLOCK *KeyBlock,
IN PWSTR KeyName, IN PCHAR KeyName,
IN ULONG TitleIndex, IN ULONG TitleIndex,
IN PWSTR Class, IN PWSTR Class,
IN ULONG CreateOptions) IN ULONG CreateOptions)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG NewKeySize; ULONG NewBlockSize;
PKEY_BLOCK NewKeyBlock; PKEY_BLOCK NewKeyBlock;
DPRINT("RegistryFile %p KeyBlock %p KeyName %S TitleIndex %x Class %S CreateOptions %x\n", DPRINT("RegistryFile %p KeyBlock %p KeyName %s TitleIndex %x Class %S CreateOptions %x\n",
RegistryFile, KeyBlock, KeyName, TitleIndex, Class,CreateOptions); RegistryFile, KeyBlock, KeyName, TitleIndex, Class,CreateOptions);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
/* Handle volatile files first */ NewBlockSize = sizeof(KEY_BLOCK) + (strlen(KeyName) ) ;
if (RegistryFile->Filename == NULL) DPRINT ("NewKeySize: %lu\n", NewBlockSize);
{
NewKeySize = sizeof(KEY_BLOCK) +
(wcslen(KeyName) + 1) * sizeof(WCHAR) +
(Class != NULL ? (wcslen(Class) + 1) * sizeof(WCHAR) : 0);
DPRINT ("NewKeySize: %lu\n", NewKeySize);
//CHECKPOINT; //CHECKPOINT;
NewKeyBlock = ExAllocatePool(NonPagedPool, NewKeySize); Status = CmiAllocateBlock(RegistryFile, (PVOID) &NewKeyBlock , NewBlockSize);
//CHECKPOINT; //CHECKPOINT;
if (NewKeyBlock == NULL) if (NewKeyBlock == NULL)
{ {
@ -2564,32 +2571,26 @@ DPRINT ("NewKeySize: %lu\n", NewKeySize);
} }
else else
{ {
RtlZeroMemory(NewKeyBlock, NewKeySize); RtlZeroMemory(NewKeyBlock, NewBlockSize);
NewKeyBlock->SubBlockId = REG_KEY_BLOCK_ID; NewKeyBlock->SubBlockId = REG_KEY_BLOCK_ID;
NewKeyBlock->Type = REG_KEY_BLOCK_TYPE; NewKeyBlock->Type = REG_KEY_BLOCK_TYPE;
ZwQuerySystemTime((PTIME) &NewKeyBlock->LastWriteTime); ZwQuerySystemTime((PTIME) &NewKeyBlock->LastWriteTime);
NewKeyBlock->ParentKeyOffset = 0; NewKeyBlock->ParentKeyOffset = -1;
NewKeyBlock->NumberOfSubKeys = 0; NewKeyBlock->NumberOfSubKeys = 0;
NewKeyBlock->HashTableOffset = 0; NewKeyBlock->HashTableOffset = -1;
NewKeyBlock->NumberOfValues = 0; NewKeyBlock->NumberOfValues = 0;
NewKeyBlock->ValuesOffset = 0; NewKeyBlock->ValuesOffset = -1;
NewKeyBlock->SecurityKeyOffset = 0; NewKeyBlock->SecurityKeyOffset = -1;
NewKeyBlock->ClassNameOffset = sizeof(KEY_BLOCK) + wcslen(KeyName); NewKeyBlock->NameSize = strlen(KeyName);
NewKeyBlock->NameSize = wcslen(KeyName);
NewKeyBlock->ClassSize = (Class != NULL) ? wcslen(Class) : 0; NewKeyBlock->ClassSize = (Class != NULL) ? wcslen(Class) : 0;
wcscpy(NewKeyBlock->Name, KeyName); memcpy(NewKeyBlock->Name, KeyName, NewKeyBlock->NameSize );
if (Class != NULL) if (Class != NULL)
{ {
wcscpy(&NewKeyBlock->Name[wcslen(KeyName) + 1], Class); /* FIXME : ClassName is in a different Block !!! */
} }
CmiLockBlock(RegistryFile, NewKeyBlock); CmiLockBlock(RegistryFile, NewKeyBlock);
*KeyBlock = NewKeyBlock; *KeyBlock = NewKeyBlock;
} }
}
else
{
UNIMPLEMENTED;
}
return Status; return Status;
} }
@ -2888,8 +2889,9 @@ CmiGetBlock(PREGISTRY_FILE RegistryFile,
BLOCK_OFFSET BlockOffset) BLOCK_OFFSET BlockOffset)
{ {
PVOID Block; PVOID Block;
long i; DWORD CurBlock;
NTSTATUS Status; NTSTATUS Status;
if( BlockOffset == 0 || BlockOffset == -1) return NULL;
Block = NULL; Block = NULL;
if (RegistryFile->Filename == NULL) if (RegistryFile->Filename == NULL)
@ -2904,17 +2906,18 @@ CmiGetBlock(PREGISTRY_FILE RegistryFile,
HEAP_BLOCK tmpHeap; HEAP_BLOCK tmpHeap;
LARGE_INTEGER fileOffset; LARGE_INTEGER fileOffset;
// search in the heap blocks currently in memory // search in the heap blocks currently in memory
for (i=0; i < RegistryFile->BlockListSize ; i++) for (CurBlock =0; CurBlock < RegistryFile->BlockListSize ; CurBlock ++)
{ {
if ( RegistryFile->BlockList[i]->BlockOffset <= BlockOffset if ( RegistryFile->BlockList[CurBlock ]->BlockOffset <= BlockOffset
&& (RegistryFile->BlockList[i]->BlockOffset && (RegistryFile->BlockList[CurBlock ]->BlockOffset
+RegistryFile->BlockList[i]->BlockSize > BlockOffset )) +RegistryFile->BlockList[CurBlock ]->BlockSize > BlockOffset ))
return ((char *)RegistryFile->BlockList[i] return ((char *)RegistryFile->BlockList[CurBlock ]
+(BlockOffset - RegistryFile->BlockList[i]->BlockOffset)); +(BlockOffset - RegistryFile->BlockList[CurBlock ]->BlockOffset));
} }
// not in memory : read from file /* not in memory : read from file */
/* increase size of list of blocks */
tmpBlockList=ExAllocatePool(NonPagedPool, tmpBlockList=ExAllocatePool(NonPagedPool,
sizeof(PHEAP_BLOCK *)*(i+1)); sizeof(PHEAP_BLOCK *)*(CurBlock +1));
if (tmpBlockList == NULL) if (tmpBlockList == NULL)
{ {
KeBugCheck(0); KeBugCheck(0);
@ -2927,6 +2930,7 @@ CmiGetBlock(PREGISTRY_FILE RegistryFile,
ExFreePool(RegistryFile->BlockList); ExFreePool(RegistryFile->BlockList);
} }
RegistryFile->BlockList = tmpBlockList; RegistryFile->BlockList = tmpBlockList;
/* try to find block at 4K limit under blockOffset */
fileOffset.u.LowPart = (BlockOffset & 0xfffff000)+REG_BLOCK_SIZE; fileOffset.u.LowPart = (BlockOffset & 0xfffff000)+REG_BLOCK_SIZE;
fileOffset.u.HighPart = 0; fileOffset.u.HighPart = 0;
Status = ZwReadFile(RegistryFile->FileHandle, Status = ZwReadFile(RegistryFile->FileHandle,
@ -2934,7 +2938,8 @@ CmiGetBlock(PREGISTRY_FILE RegistryFile,
&tmpHeap, &tmpHeap,
sizeof(HEAP_BLOCK), sizeof(HEAP_BLOCK),
&fileOffset, 0); &fileOffset, 0);
/* FIXME : better is to start from previous block */ /* if it's not a block, try page 4k before ... */
/* FIXME : better is to start from previous block in memory */
while (tmpHeap.BlockId != 0x6e696268 && fileOffset.u.LowPart >= REG_BLOCK_SIZE) while (tmpHeap.BlockId != 0x6e696268 && fileOffset.u.LowPart >= REG_BLOCK_SIZE)
{ {
fileOffset.u.LowPart -= REG_BLOCK_SIZE; fileOffset.u.LowPart -= REG_BLOCK_SIZE;
@ -2946,15 +2951,19 @@ CmiGetBlock(PREGISTRY_FILE RegistryFile,
} }
if (tmpHeap.BlockId != 0x6e696268 ) if (tmpHeap.BlockId != 0x6e696268 )
return NULL; return NULL;
RegistryFile->BlockList [RegistryFile->BlockListSize ++] RegistryFile->BlockListSize ++;
RegistryFile->BlockList [CurBlock]
= ExAllocatePool(NonPagedPool,tmpHeap.BlockSize); = ExAllocatePool(NonPagedPool,tmpHeap.BlockSize);
CHECKPOINT;
Status = ZwReadFile(RegistryFile->FileHandle, Status = ZwReadFile(RegistryFile->FileHandle,
0, 0, 0, 0, 0, 0, 0, 0,
RegistryFile->HeaderBlock, RegistryFile->BlockList[CurBlock ],
tmpHeap.BlockSize, tmpHeap.BlockSize,
&fileOffset, 0); &fileOffset, 0);
return ((char *)RegistryFile->BlockList[i] DPRINT(" read %d block file %x octets at %x, Status=%x\n",CurBlock,tmpHeap.BlockSize,fileOffset.u.LowPart,Status);
+(BlockOffset - RegistryFile->BlockList[i]->BlockOffset)); Block = ((char *)RegistryFile->BlockList[CurBlock]
+(BlockOffset - RegistryFile->BlockList[CurBlock]->BlockOffset));
DPRINT(" hbin at %x, block at %x\n",RegistryFile->BlockList[CurBlock],Block);
} }
return Block; return Block;