Author: jgardou
Date: Wed Oct 1 17:48:32 2014
New Revision: 64444
URL:
http://svn.reactos.org/svn/reactos?rev=64444&view=rev
Log:
[ADVAPI32]
- Add implementation of RegCreateKeyEx and RegSetValueEx for HKCR subkeys
CORE-8582
Modified:
trunk/reactos/dll/win32/advapi32/reg/hkcr.c
trunk/reactos/dll/win32/advapi32/reg/reg.c
trunk/reactos/dll/win32/advapi32/reg/reg.h
Modified: trunk/reactos/dll/win32/advapi32/reg/hkcr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/hkc…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/hkcr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/reg/hkcr.c [iso-8859-1] Wed Oct 1 17:48:32 2014
@@ -96,7 +96,8 @@
LONG
GetFallbackHKCRKey(
_In_ HKEY hKey,
- _Out_ HKEY* MachineKey)
+ _Out_ HKEY* MachineKey,
+ _In_ BOOL MustCreate)
{
UNICODE_STRING KeyName;
LPWSTR SubKeyName;
@@ -135,13 +136,29 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
+}
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Wed Oct 1 17:48:32 2014
@@ -1084,16 +1084,18 @@
*
* @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;
@@ -1116,6 +1118,22 @@
}
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;
@@ -1143,9 +1161,6 @@
{
return RtlNtStatusToDosError(Status);
}
-
- if (IsHKCRKey(ParentKey))
- MakeHKCRKey(phkResult);
return ERROR_SUCCESS;
}
@@ -4851,17 +4866,33 @@
*
* @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))
{
@@ -4878,16 +4909,10 @@
}
_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);
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/reg.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/reg/reg.h [iso-8859-1] Wed Oct 1 17:48:32 2014
@@ -21,6 +21,19 @@
{
*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
@@ -49,3 +62,13 @@
_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);
+