mirror of
https://github.com/reactos/reactos.git
synced 2024-09-09 12:20:21 +00:00
[ADVAPI32]
- Add implementation of RegCreateKeyEx and RegSetValueEx for HKCR subkeys CORE-8582 svn path=/trunk/; revision=64444
This commit is contained in:
parent
b0408707b8
commit
e854412f52
|
@ -96,7 +96,8 @@ static
|
||||||
LONG
|
LONG
|
||||||
GetFallbackHKCRKey(
|
GetFallbackHKCRKey(
|
||||||
_In_ HKEY hKey,
|
_In_ HKEY hKey,
|
||||||
_Out_ HKEY* MachineKey)
|
_Out_ HKEY* MachineKey,
|
||||||
|
_In_ BOOL MustCreate)
|
||||||
{
|
{
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
LPWSTR SubKeyName;
|
LPWSTR SubKeyName;
|
||||||
|
@ -135,6 +136,21 @@ GetFallbackHKCRKey(
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MustCreate)
|
||||||
|
{
|
||||||
|
ErrorCode = RegCreateKeyExW(
|
||||||
|
HKEY_LOCAL_MACHINE,
|
||||||
|
SubKeyName,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
SamDesired,
|
||||||
|
NULL,
|
||||||
|
MachineKey,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Open the key. */
|
/* Open the key. */
|
||||||
ErrorCode = RegOpenKeyExW(
|
ErrorCode = RegOpenKeyExW(
|
||||||
HKEY_LOCAL_MACHINE,
|
HKEY_LOCAL_MACHINE,
|
||||||
|
@ -142,6 +158,7 @@ GetFallbackHKCRKey(
|
||||||
0,
|
0,
|
||||||
SamDesired,
|
SamDesired,
|
||||||
MachineKey);
|
MachineKey);
|
||||||
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&KeyName);
|
RtlFreeUnicodeString(&KeyName);
|
||||||
|
|
||||||
|
@ -197,6 +214,110 @@ GetPreferredHKCRKey(
|
||||||
return ErrorCode;
|
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 */
|
/* Same as RegOpenKeyExW, but for HKEY_CLASSES_ROOT subkeys */
|
||||||
LONG
|
LONG
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -248,7 +369,7 @@ OpenHKCRKey(
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
|
|
||||||
/* If we're here, we must open from HKLM key. */
|
/* If we're here, we must open from HKLM key. */
|
||||||
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey);
|
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
|
||||||
if (ErrorCode != ERROR_SUCCESS)
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Maybe the key doesn't exist in the HKLM view */
|
/* Maybe the key doesn't exist in the HKLM view */
|
||||||
|
@ -313,7 +434,7 @@ DeleteHKCRKey(
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
|
|
||||||
/* If we're here, we must open from HKLM key. */
|
/* If we're here, we must open from HKLM key. */
|
||||||
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey);
|
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
|
||||||
if (ErrorCode != ERROR_SUCCESS)
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Maybe the key doesn't exist in the HKLM view */
|
/* Maybe the key doesn't exist in the HKLM view */
|
||||||
|
@ -378,7 +499,7 @@ QueryHKCRValue(
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
|
|
||||||
/* If we're here, we must open from HKLM key. */
|
/* If we're here, we must open from HKLM key. */
|
||||||
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey);
|
ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
|
||||||
if (ErrorCode != ERROR_SUCCESS)
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Maybe the key doesn't exist in the HKLM view */
|
/* Maybe the key doesn't exist in the HKLM view */
|
||||||
|
@ -395,3 +516,72 @@ QueryHKCRValue(
|
||||||
|
|
||||||
return ErrorCode;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1084,16 +1084,18 @@ Exit:
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LONG WINAPI
|
LONG
|
||||||
RegCreateKeyExW(HKEY hKey,
|
WINAPI
|
||||||
LPCWSTR lpSubKey,
|
RegCreateKeyExW(
|
||||||
DWORD Reserved,
|
_In_ HKEY hKey,
|
||||||
LPWSTR lpClass,
|
_In_ LPCWSTR lpSubKey,
|
||||||
DWORD dwOptions,
|
_In_ DWORD Reserved,
|
||||||
REGSAM samDesired,
|
_In_opt_ LPWSTR lpClass,
|
||||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
_In_ DWORD dwOptions,
|
||||||
PHKEY phkResult,
|
_In_ REGSAM samDesired,
|
||||||
LPDWORD lpdwDisposition)
|
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
|
_Out_ PHKEY phkResult,
|
||||||
|
_Out_opt_ LPDWORD lpdwDisposition)
|
||||||
{
|
{
|
||||||
UNICODE_STRING SubKeyString;
|
UNICODE_STRING SubKeyString;
|
||||||
UNICODE_STRING ClassString;
|
UNICODE_STRING ClassString;
|
||||||
|
@ -1117,6 +1119,22 @@ RegCreateKeyExW(HKEY hKey,
|
||||||
|
|
||||||
TRACE("ParentKey %p\n", ParentKey);
|
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)
|
if (dwOptions & REG_OPTION_OPEN_LINK)
|
||||||
Attributes |= OBJ_OPENLINK;
|
Attributes |= OBJ_OPENLINK;
|
||||||
|
|
||||||
|
@ -1144,9 +1162,6 @@ RegCreateKeyExW(HKEY hKey,
|
||||||
return RtlNtStatusToDosError(Status);
|
return RtlNtStatusToDosError(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsHKCRKey(ParentKey))
|
|
||||||
MakeHKCRKey(phkResult);
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4851,18 +4866,34 @@ RegSetValueExA(HKEY hKey,
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LONG WINAPI
|
LONG
|
||||||
RegSetValueExW(HKEY hKey,
|
WINAPI
|
||||||
LPCWSTR lpValueName,
|
RegSetValueExW(
|
||||||
DWORD Reserved,
|
_In_ HKEY hKey,
|
||||||
DWORD dwType,
|
_In_ LPCWSTR lpValueName,
|
||||||
CONST BYTE* lpData,
|
_In_ DWORD Reserved,
|
||||||
DWORD cbData)
|
_In_ DWORD dwType,
|
||||||
|
_In_ CONST BYTE* lpData,
|
||||||
|
_In_ DWORD cbData)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ValueName;
|
UNICODE_STRING ValueName;
|
||||||
HANDLE KeyHandle;
|
HANDLE KeyHandle;
|
||||||
NTSTATUS Status;
|
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))
|
if (is_string(dwType) && (cbData != 0))
|
||||||
{
|
{
|
||||||
PWSTR pwsData = (PWSTR)lpData;
|
PWSTR pwsData = (PWSTR)lpData;
|
||||||
|
@ -4878,18 +4909,12 @@ RegSetValueExW(HKEY hKey,
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
_SEH2_YIELD(return ERROR_NOACCESS);
|
ClosePredefKey(KeyHandle);
|
||||||
|
return ERROR_NOACCESS;
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MapDefaultKey(&KeyHandle,
|
|
||||||
hKey);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return RtlNtStatusToDosError(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&ValueName, lpValueName);
|
RtlInitUnicodeString(&ValueName, lpValueName);
|
||||||
|
|
||||||
Status = NtSetValueKey(KeyHandle,
|
Status = NtSetValueKey(KeyHandle,
|
||||||
|
|
|
@ -22,6 +22,19 @@ MakeHKCRKey(_Inout_ HKEY* hKey)
|
||||||
*hKey = (HKEY)((ULONG_PTR)(*hKey) | 0x2);
|
*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
|
LONG
|
||||||
WINAPI
|
WINAPI
|
||||||
OpenHKCRKey(
|
OpenHKCRKey(
|
||||||
|
@ -49,3 +62,13 @@ QueryHKCRValue(
|
||||||
_In_ LPBYTE Data,
|
_In_ LPBYTE Data,
|
||||||
_In_ LPDWORD Count);
|
_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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue