[KMTEST]
authorCameron Gutman <aicommander@gmail.com>
Sat, 22 May 2010 18:34:01 +0000 (18:34 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sat, 22 May 2010 18:34:01 +0000 (18:34 +0000)
- Add support for recovering from crashed tests
- Add check to prevent us from running the test every boot
- Delete some useless code
- Record test result information in the registry
- Under the Kmtest\Parameters key, you will find CurrentStage which is the stage that testing is on (almost always 8 if it boots). You will also find <Test Name>SuccessCount which is the number of successful tests, <Test Name>FailureCount which is the number of failed tests, <Test Name>TotalCount which is the total number of tests, and <Test Name>SkippedCount which is the number of tests that have been skipped
- Enjoy your reg testing! :)

svn path=/trunk/; revision=47309

rostests/drivers/kmtest/deviface.c [deleted file]
rostests/drivers/kmtest/deviface_test.c
rostests/drivers/kmtest/kmtest.c
rostests/drivers/kmtest/kmtest.h
rostests/drivers/kmtest/kmtest.rbuild
rostests/drivers/kmtest/ntos_ex.c
rostests/drivers/kmtest/ntos_io.c
rostests/drivers/kmtest/ntos_ke.c
rostests/drivers/kmtest/ntos_ob.c
rostests/drivers/kmtest/ntos_pools.c

diff --git a/rostests/drivers/kmtest/deviface.c b/rostests/drivers/kmtest/deviface.c
deleted file mode 100644 (file)
index a3011f3..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * PnP Test
- * ReactOS Device Interface functions implementation
- *
- * Copyright 2003, 2004 Filip Navara <xnavara@volny.cz>
- * Copyright 2003, 2004 Matthew Brace <ismarc@austin.rr.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; see the file COPYING.LIB.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <ddk/ntddk.h>
-#include "kmtest.h"
-
-//#define NDEBUG
-#include "debug.h"
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*
- * IoGetDeviceInterfaces
- *
- * Returns a list of device interfaces of a particular device interface class.
- *
- * Parameters
- *    InterfaceClassGuid
- *       Points to a class GUID specifying the device interface class.
- *
- *    PhysicalDeviceObject
- *       Points to an optional PDO that narrows the search to only the
- *       device interfaces of the device represented by the PDO.
- *
- *    Flags
- *       Specifies flags that modify the search for device interfaces. The
- *       DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
- *       returned symbolic links should contain also disabled device
- *       interfaces in addition to the enabled ones.
- *
- *    SymbolicLinkList
- *       Points to a character pointer that is filled in on successful return
- *       with a list of unicode strings identifying the device interfaces
- *       that match the search criteria. The newly allocated buffer contains
- *       a list of symbolic link names. Each unicode string in the list is
- *       null-terminated; the end of the whole list is marked by an additional
- *       NULL. The caller is responsible for freeing the buffer (ExFreePool)
- *       when it is no longer needed.
- *       If no device interfaces match the search criteria, this routine
- *       returns STATUS_SUCCESS and the string contains a single NULL
- *       character.
- *
- * Status
- *    @unimplemented
- *
- *    The parameters PhysicalDeviceObject and Flags aren't correctly
- *    processed. Rest of the cases was tested under Win XP and the
- *    function worked correctly.
- */
-
-NTSTATUS NTAPI
-ReactOS_IoGetDeviceInterfaces(
-   IN CONST GUID *InterfaceClassGuid,
-   IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
-   IN ULONG Flags,
-   OUT PWSTR *SymbolicLinkList)
-{
-   PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
-   PWCHAR BaseInterfaceString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
-   UNICODE_STRING GuidString;
-   UNICODE_STRING BaseKeyName;
-   UNICODE_STRING AliasKeyName;
-   UNICODE_STRING SymbolicLink;
-   UNICODE_STRING Control;
-   UNICODE_STRING SubKeyName;
-   UNICODE_STRING SymbolicLinkKeyName;
-   UNICODE_STRING ControlKeyName;
-   UNICODE_STRING TempString;
-   HANDLE InterfaceKey;
-   HANDLE SubKey;
-   HANDLE SymbolicLinkKey;
-   PKEY_FULL_INFORMATION fip;
-   PKEY_FULL_INFORMATION bfip=NULL;
-   PKEY_BASIC_INFORMATION bip;
-   PKEY_VALUE_PARTIAL_INFORMATION vpip=NULL;
-   PWCHAR SymLinkList = NULL;
-   ULONG SymLinkListSize = 0;
-   NTSTATUS Status;
-   ULONG Size = 0;
-   ULONG i = 0;
-   ULONG j = 0;
-   OBJECT_ATTRIBUTES ObjectAttributes;
-
-   Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("RtlStringFromGUID() Failed.\n");
-      return STATUS_INVALID_HANDLE;
-   }
-
-   RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString);
-   RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink");
-   RtlInitUnicodeString(&Control, L"\\Control");
-   BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
-   BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR));
-   BaseKeyName.Buffer = ExAllocatePool(
-      NonPagedPool,
-      BaseKeyName.MaximumLength);
-   ASSERT(BaseKeyName.Buffer != NULL);
-   wcscpy(BaseKeyName.Buffer, BaseKeyString);
-   RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
-
-   if (PhysicalDeviceObject)
-   {
-      WCHAR GuidBuffer[40];
-      UNICODE_STRING PdoGuidString;
-
-      RtlFreeUnicodeString(&BaseKeyName);
-
-      IoGetDeviceProperty(
-         PhysicalDeviceObject,
-         DevicePropertyClassGuid,
-         sizeof(GuidBuffer),
-         GuidBuffer,
-         &Size);
-
-      RtlInitUnicodeString(&PdoGuidString, GuidBuffer);
-      if (RtlCompareUnicodeString(&GuidString, &PdoGuidString, TRUE))
-      {
-         DPRINT("Inconsistent Guid's asked for in IoGetDeviceInterfaces()\n");
-         return STATUS_INVALID_HANDLE;
-      }
-
-      DPRINT("IoGetDeviceInterfaces() called with PDO, not implemented.\n");
-      return STATUS_NOT_IMPLEMENTED;
-   }
-   else
-   {
-      InitializeObjectAttributes(
-         &ObjectAttributes,
-         &BaseKeyName,
-         OBJ_CASE_INSENSITIVE,
-         NULL,
-         NULL);
-
-      Status = ZwOpenKey(
-         &InterfaceKey,
-         KEY_READ,
-         &ObjectAttributes);
-
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
-         RtlFreeUnicodeString(&BaseKeyName);
-         return Status;
-      }
-
-      Status = ZwQueryKey(
-         InterfaceKey,
-         KeyFullInformation,
-         NULL,
-         0,
-         &Size);
-
-      if (Status != STATUS_BUFFER_TOO_SMALL)
-      {
-         DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
-         RtlFreeUnicodeString(&BaseKeyName);
-         ZwClose(InterfaceKey);
-         return Status;
-      }
-
-      fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
-      ASSERT(fip != NULL);
-
-      Status = ZwQueryKey(
-         InterfaceKey,
-         KeyFullInformation,
-         fip,
-         Size,
-         &Size);
-
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
-         ExFreePool(fip);
-         RtlFreeUnicodeString(&BaseKeyName);
-         ZwClose(InterfaceKey);
-         return Status;
-      }
-
-      for (; i < fip->SubKeys; i++)
-      {
-         Status = ZwEnumerateKey(
-            InterfaceKey,
-            i,
-            KeyBasicInformation,
-            NULL,
-            0,
-            &Size);
-
-         if (Status != STATUS_BUFFER_TOO_SMALL)
-         {
-            DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
-            ExFreePool(fip);
-            if (SymLinkList != NULL)
-               ExFreePool(SymLinkList);
-            RtlFreeUnicodeString(&BaseKeyName);
-            ZwClose(InterfaceKey);
-            return Status;
-         }
-
-         bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
-         ASSERT(bip != NULL);
-
-         Status = ZwEnumerateKey(
-            InterfaceKey,
-            i,
-            KeyBasicInformation,
-            bip,
-            Size,
-            &Size);
-
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
-            ExFreePool(fip);
-            ExFreePool(bip);
-            if (SymLinkList != NULL)
-               ExFreePool(SymLinkList);
-            RtlFreeUnicodeString(&BaseKeyName);
-            ZwClose(InterfaceKey);
-            return Status;
-         }
-
-         SubKeyName.Length = 0;
-         SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
-         SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
-         ASSERT(SubKeyName.Buffer != NULL);
-         TempString.Length = TempString.MaximumLength = bip->NameLength;
-         TempString.Buffer = bip->Name;
-         RtlCopyUnicodeString(&SubKeyName, &BaseKeyName);
-         RtlAppendUnicodeToString(&SubKeyName, L"\\");
-         RtlAppendUnicodeStringToString(&SubKeyName, &TempString);
-
-         ExFreePool(bip);
-
-         InitializeObjectAttributes(
-            &ObjectAttributes,
-            &SubKeyName,
-            OBJ_CASE_INSENSITIVE,
-            NULL,
-            NULL);
-
-         Status = ZwOpenKey(
-            &SubKey,
-            KEY_READ,
-            &ObjectAttributes);
-
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
-            ExFreePool(fip);
-            if (SymLinkList != NULL)
-               ExFreePool(SymLinkList);
-            RtlFreeUnicodeString(&SubKeyName);
-            RtlFreeUnicodeString(&BaseKeyName);
-            ZwClose(InterfaceKey);
-            return Status;
-         }
-
-         Status = ZwQueryKey(
-            SubKey,
-            KeyFullInformation,
-            NULL,
-            0,
-            &Size);
-
-         if (Status != STATUS_BUFFER_TOO_SMALL)
-         {
-            DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
-            ExFreePool(fip);
-            RtlFreeUnicodeString(&BaseKeyName);
-            RtlFreeUnicodeString(&SubKeyName);
-            ZwClose(SubKey);
-            ZwClose(InterfaceKey);
-            return Status;
-         }
-
-         bfip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
-         ASSERT(bfip != NULL);
-
-         Status = ZwQueryKey(
-            SubKey,
-            KeyFullInformation,
-            bfip,
-            Size,
-            &Size);
-
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
-            ExFreePool(fip);
-            RtlFreeUnicodeString(&SubKeyName);
-            RtlFreeUnicodeString(&BaseKeyName);
-            ZwClose(SubKey);
-            ZwClose(InterfaceKey);
-            return Status;
-         }
-
-         for(j = 0; j < bfip->SubKeys; j++)
-         {
-            Status = ZwEnumerateKey(
-               SubKey,
-               j,
-               KeyBasicInformation,
-               NULL,
-               0,
-               &Size);
-
-            if (Status == STATUS_NO_MORE_ENTRIES)
-               continue;
-
-            if (Status != STATUS_BUFFER_TOO_SMALL)
-            {
-               DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
-               ExFreePool(bfip);
-               ExFreePool(fip);
-               if (SymLinkList != NULL)
-                  ExFreePool(SymLinkList);
-               RtlFreeUnicodeString(&SubKeyName);
-               RtlFreeUnicodeString(&BaseKeyName);
-               ZwClose(SubKey);
-               ZwClose(InterfaceKey);
-               return Status;
-            }
-
-            bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
-            ASSERT(bip != NULL);
-
-            Status = ZwEnumerateKey(
-               SubKey,
-               j,
-               KeyBasicInformation,
-               bip,
-               Size,
-               &Size);
-
-            if (!NT_SUCCESS(Status))
-            {
-               DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
-               ExFreePool(fip);
-               ExFreePool(bfip);
-               ExFreePool(bip);
-               if (SymLinkList != NULL)
-                  ExFreePool(SymLinkList);
-               RtlFreeUnicodeString(&SubKeyName);
-               RtlFreeUnicodeString(&BaseKeyName);
-               ZwClose(SubKey);
-               ZwClose(InterfaceKey);
-               return Status;
-            }
-
-            if (!wcsncmp(bip->Name, L"Control", bip->NameLength))
-            {
-               continue;
-            }
-
-            SymbolicLinkKeyName.Length = 0;
-            SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR);
-            SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength);
-            ASSERT(SymbolicLinkKeyName.Buffer != NULL);
-            TempString.Length = TempString.MaximumLength = bip->NameLength;
-            TempString.Buffer = bip->Name;
-            RtlCopyUnicodeString(&SymbolicLinkKeyName, &SubKeyName);
-            RtlAppendUnicodeToString(&SymbolicLinkKeyName, L"\\");
-            RtlAppendUnicodeStringToString(&SymbolicLinkKeyName, &TempString);
-
-            ControlKeyName.Length = 0;
-            ControlKeyName.MaximumLength = SymbolicLinkKeyName.Length + Control.Length + sizeof(WCHAR);
-            ControlKeyName.Buffer = ExAllocatePool(NonPagedPool, ControlKeyName.MaximumLength);
-            ASSERT(ControlKeyName.Buffer != NULL);
-            RtlCopyUnicodeString(&ControlKeyName, &SymbolicLinkKeyName);
-            RtlAppendUnicodeStringToString(&ControlKeyName, &Control);
-
-            ExFreePool(bip);
-
-            InitializeObjectAttributes(
-               &ObjectAttributes,
-               &SymbolicLinkKeyName,
-               OBJ_CASE_INSENSITIVE,
-               NULL,
-               NULL);
-
-            Status = ZwOpenKey(
-               &SymbolicLinkKey,
-               KEY_READ,
-               &ObjectAttributes);
-
-            if (!NT_SUCCESS(Status))
-            {
-               DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
-               ExFreePool(fip);
-               ExFreePool(bfip);
-               if (SymLinkList != NULL)
-                  ExFreePool(SymLinkList);
-               RtlFreeUnicodeString(&SymbolicLinkKeyName);
-               RtlFreeUnicodeString(&SubKeyName);
-               RtlFreeUnicodeString(&BaseKeyName);
-               ZwClose(SubKey);
-               ZwClose(InterfaceKey);
-               return Status;
-            }
-
-            Status = ZwQueryValueKey(
-               SymbolicLinkKey,
-               &SymbolicLink,
-               KeyValuePartialInformation,
-               NULL,
-               0,
-               &Size);
-
-            if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-               continue;
-
-            if (Status != STATUS_BUFFER_TOO_SMALL)
-            {
-               DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
-               ExFreePool(fip);
-               ExFreePool(bfip);
-               if (SymLinkList != NULL)
-                  ExFreePool(SymLinkList);
-               RtlFreeUnicodeString(&SymbolicLinkKeyName);
-               RtlFreeUnicodeString(&SubKeyName);
-               RtlFreeUnicodeString(&BaseKeyName);
-               ZwClose(SymbolicLinkKey);
-               ZwClose(SubKey);
-               ZwClose(InterfaceKey);
-               return Status;
-            }
-
-            vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
-            ASSERT(vpip != NULL);
-
-            Status = ZwQueryValueKey(
-               SymbolicLinkKey,
-               &SymbolicLink,
-               KeyValuePartialInformation,
-               vpip,
-               Size,
-               &Size);
-
-            if (!NT_SUCCESS(Status))
-            {
-               DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
-               ExFreePool(fip);
-               ExFreePool(bfip);
-               ExFreePool(vpip);
-               if (SymLinkList != NULL)
-                  ExFreePool(SymLinkList);
-               RtlFreeUnicodeString(&SymbolicLinkKeyName);
-               RtlFreeUnicodeString(&SubKeyName);
-               RtlFreeUnicodeString(&BaseKeyName);
-               ZwClose(SymbolicLinkKey);
-               ZwClose(SubKey);
-               ZwClose(InterfaceKey);
-               return Status;
-            }
-
-            Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ControlKeyName.Buffer);
-
-            if (NT_SUCCESS(Status))
-            {
-               /* Put the name in the string here */
-               if (SymLinkList == NULL)
-               {
-                  SymLinkListSize = vpip->DataLength;
-                  SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
-                  ASSERT(SymLinkList != NULL);
-                  RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength);
-                  SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0;
-                  SymLinkList[1] = '?';
-               }
-               else
-               {
-                  PWCHAR OldSymLinkList;
-                  ULONG OldSymLinkListSize;
-                  PWCHAR SymLinkListPtr;
-
-                  OldSymLinkList = SymLinkList;
-                  OldSymLinkListSize = SymLinkListSize;
-                  SymLinkListSize += vpip->DataLength;
-                  SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
-                  ASSERT(SymLinkList != NULL);
-                  RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize);
-                  ExFreePool(OldSymLinkList);
-                  SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR));
-                  RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength);
-                  SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
-                  SymLinkListPtr[1] = '?';
-               }
-            }
-
-            RtlFreeUnicodeString(&SymbolicLinkKeyName);
-            RtlFreeUnicodeString(&ControlKeyName);
-            ZwClose(SymbolicLinkKey);
-         }
-
-         ExFreePool(vpip);
-         RtlFreeUnicodeString(&SubKeyName);
-         ZwClose(SubKey);
-      }
-
-      if (SymLinkList != NULL)
-      {
-         SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0;
-      }
-      else
-      {
-         SymLinkList = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
-         SymLinkList[0] = 0;
-      }
-
-      *SymbolicLinkList = SymLinkList;
-
-      RtlFreeUnicodeString(&BaseKeyName);
-      ZwClose(InterfaceKey);
-      ExFreePool(bfip);
-      ExFreePool(fip);
-   }
-
-   return STATUS_SUCCESS;
-}
index 0fbd91e..2e27349 100644 (file)
@@ -26,7 +26,7 @@
 #include <ndk/iotypes.h>
 #include "kmtest.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include "debug.h"
 
 /* PRIVATE FUNCTIONS **********************************************************/
@@ -52,26 +52,26 @@ VOID DeviceInterfaceTest_Func()
    PWSTR SymbolicLinkListPtr;
    GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
 
-   Status = IoGetDeviceInterfaces_Func(
+   Status = IoGetDeviceInterfaces(
       &Guid,
       NULL,
       0,
       &SymbolicLinkList);
 
+   ok(NT_SUCCESS(Status),
+         "IoGetDeviceInterfaces failed with status 0x%X\n",
+         (unsigned int)Status);
    if (!NT_SUCCESS(Status))
    {
-      DPRINT(
-         "[PnP Test] IoGetDeviceInterfaces failed with status 0x%X\n",
-         Status);
       return;
    }
 
-   DPRINT("[PnP Test] IoGetDeviceInterfaces results:\n");
+   DPRINT("IoGetDeviceInterfaces results:\n");
    for (SymbolicLinkListPtr = SymbolicLinkList;
         SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0;
         SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1)
    {
-      DPRINT("[PnP Test] %S\n", SymbolicLinkListPtr);
+      DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr);
    }
 
 #if 0
@@ -102,7 +102,7 @@ VOID DeviceInterfaceTest_Func()
    ExFreePool(SymbolicLinkList);
 }
 
-VOID RegisterDI_Test()
+VOID RegisterDI_Test(HANDLE KeyHandle)
 {
     GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
     DEVICE_OBJECT DeviceObject;
@@ -111,6 +111,8 @@ VOID RegisterDI_Test()
     UNICODE_STRING SymbolicLinkName;
     NTSTATUS Status;
 
+    StartTest();
+
     RtlInitUnicodeString(&SymbolicLinkName, L"");
 
     // Prepare our surrogate of a Device Object
@@ -132,23 +134,8 @@ VOID RegisterDI_Test()
 
     ok(Status == STATUS_INVALID_DEVICE_REQUEST,
         "IoRegisterDeviceInterface returned 0x%08lX\n", Status);
-}
 
-VOID NtoskrnlIoDeviceInterface()
-{
-    StartTest();
-
-    // Test IoRegisterDeviceInterface() failures now
-    RegisterDI_Test();
-
-/*
-    DPRINT("Calling DeviceInterfaceTest_Func with native functions\n");
-    IoGetDeviceInterfaces_Func = IoGetDeviceInterfaces;
-    DeviceInterfaceTest_Func();
-    DPRINT("Calling DeviceInterfaceTest_Func with ReactOS functions\n");
-    IoGetDeviceInterfaces_Func = ReactOS_IoGetDeviceInterfaces;
     DeviceInterfaceTest_Func();
-*/
 
-    FinishTest("NTOSKRNL Io Device Interface Test");
+    FinishTest(KeyHandle, L"IoDeviceInterfaceTest");
 }
index 964486a..3164688 100644 (file)
 #include <ddk/ntddk.h>
 #include "kmtest.h"
 
+#define NDEBUG
+#include <debug.h>
+
 LONG successes;
 LONG failures;
+LONG skipped;
 tls_data glob_data;
 
 /* PRIVATE FUNCTIONS ***********************************************************/
@@ -35,12 +39,61 @@ StartTest()
 {
     successes = 0;
     failures = 0;
+    skipped = 0;
 }
 
 VOID
-FinishTest(LPSTR TestName)
+FinishTest(HANDLE KeyHandle, LPWSTR TestName)
 {
-    DbgPrint("%s: %d test executed (0 marked as todo, %d failures), 0 skipped.\n", TestName, successes + failures, failures);
+    WCHAR KeyName[100];
+    LONG total = successes + failures;
+    UNICODE_STRING KeyNameU;
+
+    wcscpy(KeyName, TestName);
+    wcscat(KeyName, L"SuccessCount");
+    RtlInitUnicodeString(&KeyNameU, KeyName);
+
+    ZwSetValueKey(KeyHandle,
+                  &KeyNameU,
+                  0,
+                  REG_DWORD,
+                  &successes,
+                  sizeof(ULONG));
+
+    wcscpy(KeyName, TestName);
+    wcscat(KeyName, L"FailureCount");
+    RtlInitUnicodeString(&KeyNameU, KeyName);
+
+    ZwSetValueKey(KeyHandle,
+                  &KeyNameU,
+                  0,
+                  REG_DWORD,
+                  &failures,
+                  sizeof(ULONG));
+
+    wcscpy(KeyName, TestName);
+    wcscat(KeyName, L"TotalCount");
+    RtlInitUnicodeString(&KeyNameU, KeyName);
+
+    ZwSetValueKey(KeyHandle,
+                  &KeyNameU,
+                  0,
+                  REG_DWORD,
+                  &total,
+                  sizeof(ULONG));
+
+    wcscpy(KeyName, TestName);
+    wcscat(KeyName, L"SkipCount");
+    RtlInitUnicodeString(&KeyNameU, KeyName);
+
+    ZwSetValueKey(KeyHandle,
+                  &KeyNameU,
+                  0,
+                  REG_DWORD,
+                  &skipped,
+                  sizeof(ULONG));
+
+    DbgPrint("%S: %d test executed (0 marked as todo, %d failures), %d skipped.\n", TestName, total, failures, skipped);
 }
 
 void kmtest_set_location(const char* file, int line)
@@ -105,11 +158,14 @@ PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriv
 /*
  * Test Declarations
  */
-VOID NtoskrnlIoTests();
-VOID NtoskrnlKeTests();
-VOID NtoskrnlObTest();
-VOID NtoskrnlExecutiveTests();
-VOID NtoskrnlPoolsTest();
+VOID RegisterDI_Test(HANDLE KeyHandle);
+VOID NtoskrnlIoMdlTest(HANDLE KeyHandle);
+VOID NtoskrnlIoIrpTest(HANDLE KeyHandle);
+VOID NtoskrnlObTest(HANDLE KeyHandle);
+VOID ExTimerTest(HANDLE KeyHandle);
+VOID PoolsTest(HANDLE KeyHandle);
+VOID PoolsCorruption(HANDLE KeyHandle);
+VOID KeStallTest(HANDLE KeyHandle);
 VOID DriverObjectTest(PDRIVER_OBJECT, int);
 VOID DeviceCreateDeleteTest(PDRIVER_OBJECT);
 VOID DeviceObjectTest(PDEVICE_OBJECT);
@@ -119,6 +175,19 @@ BOOLEAN DetachDeviceTest(PDEVICE_OBJECT);
 BOOLEAN AttachDeviceTest(PDEVICE_OBJECT,  PWCHAR);
 VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN);
 
+typedef enum {
+    TestStageExTimer = 0,
+    TestStageIoMdl,
+    TestStageIoDi,
+    TestStageIoIrp,
+    TestStageMmPoolTest,
+    TestStageMmPoolCorruption,
+    TestStageOb,
+    TestStageKeStall,
+    TestStageDrv,
+    TestStageMax
+} TEST_STAGE;
+
 /*
  * KmtestDispatch
  */
@@ -192,7 +261,148 @@ KmtestUnload(IN PDRIVER_OBJECT DriverObject)
 
         IoDeleteDevice(MainDeviceObject);
     }
-    FinishTest("Driver Tests");
+}
+
+static
+PKEY_VALUE_PARTIAL_INFORMATION
+NTAPI
+ReadRegistryValue(HANDLE KeyHandle, PWCHAR ValueName)
+{
+    NTSTATUS Status;
+    PKEY_VALUE_PARTIAL_INFORMATION InformationBuffer = NULL;
+    ULONG AllocatedLength = 0, RequiredLength = 0;
+    UNICODE_STRING ValueNameU;
+
+    RtlInitUnicodeString(&ValueNameU, ValueName);
+
+    Status = ZwQueryValueKey(KeyHandle,
+                             &ValueNameU,
+                             KeyValuePartialInformation,
+                             NULL,
+                             0,
+                             &RequiredLength);
+    if (Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW)
+    {
+        InformationBuffer = ExAllocatePool(PagedPool, RequiredLength);
+        AllocatedLength = RequiredLength;
+        if (!InformationBuffer) return NULL;
+
+        Status = ZwQueryValueKey(KeyHandle,
+                                 &ValueNameU,
+                                 KeyValuePartialInformation,
+                                 InformationBuffer,
+                                 AllocatedLength,
+                                 &RequiredLength);
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to read %S (0x%x)\n", ValueName, Status);
+        if (InformationBuffer != NULL)
+            ExFreePool(InformationBuffer);
+        return NULL;
+    }
+
+    return InformationBuffer;
+}
+
+static
+VOID
+RunKernelModeTest(PDRIVER_OBJECT DriverObject,
+                  PUNICODE_STRING RegistryPath,
+                  HANDLE KeyHandle,
+                  TEST_STAGE Stage)
+{
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"CurrentStage");
+    PWCHAR LowerDriverRegPath;
+
+    DPRINT1("Running stage %d test...\n", Stage);
+
+    ZwSetValueKey(KeyHandle,
+                  &KeyName,
+                  0,
+                  REG_DWORD,
+                  &Stage,
+                  sizeof(ULONG));
+
+    switch (Stage)
+    {
+       case TestStageExTimer:
+         ExTimerTest(KeyHandle);
+         break;
+
+       case TestStageIoMdl:
+         NtoskrnlIoMdlTest(KeyHandle);
+         break;
+
+       case TestStageIoDi:
+         RegisterDI_Test(KeyHandle);
+         break;
+
+       case TestStageIoIrp:
+         NtoskrnlIoIrpTest(KeyHandle);
+         break;
+
+       case TestStageMmPoolTest:
+         PoolsTest(KeyHandle);
+         break;
+
+       case TestStageMmPoolCorruption:
+         PoolsCorruption(KeyHandle);
+         break;
+
+       case TestStageOb:
+         NtoskrnlObTest(KeyHandle);
+         break;
+
+       case TestStageKeStall:
+         KeStallTest(KeyHandle);
+         break;
+
+       case TestStageDrv:
+         /* Start the tests for the driver routines */
+         StartTest();
+
+         /* Do DriverObject Test for Driver Entry */
+         DriverObjectTest(DriverObject, 0);
+
+         /* Create and delete device, on return MainDeviceObject has been created */
+         DeviceCreateDeleteTest(DriverObject);
+
+         /* Make sure a device object was created */
+         if (MainDeviceObject)
+         {
+             LowerDriverRegPath = CreateLowerDeviceRegistryKey(RegistryPath, L"kmtestassist");
+
+             if (LowerDriverRegPath)
+             {
+                 /* Load driver test and load the lower driver */
+                 if (ZwLoadTest(DriverObject, RegistryPath, LowerDriverRegPath))
+                 {
+                     AttachDeviceTest(MainDeviceObject, L"kmtestassists");
+                     if (AttachDeviceObject)
+                     {
+                         LowerDeviceKernelAPITest(MainDeviceObject, FALSE);
+                     }
+
+                     /* Unload lower driver without detaching from its device */
+                     ZwUnloadTest(DriverObject, RegistryPath, LowerDriverRegPath);
+                     LowerDeviceKernelAPITest(MainDeviceObject, TRUE);
+                 }
+                 else
+                 {
+                     DbgPrint("Failed to load kmtestassist driver\n");
+                 }
+             }
+         }
+
+         FinishTest(KeyHandle, L"DriverTest");
+         break;
+
+       default:
+         ASSERT(FALSE);
+         break;
+     }
 }
 
 /*
@@ -204,61 +414,98 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
             PUNICODE_STRING RegistryPath)
 {
     int i;
-    PWCHAR LowerDriverRegPath;
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING ParameterKeyName = RTL_CONSTANT_STRING(L"Parameters");
+    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+    PULONG KeyValue;
+    TEST_STAGE CurrentStage;
+    HANDLE DriverKeyHandle, ParameterKeyHandle;
 
     DbgPrint("\n===============================================\n");
     DbgPrint("Kernel Mode Regression Driver Test starting...\n");
     DbgPrint("===============================================\n");
 
-    MainDeviceObject = NULL;
-    AttachDeviceObject = NULL;
-    ThisDriverObject = DriverObject;
-
-    NtoskrnlExecutiveTests();
-    NtoskrnlKeTests();
-    NtoskrnlIoTests();
-    NtoskrnlObTest();
-    NtoskrnlPoolsTest();
+    InitializeObjectAttributes(&ObjectAttributes,
+                               RegistryPath,
+                               OBJ_CASE_INSENSITIVE,
+                               0,
+                               NULL);
 
-    /* Start the tests for the driver routines */
-    StartTest();
+    Status = ZwOpenKey(&DriverKeyHandle,
+                       KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open %wZ\n", RegistryPath);
+        return Status;
+    }
 
-    /* Do DriverObject Test for Driver Entry */
-    DriverObjectTest(DriverObject, 0);
-    /* Create and delete device, on return MainDeviceObject has been created */
-    DeviceCreateDeleteTest(DriverObject);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ParameterKeyName,
+                               OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
+                               DriverKeyHandle,
+                               NULL);
+    Status = ZwCreateKey(&ParameterKeyHandle,
+                         KEY_SET_VALUE | KEY_QUERY_VALUE,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         NULL);
+    ZwClose(DriverKeyHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create %wZ\\%wZ\n", RegistryPath, &ParameterKeyName);
+        return Status;
+    }
 
-    /* Make sure a device object was created */
-    if (MainDeviceObject)
+    KeyInfo = ReadRegistryValue(ParameterKeyHandle, L"CurrentStage");
+    if (KeyInfo)
     {
-        LowerDriverRegPath = CreateLowerDeviceRegistryKey(RegistryPath, L"kmtestassist");
+        if (KeyInfo->DataLength != sizeof(ULONG))
+        {
+            DPRINT1("Invalid data length for CurrentStage: %d\n", KeyInfo->DataLength);
+            ExFreePool(KeyInfo);
+            return STATUS_UNSUCCESSFUL;
+        }
 
-        if (LowerDriverRegPath)
+        KeyValue = (PULONG)KeyInfo->Data;
+
+        if ((*KeyValue) + 1 < TestStageMax)
+        {
+            DPRINT1("Resuming testing after a crash at stage %d\n", (*KeyValue));
+
+            CurrentStage = (TEST_STAGE)((*KeyValue) + 1);
+        }
+        else
         {
-            /* Load driver test and load the lower driver */
-            if (ZwLoadTest(DriverObject, RegistryPath, LowerDriverRegPath))
-            {
-                AttachDeviceTest(MainDeviceObject, L"kmtestassists");
-                if (AttachDeviceObject)
-                {
-                    LowerDeviceKernelAPITest(MainDeviceObject, FALSE);
-                }
-
-                /* Unload lower driver without detaching from its device */
-                ZwUnloadTest(DriverObject, RegistryPath, LowerDriverRegPath);
-                LowerDeviceKernelAPITest(MainDeviceObject, TRUE);
-            }
-            else
-            {
-                DbgPrint("Failed to load kmtestassist driver\n");
-            }
+            DPRINT1("Testing was completed on a previous boot\n");
+            ExFreePool(KeyInfo);
+            return STATUS_UNSUCCESSFUL;
         }
+
+        ExFreePool(KeyInfo);
     }
     else
     {
-        return STATUS_UNSUCCESSFUL;
+        DPRINT1("Starting a fresh test\n");
+        CurrentStage = (TEST_STAGE)0;
     }
 
+    /* Run the tests */
+    while (CurrentStage < TestStageMax)
+    {
+       RunKernelModeTest(DriverObject,
+                         RegistryPath,
+                         ParameterKeyHandle,
+                         CurrentStage);
+       CurrentStage++;
+    }
+
+    DPRINT1("Testing is complete!\n");
+    ZwClose(ParameterKeyHandle);
+
     /* Set all MajorFunctions to NULL to verify that kernel fixes them */
     for (i = 1; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
         DriverObject->MajorFunction[i] = NULL;
index a0f20d3..c244d30 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef PNPTEST_H
-#define PNPTEST_H
+#ifndef KMTEST_H
+#define KMTEST_H
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -30,7 +30,7 @@ typedef struct
 extern tls_data glob_data;
 
 VOID StartTest();
-VOID FinishTest(LPSTR TestName);
+VOID FinishTest(HANDLE KeyHandle, LPWSTR TestName);
 void kmtest_set_location(const char* file, int line);
 
 #ifdef __GNUC__
@@ -51,4 +51,4 @@ PDEVICE_OBJECT AttachDeviceObject;
 PDEVICE_OBJECT MainDeviceObject;
 PDRIVER_OBJECT ThisDriverObject;
 
-#endif /* PNPTEST_H */
+#endif /* KMTEST_H */
index 9219db9..b992079 100644 (file)
@@ -5,7 +5,6 @@
        <library>hal</library>
        <library>pseh</library>
        <file>kmtest.c</file>
-       <file>deviface.c</file>
        <file>deviface_test.c</file>
        <file>drvobj_test.c</file>
        <file>devobj_test.c</file>
index 84d6859..8edf7fe 100644 (file)
@@ -27,7 +27,7 @@
 #include <ndk/ntndk.h>
 #include "kmtest.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include "debug.h"
 
 /* PRIVATE FUNCTIONS ***********************************************************/
@@ -44,9 +44,10 @@ TestTimerApcRoutine(IN PVOID TimerContext,
     (*ApcCount)++;
 }
 
+/* PUBLIC FUNCTIONS *************************************************************/
 
 VOID
-ExTimerTest()
+ExTimerTest(HANDLE KeyHandle)
 {
     UNICODE_STRING TimerName;
     OBJECT_ATTRIBUTES ObjectAttributes;
@@ -167,13 +168,5 @@ ExTimerTest()
     Status = ZwClose(TimerHandle);
     ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status);
 
-    FinishTest("NTOSKRNL Executive Timer");
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID
-NtoskrnlExecutiveTests()
-{
-    ExTimerTest();
+    FinishTest(KeyHandle, L"ExTimerTest");
 }
index 986098e..d49955b 100644 (file)
 #define NDEBUG
 #include "debug.h"
 
-VOID NtoskrnlIoDeviceInterface();
-
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-VOID NtoskrnlIoMdlTest()
+VOID NtoskrnlIoMdlTest(HANDLE KeyHandle)
 {
     PMDL Mdl;
     PIRP Irp;
@@ -81,10 +79,10 @@ VOID NtoskrnlIoMdlTest()
     IoFreeIrp(Irp);
     ExFreePool(VirtualAddress);
 
-    FinishTest("NTOSKRNL Io Mdl");
+    FinishTest(KeyHandle, L"IoMdlTest");
 }
 
-VOID NtoskrnlIoIrpTest()
+VOID NtoskrnlIoIrpTest(HANDLE KeyHandle)
 {
     USHORT size;
     IRP *iorp;
@@ -166,12 +164,5 @@ VOID NtoskrnlIoIrpTest()
         IoFreeIrp(iorp);
     }
 
-    FinishTest("NTOSKRNL Io Irp");
-}
-
-VOID NtoskrnlIoTests()
-{
-    NtoskrnlIoMdlTest();
-    NtoskrnlIoDeviceInterface();
-    NtoskrnlIoIrpTest();
+    FinishTest(KeyHandle, L"IoIrpTest");
 }
index 1c60322..d59eeb3 100644 (file)
 #define NDEBUG
 #include "debug.h"
 
-/* PRIVATE FUNCTIONS ***********************************************************/
+/* PUBLIC FUNCTIONS ***********************************************************/
 
 VOID
-NTAPI
-KeStallTest()
+KeStallTest(HANDLE KeyHandle)
 {
     ULONG i;
     LARGE_INTEGER TimeStart, TimeFinish;
@@ -74,13 +73,5 @@ KeStallTest()
     KeQuerySystemTime(&TimeFinish);
     DPRINT1("Time elapsed: %d secs\n", (TimeFinish.QuadPart - TimeStart.QuadPart) / 10000000); // 30
 
-    FinishTest("NTOSKRNL KeStallmanExecution test");
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID
-NtoskrnlKeTests()
-{
-    KeStallTest();
+    FinishTest(KeyHandle, L"KeStallmanExecutionTest");
 }
index a7c62fa..c8b4d35 100644 (file)
@@ -26,7 +26,7 @@
 #include <ddk/ntifs.h>
 #include "kmtest.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include "debug.h"
 
 #include "ntndk.h"
@@ -487,7 +487,7 @@ ObtReferenceTests()
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 VOID
-NtoskrnlObTest()
+NtoskrnlObTest(HANDLE KeyHandle)
 {
     StartTest();
 
@@ -515,5 +515,5 @@ NtoskrnlObTest()
     ObtClose();
     DPRINT("Cleanup done\n");
 
-    FinishTest("NTOSKRNL Ob Manager");
+    FinishTest(KeyHandle, L"ObMgrTest");
 }
index 816d7c3..37c9987 100644 (file)
 #include <pseh/pseh2.h>
 #include "kmtest.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include "debug.h"
 
 #define TAG_POOLTEST 'tstP'
 
-/* PRIVATE FUNCTIONS ***********************************************************/
+/* PUBLIC FUNCTIONS ***********************************************************/
 
 VOID
-PoolsTest()
+PoolsTest(HANDLE KeyHandle)
 {
     PVOID Ptr;
     ULONG AllocSize, i, AllocNumber;
@@ -124,11 +124,11 @@ PoolsTest()
     ExFreePoolWithTag(Allocs, TAG_POOLTEST);
 
 
-    FinishTest("NTOSKRNL Pools Tests");
+    FinishTest(KeyHandle, L"MmPoolAllocTest");
 }
 
 VOID
-PoolsCorruption()
+PoolsCorruption(HANDLE KeyHandle)
 {
     PULONG Ptr, TestPtr;
     ULONG AllocSize;
@@ -174,14 +174,5 @@ PoolsCorruption()
     // free the pool
     ExFreePoolWithTag(Ptr, TAG_POOLTEST);
 
-    FinishTest("NTOSKRNL Pool Corruption");
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID
-NtoskrnlPoolsTest()
-{
-    PoolsTest();
-    //PoolsCorruption();
+    FinishTest(KeyHandle, L"MmPoolCorruptionTest");
 }