2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: File system mini-filter support routines
5 * PROGRAMMER: Ged Murphy <gedmurphy@reactos.org>
10 #define KMT_FLT_USER_MODE
12 #include <kmt_public.h>
18 * We need to call the internal function in the service.c file
22 IN PCWSTR ServiceName
,
23 IN PCWSTR ServicePath
,
24 IN PCWSTR DisplayName OPTIONAL
,
26 OUT SC_HANDLE
*ServiceHandle
);
28 DWORD
EnablePrivilegeInCurrentProcess(
29 _In_z_ LPWSTR lpPrivName
,
32 // move to a shared location
33 typedef struct _KMTFLT_MESSAGE_HEADER
39 } KMTFLT_MESSAGE_HEADER
, *PKMTFLT_MESSAGE_HEADER
;
41 extern HANDLE KmtestHandle
;
42 static WCHAR TestServiceName
[MAX_PATH
];
47 * @name KmtFltCreateService
49 * Create the specified driver service and return a handle to it
52 * Name of the service to create
54 * File name of the driver, relative to the current directory
56 * Service display name
57 * @param ServiceHandle
58 * Pointer to a variable to receive the handle to the service
60 * @return Win32 error code
64 _In_z_ PCWSTR ServiceName
,
65 _In_z_ PCWSTR DisplayName
,
66 _Out_ SC_HANDLE
*ServiceHandle
)
68 WCHAR ServicePath
[MAX_PATH
];
70 StringCbCopy(ServicePath
, sizeof ServicePath
, ServiceName
);
71 StringCbCat(ServicePath
, sizeof ServicePath
, L
"_drv.sys");
73 StringCbCopy(TestServiceName
, sizeof TestServiceName
, L
"Kmtest-");
74 StringCbCat(TestServiceName
, sizeof TestServiceName
, ServiceName
);
76 return KmtpCreateService(TestServiceName
,
79 SERVICE_FILE_SYSTEM_DRIVER
,
84 * @name KmtFltDeleteService
86 * Delete the specified filter driver
89 * If *ServiceHandle is NULL, name of the service to delete
90 * @param ServiceHandle
91 * Pointer to a variable containing the service handle.
92 * Will be set to NULL on success
94 * @return Win32 error code
98 _In_opt_z_ PCWSTR ServiceName
,
99 _Inout_ SC_HANDLE
*ServiceHandle
)
101 return KmtDeleteService(ServiceName
, ServiceHandle
);
105 * @name KmtFltLoadDriver
107 * Delete the specified filter driver
109 * @return Win32 error code
113 _In_ BOOLEAN EnableDriverLoadPrivlege
,
114 _In_ BOOLEAN RestartIfRunning
,
115 _In_ BOOLEAN ConnectComms
,
121 if (EnableDriverLoadPrivlege
)
123 Error
= EnablePrivilegeInCurrentProcess(SE_LOAD_DRIVER_NAME
, TRUE
);
130 Error
= KmtFltLoad(TestServiceName
);
131 if ((Error
== ERROR_SERVICE_ALREADY_RUNNING
) && RestartIfRunning
)
133 Error
= KmtFltUnload(TestServiceName
);
140 Error
= KmtFltLoad(TestServiceName
);
150 Error
= KmtFltConnectComms(hPort
);
157 * @name KmtFltUnloadDriver
159 * Unload the specified filter driver
162 * Handle to the filter's comms port
163 * @param DisonnectComms
164 * TRUE to disconnect the comms connection before unloading
166 * @return Win32 error code
171 _In_ BOOLEAN DisonnectComms
)
173 DWORD Error
= ERROR_SUCCESS
;
177 Error
= KmtFltDisconnect(hPort
);
185 Error
= KmtFltUnload(TestServiceName
);
197 * @name KmtFltConnectComms
199 * Create a comms connection to the specified filter
202 * Handle to the filter's comms port
204 * @return Win32 error code
210 return KmtFltConnect(TestServiceName
, hPort
);
214 * @name KmtFltDisconnectComms
216 * Disconenct from the comms port
219 * Handle to the filter's comms port
221 * @return Win32 error code
224 KmtFltDisconnectComms(
227 return KmtFltDisconnect(hPort
);
232 * @name KmtFltCloseService
234 * Close the specified driver service handle
236 * @param ServiceHandle
237 * Pointer to a variable containing the service handle.
238 * Will be set to NULL on success
240 * @return Win32 error code
242 DWORD
KmtFltCloseService(
243 _Inout_ SC_HANDLE
*ServiceHandle
)
245 return KmtCloseService(ServiceHandle
);
249 * @name KmtFltRunKernelTest
251 * Run the specified filter test part
254 * Handle to the filter's comms port
256 * Name of the test to run
258 * @return Win32 error code
263 _In_z_ PCSTR TestName
)
265 return KmtFltSendStringToDriver(hPort
, KMTFLT_RUN_TEST
, TestName
);
269 * @name KmtFltSendToDriver
271 * Send an I/O control message with no arguments to the driver opened with KmtOpenDriver
274 * Handle to the filter's comms port
276 * The message to send to the filter
278 * @return Win32 error code
286 return KmtFltSendBufferToDriver(hPort
, Message
, NULL
, 0, NULL
, 0, NULL
);
290 * @name KmtFltSendStringToDriver
292 * Send an I/O control message with a string argument to the driver opened with KmtOpenDriver
296 * Handle to the filter's comms port
298 * The message associated with the string
300 * An ANSI string to send to the filter
302 * @return Win32 error code
305 KmtFltSendStringToDriver(
312 return KmtFltSendBufferToDriver(hPort
, Message
, (PVOID
)String
, (DWORD
)strlen(String
), NULL
, 0, NULL
);
316 * @name KmtFltSendWStringToDriver
318 * Send an I/O control message with a wide string argument to the driver opened with KmtOpenDriver
321 * Handle to the filter's comms port
323 * The message associated with the string
325 * An wide string to send to the filter
327 * @return Win32 error code
330 KmtFltSendWStringToDriver(
335 return KmtFltSendBufferToDriver(hPort
, Message
, (PVOID
)String
, (DWORD
)wcslen(String
) * sizeof(WCHAR
), NULL
, 0, NULL
);
339 * @name KmtFltSendUlongToDriver
341 * Send an I/O control message with an integer argument to the driver opened with KmtOpenDriver
344 * Handle to the filter's comms port
346 * The message associated with the value
348 * An 32bit valueng to send to the filter
350 * @return Win32 error code
353 KmtFltSendUlongToDriver(
358 return KmtFltSendBufferToDriver(hPort
, Message
, &Value
, sizeof(Value
), NULL
, 0, NULL
);
362 * @name KmtSendBufferToDriver
364 * Send an I/O control message with the specified arguments to the driver opened with KmtOpenDriver
367 * Handle to the filter's comms port
369 * The message associated with the value
371 * Pointer to a buffer to send to the filter
373 * Size of the buffer pointed to by InBuffer
375 * Pointer to a buffer to receive a response from the filter
376 * @param OutBufferSize
377 * Size of the buffer pointed to by OutBuffer
378 * @param BytesReturned
379 * Number of bytes written in the reply buffer
381 * @return Win32 error code
384 KmtFltSendBufferToDriver(
387 _In_reads_bytes_(BufferSize
) LPVOID InBuffer
,
388 _In_ DWORD BufferSize
,
389 _Out_writes_bytes_to_opt_(OutBufferSize
, *BytesReturned
) LPVOID OutBuffer
,
390 _In_ DWORD OutBufferSize
,
391 _Out_opt_ LPDWORD BytesReturned
)
393 PKMTFLT_MESSAGE_HEADER Ptr
;
394 KMTFLT_MESSAGE_HEADER Header
;
395 BOOLEAN FreeMemory
= FALSE
;
405 InBufferSize
= sizeof(KMTFLT_MESSAGE_HEADER
) + BufferSize
;
406 Ptr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, InBufferSize
);
409 return ERROR_NOT_ENOUGH_MEMORY
;
415 InBufferSize
= sizeof(KMTFLT_MESSAGE_HEADER
);
419 Ptr
->Message
= Message
;
422 Ptr
->Buffer
= (Ptr
+ 1);
423 StringCbCopy(Ptr
->Buffer
, BufferSize
, InBuffer
);
424 Ptr
->BufferSize
= BufferSize
;
427 Error
= KmtFltSendMessage(hPort
, Ptr
, InBufferSize
, OutBuffer
, OutBufferSize
, BytesReturned
);
431 HeapFree(GetProcessHeap(), 0, Ptr
);
438 * @name KmtFltAddAltitude
440 * Sets up the mini-filter altitude data in the registry
443 * The altitude string to set
445 * @return Win32 error code
449 _In_z_ LPWSTR Altitude
)
451 WCHAR DefaultInstance
[128];
458 StringCbCopy(KeyPath
, sizeof KeyPath
, L
"SYSTEM\\CurrentControlSet\\Services\\");
459 StringCbCat(KeyPath
, sizeof KeyPath
, TestServiceName
);
460 StringCbCat(KeyPath
, sizeof KeyPath
, L
"\\Instances\\");
462 Error
= RegCreateKeyEx(HKEY_LOCAL_MACHINE
,
466 REG_OPTION_NON_VOLATILE
,
467 KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
,
471 if (Error
!= ERROR_SUCCESS
)
476 StringCbCopy(DefaultInstance
, sizeof DefaultInstance
, TestServiceName
);
477 StringCbCat(DefaultInstance
, sizeof DefaultInstance
, L
" Instance");
479 Error
= RegSetValueExW(hKey
,
483 (LPBYTE
)DefaultInstance
,
484 (wcslen(DefaultInstance
) + 1) * sizeof(WCHAR
));
485 if (Error
!= ERROR_SUCCESS
)
490 Error
= RegCreateKeyW(hKey
, DefaultInstance
, &hSubKey
);
491 if (Error
!= ERROR_SUCCESS
)
496 Error
= RegSetValueExW(hSubKey
,
501 (wcslen(Altitude
) + 1) * sizeof(WCHAR
));
502 if (Error
!= ERROR_SUCCESS
)
507 Error
= RegSetValueExW(hSubKey
,
517 RegCloseKey(hSubKey
);
529 * Private functions, not meant for use in kmtests
532 DWORD
EnablePrivilege(
534 _In_z_ LPWSTR lpPrivName
,
537 TOKEN_PRIVILEGES TokenPrivileges
;
540 DWORD dwError
= ERROR_SUCCESS
;
542 /* Get the luid for this privilege */
543 if (!LookupPrivilegeValueW(NULL
, lpPrivName
, &luid
))
544 return GetLastError();
546 /* Setup the struct with the priv info */
547 TokenPrivileges
.PrivilegeCount
= 1;
548 TokenPrivileges
.Privileges
[0].Luid
= luid
;
549 TokenPrivileges
.Privileges
[0].Attributes
= bEnable
? SE_PRIVILEGE_ENABLED
: 0;
551 /* Enable the privilege info in the token */
552 bSuccess
= AdjustTokenPrivileges(hToken
,
555 sizeof(TOKEN_PRIVILEGES
),
558 if (bSuccess
== FALSE
) dwError
= GetLastError();
564 DWORD
EnablePrivilegeInCurrentProcess(
565 _In_z_ LPWSTR lpPrivName
,
570 DWORD dwError
= ERROR_SUCCESS
;
572 /* Get a handle to our token */
573 bSuccess
= OpenProcessToken(GetCurrentProcess(),
574 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
576 if (bSuccess
== FALSE
) return GetLastError();
578 /* Enable the privilege in the agent token */
579 dwError
= EnablePrivilege(hToken
, lpPrivName
, bEnable
);
581 /* We're done with this now */