diff --git a/modules/rostests/kmtests/CMakeLists.txt b/modules/rostests/kmtests/CMakeLists.txt index d51ef000c77..64b088d2210 100644 --- a/modules/rostests/kmtests/CMakeLists.txt +++ b/modules/rostests/kmtests/CMakeLists.txt @@ -119,6 +119,8 @@ add_target_include_directories(kmtest_printf ${REACTOS_SOURCE_DIR}/sdk/lib/crt/i # list(APPEND KMTEST_SOURCE + kmtest/filter.c + kmtest/fltsupport.c kmtest/kmtest.c kmtest/service.c kmtest/support.c @@ -143,8 +145,8 @@ list(APPEND KMTEST_SOURCE add_executable(kmtest ${KMTEST_SOURCE}) set_module_type(kmtest win32cui) target_link_libraries(kmtest ${PSEH_LIB}) -add_importlibs(kmtest advapi32 ws2_32 msvcrt kernel32 ntdll) -add_target_compile_definitions(kmtest KMT_USER_MODE) +add_importlibs(kmtest fltlib advapi32 ws2_32 msvcrt kernel32 ntdll) +add_target_compile_definitions(kmtest KMT_USER_MODE NTDDI_VERSION=NTDDI_WS03SP1) #add_pch(kmtest include/kmt_test.h) set_target_properties(kmtest PROPERTIES OUTPUT_NAME "kmtest_") #add_rostests_file(TARGET kmtest) diff --git a/modules/rostests/kmtests/include/kmt_platform.h b/modules/rostests/kmtests/include/kmt_platform.h index 9e732c397a9..636f099cf67 100644 --- a/modules/rostests/kmtests/include/kmt_platform.h +++ b/modules/rostests/kmtests/include/kmt_platform.h @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef KMT_EMULATE_KERNEL #define ok_irql(i) diff --git a/modules/rostests/kmtests/include/kmt_public.h b/modules/rostests/kmtests/include/kmt_public.h index 963ff3b8599..00442f4d3ed 100644 --- a/modules/rostests/kmtests/include/kmt_public.h +++ b/modules/rostests/kmtests/include/kmt_public.h @@ -23,6 +23,11 @@ #define IOCTL_KMTEST_USERMODE_AWAIT_REQ \ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_READ_DATA) + +#define KMTFLT_GET_TESTS 0x800 +#define KMTFLT_RUN_TEST 0x801 + + #define KMTEST_DEVICE_NAME L"Kmtest" #define KMTEST_DEVICE_DRIVER_PATH L"\\Device\\" KMTEST_DEVICE_NAME #define KMTEST_DEVICE_PATH L"\\\\.\\Global\\GLOBALROOT" KMTEST_DEVICE_DRIVER_PATH diff --git a/modules/rostests/kmtests/include/kmt_test.h b/modules/rostests/kmtests/include/kmt_test.h index 59416761404..8fcc93a4190 100644 --- a/modules/rostests/kmtests/include/kmt_test.h +++ b/modules/rostests/kmtests/include/kmt_test.h @@ -173,6 +173,16 @@ DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String); DWORD KmtSendWStringToDriver(IN DWORD ControlCode, IN PCWSTR String); DWORD KmtSendUlongToDriver(IN DWORD ControlCode, IN DWORD Value); DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, IN DWORD InLength, IN OUT PDWORD OutLength); + +DWORD KmtFltLoadDriver(_In_z_ PCWSTR ServiceName, _In_ BOOLEAN RestartIfRunning, _In_ BOOLEAN ConnectComms, _Out_ HANDLE *hPort); +DWORD KmtFltUnloadDriver(_In_ HANDLE *hPort, _In_ BOOLEAN DisonnectComms); +DWORD KmtFltRunKernelTest(_In_ HANDLE hPort, _In_z_ PCSTR TestName); +DWORD KmtFltSendToDriver(_In_ HANDLE hPort, _In_ DWORD Message); +DWORD KmtFltSendStringToDriver(_In_ HANDLE hPort, _In_ DWORD Message, _In_ PCSTR String); +DWORD KmtFltSendWStringToDriver(_In_ HANDLE hPort, _In_ DWORD Message, _In_ PCWSTR String); +DWORD KmtFltSendUlongToDriver(_In_ HANDLE hPort, _In_ DWORD Message, _In_ DWORD Value); +DWORD KmtFltSendBufferToDriver(_In_ HANDLE hPort, _In_ DWORD Message, _In_reads_bytes_(BufferSize) LPVOID Buffer, _In_ DWORD BufferSize, _Out_writes_bytes_to_opt_(dwOutBufferSize, *lpBytesReturned) LPVOID lpOutBuffer, _In_ DWORD dwOutBufferSize, _Out_opt_ LPDWORD lpBytesReturned); + #else /* if !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ #error either KMT_KERNEL_MODE or KMT_USER_MODE must be defined #endif /* !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ diff --git a/modules/rostests/kmtests/kmtest/filter.c b/modules/rostests/kmtests/kmtest/filter.c new file mode 100644 index 00000000000..cb5957477cd --- /dev/null +++ b/modules/rostests/kmtests/kmtest/filter.c @@ -0,0 +1,428 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: File system filter implementation of the original service.c file + * PROGRAMMER: Thomas Faber + * Ged Murphy + */ + +//#include +#include +#include "kmtest.h" + +#include + +#define SERVICE_ACCESS (SERVICE_START | SERVICE_STOP | DELETE) + +/* + * We need to call the internal function in the service.c file + */ +DWORD +KmtpCreateService( + IN PCWSTR ServiceName, + IN PCWSTR ServicePath, + IN PCWSTR DisplayName OPTIONAL, + IN DWORD ServiceType, + OUT SC_HANDLE *ServiceHandle); + +static SC_HANDLE ScmHandle; + + +/** + * @name KmtFltCreateService + * + * 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 +KmtFltCreateService( + _In_z_ PCWSTR ServiceName, + _In_z_ PCWSTR ServicePath, + _In_z_ PCWSTR DisplayName OPTIONAL, + _Out_ SC_HANDLE *ServiceHandle) +{ + return KmtpCreateService(ServiceName, + ServicePath, + DisplayName, + SERVICE_FILE_SYSTEM_DRIVER, + ServiceHandle); +} + +/** + * @name KmtFltLoad + * + * Start the specified filter driver by name + * + * @param ServiceName + * The name of the filter to start + * + * @return Win32 error code + */ +DWORD +KmtFltLoad( + _In_z_ PCWSTR ServiceName) +{ + HRESULT hResult; + DWORD Error = ERROR_SUCCESS; + + assert(ServiceName); + + hResult = FilterLoad(ServiceName); + Error = SCODE_CODE(hResult); + + return Error; +} + +/** + * @name KmtFltCreateAndStartService + * + * Create and load the specified filter driver 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 +KmtFltCreateAndStartService( + _In_z_ PCWSTR ServiceName, + _In_z_ PCWSTR ServicePath, + _In_z_ PCWSTR DisplayName OPTIONAL, + _Out_ SC_HANDLE *ServiceHandle, + _In_ BOOLEAN RestartIfRunning) +{ + DWORD Error = ERROR_SUCCESS; + + assert(ServiceHandle); + + Error = KmtFltCreateService(ServiceName, ServicePath, DisplayName, ServiceHandle); + + if (Error == ERROR_SERVICE_EXISTS) + *ServiceHandle = OpenService(ScmHandle, ServiceName, SERVICE_ACCESS); + + if (Error && Error != ERROR_SERVICE_EXISTS) + goto cleanup; + + Error = KmtFltLoad(ServiceName); + + if (Error != ERROR_SERVICE_ALREADY_RUNNING) + goto cleanup; + + Error = ERROR_SUCCESS; + + if (!RestartIfRunning) + goto cleanup; + + Error = KmtFltUnload(ServiceName); + if (Error) + goto cleanup; + + Error = KmtFltLoad(ServiceName); + if (Error) + goto cleanup; + +cleanup: + assert(Error); + return Error; +} + + +/** + * @name KmtFltConnect + * + * Create a comms connection to the specified filter + * + * @param ServiceName + * Name of the filter to connect to + * @param hPort + * Handle to the filter's comms port + * + * @return Win32 error code + */ +DWORD +KmtFltConnect( + _In_z_ PCWSTR ServiceName, + _Out_ HANDLE *hPort) +{ + HRESULT hResult; + DWORD Error = ERROR_SUCCESS; + + assert(ServiceName); + assert(hPort); + + hResult = FilterConnectCommunicationPort(ServiceName, + 0, + NULL, + 0, + NULL, + hPort); + Error = SCODE_CODE(hResult); + + return Error; +} + +/** + * @name KmtFltDisconnect + * + * Disconenct from the comms port + * + * @param hPort + * Handle to the filter's comms port + * + * @return Win32 error code + */ +DWORD +KmtFltDisconnect( + _Out_ HANDLE *hPort) +{ + DWORD Error = ERROR_SUCCESS; + + assert(hPort); + + if (!CloseHandle(hPort)) + { + Error = GetLastError(); + } + + return Error; +} + +/** + * @name KmtFltSendMessage + * + * Sneds a message to a filter driver + * + * @param hPort + * Handle to the filter's comms port + * @InBuffer + * Pointer to a buffer to send to the filter + * @InBufferSize + * Size of the buffer pointed to by InBuffer + * @OutBuffer + * Pointer to a buffer to receive reply data from the filter + * @OutBufferSize + * Size of the buffer pointed to by OutBuffer + * @BytesReturned + * Number of bytes written in the reply buffer + * + * @return Win32 error code + */ +DWORD +KmtFltSendMessage( + _In_ HANDLE hPort, + _In_reads_bytes_(dwInBufferSize) LPVOID InBuffer, + _In_ DWORD InBufferSize, + _Out_writes_bytes_to_opt_(dutBufferSize, *BytesReturned) LPVOID OutBuffer, + _In_ DWORD OutBufferSize, + _Out_opt_ LPDWORD BytesReturned) +{ + DWORD BytesRet; + HRESULT hResult; + DWORD Error; + + assert(hPort); + assert(InBuffer); + assert(InBufferSize); + + if (BytesReturned) *BytesReturned = 0; + + hResult = FilterSendMessage(hPort, + InBuffer, + InBufferSize, + OutBuffer, + OutBufferSize, + &BytesRet); + + Error = SCODE_CODE(hResult); + if (Error == ERROR_SUCCESS) + { + if (BytesRet) + { + *BytesReturned = BytesRet; + } + } + + return Error; +} + +/** + * @name KmtFltGetMessage + * + * Gets a message from a filter driver + * + * @param hPort + * Handle to the filter's comms port + * @MessageBuffer + * Pointer to a buffer to receive the data from the filter + * @MessageBufferSize + * Size of the buffer pointed to by MessageBuffer + * @Overlapped + * Pointer to an overlapped structure + * + * @return Win32 error code + */ +DWORD +KmtFltGetMessage( + _In_ HANDLE hPort, + _Out_writes_bytes_(MessageBufferSize) PFILTER_MESSAGE_HEADER MessageBuffer, + _In_ DWORD MessageBufferSize, + _In_opt_ LPOVERLAPPED Overlapped) +{ + HRESULT hResult; + DWORD Error; + + assert(hPort); + assert(MessageBuffer); + + hResult = FilterGetMessage(hPort, + MessageBuffer, + MessageBufferSize, + Overlapped); + Error = SCODE_CODE(hResult); + return Error; +} + +/** + * @name KmtFltReplyMessage + * + * Replies to a message from a filter driver + * + * @param hPort + * Handle to the filter's comms port + * @ReplyBuffer + * Pointer to a buffer to return to the filter + * @ReplyBufferSize + * Size of the buffer pointed to by ReplyBuffer + * + * @return Win32 error code + */ +DWORD +KmtFltReplyMessage( + _In_ HANDLE hPort, + _In_reads_bytes_(ReplyBufferSize) PFILTER_REPLY_HEADER ReplyBuffer, + _In_ DWORD ReplyBufferSize) +{ + HRESULT hResult; + DWORD Error; + + hResult = FilterReplyMessage(hPort, + ReplyBuffer, + ReplyBufferSize); + Error = SCODE_CODE(hResult); + return Error; +} + +/** +* @name KmtFltGetMessageResult +* +* Gets the overlapped result from the IO +* +* @param hPort +* Handle to the filter's comms port +* @Overlapped +* Pointer to the overlapped structure usdd in the IO +* @BytesTransferred +* Number of bytes transferred in the IO +* +* @return Win32 error code +*/ +DWORD +KmtFltGetMessageResult( + _In_ HANDLE hPort, + _In_ LPOVERLAPPED Overlapped, + _Out_ LPDWORD BytesTransferred) +{ + BOOL Success; + DWORD Error = ERROR_SUCCESS; + + *BytesTransferred = 0; + + Success = GetOverlappedResult(hPort, Overlapped, BytesTransferred, TRUE); + if (!Success) + { + Error = GetLastError(); + } + + return Error; +} + +/** + * @name KmtFltUnload + * + * Unload the specified filter driver + * + * @param ServiceName + * The name of the filter to unload + * + * @return Win32 error code + */ +DWORD +KmtFltUnload( + _In_z_ PCWSTR ServiceName) +{ + HRESULT hResult; + DWORD Error = ERROR_SUCCESS; + + assert(ServiceName); + + hResult = FilterUnload(ServiceName); + Error = SCODE_CODE(hResult); + + return Error; +} + +/** + * @name KmtFltDeleteService + * + * Delete the specified filter driver + * + * @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 +KmtFltDeleteService( + _In_z_ PCWSTR ServiceName OPTIONAL, + _Inout_ SC_HANDLE *ServiceHandle) +{ + return KmtDeleteService(ServiceName, ServiceHandle); +} + +/** + * @name KmtFltCloseService + * + * 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 KmtFltCloseService( + _Inout_ SC_HANDLE *ServiceHandle) +{ + return KmtCloseService(ServiceHandle); +} diff --git a/modules/rostests/kmtests/kmtest/fltsupport.c b/modules/rostests/kmtests/kmtest/fltsupport.c new file mode 100644 index 00000000000..772e98a211c --- /dev/null +++ b/modules/rostests/kmtests/kmtest/fltsupport.c @@ -0,0 +1,301 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: File system mini-filter support routines + * PROGRAMMER: Ged Murphy + */ + +#include + +#include "kmtest.h" +#include + +#include +#include + +// move to a shared location +typedef struct _KMTFLT_MESSAGE_HEADER +{ + ULONG Message; + PVOID Buffer; + ULONG BufferSize; + +} KMTFLT_MESSAGE_HEADER, *PKMTFLT_MESSAGE_HEADER; + +extern HANDLE KmtestHandle; +static WCHAR TestServiceName[MAX_PATH]; + + +/** + * @name KmtFltLoadDriver + * + * Load the specified filter driver + * This routine will create the service entry if it doesn't already exist + * + * @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 + * @param ConnectComms + * TRUE to create a comms connection to the specified filter + * @param hPort + * Handle to the filter's comms port + * + * @return Win32 error code + */ +DWORD +KmtFltLoadDriver( + _In_z_ PCWSTR ServiceName, + _In_ BOOLEAN RestartIfRunning, + _In_ BOOLEAN ConnectComms, + _Out_ HANDLE *hPort) +{ + DWORD Error = ERROR_SUCCESS; + WCHAR ServicePath[MAX_PATH]; + SC_HANDLE TestServiceHandle; + + StringCbCopy(ServicePath, sizeof ServicePath, ServiceName); + StringCbCat(ServicePath, sizeof ServicePath, L"_drv.sys"); + + StringCbCopy(TestServiceName, sizeof TestServiceName, L"Kmtest-"); + StringCbCat(TestServiceName, sizeof TestServiceName, ServiceName); + + Error = KmtFltCreateAndStartService(TestServiceName, ServicePath, NULL, &TestServiceHandle, TRUE); + + if (Error == ERROR_SUCCESS && ConnectComms) + { + Error = KmtFltConnect(ServiceName, hPort); + } + + return Error; +} + +/** + * @name KmtFltUnloadDriver + * + * Unload the specified filter driver + * + * @param hPort + * Handle to the filter's comms port + * @param ConnectComms + * TRUE to disconnect the comms connection before unloading + * + * @return Win32 error code + */ +DWORD +KmtFltUnloadDriver( + _In_ HANDLE *hPort, + _In_ BOOLEAN DisonnectComms) +{ + DWORD Error = ERROR_SUCCESS; + + if (DisonnectComms) + { + Error = KmtFltDisconnect(hPort); + + if (Error) + { + return Error; + } + } + + Error = KmtFltUnload(TestServiceName); + + if (Error) + { + // TODO + __debugbreak(); + } + + return Error; +} + + +/** +* @name KmtFltRunKernelTest +* +* Run the specified filter test part +* +* @param hPort +* Handle to the filter's comms port +* @param TestName +* Name of the test to run +* +* @return Win32 error code +*/ +DWORD +KmtFltRunKernelTest( + _In_ HANDLE hPort, + _In_z_ PCSTR TestName) +{ + return KmtFltSendStringToDriver(hPort, KMTFLT_RUN_TEST, TestName); +} + +/** +* @name KmtFltSendToDriver +* +* Send an I/O control message with no arguments to the driver opened with KmtOpenDriver +* +* @param hPort +* Handle to the filter's comms port +* @param Message +* The message to send to the filter +* +* @return Win32 error code as returned by DeviceIoControl +*/ +DWORD +KmtFltSendToDriver( + _In_ HANDLE hPort, + _In_ DWORD Message) +{ + assert(hPort); + return KmtFltSendBufferToDriver(hPort, Message, NULL, 0, NULL, 0, NULL); +} + +/** + * @name KmtFltSendStringToDriver + * + * Send an I/O control message with a string argument to the driver opened with KmtOpenDriver + * + * + * @param hPort + * Handle to the filter's comms port + * @param Message + * The message associated with the string + * @param String + * An ANSI string to send to the filter + * + * @return Win32 error code as returned by DeviceIoControl + */ +DWORD +KmtFltSendStringToDriver( + _In_ HANDLE hPort, + _In_ DWORD Message, + _In_ PCSTR String) +{ + assert(hPort); + assert(String); + return KmtFltSendBufferToDriver(hPort, Message, (PVOID)String, (DWORD)strlen(String), NULL, 0, NULL); +} + +/** + * @name KmtFltSendWStringToDriver + * + * Send an I/O control message with a wide string argument to the driver opened with KmtOpenDriver + * + * @param hPort + * Handle to the filter's comms port + * @param Message + * The message associated with the string + * @param String + * An wide string to send to the filter + * + * @return Win32 error code as returned by DeviceIoControl + */ +DWORD +KmtFltSendWStringToDriver( + _In_ HANDLE hPort, + _In_ DWORD Message, + _In_ PCWSTR String) +{ + return KmtFltSendBufferToDriver(hPort, Message, (PVOID)String, (DWORD)wcslen(String) * sizeof(WCHAR), NULL, 0, NULL); +} + +/** + * @name KmtFltSendUlongToDriver + * + * Send an I/O control message with an integer argument to the driver opened with KmtOpenDriver + * + * @param hPort + * Handle to the filter's comms port + * @param Message + * The message associated with the value + * @param Value + * An 32bit valueng to send to the filter + * + * @return Win32 error code as returned by DeviceIoControl + */ +DWORD +KmtFltSendUlongToDriver( + _In_ HANDLE hPort, + _In_ DWORD Message, + _In_ DWORD Value) +{ + return KmtFltSendBufferToDriver(hPort, Message, &Value, sizeof(Value), NULL, 0, NULL); +} + +/** + * @name KmtSendBufferToDriver + * + * Send an I/O control message with the specified arguments to the driver opened with KmtOpenDriver + * + * @param hPort + * Handle to the filter's comms port + * @param Message + * The message associated with the value + * @param InBuffer + * Pointer to a buffer to send to the filter + * @param BufferSize + * Size of the buffer pointed to by InBuffer + * @param OutBuffer + * Pointer to a buffer to receive a response from the filter + * @param OutBufferSize + * Size of the buffer pointed to by OutBuffer + * @param BytesReturned + * Number of bytes written in the reply buffer + * + * @return Win32 error code as returned by DeviceIoControl + */ +DWORD +KmtFltSendBufferToDriver( + _In_ HANDLE hPort, + _In_ DWORD Message, + _In_reads_bytes_(BufferSize) LPVOID InBuffer, + _In_ DWORD BufferSize, + _Out_writes_bytes_to_opt_(OutBufferSize, *BytesReturned) LPVOID OutBuffer, + _In_ DWORD OutBufferSize, + _Out_opt_ LPDWORD BytesReturned) +{ + PKMTFLT_MESSAGE_HEADER Ptr; + KMTFLT_MESSAGE_HEADER Header; + BOOLEAN FreeMemory = FALSE; + DWORD InBufferSize; + DWORD Error; + + assert(hPort); + + if (BufferSize) + { + assert(InBuffer); + + InBufferSize = sizeof(KMTFLT_MESSAGE_HEADER) + BufferSize; + Ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, InBufferSize); + if (!Ptr) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + FreeMemory = TRUE; + } + else + { + InBufferSize = sizeof(KMTFLT_MESSAGE_HEADER); + Ptr = &Header; + } + + Ptr->Message = Message; + if (BufferSize) + { + Ptr->Buffer = (Ptr + 1); + StringCbCopy(Ptr->Buffer, BufferSize, InBuffer); + Ptr->BufferSize = BufferSize; + } + + Error = KmtFltSendMessage(hPort, Ptr, InBufferSize, OutBuffer, OutBufferSize, BytesReturned); + + if (FreeMemory) + { + HeapFree(GetProcessHeap(), 0, Ptr); + } + + return Error; +} diff --git a/modules/rostests/kmtests/kmtest/kmtest.h b/modules/rostests/kmtests/kmtest/kmtest.h index 4f9709245f3..7329d18e485 100644 --- a/modules/rostests/kmtests/kmtest/kmtest.h +++ b/modules/rostests/kmtests/kmtest/kmtest.h @@ -60,5 +60,76 @@ KmtDeleteService( DWORD KmtCloseService( IN OUT SC_HANDLE *ServiceHandle); + + +/* FS Filter management functions */ + +DWORD +KmtFltCreateService( + _In_z_ PCWSTR ServiceName, + _In_z_ PCWSTR ServicePath, + _In_z_ PCWSTR DisplayName OPTIONAL, + _Out_ SC_HANDLE *ServiceHandle); + +DWORD +KmtFltLoad( + _In_z_ PCWSTR ServiceName); + +DWORD +KmtFltCreateAndStartService( + _In_z_ PCWSTR ServiceName, + _In_z_ PCWSTR ServicePath, + _In_z_ PCWSTR DisplayName OPTIONAL, + _Out_ SC_HANDLE *ServiceHandle, + _In_ BOOLEAN RestartIfRunning); + +DWORD +KmtFltConnect( + _In_z_ PCWSTR ServiceName, + _Out_ HANDLE *hPort); + +DWORD +KmtFltDisconnect( + _Out_ HANDLE *hPort); + +DWORD +KmtFltSendMessage( + _In_ HANDLE hPort, + _In_reads_bytes_(dwInBufferSize) LPVOID lpInBuffer, + _In_ DWORD dwInBufferSize, + _Out_writes_bytes_to_opt_(dwOutBufferSize, *lpBytesReturned) LPVOID lpOutBuffer, + _In_ DWORD dwOutBufferSize, + _Out_opt_ LPDWORD lpBytesReturned); + +DWORD +KmtFltGetMessage( + _In_ HANDLE hPort, + _Out_writes_bytes_(dwMessageBufferSize) PFILTER_MESSAGE_HEADER lpMessageBuffer, + _In_ DWORD dwMessageBufferSize, + _In_opt_ LPOVERLAPPED Overlapped); + +DWORD +KmtFltReplyMessage( + _In_ HANDLE hPort, + _In_reads_bytes_(dwReplyBufferSize) PFILTER_REPLY_HEADER lpReplyBuffer, + _In_ DWORD dwReplyBufferSize); + +DWORD +KmtFltGetMessageResult( + _In_ HANDLE hPort, + _In_ LPOVERLAPPED Overlapped, + _Out_ LPDWORD BytesTransferred); + +DWORD +KmtFltUnload( + _In_z_ PCWSTR ServiceName); + +DWORD +KmtFltDeleteService( + _In_z_ PCWSTR ServiceName OPTIONAL, + _Inout_ SC_HANDLE *ServiceHandle); + +DWORD KmtFltCloseService( + _Inout_ SC_HANDLE *ServiceHandle); #endif /* !defined _KMTESTS_H_ */ diff --git a/modules/rostests/kmtests/kmtest/service.c b/modules/rostests/kmtests/kmtest/service.c index 9fa8785f488..3f617fc302d 100644 --- a/modules/rostests/kmtests/kmtest/service.c +++ b/modules/rostests/kmtests/kmtest/service.c @@ -12,6 +12,19 @@ #define SERVICE_ACCESS (SERVICE_START | SERVICE_STOP | DELETE) +/* + * This is an internal function not meant for use by the kmtests app, + * so we declare it here instead of kmtest.h + */ +DWORD +KmtpCreateService( + IN PCWSTR ServiceName, + IN PCWSTR ServicePath, + IN PCWSTR DisplayName OPTIONAL, + IN DWORD ServiceType, + OUT SC_HANDLE *ServiceHandle); + + static SC_HANDLE ScmHandle; /** @@ -80,35 +93,11 @@ KmtCreateService( IN PCWSTR DisplayName OPTIONAL, OUT SC_HANDLE *ServiceHandle) { - DWORD Error = ERROR_SUCCESS; - WCHAR DriverPath[MAX_PATH]; - HRESULT result = S_OK; - - assert(ServiceHandle); - assert(ServiceName && ServicePath); - - if (!GetModuleFileName(NULL, DriverPath, sizeof DriverPath / sizeof DriverPath[0])) - error_goto(Error, cleanup); - - assert(wcsrchr(DriverPath, L'\\') != NULL); - wcsrchr(DriverPath, L'\\')[1] = L'\0'; - - result = StringCbCat(DriverPath, sizeof DriverPath, ServicePath); - if (FAILED(result)) - error_value_goto(Error, result, cleanup); - - if (GetFileAttributes(DriverPath) == INVALID_FILE_ATTRIBUTES) - error_goto(Error, 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; + return KmtpCreateService(ServiceName, + ServicePath, + DisplayName, + SERVICE_KERNEL_DRIVER, + ServiceHandle); } /** @@ -307,3 +296,47 @@ DWORD KmtCloseService( cleanup: return Error; } + + +/* + * Private function, not meant for use in kmtests + * See KmtCreateService & KmtFltCreateService + */ +DWORD +KmtpCreateService( + IN PCWSTR ServiceName, + IN PCWSTR ServicePath, + IN PCWSTR DisplayName OPTIONAL, + IN DWORD ServiceType, + OUT SC_HANDLE *ServiceHandle) +{ + DWORD Error = ERROR_SUCCESS; + WCHAR DriverPath[MAX_PATH]; + HRESULT result = S_OK; + + assert(ServiceHandle); + assert(ServiceName && ServicePath); + + if (!GetModuleFileName(NULL, DriverPath, sizeof DriverPath / sizeof DriverPath[0])) + error_goto(Error, cleanup); + + assert(wcsrchr(DriverPath, L'\\') != NULL); + wcsrchr(DriverPath, L'\\')[1] = L'\0'; + + result = StringCbCat(DriverPath, sizeof DriverPath, ServicePath); + if (FAILED(result)) + error_value_goto(Error, result, cleanup); + + if (GetFileAttributes(DriverPath) == INVALID_FILE_ATTRIBUTES) + error_goto(Error, cleanup); + + *ServiceHandle = CreateService(ScmHandle, ServiceName, DisplayName, + SERVICE_ACCESS, ServiceType, SERVICE_DEMAND_START, + SERVICE_ERROR_NORMAL, DriverPath, NULL, NULL, NULL, NULL, NULL); + + if (!*ServiceHandle) + error_goto(Error, cleanup); + +cleanup: + return Error; +} \ No newline at end of file