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)
/* 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))
if (ErrorCode != ERROR_SUCCESS)
{
RtlFreeUnicodeString(&KeyName);
+ *MachineKey = hKey;
return ErrorCode;
}
/* 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))
if (ErrorCode != ERROR_SUCCESS)
{
RtlFreeUnicodeString(&KeyName);
+ *PreferredKey = hKey;
return ErrorCode;
}
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
IN LPCWSTR lpSubKey OPTIONAL,
IN LPCWSTR lpValueName OPTIONAL)
{
- UNICODE_STRING ValueName;
- HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
- NTSTATUS Status;
-
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
+ HKEY hSubKey = hKey;
+ LONG ErrorCode;
- if (lpSubKey != NULL)
+ if (lpSubKey)
{
- 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;
-
- RtlInitUnicodeString(&ValueName, lpValueName);
+ ErrorCode = RegDeleteValueW(hSubKey, lpValueName);
- Status = NtDeleteValueKey(CurKey,
- &ValueName);
-
- if (SubKeyHandle != NULL)
+ if (hSubKey != hKey)
{
- NtClose(SubKeyHandle);
- }
-
-Cleanup:
- ClosePredefKey(KeyHandle);
-
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
+ RegCloseKey(hSubKey);
}
-
- return ERROR_SUCCESS;
+ return ErrorCode;
}
Ret = RegDeleteKeyValueW(hKey,
SubKey.Buffer,
- SubKey.Buffer);
+ ValueName.Buffer);
RtlFreeUnicodeString(&SubKey);
RtlFreeUnicodeString(&ValueName);
UNICODE_STRING ValueName;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
Status = MapDefaultKey(&KeyHandle,
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;
}
UNICODE_STRING ValueName;
NTSTATUS Status;
HANDLE KeyHandle;
+ LONG ErrorCode = ERROR_SUCCESS;
Status = MapDefaultKey(&KeyHandle,
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;
}