[ADVAPI32] Handle HKCR in RegDeleteValueA+W and RegDeleteKeyValueW (#6033)

- HKCR delete handling; delete the value in HKCU if it exists there, otherwise delete it in HKLM.
- Changed RegDeleteKeyValueW to just use the regular Reg functions to get HKCR handling for free.
This commit is contained in:
Whindmar Saksit 2024-03-24 18:28:26 +01:00 committed by GitHub
parent 373816c729
commit 2449ed5d85
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 111 additions and 68 deletions

View file

@ -17,6 +17,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg);
static const UNICODE_STRING HKLM_ClassesPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes");
static
BOOL
ValueExists(_In_ HKEY hNormalKey, _In_ PUNICODE_STRING Name)
{
KEY_VALUE_PARTIAL_INFORMATION kvi;
ULONG total_size = sizeof(kvi);
NTSTATUS status;
ASSERT(!IsHKCRKey(hNormalKey));
status = NtQueryValueKey(hNormalKey, Name, KeyValuePartialInformation,
&kvi, total_size, &total_size);
return status != STATUS_OBJECT_NAME_NOT_FOUND;
}
static
LONG
GetKeyName(HKEY hKey, PUNICODE_STRING KeyName)
@ -107,7 +121,10 @@ GetFallbackHKCRKey(
/* Get the key name */
ErrorCode = GetKeyName(hKey, &KeyName);
if (ErrorCode != ERROR_SUCCESS)
{
*MachineKey = hKey;
return ErrorCode;
}
/* See if we really need a conversion */
if (RtlPrefixUnicodeString(&HKLM_ClassesPath, &KeyName, TRUE))
@ -133,6 +150,7 @@ GetFallbackHKCRKey(
if (ErrorCode != ERROR_SUCCESS)
{
RtlFreeUnicodeString(&KeyName);
*MachineKey = hKey;
return ErrorCode;
}
@ -180,7 +198,10 @@ GetPreferredHKCRKey(
/* Get the key name */
ErrorCode = GetKeyName(hKey, &KeyName);
if (ErrorCode != ERROR_SUCCESS)
{
*PreferredKey = hKey;
return ErrorCode;
}
/* See if we really need a conversion */
if (!RtlPrefixUnicodeString(&HKLM_ClassesPath, &KeyName, TRUE))
@ -198,6 +219,7 @@ GetPreferredHKCRKey(
if (ErrorCode != ERROR_SUCCESS)
{
RtlFreeUnicodeString(&KeyName);
*PreferredKey = hKey;
return ErrorCode;
}
@ -476,6 +498,50 @@ DeleteHKCRKey(
return ErrorCode;
}
/* HKCR version of RegDeleteValueA+W */
LONG
WINAPI
DeleteHKCRValue(
_In_ HKEY hKey,
_In_ PUNICODE_STRING ValueName)
{
HKEY hActualKey;
LONG ErrorCode;
ASSERT(IsHKCRKey(hKey));
/* Remove the HKCR flag while we're working */
hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
/* Does the HKCU key and value exist? */
ErrorCode = GetPreferredHKCRKey(hKey, &hActualKey);
if (ErrorCode == ERROR_SUCCESS)
{
if (!ValueExists(hActualKey, ValueName))
{
if (hActualKey != hKey)
{
RegCloseKey(hActualKey);
}
ErrorCode = ERROR_FILE_NOT_FOUND;
}
}
if (ErrorCode == ERROR_FILE_NOT_FOUND)
{
ErrorCode = GetFallbackHKCRKey(hKey, &hActualKey, FALSE);
}
if (ErrorCode == ERROR_SUCCESS)
{
NTSTATUS Status = NtDeleteValueKey(hActualKey, ValueName);
ErrorCode = NT_SUCCESS(Status) ? ERROR_SUCCESS : RtlNtStatusToDosError(Status);
}
if (hActualKey != hKey)
{
RegCloseKey(hActualKey);
}
return ErrorCode;
}
/* HKCR version of RegQueryValueExW */
LONG
WINAPI

View file

@ -1362,62 +1362,24 @@ RegDeleteKeyValueW(IN HKEY hKey,
IN LPCWSTR lpSubKey OPTIONAL,
IN LPCWSTR lpValueName OPTIONAL)
{
UNICODE_STRING ValueName;
HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
HKEY hSubKey = hKey;
LONG ErrorCode;
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
if (lpSubKey)
{
return RtlNtStatusToDosError(Status);
}
if (lpSubKey != NULL)
ErrorCode = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_SET_VALUE, &hSubKey);
if (ErrorCode)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
return ErrorCode;
}
}
ErrorCode = RegDeleteValueW(hSubKey, lpValueName);
RtlInitUnicodeString(&SubKeyName, lpSubKey);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyName,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
Status = NtOpenKey(&SubKeyHandle,
KEY_SET_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
if (hSubKey != hKey)
{
goto Cleanup;
RegCloseKey(hSubKey);
}
CurKey = SubKeyHandle;
}
else
CurKey = KeyHandle;
RtlInitUnicodeString(&ValueName, lpValueName);
Status = NtDeleteValueKey(CurKey,
&ValueName);
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
Cleanup:
ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
}
return ERROR_SUCCESS;
return ErrorCode;
}
@ -1449,7 +1411,7 @@ RegDeleteKeyValueA(IN HKEY hKey,
Ret = RegDeleteKeyValueW(hKey,
SubKey.Buffer,
SubKey.Buffer);
ValueName.Buffer);
RtlFreeUnicodeString(&SubKey);
RtlFreeUnicodeString(&ValueName);
@ -2328,6 +2290,7 @@ RegDeleteValueA(HKEY hKey,
UNICODE_STRING ValueName;
HANDLE KeyHandle;
NTSTATUS Status;
LONG ErrorCode = ERROR_SUCCESS;
Status = MapDefaultKey(&KeyHandle,
hKey);
@ -2336,19 +2299,25 @@ RegDeleteValueA(HKEY hKey,
return RtlNtStatusToDosError(Status);
}
RtlCreateUnicodeStringFromAsciiz(&ValueName, lpValueName);
Status = NtDeleteValueKey(KeyHandle,
&ValueName);
RtlFreeUnicodeString (&ValueName);
ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
if (!RtlCreateUnicodeStringFromAsciiz(&ValueName, lpValueName))
{
return RtlNtStatusToDosError(Status);
ClosePredefKey(KeyHandle);
return ERROR_NOT_ENOUGH_MEMORY;
}
return ERROR_SUCCESS;
if (IsHKCRKey(KeyHandle))
{
ErrorCode = DeleteHKCRValue(KeyHandle, &ValueName);
}
else
{
Status = NtDeleteValueKey(KeyHandle, &ValueName);
if (!NT_SUCCESS(Status))
ErrorCode = RtlNtStatusToDosError(Status);
}
RtlFreeUnicodeString(&ValueName);
ClosePredefKey(KeyHandle);
return ErrorCode;
}
@ -2364,6 +2333,7 @@ RegDeleteValueW(HKEY hKey,
UNICODE_STRING ValueName;
NTSTATUS Status;
HANDLE KeyHandle;
LONG ErrorCode = ERROR_SUCCESS;
Status = MapDefaultKey(&KeyHandle,
hKey);
@ -2374,17 +2344,18 @@ RegDeleteValueW(HKEY hKey,
RtlInitUnicodeString(&ValueName, lpValueName);
Status = NtDeleteValueKey(KeyHandle,
&ValueName);
ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
if (IsHKCRKey(KeyHandle))
{
return RtlNtStatusToDosError(Status);
ErrorCode = DeleteHKCRValue(KeyHandle, &ValueName);
}
return ERROR_SUCCESS;
else
{
Status = NtDeleteValueKey(KeyHandle, &ValueName);
if (!NT_SUCCESS(Status))
ErrorCode = RtlNtStatusToDosError(Status);
}
ClosePredefKey(KeyHandle);
return ErrorCode;
}

View file

@ -52,6 +52,12 @@ DeleteHKCRKey(
_In_ REGSAM RegSam,
_In_ DWORD Reserved);
LONG
WINAPI
DeleteHKCRValue(
_In_ HKEY hKey,
_In_ PUNICODE_STRING ValueName);
LONG
WINAPI
QueryHKCRValue(