[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / reg / reg.c
index 28dcbe4..6ad365a 100644 (file)
@@ -14,7 +14,9 @@
 /* INCLUDES *****************************************************************/
 
 #include <advapi32.h>
-#include <wine/debug.h>
+
+#include <ndk/cmfuncs.h>
+#include <pseh/pseh2.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(reg);
 
@@ -933,7 +935,7 @@ CreateNestedKey(PHKEY KeyHandle,
     LocalObjectAttributes.ObjectName = &LocalKeyName;
     FullNameLength = LocalKeyName.Length / sizeof(WCHAR);
 
-  LocalKeyHandle = NULL;
+    LocalKeyHandle = NULL;
 
     /* Remove the last part of the key name and try to create the key again. */
     while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
@@ -1023,8 +1025,9 @@ RegCreateKeyExA(HKEY hKey,
 {
     UNICODE_STRING SubKeyString;
     UNICODE_STRING ClassString;
-    OBJECT_ATTRIBUTES Attributes;
+    OBJECT_ATTRIBUTES ObjectAttributes;
     HANDLE ParentKey;
+    ULONG Attributes = OBJ_CASE_INSENSITIVE;
     NTSTATUS Status;
 
     TRACE("RegCreateKeyExA() called\n");
@@ -1048,15 +1051,18 @@ RegCreateKeyExA(HKEY hKey,
                                          lpClass);
     }
 
+    if (dwOptions & REG_OPTION_OPEN_LINK)
+        Attributes |= OBJ_OPENLINK;
+
     RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
                                      (LPSTR)lpSubKey);
-    InitializeObjectAttributes(&Attributes,
+    InitializeObjectAttributes(&ObjectAttributes,
                                &SubKeyString,
-                               OBJ_CASE_INSENSITIVE,
+                               Attributes,
                                (HANDLE)ParentKey,
                                lpSecurityAttributes ? (PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
     Status = CreateNestedKey(phkResult,
-                             &Attributes,
+                             &ObjectAttributes,
                              (lpClass == NULL)? NULL : &ClassString,
                              dwOptions,
                              samDesired,
@@ -1097,8 +1103,9 @@ RegCreateKeyExW(HKEY hKey,
 {
     UNICODE_STRING SubKeyString;
     UNICODE_STRING ClassString;
-    OBJECT_ATTRIBUTES Attributes;
+    OBJECT_ATTRIBUTES ObjectAttributes;
     HANDLE ParentKey;
+    ULONG Attributes = OBJ_CASE_INSENSITIVE;
     NTSTATUS Status;
 
     TRACE("RegCreateKeyExW() called\n");
@@ -1116,17 +1123,20 @@ RegCreateKeyExW(HKEY hKey,
 
     TRACE("ParentKey %p\n", ParentKey);
 
+    if (dwOptions & REG_OPTION_OPEN_LINK)
+        Attributes |= OBJ_OPENLINK;
+
     RtlInitUnicodeString(&ClassString,
                          lpClass);
     RtlInitUnicodeString(&SubKeyString,
                          lpSubKey);
-    InitializeObjectAttributes(&Attributes,
+    InitializeObjectAttributes(&ObjectAttributes,
                                &SubKeyString,
-                               OBJ_CASE_INSENSITIVE,
+                               Attributes,
                                (HANDLE)ParentKey,
                                lpSecurityAttributes ? (PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
     Status = CreateNestedKey(phkResult,
-                             &Attributes,
+                             &ObjectAttributes,
                              (lpClass == NULL)? NULL : &ClassString,
                              dwOptions,
                              samDesired,
@@ -1311,7 +1321,7 @@ Cleanup:
 /************************************************************************
  *  RegDeleteKeyExA
  *
- * @unimplemented
+ * @implemented
  */
 LONG
 WINAPI
@@ -1320,15 +1330,68 @@ RegDeleteKeyExA(HKEY hKey,
                 REGSAM samDesired,
                 DWORD Reserved)
 {
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyName;
+    HANDLE ParentKey;
+    HANDLE TargetKey;
+    NTSTATUS Status;
+
+    /* Make sure we got a subkey */
+    if (!lpSubKey)
+    {
+        /* Fail */
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    if (samDesired & KEY_WOW64_32KEY)
+        ERR("Wow64 not yet supported!\n");
+
+    if (samDesired & KEY_WOW64_64KEY)
+        ERR("Wow64 not yet supported!\n");
+
+    RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
+                                     (LPSTR)lpSubKey);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               ParentKey,
+                               NULL);
+
+    Status = NtOpenKey(&TargetKey,
+                       DELETE,
+                       &ObjectAttributes);
+    RtlFreeUnicodeString(&SubKeyName);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Cleanup;
+    }
+
+    Status = NtDeleteKey(TargetKey);
+    NtClose (TargetKey);
+
+Cleanup:
+    ClosePredefKey(ParentKey);
+
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    return ERROR_SUCCESS;
 }
 
 
 /************************************************************************
  *  RegDeleteKeyExW
  *
- * @unimplemented
+ * @implemented
  */
 LONG
 WINAPI
@@ -1337,8 +1400,60 @@ RegDeleteKeyExW(HKEY hKey,
                 REGSAM samDesired,
                 DWORD Reserved)
 {
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyName;
+    HANDLE ParentKey;
+    HANDLE TargetKey;
+    NTSTATUS Status;
+
+    /* Make sure we got a subkey */
+    if (!lpSubKey)
+    {
+        /* Fail */
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    if (samDesired & KEY_WOW64_32KEY)
+        ERR("Wow64 not yet supported!\n");
+
+    if (samDesired & KEY_WOW64_64KEY)
+        ERR("Wow64 not yet supported!\n");
+
+
+    RtlInitUnicodeString(&SubKeyName,
+                         (LPWSTR)lpSubKey);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               ParentKey,
+                               NULL);
+    Status = NtOpenKey(&TargetKey,
+                       DELETE,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Cleanup;
+    }
+
+    Status = NtDeleteKey(TargetKey);
+    NtClose(TargetKey);
+
+Cleanup:
+    ClosePredefKey(ParentKey);
+
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    return ERROR_SUCCESS;
 }
 
 
@@ -2545,7 +2660,7 @@ RegEnumKeyExA(HKEY hKey,
             if (KeyInfo->Node.NameLength > NameLength ||
                 KeyInfo->Node.ClassLength > ClassLength)
             {
-                               ErrorCode = ERROR_BUFFER_OVERFLOW;
+                ErrorCode = ERROR_BUFFER_OVERFLOW;
             }
             else
             {
@@ -3053,13 +3168,11 @@ RegGetKeySecurity(HKEY hKey,
         return RtlNtStatusToDosError(Status);
     }
 
-#if 0
     Status = NtQuerySecurityObject(KeyHandle,
                                    SecurityInformation,
                                    pSecurityDescriptor,
                                    *lpcbSecurityDescriptor,
                                    lpcbSecurityDescriptor);
-#endif
 
     ClosePredefKey(KeyHandle);
 
@@ -3349,6 +3462,7 @@ RegOpenKeyExA(HKEY hKey,
     UNICODE_STRING SubKeyString;
     HANDLE KeyHandle;
     NTSTATUS Status;
+    ULONG Attributes = OBJ_CASE_INSENSITIVE;
     LONG ErrorCode = ERROR_SUCCESS;
 
     TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
@@ -3365,11 +3479,14 @@ RegOpenKeyExA(HKEY hKey,
         return RtlNtStatusToDosError(Status);
     }
 
+    if (ulOptions & REG_OPTION_OPEN_LINK)
+        Attributes |= OBJ_OPENLINK;
+
     RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
                                      (LPSTR)lpSubKey);
     InitializeObjectAttributes(&ObjectAttributes,
                                &SubKeyString,
-                               OBJ_CASE_INSENSITIVE,
+                               Attributes,
                                KeyHandle,
                                NULL);
 
@@ -3404,6 +3521,7 @@ RegOpenKeyExW(HKEY hKey,
     UNICODE_STRING SubKeyString;
     HANDLE KeyHandle;
     NTSTATUS Status;
+    ULONG Attributes = OBJ_CASE_INSENSITIVE;
     LONG ErrorCode = ERROR_SUCCESS;
 
     TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
@@ -3419,6 +3537,9 @@ RegOpenKeyExW(HKEY hKey,
         return RtlNtStatusToDosError(Status);
     }
 
+    if (ulOptions & REG_OPTION_OPEN_LINK)
+        Attributes |= OBJ_OPENLINK;
+
     if (lpSubKey != NULL)
         RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
     else
@@ -3426,7 +3547,7 @@ RegOpenKeyExW(HKEY hKey,
 
     InitializeObjectAttributes(&ObjectAttributes,
                                &SubKeyString,
-                               OBJ_CASE_INSENSITIVE,
+                               Attributes,
                                KeyHandle,
                                NULL);
 
@@ -3773,7 +3894,6 @@ RegQueryInfoKeyW(HKEY hKey,
         *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
     }
 
-#if 0
     if (lpcbSecurityDescriptor != NULL)
     {
         Status = NtQuerySecurityObject(KeyHandle,
@@ -3796,7 +3916,6 @@ RegQueryInfoKeyW(HKEY hKey,
             goto Cleanup;
         }
     }
-#endif
 
     if (lpftLastWriteTime != NULL)
     {
@@ -4031,8 +4150,8 @@ RegQueryValueExA(HKEY hkeyorg,
     RtlInitAnsiString( &nameA, name );
     if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
     {
-        return RtlNtStatusToDosError(status);
         ClosePredefKey(hkey);
+        return RtlNtStatusToDosError(status);
     }
 
     status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
@@ -4833,10 +4952,29 @@ RegSetValueExW(HKEY hKey,
                DWORD cbData)
 {
     UNICODE_STRING ValueName;
-    PUNICODE_STRING pValueName;
     HANDLE KeyHandle;
     NTSTATUS Status;
 
+    if (is_string(dwType) && (cbData != 0))
+    {
+        PWSTR pwsData = (PWSTR)lpData;
+
+        _SEH2_TRY
+        {
+            if((pwsData[cbData / sizeof(WCHAR) - 1] != L'\0') &&
+                (pwsData[cbData / sizeof(WCHAR)] == L'\0'))
+            {
+                /* Increment length if last character is not zero and next is zero */
+                cbData += sizeof(WCHAR);
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            _SEH2_YIELD(return ERROR_NOACCESS);
+        }
+        _SEH2_END;
+    }
+
     Status = MapDefaultKey(&KeyHandle,
                            hKey);
     if (!NT_SUCCESS(Status))
@@ -4845,22 +4983,9 @@ RegSetValueExW(HKEY hKey,
     }
 
     RtlInitUnicodeString(&ValueName, lpValueName);
-    pValueName = &ValueName;
-
-    if (is_string(dwType) && (cbData != 0))
-    {
-        PWSTR pwsData = (PWSTR)lpData;
-
-        if((pwsData[cbData / sizeof(WCHAR) - 1] != L'\0') &&
-            (pwsData[cbData / sizeof(WCHAR)] == L'\0'))
-        {
-            /* Increment length if last character is not zero and next is zero */
-            cbData += sizeof(WCHAR);
-        }
-    }
 
     Status = NtSetValueKey(KeyHandle,
-                           pValueName,
+                           &ValueName,
                            0,
                            dwType,
                            (PVOID)lpData,