Author: hbelusca
Date: Sun Jan 17 00:50:03 2016
New Revision: 70602
URL:
http://svn.reactos.org/svn/reactos?rev=70602&view=rev
Log:
[MKHIVE]
- Make mkhive tool correctly initialize the Max(Value)[Name|Data]Length members of HHIVE
structure. CORE-10794 #resolve
- Add default security hive descriptors to our mkhive-built registry hives. CORE-10795
#resolve
- Make MKHIVE fully using the CMLIB library. CORE-10802
CORE-10793
Modified:
trunk/reactos/tools/mkhive/cmi.c
trunk/reactos/tools/mkhive/cmi.h
trunk/reactos/tools/mkhive/mkhive.c
trunk/reactos/tools/mkhive/mkhive.h
trunk/reactos/tools/mkhive/registry.c
trunk/reactos/tools/mkhive/rtl.c
Modified: trunk/reactos/tools/mkhive/cmi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/cmi.c?rev=706…
==============================================================================
--- trunk/reactos/tools/mkhive/cmi.c [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/cmi.c [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -16,7 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/cmi.c
* PURPOSE: Registry file manipulation routines
@@ -33,7 +34,7 @@
IN BOOLEAN Paged,
IN ULONG Tag)
{
- return (PVOID) malloc((size_t)Size);
+ return (PVOID)malloc((size_t)Size);
}
VOID
@@ -69,9 +70,10 @@
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
FILE *File = CmHive->FileHandles[HFILE_TYPE_PRIMARY];
- if (0 != fseek (File, *FileOffset, SEEK_SET))
+ if (fseek(File, *FileOffset, SEEK_SET) != 0)
return FALSE;
- return BufferLength == fwrite (Buffer, 1, BufferLength, File);
+
+ return (fwrite(Buffer, 1, BufferLength, File) == BufferLength);
}
static BOOLEAN
@@ -96,25 +98,24 @@
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
FILE *File = CmHive->FileHandles[HFILE_TYPE_PRIMARY];
- return 0 == fflush (File);
+ return (fflush(File) == 0);
}
NTSTATUS
-CmiInitializeTempHive(
- IN OUT PCMHIVE Hive)
+CmiInitializeHive(
+ IN OUT PCMHIVE Hive,
+ IN PCWSTR Name)
{
NTSTATUS Status;
- RtlZeroMemory (
- Hive,
- sizeof(CMHIVE));
+ RtlZeroMemory(Hive, sizeof(*Hive));
DPRINT("Hive 0x%p\n", Hive);
Status = HvInitialize(&Hive->Hive,
HINIT_CREATE,
- 0,
- 0,
+ HIVE_NOLAZYFLUSH,
+ HFILE_TYPE_PRIMARY,
0,
CmpAllocate,
CmpFree,
@@ -129,94 +130,59 @@
return Status;
}
- if (!CmCreateRootNode (&Hive->Hive, L""))
- {
- HvFree (&Hive->Hive);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Hive->Flags = HIVE_NO_FILE;
+ // HACK: See the HACK from r31253
+ if (!CmCreateRootNode(&Hive->Hive, Name))
+ {
+ HvFree(&Hive->Hive);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
/* Add the new hive to the hive list */
InsertTailList(&CmiHiveListHead,
&Hive->HiveList);
- VERIFY_REGISTRY_HIVE (Hive);
-
return STATUS_SUCCESS;
}
-static NTSTATUS
-CmiAddKeyToHashTable(
- IN PCMHIVE RegistryHive,
- IN OUT PCM_KEY_FAST_INDEX HashCell,
- IN HCELL_INDEX HashCellIndex,
- IN PCM_KEY_NODE NewKeyCell,
- IN HCELL_INDEX NKBOffset)
-{
- ULONG i;
- ULONG HashKey = 0;
-
- if (NewKeyCell->Flags & KEY_COMP_NAME)
- {
- RtlCopyMemory(
- &HashKey,
- NewKeyCell->Name,
- min(NewKeyCell->NameLength, sizeof(ULONG)));
- }
-
- for (i = 0; i < HashCell->Count; i++)
- {
- if (HashCell->List[i].HashKey > HashKey)
- break;
- }
-
- if (i < HashCell->Count)
- {
- RtlMoveMemory(HashCell->List + i + 1,
- HashCell->List + i,
- (HashCell->Count - i) *
- sizeof(HashCell->List[0]));
- }
-
- HashCell->List[i].Cell = NKBOffset;
- HashCell->List[i].HashKey = HashKey;
- HashCell->Count++;
- HvMarkCellDirty(&RegistryHive->Hive, HashCellIndex, FALSE);
+NTSTATUS
+CmiCreateSecurityKey(
+ IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength)
+{
+ HCELL_INDEX SecurityCell;
+ PCM_KEY_NODE Node;
+ PCM_KEY_SECURITY Security;
+
+ Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
+ SecurityCell = HvAllocateCell(Hive,
+ FIELD_OFFSET(CM_KEY_SECURITY, Descriptor) +
+ DescriptorLength,
+ Stable,
+ HCELL_NIL);
+ if (SecurityCell == HCELL_NIL)
+ {
+ HvReleaseCell(Hive, Cell);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Node->Security = SecurityCell;
+ Security = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityCell);
+ Security->Signature = CM_KEY_SECURITY_SIGNATURE;
+ Security->ReferenceCount = 1;
+ Security->DescriptorLength = DescriptorLength;
+
+ RtlMoveMemory(&Security->Descriptor,
+ Descriptor,
+ DescriptorLength);
+
+ Security->Flink = Security->Blink = SecurityCell;
+
+ HvReleaseCell(Hive, SecurityCell);
+ HvReleaseCell(Hive, Cell);
+
return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-CmiAllocateHashTableCell (
- IN PCMHIVE RegistryHive,
- OUT PCM_KEY_FAST_INDEX *HashBlock,
- OUT HCELL_INDEX *HBOffset,
- IN USHORT SubKeyCount,
- IN HSTORAGE_TYPE Storage)
-{
- PCM_KEY_FAST_INDEX NewHashBlock;
- ULONG NewHashSize;
- NTSTATUS Status;
-
- Status = STATUS_SUCCESS;
- *HashBlock = NULL;
- NewHashSize = FIELD_OFFSET(CM_KEY_FAST_INDEX, List) +
- (SubKeyCount * sizeof(CM_INDEX));
- *HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage,
HCELL_NIL);
-
- if (*HBOffset == HCELL_NIL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- else
- {
- NewHashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive,
*HBOffset);
- NewHashBlock->Signature = CM_KEY_FAST_LEAF;
- NewHashBlock->Count = 0;
- *HashBlock = NewHashBlock;
- }
-
- return Status;
}
static NTSTATUS
@@ -224,105 +190,98 @@
IN PCMHIVE RegistryHive,
IN HCELL_INDEX ParentKeyCellOffset,
IN PCUNICODE_STRING SubKeyName,
- IN ULONG CreateOptions,
+ IN BOOLEAN VolatileKey,
OUT HCELL_INDEX* pNKBOffset)
{
HCELL_INDEX NKBOffset;
PCM_KEY_NODE NewKeyCell;
- ULONG NewBlockSize;
- NTSTATUS Status;
- USHORT NameLength;
- PWSTR NamePtr;
- BOOLEAN Packable;
+ UNICODE_STRING KeyName;
HSTORAGE_TYPE Storage;
- ULONG i;
-
- /* Skip leading backslash */
- if (SubKeyName->Buffer[0] == L'\\')
- {
- NamePtr = &SubKeyName->Buffer[1];
- NameLength = SubKeyName->Length - sizeof(WCHAR);
+
+ /* Skip leading path separator if present */
+ if (SubKeyName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
+ {
+ KeyName.Buffer = &SubKeyName->Buffer[1];
+ KeyName.Length = KeyName.MaximumLength = SubKeyName->Length - sizeof(WCHAR);
}
else
{
- NamePtr = SubKeyName->Buffer;
- NameLength = SubKeyName->Length;
- }
-
- /* Check whether key name can be packed */
- Packable = TRUE;
- for (i = 0; i < NameLength / sizeof(WCHAR); i++)
- {
- if (NamePtr[i] & 0xFF00)
+ KeyName = *SubKeyName;
+ }
+
+ Storage = (VolatileKey ? Volatile : Stable);
+
+ NKBOffset = HvAllocateCell(&RegistryHive->Hive,
+ FIELD_OFFSET(CM_KEY_NODE, Name) +
+ CmpNameSize(&RegistryHive->Hive, &KeyName),
+ Storage,
+ HCELL_NIL);
+ if (NKBOffset == HCELL_NIL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NewKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive, NKBOffset);
+ if (NewKeyCell == NULL)
+ {
+ HvFreeCell(&RegistryHive->Hive, NKBOffset);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE;
+ NewKeyCell->Flags = (VolatileKey ? KEY_IS_VOLATILE : 0);
+ KeQuerySystemTime(&NewKeyCell->LastWriteTime);
+ NewKeyCell->Parent = ParentKeyCellOffset;
+ NewKeyCell->SubKeyCounts[Stable] = 0;
+ NewKeyCell->SubKeyCounts[Volatile] = 0;
+ NewKeyCell->SubKeyLists[Stable] = HCELL_NIL;
+ NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
+ NewKeyCell->ValueList.Count = 0;
+ NewKeyCell->ValueList.List = HCELL_NIL;
+ NewKeyCell->Security = HCELL_NIL;
+ NewKeyCell->Class = HCELL_NIL;
+ NewKeyCell->ClassLength = 0;
+ NewKeyCell->MaxNameLen = 0;
+ NewKeyCell->MaxClassLen = 0;
+ NewKeyCell->MaxValueNameLen = 0;
+ NewKeyCell->MaxValueDataLen = 0;
+ NewKeyCell->NameLength = CmpCopyName(&RegistryHive->Hive,
NewKeyCell->Name, &KeyName);
+ if (NewKeyCell->NameLength < KeyName.Length) NewKeyCell->Flags |=
KEY_COMP_NAME;
+
+ /* Inherit the security from the parent */
+ if (ParentKeyCellOffset == HCELL_NIL)
+ {
+ // We are in fact creating a root key.
+ // This is not handled there, but when we
+ // call CmCreateRootNode instead.
+ ASSERT(FALSE);
+ }
+ else
+ {
+ /* Get the parent node */
+ PCM_KEY_NODE ParentKeyCell;
+ ParentKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive,
ParentKeyCellOffset);
+
+ if (ParentKeyCell)
{
- Packable = FALSE;
- break;
+ /* Inherit the security block of the parent */
+ NewKeyCell->Security = ParentKeyCell->Security;
+ if (NewKeyCell->Security != HCELL_NIL)
+ {
+ PCM_KEY_SECURITY Security;
+ Security = (PCM_KEY_SECURITY)HvGetCell(&RegistryHive->Hive,
NewKeyCell->Security);
+ ++Security->ReferenceCount;
+ HvReleaseCell(&RegistryHive->Hive, NewKeyCell->Security);
+ }
+
+ HvReleaseCell(&RegistryHive->Hive, ParentKeyCellOffset);
}
}
- /* Adjust name size */
- if (Packable)
- {
- NameLength = NameLength / sizeof(WCHAR);
- }
-
- Status = STATUS_SUCCESS;
-
- Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
- NewBlockSize = FIELD_OFFSET(CM_KEY_NODE, Name) + NameLength;
- NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage,
HCELL_NIL);
- if (NKBOffset == HCELL_NIL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- else
- {
- NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
- NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE;
- if (CreateOptions & REG_OPTION_VOLATILE)
- {
- NewKeyCell->Flags = KEY_IS_VOLATILE;
- }
- else
- {
- NewKeyCell->Flags = 0;
- }
- KeQuerySystemTime(&NewKeyCell->LastWriteTime);
- NewKeyCell->Parent = ParentKeyCellOffset;
- NewKeyCell->SubKeyCounts[Stable] = 0;
- NewKeyCell->SubKeyCounts[Volatile] = 0;
- NewKeyCell->SubKeyLists[Stable] = HCELL_NIL;
- NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
- NewKeyCell->ValueList.Count = 0;
- NewKeyCell->ValueList.List = HCELL_NIL;
- NewKeyCell->Security = HCELL_NIL;
- NewKeyCell->Class = HCELL_NIL;
-
- /* Pack the key name */
- NewKeyCell->NameLength = NameLength;
- if (Packable)
- {
- NewKeyCell->Flags |= KEY_COMP_NAME;
- for (i = 0; i < NameLength; i++)
- {
- ((PCHAR)NewKeyCell->Name)[i] = (CHAR)(NamePtr[i] & 0x00FF);
- }
- }
- else
- {
- RtlCopyMemory(NewKeyCell->Name,
- NamePtr,
- NameLength);
- }
-
- VERIFY_KEY_CELL(NewKeyCell);
- }
-
- if (NT_SUCCESS(Status))
- {
- *pNKBOffset = NKBOffset;
- }
- return Status;
+ HvReleaseCell(&RegistryHive->Hive, NKBOffset);
+
+ *pNKBOffset = NKBOffset;
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -330,291 +289,156 @@
IN PCMHIVE RegistryHive,
IN HCELL_INDEX ParentKeyCellOffset,
IN PCUNICODE_STRING SubKeyName,
- IN ULONG CreateOptions,
- OUT PCM_KEY_NODE *pSubKeyCell,
+ IN BOOLEAN VolatileKey,
OUT HCELL_INDEX *pBlockOffset)
{
PCM_KEY_NODE ParentKeyCell;
HCELL_INDEX NKBOffset;
NTSTATUS Status;
+ /* Create the new key */
+ Status = CmiCreateSubKey(RegistryHive, ParentKeyCellOffset, SubKeyName, VolatileKey,
&NKBOffset);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Mark the parent cell as dirty */
+ HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset, FALSE);
+
+ if (!CmpAddSubKey(&RegistryHive->Hive, ParentKeyCellOffset, NKBOffset))
+ {
+ /* FIXME: delete newly created cell */
+ // CmpFreeKeyByCell(&RegistryHive->Hive, NewCell /*NKBOffset*/, FALSE);
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get the parent node */
ParentKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive,
ParentKeyCellOffset);
if (!ParentKeyCell)
- return STATUS_UNSUCCESSFUL;
- VERIFY_KEY_CELL(ParentKeyCell);
-
- /* Create the new key */
- Status = CmiCreateSubKey(RegistryHive, ParentKeyCellOffset, SubKeyName,
CreateOptions, &NKBOffset);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (!CmpAddSubKey(&RegistryHive->Hive, ParentKeyCellOffset, NKBOffset))
{
/* FIXME: delete newly created cell */
return STATUS_UNSUCCESSFUL;
}
-
+ VERIFY_KEY_CELL(ParentKeyCell);
+
+ /* Update the timestamp */
KeQuerySystemTime(&ParentKeyCell->LastWriteTime);
- HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset, FALSE);
+
+ /* Check if we need to update name maximum, update it if so */
+ if (ParentKeyCell->MaxNameLen < SubKeyName->Length)
+ ParentKeyCell->MaxNameLen = SubKeyName->Length;
+
+ /* Release the cell */
+ HvReleaseCell(&RegistryHive->Hive, ParentKeyCellOffset);
*pBlockOffset = NKBOffset;
return STATUS_SUCCESS;
-}
-
-#if 0 // Those two functions seem to be unused, but keep them just in case we may need to
use them in the future...
-static BOOLEAN
-CmiCompareHash(
- IN PCUNICODE_STRING KeyName,
- IN PCHAR HashString)
-{
- CHAR Buffer[4];
-
- Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0;
- Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0;
- Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0;
- Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0;
-
- return (strncmp(Buffer, HashString, 4) == 0);
-}
-
-static BOOLEAN
-CmiCompareHashI(
- IN PCUNICODE_STRING KeyName,
- IN PCHAR HashString)
-{
- CHAR Buffer[4];
-
- Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0;
- Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0;
- Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0;
- Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0;
-
- return (strncasecmp(Buffer, HashString, 4) == 0);
-}
-#endif
-
-NTSTATUS
-CmiScanForSubKey(
- IN PCMHIVE RegistryHive,
- IN HCELL_INDEX ParentKeyCellOffset,
- IN PCUNICODE_STRING SubKeyName,
- IN ULONG Attributes,
- OUT PCM_KEY_NODE *pSubKeyCell,
- OUT HCELL_INDEX *pBlockOffset)
-{
- PCM_KEY_NODE KeyCell;
- PCM_KEY_FAST_INDEX HashBlock;
- PCM_KEY_NODE CurSubKeyCell;
- BOOLEAN CaseInsensitive;
- ULONG Storage;
- ULONG i;
-
- KeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive, ParentKeyCellOffset);
- if (!KeyCell)
- return STATUS_UNSUCCESSFUL;
- VERIFY_KEY_CELL(KeyCell);
-
- ASSERT(RegistryHive);
-
- *pSubKeyCell = NULL;
- CaseInsensitive = (Attributes & OBJ_CASE_INSENSITIVE) != 0;
-
- for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
- {
- if (KeyCell->SubKeyLists[Storage] == HCELL_NIL)
- {
- /* The key does not have any subkeys */
- continue;
- }
-
- /* Get hash table */
- HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive,
KeyCell->SubKeyLists[Storage]);
- if (!HashBlock || HashBlock->Signature != CM_KEY_FAST_LEAF)
- return STATUS_UNSUCCESSFUL;
-
- for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
- {
- if ((HashBlock->List[i].HashKey == 0) ||
- (CmCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey,
CaseInsensitive)))
- {
- CurSubKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive,
- HashBlock->List[i].Cell);
-
- if (CmCompareKeyName(CurSubKeyCell, SubKeyName, CaseInsensitive))
- {
- *pSubKeyCell = CurSubKeyCell;
- *pBlockOffset = HashBlock->List[i].Cell;
- return STATUS_SUCCESS;
- }
- }
- }
- }
-
- return STATUS_OBJECT_NAME_NOT_FOUND;
-}
-
-static USHORT
-CmiGetPackedNameLength(
- IN PCUNICODE_STRING Name,
- OUT PBOOLEAN pPackable)
-{
- USHORT i;
-
- *pPackable = TRUE;
-
- for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
- {
- if (Name->Buffer[i] & 0xFF00)
- {
- *pPackable = FALSE;
- return Name->Length;
- }
- }
-
- return (Name->Length / sizeof(WCHAR));
-}
-
-static NTSTATUS
-CmiAllocateValueCell(
- IN PCMHIVE RegistryHive,
- OUT PCM_KEY_VALUE *ValueCell,
- OUT HCELL_INDEX *VBOffset,
- IN PCUNICODE_STRING ValueName,
- IN HSTORAGE_TYPE Storage)
-{
- PCM_KEY_VALUE NewValueCell;
- BOOLEAN Packable;
- USHORT NameLength, i;
- NTSTATUS Status;
-
- Status = STATUS_SUCCESS;
-
- NameLength = CmiGetPackedNameLength(ValueName, &Packable);
-
- DPRINT("ValueName->Length %u NameLength %u\n", ValueName->Length,
NameLength);
-
- *VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) +
NameLength, Storage, HCELL_NIL);
- if (*VBOffset == HCELL_NIL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- else
- {
- NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset);
- NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
- NewValueCell->NameLength = (USHORT)NameLength;
- if (Packable)
- {
- /* Pack the value name */
- for (i = 0; i < NameLength; i++)
- {
- ((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName->Buffer[i];
- }
- NewValueCell->Flags |= VALUE_COMP_NAME;
- }
- else
- {
- /* Copy the value name */
- RtlCopyMemory(NewValueCell->Name,
- ValueName->Buffer,
- NameLength);
- NewValueCell->Flags = 0;
- }
- NewValueCell->Type = 0;
- NewValueCell->DataLength = 0;
- NewValueCell->Data = HCELL_NIL;
- *ValueCell = NewValueCell;
- }
-
- return Status;
}
NTSTATUS
CmiAddValueKey(
IN PCMHIVE RegistryHive,
- IN HCELL_INDEX KeyCellOffset,
+ IN PCM_KEY_NODE Parent,
IN PCUNICODE_STRING ValueName,
OUT PCM_KEY_VALUE *pValueCell,
OUT HCELL_INDEX *pValueCellOffset)
{
- PVALUE_LIST_CELL ValueListCell;
- PCM_KEY_NODE KeyCell;
+ PCELL_DATA ValueListCell;
PCM_KEY_VALUE NewValueCell;
HCELL_INDEX ValueListCellOffset;
HCELL_INDEX NewValueCellOffset;
ULONG CellSize;
HSTORAGE_TYPE Storage;
- NTSTATUS Status;
-
- KeyCell = HvGetCell(&RegistryHive->Hive, KeyCellOffset);
- if (!KeyCell)
- return STATUS_UNSUCCESSFUL;
-
- Storage = (KeyCell->Flags & KEY_IS_VOLATILE) ? Volatile : Stable;
- if (KeyCell->ValueList.List == HCELL_NIL)
+
+#ifndef FIELD_SIZE
+#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
+#endif
+
+ Storage = (Parent->Flags & KEY_IS_VOLATILE) ? Volatile : Stable;
+ if (Parent->ValueList.List == HCELL_NIL)
{
/* Allocate some room for the value list */
- CellSize = sizeof(VALUE_LIST_CELL) + (3 * sizeof(HCELL_INDEX));
+ CellSize = FIELD_SIZE(CELL_DATA, u.KeyList) + (3 * sizeof(HCELL_INDEX));
ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize,
Storage, HCELL_NIL);
if (ValueListCellOffset == HCELL_NIL)
return STATUS_INSUFFICIENT_RESOURCES;
- ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive,
ValueListCellOffset);
+ ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive,
ValueListCellOffset);
+ if (!ValueListCell)
+ {
+ HvFreeCell(&RegistryHive->Hive, ValueListCellOffset);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Parent->ValueList.List = ValueListCellOffset;
+ }
+ else
+ {
+ ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive,
Parent->ValueList.List);
if (!ValueListCell)
return STATUS_UNSUCCESSFUL;
- KeyCell->ValueList.List = ValueListCellOffset;
- HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
- }
- else
- {
- ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive,
KeyCell->ValueList.List);
- if (!ValueListCell)
- return STATUS_UNSUCCESSFUL;
-
CellSize = ABS_VALUE(HvGetCellSize(&RegistryHive->Hive, ValueListCell));
- if (KeyCell->ValueList.Count >= CellSize / sizeof(HCELL_INDEX))
+ if (Parent->ValueList.Count >= CellSize / sizeof(HCELL_INDEX))
{
CellSize *= 2;
- ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive,
KeyCell->ValueList.List, CellSize);
+ ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive,
Parent->ValueList.List, CellSize);
if (ValueListCellOffset == HCELL_NIL)
return STATUS_INSUFFICIENT_RESOURCES;
- ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive,
ValueListCellOffset);
+ ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive,
ValueListCellOffset);
if (!ValueListCell)
return STATUS_UNSUCCESSFUL;
- KeyCell->ValueList.List = ValueListCellOffset;
- HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
+ Parent->ValueList.List = ValueListCellOffset;
}
}
- Status = CmiAllocateValueCell(RegistryHive,
- &NewValueCell,
- &NewValueCellOffset,
- ValueName,
- Storage);
- if (!NT_SUCCESS(Status))
- return Status;
-
- ValueListCell->ValueOffset[KeyCell->ValueList.Count] = NewValueCellOffset;
- KeyCell->ValueList.Count++;
- if (NewValueCell->Flags & VALUE_COMP_NAME)
- {
- if (NewValueCell->NameLength*sizeof(WCHAR) > KeyCell->MaxValueNameLen)
- KeyCell->MaxValueNameLen = NewValueCell->NameLength*sizeof(WCHAR);
+
+ NewValueCellOffset = HvAllocateCell(&RegistryHive->Hive,
+ FIELD_OFFSET(CM_KEY_VALUE, Name) +
+ CmpNameSize(&RegistryHive->Hive,
(PUNICODE_STRING)ValueName),
+ Storage,
+ HCELL_NIL);
+ if (NewValueCellOffset == HCELL_NIL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NewValueCell = (PCM_KEY_VALUE)HvGetCell(&RegistryHive->Hive,
NewValueCellOffset);
+ if (NewValueCell == NULL)
+ {
+ HvFreeCell(&RegistryHive->Hive, NewValueCellOffset);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
+ NewValueCell->NameLength = CmpCopyName(&RegistryHive->Hive,
+ NewValueCell->Name,
+ (PUNICODE_STRING)ValueName);
+
+ /* Check for compressed name */
+ if (NewValueCell->NameLength < ValueName->Length)
+ {
+ /* This is a compressed name */
+ NewValueCell->Flags = VALUE_COMP_NAME;
}
else
{
- if (NewValueCell->NameLength > KeyCell->MaxValueNameLen)
- KeyCell->MaxValueNameLen = NewValueCell->NameLength;
- }
-
- HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
- HvMarkCellDirty(&RegistryHive->Hive, KeyCell->ValueList.List, FALSE);
+ /* No flags to set */
+ NewValueCell->Flags = 0;
+ }
+
+ NewValueCell->Type = 0;
+ NewValueCell->DataLength = 0;
+ NewValueCell->Data = HCELL_NIL;
+
+
+ ValueListCell->u.KeyList[Parent->ValueList.Count] = NewValueCellOffset;
+ Parent->ValueList.Count++;
+
+ HvMarkCellDirty(&RegistryHive->Hive, Parent->ValueList.List, FALSE);
HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset, FALSE);
*pValueCell = NewValueCell;
@@ -622,53 +446,3 @@
return STATUS_SUCCESS;
}
-
-NTSTATUS
-CmiScanForValueKey(
- IN PCMHIVE RegistryHive,
- IN HCELL_INDEX KeyCellOffset,
- IN PCUNICODE_STRING ValueName,
- OUT PCM_KEY_VALUE *pValueCell,
- OUT HCELL_INDEX *pValueCellOffset)
-{
- PCM_KEY_NODE KeyCell;
- PVALUE_LIST_CELL ValueListCell;
- PCM_KEY_VALUE CurValueCell;
- ULONG i;
-
- KeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive, KeyCellOffset);
- if (!KeyCell)
- return STATUS_UNSUCCESSFUL;
-
- *pValueCell = NULL;
- *pValueCellOffset = HCELL_NIL;
-
- /* The key does not have any values */
- if (KeyCell->ValueList.List == HCELL_NIL)
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive,
KeyCell->ValueList.List);
-
- VERIFY_VALUE_LIST_CELL(ValueListCell);
-
- for (i = 0; i < KeyCell->ValueList.Count; i++)
- {
- CurValueCell = (PCM_KEY_VALUE)HvGetCell(&RegistryHive->Hive,
- ValueListCell->ValueOffset[i]);
-
- if (CmComparePackedNames(ValueName,
- (PUCHAR)CurValueCell->Name,
- CurValueCell->NameLength,
- (CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE :
FALSE,
- TRUE))
- {
- *pValueCell = CurValueCell;
- *pValueCellOffset = ValueListCell->ValueOffset[i];
- return STATUS_SUCCESS;
- }
- }
-
- return STATUS_OBJECT_NAME_NOT_FOUND;
-}
Modified: trunk/reactos/tools/mkhive/cmi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/cmi.h?rev=706…
==============================================================================
--- trunk/reactos/tools/mkhive/cmi.h [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/cmi.h [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -16,7 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/cmi.h
* PURPOSE: Registry file manipulation routines
@@ -24,42 +25,31 @@
*/
#define VERIFY_KEY_CELL(key)
-#define VERIFY_VALUE_LIST_CELL(cell)
NTSTATUS
-CmiInitializeTempHive(
- IN OUT PCMHIVE Hive);
+CmiInitializeHive(
+ IN OUT PCMHIVE Hive,
+ IN PCWSTR Name);
+
+NTSTATUS
+CmiCreateSecurityKey(
+ IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength);
NTSTATUS
CmiAddSubKey(
IN PCMHIVE RegistryHive,
IN HCELL_INDEX ParentKeyCellOffset,
IN PCUNICODE_STRING SubKeyName,
- IN ULONG CreateOptions,
- OUT PCM_KEY_NODE *pSubKeyCell,
- OUT HCELL_INDEX *pBlockOffset);
-
-NTSTATUS
-CmiScanForSubKey(
- IN PCMHIVE RegistryHive,
- IN HCELL_INDEX ParentKeyCellOffset,
- IN PCUNICODE_STRING SubKeyName,
- IN ULONG Attributes,
- OUT PCM_KEY_NODE *pSubKeyCell,
+ IN BOOLEAN VolatileKey,
OUT HCELL_INDEX *pBlockOffset);
NTSTATUS
CmiAddValueKey(
IN PCMHIVE RegistryHive,
- IN HCELL_INDEX KeyCellOffset,
+ IN PCM_KEY_NODE Parent,
IN PCUNICODE_STRING ValueName,
OUT PCM_KEY_VALUE *pValueCell,
OUT HCELL_INDEX *pValueCellOffset);
-
-NTSTATUS
-CmiScanForValueKey(
- IN PCMHIVE RegistryHive,
- IN HCELL_INDEX KeyCellOffset,
- IN PCUNICODE_STRING ValueName,
- OUT PCM_KEY_VALUE *pValueCell,
- OUT HCELL_INDEX *pValueCellOffset);
Modified: trunk/reactos/tools/mkhive/mkhive.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/mkhive.c?rev=…
==============================================================================
--- trunk/reactos/tools/mkhive/mkhive.c [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/mkhive.c [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -16,7 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/mkhive.c
* PURPOSE: Hive maker
@@ -33,7 +34,7 @@
#ifdef _MSC_VER
#include <stdlib.h>
#define PATH_MAX _MAX_PATH
-#endif//_MSC_VER
+#endif // _MSC_VER
#ifndef _WIN32
#ifndef PATH_MAX
Modified: trunk/reactos/tools/mkhive/mkhive.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/mkhive.h?rev=…
==============================================================================
--- trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -16,7 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/mkhive.h
* PURPOSE: Hive maker
@@ -54,6 +55,7 @@
typedef DWORD REGSAM;
typedef LPVOID LPSECURITY_ATTRIBUTES;
+typedef HANDLE HKEY, *PHKEY;
NTSTATUS NTAPI
RtlAnsiStringToUnicodeString(
@@ -122,8 +124,6 @@
#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
-#define HIVE_NO_FILE 2
-#define VERIFY_REGISTRY_HIVE(hive)
extern LIST_ENTRY CmiHiveListHead;
#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
#define PAGED_CODE()
Modified: trunk/reactos/tools/mkhive/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/registry.c?re…
==============================================================================
--- trunk/reactos/tools/mkhive/registry.c [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/registry.c [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -16,7 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/registry.c
* PURPOSE: Registry code
@@ -25,9 +26,7 @@
/*
* TODO:
- * - Implement RegDeleteKeyW()
- * - Implement RegEnumValue()
- * - Implement RegQueryValueExW()
+ * - Implement RegDeleteKeyW() and RegDeleteValueW()
*/
#include <stdlib.h>
@@ -36,9 +35,6 @@
#define NDEBUG
#include "mkhive.h"
-
-#define REG_DATA_SIZE_MASK 0x7FFFFFFF
-#define REG_DATA_IN_OFFSET 0x80000000
static CMHIVE RootHive;
static PMEMKEY RootKey;
@@ -49,6 +45,291 @@
CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */
CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */
+//
+// TODO: Write these values in a more human-readable form.
+// See
http://amnesia.gtisc.gatech.edu/~moyix/suzibandit.ltd.uk/MSc/Registry%20Str…
+// Appendix 12 "The Registry NT Security Descriptor" for more information.
+//
+// Those SECURITY_DESCRIPTORs were obtained by dumping the security block "sk"
+// of registry hives created by setting their permissions to be the same as
+// the ones of the BCD, SOFTWARE, or SYSTEM, SAM and .DEFAULT system hives.
+// A cross-check was subsequently done with the system hives to verify that
+// the security descriptors were the same.
+//
+UCHAR BcdSecurity[] =
+{
+ // SECURITY_DESCRIPTOR_RELATIVE
+ 0x01, // Revision
+ 0x00, // Sbz1
+ 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
+ // SE_DACL_PROTECTED (0x1000) |
+ // SE_DACL_AUTO_INHERITED (0x0400) |
+ // SE_DACL_PRESENT (0x0004)
+ 0x48, 0x00, 0x00, 0x00, // Owner
+ 0x58, 0x00, 0x00, 0x00, // Group
+ 0x00, 0x00, 0x00, 0x00, // Sacl (None)
+ 0x14, 0x00, 0x00, 0x00, // Dacl
+
+ // DACL
+ 0x02, // AclRevision
+ 0x00, // Sbz1
+ 0x34, 0x00, // AclSize
+ 0x02, 0x00, // AceCount
+ 0x00, 0x00, // Sbz2
+
+ // (1st ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x19, 0x00, 0x06, 0x00, // ACCESS_MASK: "Write DAC" (0x00040000) |
+ // "Read Control" (0x00020000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // (2nd ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-5-18 "Local System")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x12, 0x00, 0x00, 0x00,
+
+ // Owner SID (S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // Group SID (S-1-5-21-domain-513 "Domain Users")
+ 0x01, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00,
+ 0xAC, 0xD0, 0x49, 0xCB,
+ 0xE6, 0x52, 0x47, 0x9C,
+ 0xE4, 0x31, 0xDB, 0x5C,
+ 0x01, 0x02, 0x00, 0x00
+};
+
+UCHAR SoftwareSecurity[] =
+{
+ // SECURITY_DESCRIPTOR_RELATIVE
+ 0x01, // Revision
+ 0x00, // Sbz1
+ 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
+ // SE_DACL_PROTECTED (0x1000) |
+ // SE_DACL_AUTO_INHERITED (0x0400) |
+ // SE_DACL_PRESENT (0x0004)
+ 0xA0, 0x00, 0x00, 0x00, // Owner
+ 0xB0, 0x00, 0x00, 0x00, // Group
+ 0x00, 0x00, 0x00, 0x00, // Sacl (None)
+ 0x14, 0x00, 0x00, 0x00, // Dacl
+
+ // DACL
+ 0x02, // AclRevision
+ 0x00, // Sbz1
+ 0x8C, 0x00, // AclSize
+ 0x06, 0x00, // AceCount
+ 0x00, 0x00, // Sbz2
+
+ // (1st ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // (2nd ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x0A, // AceFlags: INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-3-0 "Creator Owner")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // (3rd ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-5-18 "Local System")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x12, 0x00, 0x00, 0x00,
+
+ // (4th ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x1F, 0x00, 0x03, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
+ // "Delete" (0x00010000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Create Subkey" (0x00000004) |
+ // "Set Value" (0x00000002) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-13 "Terminal Server Users")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x0D, 0x00, 0x00, 0x00,
+
+ // (5th ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-32-545 "Users")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x21, 0x02, 0x00, 0x00,
+
+ // (6th ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x1F, 0x00, 0x03, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
+ // "Delete" (0x00010000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Create Subkey" (0x00000004) |
+ // "Set Value" (0x00000002) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-32-547 "Power Users")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x23, 0x02, 0x00, 0x00,
+
+ // Owner SID (S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // Group SID (S-1-5-21-domain-513 "Domain Users")
+ 0x01, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00,
+ 0xAC, 0xD0, 0x49, 0xCB,
+ 0xE6, 0x52, 0x47, 0x9C,
+ 0xE4, 0x31, 0xDB, 0x5C,
+ 0x01, 0x02, 0x00, 0x00
+};
+
+// Same security for SYSTEM, SAM and .DEFAULT
+UCHAR SystemSecurity[] =
+{
+ // SECURITY_DESCRIPTOR_RELATIVE
+ 0x01, // Revision
+ 0x00, // Sbz1
+ 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
+ // SE_DACL_PROTECTED (0x1000) |
+ // SE_DACL_AUTO_INHERITED (0x0400) |
+ // SE_DACL_PRESENT (0x0004)
+ 0x8C, 0x00, 0x00, 0x00, // Owner
+ 0x9C, 0x00, 0x00, 0x00, // Group
+ 0x00, 0x00, 0x00, 0x00, // Sacl (None)
+ 0x14, 0x00, 0x00, 0x00, // Dacl
+
+ // DACL
+ 0x02, // AclRevision
+ 0x00, // Sbz1
+ 0x78, 0x00, // AclSize
+ 0x05, 0x00, // AceCount
+ 0x00, 0x00, // Sbz2
+
+ // (1st ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // (2nd ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x0A, // AceFlags: INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-3-0 "Creator Owner")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // (3rd ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x14, 0x00, // AceSize
+ 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
+ // (SidStart: S-1-5-18 "Local System")
+ 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x12, 0x00, 0x00, 0x00,
+
+ // (4th ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-32-545 "Users")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x21, 0x02, 0x00, 0x00,
+
+ // (5th ACE)
+ 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
+ 0x02, // AceFlags: CONTAINER_INHERIT_ACE
+ 0x18, 0x00, // AceSize
+ 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
+ // "Notify" (0x00000010) |
+ // "Enumerate Subkeys" (0x00000008) |
+ // "Query Value" (0x00000001)
+ // (SidStart: S-1-5-32-547 "Power Users")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x23, 0x02, 0x00, 0x00,
+
+ // Owner SID (S-1-5-32-544 "Administrators")
+ 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x20, 0x02, 0x00, 0x00,
+
+ // Group SID (S-1-5-21-domain-513 "Domain Users")
+ 0x01, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00,
+ 0xAC, 0xD0, 0x49, 0xCB,
+ 0xE6, 0x52, 0x47, 0x9C,
+ 0xE4, 0x31, 0xDB, 0x5C,
+ 0x01, 0x02, 0x00, 0x00
+};
+
static PMEMKEY
CreateInMemoryStructure(
IN PCMHIVE RegistryHive,
@@ -56,7 +337,7 @@
{
PMEMKEY Key;
- Key = (PMEMKEY) malloc (sizeof(MEMKEY));
+ Key = (PMEMKEY)malloc(sizeof(MEMKEY));
if (!Key)
return NULL;
@@ -83,13 +364,14 @@
PMEMKEY CurrentKey;
PCMHIVE ParentRegistryHive;
HCELL_INDEX ParentCellOffset;
+ PCM_KEY_NODE ParentKeyCell;
PLIST_ENTRY Ptr;
PCM_KEY_NODE SubKeyCell;
HCELL_INDEX BlockOffset;
DPRINT("RegpCreateOpenKey('%S')\n", KeyName);
- if (*KeyName == L'\\')
+ if (*KeyName == OBJ_NAME_PATH_SEPARATOR)
{
KeyName++;
ParentRegistryHive = RootKey->RegistryHive;
@@ -102,14 +384,14 @@
}
else
{
- ParentRegistryHive = HKEY_TO_MEMKEY(RootKey)->RegistryHive;
- ParentCellOffset = HKEY_TO_MEMKEY(RootKey)->KeyCellOffset;
+ ParentRegistryHive = HKEY_TO_MEMKEY(hParentKey)->RegistryHive;
+ ParentCellOffset = HKEY_TO_MEMKEY(hParentKey)->KeyCellOffset;
}
LocalKeyName = (PWSTR)KeyName;
for (;;)
{
- End = (PWSTR)strchrW(LocalKeyName, '\\');
+ End = (PWSTR)strchrW(LocalKeyName, OBJ_NAME_PATH_SEPARATOR);
if (End)
{
KeyString.Buffer = LocalKeyName;
@@ -121,19 +403,22 @@
RtlInitUnicodeString(&KeyString, LocalKeyName);
if (KeyString.Length == 0)
{
- /* Trailing backslash char; we're done */
+ /* Trailing path separator: we're done */
break;
}
}
- Status = CmiScanForSubKey(ParentRegistryHive,
- ParentCellOffset,
- &KeyString,
- OBJ_CASE_INSENSITIVE,
- &SubKeyCell,
- &BlockOffset);
- if (NT_SUCCESS(Status))
+ ParentKeyCell = (PCM_KEY_NODE)HvGetCell(&ParentRegistryHive->Hive,
ParentCellOffset);
+ if (!ParentKeyCell)
+ return STATUS_UNSUCCESSFUL;
+
+ VERIFY_KEY_CELL(ParentKeyCell);
+
+ BlockOffset = CmpFindSubKeyByName(&ParentRegistryHive->Hive,
ParentKeyCell, &KeyString);
+ if (BlockOffset != HCELL_NIL)
{
+ Status = STATUS_SUCCESS;
+
/* Search for a possible reparse point */
Ptr = CmiReparsePointsHead.Flink;
while (Ptr != &CmiReparsePointsHead)
@@ -149,19 +434,20 @@
Ptr = Ptr->Flink;
}
}
- else if (Status == STATUS_OBJECT_NAME_NOT_FOUND && AllowCreation)
+ else if (AllowCreation) // && (BlockOffset == HCELL_NIL)
{
Status = CmiAddSubKey(ParentRegistryHive,
ParentCellOffset,
&KeyString,
- Volatile ? REG_OPTION_VOLATILE : 0,
- &SubKeyCell,
+ Volatile,
&BlockOffset);
}
+
+ HvReleaseCell(&ParentRegistryHive->Hive, ParentCellOffset);
+
if (!NT_SUCCESS(Status))
return ERROR_UNSUCCESSFUL;
-nextsubkey:
ParentCellOffset = BlockOffset;
if (End)
LocalKeyName = End + 1;
@@ -172,6 +458,7 @@
CurrentKey = CreateInMemoryStructure(ParentRegistryHive, ParentCellOffset);
if (!CurrentKey)
return ERROR_OUTOFMEMORY;
+
*Key = MEMKEY_TO_HKEY(CurrentKey);
return ERROR_SUCCESS;
@@ -186,54 +473,14 @@
return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
}
-static PWSTR
-MultiByteToWideChar(
- IN PCSTR MultiByteString)
-{
- ANSI_STRING Source;
- UNICODE_STRING Destination;
- NTSTATUS Status;
-
- RtlInitAnsiString(&Source, MultiByteString);
- Status = RtlAnsiStringToUnicodeString(&Destination, &Source, TRUE);
- if (!NT_SUCCESS(Status))
- return NULL;
- return Destination.Buffer;
-}
-
LONG WINAPI
RegDeleteKeyW(
IN HKEY hKey,
IN LPCWSTR lpSubKey)
{
- DPRINT1("FIXME: implement RegDeleteKeyW!\n");
+ DPRINT1("RegDeleteKeyW(0x%p, '%S') is UNIMPLEMENTED!\n",
+ hKey, (lpSubKey ? lpSubKey : L""));
return ERROR_SUCCESS;
-}
-
-LONG WINAPI
-RegDeleteKeyA(
- IN HKEY hKey,
- IN LPCSTR lpSubKey)
-{
- PWSTR lpSubKeyW = NULL;
- LONG rc;
-
- if (lpSubKey != NULL && strchr(lpSubKey, '\\') != NULL)
- return ERROR_INVALID_PARAMETER;
-
- if (lpSubKey)
- {
- lpSubKeyW = MultiByteToWideChar(lpSubKey);
- if (!lpSubKeyW)
- return ERROR_OUTOFMEMORY;
- }
-
- rc = RegDeleteKeyW(hKey, lpSubKeyW);
-
- if (lpSubKey)
- free(lpSubKeyW);
-
- return rc;
}
LONG WINAPI
@@ -265,57 +512,6 @@
}
LONG WINAPI
-RegOpenKeyA(
- IN HKEY hKey,
- IN LPCSTR lpSubKey,
- OUT PHKEY phkResult)
-{
- PWSTR lpSubKeyW;
- LONG rc;
-
- lpSubKeyW = MultiByteToWideChar(lpSubKey);
- if (!lpSubKeyW)
- return ERROR_OUTOFMEMORY;
-
- rc = RegOpenKeyW(hKey, lpSubKeyW, phkResult);
- free(lpSubKeyW);
- return rc;
-}
-
-static LONG
-RegpOpenOrCreateValue(
- IN HKEY hKey,
- IN LPCWSTR ValueName,
- IN BOOL AllowCreation,
- OUT PCM_KEY_VALUE *ValueCell,
- OUT PHCELL_INDEX ValueCellOffset)
-{
- PMEMKEY ParentKey;
- UNICODE_STRING ValueString;
- NTSTATUS Status;
-
- ParentKey = HKEY_TO_MEMKEY(hKey);
- RtlInitUnicodeString(&ValueString, ValueName);
-
- Status = CmiScanForValueKey(ParentKey->RegistryHive,
- ParentKey->KeyCellOffset,
- &ValueString,
- ValueCell,
- ValueCellOffset);
- if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- Status = CmiAddValueKey(ParentKey->RegistryHive,
- ParentKey->KeyCellOffset,
- &ValueString,
- ValueCell,
- ValueCellOffset);
- }
- if (!NT_SUCCESS(Status))
- return ERROR_UNSUCCESSFUL;
- return ERROR_SUCCESS;
-}
-
-LONG WINAPI
RegSetValueExW(
IN HKEY hKey,
IN LPCWSTR lpValueName OPTIONAL,
@@ -324,49 +520,84 @@
IN const UCHAR* lpData,
IN USHORT cbData)
{
- PMEMKEY Key, DestKey;
- PHKEY phKey;
+ PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
+ PHHIVE Hive;
+ PCM_KEY_NODE KeyNode; // ParentNode
PCM_KEY_VALUE ValueCell;
- HCELL_INDEX ValueCellOffset;
+ HCELL_INDEX CellIndex;
+ UNICODE_STRING ValueNameString;
+
PVOID DataCell;
LONG DataCellSize;
NTSTATUS Status;
if (dwType == REG_LINK)
{
+ PMEMKEY DestKey;
+
/* Special handling of registry links */
if (cbData != sizeof(PVOID))
return STATUS_INVALID_PARAMETER;
- phKey = (PHKEY)lpData;
- Key = HKEY_TO_MEMKEY(hKey);
- DestKey = HKEY_TO_MEMKEY(*phKey);
+ DestKey = HKEY_TO_MEMKEY(*(PHKEY)lpData);
+
+ // FIXME: Add additional checks for the validity of DestKey
/* Create the link in registry hive (if applicable) */
if (Key->RegistryHive != DestKey->RegistryHive)
return STATUS_SUCCESS;
+
DPRINT1("Save link to registry\n");
return STATUS_NOT_IMPLEMENTED;
}
- if ((cbData & REG_DATA_SIZE_MASK) != cbData)
+ if ((cbData & ~CM_KEY_VALUE_SPECIAL_SIZE) != cbData)
return STATUS_UNSUCCESSFUL;
- Key = HKEY_TO_MEMKEY(hKey);
-
- Status = RegpOpenOrCreateValue(hKey, lpValueName, TRUE, &ValueCell,
&ValueCellOffset);
+ Hive = &Key->RegistryHive->Hive;
+
+ KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Key->KeyCellOffset);
+ if (!KeyNode)
+ return ERROR_UNSUCCESSFUL;
+
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
+ /* Mark the parent as dirty since we are going to create a new value in it */
+ HvMarkCellDirty(Hive, Key->KeyCellOffset, FALSE);
+
+ /* Initialize value name string */
+ RtlInitUnicodeString(&ValueNameString, lpValueName);
+ CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
+ if (CellIndex == HCELL_NIL)
+ {
+ /* The value doesn't exist, create a new one */
+ Status = CmiAddValueKey(Key->RegistryHive,
+ KeyNode,
+ &ValueNameString,
+ &ValueCell,
+ &CellIndex);
+ }
+ else
+ {
+ /* The value already exists, use it. Get the value cell. */
+ ValueCell = HvGetCell(&Key->RegistryHive->Hive, CellIndex);
+ ASSERT(ValueCell != NULL);
+ }
+
+ // /**/HvReleaseCell(Hive, CellIndex);/**/
+
if (!NT_SUCCESS(Status))
return ERROR_UNSUCCESSFUL;
- /* Get size of the allocated cellule (if any) */
- if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
- (ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
- {
- DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
+ /* Get size of the allocated cell (if any) */
+ if (!(ValueCell->DataLength & CM_KEY_VALUE_SPECIAL_SIZE) &&
+ (ValueCell->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE) != 0)
+ {
+ DataCell = HvGetCell(Hive, ValueCell->Data);
if (!DataCell)
return ERROR_UNSUCCESSFUL;
- DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
+ DataCellSize = -HvGetCellSize(Hive, DataCell);
}
else
{
@@ -379,12 +610,11 @@
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
if (DataCell)
- HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
+ HvFreeCell(Hive, ValueCell->Data);
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
- ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
+ ValueCell->DataLength = (ULONG)(cbData | CM_KEY_VALUE_SPECIAL_SIZE);
ValueCell->Type = dwType;
- HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
}
else
{
@@ -396,7 +626,7 @@
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
- NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData,
Stable, HCELL_NIL);
+ NewOffset = HvAllocateCell(Hive, cbData, Stable, HCELL_NIL);
if (NewOffset == HCELL_NIL)
{
DPRINT("HvAllocateCell() failed with status 0x%08x\n",
Status);
@@ -404,52 +634,114 @@
}
if (DataCell)
- HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
+ HvFreeCell(Hive, ValueCell->Data);
ValueCell->Data = NewOffset;
- DataCell = (PVOID)HvGetCell(&Key->RegistryHive->Hive, NewOffset);
+ DataCell = (PVOID)HvGetCell(Hive, NewOffset);
}
- /* Copy new contents to cellule */
+ /* Copy new contents to cell */
RtlCopyMemory(DataCell, lpData, cbData);
- ValueCell->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
+ ValueCell->DataLength = (ULONG)(cbData & ~CM_KEY_VALUE_SPECIAL_SIZE);
ValueCell->Type = dwType;
- HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
- HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
- }
-
- HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset, FALSE);
+ HvMarkCellDirty(Hive, ValueCell->Data, FALSE);
+ }
+
+ HvMarkCellDirty(Hive, CellIndex, FALSE);
+
+ /* Check if the maximum value name length changed, update it if so */
+ if (KeyNode->MaxValueNameLen < ValueNameString.Length)
+ KeyNode->MaxValueNameLen = ValueNameString.Length;
+
+ /* Check if the maximum data length changed, update it if so */
+ if (KeyNode->MaxValueDataLen < cbData)
+ KeyNode->MaxValueDataLen = cbData;
+
+ /* Save the write time */
+ KeQuerySystemTime(&KeyNode->LastWriteTime);
DPRINT("Return status 0x%08x\n", Status);
return Status;
}
+
+// Synced with freeldr/windows/registry.c
+static
+VOID
+RepGetValueData(
+ IN PHHIVE Hive,
+ IN PCM_KEY_VALUE ValueCell,
+ OUT ULONG* Type OPTIONAL,
+ OUT PUCHAR Data OPTIONAL,
+ IN OUT ULONG* DataSize OPTIONAL)
+{
+ ULONG DataLength;
+ PVOID DataCell;
+
+ /* Does the caller want the type? */
+ if (Type != NULL)
+ *Type = ValueCell->Type;
+
+ /* Does the caller provide DataSize? */
+ if (DataSize != NULL)
+ {
+ // NOTE: CmpValueToData doesn't support big data (the function will
+ // bugcheck if so), FreeLdr is not supposed to read such data.
+ // If big data is needed, use instead CmpGetValueData.
+ // CmpGetValueData(Hive, ValueCell, DataSize, &DataCell, ...);
+ DataCell = CmpValueToData(Hive, ValueCell, &DataLength);
+
+ /* Does the caller want the data? */
+ if ((Data != NULL) && (*DataSize != 0))
+ {
+ RtlCopyMemory(Data,
+ DataCell,
+ min(*DataSize, DataLength));
+ }
+
+ /* Return the actual data length */
+ *DataSize = DataLength;
+ }
+}
+
+// Similar to RegQueryValue in freeldr/windows/registry.c
LONG WINAPI
RegQueryValueExW(
IN HKEY hKey,
IN LPCWSTR lpValueName,
IN PULONG lpReserved,
- OUT PULONG lpType,
- OUT PUCHAR lpData,
- OUT PSIZE_T lpcbData)
-{
- //ParentKey = HKEY_TO_MEMKEY(RootKey);
+ OUT PULONG lpType OPTIONAL,
+ OUT PUCHAR lpData OPTIONAL,
+ IN OUT PSIZE_T lpcbData OPTIONAL)
+{
+ PMEMKEY ParentKey = HKEY_TO_MEMKEY(hKey);
+ PHHIVE Hive = &ParentKey->RegistryHive->Hive;
+ PCM_KEY_NODE KeyNode;
PCM_KEY_VALUE ValueCell;
- HCELL_INDEX ValueCellOffset;
- LONG rc;
-
- rc = RegpOpenOrCreateValue(hKey,
- lpValueName,
- FALSE,
- &ValueCell,
- &ValueCellOffset);
- if (rc != ERROR_SUCCESS)
- return rc;
-
- DPRINT1("RegQueryValueExW(%S) not implemented\n", lpValueName);
- /* ValueCell and ValueCellOffset are valid */
-
- return ERROR_UNSUCCESSFUL;
+ HCELL_INDEX CellIndex;
+ UNICODE_STRING ValueNameString;
+
+ KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey->KeyCellOffset);
+ if (!KeyNode)
+ return ERROR_UNSUCCESSFUL;
+
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
+ /* Initialize value name string */
+ RtlInitUnicodeString(&ValueNameString, lpValueName);
+ CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
+ if (CellIndex == HCELL_NIL)
+ return ERROR_FILE_NOT_FOUND;
+
+ /* Get the value cell */
+ ValueCell = HvGetCell(Hive, CellIndex);
+ ASSERT(ValueCell != NULL);
+
+ RepGetValueData(Hive, ValueCell, lpType, lpData, lpcbData);
+
+ HvReleaseCell(Hive, CellIndex);
+
+ return ERROR_SUCCESS;
}
LONG WINAPI
@@ -457,14 +749,18 @@
IN HKEY hKey,
IN LPCWSTR lpValueName OPTIONAL)
{
- DPRINT1("RegDeleteValueW() unimplemented\n");
+ DPRINT1("RegDeleteValueW(0x%p, '%S') is UNIMPLEMENTED!\n",
+ hKey, (lpValueName ? lpValueName : L""));
return ERROR_UNSUCCESSFUL;
}
+
static BOOL
ConnectRegistry(
IN HKEY RootKey,
IN PCMHIVE HiveToConnect,
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength,
IN LPCWSTR Path)
{
NTSTATUS Status;
@@ -476,13 +772,31 @@
if (!ReparsePoint)
return FALSE;
- Status = CmiInitializeTempHive(HiveToConnect);
+ /*
+ * Use a dummy root key name:
+ * - On 2k/XP/2k3, this is "$$$PROTO.HIV"
+ * - On Vista+, this is "CMI-CreateHive{guid}"
+ * See
https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20fi…
+ * for more information.
+ */
+ Status = CmiInitializeHive(HiveToConnect, L"$$$PROTO.HIV");
if (!NT_SUCCESS(Status))
{
- DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n",
Status);
+ DPRINT1("CmiInitializeHive() failed with status 0x%08x\n", Status);
free(ReparsePoint);
return FALSE;
}
+
+ /*
+ * Add security to the root key.
+ * NOTE: One can implement this using the lpSecurityAttributes
+ * parameter of RegCreateKeyExW.
+ */
+ Status = CmiCreateSecurityKey(&HiveToConnect->Hive,
+ HiveToConnect->Hive.BaseBlock->RootCell,
+ Descriptor, DescriptorLength);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("Failed to add security for root key '%S'\n", Path);
/* Create key */
rc = RegCreateKeyExW(RootKey,
@@ -523,10 +837,10 @@
InitializeListHead(&CmiHiveListHead);
InitializeListHead(&CmiReparsePointsHead);
- Status = CmiInitializeTempHive(&RootHive);
+ Status = CmiInitializeHive(&RootHive, L"");
if (!NT_SUCCESS(Status))
{
- DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n",
Status);
+ DPRINT1("CmiInitializeHive() failed with status 0x%08x\n", Status);
return;
}
@@ -536,31 +850,37 @@
/* Create DEFAULT key */
ConnectRegistry(NULL,
&DefaultHive,
+ SystemSecurity, sizeof(SystemSecurity),
L"Registry\\User\\.DEFAULT");
/* Create SAM key */
ConnectRegistry(NULL,
&SamHive,
+ SystemSecurity, sizeof(SystemSecurity),
L"Registry\\Machine\\SAM");
/* Create SECURITY key */
ConnectRegistry(NULL,
&SecurityHive,
+ NULL, 0,
L"Registry\\Machine\\SECURITY");
/* Create SOFTWARE key */
ConnectRegistry(NULL,
&SoftwareHive,
+ SoftwareSecurity, sizeof(SoftwareSecurity),
L"Registry\\Machine\\SOFTWARE");
/* Create BCD key */
ConnectRegistry(NULL,
&BcdHive,
+ BcdSecurity, sizeof(BcdSecurity),
L"Registry\\Machine\\BCD00000000");
/* Create SYSTEM key */
ConnectRegistry(NULL,
&SystemHive,
+ SystemSecurity, sizeof(SystemSecurity),
L"Registry\\Machine\\SYSTEM");
/* Create 'ControlSet001' key */
Modified: trunk/reactos/tools/mkhive/rtl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/rtl.c?rev=706…
==============================================================================
--- trunk/reactos/tools/mkhive/rtl.c [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/rtl.c [iso-8859-1] Sun Jan 17 00:50:03 2016
@@ -1,4 +1,5 @@
-/* COPYRIGHT: See COPYING in the top level directory
+/*
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker
* FILE: tools/mkhive/rtl.c
* PURPOSE: Runtime Library
@@ -217,6 +218,23 @@
//DbgBreakPoint();
}
+// DECLSPEC_NORETURN
+VOID
+NTAPI
+KeBugCheckEx(
+ IN ULONG BugCheckCode,
+ IN ULONG_PTR BugCheckParameter1,
+ IN ULONG_PTR BugCheckParameter2,
+ IN ULONG_PTR BugCheckParameter3,
+ IN ULONG_PTR BugCheckParameter4)
+{
+ char Buffer[70];
+ printf("*** STOP: 0x%08lX (0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX)",
+ BugCheckCode, BugCheckParameter1, BugCheckParameter2,
+ BugCheckParameter3, BugCheckParameter4);
+ ASSERT(FALSE);
+}
+
unsigned char BitScanForward(ULONG * Index, unsigned long Mask)
{
*Index = 0;