mirror of
https://github.com/reactos/reactos.git
synced 2024-12-04 08:53:32 +08:00
[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:
parent
373816c729
commit
2449ed5d85
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING SubKeyName;
|
||||
|
||||
RtlInitUnicodeString(&SubKeyName, lpSubKey);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&SubKeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&SubKeyHandle,
|
||||
KEY_SET_VALUE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
ErrorCode = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_SET_VALUE, &hSubKey);
|
||||
if (ErrorCode)
|
||||
{
|
||||
goto Cleanup;
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
CurKey = SubKeyHandle;
|
||||
}
|
||||
else
|
||||
CurKey = KeyHandle;
|
||||
ErrorCode = RegDeleteValueW(hSubKey, lpValueName);
|
||||
|
||||
RtlInitUnicodeString(&ValueName, lpValueName);
|
||||
|
||||
Status = NtDeleteValueKey(CurKey,
|
||||
&ValueName);
|
||||
|
||||
if (SubKeyHandle != NULL)
|
||||
if (hSubKey != hKey)
|
||||
{
|
||||
NtClose(SubKeyHandle);
|
||||
RegCloseKey(hSubKey);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,6 +52,12 @@ DeleteHKCRKey(
|
||||
_In_ REGSAM RegSam,
|
||||
_In_ DWORD Reserved);
|
||||
|
||||
LONG
|
||||
WINAPI
|
||||
DeleteHKCRValue(
|
||||
_In_ HKEY hKey,
|
||||
_In_ PUNICODE_STRING ValueName);
|
||||
|
||||
LONG
|
||||
WINAPI
|
||||
QueryHKCRValue(
|
||||
|
Loading…
Reference in New Issue
Block a user