mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:56:00 +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_HASH_TABLE_BLOCK_ID 0x666c
|
||||
#define REG_VALUE_CELL_ID 0x6b76
|
||||
#define REG_LINK_KEY_CELL_TYPE 0x10
|
||||
#define REG_KEY_CELL_TYPE 0x20
|
||||
#define REG_ROOT_KEY_CELL_TYPE 0x2c
|
||||
#define REG_HIVE_ID 0x66676572
|
||||
|
||||
#define REGISTRY_FILE_MAGIC "REGEDIT4"
|
||||
|
@ -191,6 +188,12 @@ typedef struct _KEY_CELL
|
|||
UCHAR Name[0];
|
||||
} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
|
||||
|
||||
/* KEY_CELL.Type constants */
|
||||
#define REG_LINK_KEY_CELL_TYPE 0x10
|
||||
#define REG_KEY_CELL_TYPE 0x20
|
||||
#define REG_ROOT_KEY_CELL_TYPE 0x2c
|
||||
|
||||
|
||||
// hash record :
|
||||
// HashValue=four letters of value's name
|
||||
typedef struct _HASH_RECORD
|
||||
|
@ -226,6 +229,10 @@ typedef struct _VALUE_CELL
|
|||
UCHAR Name[0]; /* warning : not zero terminated */
|
||||
} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
|
||||
|
||||
/* VALUE_CELL.Flags constants */
|
||||
#define REG_VALUE_NAME_PACKED 0x0001
|
||||
|
||||
|
||||
typedef struct _DATA_CELL
|
||||
{
|
||||
LONG CellSize;
|
||||
|
@ -427,7 +434,7 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName,
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset);
|
||||
|
||||
|
@ -440,14 +447,14 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueNameBuf,
|
||||
OUT PVALUE_CELL *pValueCell,
|
||||
OUT BLOCK_OFFSET *pVBOffset);
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PVALUE_CELL *pValueCell,
|
||||
OUT BLOCK_OFFSET *pVBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName);
|
||||
IN PUNICODE_STRING ValueName);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
|
||||
|
@ -468,9 +475,9 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
NTSTATUS
|
||||
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset,
|
||||
IN PCHAR ValueNameBuf);
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset,
|
||||
IN PUNICODE_STRING ValueName);
|
||||
|
||||
NTSTATUS
|
||||
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
|
||||
|
@ -509,4 +516,19 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiInitHives(BOOLEAN SetUpBoot);
|
||||
|
||||
ULONG
|
||||
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
|
||||
OUT PBOOLEAN Packable);
|
||||
|
||||
BOOLEAN
|
||||
CmiComparePackedNames(IN PUNICODE_STRING Name,
|
||||
IN PCHAR NameBuffer,
|
||||
IN USHORT NameBufferSize,
|
||||
IN BOOLEAN NamePacked);
|
||||
|
||||
VOID
|
||||
CmiCopyPackedName(PWCHAR NameBuffer,
|
||||
PCHAR PackedNameBuffer,
|
||||
ULONG PackedNameSize);
|
||||
|
||||
#endif /*__INCLUDE_CM_H*/
|
||||
|
|
|
@ -515,8 +515,16 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
|||
switch (KeyValueInformationClass)
|
||||
{
|
||||
case KeyValueBasicInformation:
|
||||
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
{
|
||||
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
|
||||
ValueCell->NameSize + sizeof(WCHAR);
|
||||
}
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -527,12 +535,24 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
|||
KeyValueInformation;
|
||||
ValueBasicInformation->TitleIndex = 0;
|
||||
ValueBasicInformation->Type = ValueCell->DataType;
|
||||
ValueBasicInformation->NameLength =
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
mbstowcs(ValueBasicInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize * 2);
|
||||
ValueBasicInformation->Name[ValueCell->NameSize] = 0;
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
{
|
||||
ValueBasicInformation->NameLength =
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
CmiCopyPackedName(ValueBasicInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize);
|
||||
ValueBasicInformation->Name[ValueCell->NameSize] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueBasicInformation->NameLength =
|
||||
ValueCell->NameSize + sizeof(WCHAR);
|
||||
RtlCopyMemory(ValueBasicInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize * sizeof(WCHAR));
|
||||
ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -569,8 +589,18 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
|||
break;
|
||||
|
||||
case KeyValueFullInformation:
|
||||
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
|
||||
ValueCell->NameSize * sizeof(WCHAR) + (ValueCell->DataSize & LONG_MAX);
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
{
|
||||
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR) +
|
||||
(ValueCell->DataSize & LONG_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
|
||||
ValueCell->NameSize + sizeof(WCHAR) +
|
||||
(ValueCell->DataSize & LONG_MAX);
|
||||
}
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -581,34 +611,56 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
|||
KeyValueInformation;
|
||||
ValueFullInformation->TitleIndex = 0;
|
||||
ValueFullInformation->Type = ValueCell->DataType;
|
||||
ValueFullInformation->DataOffset =
|
||||
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
|
||||
+ (ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
ValueFullInformation->DataOffset =
|
||||
(ValueFullInformation->DataOffset + 3) & 0xfffffffc;
|
||||
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
|
||||
ValueFullInformation->NameLength =
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
mbstowcs(ValueFullInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize * 2);
|
||||
ValueFullInformation->Name[ValueCell->NameSize] = 0;
|
||||
if (ValueCell->DataSize > 0)
|
||||
{
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
|
||||
RtlCopyMemory((PCHAR) ValueFullInformation
|
||||
+ ValueFullInformation->DataOffset,
|
||||
DataCell->Data,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
}
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
{
|
||||
ValueFullInformation->DataOffset =
|
||||
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
|
||||
+ (ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory((PCHAR) ValueFullInformation
|
||||
+ ValueFullInformation->DataOffset,
|
||||
&ValueCell->DataOffset,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
}
|
||||
{
|
||||
ValueFullInformation->DataOffset =
|
||||
(DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
|
||||
+ ValueCell->NameSize + sizeof(WCHAR);
|
||||
}
|
||||
ValueFullInformation->DataOffset =
|
||||
(ValueFullInformation->DataOffset + 3) & 0xfffffffc;
|
||||
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
{
|
||||
ValueFullInformation->NameLength =
|
||||
(ValueCell->NameSize + 1) * sizeof(WCHAR);
|
||||
|
||||
CmiCopyPackedName(ValueFullInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize);
|
||||
ValueFullInformation->Name[ValueCell->NameSize] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueFullInformation->NameLength =
|
||||
ValueCell->NameSize + sizeof(WCHAR);
|
||||
RtlCopyMemory(ValueFullInformation->Name,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize);
|
||||
ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
if (ValueCell->DataSize > 0)
|
||||
{
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
|
||||
RtlCopyMemory((PCHAR) ValueFullInformation
|
||||
+ ValueFullInformation->DataOffset,
|
||||
DataCell->Data,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory((PCHAR) ValueFullInformation
|
||||
+ ValueFullInformation->DataOffset,
|
||||
&ValueCell->DataOffset,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -859,7 +911,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
|||
NTSTATUS Status;
|
||||
PVOID Object;
|
||||
|
||||
DPRINT("KH %x DA %x OA %x OA->ON %x\n",
|
||||
DPRINT("NtOpenFile(KH %x DA %x OA %x OA->ON '%wZ'\n",
|
||||
KeyHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
|
@ -877,7 +929,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
|||
|
||||
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
|
||||
|
||||
DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
|
||||
DPRINT("RemainingPath '%wZ'\n", &RemainingPath);
|
||||
|
||||
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
|
||||
{
|
||||
|
@ -1081,14 +1133,10 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
|||
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
|
||||
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
|
||||
char ValueName2[MAX_PATH];
|
||||
|
||||
DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x)\n",
|
||||
KeyHandle, ValueName->Buffer, Length);
|
||||
|
||||
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
|
||||
ValueName2[ValueName->Length >> 1] = 0;
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_QUERY_VALUE,
|
||||
|
@ -1115,7 +1163,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
|||
/* Get Value block of interest */
|
||||
Status = CmiScanKeyForValue(RegistryHive,
|
||||
KeyCell,
|
||||
ValueName2,
|
||||
ValueName,
|
||||
&ValueCell,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1159,39 +1207,39 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
|||
}
|
||||
else
|
||||
{
|
||||
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
|
||||
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
|
||||
KeyValueInformation;
|
||||
ValuePartialInformation->TitleIndex = 0;
|
||||
ValuePartialInformation->Type = ValueCell->DataType;
|
||||
ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX;
|
||||
if (ValueCell->DataSize > 0)
|
||||
{
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
|
||||
RtlCopyMemory(ValuePartialInformation->Data,
|
||||
{
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
|
||||
RtlCopyMemory(ValuePartialInformation->Data,
|
||||
DataCell->Data,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
}
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(ValuePartialInformation->Data,
|
||||
&ValueCell->DataOffset,
|
||||
{
|
||||
RtlCopyMemory(ValuePartialInformation->Data,
|
||||
&ValueCell->DataOffset,
|
||||
ValueCell->DataSize & LONG_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyValueFullInformation:
|
||||
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)
|
||||
+ (ValueCell->NameSize -1) * sizeof(WCHAR)
|
||||
+ (ValueCell->DataSize & LONG_MAX);
|
||||
+ (ValueCell->NameSize -1) * sizeof(WCHAR)
|
||||
+ (ValueCell->DataSize & LONG_MAX);
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
Status = STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
|
||||
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
|
||||
KeyValueInformation;
|
||||
ValueFullInformation->TitleIndex = 0;
|
||||
ValueFullInformation->Type = ValueCell->DataType;
|
||||
|
@ -1251,17 +1299,13 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
PKEY_CELL KeyCell;
|
||||
PVALUE_CELL ValueCell;
|
||||
BLOCK_OFFSET VBOffset;
|
||||
char ValueName2[MAX_PATH];
|
||||
PDATA_CELL DataCell;
|
||||
PDATA_CELL NewDataCell;
|
||||
PHBIN pBin;
|
||||
ULONG DesiredAccess;
|
||||
|
||||
DPRINT("KeyHandle %x ValueName %S Type %d\n",
|
||||
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
|
||||
|
||||
wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
|
||||
ValueName2[ValueName->Length>>1] = 0;
|
||||
DPRINT("NtSetValueKey(KeyHandle %x ValueName %S Type %d)\n",
|
||||
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
|
||||
|
||||
DesiredAccess = KEY_SET_VALUE;
|
||||
if (Type == REG_LINK)
|
||||
|
@ -1287,7 +1331,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
RegistryHive = KeyObject->RegistryHive;
|
||||
Status = CmiScanKeyForValue(RegistryHive,
|
||||
KeyCell,
|
||||
ValueName2,
|
||||
ValueName,
|
||||
&ValueCell,
|
||||
&VBOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1301,9 +1345,10 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
|
||||
if (ValueCell == NULL)
|
||||
{
|
||||
DPRINT("Allocate new value cell\n");
|
||||
Status = CmiAddValueToKey(RegistryHive,
|
||||
KeyCell,
|
||||
ValueName2,
|
||||
ValueName,
|
||||
&ValueCell,
|
||||
&VBOffset);
|
||||
}
|
||||
|
@ -1316,71 +1361,93 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
ObDereferenceObject(KeyObject);
|
||||
return(Status);
|
||||
}
|
||||
else
|
||||
|
||||
DPRINT("DataSize %lu\n", DataSize);
|
||||
DPRINT("ValueCell %p\n", ValueCell);
|
||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
||||
|
||||
if (DataSize <= 4)
|
||||
{
|
||||
DPRINT("DataSize (%d)\n", DataSize);
|
||||
|
||||
/* If datasize <= 4 then write in valueblock directly */
|
||||
if (DataSize <= 4)
|
||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
||||
if ((ValueCell->DataSize >= 0) &&
|
||||
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
|
||||
{
|
||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
||||
if ((ValueCell->DataSize >= 0) &&
|
||||
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
|
||||
{
|
||||
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
|
||||
}
|
||||
|
||||
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
|
||||
ValueCell->DataSize = DataSize | 0x80000000;
|
||||
ValueCell->DataType = Type;
|
||||
RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
|
||||
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
|
||||
}
|
||||
|
||||
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
|
||||
ValueCell->DataSize = DataSize | 0x80000000;
|
||||
ValueCell->DataType = Type;
|
||||
RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
|
||||
}
|
||||
else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
|
||||
{
|
||||
/* If new data size is <= current then overwrite current data */
|
||||
else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
|
||||
{
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
|
||||
RtlCopyMemory(DataCell->Data, Data, DataSize);
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = Type;
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
/* Update time of heap */
|
||||
if (IsPermanentHive(RegistryHive))
|
||||
{
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BLOCK_OFFSET NewOffset;
|
||||
|
||||
/* Destroy current data block and allocate a new one */
|
||||
if ((ValueCell->DataSize >= 0) &&
|
||||
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
|
||||
{
|
||||
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
|
||||
}
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID *)&NewDataCell,
|
||||
DataSize,
|
||||
&NewOffset);
|
||||
RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = Type;
|
||||
CmiReleaseBlock(RegistryHive, NewDataCell);
|
||||
ValueCell->DataOffset = NewOffset;
|
||||
}
|
||||
|
||||
if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
|
||||
{
|
||||
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
|
||||
}
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
|
||||
RtlCopyMemory(DataCell->Data, Data, DataSize);
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = Type;
|
||||
CmiReleaseBlock(RegistryHive, DataCell);
|
||||
|
||||
/* Update time of heap */
|
||||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
|
||||
if (IsPermanentHive(RegistryHive))
|
||||
{
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* New data size is larger than the current, destroy current
|
||||
* data block and allocate a new one.
|
||||
*/
|
||||
BLOCK_OFFSET NewOffset;
|
||||
|
||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
||||
|
||||
if ((ValueCell->DataSize >= 0) &&
|
||||
(DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
|
||||
{
|
||||
CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
|
||||
ValueCell->DataSize = 0;
|
||||
ValueCell->DataType = 0;
|
||||
ValueCell->DataOffset = 0xffffffff;
|
||||
}
|
||||
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID *)&NewDataCell,
|
||||
DataSize,
|
||||
&NewOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
|
||||
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = Type;
|
||||
CmiReleaseBlock(RegistryHive, NewDataCell);
|
||||
ValueCell->DataOffset = NewOffset;
|
||||
}
|
||||
|
||||
/* Mark link key */
|
||||
if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) &&
|
||||
(Type == REG_LINK))
|
||||
{
|
||||
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
|
||||
}
|
||||
|
||||
/* Update time of heap */
|
||||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
|
||||
{
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
@ -1395,13 +1462,9 @@ NTSTATUS STDCALL
|
|||
NtDeleteValueKey(IN HANDLE KeyHandle,
|
||||
IN PUNICODE_STRING ValueName)
|
||||
{
|
||||
CHAR ValueName2[MAX_PATH];
|
||||
PKEY_OBJECT KeyObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
|
||||
ValueName2[ValueName->Length>>1] = 0;
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_QUERY_VALUE,
|
||||
|
@ -1421,7 +1484,7 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
|
|||
|
||||
Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
|
||||
KeyObject->KeyCell,
|
||||
ValueName2);
|
||||
ValueName);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
@ -1452,12 +1515,12 @@ NtLoadKey2(IN PHANDLE KeyHandle,
|
|||
NTSTATUS STDCALL
|
||||
NtNotifyChangeKey(
|
||||
IN HANDLE KeyHandle,
|
||||
IN HANDLE Event,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
IN HANDLE Event,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG CompletionFilter,
|
||||
IN BOOLEAN Asynchroneous,
|
||||
IN BOOLEAN Asynchroneous,
|
||||
OUT PVOID ChangeBuffer,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN WatchSubtree)
|
||||
|
@ -1475,7 +1538,6 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
|
|||
OUT PULONG ReturnLength)
|
||||
{
|
||||
PREGISTRY_HIVE RegistryHive;
|
||||
UCHAR ValueName[MAX_PATH];
|
||||
PVALUE_CELL ValueCell;
|
||||
PKEY_OBJECT KeyObject;
|
||||
PDATA_CELL DataCell;
|
||||
|
@ -1511,17 +1573,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
|
|||
|
||||
for (i = 0; i < NumberOfValues; i++)
|
||||
{
|
||||
wcstombs(ValueName,
|
||||
ValueList[i].ValueName->Buffer,
|
||||
ValueList[i].ValueName->Length >> 1);
|
||||
ValueName[ValueList[i].ValueName->Length >> 1] = 0;
|
||||
|
||||
DPRINT("ValueName: '%s'\n", ValueName);
|
||||
DPRINT("ValueName: '%wZ'\n", ValueList[i].ValueName);
|
||||
|
||||
/* Get Value block of interest */
|
||||
Status = CmiScanKeyForValue(RegistryHive,
|
||||
KeyCell,
|
||||
ValueName,
|
||||
ValueList[i].ValueName,
|
||||
&ValueCell,
|
||||
NULL);
|
||||
|
||||
|
|
|
@ -1204,7 +1204,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
/* Reallocate the hash table block */
|
||||
Status = CmiAllocateHashTableBlock(RegistryHive,
|
||||
&NewHashBlock,
|
||||
&HTOffset,
|
||||
&HTOffset,
|
||||
HashBlock->HashTableSize +
|
||||
REG_EXTEND_HASH_TABLE_SIZE);
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
&HashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
||||
CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
|
||||
KeyCell->HashTableOffset = HTOffset;
|
||||
KeyCell->HashTableOffset = HTOffset;
|
||||
HashBlock = NewHashBlock;
|
||||
}
|
||||
}
|
||||
|
@ -1237,13 +1237,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName,
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset)
|
||||
{
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PVALUE_CELL CurValueCell;
|
||||
ULONG Length;
|
||||
ULONG i;
|
||||
|
||||
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
|
||||
|
@ -1261,17 +1260,17 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
|||
for (i = 0; i < KeyCell->NumberOfValues; i++)
|
||||
{
|
||||
CurValueCell = CmiGetBlock(RegistryHive,
|
||||
ValueListCell->Values[i],
|
||||
NULL);
|
||||
/* FIXME: perhaps we must not ignore case if NtCreateKey has not been */
|
||||
/* called with OBJ_CASE_INSENSITIVE flag ? */
|
||||
Length = strlen(ValueName);
|
||||
ValueListCell->Values[i],
|
||||
NULL);
|
||||
|
||||
if ((CurValueCell != NULL) &&
|
||||
(CurValueCell->NameSize == Length) &&
|
||||
(_strnicmp(CurValueCell->Name, ValueName, Length) == 0))
|
||||
CmiComparePackedNames(ValueName,
|
||||
CurValueCell->Name,
|
||||
CurValueCell->NameSize,
|
||||
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
|
||||
{
|
||||
*ValueCell = CurValueCell;
|
||||
if (VBOffset)
|
||||
if (VBOffset)
|
||||
*VBOffset = ValueListCell->Values[i];
|
||||
//DPRINT("Found value %s\n", ValueName);
|
||||
break;
|
||||
|
@ -1280,7 +1279,7 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
|||
}
|
||||
|
||||
CmiReleaseBlock(RegistryHive, ValueListCell);
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1293,7 +1292,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
|||
{
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PVALUE_CELL CurValueCell;
|
||||
|
||||
|
||||
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
|
||||
|
||||
*ValueCell = NULL;
|
||||
|
@ -1321,7 +1320,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
CmiReleaseBlock(RegistryHive, CurValueCell);
|
||||
CmiReleaseBlock(RegistryHive, ValueListCell);
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1329,7 +1328,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueNameBuf,
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PVALUE_CELL *pValueCell,
|
||||
OUT BLOCK_OFFSET *pVBOffset)
|
||||
{
|
||||
|
@ -1343,7 +1342,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
|||
Status = CmiAllocateValueCell(RegistryHive,
|
||||
&NewValueCell,
|
||||
&VBOffset,
|
||||
ValueNameBuf);
|
||||
ValueName);
|
||||
*pVBOffset = VBOffset;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1407,7 +1406,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS
|
||||
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName)
|
||||
IN PUNICODE_STRING ValueName)
|
||||
{
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PVALUE_CELL CurValueCell;
|
||||
|
@ -1425,9 +1424,12 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
|||
for (i = 0; i < KeyCell->NumberOfValues; i++)
|
||||
{
|
||||
CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
|
||||
|
||||
if ((CurValueCell != NULL) &&
|
||||
(CurValueCell->NameSize == strlen(ValueName)) &&
|
||||
(memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0))
|
||||
CmiComparePackedNames(ValueName,
|
||||
CurValueCell->Name,
|
||||
CurValueCell->NameSize,
|
||||
CurValueCell->Flags & REG_VALUE_NAME_PACKED))
|
||||
{
|
||||
if ((KeyCell->NumberOfValues - 1) < i)
|
||||
{
|
||||
|
@ -1539,20 +1541,25 @@ NTSTATUS
|
|||
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
|
||||
PVALUE_CELL *ValueCell,
|
||||
BLOCK_OFFSET *VBOffset,
|
||||
IN PCHAR ValueNameBuf)
|
||||
IN PUNICODE_STRING ValueName)
|
||||
{
|
||||
PVALUE_CELL NewValueCell;
|
||||
ULONG NewValueSize;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN Packable;
|
||||
ULONG NameSize;
|
||||
ULONG i;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
NewValueSize = sizeof(VALUE_CELL) + strlen(ValueNameBuf);
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID*) &NewValueCell,
|
||||
NewValueSize,
|
||||
VBOffset);
|
||||
NameSize = CmiGetPackedNameLength(ValueName,
|
||||
&Packable);
|
||||
|
||||
DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize);
|
||||
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID*) &NewValueCell,
|
||||
sizeof(VALUE_CELL) + NameSize,
|
||||
VBOffset);
|
||||
if ((NewValueCell == NULL) || (!NT_SUCCESS(Status)))
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -1560,8 +1567,22 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
|
|||
else
|
||||
{
|
||||
NewValueCell->Id = REG_VALUE_CELL_ID;
|
||||
NewValueCell->NameSize = strlen(ValueNameBuf);
|
||||
memcpy(NewValueCell->Name, ValueNameBuf, strlen(ValueNameBuf));
|
||||
NewValueCell->NameSize = NameSize;
|
||||
if (Packable)
|
||||
{
|
||||
/* Pack the value name */
|
||||
for (i = 0; i < NameSize; i++)
|
||||
NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i];
|
||||
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the value name */
|
||||
RtlCopyMemory(NewValueCell->Name,
|
||||
ValueName->Buffer,
|
||||
NameSize);
|
||||
NewValueCell->Flags = 0;
|
||||
}
|
||||
NewValueCell->DataType = 0;
|
||||
NewValueCell->DataSize = 0;
|
||||
NewValueCell->DataOffset = 0xffffffff;
|
||||
|
@ -1669,9 +1690,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
NTSTATUS
|
||||
CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID *Block,
|
||||
LONG BlockSize,
|
||||
BLOCK_OFFSET * pBlockOffset)
|
||||
PVOID *Block,
|
||||
LONG BlockSize,
|
||||
BLOCK_OFFSET * pBlockOffset)
|
||||
{
|
||||
PCELL_HEADER NewBlock;
|
||||
NTSTATUS Status;
|
||||
|
@ -1687,86 +1708,88 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
|||
{
|
||||
NewBlock = ExAllocatePool(NonPagedPool, BlockSize);
|
||||
|
||||
if (NewBlock == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(NewBlock, BlockSize);
|
||||
NewBlock->CellSize = BlockSize;
|
||||
CmiLockBlock(RegistryHive, NewBlock);
|
||||
*Block = NewBlock;
|
||||
if (pBlockOffset)
|
||||
*pBlockOffset = (BLOCK_OFFSET) NewBlock;
|
||||
}
|
||||
if (NewBlock == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(NewBlock, BlockSize);
|
||||
NewBlock->CellSize = BlockSize;
|
||||
CmiLockBlock(RegistryHive, NewBlock);
|
||||
*Block = NewBlock;
|
||||
if (pBlockOffset)
|
||||
*pBlockOffset = (BLOCK_OFFSET) NewBlock;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
/* first search in free blocks */
|
||||
NewBlock = NULL;
|
||||
for (i = 0; i < RegistryHive->FreeListSize; i++)
|
||||
{
|
||||
if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
|
||||
{
|
||||
PVOID Temp;
|
||||
NewBlock = RegistryHive->FreeList[i];
|
||||
/* first search in free blocks */
|
||||
NewBlock = NULL;
|
||||
for (i = 0; i < RegistryHive->FreeListSize; i++)
|
||||
{
|
||||
if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
|
||||
{
|
||||
PVOID Temp;
|
||||
|
||||
if (pBlockOffset)
|
||||
*pBlockOffset = RegistryHive->FreeListOffset[i];
|
||||
NewBlock = RegistryHive->FreeList[i];
|
||||
if (pBlockOffset)
|
||||
*pBlockOffset = RegistryHive->FreeListOffset[i];
|
||||
|
||||
/* Update time of heap */
|
||||
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
|
||||
/* Update time of heap */
|
||||
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
|
||||
|
||||
if (Temp)
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
if (Temp)
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
|
||||
if ((i + 1) < RegistryHive->FreeListSize)
|
||||
{
|
||||
RtlMoveMemory(&RegistryHive->FreeList[i],
|
||||
&RegistryHive->FreeList[i + 1],
|
||||
sizeof(RegistryHive->FreeList[0])
|
||||
* (RegistryHive->FreeListSize - i - 1));
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[i],
|
||||
&RegistryHive->FreeListOffset[i + 1],
|
||||
sizeof(RegistryHive->FreeListOffset[0])
|
||||
* (RegistryHive->FreeListSize - i - 1));
|
||||
}
|
||||
RegistryHive->FreeListSize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i + 1) < RegistryHive->FreeListSize)
|
||||
{
|
||||
RtlMoveMemory(&RegistryHive->FreeList[i],
|
||||
&RegistryHive->FreeList[i + 1],
|
||||
sizeof(RegistryHive->FreeList[0])
|
||||
* (RegistryHive->FreeListSize - i - 1));
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[i],
|
||||
&RegistryHive->FreeListOffset[i + 1],
|
||||
sizeof(RegistryHive->FreeListOffset[0])
|
||||
* (RegistryHive->FreeListSize - i - 1));
|
||||
}
|
||||
RegistryHive->FreeListSize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Need to extend hive file : */
|
||||
if (NewBlock == NULL)
|
||||
{
|
||||
/* Add a new block */
|
||||
Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
|
||||
}
|
||||
/* Need to extend hive file : */
|
||||
if (NewBlock == NULL)
|
||||
{
|
||||
/* Add a new block */
|
||||
Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*Block = NewBlock;
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*Block = NewBlock;
|
||||
|
||||
/* Split the block in two parts */
|
||||
if (NewBlock->CellSize > BlockSize)
|
||||
{
|
||||
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
|
||||
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
|
||||
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
|
||||
}
|
||||
else if (NewBlock->CellSize < BlockSize)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
RtlZeroMemory(*Block, BlockSize);
|
||||
((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
|
||||
CmiLockBlock(RegistryHive, *Block);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
/* Split the block in two parts */
|
||||
if (NewBlock->CellSize > BlockSize)
|
||||
{
|
||||
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
|
||||
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
|
||||
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
|
||||
}
|
||||
else if (NewBlock->CellSize < BlockSize)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
RtlZeroMemory(*Block, BlockSize);
|
||||
((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
|
||||
CmiLockBlock(RegistryHive, *Block);
|
||||
}
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1781,27 +1804,27 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
|||
Status = STATUS_SUCCESS;
|
||||
|
||||
if (IsVolatileHive(RegistryHive))
|
||||
{
|
||||
CmiReleaseBlock(RegistryHive, Block);
|
||||
ExFreePool(Block);
|
||||
}
|
||||
{
|
||||
CmiReleaseBlock(RegistryHive, Block);
|
||||
ExFreePool(Block);
|
||||
}
|
||||
else
|
||||
{
|
||||
PCELL_HEADER pFree = Block;
|
||||
{
|
||||
PCELL_HEADER pFree = Block;
|
||||
|
||||
if (pFree->CellSize < 0)
|
||||
pFree->CellSize = -pFree->CellSize;
|
||||
if (pFree->CellSize < 0)
|
||||
pFree->CellSize = -pFree->CellSize;
|
||||
|
||||
CmiAddFree(RegistryHive, Block, Offset);
|
||||
CmiReleaseBlock(RegistryHive, Block);
|
||||
CmiAddFree(RegistryHive, Block, Offset);
|
||||
CmiReleaseBlock(RegistryHive, Block);
|
||||
|
||||
/* Update time of heap */
|
||||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
/* Update time of heap */
|
||||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
|
||||
/* FIXME: Set first dword to block_offset of another free block ? */
|
||||
/* FIXME: Concatenate with previous and next block if free */
|
||||
}
|
||||
/* FIXME: Set first dword to block_offset of another free block ? */
|
||||
/* FIXME: Concatenate with previous and next block if free */
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -1825,29 +1848,29 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
|||
FreeBlock, FreeOffset);
|
||||
DPRINT("\n");
|
||||
if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
|
||||
{
|
||||
{
|
||||
DPRINT("\n");
|
||||
tmpList = ExAllocatePool(PagedPool,
|
||||
tmpList = ExAllocatePool(PagedPool,
|
||||
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
|
||||
DPRINT("\n");
|
||||
|
||||
if (tmpList == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
if (tmpList == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
DPRINT("\n");
|
||||
|
||||
tmpListOffset = ExAllocatePool(PagedPool,
|
||||
tmpListOffset = ExAllocatePool(PagedPool,
|
||||
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32));
|
||||
DPRINT("\n");
|
||||
|
||||
if (tmpListOffset == NULL)
|
||||
{
|
||||
ExFreePool(tmpList);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
if (tmpListOffset == NULL)
|
||||
{
|
||||
ExFreePool(tmpList);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
DPRINT("\n");
|
||||
|
||||
if (RegistryHive->FreeListMax)
|
||||
{
|
||||
if (RegistryHive->FreeListMax)
|
||||
{
|
||||
DPRINT("\n");
|
||||
RtlMoveMemory(tmpList, RegistryHive->FreeList,
|
||||
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
|
||||
|
@ -1986,3 +2009,80 @@ CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
|||
/* FIXME: Implement */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
|
||||
OUT PBOOLEAN Packable)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (Packable != NULL)
|
||||
*Packable = TRUE;
|
||||
|
||||
for (i = 0; i < Name->Length; i++)
|
||||
{
|
||||
if (Name->Buffer[i] > 0xFF)
|
||||
{
|
||||
if (Packable != NULL)
|
||||
*Packable = FALSE;
|
||||
return(Name->Length);
|
||||
}
|
||||
}
|
||||
|
||||
return(Name->Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
CmiComparePackedNames(IN PUNICODE_STRING Name,
|
||||
IN PCHAR NameBuffer,
|
||||
IN USHORT NameBufferSize,
|
||||
IN BOOLEAN NamePacked)
|
||||
{
|
||||
PWCHAR UNameBuffer;
|
||||
ULONG i;
|
||||
|
||||
if (NamePacked)
|
||||
{
|
||||
if (Name->Length != NameBufferSize * sizeof(WCHAR))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i]))
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Name->Length != NameBufferSize)
|
||||
return(FALSE);
|
||||
|
||||
UNameBuffer = (PWCHAR)NameBuffer;
|
||||
|
||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i]))
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmiCopyPackedName(PWCHAR NameBuffer,
|
||||
PCHAR PackedNameBuffer,
|
||||
ULONG PackedNameSize)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < PackedNameSize; i++)
|
||||
NameBuffer[i] = (WCHAR)PackedNameBuffer[i];
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.78 2002/11/26 15:31:41 ekohl Exp $
|
||||
/* $Id: registry.c,v 1.79 2002/11/30 14:46:27 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include <string.h>
|
||||
#include <internal/pool.h>
|
||||
#include <internal/registry.h>
|
||||
#include <reactos/bugcodes.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -204,7 +205,7 @@ CmiCheckByName(BOOLEAN Verbose,
|
|||
wcscpy(KeyPathBuffer, L"\\Registry\\");
|
||||
wcscat(KeyPathBuffer, KeyName);
|
||||
|
||||
RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
|
||||
RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyPath,
|
||||
|
@ -219,11 +220,11 @@ CmiCheckByName(BOOLEAN Verbose,
|
|||
if (CHECKED)
|
||||
{
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
{
|
||||
DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status);
|
||||
DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status);
|
||||
assert(NT_SUCCESS(Status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CmiCheckKey(Verbose, Key);
|
||||
|
@ -484,6 +485,7 @@ CmInit2(PCHAR CommandLine)
|
|||
{
|
||||
PCHAR p1, p2;
|
||||
ULONG PiceStart;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* FIXME: Store system start options */
|
||||
|
||||
|
@ -515,12 +517,17 @@ CmInit2(PCHAR CommandLine)
|
|||
p1 = p2;
|
||||
}
|
||||
#ifndef WIN32_REGDBG
|
||||
RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
|
||||
L"\\Pice",
|
||||
L"Start",
|
||||
REG_DWORD,
|
||||
&PiceStart,
|
||||
sizeof(ULONG));
|
||||
Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
|
||||
L"\\Pice",
|
||||
L"Start",
|
||||
REG_DWORD,
|
||||
&PiceStart,
|
||||
sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
KeBugCheck(CONFIG_INITIALIZATION_FAILED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -602,12 +609,12 @@ CmiCreateCurrentControlSetLink(VOID)
|
|||
|
||||
RtlInitUnicodeStringFromLiteral(&LinkValue,
|
||||
L"SymbolicLinkValue");
|
||||
Status=NtSetValueKey(KeyHandle,
|
||||
&LinkValue,
|
||||
0,
|
||||
REG_LINK,
|
||||
(PVOID)TargetNameBuffer,
|
||||
TargetNameLength);
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&LinkValue,
|
||||
0,
|
||||
REG_LINK,
|
||||
(PVOID)TargetNameBuffer,
|
||||
TargetNameLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
|
||||
|
|
|
@ -168,6 +168,8 @@ CmiObjectParse(PVOID ParsedObject,
|
|||
if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
|
||||
!((Attributes & OBJ_OPENLINK) && (end == NULL)))
|
||||
{
|
||||
DPRINT("Found link\n");
|
||||
|
||||
RtlInitUnicodeString(&LinkPath, NULL);
|
||||
Status = CmiGetLinkTarget(FoundObject->RegistryHive,
|
||||
FoundObject->KeyCell,
|
||||
|
@ -436,18 +438,22 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
|
|||
PKEY_CELL KeyCell,
|
||||
PUNICODE_STRING TargetPath)
|
||||
{
|
||||
UNICODE_STRING LinkName = UNICODE_STRING_INITIALIZER(L"SymbolicLinkValue");
|
||||
PVALUE_CELL ValueCell;
|
||||
PDATA_CELL DataCell;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("CmiGetLinkTarget() called\n");
|
||||
|
||||
/* Get Value block of interest */
|
||||
Status = CmiScanKeyForValue(RegistryHive,
|
||||
KeyCell,
|
||||
"SymbolicLinkValue",
|
||||
&LinkName,
|
||||
&ValueCell,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -485,6 +491,8 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
|
|||
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
DPRINT("TargetPath '%wZ'\n", TargetPath);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#ifdef WIN32_REGDBG
|
||||
#include "cm_win32.h"
|
||||
#else
|
||||
|
@ -23,6 +25,9 @@
|
|||
#include "cm.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlCheckRegistryKey(IN ULONG RelativeTo,
|
||||
IN PWSTR Path)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue