-/* $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
* PROJECT: ReactOS kernel
typedef struct _KEY_BLOCK
{
+ DWORD SubBlockSize;
WORD SubBlockId;
WORD Type;
LARGE_INTEGER LastWriteTime;
DWORD Unused4[5];
WORD NameSize;
WORD ClassSize;
-// FIXME : Name is char, not wchar
- WCHAR Name[0];
+ UCHAR Name[0]; /* warning : not zero terminated */
} KEY_BLOCK, *PKEY_BLOCK;
// hash record :
typedef struct _HASH_TABLE_BLOCK
{
+ DWORD SubBlockSize;
WORD SubBlockId;
WORD HashTableSize;
HASH_RECORD Table[0];
typedef struct _VALUE_LIST_BLOCK
{
+ DWORD SubBlockSize;
BLOCK_OFFSET Values[0];
} VALUE_LIST_BLOCK, *PVALUE_LIST_BLOCK;
typedef struct _VALUE_BLOCK
{
+ DWORD SubBlockSize;
WORD SubBlockId; // "kv"
WORD NameSize; // length of Name
DWORD DataSize; // length of datas in the subblock pinted by DataOffset
WORD Flags;
WORD Unused1;
// FIXME : Name is char, not wchar
- WCHAR Name[0];
+ WCHAR Name[0]; /* warning : not zero terminated */
} VALUE_BLOCK, *PVALUE_BLOCK;
typedef struct _IN_MEMORY_BLOCK
static NTSTATUS CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
OUT PKEY_BLOCK *SubKeyBlock,
- IN PWSTR KeyName,
+ IN PCHAR KeyName,
IN ACCESS_MASK DesiredAccess);
static NTSTATUS CmiAddSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK CurKeyBlock,
OUT PKEY_BLOCK *SubKeyBlock,
- IN PWSTR NewSubKeyName,
+ IN PCHAR NewSubKeyName,
IN ULONG TitleIndex,
IN PWSTR Class,
IN ULONG CreateOptions);
IN PWSTR ValueName);
static NTSTATUS CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
OUT PKEY_BLOCK *KeyBlock,
- IN PWSTR NewSubKeyName,
+ IN PCHAR NewSubKeyName,
IN ULONG TitleIndex,
IN PWSTR Class,
IN ULONG CreateOptions);
UNICODE_STRING KeyName;
/* FIXME : delete temporary \Registry\Machine\System */
/* load the SYSTEM Hive */
-CHECKPOINT;
CmiSystemFile = CmiCreateRegistry(SYSTEM_REG_FILE);
if( CmiSystemFile )
{
CmiKeyType);
NewKey->RegistryFile = CmiSystemFile;
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->NextKey = NULL;
- NewKey->Name = NewKey->KeyBlock->Name;
- }
-CHECKPOINT;
/* tests :*/
{
-// HANDLE HKey;
+ HANDLE HKey;
NTSTATUS Status;
PKEY_BLOCK SubKeyBlock;
Status = CmiScanForSubKey(CmiSystemFile,
DPRINT("not found subkey ControlSet001\n");
}
//RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\Windows");
-//RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\ControlSet001");
-// InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
-// Status = NtOpenKey ( &HKey, KEY_READ , &ObjectAttributes);
-
+RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\ControlSet001");
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
+ Status = NtOpenKey ( &HKey, KEY_READ , &ObjectAttributes);
+DPRINT(" NtOpenKey = %x, HKey=%x\n",Status,HKey);
}
+ }
#endif
}
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
BasicInformation->TitleIndex = Index;
BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
- wcsncpy(BasicInformation->Name,
+ mbstowcs(BasicInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
BasicInformation->Name[SubKeyBlock->NameSize] = 0;
SubKeyBlock->NameSize * sizeof(WCHAR);
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
- wcsncpy(NodeInformation->Name,
+ mbstowcs(NodeInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
NodeInformation->Name[SubKeyBlock->NameSize] = 0;
if (SubKeyBlock->ClassSize != 0)
{
wcsncpy(NodeInformation->Name + SubKeyBlock->NameSize + 1,
- &SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
+ (PWSTR)&SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
SubKeyBlock->ClassSize);
NodeInformation->
Name[SubKeyBlock->NameSize + 1 + SubKeyBlock->ClassSize] = 0;
FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, SubKeyBlock);
wcsncpy(FullInformation->Class,
- &SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
+ (PWSTR)&SubKeyBlock->Name[SubKeyBlock->NameSize + 1],
SubKeyBlock->ClassSize);
FullInformation->Class[SubKeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) +
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
BasicInformation->TitleIndex = 0;
BasicInformation->NameLength = KeyBlock->NameSize;
- wcsncpy(BasicInformation->Name,
+ mbstowcs(BasicInformation->Name,
KeyBlock->Name,
KeyBlock->NameSize);
BasicInformation->Name[KeyBlock->NameSize] = 0;
KeyBlock->NameSize * sizeof(WCHAR);
NodeInformation->ClassLength = KeyBlock->ClassSize;
NodeInformation->NameLength = KeyBlock->NameSize;
- wcsncpy(NodeInformation->Name,
+ mbstowcs(NodeInformation->Name,
KeyBlock->Name,
KeyBlock->NameSize);
NodeInformation->Name[KeyBlock->NameSize] = 0;
if (KeyBlock->ClassSize != 0)
{
wcsncpy(NodeInformation->Name + KeyBlock->NameSize + 1,
- &KeyBlock->Name[KeyBlock->NameSize + 1],
+ (PWSTR)&KeyBlock->Name[KeyBlock->NameSize + 1],
KeyBlock->ClassSize);
NodeInformation->
Name[KeyBlock->NameSize + 1 + KeyBlock->ClassSize] = 0;
FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, KeyBlock);
wcsncpy(FullInformation->Class,
- &KeyBlock->Name[KeyBlock->NameSize + 1],
+ (PWSTR)&KeyBlock->Name[KeyBlock->NameSize + 1],
KeyBlock->ClassSize);
FullInformation->Class[KeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) +
{
NTSTATUS Status;
/* FIXME: this should be allocated based on the largest subkey name */
- WCHAR CurKeyName[260];
+ CHAR CurKeyName[260];
PWSTR Remainder, NextSlash;
PREGISTRY_FILE RegistryFile;
PKEY_OBJECT NewKeyObject;
/* Copy just the current subkey name to a buffer */
if (NextSlash != NULL)
{
- wcsncpy(CurKeyName, Remainder, NextSlash - Remainder);
+ wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0;
}
else
{
- wcscpy(CurKeyName, Remainder);
+ wcstombs(CurKeyName, Remainder, wcslen(Remainder) + 1);
}
/* Verify existance of CurKeyName */
ZwQuerySystemTime((PTIME) &RootKeyBlock->LastWriteTime);
RootKeyBlock->ParentKeyOffset = 0;
RootKeyBlock->NumberOfSubKeys = 0;
- RootKeyBlock->HashTableOffset = 0;
+ RootKeyBlock->HashTableOffset = -1;
RootKeyBlock->NumberOfValues = 0;
- RootKeyBlock->ValuesOffset = 0;
+ RootKeyBlock->ValuesOffset = -1;
RootKeyBlock->SecurityKeyOffset = 0;
- RootKeyBlock->ClassNameOffset = sizeof(KEY_BLOCK);
+ RootKeyBlock->ClassNameOffset = -1;
RootKeyBlock->NameSize = 0;
RootKeyBlock->ClassSize = 0;
- RootKeyBlock->Name[0] = 0;
RegistryFile->HeaderBlock->RootKeyBlock = (BLOCK_OFFSET) RootKeyBlock;
}
{
/* FIXME: this should be allocated based on the largest subkey name */
NTSTATUS Status;
- WCHAR CurKeyName[256];
+ CHAR CurKeyName[256];
PWSTR ClassName;
PWSTR Remainder, NextSlash;
PKEY_BLOCK CurKeyBlock, SubKeyBlock;
(NextSlash = wcschr(Remainder, L'\\')) != NULL)
{
/* Copy just the current subkey name to a buffer */
- wcsncpy(CurKeyName, Remainder, NextSlash - Remainder);
+ wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0;
/* Verify existance of/Create CurKeyName */
{
ClassName = NULL;
}
+ wcstombs(CurKeyName, Remainder, wcslen(Remainder)+1 );
+ CurKeyName[ wcslen(Remainder)] = 0;
Status = CmiAddSubKey(RegistryFile,
CurKeyBlock,
&SubKeyBlock,
- Remainder,
+ CurKeyName,
TitleIndex,
ClassName,
CreateOptions);
{
/* FIXME: this should be allocated based on the largest subkey name */
NTSTATUS Status;
- WCHAR CurKeyName[256];
+ CHAR CurKeyName[MAX_PATH];
PWSTR Remainder, NextSlash;
PKEY_BLOCK CurKeyBlock, SubKeyBlock;
/* FIXME: this access of RootKeyBlock should be guarded by spinlock */
CurKeyBlock = CmiGetBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock);
Remainder = KeyNameBuf;
- wcscpy(CurKeyName, Remainder);
+ wcstombs(CurKeyName, Remainder, wcslen(Remainder) + 1 );
while (NT_SUCCESS(Status) &&
(NextSlash = wcschr(Remainder, L'\\')) != NULL)
{
/* Copy just the current subkey name to a buffer */
- wcsncpy(CurKeyName, Remainder, NextSlash - Remainder);
+ wcstombs(CurKeyName, Remainder, NextSlash - Remainder);
CurKeyName[NextSlash - Remainder] = 0;
/* Verify existance of CurKeyName */
CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
OUT PKEY_BLOCK *SubKeyBlock,
- IN PWSTR KeyName,
+ IN PCHAR KeyName,
IN ACCESS_MASK DesiredAccess)
{
ULONG Idx;
PHASH_TABLE_BLOCK HashBlock;
PKEY_BLOCK CurSubKeyBlock;
+ WORD KeyLength = strlen(KeyName);
HashBlock = CmiGetBlock(RegistryFile, KeyBlock->HashTableOffset);
*SubKeyBlock = NULL;
- if (HashBlock == 0)
+ if (HashBlock == NULL)
{
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 &&
- !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,
HashBlock->Table[Idx].KeyOffset);
- if (!wcscmp(KeyName, CurSubKeyBlock->Name))
+ if ( CurSubKeyBlock->NameSize == KeyLength
+ && !memcmp(KeyName, CurSubKeyBlock->Name, KeyLength))
{
*SubKeyBlock = CurSubKeyBlock;
break;
}
}
}
+CHECKPOINT;
CmiReleaseBlock(RegistryFile, HashBlock);
CmiAddSubKey(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock,
PKEY_BLOCK *SubKeyBlock,
- PWSTR NewSubKeyName,
+ PCHAR NewSubKeyName,
ULONG TitleIndex,
PWSTR Class,
ULONG CreateOptions)
{
return Status;
}
- if (KeyBlock->HashTableOffset == 0)
+ if (KeyBlock->HashTableOffset == -1)
{
Status = CmiAllocateHashTableBlock(RegistryFile,
&HashBlock,
static NTSTATUS
CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
OUT PKEY_BLOCK *KeyBlock,
- IN PWSTR KeyName,
+ IN PCHAR KeyName,
IN ULONG TitleIndex,
IN PWSTR Class,
IN ULONG CreateOptions)
{
NTSTATUS Status;
- ULONG NewKeySize;
+ ULONG NewBlockSize;
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);
Status = STATUS_SUCCESS;
- /* Handle volatile files first */
- if (RegistryFile->Filename == NULL)
- {
- NewKeySize = sizeof(KEY_BLOCK) +
- (wcslen(KeyName) + 1) * sizeof(WCHAR) +
- (Class != NULL ? (wcslen(Class) + 1) * sizeof(WCHAR) : 0);
-DPRINT ("NewKeySize: %lu\n", NewKeySize);
+ NewBlockSize = sizeof(KEY_BLOCK) + (strlen(KeyName) ) ;
+DPRINT ("NewKeySize: %lu\n", NewBlockSize);
//CHECKPOINT;
- NewKeyBlock = ExAllocatePool(NonPagedPool, NewKeySize);
+ Status = CmiAllocateBlock(RegistryFile, (PVOID) &NewKeyBlock , NewBlockSize);
//CHECKPOINT;
if (NewKeyBlock == NULL)
{
}
else
{
- RtlZeroMemory(NewKeyBlock, NewKeySize);
+ RtlZeroMemory(NewKeyBlock, NewBlockSize);
NewKeyBlock->SubBlockId = REG_KEY_BLOCK_ID;
NewKeyBlock->Type = REG_KEY_BLOCK_TYPE;
ZwQuerySystemTime((PTIME) &NewKeyBlock->LastWriteTime);
- NewKeyBlock->ParentKeyOffset = 0;
+ NewKeyBlock->ParentKeyOffset = -1;
NewKeyBlock->NumberOfSubKeys = 0;
- NewKeyBlock->HashTableOffset = 0;
+ NewKeyBlock->HashTableOffset = -1;
NewKeyBlock->NumberOfValues = 0;
- NewKeyBlock->ValuesOffset = 0;
- NewKeyBlock->SecurityKeyOffset = 0;
- NewKeyBlock->ClassNameOffset = sizeof(KEY_BLOCK) + wcslen(KeyName);
- NewKeyBlock->NameSize = wcslen(KeyName);
+ NewKeyBlock->ValuesOffset = -1;
+ NewKeyBlock->SecurityKeyOffset = -1;
+ NewKeyBlock->NameSize = strlen(KeyName);
NewKeyBlock->ClassSize = (Class != NULL) ? wcslen(Class) : 0;
- wcscpy(NewKeyBlock->Name, KeyName);
+ memcpy(NewKeyBlock->Name, KeyName, NewKeyBlock->NameSize );
if (Class != NULL)
{
- wcscpy(&NewKeyBlock->Name[wcslen(KeyName) + 1], Class);
+ /* FIXME : ClassName is in a different Block !!! */
}
CmiLockBlock(RegistryFile, NewKeyBlock);
*KeyBlock = NewKeyBlock;
}
- }
- else
- {
- UNIMPLEMENTED;
- }
return Status;
}
BLOCK_OFFSET BlockOffset)
{
PVOID Block;
- long i;
+ DWORD CurBlock;
NTSTATUS Status;
+ if( BlockOffset == 0 || BlockOffset == -1) return NULL;
Block = NULL;
if (RegistryFile->Filename == NULL)
HEAP_BLOCK tmpHeap;
LARGE_INTEGER fileOffset;
// 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
- && (RegistryFile->BlockList[i]->BlockOffset
- +RegistryFile->BlockList[i]->BlockSize > BlockOffset ))
- return ((char *)RegistryFile->BlockList[i]
- +(BlockOffset - RegistryFile->BlockList[i]->BlockOffset));
+ if ( RegistryFile->BlockList[CurBlock ]->BlockOffset <= BlockOffset
+ && (RegistryFile->BlockList[CurBlock ]->BlockOffset
+ +RegistryFile->BlockList[CurBlock ]->BlockSize > BlockOffset ))
+ return ((char *)RegistryFile->BlockList[CurBlock ]
+ +(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,
- sizeof(PHEAP_BLOCK *)*(i+1));
+ sizeof(PHEAP_BLOCK *)*(CurBlock +1));
if (tmpBlockList == NULL)
{
KeBugCheck(0);
ExFreePool(RegistryFile->BlockList);
}
RegistryFile->BlockList = tmpBlockList;
+ /* try to find block at 4K limit under blockOffset */
fileOffset.u.LowPart = (BlockOffset & 0xfffff000)+REG_BLOCK_SIZE;
fileOffset.u.HighPart = 0;
Status = ZwReadFile(RegistryFile->FileHandle,
&tmpHeap,
sizeof(HEAP_BLOCK),
&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)
{
fileOffset.u.LowPart -= REG_BLOCK_SIZE;
}
if (tmpHeap.BlockId != 0x6e696268 )
return NULL;
- RegistryFile->BlockList [RegistryFile->BlockListSize ++]
+ RegistryFile->BlockListSize ++;
+ RegistryFile->BlockList [CurBlock]
= ExAllocatePool(NonPagedPool,tmpHeap.BlockSize);
+CHECKPOINT;
Status = ZwReadFile(RegistryFile->FileHandle,
0, 0, 0, 0,
- RegistryFile->HeaderBlock,
+ RegistryFile->BlockList[CurBlock ],
tmpHeap.BlockSize,
&fileOffset, 0);
- return ((char *)RegistryFile->BlockList[i]
- +(BlockOffset - RegistryFile->BlockList[i]->BlockOffset));
+DPRINT(" read %d block file %x octets at %x, Status=%x\n",CurBlock,tmpHeap.BlockSize,fileOffset.u.LowPart,Status);
+ Block = ((char *)RegistryFile->BlockList[CurBlock]
+ +(BlockOffset - RegistryFile->BlockList[CurBlock]->BlockOffset));
+DPRINT(" hbin at %x, block at %x\n",RegistryFile->BlockList[CurBlock],Block);
}
return Block;