Implemented packing of value names

svn path=/trunk/; revision=3811
This commit is contained in:
Eric Kohl 2002-11-30 14:46:27 +00:00
parent 4bad5b8b2f
commit d608e437c9
6 changed files with 492 additions and 293 deletions

View file

@ -42,9 +42,6 @@
#define REG_KEY_CELL_ID 0x6b6e
#define REG_HASH_TABLE_BLOCK_ID 0x666c
#define REG_VALUE_CELL_ID 0x6b76
#define REG_LINK_KEY_CELL_TYPE 0x10
#define REG_KEY_CELL_TYPE 0x20
#define REG_ROOT_KEY_CELL_TYPE 0x2c
#define REG_HIVE_ID 0x66676572
#define REGISTRY_FILE_MAGIC "REGEDIT4"
@ -191,6 +188,12 @@ typedef struct _KEY_CELL
UCHAR Name[0];
} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
/* KEY_CELL.Type constants */
#define REG_LINK_KEY_CELL_TYPE 0x10
#define REG_KEY_CELL_TYPE 0x20
#define REG_ROOT_KEY_CELL_TYPE 0x2c
// hash record :
// HashValue=four letters of value's name
typedef struct _HASH_RECORD
@ -226,6 +229,10 @@ typedef struct _VALUE_CELL
UCHAR Name[0]; /* warning : not zero terminated */
} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
/* VALUE_CELL.Flags constants */
#define REG_VALUE_NAME_PACKED 0x0001
typedef struct _DATA_CELL
{
LONG CellSize;
@ -427,7 +434,7 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueName,
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset);
@ -440,14 +447,14 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueNameBuf,
OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pVBOffset);
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pVBOffset);
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueName);
IN PUNICODE_STRING ValueName);
NTSTATUS
CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
@ -468,9 +475,9 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf);
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset,
IN PUNICODE_STRING ValueName);
NTSTATUS
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
@ -509,4 +516,19 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiInitHives(BOOLEAN SetUpBoot);
ULONG
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
OUT PBOOLEAN Packable);
BOOLEAN
CmiComparePackedNames(IN PUNICODE_STRING Name,
IN PCHAR NameBuffer,
IN USHORT NameBufferSize,
IN BOOLEAN NamePacked);
VOID
CmiCopyPackedName(PWCHAR NameBuffer,
PCHAR PackedNameBuffer,
ULONG PackedNameSize);
#endif /*__INCLUDE_CM_H*/

View file

@ -515,8 +515,16 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
(ValueCell->NameSize + 1) * sizeof(WCHAR);
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
(ValueCell->NameSize + 1) * sizeof(WCHAR);
}
else
{
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
ValueCell->NameSize + sizeof(WCHAR);
}
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
@ -527,12 +535,24 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
ValueBasicInformation->NameLength =
(ValueCell->NameSize + 1) * sizeof(WCHAR);
mbstowcs(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize * 2);
ValueBasicInformation->Name[ValueCell->NameSize] = 0;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
ValueBasicInformation->NameLength =
(ValueCell->NameSize + 1) * sizeof(WCHAR);
CmiCopyPackedName(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
ValueBasicInformation->Name[ValueCell->NameSize] = 0;
}
else
{
ValueBasicInformation->NameLength =
ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize * sizeof(WCHAR));
ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
}
break;
@ -569,8 +589,18 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
break;
case KeyValueFullInformation:
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
ValueCell->NameSize * sizeof(WCHAR) + (ValueCell->DataSize & LONG_MAX);
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
(ValueCell->NameSize + 1) * sizeof(WCHAR) +
(ValueCell->DataSize & LONG_MAX);
}
else
{
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
ValueCell->NameSize + sizeof(WCHAR) +
(ValueCell->DataSize & LONG_MAX);
}
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
@ -581,34 +611,56 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
ValueFullInformation->DataOffset =
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+ (ValueCell->NameSize + 1) * sizeof(WCHAR);
ValueFullInformation->DataOffset =
(ValueFullInformation->DataOffset + 3) & 0xfffffffc;
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
ValueFullInformation->NameLength =
(ValueCell->NameSize + 1) * sizeof(WCHAR);
mbstowcs(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize * 2);
ValueFullInformation->Name[ValueCell->NameSize] = 0;
if (ValueCell->DataSize > 0)
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
DataCell->Data,
ValueCell->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryHive, DataCell);
}
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
ValueFullInformation->DataOffset =
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+ (ValueCell->NameSize + 1) * sizeof(WCHAR);
}
else
{
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
&ValueCell->DataOffset,
ValueCell->DataSize & LONG_MAX);
}
{
ValueFullInformation->DataOffset =
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+ ValueCell->NameSize + sizeof(WCHAR);
}
ValueFullInformation->DataOffset =
(ValueFullInformation->DataOffset + 3) & 0xfffffffc;
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
ValueFullInformation->NameLength =
(ValueCell->NameSize + 1) * sizeof(WCHAR);
CmiCopyPackedName(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
ValueFullInformation->Name[ValueCell->NameSize] = 0;
}
else
{
ValueFullInformation->NameLength =
ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
if (ValueCell->DataSize > 0)
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
DataCell->Data,
ValueCell->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryHive, DataCell);
}
else
{
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
&ValueCell->DataOffset,
ValueCell->DataSize & LONG_MAX);
}
}
break;
}
@ -859,7 +911,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
NTSTATUS Status;
PVOID Object;
DPRINT("KH %x DA %x OA %x OA->ON %x\n",
DPRINT("NtOpenFile(KH %x DA %x OA %x OA->ON '%wZ'\n",
KeyHandle,
DesiredAccess,
ObjectAttributes,
@ -877,7 +929,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
DPRINT("RemainingPath '%wZ'\n", &RemainingPath);
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
{
@ -1081,14 +1133,10 @@ NtQueryValueKey(IN HANDLE KeyHandle,
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
char ValueName2[MAX_PATH];
DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x)\n",
KeyHandle, ValueName->Buffer, Length);
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
ValueName2[ValueName->Length >> 1] = 0;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
@ -1115,7 +1163,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
ValueName2,
ValueName,
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
@ -1159,39 +1207,39 @@ NtQueryValueKey(IN HANDLE KeyHandle,
}
else
{
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
KeyValueInformation;
ValuePartialInformation->TitleIndex = 0;
ValuePartialInformation->Type = ValueCell->DataType;
ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX;
if (ValueCell->DataSize > 0)
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory(ValuePartialInformation->Data,
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data,
ValueCell->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryHive, DataCell);
}
CmiReleaseBlock(RegistryHive, DataCell);
}
else
{
RtlCopyMemory(ValuePartialInformation->Data,
&ValueCell->DataOffset,
{
RtlCopyMemory(ValuePartialInformation->Data,
&ValueCell->DataOffset,
ValueCell->DataSize & LONG_MAX);
}
}
}
break;
case KeyValueFullInformation:
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)
+ (ValueCell->NameSize -1) * sizeof(WCHAR)
+ (ValueCell->DataSize & LONG_MAX);
+ (ValueCell->NameSize -1) * sizeof(WCHAR)
+ (ValueCell->DataSize & LONG_MAX);
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
@ -1251,17 +1299,13 @@ NtSetValueKey(IN HANDLE KeyHandle,
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
BLOCK_OFFSET VBOffset;
char ValueName2[MAX_PATH];
PDATA_CELL DataCell;
PDATA_CELL NewDataCell;
PHBIN pBin;
ULONG DesiredAccess;
DPRINT("KeyHandle %x ValueName %S Type %d\n",
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
ValueName2[ValueName->Length>>1] = 0;
DPRINT("NtSetValueKey(KeyHandle %x ValueName %S Type %d)\n",
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
DesiredAccess = KEY_SET_VALUE;
if (Type == REG_LINK)
@ -1287,7 +1331,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
RegistryHive = KeyObject->RegistryHive;
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
ValueName2,
ValueName,
&ValueCell,
&VBOffset);
if (!NT_SUCCESS(Status))
@ -1301,9 +1345,10 @@ NtSetValueKey(IN HANDLE KeyHandle,
if (ValueCell == NULL)
{
DPRINT("Allocate new value cell\n");
Status = CmiAddValueToKey(RegistryHive,
KeyCell,
ValueName2,
ValueName,
&ValueCell,
&VBOffset);
}
@ -1316,71 +1361,93 @@ NtSetValueKey(IN HANDLE KeyHandle,
ObDereferenceObject(KeyObject);
return(Status);
}
else
DPRINT("DataSize %lu\n", DataSize);
DPRINT("ValueCell %p\n", ValueCell);
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
if (DataSize <= 4)
{
DPRINT("DataSize (%d)\n", DataSize);
/* If datasize <= 4 then write in valueblock directly */
if (DataSize <= 4)
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
if ((ValueCell->DataSize >= 0) &&
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
if ((ValueCell->DataSize >= 0) &&
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
}
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
ValueCell->DataSize = DataSize | 0x80000000;
ValueCell->DataType = Type;
RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
}
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
ValueCell->DataSize = DataSize | 0x80000000;
ValueCell->DataType = Type;
RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
}
else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
{
/* If new data size is <= current then overwrite current data */
else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
RtlCopyMemory(DataCell->Data, Data, DataSize);
ValueCell->DataSize = DataSize;
ValueCell->DataType = Type;
CmiReleaseBlock(RegistryHive, DataCell);
/* Update time of heap */
if (IsPermanentHive(RegistryHive))
{
ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
}
else
{
BLOCK_OFFSET NewOffset;
/* Destroy current data block and allocate a new one */
if ((ValueCell->DataSize >= 0) &&
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
}
Status = CmiAllocateBlock(RegistryHive,
(PVOID *)&NewDataCell,
DataSize,
&NewOffset);
RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
ValueCell->DataSize = DataSize;
ValueCell->DataType = Type;
CmiReleaseBlock(RegistryHive, NewDataCell);
ValueCell->DataOffset = NewOffset;
}
if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
{
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
}
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
RtlCopyMemory(DataCell->Data, Data, DataSize);
ValueCell->DataSize = DataSize;
ValueCell->DataType = Type;
CmiReleaseBlock(RegistryHive, DataCell);
/* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
if (IsPermanentHive(RegistryHive))
{
ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
}
else
{
/*
* New data size is larger than the current, destroy current
* data block and allocate a new one.
*/
BLOCK_OFFSET NewOffset;
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
if ((ValueCell->DataSize >= 0) &&
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
ValueCell->DataSize = 0;
ValueCell->DataType = 0;
ValueCell->DataOffset = 0xffffffff;
}
Status = CmiAllocateBlock(RegistryHive,
(PVOID *)&NewDataCell,
DataSize,
&NewOffset);
if (!NT_SUCCESS(Status))
{
DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return(Status);
}
RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
ValueCell->DataSize = DataSize;
ValueCell->DataType = Type;
CmiReleaseBlock(RegistryHive, NewDataCell);
ValueCell->DataOffset = NewOffset;
}
/* Mark link key */
if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) &&
(Type == REG_LINK))
{
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
}
/* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
{
ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
@ -1395,13 +1462,9 @@ NTSTATUS STDCALL
NtDeleteValueKey(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName)
{
CHAR ValueName2[MAX_PATH];
PKEY_OBJECT KeyObject;
NTSTATUS Status;
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
ValueName2[ValueName->Length>>1] = 0;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
@ -1421,7 +1484,7 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
KeyObject->KeyCell,
ValueName2);
ValueName);
/* Release hive lock */
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
@ -1452,12 +1515,12 @@ NtLoadKey2(IN PHANDLE KeyHandle,
NTSTATUS STDCALL
NtNotifyChangeKey(
IN HANDLE KeyHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
IN BOOLEAN Asynchroneous,
IN BOOLEAN Asynchroneous,
OUT PVOID ChangeBuffer,
IN ULONG Length,
IN BOOLEAN WatchSubtree)
@ -1475,7 +1538,6 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
UCHAR ValueName[MAX_PATH];
PVALUE_CELL ValueCell;
PKEY_OBJECT KeyObject;
PDATA_CELL DataCell;
@ -1511,17 +1573,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
for (i = 0; i < NumberOfValues; i++)
{
wcstombs(ValueName,
ValueList[i].ValueName->Buffer,
ValueList[i].ValueName->Length >> 1);
ValueName[ValueList[i].ValueName->Length >> 1] = 0;
DPRINT("ValueName: '%s'\n", ValueName);
DPRINT("ValueName: '%wZ'\n", ValueList[i].ValueName);
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
ValueName,
ValueList[i].ValueName,
&ValueCell,
NULL);

View file

@ -1204,7 +1204,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
/* Reallocate the hash table block */
Status = CmiAllocateHashTableBlock(RegistryHive,
&NewHashBlock,
&HTOffset,
&HTOffset,
HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE);
@ -1219,7 +1219,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
&HashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
KeyCell->HashTableOffset = HTOffset;
KeyCell->HashTableOffset = HTOffset;
HashBlock = NewHashBlock;
}
}
@ -1237,13 +1237,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueName,
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset)
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
ULONG Length;
ULONG i;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
@ -1261,17 +1260,17 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
for (i = 0; i < KeyCell->NumberOfValues; i++)
{
CurValueCell = CmiGetBlock(RegistryHive,
ValueListCell->Values[i],
NULL);
/* FIXME: perhaps we must not ignore case if NtCreateKey has not been */
/* called with OBJ_CASE_INSENSITIVE flag ? */
Length = strlen(ValueName);
ValueListCell->Values[i],
NULL);
if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == Length) &&
(_strnicmp(CurValueCell->Name, ValueName, Length) == 0))
CmiComparePackedNames(ValueName,
CurValueCell->Name,
CurValueCell->NameSize,
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
{
*ValueCell = CurValueCell;
if (VBOffset)
if (VBOffset)
*VBOffset = ValueListCell->Values[i];
//DPRINT("Found value %s\n", ValueName);
break;
@ -1280,7 +1279,7 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
}
CmiReleaseBlock(RegistryHive, ValueListCell);
return STATUS_SUCCESS;
}
@ -1293,7 +1292,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
*ValueCell = NULL;
@ -1321,7 +1320,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
CmiReleaseBlock(RegistryHive, CurValueCell);
CmiReleaseBlock(RegistryHive, ValueListCell);
return STATUS_SUCCESS;
}
@ -1329,7 +1328,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueNameBuf,
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pVBOffset)
{
@ -1343,7 +1342,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
Status = CmiAllocateValueCell(RegistryHive,
&NewValueCell,
&VBOffset,
ValueNameBuf);
ValueName);
*pVBOffset = VBOffset;
if (!NT_SUCCESS(Status))
@ -1407,7 +1406,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PCHAR ValueName)
IN PUNICODE_STRING ValueName)
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
@ -1425,9 +1424,12 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
for (i = 0; i < KeyCell->NumberOfValues; i++)
{
CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == strlen(ValueName)) &&
(memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0))
CmiComparePackedNames(ValueName,
CurValueCell->Name,
CurValueCell->NameSize,
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
{
if ((KeyCell->NumberOfValues - 1) < i)
{
@ -1539,20 +1541,25 @@ NTSTATUS
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
PVALUE_CELL *ValueCell,
BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf)
IN PUNICODE_STRING ValueName)
{
PVALUE_CELL NewValueCell;
ULONG NewValueSize;
NTSTATUS Status;
BOOLEAN Packable;
ULONG NameSize;
ULONG i;
Status = STATUS_SUCCESS;
NewValueSize = sizeof(VALUE_CELL) + strlen(ValueNameBuf);
Status = CmiAllocateBlock(RegistryHive,
(PVOID*) &NewValueCell,
NewValueSize,
VBOffset);
NameSize = CmiGetPackedNameLength(ValueName,
&Packable);
DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize);
Status = CmiAllocateBlock(RegistryHive,
(PVOID*) &NewValueCell,
sizeof(VALUE_CELL) + NameSize,
VBOffset);
if ((NewValueCell == NULL) || (!NT_SUCCESS(Status)))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1560,8 +1567,22 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
else
{
NewValueCell->Id = REG_VALUE_CELL_ID;
NewValueCell->NameSize = strlen(ValueNameBuf);
memcpy(NewValueCell->Name, ValueNameBuf, strlen(ValueNameBuf));
NewValueCell->NameSize = NameSize;
if (Packable)
{
/* Pack the value name */
for (i = 0; i < NameSize; i++)
NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i];
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
}
else
{
/* Copy the value name */
RtlCopyMemory(NewValueCell->Name,
ValueName->Buffer,
NameSize);
NewValueCell->Flags = 0;
}
NewValueCell->DataType = 0;
NewValueCell->DataSize = 0;
NewValueCell->DataOffset = 0xffffffff;
@ -1669,9 +1690,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
PVOID *Block,
LONG BlockSize,
BLOCK_OFFSET * pBlockOffset)
PVOID *Block,
LONG BlockSize,
BLOCK_OFFSET * pBlockOffset)
{
PCELL_HEADER NewBlock;
NTSTATUS Status;
@ -1687,86 +1708,88 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
{
NewBlock = ExAllocatePool(NonPagedPool, BlockSize);
if (NewBlock == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
RtlZeroMemory(NewBlock, BlockSize);
NewBlock->CellSize = BlockSize;
CmiLockBlock(RegistryHive, NewBlock);
*Block = NewBlock;
if (pBlockOffset)
*pBlockOffset = (BLOCK_OFFSET) NewBlock;
}
if (NewBlock == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
RtlZeroMemory(NewBlock, BlockSize);
NewBlock->CellSize = BlockSize;
CmiLockBlock(RegistryHive, NewBlock);
*Block = NewBlock;
if (pBlockOffset)
*pBlockOffset = (BLOCK_OFFSET) NewBlock;
}
}
else
{
ULONG i;
ULONG i;
/* first search in free blocks */
NewBlock = NULL;
for (i = 0; i < RegistryHive->FreeListSize; i++)
{
if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
{
PVOID Temp;
NewBlock = RegistryHive->FreeList[i];
/* first search in free blocks */
NewBlock = NULL;
for (i = 0; i < RegistryHive->FreeListSize; i++)
{
if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
{
PVOID Temp;
if (pBlockOffset)
*pBlockOffset = RegistryHive->FreeListOffset[i];
NewBlock = RegistryHive->FreeList[i];
if (pBlockOffset)
*pBlockOffset = RegistryHive->FreeListOffset[i];
/* Update time of heap */
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
/* Update time of heap */
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
if (Temp)
ZwQuerySystemTime((PTIME) &pBin->DateModified);
if (Temp)
ZwQuerySystemTime((PTIME) &pBin->DateModified);
if ((i + 1) < RegistryHive->FreeListSize)
{
RtlMoveMemory(&RegistryHive->FreeList[i],
&RegistryHive->FreeList[i + 1],
sizeof(RegistryHive->FreeList[0])
* (RegistryHive->FreeListSize - i - 1));
RtlMoveMemory(&RegistryHive->FreeListOffset[i],
&RegistryHive->FreeListOffset[i + 1],
sizeof(RegistryHive->FreeListOffset[0])
* (RegistryHive->FreeListSize - i - 1));
}
RegistryHive->FreeListSize--;
break;
}
}
if ((i + 1) < RegistryHive->FreeListSize)
{
RtlMoveMemory(&RegistryHive->FreeList[i],
&RegistryHive->FreeList[i + 1],
sizeof(RegistryHive->FreeList[0])
* (RegistryHive->FreeListSize - i - 1));
RtlMoveMemory(&RegistryHive->FreeListOffset[i],
&RegistryHive->FreeListOffset[i + 1],
sizeof(RegistryHive->FreeListOffset[0])
* (RegistryHive->FreeListSize - i - 1));
}
RegistryHive->FreeListSize--;
break;
}
}
/* Need to extend hive file : */
if (NewBlock == NULL)
{
/* Add a new block */
Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
}
/* Need to extend hive file : */
if (NewBlock == NULL)
{
/* Add a new block */
Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
}
if (NT_SUCCESS(Status))
{
*Block = NewBlock;
if (NT_SUCCESS(Status))
{
*Block = NewBlock;
/* Split the block in two parts */
if (NewBlock->CellSize > BlockSize)
{
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
}
else if (NewBlock->CellSize < BlockSize)
{
return STATUS_UNSUCCESSFUL;
}
RtlZeroMemory(*Block, BlockSize);
((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
CmiLockBlock(RegistryHive, *Block);
}
}
return Status;
/* Split the block in two parts */
if (NewBlock->CellSize > BlockSize)
{
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
}
else if (NewBlock->CellSize < BlockSize)
{
return(STATUS_UNSUCCESSFUL);
}
RtlZeroMemory(*Block, BlockSize);
((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
CmiLockBlock(RegistryHive, *Block);
}
}
return(Status);
}
@ -1781,27 +1804,27 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
Status = STATUS_SUCCESS;
if (IsVolatileHive(RegistryHive))
{
CmiReleaseBlock(RegistryHive, Block);
ExFreePool(Block);
}
{
CmiReleaseBlock(RegistryHive, Block);
ExFreePool(Block);
}
else
{
PCELL_HEADER pFree = Block;
{
PCELL_HEADER pFree = Block;
if (pFree->CellSize < 0)
pFree->CellSize = -pFree->CellSize;
if (pFree->CellSize < 0)
pFree->CellSize = -pFree->CellSize;
CmiAddFree(RegistryHive, Block, Offset);
CmiReleaseBlock(RegistryHive, Block);
CmiAddFree(RegistryHive, Block, Offset);
CmiReleaseBlock(RegistryHive, Block);
/* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
ZwQuerySystemTime((PTIME) &pBin->DateModified);
/* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
ZwQuerySystemTime((PTIME) &pBin->DateModified);
/* FIXME: Set first dword to block_offset of another free block ? */
/* FIXME: Concatenate with previous and next block if free */
}
/* FIXME: Set first dword to block_offset of another free block ? */
/* FIXME: Concatenate with previous and next block if free */
}
return Status;
}
@ -1825,29 +1848,29 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
FreeBlock, FreeOffset);
DPRINT("\n");
if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
{
{
DPRINT("\n");
tmpList = ExAllocatePool(PagedPool,
tmpList = ExAllocatePool(PagedPool,
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
DPRINT("\n");
if (tmpList == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
if (tmpList == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
DPRINT("\n");
tmpListOffset = ExAllocatePool(PagedPool,
tmpListOffset = ExAllocatePool(PagedPool,
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32));
DPRINT("\n");
if (tmpListOffset == NULL)
{
ExFreePool(tmpList);
return STATUS_INSUFFICIENT_RESOURCES;
}
if (tmpListOffset == NULL)
{
ExFreePool(tmpList);
return STATUS_INSUFFICIENT_RESOURCES;
}
DPRINT("\n");
if (RegistryHive->FreeListMax)
{
if (RegistryHive->FreeListMax)
{
DPRINT("\n");
RtlMoveMemory(tmpList, RegistryHive->FreeList,
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
@ -1986,3 +2009,80 @@ CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
/* FIXME: Implement */
}
}
ULONG
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
OUT PBOOLEAN Packable)
{
ULONG i;
if (Packable != NULL)
*Packable = TRUE;
for (i = 0; i < Name->Length; i++)
{
if (Name->Buffer[i] > 0xFF)
{
if (Packable != NULL)
*Packable = FALSE;
return(Name->Length);
}
}
return(Name->Length / sizeof(WCHAR));
}
BOOLEAN
CmiComparePackedNames(IN PUNICODE_STRING Name,
IN PCHAR NameBuffer,
IN USHORT NameBufferSize,
IN BOOLEAN NamePacked)
{
PWCHAR UNameBuffer;
ULONG i;
if (NamePacked)
{
if (Name->Length != NameBufferSize * sizeof(WCHAR))
{
return(FALSE);
}
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
{
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i]))
return(FALSE);
}
}
else
{
if (Name->Length != NameBufferSize)
return(FALSE);
UNameBuffer = (PWCHAR)NameBuffer;
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
{
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i]))
return(FALSE);
}
}
return(TRUE);
}
VOID
CmiCopyPackedName(PWCHAR NameBuffer,
PCHAR PackedNameBuffer,
ULONG PackedNameSize)
{
ULONG i;
for (i = 0; i < PackedNameSize; i++)
NameBuffer[i] = (WCHAR)PackedNameBuffer[i];
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.78 2002/11/26 15:31:41 ekohl Exp $
/* $Id: registry.c,v 1.79 2002/11/30 14:46:27 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -20,6 +20,7 @@
#include <string.h>
#include <internal/pool.h>
#include <internal/registry.h>
#include <reactos/bugcodes.h>
#define NDEBUG
#include <internal/debug.h>
@ -204,7 +205,7 @@ CmiCheckByName(BOOLEAN Verbose,
wcscpy(KeyPathBuffer, L"\\Registry\\");
wcscat(KeyPathBuffer, KeyName);
RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyPath,
@ -219,11 +220,11 @@ CmiCheckByName(BOOLEAN Verbose,
if (CHECKED)
{
if (!NT_SUCCESS(Status))
{
{
DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status);
DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status);
assert(NT_SUCCESS(Status));
}
}
}
CmiCheckKey(Verbose, Key);
@ -484,6 +485,7 @@ CmInit2(PCHAR CommandLine)
{
PCHAR p1, p2;
ULONG PiceStart;
NTSTATUS Status;
/* FIXME: Store system start options */
@ -515,12 +517,17 @@ CmInit2(PCHAR CommandLine)
p1 = p2;
}
#ifndef WIN32_REGDBG
RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
L"\\Pice",
L"Start",
REG_DWORD,
&PiceStart,
sizeof(ULONG));
Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
L"\\Pice",
L"Start",
REG_DWORD,
&PiceStart,
sizeof(ULONG));
if (!NT_SUCCESS(Status))
{
KeBugCheck(CONFIG_INITIALIZATION_FAILED);
}
#endif
}
@ -602,12 +609,12 @@ CmiCreateCurrentControlSetLink(VOID)
RtlInitUnicodeStringFromLiteral(&LinkValue,
L"SymbolicLinkValue");
Status=NtSetValueKey(KeyHandle,
&LinkValue,
0,
REG_LINK,
(PVOID)TargetNameBuffer,
TargetNameLength);
Status = NtSetValueKey(KeyHandle,
&LinkValue,
0,
REG_LINK,
(PVOID)TargetNameBuffer,
TargetNameLength);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);

View file

@ -168,6 +168,8 @@ CmiObjectParse(PVOID ParsedObject,
if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
!((Attributes & OBJ_OPENLINK) && (end == NULL)))
{
DPRINT("Found link\n");
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive,
FoundObject->KeyCell,
@ -436,18 +438,22 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath)
{
UNICODE_STRING LinkName = UNICODE_STRING_INITIALIZER(L"SymbolicLinkValue");
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
NTSTATUS Status;
DPRINT("CmiGetLinkTarget() called\n");
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
"SymbolicLinkValue",
&LinkName,
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
return(Status);
}
@ -485,6 +491,8 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}
DPRINT("TargetPath '%wZ'\n", TargetPath);
return(STATUS_SUCCESS);
}

View file

@ -6,6 +6,8 @@
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#ifdef WIN32_REGDBG
#include "cm_win32.h"
#else
@ -23,6 +25,9 @@
#include "cm.h"
#endif
/* FUNCTIONS ****************************************************************/
NTSTATUS STDCALL
RtlCheckRegistryKey(IN ULONG RelativeTo,
IN PWSTR Path)