summaryrefslogtreecommitdiff
path: root/TrEE/Test
diff options
context:
space:
mode:
authorkarlf <[email protected]>2016-08-11 13:28:13 -0700
committerkarlf <[email protected]>2016-08-11 13:28:13 -0700
commit96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch)
treead5f3ede5cbcd6b598677ce41bcf8318471bdd92 /TrEE/Test
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'TrEE/Test')
-rw-r--r--TrEE/Test/SampleTest.cpp836
-rw-r--r--TrEE/Test/TrEESampleTest.vcxproj256
-rw-r--r--TrEE/Test/TrEESampleTest.vcxproj.Filters22
3 files changed, 1114 insertions, 0 deletions
diff --git a/TrEE/Test/SampleTest.cpp b/TrEE/Test/SampleTest.cpp
new file mode 100644
index 00000000..89bd9471
--- /dev/null
+++ b/TrEE/Test/SampleTest.cpp
@@ -0,0 +1,836 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+ sampletest.cpp
+
+Abstract:
+
+ This file demonstrates I/O to TrEE secure services.
+
+Environment:
+
+ User mode
+
+--*/
+
+#pragma warning(disable:4127)
+
+#include <initguid.h>
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <Windows.h>
+#include <winioctl.h>
+#include <cfgmgr32.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef LONG NTSTATUS;
+
+#include <TrustedRT.h>
+#include <SampleSecureService.h>
+#include <SampleOSService.h>
+
+#define TEST_ASSERT(_Assertion, _Message, ...) do { \
+ if (!(_Assertion)) { \
+ wprintf(_Message L"\n", __VA_ARGS__); \
+ Success = FALSE; \
+ goto End; \
+ }\
+ } while (0)
+
+#define TEST_COMMENT(_Message, ...) wprintf(_Message L"\n", __VA_ARGS__)
+
+#define TEST_STRING L"This is a test string.\n"
+
+HANDLE
+OpenServiceHandleByInterface(
+ _In_ LPCGUID ServiceGuid
+ )
+
+/*++
+
+Routine Description:
+
+ This routine opens a handle to the service device specified the GUID using
+ PnP device interface. The device interface gives a symbolic link to the
+ service device that can be fed to CreateFile function.
+
+Arguments:
+
+ ServiceGuid - Supplies the GUID of the service to open.
+
+Return Value:
+
+ HANDLE to the secure service, NULL if error occurred.
+
+--*/
+
+{
+ CONFIGRET ConfigRet;
+ WCHAR InterfaceSymlink[1024];
+ HANDLE ServiceHandle;
+ BOOL Success;
+
+ ServiceHandle = INVALID_HANDLE_VALUE;
+ ConfigRet = CM_Get_Device_Interface_ListW(
+ const_cast<LPGUID>(ServiceGuid),
+ NULL,
+ InterfaceSymlink,
+ _countof(InterfaceSymlink),
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT
+ );
+
+ TEST_ASSERT(ConfigRet == CR_SUCCESS, L"GetDeviceInterface failed, configret=%d", ConfigRet);
+ TEST_COMMENT(L"Symlink=%ws", InterfaceSymlink);
+
+ ServiceHandle = CreateFileW(
+ InterfaceSymlink,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ TEST_ASSERT(ServiceHandle != INVALID_HANDLE_VALUE, L"Service open failed");
+
+End:
+ return ServiceHandle;
+}
+
+HANDLE
+OpenServiceHandleByFilename(
+ _In_ LPCGUID ServiceGuid
+ )
+
+/*++
+
+Routine Description:
+
+ This routine opens a handle to the service device specified the GUID using
+ TrEE-namespace filename. The filename has format \\.\WindowsTrustedRT\{GUID}.
+ The filename is parsed in IRP_MJ_CREATE handler in TrEE class extension.
+ Then request is forwarded to corresponding service device.
+
+Arguments:
+
+ ServiceGuid - Supplies the GUID of the service to open.
+
+Return Value:
+
+ HANDLE to the secure service, NULL if error occurred.
+
+--*/
+
+{
+ WCHAR InterfaceGuid[1024];
+ WCHAR InterfaceSymlink[1024];
+ HANDLE ServiceHandle;
+ BOOL Success;
+
+ ServiceHandle = INVALID_HANDLE_VALUE;
+ swprintf_s(InterfaceGuid,
+ L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ ServiceGuid->Data1,
+ ServiceGuid->Data2,
+ ServiceGuid->Data3,
+ ServiceGuid->Data4[0],
+ ServiceGuid->Data4[1],
+ ServiceGuid->Data4[2],
+ ServiceGuid->Data4[3],
+ ServiceGuid->Data4[4],
+ ServiceGuid->Data4[5],
+ ServiceGuid->Data4[6],
+ ServiceGuid->Data4[7]
+ );
+
+ swprintf_s(InterfaceSymlink, L"\\\\.\\WindowsTrustedRT\\%ws", InterfaceGuid);
+
+ TEST_COMMENT(L"Guid=%ws", InterfaceGuid);
+ TEST_COMMENT(L"Symlink=%ws", InterfaceSymlink);
+
+ ServiceHandle = CreateFileW(
+ InterfaceSymlink,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ TEST_ASSERT(ServiceHandle != INVALID_HANDLE_VALUE, L"Service open failed");
+
+End:
+ return ServiceHandle;
+}
+
+BOOL
+CallTrEEService(
+ _In_ HANDLE ServiceHandle,
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ ULONG InputBufferLength,
+ _Out_writes_bytes_to_(OutputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ ULONG OutputBufferLength,
+ _Out_ PULONG BytesWritten
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is a wrapper for DeviceIoControl to conveniently send TrEE
+ secure function requests. Input and output buffers are packed to TrEE
+ request structs and number of bytes written is unpacked from response
+ struct.
+
+Arguments:
+
+ ServiceHandle - Supplies a handle to the secure service on which the
+ request is to be sent.
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the input buffer that contains the data
+ required to perform the operation
+
+ InputBufferLength - Supplies the size of the input buffer, in bytes.
+
+ OutputBuffer - Supplies a pointer to the output buffer that is to receive
+ the data returned by the operation.
+
+ OutputBufferLength - Supplies the size of the output buffer, in bytes.
+
+ BytesWritten - Supplies a pointer to a variable that receives the size of
+ the data stored in the output buffer, in bytes.
+
+Return Value:
+
+ TRUE if successful.
+
+--*/
+
+{
+ TR_SERVICE_REQUEST Request;
+ TR_SERVICE_REQUEST_RESPONSE Response;
+ BOOL Success;
+ ULONG ResponseBytesWritten;
+
+ Request.FunctionCode = FunctionCode;
+ Request.InputBuffer = InputBuffer;
+ Request.InputBufferSize = InputBufferLength;
+ Request.OutputBuffer = OutputBuffer;
+ Request.OutputBufferSize = OutputBufferLength;
+
+ Success = DeviceIoControl(ServiceHandle,
+ IOCTL_TR_EXECUTE_FUNCTION,
+ &Request,
+ sizeof(Request),
+ &Response,
+ sizeof(Response),
+ &ResponseBytesWritten,
+ NULL);
+
+ if (ResponseBytesWritten >= sizeof(Response)) {
+ *BytesWritten = (ULONG)Response.BytesWritten;
+ return Success;
+
+ } else {
+
+ *BytesWritten = 0;
+ return FALSE;
+ }
+}
+
+typedef struct _ASYNC_TREE_CALL {
+ OVERLAPPED Overlapped;
+ TR_SERVICE_REQUEST Request;
+ TR_SERVICE_REQUEST_RESPONSE Response;
+} ASYNC_TREE_CALL, *PASYNC_TREE_CALL;
+
+BOOL
+CallTrEEServiceEx(
+ _In_ HANDLE ServiceHandle,
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ ULONG InputBufferLength,
+ _Out_writes_bytes_to_(OutputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ ULONG OutputBufferLength,
+ _Out_ PULONG BytesWritten,
+ _Deref_out_ PASYNC_TREE_CALL* pAsyncContext
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is a wrapper for DeviceIoControl similar to CallTrEEService,
+ except that it performs asynchronous I/O.
+
+Arguments:
+
+ ServiceHandle - Supplies a handle to the secure service on which the
+ request is to be sent. The handle must have been opened
+ with FILE_FLAG_OVERLAPPED flag.
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the input buffer that contains the data
+ required to perform the operation
+
+ InputBufferLength - Supplies the size of the input buffer, in bytes.
+
+ OutputBuffer - Supplies a pointer to the output buffer that is to receive
+ the data returned by the operation.
+
+ OutputBufferLength - Supplies the size of the output buffer, in bytes.
+
+ BytesWritten - Supplies a pointer to a variable that receives the size of
+ the data stored in the output buffer, in bytes.
+
+ pAsyncContext - Supplies a pointer to a variable that receives the pointer
+ to ASYNC_TREE_CALL which contains necessary input and
+ output buffer for the request and an OVERLAPPED struct to
+ track the progress of the request.
+
+Return Value:
+
+ TRUE if the operation was completed synchronously and successfully.
+
+ FALSE if the operation is undergoing asynchronously or has failed. Check
+ the value of GetLastError to distinguish the case.
+
+--*/
+
+{
+ PASYNC_TREE_CALL AsyncContext;
+ BOOL Success;
+ ULONG ResponseBytesWritten;
+
+ AsyncContext = new ASYNC_TREE_CALL;
+ memset(AsyncContext, 0, sizeof(ASYNC_TREE_CALL));
+ AsyncContext->Request.FunctionCode = FunctionCode;
+ AsyncContext->Request.InputBuffer = InputBuffer;
+ AsyncContext->Request.InputBufferSize = InputBufferLength;
+ AsyncContext->Request.OutputBuffer = OutputBuffer;
+ AsyncContext->Request.OutputBufferSize = OutputBufferLength;
+ AsyncContext->Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ *pAsyncContext = AsyncContext;
+
+ Success = DeviceIoControl(ServiceHandle,
+ IOCTL_TR_EXECUTE_FUNCTION,
+ &AsyncContext->Request,
+ sizeof(TR_SERVICE_REQUEST),
+ &AsyncContext->Response,
+ sizeof(TR_SERVICE_REQUEST_RESPONSE),
+ &ResponseBytesWritten,
+ &AsyncContext->Overlapped);
+
+ if (ResponseBytesWritten >= sizeof(TR_SERVICE_REQUEST_RESPONSE)) {
+ *BytesWritten = (ULONG)AsyncContext->Response.BytesWritten;
+ return Success;
+
+ } else {
+
+ *BytesWritten = 0;
+ return FALSE;
+ }
+}
+
+VOID
+CleanupAsyncTrEECallContext(
+ _In_ PASYNC_TREE_CALL AsyncContext
+ )
+
+/*++
+
+Routine Description:
+
+ This routine cleans up the memory and resources used by ASYNC_TREE_CALL
+ struct returned from CallTrEEServiceEx function.
+
+Arguments:
+
+ AsyncContext - Supplies a pointer to ASYNC_TREE_CALL struct returned from
+ CallTrEEServiceEx function.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ CloseHandle(AsyncContext->Overlapped.hEvent);
+ delete AsyncContext;
+}
+
+int
+__cdecl
+wmain(
+ int argc,
+ const wchar_t** argv
+ )
+{
+ DWORD BytesWritten;
+ HANDLE TestServiceHandle;
+ HANDLE Test2ServiceHandle;
+ HANDLE MasterDeviceHandle;
+ BOOL Success;
+ ULONG64 TestFlag;
+
+ Success = TRUE;
+ TestServiceHandle = INVALID_HANDLE_VALUE;
+ Test2ServiceHandle = INVALID_HANDLE_VALUE;
+ MasterDeviceHandle = INVALID_HANDLE_VALUE;
+
+ if (argc > 1) {
+ swscanf_s(argv[1], L"%I64x", &TestFlag);
+
+ } else {
+
+ TestFlag = ~0UI64;
+ }
+
+ //
+ // Open the service using TrEE-namespace filename.
+ //
+ TestServiceHandle = OpenServiceHandleByFilename(&GUID_SAMPLE_TEST_SERVICE);
+ TEST_ASSERT(TestServiceHandle != INVALID_HANDLE_VALUE, L"Test service open failed");
+
+ if ((TestFlag & 0x1) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_HELLO_WORLD");
+
+ wchar_t* HelloWorld;
+
+ //
+ // First call the service with no output buffer to detect how large
+ // output buffer should be.
+ //
+ Success = CallTrEEService(TestServiceHandle,
+ TEST_SERVICE_HELLO_WORLD,
+ NULL, 0,
+ NULL, 0,
+ &BytesWritten);
+
+ TEST_ASSERT(!Success, L"CallTrEEService (get size) unexpectedly succeeded");
+ TEST_ASSERT(BytesWritten > 0, L"CallTrEEService (get size) returned 0 bytes required size");
+
+ //
+ // The request fails, but BytesWritten variable will contain the
+ // required size of output buffer.
+ //
+ HelloWorld = (wchar_t*)malloc(BytesWritten);
+ Success = CallTrEEService(TestServiceHandle,
+ TEST_SERVICE_HELLO_WORLD,
+ NULL, 0,
+ HelloWorld, BytesWritten,
+ &BytesWritten);
+
+ TEST_ASSERT(Success, L"CallTrEEService (read data) failed (err=%d)", GetLastError());
+ TEST_ASSERT(BytesWritten > 0, L"CallTrEEService (read data) returned 0 bytes written");
+
+ //
+ // The service will return classic "Hello, world!" message.
+ //
+ TEST_COMMENT(L"TEST_SERVICE_HELLO_WORLD returned: %ws", HelloWorld);
+ }
+
+ if ((TestFlag & 0x2) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_GET_INTERRUPT_TIME");
+
+ ULONG64 InterruptTime;
+
+ Success = CallTrEEService(TestServiceHandle,
+ TEST_SERVICE_GET_INTERRUPT_TIME,
+ NULL, 0,
+ &InterruptTime, sizeof(InterruptTime),
+ &BytesWritten);
+
+ TEST_ASSERT(Success, L"CallTrEEService (read data) failed (err=%d)", GetLastError());
+ TEST_ASSERT(BytesWritten == sizeof(ULONG64),
+ L"CallTrEEService (read data) returned unexpected number of bytes (BytesWritten=%d)",
+ BytesWritten);
+
+ TEST_COMMENT(L"TEST_SERVICE_GET_INTERRUPT_TIME returned: %I64x", InterruptTime);
+ }
+
+ if ((TestFlag & 0x4) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_KERNEL_ONLY");
+
+ DWORD Error;
+
+ //
+ // This call is available only from kernel mode. The service will fail
+ // the request if it came from usermode.
+ //
+ Success = CallTrEEService(TestServiceHandle,
+ TEST_SERVICE_KERNEL_ONLY,
+ NULL, 0,
+ NULL, 0,
+ &BytesWritten);
+
+ Error = GetLastError();
+
+ TEST_ASSERT(!Success, L"CallTrEEService unexpectedly succeeded");
+
+ TEST_COMMENT(L"TEST_SERVICE_KERNEL_ONLY failed with err=%d", Error);
+ }
+
+ {
+ DWORD Error;
+ ULONG Input;
+ ULONG Output;
+ PASYNC_TREE_CALL AsyncContext;
+
+ if ((TestFlag & 0x8) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_DELAYED_COMPLETION(1500ms, synchronous wait)");
+ Input = 1500;
+ Output = 0;
+ Success = CallTrEEService(TestServiceHandle,
+ TEST_SERVICE_DELAYED_COMPLETION,
+ &Input, sizeof(Input),
+ &Output, sizeof(Output),
+ &BytesWritten);
+
+ TEST_ASSERT(Success, L"CallTrEEService failed (err=%d)", GetLastError());
+ TEST_ASSERT(BytesWritten == sizeof(Output),
+ L"CallTrEEService returned unexpected number of bytes (BytesWritten=%d)",
+ BytesWritten);
+
+ TEST_COMMENT(L"Output buffer contains: %08x", Output);
+ }
+
+ if ((TestFlag & 0x10) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_DELAYED_COMPLETION(5000ms, asynchronous wait)");
+ Input = 5000;
+ Output = 0;
+
+ //
+ // CallTrEEServiceEx is called to demonstrate asynchronous operation.
+ //
+ Success = CallTrEEServiceEx(TestServiceHandle,
+ TEST_SERVICE_DELAYED_COMPLETION,
+ &Input, sizeof(Input),
+ &Output, sizeof(Output),
+ &BytesWritten,
+ &AsyncContext);
+
+ Error = GetLastError();
+
+ TEST_ASSERT(!Success, L"CallTrEEServiceEx unexpectedly succeeded");
+ TEST_ASSERT(GetLastError() == ERROR_IO_PENDING,
+ L"CallTrEEServiceEx returned unexpected error code (err=%d)",
+ Error);
+
+ while (true) {
+ TEST_COMMENT(L"Waiting for completion...");
+ Error = WaitForSingleObject(AsyncContext->Overlapped.hEvent, 500);
+
+ TEST_ASSERT((Error == STATUS_TIMEOUT) || (Error == STATUS_WAIT_0),
+ L"WaitForSingleObject returned unexpected value %d",
+ Error);
+
+ if (Error == STATUS_WAIT_0) {
+ break;
+ }
+ }
+
+ TEST_ASSERT(AsyncContext->Overlapped.Internal == STATUS_SUCCESS,
+ L"Request failed (NTSTATUS=%08x)",
+ (NTSTATUS)AsyncContext->Overlapped.Internal);
+
+ //
+ // IOCTL's output buffer points to TR_SERVICE_REQUEST_RESPONSE. So this
+ // request's number of bytes written is always sizeof(TR_SERVICE_REQUEST_RESPONSE).
+ //
+ TEST_ASSERT(AsyncContext->Overlapped.InternalHigh == sizeof(TR_SERVICE_REQUEST_RESPONSE),
+ L"Request response size incorrect (BytesWritten=%u)",
+ (ULONG)AsyncContext->Overlapped.InternalHigh);
+
+ //
+ // Number of bytes written to secure request's output buffer is
+ // returned in TR_SERVICE_REQUEST_RESPONSE::BytesWritten.
+ //
+ TEST_ASSERT(AsyncContext->Response.BytesWritten == sizeof(ULONG),
+ L"Number of bytes written to output buffer incorrect (BytesWritten=%u)",
+ (ULONG)AsyncContext->Response.BytesWritten);
+
+ TEST_COMMENT(L"Output buffer contains: %08x", Output);
+
+ CleanupAsyncTrEECallContext(AsyncContext);
+ }
+
+ if ((TestFlag & 0x20) != 0) {
+ TEST_COMMENT(L"\n::::: TEST_SERVICE_DELAYED_COMPLETION(5000ms, asynchronous wait + cancel)");
+ Input = 5000;
+ Output = 0;
+ Success = CallTrEEServiceEx(TestServiceHandle,
+ TEST_SERVICE_DELAYED_COMPLETION,
+ &Input, sizeof(Input),
+ &Output, sizeof(Output),
+ &BytesWritten,
+ &AsyncContext);
+
+ Error = GetLastError();
+
+ TEST_ASSERT(!Success, L"CallTrEEServiceEx unexpectedly succeeded");
+ TEST_ASSERT(GetLastError() == ERROR_IO_PENDING,
+ L"CallTrEEServiceEx returned unexpected error code (err=%d)",
+ Error);
+
+ Sleep(1000);
+
+ TEST_COMMENT(L"Cancelling...");
+
+ //
+ // The request is cancelled before it can be completed.
+ //
+ Success = CancelIoEx(TestServiceHandle, &AsyncContext->Overlapped);
+
+ TEST_ASSERT(Success, L"CancelIoEx failed (err=%d)", GetLastError());
+
+ //
+ // When the cancellation is handled by the miniport driver, the request
+ // will have status STATUS_CANCELLED.
+ //
+ for (int i = 0; i < 10; ++i) {
+ TEST_COMMENT(L"Request status = %08x",
+ (NTSTATUS)AsyncContext->Overlapped.Internal);
+
+ if ((NTSTATUS)AsyncContext->Overlapped.Internal == STATUS_CANCELLED) {
+ break;
+ }
+
+ Sleep(20);
+ }
+
+ TEST_ASSERT((NTSTATUS)AsyncContext->Overlapped.Internal == STATUS_CANCELLED,
+ L"Request not cancelled (NTSTATUS=%08x)",
+ (NTSTATUS)AsyncContext->Overlapped.Internal);
+
+ CleanupAsyncTrEECallContext(AsyncContext);
+ }
+ }
+
+ {
+ DWORD Error;
+ ULONG Input;
+ ULONG Output;
+ OVERLAPPED Overlapped;
+
+ if ((TestFlag & 0x40) != 0) {
+ TEST_COMMENT(L"\n::::: IOCTL_TEST_DELAYED_COMPLETION(3000ms + async wait)");
+
+ memset(&Overlapped, 0, sizeof(Overlapped));
+ Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ //
+ // Other I/O doesn't use TR_SERVICE_REQUEST structs. Use
+ // DeviceIocontrol and specify input and output buffers directly in
+ // parameters.
+ //
+ Input = 3000;
+ Output = 0;
+ Success = DeviceIoControl(TestServiceHandle,
+ IOCTL_TEST_DELAYED_COMPLETION,
+ &Input, sizeof(Input),
+ &Output, sizeof(Output),
+ &BytesWritten,
+ &Overlapped);
+
+ Error = GetLastError();
+
+ TEST_ASSERT(!Success, L"CallTrEEServiceEx unexpectedly succeeded");
+ TEST_ASSERT(GetLastError() == ERROR_IO_PENDING,
+ L"CallTrEEServiceEx returned unexpected error code (err=%d)",
+ Error);
+
+ while (true) {
+ TEST_COMMENT(L"Waiting for completion...");
+ Error = WaitForSingleObject(Overlapped.hEvent, 500);
+
+ TEST_ASSERT((Error == STATUS_TIMEOUT) || (Error == STATUS_WAIT_0),
+ L"WaitForSingleObject returned unexpected value %d",
+ Error);
+
+ if (Error == STATUS_WAIT_0) {
+ break;
+ }
+ }
+
+ TEST_ASSERT(Overlapped.Internal == STATUS_SUCCESS,
+ L"Request failed (NTSTATUS=%08x)",
+ (NTSTATUS)Overlapped.Internal);
+
+ //
+ // IOCTL's output buffer points to ULONG Output.
+ //
+ TEST_ASSERT(Overlapped.InternalHigh == sizeof(ULONG),
+ L"Request response size incorrect (BytesWritten=%u)",
+ (ULONG)Overlapped.InternalHigh);
+
+ TEST_COMMENT(L"Output buffer contains: %08x", Output);
+ }
+
+ if ((TestFlag & 0x80) != 0) {
+ TEST_COMMENT(L"\n::::: IOCTL_TEST_DELAYED_COMPLETION(5000ms, asynchronous wait + cancel)");
+ Overlapped.Internal = 0;
+ Overlapped.InternalHigh = 0;
+ Overlapped.Offset = 0;
+ Overlapped.OffsetHigh = 0;
+ Overlapped.Pointer = 0;
+ Input = 5000;
+ Output = 0;
+ Success = DeviceIoControl(TestServiceHandle,
+ IOCTL_TEST_DELAYED_COMPLETION,
+ &Input, sizeof(Input),
+ &Output, sizeof(Output),
+ &BytesWritten,
+ &Overlapped);
+
+ Error = GetLastError();
+
+ TEST_ASSERT(!Success, L"CallTrEEServiceEx unexpectedly succeeded");
+ TEST_ASSERT(GetLastError() == ERROR_IO_PENDING,
+ L"CallTrEEServiceEx returned unexpected error code (err=%d)",
+ Error);
+
+ Sleep(1000);
+
+ TEST_COMMENT(L"Cancelling...");
+
+ //
+ // The request is cancelled before it can be completed.
+ //
+ Success = CancelIoEx(TestServiceHandle, &Overlapped);
+
+ TEST_ASSERT(Success, L"CancelIoEx failed (err=%d)", GetLastError());
+
+ //
+ // When the cancellation is handled by the miniport driver, the request
+ // will have status STATUS_CANCELLED.
+ //
+ for (int i = 0; i < 10; ++i) {
+ TEST_COMMENT(L"Request status = %08x",
+ (NTSTATUS)Overlapped.Internal);
+
+ if ((NTSTATUS)Overlapped.Internal == STATUS_CANCELLED) {
+ break;
+ }
+
+ Sleep(20);
+ }
+
+ TEST_ASSERT((NTSTATUS)Overlapped.Internal == STATUS_CANCELLED,
+ L"Request not cancelled (NTSTATUS=%08x)",
+ (NTSTATUS)Overlapped.Internal);
+
+ CloseHandle(Overlapped.hEvent);
+ }
+ }
+
+ //
+ // Open the service using PnP device interface.
+ //
+ Test2ServiceHandle = OpenServiceHandleByInterface(&GUID_SAMPLE_TEST2_SERVICE);
+ TEST_ASSERT(Test2ServiceHandle != INVALID_HANDLE_VALUE, L"Test2 service open failed");
+
+ {
+ char Input[64];
+ size_t InputLength;
+ char Output[128];
+
+ if ((TestFlag & 0x100) != 0)
+ {
+ //
+ // This service talks to another driversin OS. Refer to
+ // miniport\TestService.c to see how the miniport driver sends requests
+ // to other drivers.
+ //
+ TEST_COMMENT(L"\n::::: TEST2_SERVICE_ECHO");
+
+ strcpy_s(Input, "Hello from usermode");
+ InputLength = strlen(Input);
+ memset(Output, 0, sizeof(Output));
+ Success = CallTrEEService(Test2ServiceHandle,
+ TEST2_SERVICE_ECHO,
+ Input, (ULONG)InputLength,
+ Output, sizeof(Output),
+ &BytesWritten);
+
+ TEST_ASSERT(Success, L"CallTrEEService failed (err=%d)", GetLastError());
+ TEST_ASSERT(BytesWritten == InputLength,
+ L"CallTrEEService returned unexpected number of bytes (BytesWritten=%d)",
+ BytesWritten);
+
+ TEST_COMMENT(L"Output buffer contains: %hs", Output);
+ }
+
+ if ((TestFlag & 0x200) != 0)
+ {
+ TEST_COMMENT(L"\n::::: TEST2_SERVICE_TWICE_REVERSED");
+
+ strcpy_s(Input, "Hello from usermode");
+ InputLength = strlen(Input);
+ memset(Output, 0, sizeof(Output));
+ Success = CallTrEEService(Test2ServiceHandle,
+ TEST2_SERVICE_ECHO_TWICE_REVERSED,
+ Input, (ULONG)InputLength,
+ Output, sizeof(Output),
+ &BytesWritten);
+
+ TEST_ASSERT(Success, L"CallTrEEService failed (err=%d)", GetLastError());
+ TEST_ASSERT(BytesWritten == InputLength * 2,
+ L"CallTrEEService returned unexpected number of bytes (BytesWritten=%d)",
+ BytesWritten);
+
+ TEST_COMMENT(L"Output buffer contains: %hs", Output);
+ }
+ }
+
+ //
+ // Open the master device using PnP device interface.
+ //
+ MasterDeviceHandle = CreateFileW(L"\\\\.\\SampleTrEEDriver",
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ TEST_ASSERT(MasterDeviceHandle != INVALID_HANDLE_VALUE, L"Master device open failed");
+
+ if ((TestFlag & 0x400) != 0)
+ {
+ TEST_COMMENT(L"\n::::: IOCTL_SAMPLE_DBGPRINT");
+
+ Success = DeviceIoControl(MasterDeviceHandle,
+ IOCTL_SAMPLE_DBGPRINT,
+ TEST_STRING, sizeof(TEST_STRING),
+ NULL, 0,
+ &BytesWritten,
+ NULL);
+
+ TEST_ASSERT(Success, L"CallTrEEService failed (err=%d)", GetLastError());
+ }
+
+End:
+ if (TestServiceHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(TestServiceHandle);
+ }
+
+ if (Test2ServiceHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(Test2ServiceHandle);
+ }
+
+ if (MasterDeviceHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(MasterDeviceHandle);
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/TrEE/Test/TrEESampleTest.vcxproj b/TrEE/Test/TrEESampleTest.vcxproj
new file mode 100644
index 00000000..dbf5824f
--- /dev/null
+++ b/TrEE/Test/TrEESampleTest.vcxproj
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Arm">
+ <Configuration>Debug</Configuration>
+ <Platform>Arm</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Arm">
+ <Configuration>Release</Configuration>
+ <Platform>Arm</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{DDA508B0-8C40-47C1-BC1C-AD6717E895EF}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{9F985327-DEA3-47CE-AF50-79656A8DBC68}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>TrEESampleTest</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(MINWIN_SDK_LIB_PATH)\ntdll.lib;$(MINCORE_SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="sampletest.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/TrEE/Test/TrEESampleTest.vcxproj.Filters b/TrEE/Test/TrEESampleTest.vcxproj.Filters
new file mode 100644
index 00000000..0bc02bf0
--- /dev/null
+++ b/TrEE/Test/TrEESampleTest.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{FCED4095-7FC8-465C-AD4F-CA121B97193C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{0B33D33B-97F5-4885-913B-C98AD039C1DF}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{83A7795F-7EE2-4FE1-B6D6-3AC2B6337B4E}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="sampletest.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file