X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=sdk%2Ftools%2Fmkhive%2Fregistry.c;h=a3cc71218409c960dcf3af8cdef487d4ee5ef533;hp=e7a8cc9100c365f0336dbdf07ed6308d25799c78;hb=6a44c10d5de75886fd98d8e491c371b3832e1b27;hpb=c2c66aff7dacc62d125f2cd61d1167e9a2aa3fd6 diff --git a/sdk/tools/mkhive/registry.c b/sdk/tools/mkhive/registry.c index e7a8cc9100c..a3cc7121840 100644 --- a/sdk/tools/mkhive/registry.c +++ b/sdk/tools/mkhive/registry.c @@ -21,7 +21,8 @@ * PROJECT: ReactOS hive maker * FILE: tools/mkhive/registry.c * PURPOSE: Registry code - * PROGRAMMER: Hervé Poussineau + * PROGRAMMERS: Hervé Poussineau + * Hermès Bélusca-Maïto */ /* @@ -29,21 +30,18 @@ * - Implement RegDeleteKeyW() and RegDeleteValueW() */ -#include -#include -#include - #define NDEBUG #include "mkhive.h" static CMHIVE RootHive; static PMEMKEY RootKey; -CMHIVE DefaultHive; /* \Registry\User\.DEFAULT */ -CMHIVE SamHive; /* \Registry\Machine\SAM */ -CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */ -CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */ -CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */ -CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */ + +static CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */ +static CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */ +static CMHIVE DefaultHive; /* \Registry\User\.DEFAULT */ +static CMHIVE SamHive; /* \Registry\Machine\SAM */ +static CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */ +static CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */ // // TODO: Write these values in a more human-readable form. @@ -56,7 +54,7 @@ CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */ // A cross-check was subsequently done with the system hives to verify that // the security descriptors were the same. // -UCHAR BcdSecurity[] = +static UCHAR BcdSecurity[] = { // SECURITY_DESCRIPTOR_RELATIVE 0x01, // Revision @@ -118,7 +116,7 @@ UCHAR BcdSecurity[] = 0x01, 0x02, 0x00, 0x00 }; -UCHAR SoftwareSecurity[] = +static UCHAR SoftwareSecurity[] = { // SECURITY_DESCRIPTOR_RELATIVE 0x01, // Revision @@ -234,7 +232,7 @@ UCHAR SoftwareSecurity[] = }; // Same security for SYSTEM, SAM and .DEFAULT -UCHAR SystemSecurity[] = +static UCHAR SystemSecurity[] = { // SECURITY_DESCRIPTOR_RELATIVE 0x01, // Revision @@ -330,6 +328,24 @@ UCHAR SystemSecurity[] = 0x01, 0x02, 0x00, 0x00 }; + +HIVE_LIST_ENTRY RegistryHives[/*MAX_NUMBER_OF_REGISTRY_HIVES*/] = +{ + /* Special Setup system registry hive */ + // WARNING: Please *keep* it in first position! + { "SETUPREG", L"Registry\\Machine\\SYSTEM" , &SystemHive , SystemSecurity , sizeof(SystemSecurity) }, + + /* Regular registry hives */ + { "SYSTEM" , L"Registry\\Machine\\SYSTEM" , &SystemHive , SystemSecurity , sizeof(SystemSecurity) }, + { "SOFTWARE", L"Registry\\Machine\\SOFTWARE" , &SoftwareHive, SoftwareSecurity, sizeof(SoftwareSecurity) }, + { "DEFAULT" , L"Registry\\User\\.DEFAULT" , &DefaultHive , SystemSecurity , sizeof(SystemSecurity) }, + { "SAM" , L"Registry\\Machine\\SAM" , &SamHive , SystemSecurity , sizeof(SystemSecurity) }, + { "SECURITY", L"Registry\\Machine\\SECURITY" , &SecurityHive, NULL , 0 }, + { "BCD" , L"Registry\\Machine\\BCD00000000", &BcdHive , BcdSecurity , sizeof(BcdSecurity) }, +}; +C_ASSERT(_countof(RegistryHives) == MAX_NUMBER_OF_REGISTRY_HIVES); + + static PMEMKEY CreateInMemoryStructure( IN PCMHIVE RegistryHive, @@ -346,10 +362,11 @@ CreateInMemoryStructure( return Key; } +LIST_ENTRY CmiHiveListHead; LIST_ENTRY CmiReparsePointsHead; static LONG -RegpOpenOrCreateKey( +RegpCreateOrOpenKey( IN HKEY hParentKey, IN PCWSTR KeyName, IN BOOL AllowCreation, @@ -369,7 +386,7 @@ RegpOpenOrCreateKey( PCM_KEY_NODE SubKeyCell; HCELL_INDEX BlockOffset; - DPRINT("RegpCreateOpenKey('%S')\n", KeyName); + DPRINT("RegpCreateOrOpenKey('%S')\n", KeyName); if (*KeyName == OBJ_NAME_PATH_SEPARATOR) { @@ -442,11 +459,18 @@ RegpOpenOrCreateKey( Volatile, &BlockOffset); } + else // if (BlockOffset == HCELL_NIL) + { + Status = STATUS_OBJECT_NAME_NOT_FOUND; // ERROR_PATH_NOT_FOUND; + } HvReleaseCell(&ParentRegistryHive->Hive, ParentCellOffset); if (!NT_SUCCESS(Status)) + { + DPRINT("RegpCreateOrOpenKey('%S'): Could not create or open subkey '%wZ'\n", KeyName, &KeyString); return ERROR_UNSUCCESSFUL; + } ParentCellOffset = BlockOffset; if (End) @@ -465,31 +489,24 @@ RegpOpenOrCreateKey( } LONG WINAPI -RegCreateKeyW( - IN HKEY hKey, - IN LPCWSTR lpSubKey, - OUT PHKEY phkResult) +RegCloseKey( + IN HKEY hKey) { - return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult); -} + PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey + + /* Free the object */ + free(Key); -LONG WINAPI -RegDeleteKeyW( - IN HKEY hKey, - IN LPCWSTR lpSubKey) -{ - DPRINT1("RegDeleteKeyW(0x%p, '%S') is UNIMPLEMENTED!\n", - hKey, (lpSubKey ? lpSubKey : L"")); return ERROR_SUCCESS; } LONG WINAPI -RegOpenKeyW( +RegCreateKeyW( IN HKEY hKey, IN LPCWSTR lpSubKey, OUT PHKEY phkResult) { - return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult); + return RegpCreateOrOpenKey(hKey, lpSubKey, TRUE, FALSE, phkResult); } LONG WINAPI @@ -504,13 +521,32 @@ RegCreateKeyExW( OUT PHKEY phkResult, OUT LPDWORD lpdwDisposition OPTIONAL) { - return RegpOpenOrCreateKey(hKey, + return RegpCreateOrOpenKey(hKey, lpSubKey, TRUE, (dwOptions & REG_OPTION_VOLATILE) != 0, phkResult); } +LONG WINAPI +RegDeleteKeyW( + IN HKEY hKey, + IN LPCWSTR lpSubKey) +{ + DPRINT1("RegDeleteKeyW(0x%p, '%S') is UNIMPLEMENTED!\n", + hKey, (lpSubKey ? lpSubKey : L"")); + return ERROR_SUCCESS; +} + +LONG WINAPI +RegOpenKeyW( + IN HKEY hKey, + IN LPCWSTR lpSubKey, + OUT PHKEY phkResult) +{ + return RegpCreateOrOpenKey(hKey, lpSubKey, FALSE, FALSE, phkResult); +} + LONG WINAPI RegSetValueExW( IN HKEY hKey, @@ -524,6 +560,7 @@ RegSetValueExW( PHHIVE Hive; PCM_KEY_NODE KeyNode; // ParentNode PCM_KEY_VALUE ValueCell; + ULONG ChildIndex; HCELL_INDEX CellIndex; UNICODE_STRING ValueNameString; @@ -567,12 +604,24 @@ RegSetValueExW( /* Initialize value name string */ RtlInitUnicodeString(&ValueNameString, lpValueName); - CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString); + if (!CmpFindNameInList(Hive, + &KeyNode->ValueList, + &ValueNameString, + &ChildIndex, + &CellIndex)) + { + /* Sanity check */ + ASSERT(CellIndex == HCELL_NIL); + /* Fail */ + // Status = STATUS_INSUFFICIENT_RESOURCES; + return ERROR_UNSUCCESSFUL; + } if (CellIndex == HCELL_NIL) { /* The value doesn't exist, create a new one */ Status = CmiAddValueKey(Key->RegistryHive, KeyNode, + ChildIndex, &ValueNameString, &ValueCell, &CellIndex); @@ -665,15 +714,15 @@ RegSetValueExW( } -// Synced with freeldr/windows/registry.c +// Synced with freeldr/ntldr/registry.c static VOID RepGetValueData( IN PHHIVE Hive, IN PCM_KEY_VALUE ValueCell, - OUT ULONG* Type OPTIONAL, + OUT PULONG Type OPTIONAL, OUT PUCHAR Data OPTIONAL, - IN OUT ULONG* DataSize OPTIONAL) + IN OUT PULONG DataSize OPTIONAL) { ULONG DataLength; PVOID DataCell; @@ -704,7 +753,7 @@ RepGetValueData( } } -// Similar to RegQueryValue in freeldr/windows/registry.c +// Similar to RegQueryValue in freeldr/ntldr/registry.c LONG WINAPI RegQueryValueExW( IN HKEY hKey, @@ -759,16 +808,16 @@ static BOOL ConnectRegistry( IN HKEY RootKey, IN PCMHIVE HiveToConnect, - IN PUCHAR Descriptor, - IN ULONG DescriptorLength, - IN LPCWSTR Path) + IN PUCHAR SecurityDescriptor, + IN ULONG SecurityDescriptorLength, + IN PCWSTR Path) { NTSTATUS Status; + LONG rc; PREPARSE_POINT ReparsePoint; PMEMKEY NewKey; - LONG rc; - ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT)); + ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint)); if (!ReparsePoint) return FALSE; @@ -794,11 +843,11 @@ ConnectRegistry( */ Status = CmiCreateSecurityKey(&HiveToConnect->Hive, HiveToConnect->Hive.BaseBlock->RootCell, - Descriptor, DescriptorLength); + SecurityDescriptor, SecurityDescriptorLength); if (!NT_SUCCESS(Status)) DPRINT1("Failed to add security for root key '%S'\n", Path); - /* Create key */ + /* Create the key */ rc = RegCreateKeyExW(RootKey, Path, 0, @@ -821,18 +870,70 @@ ConnectRegistry( ReparsePoint->DestinationHive = NewKey->RegistryHive; ReparsePoint->DestinationKeyCellOffset = NewKey->KeyCellOffset; InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry); + return TRUE; } -LIST_ENTRY CmiHiveListHead; +static BOOL +CreateSymLink( + IN PCWSTR LinkKeyPath OPTIONAL, + IN OUT PHKEY LinkKeyHandle OPTIONAL, + // IN PCWSTR TargetKeyPath OPTIONAL, + IN HKEY TargetKeyHandle) +{ + LONG rc; + PMEMKEY LinkKey, TargetKey; + PREPARSE_POINT ReparsePoint; + + ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint)); + if (!ReparsePoint) + return FALSE; + + if (LinkKeyPath && !(LinkKeyHandle && *LinkKeyHandle)) + { + /* Create the link key */ + rc = RegCreateKeyExW(NULL, + LinkKeyPath, + 0, + NULL, + REG_OPTION_VOLATILE, + 0, + NULL, + (PHKEY)&LinkKey, + NULL); + if (rc != ERROR_SUCCESS) + { + free(ReparsePoint); + return FALSE; + } + } + else if (LinkKeyHandle) + { + /* Use the user-provided link key handle */ + LinkKey = HKEY_TO_MEMKEY(*LinkKeyHandle); + } + + if (LinkKeyHandle) + *LinkKeyHandle = MEMKEY_TO_HKEY(LinkKey); + + TargetKey = HKEY_TO_MEMKEY(TargetKeyHandle); + + ReparsePoint->SourceHive = LinkKey->RegistryHive; + ReparsePoint->SourceKeyCellOffset = LinkKey->KeyCellOffset; + ReparsePoint->DestinationHive = TargetKey->RegistryHive; + ReparsePoint->DestinationKeyCellOffset = TargetKey->KeyCellOffset; + InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry); + + return TRUE; +} VOID -RegInitializeRegistry(VOID) +RegInitializeRegistry( + IN PCSTR HiveList) { - UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\"); NTSTATUS Status; - PMEMKEY ControlSetKey, CurrentControlSetKey; - PREPARSE_POINT ReparsePoint; + UINT i; + HKEY ControlSetKey; InitializeListHead(&CmiHiveListHead); InitializeListHead(&CmiReparsePointsHead); @@ -847,70 +948,58 @@ RegInitializeRegistry(VOID) RootKey = CreateInMemoryStructure(&RootHive, RootHive.Hive.BaseBlock->RootCell); - /* 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 */ + for (i = 0; i < _countof(RegistryHives); ++i) + { + /* Skip this registry hive if it's not in the list */ + if (!strstr(HiveList, RegistryHives[i].HiveName)) + continue; + + /* Create the registry key */ + ConnectRegistry(NULL, + RegistryHives[i].CmHive, + RegistryHives[i].SecurityDescriptor, + RegistryHives[i].SecurityDescriptorLength, + RegistryHives[i].HiveRegistryPath); + + /* If we happen to deal with the special setup registry hive, stop there */ + // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0) + if (i == 0) + break; + } + + /* Create the 'ControlSet001' key */ RegCreateKeyW(NULL, L"Registry\\Machine\\SYSTEM\\ControlSet001", - (HKEY*)&ControlSetKey); - - /* Create 'CurrentControlSet' key */ - RegCreateKeyExW(NULL, - L"Registry\\Machine\\SYSTEM\\CurrentControlSet", - 0, - NULL, - REG_OPTION_VOLATILE, - 0, - NULL, - (HKEY*)&CurrentControlSetKey, - NULL); - - /* Connect 'CurrentControlSet' to 'ControlSet001' */ - ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT)); - ReparsePoint->SourceHive = CurrentControlSetKey->RegistryHive; - ReparsePoint->SourceKeyCellOffset = CurrentControlSetKey->KeyCellOffset; - ReparsePoint->DestinationHive = ControlSetKey->RegistryHive; - ReparsePoint->DestinationKeyCellOffset = ControlSetKey->KeyCellOffset; - InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry); + &ControlSetKey); + + /* Create the 'CurrentControlSet' key as a symlink to 'ControlSet001' */ + CreateSymLink(L"Registry\\Machine\\SYSTEM\\CurrentControlSet", + NULL, ControlSetKey); + + RegCloseKey(ControlSetKey); + +#if 0 + /* Link SECURITY to SAM */ + CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", L"\\Registry\\Machine\\SAM\\SAM"); + /* Link S-1-5-18 to .Default */ + CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18", L"\\Registry\\User\\.Default"); +#endif } VOID RegShutdownRegistry(VOID) { + PLIST_ENTRY Entry; + PREPARSE_POINT ReparsePoint; + + /* Clean up the reparse points list */ + while (!IsListEmpty(&CmiReparsePointsHead)) + { + Entry = RemoveHeadList(&CmiReparsePointsHead); + ReparsePoint = CONTAINING_RECORD(Entry, REPARSE_POINT, ListEntry); + free(ReparsePoint); + } + /* FIXME: clean up the complete hive */ free(RootKey);