many bugs corrected

now pass OK tests 1,2,3 and 5 of regtest

svn path=/trunk/; revision=1438
This commit is contained in:
jean 2000-11-27 14:54:28 +00:00
parent c07ef00211
commit bd1cb1e820

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.50 2000/11/21 15:10:15 jean Exp $ /* $Id: registry.c,v 1.51 2000/11/27 14:54:28 jean Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -28,9 +28,9 @@
#define REG_HEAP_BLOCK_DATA_OFFSET 32 #define REG_HEAP_BLOCK_DATA_OFFSET 32
#define REG_HEAP_ID 0x6e696268 #define REG_HEAP_ID 0x6e696268
#define REG_INIT_BLOCK_LIST_SIZE 32 #define REG_INIT_BLOCK_LIST_SIZE 32
#define REG_INIT_HASH_TABLE_SIZE 32 #define REG_INIT_HASH_TABLE_SIZE 3
#define REG_EXTEND_HASH_TABLE_SIZE 32 #define REG_EXTEND_HASH_TABLE_SIZE 4
#define REG_VALUE_LIST_BLOCK_MULTIPLE 32 #define REG_VALUE_LIST_BLOCK_MULTIPLE 4
#define REG_KEY_BLOCK_ID 0x6b6e #define REG_KEY_BLOCK_ID 0x6b6e
#define REG_HASH_TABLE_BLOCK_ID 0x666c #define REG_HASH_TABLE_BLOCK_ID 0x666c
#define REG_VALUE_BLOCK_ID 0x6b76 #define REG_VALUE_BLOCK_ID 0x6b76
@ -142,8 +142,8 @@ typedef struct _VALUE_BLOCK
LONG SubBlockSize; LONG SubBlockSize;
WORD SubBlockId; // "kv" WORD SubBlockId; // "kv"
WORD NameSize; // length of Name WORD NameSize; // length of Name
LONG DataSize; // length of datas in the subblock pinted by DataOffset LONG DataSize; // length of datas in the subblock pointed by DataOffset
BLOCK_OFFSET DataOffset; // datas are here if DataSize <=4 BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set
DWORD DataType; DWORD DataType;
WORD Flags; WORD Flags;
WORD Unused1; WORD Unused1;
@ -262,14 +262,11 @@ static NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock, IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueNameBuf, IN PCHAR ValueNameBuf,
IN ULONG Type, OUT PVALUE_BLOCK *pValueBlock,
IN PVOID Data, OUT BLOCK_OFFSET *pVBOffset);
IN LONG DataSize);
static NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock, IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueName); IN PCHAR ValueName);
static NTSTATUS CmiDestroyKeyBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
OUT PHASH_TABLE_BLOCK *HashBlock, OUT PHASH_TABLE_BLOCK *HashBlock,
OUT BLOCK_OFFSET *HBOffset, OUT BLOCK_OFFSET *HBOffset,
@ -281,16 +278,10 @@ static NTSTATUS CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashBlock, PHASH_TABLE_BLOCK HashBlock,
PKEY_BLOCK NewKeyBlock, PKEY_BLOCK NewKeyBlock,
BLOCK_OFFSET NKBOffset); BLOCK_OFFSET NKBOffset);
static NTSTATUS CmiDestroyHashTableBlock(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashBlock,
BLOCK_OFFSET Offset);
static NTSTATUS CmiAllocateValueBlock(IN PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAllocateValueBlock(IN PREGISTRY_FILE RegistryFile,
OUT PVALUE_BLOCK *ValueBlock, OUT PVALUE_BLOCK *ValueBlock,
OUT BLOCK_OFFSET *VBOffset, OUT BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf, IN PCHAR ValueNameBuf);
IN ULONG Type,
IN PVOID Data,
IN LONG DataSize);
static NTSTATUS CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile, static NTSTATUS CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
PVALUE_BLOCK ValueBlock, BLOCK_OFFSET VBOffset); PVALUE_BLOCK ValueBlock, BLOCK_OFFSET VBOffset);
static NTSTATUS CmiAllocateBlock(PREGISTRY_FILE RegistryFile, static NTSTATUS CmiAllocateBlock(PREGISTRY_FILE RegistryFile,
@ -976,7 +967,7 @@ NtEnumerateValueKey (
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL); DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL);
RtlCopyMemory(ValuePartialInformation->Data, RtlCopyMemory(ValuePartialInformation->Data,
DataBlock->Data, DataBlock->Data,
ValueBlock->DataSize); ValueBlock->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryFile, DataBlock); CmiReleaseBlock(RegistryFile, DataBlock);
} }
else else
@ -1018,7 +1009,7 @@ NtEnumerateValueKey (
RtlCopyMemory((char *)(ValueFullInformation) RtlCopyMemory((char *)(ValueFullInformation)
+ ValueFullInformation->DataOffset, + ValueFullInformation->DataOffset,
DataBlock->Data, DataBlock->Data,
ValueBlock->DataSize); ValueBlock->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryFile, DataBlock); CmiReleaseBlock(RegistryFile, DataBlock);
} }
else else
@ -1053,7 +1044,7 @@ NtFlushKey (
PREGISTRY_FILE RegistryFile; PREGISTRY_FILE RegistryFile;
WCHAR LogName[MAX_PATH]; WCHAR LogName[MAX_PATH];
HANDLE FileHandle; HANDLE FileHandle;
HANDLE FileHandleLog; // HANDLE FileHandleLog;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
// KIRQL OldIrql; // KIRQL OldIrql;
UNICODE_STRING TmpFileName; UNICODE_STRING TmpFileName;
@ -1068,25 +1059,6 @@ NtFlushKey (
NULL); NULL);
RegistryFile = KeyObject->RegistryFile; RegistryFile = KeyObject->RegistryFile;
// KeAcquireSpinLock(&RegistryFile->RegLock, &OldIrql); // KeAcquireSpinLock(&RegistryFile->RegLock, &OldIrql);
/* update header of registryfile */
RtlInitUnicodeString (&TmpFileName, RegistryFile->Filename);
InitializeObjectAttributes(&ObjectAttributes,
&TmpFileName,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
NULL, 0, 0);
RegistryFile->HeaderBlock->Version++;
Status = ZwWriteFile(FileHandle,
0, 0, 0, 0,
RegistryFile->HeaderBlock,
sizeof(HEADER_BLOCK),
0, 0);
/* then write changed blocks in .log */ /* then write changed blocks in .log */
wcscpy(LogName,RegistryFile->Filename ); wcscpy(LogName,RegistryFile->Filename );
wcscat(LogName,L".log"); wcscat(LogName,L".log");
@ -1096,6 +1068,8 @@ NtFlushKey (
0, 0,
NULL, NULL,
NULL); NULL);
/* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files
so we can't create log file
Status = ZwCreateFile(&FileHandleLog, Status = ZwCreateFile(&FileHandleLog,
FILE_ALL_ACCESS, FILE_ALL_ACCESS,
&ObjectAttributes, &ObjectAttributes,
@ -1122,6 +1096,27 @@ NtFlushKey (
0, 0); 0, 0);
} }
ZwClose(FileHandleLog); ZwClose(FileHandleLog);
END FIXME*/
/* update header of registryfile with Version >VersionOld */
/* this allow recover if system crash while updating hove file */
RtlInitUnicodeString (&TmpFileName, RegistryFile->Filename);
InitializeObjectAttributes(&ObjectAttributes,
&TmpFileName,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
NULL, 0, 0);
RegistryFile->HeaderBlock->Version++;
Status = ZwWriteFile(FileHandle,
0, 0, 0, 0,
RegistryFile->HeaderBlock,
sizeof(HEADER_BLOCK),
0, 0);
/* update changed blocks in file */ /* update changed blocks in file */
fileOffset.u.HighPart = 0; fileOffset.u.HighPart = 0;
for (i=0; i < RegistryFile->BlockListSize ; i++) for (i=0; i < RegistryFile->BlockListSize ; i++)
@ -1475,7 +1470,7 @@ NtQueryValueKey (
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL); DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL);
RtlCopyMemory(ValuePartialInformation->Data, RtlCopyMemory(ValuePartialInformation->Data,
DataBlock->Data, DataBlock->Data,
ValueBlock->DataSize); ValueBlock->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryFile, DataBlock); CmiReleaseBlock(RegistryFile, DataBlock);
} }
else else
@ -1516,7 +1511,7 @@ NtQueryValueKey (
RtlCopyMemory((char *)(ValueFullInformation) RtlCopyMemory((char *)(ValueFullInformation)
+ ValueFullInformation->DataOffset, + ValueFullInformation->DataOffset,
DataBlock->Data, DataBlock->Data,
ValueBlock->DataSize); ValueBlock->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryFile, DataBlock); CmiReleaseBlock(RegistryFile, DataBlock);
} }
else else
@ -1558,7 +1553,7 @@ NtSetValueKey (
PVALUE_BLOCK ValueBlock; PVALUE_BLOCK ValueBlock;
BLOCK_OFFSET VBOffset; BLOCK_OFFSET VBOffset;
char ValueName2[MAX_PATH]; char ValueName2[MAX_PATH];
PVOID DataBlock, NewDataBlock; PDATA_BLOCK DataBlock, NewDataBlock;
PHEAP_BLOCK pHeap; PHEAP_BLOCK pHeap;
// KIRQL OldIrql; // KIRQL OldIrql;
@ -1593,17 +1588,34 @@ NtSetValueKey (
Status = CmiAddValueToKey(RegistryFile, Status = CmiAddValueToKey(RegistryFile,
KeyBlock, KeyBlock,
ValueName2, ValueName2,
Type, &ValueBlock,
Data, &VBOffset);
DataSize); }
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (KeyObject);
return Status;
} }
else else
{ {
/* FIXME if datasize <=4 then write in valueblock directly */
if (DataSize <= 4)
{
if (( ValueBlock->DataSize <0 )
&& (DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL)))
{
CmiDestroyBlock(RegistryFile, DataBlock, ValueBlock->DataOffset);
}
RtlCopyMemory(&ValueBlock->DataOffset, Data, DataSize);
ValueBlock->DataSize = DataSize | 0x80000000;
ValueBlock->DataType = Type;
memcpy(&ValueBlock->DataOffset, Data, DataSize);
}
/* If new data size is <= current then overwrite current data */ /* If new data size is <= current then overwrite current data */
if (DataSize <= ValueBlock->DataSize) else if (DataSize <= (ValueBlock->DataSize & 0x7fffffff))
{ {
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,&pHeap); DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,&pHeap);
RtlCopyMemory(DataBlock, Data, DataSize); RtlCopyMemory(DataBlock->Data, Data, DataSize);
ValueBlock->DataSize = DataSize; ValueBlock->DataSize = DataSize;
ValueBlock->DataType = Type; ValueBlock->DataType = Type;
CmiReleaseBlock(RegistryFile, DataBlock); CmiReleaseBlock(RegistryFile, DataBlock);
@ -1615,15 +1627,18 @@ NtSetValueKey (
{ {
BLOCK_OFFSET NewOffset; BLOCK_OFFSET NewOffset;
/* Destroy current data block and allocate a new one */ /* Destroy current data block and allocate a new one */
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL); if (( ValueBlock->DataSize <0 )
&& (DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,NULL)))
{
CmiDestroyBlock(RegistryFile, DataBlock, ValueBlock->DataOffset);
}
Status = CmiAllocateBlock(RegistryFile, Status = CmiAllocateBlock(RegistryFile,
&NewDataBlock, (PVOID *)&NewDataBlock,
DataSize,&NewOffset); DataSize,&NewOffset);
RtlCopyMemory(NewDataBlock, Data, DataSize); RtlCopyMemory(&NewDataBlock->Data[0], Data, DataSize);
ValueBlock->DataSize = DataSize; ValueBlock->DataSize = DataSize;
ValueBlock->DataType = Type; ValueBlock->DataType = Type;
CmiReleaseBlock(RegistryFile, NewDataBlock); CmiReleaseBlock(RegistryFile, NewDataBlock);
CmiDestroyBlock(RegistryFile, DataBlock, ValueBlock->DataOffset);
ValueBlock->DataOffset = NewOffset; ValueBlock->DataOffset = NewOffset;
} }
/* update time of heap */ /* update time of heap */
@ -2167,8 +2182,9 @@ DPRINT("delete object key\n");
if (KeyObject->Flags & KO_MARKED_FOR_DELETE) if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
{ {
DPRINT1("delete really key\n"); DPRINT1("delete really key\n");
CmiDestroyKeyBlock(KeyObject->RegistryFile, CmiDestroyBlock(KeyObject->RegistryFile,
KeyObject->KeyBlock); KeyObject->KeyBlock,
KeyObject->BlockOffset);
} }
else else
{ {
@ -2343,6 +2359,9 @@ CmiCreateRegistry(PWSTR Filename)
,Status,fileOffset.u.LowPart); ,Status,fileOffset.u.LowPart);
return NULL; return NULL;
} }
RegistryFile->FreeListSize = 0;
RegistryFile->FreeListMax = 0;
RegistryFile->FreeList = NULL;
for(i=0 ; i <RegistryFile->BlockListSize; i++) for(i=0 ; i <RegistryFile->BlockListSize; i++)
{ {
tmpHeap = (PHEAP_BLOCK)(((char *)RegistryFile->BlockList [0])+BlockOffset); tmpHeap = (PHEAP_BLOCK)(((char *)RegistryFile->BlockList [0])+BlockOffset);
@ -2375,9 +2394,6 @@ CmiCreateRegistry(PWSTR Filename)
} }
BlockOffset += tmpHeap->BlockSize; BlockOffset += tmpHeap->BlockSize;
} }
RegistryFile->FreeListSize = 0;
RegistryFile->FreeListMax = 0;
RegistryFile->FreeList = NULL;
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_ALL_ACCESS, FILE_ALL_ACCESS,
IoFileObjectType, IoFileObjectType,
@ -2641,7 +2657,6 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
} }
else else
{ {
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);
@ -2675,7 +2690,9 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
SubKey->BlockOffset = NKBOffset; SubKey->BlockOffset = NKBOffset;
/* don't modify hash table if key is volatile and parent is not */ /* don't modify hash table if key is volatile and parent is not */
if (RegistryFile == CmiVolatileFile && Parent->RegistryFile != RegistryFile) if (RegistryFile == CmiVolatileFile && Parent->RegistryFile != RegistryFile)
{
return Status; return Status;
}
if (KeyBlock->HashTableOffset == -1) if (KeyBlock->HashTableOffset == -1)
{ {
Status = CmiAllocateHashTableBlock(RegistryFile, Status = CmiAllocateHashTableBlock(RegistryFile,
@ -2709,8 +2726,8 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
RtlCopyMemory(&NewHashBlock->Table[0], RtlCopyMemory(&NewHashBlock->Table[0],
&HashBlock->Table[0], &HashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
CmiDestroyHashTableBlock(RegistryFile, HashBlock CmiDestroyBlock(RegistryFile, HashBlock
, HTOffset); , KeyBlock->HashTableOffset);
KeyBlock->HashTableOffset = HTOffset; KeyBlock->HashTableOffset = HTOffset;
HashBlock = NewHashBlock; HashBlock = NewHashBlock;
} }
@ -2752,7 +2769,7 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
!_strnicmp(CurValueBlock->Name, ValueName,strlen(ValueName))) !_strnicmp(CurValueBlock->Name, ValueName,strlen(ValueName)))
{ {
*ValueBlock = CurValueBlock; *ValueBlock = CurValueBlock;
*VBOffset = ValueListBlock->Values[Idx]; if(VBOffset) *VBOffset = ValueListBlock->Values[Idx];
break; break;
} }
CmiReleaseBlock(RegistryFile, CurValueBlock); CmiReleaseBlock(RegistryFile, CurValueBlock);
@ -2799,23 +2816,20 @@ static NTSTATUS
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile, CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock, IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueNameBuf, IN PCHAR ValueNameBuf,
IN ULONG Type, OUT PVALUE_BLOCK *pValueBlock,
IN PVOID Data, OUT BLOCK_OFFSET *pVBOffset)
IN LONG DataSize)
{ {
NTSTATUS Status; NTSTATUS Status;
PVALUE_LIST_BLOCK ValueListBlock, NewValueListBlock; PVALUE_LIST_BLOCK ValueListBlock, NewValueListBlock;
PVALUE_BLOCK ValueBlock;
BLOCK_OFFSET VBOffset; BLOCK_OFFSET VBOffset;
BLOCK_OFFSET VLBOffset; BLOCK_OFFSET VLBOffset;
PVALUE_BLOCK NewValueBlock;
Status = CmiAllocateValueBlock(RegistryFile, Status = CmiAllocateValueBlock(RegistryFile,
&ValueBlock, &NewValueBlock,
&VBOffset, &VBOffset,
ValueNameBuf, ValueNameBuf);
Type, *pVBOffset=VBOffset;
Data,
DataSize);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
@ -2826,17 +2840,18 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
{ {
Status = CmiAllocateBlock(RegistryFile, Status = CmiAllocateBlock(RegistryFile,
(PVOID) &ValueListBlock, (PVOID) &ValueListBlock,
sizeof(BLOCK_OFFSET) * sizeof(BLOCK_OFFSET) * 3,
REG_VALUE_LIST_BLOCK_MULTIPLE,&VLBOffset); &VLBOffset);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
CmiDestroyValueBlock(RegistryFile, CmiDestroyValueBlock(RegistryFile,
ValueBlock,VBOffset); NewValueBlock,VBOffset);
return Status; return Status;
} }
KeyBlock->ValuesOffset = VLBOffset; KeyBlock->ValuesOffset = VLBOffset;
} }
else if ( ! (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)) else if ( KeyBlock->NumberOfValues
>= -(ValueListBlock->SubBlockSize-4)/sizeof(BLOCK_OFFSET))
{ {
Status = CmiAllocateBlock(RegistryFile, Status = CmiAllocateBlock(RegistryFile,
(PVOID) &NewValueListBlock, (PVOID) &NewValueListBlock,
@ -2846,11 +2861,11 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
CmiDestroyValueBlock(RegistryFile, CmiDestroyValueBlock(RegistryFile,
ValueBlock,VBOffset); NewValueBlock,VBOffset);
return Status; return Status;
} }
RtlCopyMemory(NewValueListBlock, RtlCopyMemory(&NewValueListBlock->Values[0],
ValueListBlock, &ValueListBlock->Values[0],
sizeof(BLOCK_OFFSET) * KeyBlock->NumberOfValues); sizeof(BLOCK_OFFSET) * KeyBlock->NumberOfValues);
CmiDestroyBlock(RegistryFile, ValueListBlock,KeyBlock->ValuesOffset); CmiDestroyBlock(RegistryFile, ValueListBlock,KeyBlock->ValuesOffset);
KeyBlock->ValuesOffset = VLBOffset; KeyBlock->ValuesOffset = VLBOffset;
@ -2859,7 +2874,8 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
ValueListBlock->Values[KeyBlock->NumberOfValues] = VBOffset; ValueListBlock->Values[KeyBlock->NumberOfValues] = VBOffset;
KeyBlock->NumberOfValues++; KeyBlock->NumberOfValues++;
CmiReleaseBlock(RegistryFile, ValueListBlock); CmiReleaseBlock(RegistryFile, ValueListBlock);
CmiReleaseBlock(RegistryFile, ValueBlock); CmiReleaseBlock(RegistryFile, NewValueBlock);
*pValueBlock = NewValueBlock;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -2915,29 +2931,6 @@ CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS
CmiDestroyKeyBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
NTSTATUS Status;
Status = STATUS_SUCCESS;
if (RegistryFile->Filename == NULL)
{
CmiReleaseBlock(RegistryFile, KeyBlock);
ExFreePool(KeyBlock);
}
else
{
KeyBlock->SubBlockSize = -KeyBlock->SubBlockSize;
/* FIXME : set first dword to block_offset of another free bloc ? */
/* FIXME : concatenate with previous and next block if free */
}
return Status;
}
static NTSTATUS static NTSTATUS
CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile, CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
OUT PHASH_TABLE_BLOCK *HashBlock, OUT PHASH_TABLE_BLOCK *HashBlock,
@ -2961,7 +2954,6 @@ CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
} }
else else
{ {
RtlZeroMemory(NewHashBlock, NewHashSize);
NewHashBlock->SubBlockId = REG_HASH_TABLE_BLOCK_ID; NewHashBlock->SubBlockId = REG_HASH_TABLE_BLOCK_ID;
NewHashBlock->HashTableSize = HashTableSize; NewHashBlock->HashTableSize = HashTableSize;
*HashBlock = NewHashBlock; *HashBlock = NewHashBlock;
@ -3016,48 +3008,15 @@ CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
static NTSTATUS
CmiDestroyHashTableBlock(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashBlock,
BLOCK_OFFSET Offset)
{
NTSTATUS Status;
PHEAP_BLOCK pHeap;
Status = STATUS_SUCCESS;
if (RegistryFile->Filename == NULL)
{
CmiReleaseBlock(RegistryFile, HashBlock);
ExFreePool(HashBlock);
}
else
{
if (HashBlock->SubBlockSize <0)
HashBlock->SubBlockSize = HashBlock->SubBlockSize;
CmiAddFree(RegistryFile, (PFREE_SUB_BLOCK) HashBlock, Offset);
CmiReleaseBlock(RegistryFile, HashBlock);
/* update time of heap */
if(RegistryFile->Filename && CmiGetBlock(RegistryFile, Offset,&pHeap))
ZwQuerySystemTime((PTIME) &pHeap->DateModified);
}
return Status;
}
static NTSTATUS static NTSTATUS
CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile, CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
PVALUE_BLOCK *ValueBlock, PVALUE_BLOCK *ValueBlock,
BLOCK_OFFSET *VBOffset, BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf, IN PCHAR ValueNameBuf)
IN ULONG Type,
IN PVOID Data,
IN LONG DataSize)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG NewValueSize; ULONG NewValueSize;
PVALUE_BLOCK NewValueBlock; PVALUE_BLOCK NewValueBlock;
PDATA_BLOCK DataBlock;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
@ -3071,27 +3030,14 @@ CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
} }
else else
{ {
RtlZeroMemory(NewValueBlock, NewValueSize);
NewValueBlock->SubBlockId = REG_VALUE_BLOCK_ID; NewValueBlock->SubBlockId = REG_VALUE_BLOCK_ID;
NewValueBlock->NameSize = strlen(ValueNameBuf); NewValueBlock->NameSize = strlen(ValueNameBuf);
memcpy(NewValueBlock->Name, ValueNameBuf,strlen(ValueNameBuf)); memcpy(NewValueBlock->Name, ValueNameBuf,strlen(ValueNameBuf));
NewValueBlock->DataType = Type; NewValueBlock->DataType = 0;
NewValueBlock->DataSize = DataSize; NewValueBlock->DataSize = 0;
Status = CmiAllocateBlock(RegistryFile, NewValueBlock->DataOffset = 0xffffffff;
(PVOID*)&DataBlock,
DataSize,&NewValueBlock->DataOffset);
if (!NT_SUCCESS(Status))
{
CmiDestroyBlock(RegistryFile,NewValueBlock,*VBOffset);
}
else
{
RtlCopyMemory(DataBlock->Data, Data, DataSize);
CmiLockBlock(RegistryFile, NewValueBlock);
CmiReleaseBlock(RegistryFile, DataBlock);
*ValueBlock = NewValueBlock; *ValueBlock = NewValueBlock;
} }
}
return Status; return Status;
} }
@ -3105,7 +3051,7 @@ CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
PVOID pBlock; PVOID pBlock;
/* first, release datas : */ /* first, release datas : */
if (ValueBlock->DataSize <0) if (ValueBlock->DataSize >0)
{ {
pBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,&pHeap); pBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset,&pHeap);
Status = CmiDestroyBlock(RegistryFile, pBlock, ValueBlock->DataOffset); Status = CmiDestroyBlock(RegistryFile, pBlock, ValueBlock->DataOffset);
@ -3155,6 +3101,7 @@ CmiAddHeap(PREGISTRY_FILE RegistryFile,PVOID *NewBlock,BLOCK_OFFSET *NewBlockOf
} }
RegistryFile->BlockList = tmpBlockList; RegistryFile->BlockList = tmpBlockList;
RegistryFile->BlockList [RegistryFile->BlockListSize++] = tmpHeap; RegistryFile->BlockList [RegistryFile->BlockListSize++] = tmpHeap;
/* initialize a free block in this heap : */
tmpBlock = (PFREE_SUB_BLOCK)((char *) tmpHeap + REG_HEAP_BLOCK_DATA_OFFSET); tmpBlock = (PFREE_SUB_BLOCK)((char *) tmpHeap + REG_HEAP_BLOCK_DATA_OFFSET);
tmpBlock-> SubBlockSize = (REG_BLOCK_SIZE - REG_HEAP_BLOCK_DATA_OFFSET) ; tmpBlock-> SubBlockSize = (REG_BLOCK_SIZE - REG_HEAP_BLOCK_DATA_OFFSET) ;
*NewBlock = (PVOID)tmpBlock; *NewBlock = (PVOID)tmpBlock;
@ -3211,17 +3158,22 @@ CmiAllocateBlock(PREGISTRY_FILE RegistryFile,
if(RegistryFile->Filename if(RegistryFile->Filename
&& CmiGetBlock(RegistryFile, RegistryFile->FreeListOffset[i],&pHeap)) && CmiGetBlock(RegistryFile, RegistryFile->FreeListOffset[i],&pHeap))
ZwQuerySystemTime((PTIME) &pHeap->DateModified); ZwQuerySystemTime((PTIME) &pHeap->DateModified);
if( (i+1) <RegistryFile->FreeListSize)
{
memmove( &RegistryFile->FreeList[i] memmove( &RegistryFile->FreeList[i]
,&RegistryFile->FreeList[i+1] ,&RegistryFile->FreeList[i+1]
,sizeof(RegistryFile->FreeList[0])*RegistryFile->FreeListSize); ,sizeof(RegistryFile->FreeList[0])
*(RegistryFile->FreeListSize-i-1));
memmove( &RegistryFile->FreeListOffset[i] memmove( &RegistryFile->FreeListOffset[i]
,&RegistryFile->FreeListOffset[i+1] ,&RegistryFile->FreeListOffset[i+1]
,sizeof(RegistryFile->FreeListOffset[0])*RegistryFile->FreeListSize); ,sizeof(RegistryFile->FreeListOffset[0])
*(RegistryFile->FreeListSize-i-1));
}
RegistryFile->FreeListSize--; RegistryFile->FreeListSize--;
break; break;
} }
} }
/* first search in free blocks */ /* need to extend hive file : */
if (NewBlock == NULL) if (NewBlock == NULL)
{ {
/* add a new block : */ /* add a new block : */
@ -3239,7 +3191,8 @@ CmiAllocateBlock(PREGISTRY_FILE RegistryFile,
} }
else if(NewBlock->SubBlockSize < BlockSize) else if(NewBlock->SubBlockSize < BlockSize)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
NewBlock->SubBlockSize = BlockSize; RtlZeroMemory(*Block, BlockSize);
((PFREE_SUB_BLOCK)(*Block)) ->SubBlockSize = - BlockSize;
CmiLockBlock(RegistryFile, *Block); CmiLockBlock(RegistryFile, *Block);
} }
} }
@ -3264,12 +3217,14 @@ CmiDestroyBlock(PREGISTRY_FILE RegistryFile,
{ {
PFREE_SUB_BLOCK pFree = Block; PFREE_SUB_BLOCK pFree = Block;
if (pFree->SubBlockSize <0) if (pFree->SubBlockSize <0)
pFree->SubBlockSize = pFree->SubBlockSize; pFree->SubBlockSize = -pFree->SubBlockSize;
CmiAddFree(RegistryFile,Block,Offset); CmiAddFree(RegistryFile,Block,Offset);
CmiReleaseBlock(RegistryFile, Block); CmiReleaseBlock(RegistryFile, Block);
/* update time of heap */ /* update time of heap */
if(RegistryFile->Filename && CmiGetBlock(RegistryFile, Offset,&pHeap)) if(RegistryFile->Filename && CmiGetBlock(RegistryFile, Offset,&pHeap))
ZwQuerySystemTime((PTIME) &pHeap->DateModified); ZwQuerySystemTime((PTIME) &pHeap->DateModified);
/* FIXME : set first dword to block_offset of another free bloc ? */
/* FIXME : concatenate with previous and next block if free */
} }
return Status; return Status;