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=7060... ============================================================================== --- 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=7060... ============================================================================== --- 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=7... ============================================================================== --- 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=7... ============================================================================== --- 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?rev... ============================================================================== --- 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%20Stru... +// 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%20fil... + * 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=7060... ============================================================================== --- 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;