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_KEY_CELL_ID 0x6b6e
#define REG_HASH_TABLE_BLOCK_ID 0x666c #define REG_HASH_TABLE_BLOCK_ID 0x666c
#define REG_VALUE_CELL_ID 0x6b76 #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 REG_HIVE_ID 0x66676572
#define REGISTRY_FILE_MAGIC "REGEDIT4" #define REGISTRY_FILE_MAGIC "REGEDIT4"
@ -191,6 +188,12 @@ typedef struct _KEY_CELL
UCHAR Name[0]; UCHAR Name[0];
} __attribute__((packed)) KEY_CELL, *PKEY_CELL; } __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 : // hash record :
// HashValue=four letters of value's name // HashValue=four letters of value's name
typedef struct _HASH_RECORD typedef struct _HASH_RECORD
@ -226,6 +229,10 @@ typedef struct _VALUE_CELL
UCHAR Name[0]; /* warning : not zero terminated */ UCHAR Name[0]; /* warning : not zero terminated */
} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL; } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
/* VALUE_CELL.Flags constants */
#define REG_VALUE_NAME_PACKED 0x0001
typedef struct _DATA_CELL typedef struct _DATA_CELL
{ {
LONG CellSize; LONG CellSize;
@ -427,7 +434,7 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueName, IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell, OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset); OUT BLOCK_OFFSET *VBOffset);
@ -440,14 +447,14 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueNameBuf, IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *pValueCell, OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pVBOffset); OUT BLOCK_OFFSET *pVBOffset);
NTSTATUS NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueName); IN PUNICODE_STRING ValueName);
NTSTATUS NTSTATUS
CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
@ -468,9 +475,9 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive, CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
OUT PVALUE_CELL *ValueCell, OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset, OUT BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf); IN PUNICODE_STRING ValueName);
NTSTATUS NTSTATUS
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
@ -509,4 +516,19 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiInitHives(BOOLEAN SetUpBoot); 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*/ #endif /*__INCLUDE_CM_H*/

View file

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

View file

@ -1204,7 +1204,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
/* Reallocate the hash table block */ /* Reallocate the hash table block */
Status = CmiAllocateHashTableBlock(RegistryHive, Status = CmiAllocateHashTableBlock(RegistryHive,
&NewHashBlock, &NewHashBlock,
&HTOffset, &HTOffset,
HashBlock->HashTableSize + HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE); REG_EXTEND_HASH_TABLE_SIZE);
@ -1219,7 +1219,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
&HashBlock->Table[0], &HashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset); CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
KeyCell->HashTableOffset = HTOffset; KeyCell->HashTableOffset = HTOffset;
HashBlock = NewHashBlock; HashBlock = NewHashBlock;
} }
} }
@ -1237,13 +1237,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueName, IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell, OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset) OUT BLOCK_OFFSET *VBOffset)
{ {
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell; PVALUE_CELL CurValueCell;
ULONG Length;
ULONG i; ULONG i;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
@ -1261,17 +1260,17 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
for (i = 0; i < KeyCell->NumberOfValues; i++) for (i = 0; i < KeyCell->NumberOfValues; i++)
{ {
CurValueCell = CmiGetBlock(RegistryHive, CurValueCell = CmiGetBlock(RegistryHive,
ValueListCell->Values[i], ValueListCell->Values[i],
NULL); NULL);
/* FIXME: perhaps we must not ignore case if NtCreateKey has not been */
/* called with OBJ_CASE_INSENSITIVE flag ? */
Length = strlen(ValueName);
if ((CurValueCell != NULL) && if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == Length) && CmiComparePackedNames(ValueName,
(_strnicmp(CurValueCell->Name, ValueName, Length) == 0)) CurValueCell->Name,
CurValueCell->NameSize,
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
{ {
*ValueCell = CurValueCell; *ValueCell = CurValueCell;
if (VBOffset) if (VBOffset)
*VBOffset = ValueListCell->Values[i]; *VBOffset = ValueListCell->Values[i];
//DPRINT("Found value %s\n", ValueName); //DPRINT("Found value %s\n", ValueName);
break; break;
@ -1280,7 +1279,7 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
} }
CmiReleaseBlock(RegistryHive, ValueListCell); CmiReleaseBlock(RegistryHive, ValueListCell);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1293,7 +1292,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
{ {
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell; PVALUE_CELL CurValueCell;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
*ValueCell = NULL; *ValueCell = NULL;
@ -1321,7 +1320,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
CmiReleaseBlock(RegistryHive, CurValueCell); CmiReleaseBlock(RegistryHive, CurValueCell);
CmiReleaseBlock(RegistryHive, ValueListCell); CmiReleaseBlock(RegistryHive, ValueListCell);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1329,7 +1328,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueNameBuf, IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *pValueCell, OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pVBOffset) OUT BLOCK_OFFSET *pVBOffset)
{ {
@ -1343,7 +1342,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
Status = CmiAllocateValueCell(RegistryHive, Status = CmiAllocateValueCell(RegistryHive,
&NewValueCell, &NewValueCell,
&VBOffset, &VBOffset,
ValueNameBuf); ValueName);
*pVBOffset = VBOffset; *pVBOffset = VBOffset;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1407,7 +1406,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueName) IN PUNICODE_STRING ValueName)
{ {
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell; PVALUE_CELL CurValueCell;
@ -1425,9 +1424,12 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
for (i = 0; i < KeyCell->NumberOfValues; i++) for (i = 0; i < KeyCell->NumberOfValues; i++)
{ {
CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL); CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
if ((CurValueCell != NULL) && if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == strlen(ValueName)) && CmiComparePackedNames(ValueName,
(memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0)) CurValueCell->Name,
CurValueCell->NameSize,
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
{ {
if ((KeyCell->NumberOfValues - 1) < i) if ((KeyCell->NumberOfValues - 1) < i)
{ {
@ -1539,20 +1541,25 @@ NTSTATUS
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
PVALUE_CELL *ValueCell, PVALUE_CELL *ValueCell,
BLOCK_OFFSET *VBOffset, BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf) IN PUNICODE_STRING ValueName)
{ {
PVALUE_CELL NewValueCell; PVALUE_CELL NewValueCell;
ULONG NewValueSize;
NTSTATUS Status; NTSTATUS Status;
BOOLEAN Packable;
ULONG NameSize;
ULONG i;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
NewValueSize = sizeof(VALUE_CELL) + strlen(ValueNameBuf); NameSize = CmiGetPackedNameLength(ValueName,
Status = CmiAllocateBlock(RegistryHive, &Packable);
(PVOID*) &NewValueCell,
NewValueSize,
VBOffset);
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))) if ((NewValueCell == NULL) || (!NT_SUCCESS(Status)))
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1560,8 +1567,22 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
else else
{ {
NewValueCell->Id = REG_VALUE_CELL_ID; NewValueCell->Id = REG_VALUE_CELL_ID;
NewValueCell->NameSize = strlen(ValueNameBuf); NewValueCell->NameSize = NameSize;
memcpy(NewValueCell->Name, ValueNameBuf, strlen(ValueNameBuf)); 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->DataType = 0;
NewValueCell->DataSize = 0; NewValueCell->DataSize = 0;
NewValueCell->DataOffset = 0xffffffff; NewValueCell->DataOffset = 0xffffffff;
@ -1669,9 +1690,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
PVOID *Block, PVOID *Block,
LONG BlockSize, LONG BlockSize,
BLOCK_OFFSET * pBlockOffset) BLOCK_OFFSET * pBlockOffset)
{ {
PCELL_HEADER NewBlock; PCELL_HEADER NewBlock;
NTSTATUS Status; NTSTATUS Status;
@ -1687,86 +1708,88 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
{ {
NewBlock = ExAllocatePool(NonPagedPool, BlockSize); NewBlock = ExAllocatePool(NonPagedPool, BlockSize);
if (NewBlock == NULL) if (NewBlock == NULL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
RtlZeroMemory(NewBlock, BlockSize); RtlZeroMemory(NewBlock, BlockSize);
NewBlock->CellSize = BlockSize; NewBlock->CellSize = BlockSize;
CmiLockBlock(RegistryHive, NewBlock); CmiLockBlock(RegistryHive, NewBlock);
*Block = NewBlock; *Block = NewBlock;
if (pBlockOffset) if (pBlockOffset)
*pBlockOffset = (BLOCK_OFFSET) NewBlock; *pBlockOffset = (BLOCK_OFFSET) NewBlock;
} }
} }
else else
{ {
ULONG i; ULONG i;
/* first search in free blocks */ /* first search in free blocks */
NewBlock = NULL; NewBlock = NULL;
for (i = 0; i < RegistryHive->FreeListSize; i++) for (i = 0; i < RegistryHive->FreeListSize; i++)
{ {
if (RegistryHive->FreeList[i]->CellSize >= BlockSize) if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
{ {
PVOID Temp; PVOID Temp;
NewBlock = RegistryHive->FreeList[i];
if (pBlockOffset) NewBlock = RegistryHive->FreeList[i];
*pBlockOffset = RegistryHive->FreeListOffset[i]; if (pBlockOffset)
*pBlockOffset = RegistryHive->FreeListOffset[i];
/* Update time of heap */ /* Update time of heap */
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin); Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
if (Temp) if (Temp)
ZwQuerySystemTime((PTIME) &pBin->DateModified); ZwQuerySystemTime((PTIME) &pBin->DateModified);
if ((i + 1) < RegistryHive->FreeListSize) if ((i + 1) < RegistryHive->FreeListSize)
{ {
RtlMoveMemory(&RegistryHive->FreeList[i], RtlMoveMemory(&RegistryHive->FreeList[i],
&RegistryHive->FreeList[i + 1], &RegistryHive->FreeList[i + 1],
sizeof(RegistryHive->FreeList[0]) sizeof(RegistryHive->FreeList[0])
* (RegistryHive->FreeListSize - i - 1)); * (RegistryHive->FreeListSize - i - 1));
RtlMoveMemory(&RegistryHive->FreeListOffset[i], RtlMoveMemory(&RegistryHive->FreeListOffset[i],
&RegistryHive->FreeListOffset[i + 1], &RegistryHive->FreeListOffset[i + 1],
sizeof(RegistryHive->FreeListOffset[0]) sizeof(RegistryHive->FreeListOffset[0])
* (RegistryHive->FreeListSize - i - 1)); * (RegistryHive->FreeListSize - i - 1));
} }
RegistryHive->FreeListSize--; RegistryHive->FreeListSize--;
break; break;
} }
} }
/* Need to extend hive file : */ /* Need to extend hive file : */
if (NewBlock == NULL) if (NewBlock == NULL)
{ {
/* Add a new block */ /* Add a new block */
Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset); Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
} }
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
*Block = NewBlock; *Block = NewBlock;
/* Split the block in two parts */ /* Split the block in two parts */
if (NewBlock->CellSize > BlockSize) if (NewBlock->CellSize > BlockSize)
{ {
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize); CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
} }
else if (NewBlock->CellSize < BlockSize) else if (NewBlock->CellSize < BlockSize)
{ {
return STATUS_UNSUCCESSFUL; return(STATUS_UNSUCCESSFUL);
} }
RtlZeroMemory(*Block, BlockSize);
((PCELL_HEADER) (*Block))->CellSize = -BlockSize; RtlZeroMemory(*Block, BlockSize);
CmiLockBlock(RegistryHive, *Block); ((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
} CmiLockBlock(RegistryHive, *Block);
} }
return Status; }
return(Status);
} }
@ -1781,27 +1804,27 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
if (IsVolatileHive(RegistryHive)) if (IsVolatileHive(RegistryHive))
{ {
CmiReleaseBlock(RegistryHive, Block); CmiReleaseBlock(RegistryHive, Block);
ExFreePool(Block); ExFreePool(Block);
} }
else else
{ {
PCELL_HEADER pFree = Block; PCELL_HEADER pFree = Block;
if (pFree->CellSize < 0) if (pFree->CellSize < 0)
pFree->CellSize = -pFree->CellSize; pFree->CellSize = -pFree->CellSize;
CmiAddFree(RegistryHive, Block, Offset); CmiAddFree(RegistryHive, Block, Offset);
CmiReleaseBlock(RegistryHive, Block); CmiReleaseBlock(RegistryHive, Block);
/* Update time of heap */ /* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin)) if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
ZwQuerySystemTime((PTIME) &pBin->DateModified); ZwQuerySystemTime((PTIME) &pBin->DateModified);
/* FIXME: Set first dword to block_offset of another free block ? */ /* FIXME: Set first dword to block_offset of another free block ? */
/* FIXME: Concatenate with previous and next block if free */ /* FIXME: Concatenate with previous and next block if free */
} }
return Status; return Status;
} }
@ -1825,29 +1848,29 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
FreeBlock, FreeOffset); FreeBlock, FreeOffset);
DPRINT("\n"); DPRINT("\n");
if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax) if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
{ {
DPRINT("\n"); DPRINT("\n");
tmpList = ExAllocatePool(PagedPool, tmpList = ExAllocatePool(PagedPool,
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32)); sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
DPRINT("\n"); DPRINT("\n");
if (tmpList == NULL) if (tmpList == NULL)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
DPRINT("\n"); DPRINT("\n");
tmpListOffset = ExAllocatePool(PagedPool, tmpListOffset = ExAllocatePool(PagedPool,
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32)); sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32));
DPRINT("\n"); DPRINT("\n");
if (tmpListOffset == NULL) if (tmpListOffset == NULL)
{ {
ExFreePool(tmpList); ExFreePool(tmpList);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
DPRINT("\n"); DPRINT("\n");
if (RegistryHive->FreeListMax) if (RegistryHive->FreeListMax)
{ {
DPRINT("\n"); DPRINT("\n");
RtlMoveMemory(tmpList, RegistryHive->FreeList, RtlMoveMemory(tmpList, RegistryHive->FreeList,
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
@ -1986,3 +2009,80 @@ CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
/* FIXME: Implement */ /* 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -20,6 +20,7 @@
#include <string.h> #include <string.h>
#include <internal/pool.h> #include <internal/pool.h>
#include <internal/registry.h> #include <internal/registry.h>
#include <reactos/bugcodes.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -204,7 +205,7 @@ CmiCheckByName(BOOLEAN Verbose,
wcscpy(KeyPathBuffer, L"\\Registry\\"); wcscpy(KeyPathBuffer, L"\\Registry\\");
wcscat(KeyPathBuffer, KeyName); wcscat(KeyPathBuffer, KeyName);
RtlInitUnicodeString(&KeyPath, KeyPathBuffer); RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&KeyPath, &KeyPath,
@ -219,11 +220,11 @@ CmiCheckByName(BOOLEAN Verbose,
if (CHECKED) if (CHECKED)
{ {
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status); DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status);
DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status); DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status);
assert(NT_SUCCESS(Status)); assert(NT_SUCCESS(Status));
} }
} }
CmiCheckKey(Verbose, Key); CmiCheckKey(Verbose, Key);
@ -484,6 +485,7 @@ CmInit2(PCHAR CommandLine)
{ {
PCHAR p1, p2; PCHAR p1, p2;
ULONG PiceStart; ULONG PiceStart;
NTSTATUS Status;
/* FIXME: Store system start options */ /* FIXME: Store system start options */
@ -515,12 +517,17 @@ CmInit2(PCHAR CommandLine)
p1 = p2; p1 = p2;
} }
#ifndef WIN32_REGDBG #ifndef WIN32_REGDBG
RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
L"\\Pice", L"\\Pice",
L"Start", L"Start",
REG_DWORD, REG_DWORD,
&PiceStart, &PiceStart,
sizeof(ULONG)); sizeof(ULONG));
if (!NT_SUCCESS(Status))
{
KeBugCheck(CONFIG_INITIALIZATION_FAILED);
}
#endif #endif
} }
@ -602,12 +609,12 @@ CmiCreateCurrentControlSetLink(VOID)
RtlInitUnicodeStringFromLiteral(&LinkValue, RtlInitUnicodeStringFromLiteral(&LinkValue,
L"SymbolicLinkValue"); L"SymbolicLinkValue");
Status=NtSetValueKey(KeyHandle, Status = NtSetValueKey(KeyHandle,
&LinkValue, &LinkValue,
0, 0,
REG_LINK, REG_LINK,
(PVOID)TargetNameBuffer, (PVOID)TargetNameBuffer,
TargetNameLength); TargetNameLength);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NtSetValueKey() failed (Status %lx)\n", 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) && if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
!((Attributes & OBJ_OPENLINK) && (end == NULL))) !((Attributes & OBJ_OPENLINK) && (end == NULL)))
{ {
DPRINT("Found link\n");
RtlInitUnicodeString(&LinkPath, NULL); RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive, Status = CmiGetLinkTarget(FoundObject->RegistryHive,
FoundObject->KeyCell, FoundObject->KeyCell,
@ -436,18 +438,22 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell, PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath) PUNICODE_STRING TargetPath)
{ {
UNICODE_STRING LinkName = UNICODE_STRING_INITIALIZER(L"SymbolicLinkValue");
PVALUE_CELL ValueCell; PVALUE_CELL ValueCell;
PDATA_CELL DataCell; PDATA_CELL DataCell;
NTSTATUS Status; NTSTATUS Status;
DPRINT("CmiGetLinkTarget() called\n");
/* Get Value block of interest */ /* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive, Status = CmiScanKeyForValue(RegistryHive,
KeyCell, KeyCell,
"SymbolicLinkValue", &LinkName,
&ValueCell, &ValueCell,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
return(Status); return(Status);
} }
@ -485,6 +491,8 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0; TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
} }
DPRINT("TargetPath '%wZ'\n", TargetPath);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View file

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