#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"
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
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;
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);
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,
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,
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*/
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;
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;
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;
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
- ValueFullInformation->DataOffset =
- (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
- + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+ if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+ {
+ ValueFullInformation->DataOffset =
+ (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+ + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+ }
+ else
+ {
+ ValueFullInformation->DataOffset =
+ (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+ + ValueCell->NameSize + sizeof(WCHAR);
+ }
ValueFullInformation->DataOffset =
- (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
+ (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->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);
- }
+ {
+ 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);
- }
+ {
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ &ValueCell->DataOffset,
+ ValueCell->DataSize & LONG_MAX);
+ }
}
break;
}
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,
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))
{
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,
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
- ValueName2,
+ ValueName,
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
}
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;
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)
RegistryHive = KeyObject->RegistryHive;
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
- ValueName2,
+ ValueName,
&ValueCell,
&VBOffset);
if (!NT_SUCCESS(Status))
if (ValueCell == NULL)
{
+ DPRINT("Allocate new value cell\n");
Status = CmiAddValueToKey(RegistryHive,
KeyCell,
- ValueName2,
+ ValueName,
&ValueCell,
&VBOffset);
}
ObDereferenceObject(KeyObject);
return(Status);
}
- else
- {
- DPRINT("DataSize (%d)\n", DataSize);
+ DPRINT("DataSize %lu\n", DataSize);
+ DPRINT("ValueCell %p\n", ValueCell);
+ DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
+
+ if (DataSize <= 4)
+ {
/* 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))
{
- 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);
- }
+ ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
- else
- {
- BLOCK_OFFSET NewOffset;
+ }
+ else
+ {
+ /*
+ * New data size is larger than the current, destroy current
+ * data block and allocate a new one.
+ */
+ 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;
- }
+ DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
- if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
+ if ((ValueCell->DataSize >= 0) &&
+ (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
- KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
+ ValueCell->DataSize = 0;
+ ValueCell->DataType = 0;
+ ValueCell->DataOffset = 0xffffffff;
}
- /* Update time of heap */
- if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+ Status = CmiAllocateBlock(RegistryHive,
+ (PVOID *)&NewDataCell,
+ DataSize,
+ &NewOffset);
+ if (!NT_SUCCESS(Status))
{
- ZwQuerySystemTime((PTIME) &pBin->DateModified);
+ 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);
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,
Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
KeyObject->KeyCell,
- ValueName2);
+ ValueName);
/* Release hive lock */
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
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)
OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
- UCHAR ValueName[MAX_PATH];
PVALUE_CELL ValueCell;
PKEY_OBJECT KeyObject;
PDATA_CELL DataCell;
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);
/* Reallocate the hash table block */
Status = CmiAllocateHashTableBlock(RegistryHive,
&NewHashBlock,
- &HTOffset,
+ &HTOffset,
HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE);
&HashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
- KeyCell->HashTableOffset = HTOffset;
+ KeyCell->HashTableOffset = HTOffset;
HashBlock = NewHashBlock;
}
}
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);
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;
}
CmiReleaseBlock(RegistryHive, ValueListCell);
-
+
return STATUS_SUCCESS;
}
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
-
+
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
*ValueCell = NULL;
CmiReleaseBlock(RegistryHive, CurValueCell);
CmiReleaseBlock(RegistryHive, ValueListCell);
-
+
return STATUS_SUCCESS;
}
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)
{
Status = CmiAllocateValueCell(RegistryHive,
&NewValueCell,
&VBOffset,
- ValueNameBuf);
+ ValueName);
*pVBOffset = VBOffset;
if (!NT_SUCCESS(Status))
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
- IN PCHAR ValueName)
+ IN PUNICODE_STRING ValueName)
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
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)
{
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;
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;
NTSTATUS
CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
- PVOID *Block,
- LONG BlockSize,
- BLOCK_OFFSET * pBlockOffset)
+ PVOID *Block,
+ LONG BlockSize,
+ BLOCK_OFFSET * pBlockOffset)
{
PCELL_HEADER NewBlock;
NTSTATUS Status;
{
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];
-
- if (pBlockOffset)
- *pBlockOffset = RegistryHive->FreeListOffset[i];
-
- /* Update time of heap */
- Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
-
- 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;
- }
- }
+ /* first search in free blocks */
+ NewBlock = NULL;
+ for (i = 0; i < RegistryHive->FreeListSize; i++)
+ {
+ if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
+ {
+ PVOID Temp;
- /* Need to extend hive file : */
- if (NewBlock == NULL)
- {
- /* Add a new block */
- Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
- }
+ NewBlock = RegistryHive->FreeList[i];
+ if (pBlockOffset)
+ *pBlockOffset = RegistryHive->FreeListOffset[i];
- 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;
+ /* Update time of heap */
+ Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
+
+ 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;
+ }
+ }
+
+ /* Need to extend hive file : */
+ if (NewBlock == NULL)
+ {
+ /* Add a new block */
+ Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
+ }
+
+ 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);
}
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;
}
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));
/* 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 */
-/* $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
#include <string.h>
#include <internal/pool.h>
#include <internal/registry.h>
+#include <reactos/bugcodes.h>
#define NDEBUG
#include <internal/debug.h>
wcscpy(KeyPathBuffer, L"\\Registry\\");
wcscat(KeyPathBuffer, KeyName);
- RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
+ RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyPath,
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);
{
PCHAR p1, p2;
ULONG PiceStart;
+ NTSTATUS Status;
/* FIXME: Store system start options */
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
}
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);
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,
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);
}
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}
+ DPRINT("TargetPath '%wZ'\n", TargetPath);
+
return(STATUS_SUCCESS);
}
* UPDATE HISTORY:
*/
+/* INCLUDES *****************************************************************/
+
#ifdef WIN32_REGDBG
#include "cm_win32.h"
#else
#include "cm.h"
#endif
+
+/* FUNCTIONS ****************************************************************/
+
NTSTATUS STDCALL
RtlCheckRegistryKey(IN ULONG RelativeTo,
IN PWSTR Path)