[KMTESTS]
[reactos.git] / kmtests / kmtest / support.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Driver
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
6 */
7
8 #define UNICODE
9 #define WIN32_LEAN_AND_MEAN
10 #include <windows.h>
11 #include <strsafe.h>
12 #include <winioctl.h>
13
14 #include <assert.h>
15
16 #include "kmtest.h"
17 #include <kmt_public.h>
18 #include <kmt_test.h>
19
20 /* pseudo-tests */
21 START_TEST(Create)
22 {
23 // nothing to do here. All tests create the service if needed
24 }
25
26 START_TEST(Delete)
27 {
28 SC_HANDLE Handle = NULL;
29 DWORD Error = KmtDeleteService(L"Kmtest", &Handle);
30
31 ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
32 }
33
34 START_TEST(Start)
35 {
36 // nothing to do here. All tests start the service
37 }
38
39 START_TEST(Stop)
40 {
41 // TODO: requiring the service to be started for this is... bad,
42 // especially when it's marked for deletion and won't start ;)
43 SC_HANDLE Handle = NULL;
44 DWORD Error = KmtStopService(L"Kmtest", &Handle);
45
46 ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
47 Error = KmtCloseService(&Handle);
48 ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
49 }
50
51 /* test support functions for special-purpose drivers */
52
53 extern HANDLE KmtestHandle;
54
55 /**
56 * @name KmtRunKernelTest
57 *
58 * Run the specified kernel-mode test part
59 *
60 * @param TestName
61 * Name of the test to run
62 *
63 * @return Win32 error code as returned by DeviceIoControl
64 */
65 DWORD
66 KmtRunKernelTest(
67 IN PCSTR TestName)
68 {
69 DWORD Error = ERROR_SUCCESS;
70 DWORD BytesRead;
71
72 if (!DeviceIoControl(KmtestHandle, IOCTL_KMTEST_RUN_TEST, (PVOID)TestName, strlen(TestName), NULL, 0, &BytesRead, NULL))
73 error(Error);
74
75 return Error;
76 }
77
78 static WCHAR TestServiceName[MAX_PATH];
79 static SC_HANDLE TestServiceHandle;
80 static HANDLE TestDeviceHandle;
81
82 /**
83 * @name KmtLoadDriver
84 *
85 * Load the specified special-purpose driver (create/start the service)
86 *
87 * @param ServiceName
88 * Name of the driver service (Kmtest- prefix will be added automatically)
89 * @param RestartIfRunning
90 * TRUE to stop and restart the service if it is already running
91 */
92 VOID
93 KmtLoadDriver(
94 IN PCWSTR ServiceName,
95 IN BOOLEAN RestartIfRunning)
96 {
97 DWORD Error = ERROR_SUCCESS;
98 WCHAR ServicePath[MAX_PATH];
99
100 StringCbCopy(ServicePath, sizeof ServicePath, ServiceName);
101 StringCbCat(ServicePath, sizeof ServicePath, L"_drv.sys");
102
103 StringCbCopy(TestServiceName, sizeof TestServiceName, L"Kmtest-");
104 StringCbCat(TestServiceName, sizeof TestServiceName, ServiceName);
105
106 Error = KmtCreateAndStartService(TestServiceName, ServicePath, NULL, &TestServiceHandle, RestartIfRunning);
107
108 if (Error)
109 {
110 // TODO
111 __debugbreak();
112 }
113 }
114
115 /**
116 * @name KmtUnloadDriver
117 *
118 * Unload special-purpose driver (stop the service)
119 */
120 VOID
121 KmtUnloadDriver(VOID)
122 {
123 DWORD Error = ERROR_SUCCESS;
124
125 Error = KmtStopService(TestServiceName, &TestServiceHandle);
126
127 if (Error)
128 {
129 // TODO
130 __debugbreak();
131 }
132 }
133
134 /**
135 * @name KmtOpenDriver
136 *
137 * Open special-purpose driver (acquire a device handle)
138 */
139 VOID
140 KmtOpenDriver(VOID)
141 {
142 DWORD Error = ERROR_SUCCESS;
143 WCHAR DevicePath[MAX_PATH];
144
145 StringCbCopy(DevicePath, sizeof DevicePath, L"\\\\.\\Global\\GLOBALROOT\\Device\\");
146 StringCbCat(DevicePath, sizeof DevicePath, TestServiceName);
147
148 TestDeviceHandle = CreateFile(DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
149 if (TestDeviceHandle == INVALID_HANDLE_VALUE)
150 error(Error);
151
152 if (Error)
153 {
154 // TODO
155 __debugbreak();
156 }
157
158 }
159
160 /**
161 * @name KmtCloseDriver
162 *
163 * Close special-purpose driver (close device handle)
164 */
165 VOID
166 KmtCloseDriver(VOID)
167 {
168 DWORD Error = ERROR_SUCCESS;
169
170 if (TestDeviceHandle && !CloseHandle(TestDeviceHandle))
171 error(Error);
172
173 if (Error)
174 {
175 // TODO
176 __debugbreak();
177 }
178 }
179
180 /**
181 * @name KmtSendToDriver
182 *
183 * Unload special-purpose driver (stop the service)
184 *
185 * @param ControlCode
186 *
187 * @return Win32 error code as returned by DeviceIoControl
188 */
189 DWORD
190 KmtSendToDriver(
191 IN DWORD ControlCode)
192 {
193 DWORD BytesRead;
194
195 if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), NULL, 0, NULL, 0, &BytesRead, NULL))
196 return GetLastError();
197
198 return ERROR_SUCCESS;
199 }
200
201 /**
202 * @name KmtSendStringToDriver
203 *
204 * Unload special-purpose driver (stop the service)
205 *
206 * @param ControlCode
207 * @param String
208 *
209 * @return Win32 error code as returned by DeviceIoControl
210 */
211 DWORD
212 KmtSendStringToDriver(
213 IN DWORD ControlCode,
214 IN PCSTR String)
215 {
216 DWORD BytesRead;
217
218 if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), (PVOID)String, strlen(String), NULL, 0, &BytesRead, NULL))
219 return GetLastError();
220
221 return ERROR_SUCCESS;
222 }
223
224 /**
225 * @name KmtSendBufferToDriver
226 *
227 * @param ControlCode
228 * @param Buffer
229 * @param Length
230 *
231 * @return Win32 error code as returned by DeviceIoControl
232 */
233 DWORD
234 KmtSendBufferToDriver(
235 IN DWORD ControlCode,
236 IN OUT PVOID Buffer,
237 IN OUT PDWORD Length)
238 {
239 assert(Length);
240
241 if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), Buffer, *Length, NULL, 0, Length, NULL))
242 return GetLastError();
243
244 return ERROR_SUCCESS;
245 }