Create a branch for Thomas Faber's work on creating a kernel mode test suite for...
[reactos.git] / rostests / drivers / kmtest / kmtest.c
diff --git a/rostests/drivers/kmtest/kmtest.c b/rostests/drivers/kmtest/kmtest.c
deleted file mode 100644 (file)
index 68817e3..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Kernel Mode regression Test
- * Driver Core
- *
- * Copyright 2004 Filip Navara <xnavara@volny.cz>
- *
- * 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>
-
-LONG successes;
-LONG failures;
-LONG skipped;
-tls_data glob_data;
-
-/* PRIVATE FUNCTIONS ***********************************************************/
-VOID
-StartTest()
-{
-    successes = 0;
-    failures = 0;
-    skipped = 0;
-}
-
-VOID
-FinishTest(HANDLE KeyHandle, LPWSTR TestName)
-{
-    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)
-{
-    glob_data.current_file=strrchr(file,'/');
-    if (glob_data.current_file==NULL)
-        glob_data.current_file=strrchr(file,'\\');
-    if (glob_data.current_file==NULL)
-        glob_data.current_file=file;
-    else
-        glob_data.current_file++;
-    glob_data.current_line=line;
-}
-
-/*
- * Checks condition.
- * Parameters:
- *   - condition - condition to check;
- *   - msg test description;
- *   - file - test application source code file name of the check
- *   - line - test application source code file line number of the check
- * Return:
- *   0 if condition does not have the expected value, 1 otherwise
- */
-int kmtest_ok(int condition, const char *msg, ... )
-{
-    va_list valist;
-
-    if (!condition)
-    {
-        if (msg[0])
-        {
-            char string[1024];
-            va_start(valist, msg);
-            vsprintf(string, msg, valist);
-            DbgPrint( "%s:%d: Test failed: %s\n",
-                glob_data.current_file, glob_data.current_line, string );
-            va_end(valist);
-        }
-        else
-        {
-            DbgPrint( "%s:%d: Test failed\n",
-                glob_data.current_file, glob_data.current_line );
-        }
-        InterlockedIncrement(&failures);
-        return 0;
-    }
-    else
-    {/*
-        if (report_success)
-            fprintf( stdout, "%s:%d: Test succeeded\n",
-            glob_data.current_file, glob_data.current_line);*/
-        InterlockedIncrement(&successes);
-    }
-    return 1;
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriver);
-
-/*
- * Test Declarations
- */
-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);
-BOOLEAN ZwLoadTest(PDRIVER_OBJECT, PUNICODE_STRING, PWCHAR);
-BOOLEAN ZwUnloadTest(PDRIVER_OBJECT, PUNICODE_STRING, PWCHAR);
-BOOLEAN DetachDeviceTest(PDEVICE_OBJECT);
-BOOLEAN AttachDeviceTest(PDEVICE_OBJECT,  PWCHAR);
-VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN);
-VOID NtoskrnlFsRtlTest(HANDLE KeyHandle);
-
-typedef enum {
-    TestStageExTimer = 0,
-    TestStageIoMdl,
-    TestStageIoDi,
-    TestStageIoIrp,
-    TestStageMmPoolTest,
-    TestStageMmPoolCorruption,
-    TestStageOb,
-    TestStageKeStall,
-    TestStageDrv,
-    TestStageFsRtl,
-    TestStageMax
-} TEST_STAGE;
-
-/*
- * KmtestDispatch
- */
-NTSTATUS
-NTAPI
-KmtestDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
-
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (AttachDeviceObject)
-    {
-        IoSkipCurrentIrpStackLocation(Irp);
-        Status = IoCallDriver(AttachDeviceObject, Irp);
-        return Status;
-    }
-
-    Irp->IoStatus.Status = Status;
-    Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
-}
-
-/*
- * KmtestCreateClose
- */
-NTSTATUS
-NTAPI
-KmtestCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (AttachDeviceObject)
-    {
-        IoSkipCurrentIrpStackLocation(Irp);
-        Status = IoCallDriver(AttachDeviceObject, Irp);
-        return Status;
-    }
-
-    /* Do DriverObject Test with Driver Initialized */
-    DriverObjectTest(DeviceObject->DriverObject, 1);
-
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    Irp->IoStatus.Information=0;
-
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_SUCCESS;
-}
-
-/*
- * KmtestUnload
- */
-VOID
-NTAPI
-KmtestUnload(IN PDRIVER_OBJECT DriverObject)
-{
-    UNICODE_STRING DosDeviceString;
-
-    if(AttachDeviceObject)
-    {
-        IoDetachDevice(AttachDeviceObject);
-    }
-
-    /* Do DriverObject Test for Unload */
-    DriverObjectTest(DriverObject, 2);
-
-    if (MainDeviceObject)
-    {
-        RtlInitUnicodeString(&DosDeviceString, L"\\DosDevices\\Kmtest");
-        IoDeleteSymbolicLink(&DosDeviceString);
-
-        IoDeleteDevice(MainDeviceObject);
-    }
-}
-
-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;
-
-       case TestStageFsRtl:
-         NtoskrnlFsRtlTest(KeyHandle);
-         break;
-
-       default:
-         ASSERT(FALSE);
-         break;
-     }
-}
-
-/*
- * DriverEntry
- */
-NTSTATUS
-NTAPI
-DriverEntry(PDRIVER_OBJECT DriverObject,
-            PUNICODE_STRING RegistryPath)
-{
-    int i;
-    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");
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               RegistryPath,
-                               OBJ_CASE_INSENSITIVE,
-                               0,
-                               NULL);
-
-    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;
-    }
-
-    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;
-    }
-
-    KeyInfo = ReadRegistryValue(ParameterKeyHandle, L"CurrentStage");
-    if (KeyInfo)
-    {
-        if (KeyInfo->DataLength != sizeof(ULONG))
-        {
-            DPRINT1("Invalid data length for CurrentStage: %d\n", KeyInfo->DataLength);
-            ExFreePool(KeyInfo);
-            return STATUS_UNSUCCESSFUL;
-        }
-
-        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
-        {
-            DPRINT1("Testing was completed on a previous boot\n");
-            ExFreePool(KeyInfo);
-            return STATUS_UNSUCCESSFUL;
-        }
-
-        ExFreePool(KeyInfo);
-    }
-    else
-    {
-        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;
-
-    /* Set necessary routines */
-    DriverObject->DriverUnload = KmtestUnload;
-    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KmtestDispatch;
-    DriverObject->MajorFunction[IRP_MJ_CREATE] = KmtestCreateClose;
-    DriverObject->MajorFunction[IRP_MJ_CLOSE] = KmtestCreateClose;
-
-    return STATUS_SUCCESS;
-}