[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / config / ntapi.c
index 3c10d1e..0e76f7c 100644 (file)
@@ -4,6 +4,7 @@
  * FILE:            ntoskrnl/config/cmapi.c
  * PURPOSE:         Configuration Manager - Internal Registry APIs
  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ *                  Eric Kohl
  */
 
 /* INCLUDES ******************************************************************/
@@ -27,7 +28,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
             IN ULONG CreateOptions,
             OUT PULONG Disposition OPTIONAL)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     CM_PARSE_CONTEXT ParseContext = {0};
     HANDLE Handle;
@@ -63,11 +64,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the error code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if(!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -113,7 +113,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
 {
     CM_PARSE_CONTEXT ParseContext = {0};
     HANDLE Handle;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     PAGED_CODE();
     DPRINT("NtOpenKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName);
@@ -135,11 +135,10 @@ NtOpenKey(OUT PHANDLE KeyHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the status */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if(!NT_SUCCESS(Status)) return Status;
     }
 
     /* Just let the object manager handle this */
@@ -267,17 +266,12 @@ NtEnumerateKey(IN HANDLE KeyHandle,
                           sizeof(ULONG));
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference and return status */
             ObDereferenceObject(KeyObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
 
     /* Setup the callback */
@@ -356,17 +350,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
                           sizeof(ULONG));
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference and return status */
             ObDereferenceObject(KeyObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
 
     /* Setup the callback */
@@ -475,17 +464,12 @@ NtQueryKey(IN HANDLE KeyHandle,
                           sizeof(ULONG));
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference and return status */
             ObDereferenceObject(KeyObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
 
     /* Setup the callback */
@@ -555,17 +539,12 @@ NtQueryValueKey(IN HANDLE KeyHandle,
                           sizeof(ULONG));
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference and return status */
             ObDereferenceObject(KeyObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
 
     /* Make sure the name is aligned properly */
@@ -912,6 +891,9 @@ NtInitializeRegistry(IN USHORT Flag)
     /* Always do this as kernel mode */
     if (KeGetPreviousMode() == UserMode) return ZwInitializeRegistry(Flag);
 
+    /* Enough of the system has booted by now */
+    Ki386PerfEnd();
+            
     /* Validate flag */
     if (Flag > CM_BOOT_FLAG_MAX) return STATUS_INVALID_PARAMETER;
 
@@ -1034,8 +1016,91 @@ NTAPI
 NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey,
                    OUT PULONG HandleCount)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    KPROCESSOR_MODE PreviousMode;
+    PCM_KEY_BODY KeyBody = NULL;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+
+    DPRINT("NtQueryOpenSubKeys()\n");
+
+    PAGED_CODE();
+
+    /* Get the processor mode */
+    PreviousMode = KeGetPreviousMode();
+
+    if (PreviousMode != KernelMode)
+    {
+        /* Prepare to probe parameters */
+        _SEH2_TRY
+        {
+            /* Probe target key */
+            ProbeForRead(TargetKey,
+                         sizeof(OBJECT_ATTRIBUTES),
+                         sizeof(ULONG));
+
+            /* Probe handle count */
+            ProbeForWriteUlong(HandleCount);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        }
+        _SEH2_END;
+    }
+
+    /* Open a handle to the key */
+    Status = ObOpenObjectByName(TargetKey,
+                                CmpKeyObjectType,
+                                PreviousMode,
+                                NULL,
+                                KEY_READ,
+                                NULL,
+                                &KeyHandle);
+    if (NT_SUCCESS(Status))
+    {
+        /* Reference the key object */
+        Status = ObReferenceObjectByHandle(KeyHandle,
+                                           KEY_READ,
+                                           CmpKeyObjectType,
+                                           PreviousMode,
+                                           (PVOID *)&KeyBody,
+                                           NULL);
+
+        /* Close the handle */
+        NtClose(KeyHandle);
+    }
+
+    /* Fail, if the key object could not be referenced */
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Lock the registry exclusively */
+    CmpLockRegistryExclusive();
+
+    /* Fail, if we did not open a hive root key */
+    if (KeyBody->KeyControlBlock->KeyCell !=
+        KeyBody->KeyControlBlock->KeyHive->BaseBlock->RootCell)
+    {
+        DPRINT("Error: Key is not a hive root key!\n");
+        CmpUnlockRegistry();
+        ObDereferenceObject(KeyBody);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Call the internal API */
+    *HandleCount = CmCountOpenSubKeys(KeyBody->KeyControlBlock,
+                                      FALSE);
+
+    /* Unlock the registry */
+    CmpUnlockRegistry();
+
+    /* Dereference the key object */
+    ObDereferenceObject(KeyBody);
+
+    DPRINT("Done.\n");
+
+    return Status;
 }
 
 NTSTATUS
@@ -1130,7 +1195,8 @@ NTAPI
 NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
              IN ULONG Flags)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+#if 0
+    NTSTATUS Status;
     OBJECT_ATTRIBUTES ObjectAttributes;
     UNICODE_STRING ObjectName;
     CM_PARSE_CONTEXT ParseContext = {0};
@@ -1174,11 +1240,10 @@ NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the error code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if(!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -1290,6 +1355,10 @@ Quickie:
 
     /* Return status */
     return Status;
+#else
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+#endif
 }
 
 NTSTATUS