[ros-diffs] [tfaber] 52519: [KMTESTS] - rework the kmtest loader application to follow everything else's coding style and to allow user-mode test parts

tfaber at svn.reactos.org tfaber at svn.reactos.org
Sun Jul 3 18:53:29 UTC 2011


Author: tfaber
Date: Sun Jul  3 18:53:26 2011
New Revision: 52519

URL: http://svn.reactos.org/svn/reactos?rev=52519&view=rev
Log:
[KMTESTS]
- rework the kmtest loader application to follow everything else's coding style and to allow user-mode test parts

Added:
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c   (with props)
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c   (with props)
Modified:
    branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt
    branches/GSoC_2011/KMTestSuite/kmtests/include/kmt_test.h
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest.rbuild
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.c
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.h
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest/service.c

Modified: branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -48,6 +48,8 @@
 list(APPEND KMTEST_SOURCE
     kmtest/kmtest.c
     kmtest/service.c
+    kmtest/support.c
+    kmtest/testlist.c
     kmtest/kmtest.rc)
 
 add_executable(kmtest ${KMTEST_SOURCE})

Modified: branches/GSoC_2011/KMTestSuite/kmtests/include/kmt_test.h
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/include/kmt_test.h?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/include/kmt_test.h [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/include/kmt_test.h [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -16,6 +16,7 @@
 #include <stdarg.h>
 
 typedef VOID KMT_TESTFUNC(VOID);
+typedef KMT_TESTFUNC *PKMT_TESTFUNC;
 
 typedef struct
 {
@@ -37,6 +38,17 @@
     CHAR LogBuffer[ANYSIZE_ARRAY];
 } KMT_RESULTBUFFER, *PKMT_RESULTBUFFER;
 
+#if defined KMT_USER_MODE
+VOID KmtLoadDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning);
+VOID KmtUnloadDriver(VOID);
+VOID KmtOpenDriver(VOID);
+VOID KmtCloseDriver(VOID);
+
+DWORD KmtSendToDriver(IN DWORD ControlCode);
+DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String);
+DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer, IN DWORD Length);
+#endif /* defined KMT_USER_MODE */
+
 extern PKMT_RESULTBUFFER ResultBuffer;
 
 #ifdef __GNUC__
@@ -47,13 +59,15 @@
 
 #define START_TEST(name) VOID Test_##name(VOID)
 
+#ifndef KMT_STRINGIZE
 #define KMT_STRINGIZE(x) #x
-#define ok(test, ...)                ok_(test, __FILE__, __LINE__, __VA_ARGS__)
-#define trace(...)                   trace_(   __FILE__, __LINE__, __VA_ARGS__)
+#endif /* !defined KMT_STRINGIZE */
+#define ok(test, ...)                ok_(test,   __FILE__, __LINE__, __VA_ARGS__)
+#define trace(...)                   trace_(     __FILE__, __LINE__, __VA_ARGS__)
 #define skip(test, ...)              skip_(test, __FILE__, __LINE__, __VA_ARGS__)
 
-#define ok_(test, file, line, ...)   KmtOk(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__)
-#define trace_(file, line, ...)      KmtTrace(   file ":" KMT_STRINGIZE(line), __VA_ARGS__)
+#define ok_(test, file, line, ...)   KmtOk(test,   file ":" KMT_STRINGIZE(line), __VA_ARGS__)
+#define trace_(file, line, ...)      KmtTrace(     file ":" KMT_STRINGIZE(line), __VA_ARGS__)
 #define skip_(test, file, line, ...) KmtSkip(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__)
 
 VOID KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments)      KMT_FORMAT(ms_printf, 3, 0);
@@ -75,7 +89,9 @@
 #define ok_eq_hex(value, expected)          ok_eq_print(value, expected, "0x%08lx")
 #define ok_bool_true(value, desc)           ok((value) == TRUE, desc " FALSE, expected TRUE\n")
 #define ok_bool_false(value, desc)          ok((value) == FALSE, desc " TRUE, expected FALSE\n")
-#define ok_eq_bool(value, expected)         ok((value) == (expected), #value " = %s, expected %s\n", (value) ? "TRUE" : "FALSE", (expected) ? "TRUE" : "FALSE")
+#define ok_eq_bool(value, expected)         ok((value) == (expected), #value " = %s, expected %s\n",    \
+                                                (value) ? "TRUE" : "FALSE",                             \
+                                                (expected) ? "TRUE" : "FALSE")
 #define ok_eq_str(value, expected)          ok(!strcmp(value, expected), #value " = \"%s\", expected \"%s\"\n", value, expected)
 #define ok_eq_wstr(value, expected)         ok(!wcscmp(value, expected), #value " = \"%ls\", expected \"%ls\"\n", value, expected)
 

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest.rbuild?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest.rbuild [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest.rbuild [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -5,5 +5,7 @@
 	<directory name="kmtest">
 		<file>kmtest.c</file>
 		<file>service.c</file>
+		<file>support.c</file>
+		<file>testlist.c</file>
 	</directory>
 </module>

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.c?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.c [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.c [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -6,6 +6,7 @@
  */
 
 #define UNICODE
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <strsafe.h>
 
@@ -19,186 +20,288 @@
 #define KMT_DEFINE_TEST_FUNCTIONS
 #include <kmt_test.h>
 
-#define LOGBUFFER_SIZE 65000
-
-static void OutputError(FILE *fp, DWORD error);
-static DWORD RunTest(char *testName);
-static DWORD ListTests(PSTR *testList);
-int __cdecl main(int argc, char **argv);
-
-static void OutputError(FILE *fp, DWORD error)
-{
-    char *message;
+#define SERVICE_NAME        L"Kmtest"
+#define SERVICE_PATH        L"kmtest_drv.sys"
+
+#define LOGBUFFER_SIZE      65000
+#define RESULTBUFFER_SIZE   FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer[LOGBUFFER_SIZE])
+
+static HANDLE KmtestHandle;
+PCSTR ErrorFileAndLine = "No error";
+
+static void OutputError(DWORD Error);
+static DWORD ListTests(VOID);
+static PKMT_TESTFUNC FindTest(PCSTR TestName);
+static DWORD OutputResult(PCSTR TestName);
+static DWORD RunTest(PCSTR TestName);
+int __cdecl main(int ArgCount, char **Arguments);
+
+/**
+ * @name OutputError
+ *
+ * Output an error message to the console.
+ *
+ * @param Error
+ *        Win32 error code
+ */
+static
+void
+OutputError(
+    DWORD Error)
+{
+    PSTR Message;
     if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
-                   NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message, 0, NULL))
-    {
-        fprintf(fp, "Could not retrieve error message (error 0x%08lx). Original error: 0x%08lx\n", GetLastError(), error);
-    }
-
-    fprintf(fp, "%s\n", message);
-
-    LocalFree(message);
-}
-
-static DWORD RunTest(char *testName)
-{
-    DWORD error = ERROR_SUCCESS;
-    HANDLE hDevice = INVALID_HANDLE_VALUE;
-    DWORD bytesRead, bytesWritten;
+                   NULL, Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&Message, 0, NULL))
+    {
+        fprintf(stderr, "%s: Could not retrieve error message (error 0x%08lx). Original error: 0x%08lx\n",
+            ErrorFileAndLine, GetLastError(), Error);
+        return;
+    }
+
+    fprintf(stderr, "%s: error 0x%08lx: %s\n", ErrorFileAndLine, Error, Message);
+
+    LocalFree(Message);
+}
+
+/**
+ * @name ListTests
+ *
+ * Output the list of tests to the console.
+ * The list will comprise tests as listed by the driver
+ * in addition to user-mode tests in TestList.
+ *
+ * @return Win32 error code
+ */
+static
+DWORD
+ListTests(VOID)
+{
+    DWORD Error = ERROR_SUCCESS;
+    CHAR Buffer[1024];
+    DWORD BytesRead;
+    PCSTR TestName = Buffer;
+    PCKMT_TEST TestEntry = TestList;
+    PCSTR NextTestName;
+
+    puts("Valid test names:");
+
+    // get test list from driver
+    if (!DeviceIoControl(KmtestHandle, IOCTL_KMTEST_GET_TESTS, NULL, 0, Buffer, sizeof Buffer, &BytesRead, NULL))
+        error_goto(Error, cleanup);
+
+    // output test list plus user-mode tests
+    while (TestEntry->TestName || *TestName)
+    {
+        // tests starting with a '-' should not be listed
+        while (TestEntry->TestName && *TestEntry->TestName == '-')
+            ++TestEntry;
+
+        if (!TestEntry->TestName)
+        {
+            NextTestName = TestName;
+            TestName += strlen(TestName) + 1;
+        }
+        else if (!*TestName)
+        {
+            NextTestName = TestEntry->TestName;
+            ++TestEntry;
+        }
+        else
+        {
+            int Result = strcmp(TestEntry->TestName, TestName);
+
+            if (Result == 0)
+            {
+                NextTestName = TestEntry->TestName;
+                TestName += strlen(TestName) + 1;
+                ++TestEntry;
+            }
+            else if (Result < 0)
+            {
+                NextTestName = TestEntry->TestName;
+                ++TestEntry;
+            }
+            else
+            {
+                NextTestName = TestName;
+                TestName += strlen(TestName) + 1;
+            }
+        }
+        printf("    %s\n", NextTestName);
+    }
+
+cleanup:
+    return Error;
+}
+
+/**
+ * @name FindTest
+ *
+ * Find a test in TestList by name.
+ *
+ * @param TestName
+ *        Name of the test to look for. Case sensitive
+ *
+ * @return pointer to test function, or NULL if not found
+ */
+static
+PKMT_TESTFUNC
+FindTest(
+    PCSTR TestName)
+{
+    PCKMT_TEST TestEntry = TestList;
+
+    for (TestEntry = TestList; TestEntry->TestName; ++TestEntry)
+    {
+        PCSTR TestEntryName = TestEntry->TestName;
+
+        // skip leading '-' if present
+        if (*TestEntryName == '-')
+            ++TestEntryName;
+
+        if (!lstrcmpA(TestEntryName, TestName))
+            break;
+    }
+
+    return TestEntry->TestFunction;
+}
+
+/**
+ * @name OutputResult
+ *
+ * Output the test results in ResultBuffer to the console.
+ *
+ * @param TestName
+ *        Name of the test whose result is to be printed
+ *
+ * @return Win32 error code
+ */
+static
+DWORD
+OutputResult(
+    PCSTR TestName)
+{
+    DWORD Error = ERROR_SUCCESS;
+    DWORD BytesWritten;
+
+    KmtFinishTest(TestName);
+
+    if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), ResultBuffer->LogBuffer, ResultBuffer->LogBufferLength, &BytesWritten, NULL))
+        Error = GetLastError();
+
+    return Error;
+}
+
+/**
+ * @name RunTest
+ *
+ * Run the named test and output its results.
+ *
+ * @param TestName
+ *        Name of the test to run. Case sensitive
+ *
+ * @return Win32 error code
+ */
+static
+DWORD
+RunTest(
+    PCSTR TestName)
+{
+    DWORD Error = ERROR_SUCCESS;
+    PKMT_TESTFUNC TestFunction;
+    DWORD BytesRead;
 
     ResultBuffer = KmtAllocateResultBuffer(LOGBUFFER_SIZE);
-    if (!ResultBuffer)
-    {
-        error = GetLastError();
+    if (!DeviceIoControl(KmtestHandle, IOCTL_KMTEST_SET_RESULTBUFFER, ResultBuffer, RESULTBUFFER_SIZE, NULL, 0, &BytesRead, NULL))
+        error_goto(Error, cleanup);
+
+    // check test list
+    TestFunction = FindTest(TestName);
+
+    if (TestFunction)
+    {
+        TestFunction();
         goto cleanup;
     }
-
-    hDevice = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0,
-                         NULL, OPEN_EXISTING, 0, NULL);
-
-    if (hDevice == INVALID_HANDLE_VALUE)
-    {
-        error = GetLastError();
+    
+    // not found in user-mode test list, call driver
+    if (!DeviceIoControl(KmtestHandle, IOCTL_KMTEST_RUN_TEST, (PVOID)TestName, strlen(TestName), NULL, 0, &BytesRead, NULL))
+        error_goto(Error, cleanup);
+
+cleanup:
+    OutputResult(TestName);
+    
+    KmtFreeResultBuffer(ResultBuffer);
+
+    return Error;
+}
+
+/**
+ * @name main
+ *
+ * Program entry point
+ *
+ * @param ArgCount
+ * @param Arguments
+ *
+ * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure
+ */
+int
+main(
+    int ArgCount,
+    char **Arguments)
+{
+    INT Status = EXIT_SUCCESS;
+    DWORD Error = ERROR_SUCCESS;
+    SC_HANDLE ServiceHandle;
+    PCSTR AppName = "kmtest.exe";
+    PCSTR TestName;
+
+    Error = KmtServiceInit();
+    if (Error)
         goto cleanup;
-    }
-
-    if (!DeviceIoControl(hDevice, IOCTL_KMTEST_SET_RESULTBUFFER, ResultBuffer, FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer[LOGBUFFER_SIZE]), NULL, 0, &bytesRead, NULL))
-    {
-        error = GetLastError();
+
+    Error = KmtCreateAndStartService(SERVICE_NAME, SERVICE_PATH, L"ReactOS Kernel-Mode Test Suite Driver", &ServiceHandle, FALSE);
+    if (Error)
         goto cleanup;
-    }
-
-    if (!DeviceIoControl(hDevice, IOCTL_KMTEST_RUN_TEST, testName, strlen(testName), NULL, 0, &bytesRead, NULL))
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    KmtFinishTest(testName);
-
-    if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), ResultBuffer->LogBuffer, ResultBuffer->LogBufferLength, &bytesWritten, NULL))
-    {
-        error = GetLastError();
-        goto cleanup;
+
+    KmtestHandle = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+    if (KmtestHandle == INVALID_HANDLE_VALUE)
+        error_goto(Error, cleanup);
+
+    if (ArgCount >= 1)
+        AppName = Arguments[0];
+
+    if (ArgCount <= 1)
+    {
+        printf("Usage: %s <test_name>                 - run the specified test\n", AppName);
+        printf("       %s --list                      - list available tests\n", AppName);
+        printf("       %s <create|delete|start|stop>  - manage the kmtest driver\n\n", AppName);
+        Error = ListTests();
+    }
+    else
+    {
+        TestName = Arguments[1];
+        if (!lstrcmpA(Arguments[1], "--list"))
+            Error = ListTests();
+        else
+            Error = RunTest(TestName);
     }
 
 cleanup:
-    if (hDevice != INVALID_HANDLE_VALUE)
-        CloseHandle(hDevice);
-
-    if (ResultBuffer)
-        KmtFreeResultBuffer(ResultBuffer);
-
-    return error;
-}
-
-static DWORD ListTests(PSTR *testList)
-{
-    DWORD error = ERROR_SUCCESS;
-    HANDLE hDevice = INVALID_HANDLE_VALUE;
-    DWORD bytesRead;
-    PSTR buffer = NULL;
-    DWORD bufferSize;
-
-    if (!testList)
-    {
-        error = ERROR_INVALID_PARAMETER;
-        goto cleanup;
-    }
-
-    hDevice = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0,
-                         NULL, OPEN_EXISTING, 0, NULL);
-
-    if (hDevice == INVALID_HANDLE_VALUE)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    bufferSize = 1024;
-    buffer = HeapAlloc(GetProcessHeap(), 0, bufferSize);
-    if (!buffer)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (!DeviceIoControl(hDevice, IOCTL_KMTEST_GET_TESTS, NULL, 0, buffer, bufferSize, &bytesRead, NULL))
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-cleanup:
-    if (buffer && error)
-    {
-        HeapFree(GetProcessHeap(), 0, buffer);
-        buffer = NULL;
-    }
-
-    if (hDevice != INVALID_HANDLE_VALUE)
-        CloseHandle(hDevice);
-
-    if (testList)
-        *testList = buffer;
-
-    return error;
-}
-
-int __cdecl main(int argc, char **argv)
-{
-    int status = EXIT_SUCCESS;
-    DWORD error;
-
-    if (argc <= 1)
-    {
-        /* no arguments: show usage and list tests */
-        char *programName = argc == 0 ? "kmtest" : argv[0];
-        char *testNames, *testName;
-        size_t len;
-
-        printf("Usage: %s test_name\n", programName);
-        printf("       %s <Create|Start|Stop|Delete>\n", programName);
-        puts("\nValid test names:");
-
-        error = ListTests(&testNames);
-        testName = testNames;
-
-        while ((len = strlen(testName)) != 0)
-        {
-            printf("    %s\n", testName);
-            testName += len + 1;
-        }
-
-        /* TODO: user-mode test parts */
-
-        if (error)
-            OutputError(stdout, error);
-    }
+    if (KmtestHandle)
+        CloseHandle(KmtestHandle);
+
+    if (Error)
+        KmtServiceCleanup(TRUE);
     else
-    {
-        char *testName = argv[1];
-
-        if (argc > 2)
-            fputs("Excess arguments ignored\n", stderr);
-
-        if (!lstrcmpiA(testName, "create"))
-            error = Service_Control(Service_Create);
-        else if (!lstrcmpiA(testName, "delete"))
-            error = Service_Control(Service_Delete);
-        else if (!lstrcmpiA(testName, "start"))
-            error = Service_Control(Service_Start);
-        else if (!lstrcmpiA(testName, "stop"))
-            error = Service_Control(Service_Stop);
-        else
-            /* TODO: user-mode test parts */
-            error = RunTest(testName);
-
-        OutputError(stdout, error);
-    }
-
-    if (error)
-        status = EXIT_FAILURE;
-
-    return status;
-}
+        Error = KmtServiceCleanup(FALSE);
+
+    if (Error)
+        OutputError(Error);
+
+    if (Error)
+        Status = EXIT_FAILURE;
+
+    return Status;
+}

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.h
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.h?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.h [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest/kmtest.h [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -8,16 +8,57 @@
 #ifndef _KMTESTS_H_
 #define _KMTESTS_H_
 
-#include <windows.h>
+extern PCSTR ErrorFileAndLine;
 
-/* service control functions */
-typedef DWORD SERVICE_FUNC(SC_HANDLE hManager);
+#ifndef KMT_STRINGIZE
+#define KMT_STRINGIZE(x) #x
+#endif /* !defined KMT_STRINGIZE */
 
-SERVICE_FUNC Service_Create;
-SERVICE_FUNC Service_Delete;
-SERVICE_FUNC Service_Start;
-SERVICE_FUNC Service_Stop;
+#define location(file, line)                    do { ErrorFileAndLine = file ":" KMT_STRINGIZE(line); } while (0)
+#define error_value(Error, value)               do { location(__FILE__, __LINE__); Error = value; } while (0)
+#define error(Error)                            error_value(Error, GetLastError())
+#define error_goto(Error, label)                do { error(Error); goto label; } while (0)
+#define error_value_goto(Error, value, label)   do { error_value(Error, value); goto label; } while (0)
 
-DWORD Service_Control(SERVICE_FUNC *Service_Func);
+/* service management functions */
+DWORD
+KmtServiceInit(VOID);
+
+DWORD
+KmtServiceCleanup(
+    BOOLEAN IgnoreErrors);
+
+DWORD
+KmtCreateService(
+    IN PCWSTR ServiceName,
+    IN PCWSTR ServicePath,
+    IN PCWSTR DisplayName OPTIONAL,
+    OUT SC_HANDLE *ServiceHandle);
+
+DWORD
+KmtStartService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle);
+
+DWORD
+KmtCreateAndStartService(
+    IN PCWSTR ServiceName,
+    IN PCWSTR ServicePath,
+    IN PCWSTR DisplayName OPTIONAL,
+    OUT SC_HANDLE *ServiceHandle,
+    IN BOOLEAN RestartIfRunning);
+
+DWORD
+KmtStopService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle);
+
+DWORD
+KmtDeleteService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle);
+
+DWORD KmtCloseService(
+    IN OUT SC_HANDLE *ServiceHandle);
 
 #endif /* !defined _KMTESTS_H_ */

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/service.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest/service.c?rev=52519&r1=52518&r2=52519&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest/service.c [iso-8859-1] (original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest/service.c [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -6,130 +6,308 @@
  */
 
 #define UNICODE
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <strsafe.h>
 
+#include <assert.h>
+
 #include "kmtest.h"
 
-#define SERVICE_NAME L"Kmtest"
-#define SERVICE_PATH L"\\kmtest_drv.sys"
-
-DWORD Service_Create(SC_HANDLE hScm)
-{
-    DWORD error = ERROR_SUCCESS;
-    SC_HANDLE hService = NULL;
-    wchar_t driverPath[MAX_PATH];
+#define SERVICE_ACCESS (SERVICE_START | SERVICE_STOP | DELETE)
+
+static SC_HANDLE ScmHandle;
+
+/**
+ * @name KmtServiceInit
+ *
+ * Initialize service management routines (by opening the service control manager)
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtServiceInit(VOID)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    assert(!ScmHandle);
+
+    ScmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+    if (!ScmHandle)
+        error(Error);
+
+    return Error;
+}
+
+/**
+ * @name KmtServiceCleanup
+ *
+ * Clean up resources used by service management routines.
+ *
+ * @param IgnoreErrors
+ *        If TRUE, the function will never set ErrorLineAndFile, and always return ERROR_SUCCESS
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtServiceCleanup(
+    BOOLEAN IgnoreErrors)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    if (ScmHandle && !CloseServiceHandle(ScmHandle) && !IgnoreErrors)
+        error(Error);
+
+    return Error;
+}
+
+/**
+ * @name KmtCreateService
+ *
+ * Create the specified driver service and return a handle to it
+ *
+ * @param ServiceName
+ *        Name of the service to create
+ * @param ServicePath
+ *        File name of the driver, relative to the current directory
+ * @param DisplayName
+ *        Service display name
+ * @param ServiceHandle
+ *        Pointer to a variable to receive the handle to the service
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtCreateService(
+    IN PCWSTR ServiceName,
+    IN PCWSTR ServicePath,
+    IN PCWSTR DisplayName OPTIONAL,
+    OUT SC_HANDLE *ServiceHandle)
+{
+    DWORD Error = ERROR_SUCCESS;
+    WCHAR DriverPath[MAX_PATH];
     HRESULT result = S_OK;
 
-    if (!GetCurrentDirectory(sizeof driverPath / sizeof driverPath[0], driverPath)
-            || FAILED(result = StringCbCat(driverPath, sizeof driverPath, SERVICE_PATH)))
+    assert(ServiceHandle);
+    assert(ServiceName && ServicePath);
+
+    if (!GetCurrentDirectory(sizeof DriverPath / sizeof DriverPath[0], DriverPath))
+        error_goto(Error, cleanup);
+
+    if (DriverPath[wcslen(DriverPath) - 1] != L'\\')
     {
-        if (FAILED(result))
-            error = result;
-        else
-            error = GetLastError();
-        goto cleanup;
+        DriverPath[wcslen(DriverPath) + 1] = L'\0';
+        DriverPath[wcslen(DriverPath)] = L'\\';
     }
 
-    hService = CreateService(hScm, SERVICE_NAME, L"ReactOS Kernel-Mode Test Suite Driver",
-                            SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
-                            SERVICE_ERROR_NORMAL, driverPath, NULL, NULL, NULL, NULL, NULL);
-
-    if (!hService)
-        error = GetLastError();
-
-cleanup:
-    return error;
-}
-
-DWORD Service_Delete(SC_HANDLE hScm)
-{
-    DWORD error = ERROR_SUCCESS;
-    SC_HANDLE hService = NULL;
-
-    hService = OpenService(hScm, SERVICE_NAME, DELETE);
-
-    if (!hService)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (!DeleteService(hService))
-        error = GetLastError();
-
-cleanup:
-    if (hService)
-        CloseServiceHandle(hService);
-
-    return error;
-}
-
-DWORD Service_Start(SC_HANDLE hScm)
-{
-    DWORD error = ERROR_SUCCESS;
-    SC_HANDLE hService = NULL;
-
-    hService = OpenService(hScm, SERVICE_NAME, SERVICE_START);
-
-    if (!hService)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (!StartService(hService, 0, NULL))
-        error = GetLastError();
-
-cleanup:
-    if (hService)
-        CloseServiceHandle(hService);
-
-    return error;
-}
-
-DWORD Service_Stop(SC_HANDLE hScm)
-{
-    DWORD error = ERROR_SUCCESS;
-    SC_HANDLE hService = NULL;
-    SERVICE_STATUS serviceStatus;
-
-    hService = OpenService(hScm, SERVICE_NAME, SERVICE_STOP);
-
-    if (!hService)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus))
-        error = GetLastError();
-
-cleanup:
-    if (hService)
-        CloseServiceHandle(hService);
-
-    return error;
-}
-
-DWORD Service_Control(SERVICE_FUNC *Service_Func)
-{
-    DWORD error = ERROR_SUCCESS;
-    SC_HANDLE hScm = NULL;
-
-    hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
-
-    if (!hScm)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    error = Service_Func(hScm);
-
-cleanup:
-    if (hScm)
-        CloseServiceHandle(hScm);
-
-    return error;
-}
+    result = StringCbCat(DriverPath, sizeof DriverPath, ServicePath);
+    if (FAILED(result))
+        error_value_goto(Error, result, cleanup);
+
+    *ServiceHandle = CreateService(ScmHandle, ServiceName, DisplayName,
+                            SERVICE_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
+                            SERVICE_ERROR_NORMAL, DriverPath, NULL, NULL, NULL, NULL, NULL);
+
+    if (!*ServiceHandle)
+        error_goto(Error, cleanup);
+
+cleanup:
+    return Error;
+}
+
+/**
+ * @name KmtStartService
+ *
+ * Start the specified driver service by handle or name (and return a handle to it)
+ *
+ * @param ServiceName
+ *        If *ServiceHandle is NULL, name of the service to start
+ * @param ServiceHandle
+ *        Pointer to a variable containing the service handle,
+ *        or NULL (in which case it will be filled with a handle to the service)
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtStartService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    assert(ServiceHandle);
+    assert(ServiceName || *ServiceHandle);
+
+    if (!*ServiceHandle)
+        *ServiceHandle = OpenService(ScmHandle, ServiceName, SERVICE_ACCESS);
+
+    if (!*ServiceHandle)
+        error_goto(Error, cleanup);
+
+    if (!StartService(*ServiceHandle, 0, NULL))
+        error_goto(Error, cleanup);
+
+cleanup:
+    return Error;
+}
+
+/**
+ * @name KmtCreateAndStartService
+ *
+ * Create and start the specified driver service and return a handle to it
+ *
+ * @param ServiceName
+ *        Name of the service to create
+ * @param ServicePath
+ *        File name of the driver, relative to the current directory
+ * @param DisplayName
+ *        Service display name
+ * @param ServiceHandle
+ *        Pointer to a variable to receive the handle to the service
+ * @param RestartIfRunning
+ *        TRUE to stop and restart the service if it is already running
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtCreateAndStartService(
+    IN PCWSTR ServiceName,
+    IN PCWSTR ServicePath,
+    IN PCWSTR DisplayName OPTIONAL,
+    OUT SC_HANDLE *ServiceHandle,
+    IN BOOLEAN RestartIfRunning)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    assert(ServiceHandle);
+
+    Error = KmtCreateService(ServiceName, ServicePath, DisplayName, ServiceHandle);
+
+    if (Error && Error != ERROR_SERVICE_EXISTS)
+        goto cleanup;
+
+    Error = KmtStartService(ServiceName, ServiceHandle);
+
+    if (Error != ERROR_SERVICE_ALREADY_RUNNING)
+        goto cleanup;
+
+    Error = ERROR_SUCCESS;
+
+    if (!RestartIfRunning)
+        goto cleanup;
+
+    Error = KmtStopService(ServiceName, ServiceHandle);
+    if (Error)
+        goto cleanup;
+
+    Error = KmtStartService(ServiceName, ServiceHandle);
+    if (Error)
+        goto cleanup;
+
+cleanup:
+    assert(Error || *ServiceHandle);
+    return Error;
+}
+
+/**
+ * @name KmtStopService
+ *
+ * Stop the specified driver service by handle or name (and return a handle to it)
+ *
+ * @param ServiceName
+ *        If *ServiceHandle is NULL, name of the service to stop
+ * @param ServiceHandle
+ *        Pointer to a variable containing the service handle,
+ *        or NULL (in which case it will be filled with a handle to the service)
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtStopService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle)
+{
+    DWORD Error = ERROR_SUCCESS;
+    SERVICE_STATUS ServiceStatus;
+
+    assert(ServiceHandle);
+    assert(ServiceName || *ServiceHandle);
+
+    if (!*ServiceHandle)
+        *ServiceHandle = OpenService(ScmHandle, ServiceName, SERVICE_ACCESS);
+
+    if (!*ServiceHandle)
+        error_goto(Error, cleanup);
+
+    if (!ControlService(*ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus))
+        error_goto(Error, cleanup);
+
+cleanup:
+    return Error;
+}
+
+/**
+ * @name KmtDeleteService
+ *
+ * Delete the specified driver service by handle or name (and return a handle to it)
+ *
+ * @param ServiceName
+ *        If *ServiceHandle is NULL, name of the service to delete
+ * @param ServiceHandle
+ *        Pointer to a variable containing the service handle.
+ *        Will be set to NULL on success
+ *
+ * @return Win32 error code
+ */
+DWORD
+KmtDeleteService(
+    IN PCWSTR ServiceName OPTIONAL,
+    IN OUT SC_HANDLE *ServiceHandle)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    assert(ServiceHandle);
+    assert(ServiceName || *ServiceHandle);
+
+    if (!*ServiceHandle)
+        *ServiceHandle = OpenService(ScmHandle, ServiceName, SERVICE_ACCESS);
+
+    if (!*ServiceHandle)
+        error_goto(Error, cleanup);
+
+    if (!DeleteService(*ServiceHandle))
+        error_goto(Error, cleanup);
+
+    if (*ServiceHandle)
+        CloseServiceHandle(*ServiceHandle);
+
+cleanup:
+    return Error;
+}
+
+/**
+ * @name KmtCloseService
+ *
+ * Close the specified driver service handle
+ *
+ * @param ServiceHandle
+ *        Pointer to a variable containing the service handle.
+ *        Will be set to NULL on success
+ *
+ * @return Win32 error code
+ */
+DWORD KmtCloseService(
+    IN OUT SC_HANDLE *ServiceHandle)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    assert(ServiceHandle);
+
+    if (*ServiceHandle && !CloseServiceHandle(*ServiceHandle))
+        error_goto(Error, cleanup);
+
+    *ServiceHandle = NULL;
+
+cleanup:
+    return Error;
+}

Added: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c?rev=52519&view=auto
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c (added)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -1,0 +1,197 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Driver
+ * PROGRAMMER:      Thomas Faber <thfabba at gmx.de>
+ */
+
+#define UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <strsafe.h>
+
+#include "kmtest.h"
+#include <kmt_test.h>
+#include <kmt_public.h>
+
+/* pseudo-tests */
+START_TEST(Create)
+{
+    // nothing to do here. All tests start the service if needed
+}
+
+START_TEST(Delete)
+{
+    // TODO: delete kmtest service
+}
+
+START_TEST(Start)
+{
+    // nothing to do here. All tests start the service
+}
+
+START_TEST(Stop)
+{
+    // TODO: stop kmtest service
+}
+
+/* test support functions for special-purpose drivers */
+
+static WCHAR TestServiceName[MAX_PATH];
+static SC_HANDLE TestServiceHandle;
+static HANDLE TestDeviceHandle;
+
+/**
+ * @name KmtLoadDriver
+ *
+ * Load the specified special-purpose driver (create/start the service)
+ *
+ * @param ServiceName
+ *        Name of the driver service (Kmtest- prefix will be added automatically)
+ * @param RestartIfRunning
+ *        TRUE to stop and restart the service if it is already running
+ */
+VOID
+KmtLoadDriver(
+    IN PCWSTR ServiceName,
+    IN BOOLEAN RestartIfRunning)
+{
+    DWORD Error = ERROR_SUCCESS;
+    WCHAR ServicePath[MAX_PATH];
+
+    StringCbCopy(ServicePath, sizeof ServicePath, ServiceName);
+    StringCbCat(ServicePath, sizeof ServicePath, L"_drv.sys");
+
+    StringCbCopy(TestServiceName, sizeof TestServiceName, L"Kmtest-");
+    StringCbCat(TestServiceName, sizeof TestServiceName, ServiceName);
+
+    Error = KmtCreateAndStartService(TestServiceName, ServicePath, NULL, &TestServiceHandle, RestartIfRunning);
+
+    if (Error)
+    {
+        // TODO
+        __debugbreak();
+    }
+}
+
+/**
+ * @name KmtUnloadDriver
+ *
+ * Unload special-purpose driver (stop the service)
+ */
+VOID
+KmtUnloadDriver(VOID)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    Error = KmtStopService(TestServiceName, &TestServiceHandle);
+
+    if (Error)
+    {
+        // TODO
+        __debugbreak();
+    }
+}
+
+/**
+ * @name KmtOpenDriver
+ *
+ * Open special-purpose driver (acquire a device handle)
+ */
+VOID
+KmtOpenDriver(VOID)
+{
+    DWORD Error = ERROR_SUCCESS;
+    WCHAR DevicePath[MAX_PATH];
+
+    StringCbCopy(DevicePath, sizeof DevicePath, L"\\\\.\\Global\\GLOBALROOT\\Device\\");
+    StringCbCat(DevicePath, sizeof DevicePath, TestServiceName);
+
+    TestDeviceHandle = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+    if (TestDeviceHandle == INVALID_HANDLE_VALUE)
+        error(Error);
+
+    if (Error)
+    {
+        // TODO
+        __debugbreak();
+    }
+
+}
+
+/**
+ * @name KmtCloseDriver
+ *
+ * Close special-purpose driver (close device handle)
+ */
+VOID
+KmtCloseDriver(VOID)
+{
+    DWORD Error = ERROR_SUCCESS;
+
+    if (TestDeviceHandle && !CloseHandle(TestDeviceHandle))
+        error(Error);
+
+    if (Error)
+    {
+        // TODO
+        __debugbreak();
+    }
+}
+
+/* TODO: check if these will be useful */
+
+/**
+ * @name KmtSendToDriver
+ *
+ * Unload special-purpose driver (stop the service)
+ *
+ * @param ControlCode
+ *
+ * @return Win32 error code as returned by DeviceIoControl
+ */
+DWORD
+KmtSendToDriver(
+    IN DWORD ControlCode)
+{
+    // TODO
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/**
+ * @name KmtSendStringToDriver
+ *
+ * Unload special-purpose driver (stop the service)
+ *
+ * @param ControlCode
+ * @param String
+ *
+ * @return Win32 error code as returned by DeviceIoControl
+ */
+DWORD
+KmtSendStringToDriver(
+    IN DWORD ControlCode,
+    IN PCSTR String)
+{
+    // TODO
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/**
+ * @name KmtSendBufferToDriver
+ *
+ * @param ControlCode
+ * @param Buffer
+ * @param Length
+ *
+ * @return Win32 error code as returned by DeviceIoControl
+ */
+DWORD
+KmtSendBufferToDriver(
+    IN DWORD ControlCode,
+    IN OUT PVOID Buffer,
+    IN DWORD Length)
+{
+    // TODO
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}

Propchange: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/support.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c?rev=52519&view=auto
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c (added)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c [iso-8859-1] Sun Jul  3 18:53:26 2011
@@ -1,0 +1,26 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite user-mode test list
+ * PROGRAMMER:      Thomas Faber <thfabba at gmx.de>
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define UNICODE
+#include <windows.h>
+#include <kmt_test.h>
+
+VOID Test_Create(VOID);
+VOID Test_Delete(VOID);
+VOID Test_Start(VOID);
+VOID Test_Stop(VOID);
+
+/* tests with a leading '-' will not be listed */
+const KMT_TEST TestList[] =
+{
+    { "-create",            Test_Create },
+    { "-delete",            Test_Delete },
+    { "-start",             Test_Start },
+    { "-stop",              Test_Stop, },
+    { NULL,                 NULL },
+};

Propchange: branches/GSoC_2011/KMTestSuite/kmtests/kmtest/testlist.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list