mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 07:56:59 +00:00
Implemented packing of value names
svn path=/trunk/; revision=3811
This commit is contained in:
parent
4bad5b8b2f
commit
d608e437c9
6 changed files with 492 additions and 293 deletions
|
@ -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*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue