From: Jérôme Gardou Date: Wed, 1 Oct 2014 17:48:32 +0000 (+0000) Subject: [ADVAPI32] X-Git-Tag: backups/0.3.17@66124~304 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=e854412f523d7a4eb778760752f4f7cb09b514f6;hp=b0408707b82e31bbcda76521e74b747ad2b382e2 [ADVAPI32] - Add implementation of RegCreateKeyEx and RegSetValueEx for HKCR subkeys CORE-8582 svn path=/trunk/; revision=64444 --- diff --git a/reactos/dll/win32/advapi32/reg/hkcr.c b/reactos/dll/win32/advapi32/reg/hkcr.c index b411799511d..2c88a2b2999 100644 --- a/reactos/dll/win32/advapi32/reg/hkcr.c +++ b/reactos/dll/win32/advapi32/reg/hkcr.c @@ -96,7 +96,8 @@ static LONG GetFallbackHKCRKey( _In_ HKEY hKey, - _Out_ HKEY* MachineKey) + _Out_ HKEY* MachineKey, + _In_ BOOL MustCreate) { UNICODE_STRING KeyName; LPWSTR SubKeyName; @@ -135,13 +136,29 @@ GetFallbackHKCRKey( return ErrorCode; } - /* Open the key. */ - ErrorCode = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - SubKeyName, - 0, - SamDesired, - MachineKey); + if (MustCreate) + { + ErrorCode = RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + SubKeyName, + 0, + NULL, + 0, + SamDesired, + NULL, + MachineKey, + NULL); + } + else + { + /* Open the key. */ + ErrorCode = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + SubKeyName, + 0, + SamDesired, + MachineKey); + } RtlFreeUnicodeString(&KeyName); @@ -197,6 +214,110 @@ GetPreferredHKCRKey( return ErrorCode; } +/* HKCR version of RegCreateKeyExW. */ +LONG +WINAPI +CreateHKCRKey( + _In_ HKEY hKey, + _In_ LPCWSTR lpSubKey, + _In_ DWORD Reserved, + _In_opt_ LPWSTR lpClass, + _In_ DWORD dwOptions, + _In_ REGSAM samDesired, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, + _Out_ PHKEY phkResult, + _Out_opt_ LPDWORD lpdwDisposition) +{ + LONG ErrorCode; + HKEY QueriedKey, TestKey; + + ASSERT(IsHKCRKey(hKey)); + + /* Remove the HKCR flag while we're working */ + hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2); + + ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) + { + /* The current key doesn't exist on HKCU side, so we can only create it in HKLM */ + ErrorCode = RegCreateKeyExW( + hKey, + lpSubKey, + Reserved, + lpClass, + dwOptions, + samDesired, + lpSecurityAttributes, + phkResult, + lpdwDisposition); + if (ErrorCode == ERROR_SUCCESS) + MakeHKCRKey(phkResult); + return ErrorCode; + } + + if (ErrorCode != ERROR_SUCCESS) + { + /* Somehow we failed for another reason (maybe deleted key or whatever) */ + return ErrorCode; + } + + /* See if the subkey already exists in HKCU. */ + ErrorCode = RegOpenKeyExW(QueriedKey, lpSubKey, 0, KEY_READ, &TestKey); + if (ErrorCode != ERROR_FILE_NOT_FOUND) + { + if (ErrorCode == ERROR_SUCCESS) + { + /* Great. Close the test one and do the real create operation */ + RegCloseKey(TestKey); + ErrorCode = RegCreateKeyExW( + QueriedKey, + lpSubKey, + Reserved, + lpClass, + dwOptions, + samDesired, + lpSecurityAttributes, + phkResult, + lpdwDisposition); + if (ErrorCode == ERROR_SUCCESS) + MakeHKCRKey(phkResult); + } + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + + return ERROR_SUCCESS; + } + + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + + /* So we must do the create operation in HKLM, creating the missing parent keys if needed. */ + ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, TRUE); + if (ErrorCode != ERROR_SUCCESS) + return ErrorCode; + + /* Do the key creation */ + ErrorCode = RegCreateKeyEx( + QueriedKey, + lpSubKey, + Reserved, + lpClass, + dwOptions, + samDesired, + lpSecurityAttributes, + phkResult, + lpdwDisposition); + + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + + if (ErrorCode == ERROR_SUCCESS) + MakeHKCRKey(phkResult); + + return ErrorCode; +} + /* Same as RegOpenKeyExW, but for HKEY_CLASSES_ROOT subkeys */ LONG WINAPI @@ -248,7 +369,7 @@ OpenHKCRKey( return ErrorCode; /* If we're here, we must open from HKLM key. */ - ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey); + ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE); if (ErrorCode != ERROR_SUCCESS) { /* Maybe the key doesn't exist in the HKLM view */ @@ -313,7 +434,7 @@ DeleteHKCRKey( return ErrorCode; /* If we're here, we must open from HKLM key. */ - ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey); + ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE); if (ErrorCode != ERROR_SUCCESS) { /* Maybe the key doesn't exist in the HKLM view */ @@ -378,7 +499,7 @@ QueryHKCRValue( return ErrorCode; /* If we're here, we must open from HKLM key. */ - ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey); + ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE); if (ErrorCode != ERROR_SUCCESS) { /* Maybe the key doesn't exist in the HKLM view */ @@ -395,3 +516,72 @@ QueryHKCRValue( return ErrorCode; } + +/* HKCR version of RegSetValueExW */ +LONG +WINAPI +SetHKCRValue( + _In_ HKEY hKey, + _In_ LPCWSTR Name, + _In_ DWORD Reserved, + _In_ DWORD Type, + _In_ CONST BYTE* Data, + _In_ DWORD DataSize) +{ + HKEY QueriedKey; + LONG ErrorCode; + + ASSERT(IsHKCRKey(hKey)); + + /* Remove the HKCR flag while we're working */ + hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2); + + ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) + { + /* The key doesn't exist on HKCU side, no chance to put a value in it */ + return RegSetValueExW(hKey, Name, Reserved, Type, Data, DataSize); + } + + if (ErrorCode != ERROR_SUCCESS) + { + /* Somehow we failed for another reason (maybe deleted key or whatever) */ + return ErrorCode; + } + + /* Check if the value already exists in the preferred key */ + ErrorCode = RegQueryValueExW(QueriedKey, Name, NULL, NULL, NULL, NULL); + if (ErrorCode != ERROR_FILE_NOT_FOUND) + { + if (ErrorCode == ERROR_SUCCESS) + { + /* Yes, so we have the right to modify it */ + ErrorCode = RegSetValueExW(QueriedKey, Name, Reserved, Type, Data, DataSize); + } + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + return ErrorCode; + } + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + + /* So we must set the value in the HKLM version */ + ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey); + if (ErrorCode == ERROR_FILE_NOT_FOUND) + { + /* No choice: put this in HKCU */ + return RegSetValueExW(hKey, Name, Reserved, Type, Data, DataSize); + } + else if (ErrorCode != ERROR_SUCCESS) + { + return ErrorCode; + } + + ErrorCode = RegSetValueExW(QueriedKey, Name, Reserved, Type, Data, DataSize); + + if (QueriedKey != hKey) + RegCloseKey(QueriedKey); + + return ErrorCode; +} diff --git a/reactos/dll/win32/advapi32/reg/reg.c b/reactos/dll/win32/advapi32/reg/reg.c index f75aad715fd..4d8f071d88b 100644 --- a/reactos/dll/win32/advapi32/reg/reg.c +++ b/reactos/dll/win32/advapi32/reg/reg.c @@ -1084,16 +1084,18 @@ Exit: * * @implemented */ -LONG WINAPI -RegCreateKeyExW(HKEY hKey, - LPCWSTR lpSubKey, - DWORD Reserved, - LPWSTR lpClass, - DWORD dwOptions, - REGSAM samDesired, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - PHKEY phkResult, - LPDWORD lpdwDisposition) +LONG +WINAPI +RegCreateKeyExW( + _In_ HKEY hKey, + _In_ LPCWSTR lpSubKey, + _In_ DWORD Reserved, + _In_opt_ LPWSTR lpClass, + _In_ DWORD dwOptions, + _In_ REGSAM samDesired, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, + _Out_ PHKEY phkResult, + _Out_opt_ LPDWORD lpdwDisposition) { UNICODE_STRING SubKeyString; UNICODE_STRING ClassString; @@ -1117,6 +1119,22 @@ RegCreateKeyExW(HKEY hKey, TRACE("ParentKey %p\n", ParentKey); + if (IsHKCRKey(ParentKey)) + { + LONG ErrorCode = CreateHKCRKey( + ParentKey, + lpSubKey, + Reserved, + lpClass, + dwOptions, + samDesired, + lpSecurityAttributes, + phkResult, + lpdwDisposition); + ClosePredefKey(ParentKey); + return ErrorCode; + } + if (dwOptions & REG_OPTION_OPEN_LINK) Attributes |= OBJ_OPENLINK; @@ -1144,9 +1162,6 @@ RegCreateKeyExW(HKEY hKey, return RtlNtStatusToDosError(Status); } - if (IsHKCRKey(ParentKey)) - MakeHKCRKey(phkResult); - return ERROR_SUCCESS; } @@ -4851,18 +4866,34 @@ RegSetValueExA(HKEY hKey, * * @implemented */ -LONG WINAPI -RegSetValueExW(HKEY hKey, - LPCWSTR lpValueName, - DWORD Reserved, - DWORD dwType, - CONST BYTE* lpData, - DWORD cbData) +LONG +WINAPI +RegSetValueExW( + _In_ HKEY hKey, + _In_ LPCWSTR lpValueName, + _In_ DWORD Reserved, + _In_ DWORD dwType, + _In_ CONST BYTE* lpData, + _In_ DWORD cbData) { UNICODE_STRING ValueName; HANDLE KeyHandle; NTSTATUS Status; + Status = MapDefaultKey(&KeyHandle, + hKey); + if (!NT_SUCCESS(Status)) + { + return RtlNtStatusToDosError(Status); + } + + if (IsHKCRKey(KeyHandle)) + { + LONG ErrorCode = SetHKCRValue(KeyHandle, lpValueName, Reserved, dwType, lpData, cbData); + ClosePredefKey(KeyHandle); + return ErrorCode; + } + if (is_string(dwType) && (cbData != 0)) { PWSTR pwsData = (PWSTR)lpData; @@ -4878,18 +4909,12 @@ RegSetValueExW(HKEY hKey, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - _SEH2_YIELD(return ERROR_NOACCESS); + ClosePredefKey(KeyHandle); + return ERROR_NOACCESS; } _SEH2_END; } - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - return RtlNtStatusToDosError(Status); - } - RtlInitUnicodeString(&ValueName, lpValueName); Status = NtSetValueKey(KeyHandle, diff --git a/reactos/dll/win32/advapi32/reg/reg.h b/reactos/dll/win32/advapi32/reg/reg.h index 20a1ebf5989..6181c0b99b6 100644 --- a/reactos/dll/win32/advapi32/reg/reg.h +++ b/reactos/dll/win32/advapi32/reg/reg.h @@ -22,6 +22,19 @@ MakeHKCRKey(_Inout_ HKEY* hKey) *hKey = (HKEY)((ULONG_PTR)(*hKey) | 0x2); } +LONG +WINAPI +CreateHKCRKey( + _In_ HKEY hKey, + _In_ LPCWSTR lpSubKey, + _In_ DWORD Reserved, + _In_opt_ LPWSTR lpClass, + _In_ DWORD dwOptions, + _In_ REGSAM samDesired, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, + _Out_ PHKEY phkResult, + _Out_opt_ LPDWORD lpdwDisposition); + LONG WINAPI OpenHKCRKey( @@ -49,3 +62,13 @@ QueryHKCRValue( _In_ LPBYTE Data, _In_ LPDWORD Count); +LONG +WINAPI +SetHKCRValue( + _In_ HKEY hKey, + _In_ LPCWSTR Name, + _In_ DWORD Reserved, + _In_ DWORD Type, + _In_ CONST BYTE* Data, + _In_ DWORD DataSize); +