summaryrefslogtreecommitdiff
path: root/TrEE
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
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'TrEE')
-rw-r--r--TrEE/Miniport/SampleMiniport.c732
-rw-r--r--TrEE/Miniport/SampleMiniport.h30
-rw-r--r--TrEE/Miniport/SampleMiniport.rc14
-rw-r--r--TrEE/Miniport/TestService.c1332
-rw-r--r--TrEE/Miniport/TrEEMiniportSample.infbin0 -> 4652 bytes
-rw-r--r--TrEE/Miniport/TrEEMiniportSample.vcxproj241
-rw-r--r--TrEE/Miniport/TrEEMiniportSample.vcxproj.Filters34
-rw-r--r--TrEE/OSService/SampleOSService.c928
-rw-r--r--TrEE/OSService/SampleOSService.rc14
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.infbin0 -> 4572 bytes
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.vcxproj222
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters31
-rw-r--r--TrEE/Test/SampleTest.cpp836
-rw-r--r--TrEE/Test/TrEESampleTest.vcxproj256
-rw-r--r--TrEE/Test/TrEESampleTest.vcxproj.Filters22
-rw-r--r--TrEE/TrEESample.sln73
-rw-r--r--TrEE/inc/SampleOSService.h66
-rw-r--r--TrEE/inc/SampleSecureService.h72
18 files changed, 4903 insertions, 0 deletions
diff --git a/TrEE/Miniport/SampleMiniport.c b/TrEE/Miniport/SampleMiniport.c
new file mode 100644
index 00000000..55bfa60a
--- /dev/null
+++ b/TrEE/Miniport/SampleMiniport.c
@@ -0,0 +1,732 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+ sample.c
+
+Abstract:
+
+ This file demonstrates a simple TrEE miniport.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <initguid.h>
+#include <wdmguid.h>
+#include <ntstrsafe.h>
+#include <TrustedRuntimeClx.h>
+#include <ntefi.h>
+#include <TrEEVariableService.h>
+#include "sampleminiport.h"
+#include <SampleSecureService.h>
+#include <SampleOSService.h>
+
+#define SDDL_SAMPLE_TEST2_SERVICE L"D:P(A;;FRFW;;;WD)(A;;FRFW;;;RC)(A;;FRFW;;;AC)"
+
+//
+// Driver entry point
+//
+
+DRIVER_INITIALIZE DriverEntry;
+
+//
+// Device callbacks
+//
+
+EVT_WDF_DRIVER_UNLOAD DriverUnload;
+EVT_WDF_DRIVER_DEVICE_ADD TreeSampleEvtAddDevice;
+
+//
+// Class Extension callbacks
+//
+
+EVT_TR_CREATE_SECURE_DEVICE_CONTEXT TreeSampleCreateSecureDeviceContext;
+EVT_TR_DESTROY_SECURE_DEVICE_CONTEXT TreeSampleDestroySecureDeviceContext;
+EVT_TR_PREPARE_HARDWARE_SECURE_ENVIRONMENT TreeSamplePrepareHardwareSecureEnvironment;
+EVT_TR_RELEASE_HARDWARE_SECURE_ENVIRONMENT TreeSampleReleaseHardwareSecureEnvironment;
+EVT_TR_CONNECT_SECURE_ENVIRONMENT TreeSampleConnectSecureEnvironment;
+EVT_TR_DISCONNECT_SECURE_ENVIRONMENT TreeSampleDisconnectSecureEnvironment;
+EVT_TR_ENUMERATE_SECURE_SERVICES TreeSampleEnumerateSecureServices;
+EVT_TR_PROCESS_OTHER_DEVICE_IO TreeSampleProcessOtherDeviceIo;
+EVT_TR_CREATE_SECURE_SERVICE_CONTEXT TreeSampleCreateSecureServiceContext;
+EVT_TR_QUERY_SERVICE_CALLBACKS TreeSampleQueryServiceCallbacks;
+
+#pragma data_seg("PAGED")
+
+TR_SECURE_DEVICE_CALLBACKS TreeSampleCallbacks = {
+ TR_DEVICE_SERIALIZE_ALL_REQUESTS |
+ TR_DEVICE_STACK_RESERVE_8K,
+
+ &TreeSampleCreateSecureDeviceContext,
+ &TreeSampleDestroySecureDeviceContext,
+
+ &TreeSamplePrepareHardwareSecureEnvironment,
+ &TreeSampleReleaseHardwareSecureEnvironment,
+
+ &TreeSampleConnectSecureEnvironment,
+ &TreeSampleDisconnectSecureEnvironment,
+
+ &TreeSampleEnumerateSecureServices,
+ &TreeSampleProcessOtherDeviceIo,
+
+ &TreeSampleQueryServiceCallbacks
+};
+
+#pragma data_seg()
+
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, DriverUnload)
+#pragma alloc_text(PAGE, TreeSampleEvtAddDevice)
+#pragma alloc_text(PAGE, TreeSampleCreateSecureDeviceContext)
+#pragma alloc_text(PAGE, TreeSampleDestroySecureDeviceContext)
+#pragma alloc_text(PAGE, TreeSamplePrepareHardwareSecureEnvironment)
+#pragma alloc_text(PAGE, TreeSampleReleaseHardwareSecureEnvironment)
+#pragma alloc_text(PAGE, TreeSampleEnumerateSecureServices)
+#pragma alloc_text(PAGE, TreeSampleProcessOtherDeviceIo)
+#pragma alloc_text(PAGE, TreeSampleQueryServiceCallbacks)
+
+_Use_decl_annotations_
+NTSTATUS
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the initialization routine for the device driver. This routine
+ creates the driver object for the TrEE miniport.
+
+ Arguments:
+
+ DriverObject - Supplies a pointer to driver object created by the
+ system.
+
+ RegistryPath - Supplies a unicode string indentifying where the
+ parameters for this driver are located in the registry.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDRIVER Driver;
+ WDF_DRIVER_CONFIG DriverConfig;
+ NTSTATUS Status;
+
+ Driver = NULL;
+
+ //
+ // Create the WDF driver object
+ //
+
+ WDF_DRIVER_CONFIG_INIT(&DriverConfig, TreeSampleEvtAddDevice);
+ DriverConfig.EvtDriverUnload = DriverUnload;
+
+ Status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &DriverConfig,
+ &Driver);
+
+ if (!NT_SUCCESS(Status)) {
+ goto DriverEntryEnd;
+ }
+
+
+DriverEntryEnd:
+
+ return Status;
+}
+
+_Use_decl_annotations_
+VOID
+DriverUnload(
+ WDFDRIVER Driver
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the cleanup function called when the driver is unloaded.
+
+ Arguments:
+
+ Driver - Supplies a handle to WDFDRIVER object created in DriverEntry.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleEvtAddDevice(
+ WDFDRIVER Driver,
+ PWDFDEVICE_INIT DeviceInit
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the driver is being attached to a specific
+ device.
+
+ Arguments:
+
+ Driver - Supplies a handle to the framework driver object.
+
+ DeviceInit - Supplies a pointer to the device initialization parameters.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDEVICE Device;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ Status = TrSecureDeviceHandoffMasterDeviceControl(
+ DeviceInit,
+ &TreeSampleCallbacks,
+ &Device);
+
+ TrSecureDeviceLogMessage(Device,
+ STATUS_SEVERITY_INFORMATIONAL,
+ "Master device discovered\n");
+
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleCreateSecureDeviceContext(
+ WDFDEVICE MasterDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the secure environment is first started.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to store any context information
+ required for future calls.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDF_OBJECT_ATTRIBUTES ContextAttributes;
+ PTREE_SAMPLE_DEVICE_CONTEXT MasterContext;
+ NTSTATUS Status;
+ DECLARE_CONST_UNICODE_STRING(SymbolicLink, L"\\DosDevices\\SampleTrEEDriver");
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ContextAttributes,
+ TREE_SAMPLE_DEVICE_CONTEXT);
+
+ Status = WdfObjectAllocateContext(MasterDevice, &ContextAttributes, &MasterContext);
+ if (!NT_SUCCESS(Status)) {
+ goto TreeSampleCreateSecureDeviceContextEnd;
+ }
+
+ MasterContext->MasterDevice = MasterDevice;
+
+ //
+ // Create a symbolic link so that usermode program can access master device.
+ //
+ Status = WdfDeviceCreateSymbolicLink(MasterDevice, &SymbolicLink);
+ if (!NT_SUCCESS(Status)) {
+ goto TreeSampleCreateSecureDeviceContextEnd;
+ }
+
+TreeSampleCreateSecureDeviceContextEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleDestroySecureDeviceContext(
+ WDFDEVICE MasterDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the secure environment is no longer used.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PTREE_SAMPLE_DEVICE_CONTEXT MasterContext;
+
+ MasterContext = WdfObjectGet_TREE_SAMPLE_DEVICE_CONTEXT(MasterDevice);
+
+ //
+ // No member needs cleanup here. ServiceCollection will be automatically
+ // reclaimed by the framework, since the parent object is going away.
+ //
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSamplePrepareHardwareSecureEnvironment(
+ WDFDEVICE MasterDevice,
+ WDFCMRESLIST RawResources,
+ WDFCMRESLIST TranslatedResources
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to handle any resources used by a secure device.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ RawResources - Supplies a pointer to the raw resources.
+
+ TranslatedResources - Supplies a pointer to the translated resources.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+ UNREFERENCED_PARAMETER(RawResources);
+ UNREFERENCED_PARAMETER(TranslatedResources);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleReleaseHardwareSecureEnvironment(
+ WDFDEVICE MasterDevice,
+ WDFCMRESLIST TranslatedResources
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to handle the displosal of any resources used by
+ a secure device.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ TranslatedResources - Supplies a pointer to the translated resources.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+ UNREFERENCED_PARAMETER(TranslatedResources);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleConnectSecureEnvironment(
+ WDFDEVICE MasterDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the secure environment should be prepared
+ for use either the first time or after a possible power state change.
+
+ This routine must be marked as pagable, since it is called during power
+ state transition.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleDisconnectSecureEnvironment(
+ WDFDEVICE MasterDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the secure environment should be prepared
+ for a possible power state change.
+
+ This routine must be marked as pagable, since it is called during power
+ state transition.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TreeSampleEnumerateSecureServices(
+ WDFDEVICE MasterDevice,
+ ULONG Index,
+ PUCHAR SecureServiceDescription,
+ ULONG *DescriptionSize
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to enumerate the supported secure services
+ provided by this secure device. The zero-based Index parameter is used
+ to determine which secure service information is being requested for.
+ If Index is larger than the number of available services then
+ STATUS_NO_MORE_ENTRIES is returned to indicate the end of the list has
+ been reached.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ Index - Supplies the zero-based index for the secure service whose
+ description is being requested.
+
+ SecureServiceDescription - Supplies a pointer to a buffer to hold the
+ secure service description. The description
+ is of type TR_SECURE_SERVICE.
+
+ DescriptionSize - Supplies a pointer to the size in bytes of
+ SecureServiceDescription on input, and holds the
+ number of bytes required on output.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ ULONG DescriptionSizeRequired;
+ PTR_SECURE_SERVICE SecureService;
+ PTR_SECURE_SERVICE_EXTENSION ServiceExtension;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ SecureService = (PTR_SECURE_SERVICE)SecureServiceDescription;
+ switch (Index) {
+ case 0:
+ //
+ // [0] Test service
+ // Major version = 1
+ // Minor version = 0
+ // No OS dependencies
+ // Open to all except restricted code (default)
+ //
+ DescriptionSizeRequired = FIELD_OFFSET(TR_SECURE_SERVICE, Dependencies);
+ if (*DescriptionSize < DescriptionSizeRequired) {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ goto TreeSampleEnumerateSecureServicesEnd;
+ }
+
+ SecureService->DescriptionSize = DescriptionSizeRequired;
+ SecureService->ServiceGuid = GUID_SAMPLE_TEST_SERVICE;
+ SecureService->MajorVersion = 1;
+ SecureService->MinorVersion = 0;
+ SecureService->ExtensionOffset = 0;
+ SecureService->CountDependencies = 0;
+
+ Status = STATUS_SUCCESS;
+ break;
+
+ case 1:
+ //
+ // [1] Test2 service
+ // Major version = 1
+ // Minor version = 0
+ // OS dependency on GUID_ECHO_SERVICE and GUID_KERNEL_MEMORY_SERVICE
+ // Open to all including restricted code
+ //
+ DescriptionSizeRequired = FIELD_OFFSET(TR_SECURE_SERVICE, Dependencies) +
+ sizeof(TR_SECURE_DEPENDENCY_V1) * 2 +
+ sizeof(TR_SECURE_SERVICE_EXTENSION) +
+ sizeof(SDDL_SAMPLE_TEST2_SERVICE);
+
+ if (*DescriptionSize < DescriptionSizeRequired) {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ goto TreeSampleEnumerateSecureServicesEnd;
+ }
+
+ SecureService->DescriptionSize = DescriptionSizeRequired;
+ SecureService->ServiceGuid = GUID_SAMPLE_TEST2_SERVICE;
+ SecureService->MajorVersion = 1;
+ SecureService->MinorVersion = 0;
+ SecureService->ExtensionOffset = FIELD_OFFSET(TR_SECURE_SERVICE, Dependencies) +
+ sizeof(TR_SECURE_DEPENDENCY_V1) * 2;
+ SecureService->CountDependencies = 2;
+ SecureService->Dependencies[0].Type = TRSecureOSDependency;
+ SecureService->Dependencies[0].Id = GUID_ECHO_SERVICE;
+ SecureService->Dependencies[0].MaxRequired = 1;
+ SecureService->Dependencies[1].Type = TRSecureOSDependency;
+ SecureService->Dependencies[1].Id = GUID_KERNEL_MEMORY_SERVICE;
+ SecureService->Dependencies[1].MaxRequired = 1;
+ ServiceExtension = (PTR_SECURE_SERVICE_EXTENSION)(
+ ((ULONG_PTR)SecureService) +
+ SecureService->ExtensionOffset);
+
+ ServiceExtension->ExtensionVersion = TR_SECURE_SERVICE_EXTENSION_VERSION;
+ ServiceExtension->SecurityDescriptorStringOffset = SecureService->ExtensionOffset +
+ sizeof(TR_SECURE_SERVICE_EXTENSION);
+ RtlCopyMemory((PVOID)(((ULONG_PTR)SecureService) + ServiceExtension->SecurityDescriptorStringOffset),
+ SDDL_SAMPLE_TEST2_SERVICE,
+ sizeof(SDDL_SAMPLE_TEST2_SERVICE));
+
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ DescriptionSizeRequired = 0;
+ Status = STATUS_NO_MORE_ENTRIES;
+ break;
+ }
+
+TreeSampleEnumerateSecureServicesEnd:
+ *DescriptionSize = DescriptionSizeRequired;
+ return Status;
+}
+
+_Use_decl_annotations_
+VOID
+TreeSampleProcessOtherDeviceIo(
+ WDFDEVICE MasterDevice,
+ WDFREQUEST Request
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when an unrecognized IO request is made to the
+ device. This can be used to process private calls directly to the
+ secure device.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ Request - Supplies a pointer to the WDF request object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PWCHAR Buffer;
+ size_t BufferSize;
+ ULONG BytesWritten;
+ WDF_REQUEST_PARAMETERS Parameters;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ WDF_REQUEST_PARAMETERS_INIT(&Parameters);
+ WdfRequestGetParameters(Request, &Parameters);
+ BytesWritten = 0;
+ switch (Parameters.Parameters.DeviceIoControl.IoControlCode) {
+ case IOCTL_SAMPLE_DBGPRINT:
+ Status = WdfRequestRetrieveInputBuffer(Request,
+ 0,
+ (PVOID*)&Buffer,
+ &BufferSize);
+
+ if (!NT_SUCCESS(Status)) {
+ goto TreeSampleProcessOtherDeviceIoEnd;
+ }
+
+ //
+ // Must be NULL-terminated
+ //
+ if (Buffer[BufferSize / sizeof(WCHAR) - 1] != L'\0') {
+ Status = STATUS_INVALID_PARAMETER;
+ goto TreeSampleProcessOtherDeviceIoEnd;
+ }
+
+ DbgPrintEx(DPFLTR_DEFAULT_ID,
+ DPFLTR_ERROR_LEVEL,
+ "[TrEEMiniportSample] %ws\n",
+ (PWSTR)Buffer);
+
+ break;
+
+ default:
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+TreeSampleProcessOtherDeviceIoEnd:
+ WdfRequestCompleteWithInformation(Request, Status, BytesWritten);
+}
+
+_Use_decl_annotations_
+PTR_SECURE_SERVICE_CALLBACKS
+TreeSampleQueryServiceCallbacks(
+ WDFDEVICE MasterDevice,
+ LPGUID ServiceGuid
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when an unrecognized IO request is made to the
+ device. This can be used to process private calls directly to the
+ secure device.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ DeviceContext - Supplies a pointer to the context.
+
+ Request - Supplies a pointer to the WDF request object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PTR_SECURE_SERVICE_CALLBACKS ServiceCallbacks;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ if (IsEqualGUID(ServiceGuid, &GUID_SAMPLE_TEST_SERVICE)) {
+
+ ServiceCallbacks = &TestServiceCallbacks;
+
+ } else if (IsEqualGUID(ServiceGuid, &GUID_SAMPLE_TEST2_SERVICE)) {
+
+ ServiceCallbacks = &Test2ServiceCallbacks;
+
+ } else {
+
+ ServiceCallbacks = NULL;
+ }
+
+ return ServiceCallbacks;
+}
diff --git a/TrEE/Miniport/SampleMiniport.h b/TrEE/Miniport/SampleMiniport.h
new file mode 100644
index 00000000..0be88b9b
--- /dev/null
+++ b/TrEE/Miniport/SampleMiniport.h
@@ -0,0 +1,30 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+ sample.h
+
+Abstract:
+
+ The shared header file for the sample TrEE miniport driver.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+//
+// Device context
+//
+
+typedef struct _TREE_SAMPLE_DEVICE_CONTEXT {
+ WDFDEVICE MasterDevice;
+} TREE_SAMPLE_DEVICE_CONTEXT, *PTREE_SAMPLE_DEVICE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(TREE_SAMPLE_DEVICE_CONTEXT);
+
+TR_SECURE_SERVICE_CALLBACKS TestServiceCallbacks;
+TR_SECURE_SERVICE_CALLBACKS Test2ServiceCallbacks; \ No newline at end of file
diff --git a/TrEE/Miniport/SampleMiniport.rc b/TrEE/Miniport/SampleMiniport.rc
new file mode 100644
index 00000000..2741cb72
--- /dev/null
+++ b/TrEE/Miniport/SampleMiniport.rc
@@ -0,0 +1,14 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
+#define VER_FILEDESCRIPTION_STR "Sample TREE Client Driver"
+#define VER_INTERNALNAME_STR "TrEEMiniportSample.sys"
+
+#include "common.ver"
+
+
diff --git a/TrEE/Miniport/TestService.c b/TrEE/Miniport/TestService.c
new file mode 100644
index 00000000..ef465297
--- /dev/null
+++ b/TrEE/Miniport/TestService.c
@@ -0,0 +1,1332 @@
+#include <ntddk.h>
+#include <wdf.h>
+#include <initguid.h>
+#include <wdmguid.h>
+#include <TrustedRuntimeClx.h>
+#include "SampleMiniport.h"
+#include <SampleSecureService.h>
+#include <SampleOSService.h>
+
+EVT_TR_CREATE_SECURE_SERVICE_CONTEXT TestServiceCreateSecureServiceContext;
+EVT_TR_DESTROY_SECURE_SERVICE_CONTEXT TestServiceDestroySecureServiceContext;
+EVT_TR_CONNECT_SECURE_SERVICE TestServiceConnectSecureService;
+EVT_TR_DISCONNECT_SECURE_SERVICE TestServiceDisconnectSecureService;
+EVT_TR_CREATE_SECURE_SERVICE_SESSION_CONTEXT TestServiceCreateSessionContext;
+EVT_TR_DESTROY_SECURE_SERVICE_SESSION_CONTEXT TestServiceDestroySessionContext;
+EVT_TR_PROCESS_SECURE_SERVICE_REQUEST TestServiceProcessSecureServiceRequest;
+EVT_TR_CANCEL_SECURE_SERVICE_REQUEST TestServiceCancelSecureServiceRequest;
+EVT_TR_PROCESS_OTHER_SECURE_SERVICE_IO TestServiceProcessOtherSecureServiceIo;
+
+EVT_TR_PROCESS_SECURE_SERVICE_REQUEST Test2ServiceProcessSecureServiceRequest;
+
+#pragma data_seg("PAGED")
+
+TR_SECURE_SERVICE_CALLBACKS TestServiceCallbacks = {
+ 0,
+
+ &TestServiceCreateSecureServiceContext,
+ &TestServiceDestroySecureServiceContext,
+
+ &TestServiceConnectSecureService,
+ &TestServiceDisconnectSecureService,
+
+ &TestServiceCreateSessionContext,
+ &TestServiceDestroySessionContext,
+
+ &TestServiceProcessSecureServiceRequest,
+ &TestServiceCancelSecureServiceRequest,
+ &TestServiceProcessOtherSecureServiceIo
+};
+
+TR_SECURE_SERVICE_CALLBACKS Test2ServiceCallbacks = {
+ 0,
+
+ &TestServiceCreateSecureServiceContext,
+ &TestServiceDestroySecureServiceContext,
+
+ &TestServiceConnectSecureService,
+ &TestServiceDisconnectSecureService,
+
+ &TestServiceCreateSessionContext,
+ &TestServiceDestroySessionContext,
+
+ &Test2ServiceProcessSecureServiceRequest,
+ &TestServiceCancelSecureServiceRequest,
+ &TestServiceProcessOtherSecureServiceIo
+};
+
+#pragma data_seg()
+
+typedef struct _TEST_SERVICE_CONTEXT {
+ GUID ServiceGuid;
+} TEST_SERVICE_CONTEXT, *PTEST_SERVICE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(TEST_SERVICE_CONTEXT);
+
+//
+// Macro to convert between forced 64-bit pointers to native
+//
+#define TruncatePointer64(_Pointer) ((PVOID)(ULONG_PTR)(ULONG64)(_Pointer))
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceCreateSecureServiceContext(
+ WDFDEVICE MasterDevice,
+ LPCGUID ServiceGuid,
+ WDFDEVICE ServiceDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when a secure service is being created.
+
+ Arguments:
+
+ MasterDevice - Supplies a handle to the master device object.
+
+ ServiceGuid - Supplies GUID of the secure service.
+
+ ServiceDevice - Supplies a handle to the new service device object
+ being created.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDF_OBJECT_ATTRIBUTES ContextAttributes;
+ PTEST_SERVICE_CONTEXT ServiceContext;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(MasterDevice);
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ContextAttributes,
+ TEST_SERVICE_CONTEXT);
+
+ Status = WdfObjectAllocateContext(ServiceDevice,
+ &ContextAttributes,
+ &ServiceContext);
+
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceCreateSecureServiceContextEnd;
+ }
+
+ ServiceContext->ServiceGuid = *ServiceGuid;
+
+TestServiceCreateSecureServiceContextEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceDestroySecureServiceContext(
+ WDFDEVICE ServiceDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when a secure service is being destroyed.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceConnectSecureService(
+ WDFDEVICE ServiceDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when a secure service is being used for the
+ first time or has returned from a power-state change.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceDisconnectSecureService(
+ WDFDEVICE ServiceDevice
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to disconnect a secure service in preparation
+ for a possible power-state change.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceCreateSessionContext(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT *SessionContextObject
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called on creation of a new session to a secure
+ service. This can be used to track any state through multiple requests
+ from the same client.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to hold any session state that may
+ be required for future calls.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(SessionContextObject);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceDestroySessionContext(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT *SessionContextObject
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called on destruction a session.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to the session context.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(SessionContextObject);
+
+ return STATUS_SUCCESS;
+}
+
+typedef
+NTSTATUS
+TREE_TEST_SERVICE_REQUEST_HANDLER(
+ _In_ WDFDEVICE ServiceDevice,
+ _In_ PTEST_SERVICE_CONTEXT ServiceContext,
+ _In_ PVOID RequestHandle,
+ _In_ KPRIORITY Priority,
+ _In_ PTR_SERVICE_REQUEST Request,
+ _In_ ULONG Flags,
+ _Out_ PULONG_PTR BytesWritten,
+ _Inout_opt_ PVOID* RequestContext
+ );
+
+TREE_TEST_SERVICE_REQUEST_HANDLER TestServiceHelloWorld;
+TREE_TEST_SERVICE_REQUEST_HANDLER TestServiceInterruptTime;
+TREE_TEST_SERVICE_REQUEST_HANDLER TestServiceKernelOnly;
+TREE_TEST_SERVICE_REQUEST_HANDLER TestServiceDelayedCompletion;
+
+TREE_TEST_SERVICE_REQUEST_HANDLER *TestServiceDispatch[] = {
+ NULL,
+ TestServiceHelloWorld,
+ TestServiceInterruptTime,
+ TestServiceKernelOnly,
+ TestServiceDelayedCompletion,
+};
+
+TREE_TEST_SERVICE_REQUEST_HANDLER Test2ServiceEchoTest;
+TREE_TEST_SERVICE_REQUEST_HANDLER Test2ServiceTwiceReversed;
+
+TREE_TEST_SERVICE_REQUEST_HANDLER *Test2ServiceDispatch[] = {
+ NULL,
+ Test2ServiceEchoTest,
+ Test2ServiceTwiceReversed,
+};
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceProcessSecureServiceRequest(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT SessionContextObject,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to process a request to the secure service.
+ This is typically the only way communication would be done to a secure
+ service.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to the context.
+
+ RequestHandle - Supplies a pointer to a request handle that will be
+ used if the operation completes asynchronously.
+
+ Priority - Supplies the priority of the request.
+
+ Request - Supplies a pointer to the data for the request.
+
+ RequestorMode - Supplies where the request originated from.
+
+ BytesWritten - Supplies a pointer to be filled out with the number of
+ bytes written.
+
+ RequestContext - Supplies a pointer to a PVOID variable where
+ additional information needed to cancel the request.
+ It will be provided in TestServiceCancelSecureServiceRequest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PTEST_SERVICE_CONTEXT ServiceContext;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(SessionContextObject);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ *BytesWritten = 0;
+ if ((Request->FunctionCode == 0) ||
+ (Request->FunctionCode >= sizeof(TestServiceDispatch)/sizeof(TestServiceDispatch[0]))) {
+
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ServiceContext = WdfObjectGet_TEST_SERVICE_CONTEXT(ServiceDevice);
+ return (*TestServiceDispatch[Request->FunctionCode])(ServiceDevice,
+ ServiceContext,
+ RequestHandle,
+ Priority,
+ Request,
+ Flags,
+ BytesWritten,
+ RequestContext);
+}
+
+#pragma region Test service request handlers
+
+#define STR_HELLO_WORLD L"Hello, world!"
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceHelloWorld(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine will write classic L"Hello, world!" message to the output
+ buffer. If output buffer is too small, BytesWritten field in the
+ response struct will contain the required size.
+
+ Arguments:
+
+ ServiceContext - Supplies a pointer to service device context object.
+
+ Refer to TestServiceProcessSecureServiceRequest for the rest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ *BytesWritten = sizeof(STR_HELLO_WORLD);
+ if (Request->OutputBufferSize < sizeof(STR_HELLO_WORLD)) {
+ //
+ // STATUS_BUFFER_OVERFLOW must be used to make WDF forward the value of
+ // *BytesWritten to let Win32 caller know how large the output buffer
+ // should be.
+ //
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ RtlCopyMemory(Request->OutputBuffer, STR_HELLO_WORLD, sizeof(STR_HELLO_WORLD));
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceInterruptTime(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine will write the value returned from
+ KeQueryInterruptTimePrecise in the output buffer.
+
+ Arguments:
+
+ ServiceContext - Supplies a pointer to service device context object.
+
+ Refer to TestServiceProcessSecureServiceRequest for the rest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ ULONG64 QpcTimestamp;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ *BytesWritten = sizeof(ULONG64);
+ if (Request->OutputBufferSize < sizeof(ULONG64)) {
+ //
+ // STATUS_BUFFER_OVERFLOW must be used to make WDF forward the value of
+ // *BytesWritten to let Win32 caller know how large the output buffer
+ // should be.
+ //
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ *(PULONG64)TruncatePointer64(Request->OutputBuffer) = KeQueryInterruptTimePrecise(&QpcTimestamp);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceKernelOnly(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine does nothing. However, if this request was sent from
+ usermode, it will complete with failure status code.
+
+ Arguments:
+
+ ServiceContext - Supplies a pointer to service device context object.
+
+ Refer to TestServiceProcessSecureServiceRequest for the rest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Request);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ *BytesWritten = 0;
+ if (Flags & TR_SERVICE_REQUEST_FROM_USERMODE) {
+ return STATUS_ACCESS_DENIED;
+
+ } else {
+
+ return STATUS_SUCCESS;
+ }
+}
+
+typedef struct _DELAYED_COMPLETION_TIMER_CONTEXT {
+ union {
+ PVOID RequestHandle;
+ WDFREQUEST Request;
+ } Request;
+ WDFWORKITEM WorkItem;
+ PVOID OutputBuffer;
+} DELAYED_COMPLETION_TIMER_CONTEXT, *PDELAYED_COMPLETION_TIMER_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(DELAYED_COMPLETION_TIMER_CONTEXT);
+
+EVT_WDF_TIMER DelayedCompletionTimerCallback;
+EVT_WDF_WORKITEM DelayedCompletionWorkItemCallback;
+
+_Use_decl_annotations_
+VOID
+DelayedCompletionTimerCallback(
+ WDFTIMER Timer
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is the callback for the timer used in delayed completion
+ request handler. It'll enqueue a work item to complete the request and
+ clean up resources.
+
+ Arguments:
+
+ Timer - Supplies a handle to the timer.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ PDELAYED_COMPLETION_TIMER_CONTEXT Context;
+
+ Context = WdfObjectGet_DELAYED_COMPLETION_TIMER_CONTEXT(Timer);
+ WdfWorkItemEnqueue(Context->WorkItem);
+}
+
+_Use_decl_annotations_
+VOID
+DelayedCompletionWorkItemCallback(
+ WDFWORKITEM WorkItem
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is enqueued from delayed completion timer callback. Since
+ a timer cannot be deleted inside its handler, it is deleted here
+ instead. Also the request is completed here.
+
+ Arguments:
+
+ WorkItem - Supplies a handle to this work item.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ PDELAYED_COMPLETION_TIMER_CONTEXT Context;
+ WDFTIMER Timer;
+
+ PAGED_CODE();
+
+ Timer = (WDFTIMER)WdfWorkItemGetParentObject(WorkItem);
+ Context = WdfObjectGet_DELAYED_COMPLETION_TIMER_CONTEXT(Timer);
+ *(PULONG)Context->OutputBuffer = 0x12345678;
+
+ //
+ // The request couldn't have been canceled if we reach here. The
+ // cancellation routine tries to stop the timer and prevent callback from
+ // being called. If it succeeds, this routine never runs. If it fails, the
+ // request is not canceled.
+ //
+ TrSecureDeviceCompleteAsyncRequest(Context->Request.RequestHandle,
+ STATUS_SUCCESS,
+ sizeof(ULONG));
+
+ WdfObjectDelete(Timer);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+TestServiceDelayedCompletion(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine completes the request after specified delay. The delay is
+ given in input buffer as ULONG in units of milliseconds. When
+ completed, output buffer will contain 0x12345678 ULONG value.
+
+ Arguments:
+
+ ServiceContext - Supplies a pointer to service device context object.
+
+ Refer to TestServiceProcessSecureServiceRequest for the rest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ PDELAYED_COMPLETION_TIMER_CONTEXT Context;
+ NTSTATUS Status;
+ WDFTIMER Timer;
+ WDF_OBJECT_ATTRIBUTES TimerAttributes;
+ WDF_TIMER_CONFIG TimerConfig;
+ WDF_OBJECT_ATTRIBUTES WorkItemAttributes;
+ WDF_WORKITEM_CONFIG WorkItemConfig;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(BytesWritten);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ if (Request->InputBufferSize < sizeof(ULONG)) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (Request->OutputBufferSize < sizeof(ULONG)) {
+ //
+ // STATUS_BUFFER_OVERFLOW must be used to make WDF forward the value of
+ // *BytesWritten to let Win32 caller know how large the output buffer
+ // should be.
+ //
+ *BytesWritten = sizeof(ULONG);
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ *BytesWritten = 0;
+ Timer = NULL;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&TimerAttributes, DELAYED_COMPLETION_TIMER_CONTEXT);
+ WDF_TIMER_CONFIG_INIT(&TimerConfig, DelayedCompletionTimerCallback);
+ TimerAttributes.ExecutionLevel = WdfExecutionLevelDispatch;
+ TimerAttributes.ParentObject = ServiceDevice;
+ Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &Timer);
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceDelayedCompletionEnd;
+ }
+
+ Context = WdfObjectGet_DELAYED_COMPLETION_TIMER_CONTEXT(Timer);
+ Context->Request.RequestHandle = RequestHandle;
+ Context->OutputBuffer = TruncatePointer64(Request->OutputBuffer);
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&WorkItemAttributes);
+ WDF_WORKITEM_CONFIG_INIT(&WorkItemConfig, DelayedCompletionWorkItemCallback);
+ WorkItemAttributes.ParentObject = Timer;
+ Status = WdfWorkItemCreate(&WorkItemConfig, &WorkItemAttributes, &Context->WorkItem);
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceDelayedCompletionEnd;
+ }
+
+ //
+ // Set timer due after given delay
+ //
+ WdfTimerStart(Timer, WDF_REL_TIMEOUT_IN_MS(*(PULONG)TruncatePointer64(Request->InputBuffer)));
+ Status = STATUS_PENDING;
+
+ //
+ // RequestContext stores the data that is needed when canceling the request
+ //
+ *RequestContext = (PVOID)Timer;
+
+TestServiceDelayedCompletionEnd:
+ if (!NT_SUCCESS(Status)) {
+ if (Timer != NULL) {
+ WdfObjectDelete(Timer);
+ }
+
+ //
+ // WorkItem is automatically deleted when parent object (Timer) is
+ // destroyed.
+ //
+ }
+
+ return Status;
+}
+
+#pragma endregion
+
+_Use_decl_annotations_
+NTSTATUS
+Test2ServiceProcessSecureServiceRequest(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT SessionContextObject,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to process a request to the secure service.
+ This is typically the only way communication would be done to a secure
+ service.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to the context.
+
+ RequestHandle - Supplies a pointer to a request handle that will be
+ used if the operation completes asynchronously.
+
+ Priority - Supplies the priority of the request.
+
+ Request - Supplies a pointer to the data for the request.
+
+ RequestorMode - Supplies where the request originated from.
+
+ BytesWritten - Supplies a pointer to be filled out with the number of
+ bytes written.
+
+ RequestContext - Supplies a pointer to a PVOID variable where
+ additional information needed to cancel the request.
+ It will be provided in TestServiceCancelSecureServiceRequest.
+ This address is valid until the request is completed
+ or canceled.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PTEST_SERVICE_CONTEXT ServiceContext;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(SessionContextObject);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ *BytesWritten = 0;
+ if ((Request->FunctionCode == 0) ||
+ (Request->FunctionCode >= sizeof(Test2ServiceDispatch)/sizeof(Test2ServiceDispatch[0]))) {
+
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ServiceContext = WdfObjectGet_TEST_SERVICE_CONTEXT(ServiceDevice);
+ return (*Test2ServiceDispatch[Request->FunctionCode])(ServiceDevice,
+ ServiceContext,
+ RequestHandle,
+ Priority,
+ Request,
+ Flags,
+ BytesWritten,
+ RequestContext);
+}
+
+#pragma region Test2 service request handlers
+
+_Use_decl_annotations_
+NTSTATUS
+Test2ServiceEchoTest(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+{
+ TR_SERVICE_REQUEST OSServiceRequest = {0};
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ OSServiceRequest.FunctionCode = ECHO_SERVICE_ECHO;
+ OSServiceRequest.InputBuffer = Request->InputBuffer;
+ OSServiceRequest.InputBufferSize = Request->InputBufferSize;
+ OSServiceRequest.OutputBuffer = Request->OutputBuffer;
+ OSServiceRequest.OutputBufferSize = Request->OutputBufferSize;
+ Status = TrSecureDeviceCallOSService(ServiceDevice,
+ &GUID_ECHO_SERVICE,
+ &OSServiceRequest,
+ BytesWritten);
+
+ //
+ // OS service calls never returns STATUS_PENDING. No need to take care of
+ // asynchronous processing.
+ //
+
+ NT_ASSERT(Status != STATUS_PENDING);
+
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+Test2ServiceTwiceReversed(
+ WDFDEVICE ServiceDevice,
+ PTEST_SERVICE_CONTEXT ServiceContext,
+ PVOID RequestHandle,
+ KPRIORITY Priority,
+ PTR_SERVICE_REQUEST Request,
+ ULONG Flags,
+ PULONG_PTR BytesWritten,
+ PVOID* RequestContext
+ )
+{
+ PVOID TemporaryBuffer;
+ ULONG_PTR OSServiceBytesWritten;
+ TR_SERVICE_REQUEST OSServiceRequest = {0};
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceContext);
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(RequestHandle);
+ UNREFERENCED_PARAMETER(RequestContext);
+
+ TemporaryBuffer = NULL;
+
+ *BytesWritten = (ULONG_PTR)(Request->InputBufferSize * 2);
+ if (Request->OutputBufferSize < Request->InputBufferSize * 2) {
+ //
+ // STATUS_BUFFER_OVERFLOW must be used to make WDF forward the value of
+ // *BytesWritten to let Win32 caller know how large the output buffer
+ // should be.
+ //
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto TestServiceTwiceReversedEnd;
+ }
+
+ TemporaryBuffer = ExAllocatePoolWithTag(PagedPool,
+ (SIZE_T)Request->InputBufferSize,
+ 'PMET');
+
+ if (TemporaryBuffer == NULL) {
+ *BytesWritten = 0;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto TestServiceTwiceReversedEnd;
+ }
+
+ OSServiceRequest.FunctionCode = ECHO_SERVICE_REVERSE;
+ OSServiceRequest.InputBuffer = Request->InputBuffer;
+ OSServiceRequest.InputBufferSize = Request->InputBufferSize;
+ OSServiceRequest.OutputBuffer = TemporaryBuffer;
+ OSServiceRequest.OutputBufferSize = Request->InputBufferSize;
+ Status = TrSecureDeviceCallOSService(ServiceDevice,
+ &GUID_ECHO_SERVICE,
+ &OSServiceRequest,
+ &OSServiceBytesWritten);
+
+ NT_ASSERT(Status != STATUS_PENDING);
+ NT_ASSERT(OSServiceBytesWritten == Request->InputBufferSize);
+
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceTwiceReversedEnd;
+ }
+
+ OSServiceRequest.FunctionCode = ECHO_SERVICE_REPEAT;
+ OSServiceRequest.InputBuffer = TemporaryBuffer;
+ OSServiceRequest.InputBufferSize = Request->InputBufferSize;
+ OSServiceRequest.OutputBuffer = Request->OutputBuffer;
+ OSServiceRequest.OutputBufferSize = Request->InputBufferSize * 2;
+ Status = TrSecureDeviceCallOSService(ServiceDevice,
+ &GUID_ECHO_SERVICE,
+ &OSServiceRequest,
+ &OSServiceBytesWritten);
+
+ NT_ASSERT(Status != STATUS_PENDING);
+ NT_ASSERT(OSServiceBytesWritten == Request->InputBufferSize * 2);
+
+TestServiceTwiceReversedEnd:
+ if (TemporaryBuffer != NULL) {
+ ExFreePool(TemporaryBuffer);
+ }
+
+ return Status;
+}
+
+#pragma endregion
+
+_Use_decl_annotations_
+VOID
+TestServiceCancelSecureServiceRequest(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT SessionContextObject,
+ PVOID RequestHandle,
+ PVOID* RequestContext
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to cancel a request made via a previous call to
+ TestServiceProcessSecureServiceRequest. Note that cancellation is
+ best-effort, and on success would result in STATUS_CANCELLED being
+ returned from the original request.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to the context.
+
+ RequestHandle - Supplies the request handle for which a cancellation
+ is being requested.
+
+ RequestContext - Supplies a pointer to a PVOID variable where
+ additional information needed to cancel the request
+ set in TestServiceProcessSecureServiceRequest.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ BOOLEAN Stopped;
+ WDFTIMER Timer;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(SessionContextObject);
+
+ if (RequestContext != NULL) {
+ //
+ // This request is the delayed completion request. Try to cancel the
+ // request by stopping the timer.
+ //
+ Timer = (WDFTIMER)*RequestContext;
+ Stopped = WdfTimerStop(Timer, FALSE);
+ if (Stopped) {
+ //
+ // Complete the request with cancelled status.
+ //
+ TrSecureDeviceCompleteAsyncRequest(RequestHandle, STATUS_CANCELLED, 0);
+ WdfObjectDelete(Timer);
+
+ } else {
+ //
+ // The timer routine is already running or completed. The request
+ // is going to be completed by timer and work item callback.
+ //
+ }
+ } else {
+ //
+ // There's nothing we can do for other types of request.
+ //
+ }
+
+ return;
+}
+
+typedef struct _OTHERIO_DELAYED_COMPLETION_CONTEXT {
+ WDFTIMER Timer;
+} OTHERIO_DELAYED_COMPLETION_CONTEXT, *POTHERIO_DELAYED_COMPLETION_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(OTHERIO_DELAYED_COMPLETION_CONTEXT);
+
+EVT_WDF_REQUEST_CANCEL OtherIoDelayedCompletionCancel;
+EVT_WDF_WORKITEM OtherIoDelayedCompletionWorkItemCallback;
+
+_Use_decl_annotations_
+VOID
+OtherIoDelayedCompletionCancel(
+ WDFREQUEST Request
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called to cancel delayed completion request in other
+ service I/O. Other I/O path uses WDF request objects as it is, so we
+ cannot reuse TestServiceCancelSecureServiceRequest.
+
+ Arguments:
+
+ Request - Supplies a handle to the request to be canceled.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+
+ POTHERIO_DELAYED_COMPLETION_CONTEXT RequestContext;
+ BOOLEAN Stopped;
+ WDFTIMER Timer;
+
+ PAGED_CODE();
+
+ RequestContext = WdfObjectGet_OTHERIO_DELAYED_COMPLETION_CONTEXT(Request);
+ Timer = RequestContext->Timer;
+ Stopped = WdfTimerStop(Timer, FALSE);
+ if (Stopped) {
+ WdfRequestComplete(Request, STATUS_CANCELLED);
+
+ //
+ // RequestContext is no more valid from here.
+ //
+ WdfObjectDelete(Timer);
+ }
+}
+
+_Use_decl_annotations_
+VOID
+OtherIoDelayedCompletionWorkItemCallback(
+ WDFWORKITEM WorkItem
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is enqueued from delayed completion timer callback. Since
+ a timer cannot be deleted inside its handler, it is deleted here
+ instead. Also the request is completed here.
+
+ Arguments:
+
+ WorkItem - Supplies a handle to this work item.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ PDELAYED_COMPLETION_TIMER_CONTEXT Context;
+ NTSTATUS Status;
+ WDFTIMER Timer;
+
+ PAGED_CODE();
+
+ Timer = (WDFTIMER)WdfWorkItemGetParentObject(WorkItem);
+ Context = WdfObjectGet_DELAYED_COMPLETION_TIMER_CONTEXT(Timer);
+ *(PULONG)Context->OutputBuffer = 0x12345678;
+
+ Status = WdfRequestUnmarkCancelable(Context->Request.Request);
+ if (Status != STATUS_CANCELLED) {
+ WdfRequestCompleteWithInformation(Context->Request.Request,
+ STATUS_SUCCESS,
+ sizeof(ULONG));
+ }
+
+ WdfObjectDelete(Timer);
+}
+
+_Use_decl_annotations_
+VOID
+TestServiceProcessOtherSecureServiceIo(
+ WDFDEVICE ServiceDevice,
+ WDFOBJECT SessionContextObject,
+ WDFREQUEST Request
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when an unrecognized IO request is made to a
+ secure service. This can be used to process private calls.
+
+ Arguments:
+
+ ServiceDevice - Supplies a handle to the service device object.
+
+ SessionContext - Supplies a pointer to the context.
+
+ Request - Supplies a pointer to the WDF request object.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDF_REQUEST_PARAMETERS Parameters;
+ NTSTATUS Status;
+ PVOID InputBuffer;
+ PVOID OutputBuffer;
+ ULONG_PTR BytesWritten;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(ServiceDevice);
+ UNREFERENCED_PARAMETER(SessionContextObject);
+
+ BytesWritten = 0;
+
+ WDF_REQUEST_PARAMETERS_INIT(&Parameters);
+ WdfRequestGetParameters(Request, &Parameters);
+ switch (Parameters.Parameters.DeviceIoControl.IoControlCode) {
+ case IOCTL_TEST_DELAYED_COMPLETION:
+ {
+ POTHERIO_DELAYED_COMPLETION_CONTEXT RequestContext;
+ WDF_OBJECT_ATTRIBUTES RequestAttributes;
+ WDFTIMER Timer;
+ WDF_OBJECT_ATTRIBUTES TimerAttributes;
+ WDF_TIMER_CONFIG TimerConfig;
+ PDELAYED_COMPLETION_TIMER_CONTEXT TimerContext;
+ WDF_OBJECT_ATTRIBUTES WorkItemAttributes;
+ WDF_WORKITEM_CONFIG WorkItemConfig;
+
+ Status = WdfRequestRetrieveInputBuffer(Request,
+ sizeof(ULONG),
+ &InputBuffer,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceProcessOtherSecureServiceIoEnd;
+ }
+
+ Status = WdfRequestRetrieveOutputBuffer(Request,
+ sizeof(ULONG),
+ &OutputBuffer,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ BytesWritten = sizeof(ULONG);
+ if (Status == STATUS_BUFFER_TOO_SMALL) {
+ //
+ // STATUS_BUFFER_OVERFLOW must be used to make WDF forward the value of
+ // *BytesWritten to let Win32 caller know how large the output buffer
+ // should be.
+ //
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+
+ goto TestServiceProcessOtherSecureServiceIoEnd;
+ }
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
+ &RequestAttributes,
+ OTHERIO_DELAYED_COMPLETION_CONTEXT);
+
+ Status = WdfObjectAllocateContext(Request,
+ &RequestAttributes,
+ &RequestContext);
+
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceProcessOtherSecureServiceIoEnd;
+ }
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
+ &TimerAttributes,
+ DELAYED_COMPLETION_TIMER_CONTEXT);
+
+ WDF_TIMER_CONFIG_INIT(&TimerConfig, DelayedCompletionTimerCallback);
+ TimerAttributes.ExecutionLevel = WdfExecutionLevelDispatch;
+ TimerAttributes.ParentObject = ServiceDevice;
+ Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &Timer);
+ if (!NT_SUCCESS(Status)) {
+ goto TestServiceProcessOtherSecureServiceIoEnd;
+ }
+
+ RequestContext->Timer =Timer;
+
+ TimerContext = WdfObjectGet_DELAYED_COMPLETION_TIMER_CONTEXT(Timer);
+ TimerContext->Request.Request = Request;
+ TimerContext->OutputBuffer = TruncatePointer64(OutputBuffer);
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&WorkItemAttributes);
+ WDF_WORKITEM_CONFIG_INIT(&WorkItemConfig,
+ OtherIoDelayedCompletionWorkItemCallback);
+
+ WorkItemAttributes.ParentObject = Timer;
+ Status = WdfWorkItemCreate(&WorkItemConfig,
+ &WorkItemAttributes,
+ &TimerContext->WorkItem);
+
+ if (!NT_SUCCESS(Status)) {
+ WdfObjectDelete(Timer);
+ goto TestServiceProcessOtherSecureServiceIoEnd;
+ }
+
+ //
+ // Set timer due after given delay
+ //
+ WdfTimerStart(Timer,
+ WDF_REL_TIMEOUT_IN_MS(
+ *(PULONG)TruncatePointer64(InputBuffer)));
+
+ WdfRequestMarkCancelable(Request, OtherIoDelayedCompletionCancel);
+ return;
+ }
+
+ default:
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+TestServiceProcessOtherSecureServiceIoEnd:
+ WdfRequestCompleteWithInformation(Request, Status, BytesWritten);
+}
diff --git a/TrEE/Miniport/TrEEMiniportSample.inf b/TrEE/Miniport/TrEEMiniportSample.inf
new file mode 100644
index 00000000..c1ba30a2
--- /dev/null
+++ b/TrEE/Miniport/TrEEMiniportSample.inf
Binary files differ
diff --git a/TrEE/Miniport/TrEEMiniportSample.vcxproj b/TrEE/Miniport/TrEEMiniportSample.vcxproj
new file mode 100644
index 00000000..0876f610
--- /dev/null
+++ b/TrEE/Miniport/TrEEMiniportSample.vcxproj
@@ -0,0 +1,241 @@
+<?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>{C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{3B965B2A-2DDB-4998-9077-9A498A025FA5}</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>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</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>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetName>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>TrEEMiniportSample</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\treeclxstub.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleminiport.c" />
+ <ClCompile Include="TestService.c" />
+ <ResourceCompile Include="sampleminiport.rc" />
+ </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/Miniport/TrEEMiniportSample.vcxproj.Filters b/TrEE/Miniport/TrEEMiniportSample.vcxproj.Filters
new file mode 100644
index 00000000..7a7caa08
--- /dev/null
+++ b/TrEE/Miniport/TrEEMiniportSample.vcxproj.Filters
@@ -0,0 +1,34 @@
+<?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>{369B4A00-B5B6-4158-886B-B676FE70F762}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{2B3E08A5-0B2C-479D-9F39-45BE166BF0E5}</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>{DCB257CE-46C6-4A90-809D-497094D76086}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{294EE363-C76D-48F8-AA82-1E45F3DE6D3D}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleminiport.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TestService.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="sampleminiport.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/TrEE/OSService/SampleOSService.c b/TrEE/OSService/SampleOSService.c
new file mode 100644
index 00000000..b75cfb88
--- /dev/null
+++ b/TrEE/OSService/SampleOSService.c
@@ -0,0 +1,928 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+ sampleservice.c
+
+Abstract:
+
+ This file demonstrates a simple service plugin for the TREE class extension driver.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <ntstrsafe.h>
+#include <initguid.h>
+#include <wdmguid.h>
+#include <TrustedRuntimeClx.h>
+#include <SampleOSService.h>
+
+typedef enum _SAMPLE_SERVICE_TYPE {
+ SampleServiceEcho,
+ SampleServiceKernelMemory
+} SAMPLE_SERVICE_TYPE;
+
+typedef struct _SAMPLE_SERVICE_FILE_CONTEXT {
+ SAMPLE_SERVICE_TYPE ServiceType;
+} SAMPLE_SERVICE_FILE_CONTEXT, *PSAMPLE_SERVICE_FILE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(SAMPLE_SERVICE_FILE_CONTEXT);
+
+typedef
+NTSTATUS
+SAMPLE_SERVICE_REQUEST_HANDLER(
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ size_t InputBufferLength,
+ _Out_writes_bytes_to_(OutputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ size_t OutputBufferLength,
+ _Out_ size_t* BytesWritten
+ );
+
+//
+// Driver entry point
+//
+
+DRIVER_INITIALIZE DriverEntry;
+
+//
+// Device callbacks
+//
+
+EVT_WDF_DRIVER_UNLOAD DriverUnload;
+EVT_WDF_DRIVER_DEVICE_ADD SampleServiceEvtAddDevice;
+EVT_WDF_DEVICE_D0_ENTRY SampleServiceEvtD0Entry;
+EVT_WDF_DEVICE_D0_EXIT SampleServiceEvtD0Exit;
+EVT_WDF_DEVICE_FILE_CREATE SampleServiceEvtCreateFile;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtInternalIoctl;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtQuery;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtExecute;
+SAMPLE_SERVICE_REQUEST_HANDLER SampleServiceEchoHandler;
+SAMPLE_SERVICE_REQUEST_HANDLER SampleServiceKernelMemoryHandler;
+
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, DriverUnload)
+#pragma alloc_text(PAGE, SampleServiceEvtAddDevice)
+#pragma alloc_text(PAGE, SampleServiceEvtCreateFile)
+#pragma alloc_text(PAGE, SampleServiceEvtInternalIoctl)
+#pragma alloc_text(PAGE, SampleServiceEvtQuery)
+#pragma alloc_text(PAGE, SampleServiceEvtExecute)
+#pragma alloc_text(PAGE, SampleServiceEchoHandler)
+#pragma alloc_text(PAGE, SampleServiceKernelMemoryHandler)
+
+#pragma data_seg("PAGED")
+
+DECLARE_CONST_UNICODE_STRING(GUID_ECHO_SERVICE_STRING,
+ L"{33C7FF13-50B0-454A-8BEB-F73EED6C0AF9}");
+
+DECLARE_CONST_UNICODE_STRING(GUID_KERNEL_MEMORY_SERVICE_STRING,
+ L"{D28698A4-3B07-4F34-B65E-AE3DA6ACF2AC}");
+
+#pragma data_seg()
+
+volatile ULONG RandomSeed;
+
+_Use_decl_annotations_
+NTSTATUS
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the initialization routine for the device driver. This routine
+ creates the driver object for the sample OS service.
+
+ Arguments:
+
+ DriverObject - Pointer to driver object created by the system.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDRIVER Driver;
+ WDF_DRIVER_CONFIG DriverConfig;
+ NTSTATUS Status;
+
+ Driver = NULL;
+
+ //
+ // Create the WDF driver object
+ //
+
+ WDF_DRIVER_CONFIG_INIT(&DriverConfig, SampleServiceEvtAddDevice);
+ DriverConfig.EvtDriverUnload = DriverUnload;
+ DriverConfig.DriverPoolTag = 'SOMS';
+
+ Status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &DriverConfig,
+ &Driver);
+
+ if (!NT_SUCCESS(Status)) {
+ goto DriverEntryEnd;
+ }
+
+DriverEntryEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+VOID
+DriverUnload(
+ WDFDRIVER Driver
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the cleanup function called when the driver is unloaded.
+
+ Arguments:
+
+ Driver - Supplies a handle to WDFDRIVER object created in DriverEntry.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtAddDevice(
+ WDFDRIVER Driver,
+ PWDFDEVICE_INIT DeviceInit
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the driver is being attached to a specific
+ device.
+
+ Arguments:
+
+ Driver - Supplies a handle to the framework driver object.
+
+ DeviceInit - Supplies a pointer to the device initialization parameters.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDEVICE Device;
+ WDF_FILEOBJECT_CONFIG FileConfig;
+ WDF_OBJECT_ATTRIBUTES ObjectAttributes;
+ WDF_PNPPOWER_EVENT_CALLBACKS PowerCallbacks;
+ WDFQUEUE Queue;
+ WDF_IO_QUEUE_CONFIG QueueConfig;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
+ WdfDeviceInitSetDeviceType(DeviceInit, 32999);
+ WdfDeviceInitSetPowerNotPageable(DeviceInit);
+
+ //
+ // Initialize file context and register file creation handler
+ //
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ObjectAttributes,
+ SAMPLE_SERVICE_FILE_CONTEXT);
+
+ ObjectAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+ WDF_FILEOBJECT_CONFIG_INIT(&FileConfig,
+ &SampleServiceEvtCreateFile,
+ WDF_NO_EVENT_CALLBACK,
+ WDF_NO_EVENT_CALLBACK);
+
+ FileConfig.FileObjectClass = WdfFileObjectWdfCanUseFsContext;
+ WdfDeviceInitSetFileObjectConfig(DeviceInit,
+ &FileConfig,
+ &ObjectAttributes);
+
+ //
+ // Device interface will be enabled/disabled in these callbacks
+ //
+
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PowerCallbacks);
+ PowerCallbacks.EvtDeviceD0Entry = SampleServiceEvtD0Entry;
+ PowerCallbacks.EvtDeviceD0Exit = SampleServiceEvtD0Exit;
+
+ Status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &Device);
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ //
+ // Create a default queue to process requests
+ //
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&ObjectAttributes);
+ ObjectAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&QueueConfig,
+ WdfIoQueueDispatchParallel);
+
+ QueueConfig.EvtIoInternalDeviceControl = SampleServiceEvtInternalIoctl;
+ Status = WdfIoQueueCreate(Device,
+ &QueueConfig,
+ &ObjectAttributes,
+ &Queue);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ //
+ // This tells TrEE driver that this OS service is available. Two services
+ // are served by this device, and they are distinguished by filename.
+ //
+ Status = WdfDeviceCreateDeviceInterface(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ Status = WdfDeviceCreateDeviceInterface(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+SampleServiceEvtAddDeviceEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtD0Entry(
+ WDFDEVICE Device,
+ WDF_POWER_DEVICE_STATE PreviousState
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is coming back from a lower
+ power state to D0.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device was in.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(PreviousState);
+
+ RandomSeed = (ULONG)(KeQueryInterruptTime() >> 8);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING,
+ TRUE);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ TRUE);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtD0Exit(
+ WDFDEVICE Device,
+ WDF_POWER_DEVICE_STATE TargetState
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is going down to a lower
+ power state.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device is going to.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(TargetState);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING,
+ FALSE);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ FALSE);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtCreateFile(
+ WDFDEVICE Device,
+ WDFREQUEST Request,
+ WDFFILEOBJECT FileObject
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is coming back from a lower
+ power state to D0.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device was in.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ UNICODE_STRING Filename;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Device);
+
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Filename = *WdfFileObjectGetFileName(FileObject);
+ if (Filename.Buffer[0] == L'\\') {
+ ++Filename.Buffer;
+ Filename.Length -= sizeof(WCHAR);
+ Filename.MaximumLength -= sizeof(WCHAR);
+ }
+
+ //
+ // Record what service is this create request is for
+ //
+ if (RtlCompareUnicodeString(&Filename,
+ &GUID_ECHO_SERVICE_STRING,
+ TRUE) == 0) {
+
+ FileContext->ServiceType = SampleServiceEcho;
+ Status = STATUS_SUCCESS;
+
+ } else if (RtlCompareUnicodeString(&Filename,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ TRUE) == 0) {
+
+ FileContext->ServiceType = SampleServiceKernelMemory;
+ Status = STATUS_SUCCESS;
+
+ } else {
+
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtInternalIoctl(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives an OS service request
+ from TrEE class extension, which is sent as an internal device control
+ request.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ PAGED_CODE();
+
+ switch (IoControlCode) {
+ case IOCTL_TR_SERVICE_QUERY:
+ SampleServiceEvtQuery(Queue,
+ Request,
+ OutputBufferLength,
+ InputBufferLength,
+ IoControlCode);
+
+ return;
+
+ case IOCTL_TR_EXECUTE_FUNCTION:
+ SampleServiceEvtExecute(Queue,
+ Request,
+ OutputBufferLength,
+ InputBufferLength,
+ IoControlCode);
+
+ return;
+
+ default:
+ WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
+ }
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtQuery(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives a query request from
+ TrEE class extension. OS service provider fills up information about
+ the service.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ WDFFILEOBJECT FileObject;
+ PTR_SERVICE_INFORMATION ServiceInformation;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(IoControlCode);
+
+ FileObject = WdfRequestGetFileObject(Request);
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Status = WdfRequestRetrieveOutputBuffer(Request,
+ sizeof(TR_SERVICE_INFORMATION),
+ (PVOID*)&ServiceInformation,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalQueryFail;
+ }
+
+ ServiceInformation->InterfaceVersion = 1;
+ ServiceInformation->ServiceMajorVersion = 1;
+ ServiceInformation->ServiceMinorVersion = 1;
+ WdfRequestCompleteWithInformation(Request,
+ STATUS_SUCCESS,
+ sizeof(TR_SERVICE_INFORMATION));
+
+ return;
+
+SampleServiceEvtInternalQueryFail:
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtExecute(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives an OS service execute
+ request from TrEE miniport.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ size_t BytesWritten;
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ WDFFILEOBJECT FileObject;
+ PTR_SERVICE_REQUEST ServiceRequest;
+ PTR_SERVICE_REQUEST_RESPONSE ServiceResponse;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(IoControlCode);
+
+ FileObject = WdfRequestGetFileObject(Request);
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Status = WdfRequestRetrieveInputBuffer(Request,
+ sizeof(TR_SERVICE_REQUEST),
+ (PVOID*)&ServiceRequest,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ Status = WdfRequestRetrieveOutputBuffer(Request,
+ sizeof(TR_SERVICE_REQUEST_RESPONSE),
+ (PVOID*)&ServiceResponse,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ switch (FileContext->ServiceType) {
+ case SampleServiceEcho:
+ Status = SampleServiceEchoHandler(ServiceRequest->FunctionCode,
+ ServiceRequest->InputBuffer,
+ (size_t)ServiceRequest->InputBufferSize,
+ ServiceRequest->OutputBuffer,
+ (size_t)ServiceRequest->OutputBufferSize,
+ &BytesWritten);
+
+ break;
+
+ case SampleServiceKernelMemory:
+ Status = SampleServiceKernelMemoryHandler(ServiceRequest->FunctionCode,
+ ServiceRequest->InputBuffer,
+ (size_t)ServiceRequest->InputBufferSize,
+ ServiceRequest->OutputBuffer,
+ (size_t)ServiceRequest->OutputBufferSize,
+ &BytesWritten);
+ break;
+
+ default:
+ //
+ // Shouldn't reach here
+ //
+ NT_ASSERT(FALSE);
+
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ //
+ // Bytes written to the output buffer of the service request goes into here
+ //
+ ServiceResponse->BytesWritten = BytesWritten;
+
+ //
+ // Number of bytes written to WDF request's output buffer is always
+ // sizeof(TR_SERVICE_REQUEST_RESPONSE)
+ //
+ WdfRequestCompleteWithInformation(Request,
+ Status,
+ sizeof(TR_SERVICE_REQUEST_RESPONSE));
+
+ return;
+
+SampleServiceEvtInternalIoctlFail:
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEchoHandler(
+ ULONG FunctionCode,
+ PVOID InputBuffer,
+ size_t InputBufferLength,
+ PVOID OutputBuffer,
+ size_t OutputBufferLength,
+ size_t* BytesWritten
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine handles OS service requests sent to echo service.
+
+ Arguments:
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the request's input buffer,
+ if an input buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ OutputBuffer - Supplies a pointer to the request's output buffer,
+ if an output buffer is available.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ BytesWritten - Supplies a pointer to the variable where number of bytes
+ actually written to the output buffer. In case the
+ output buffer is too small to contain all the data, the
+ required size will be written.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ ULONG Index;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ switch (FunctionCode) {
+ case ECHO_SERVICE_ECHO:
+ if (OutputBufferLength < InputBufferLength) {
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceEchoHandlerEnd;
+ }
+
+ RtlCopyMemory(OutputBuffer, InputBuffer, InputBufferLength);
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ECHO_SERVICE_REPEAT:
+ *BytesWritten = 0;
+ while (OutputBufferLength >= InputBufferLength) {
+ RtlCopyMemory(OutputBuffer, InputBuffer, InputBufferLength);
+
+ OutputBuffer = (PVOID)(((ULONG_PTR)OutputBuffer) + InputBufferLength);
+ OutputBufferLength -= InputBufferLength;
+ *BytesWritten += InputBufferLength;
+ }
+
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ECHO_SERVICE_REVERSE:
+ if (OutputBufferLength < InputBufferLength) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceEchoHandlerEnd;
+ }
+
+ for (Index = 0; Index < InputBufferLength; ++Index) {
+ ((PUCHAR)OutputBuffer)[Index] = ((PUCHAR)InputBuffer)[InputBufferLength - Index - 1];
+ }
+
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+SampleServiceEchoHandlerEnd:
+ return Status;
+}
+
+UCHAR ScratchMemory[1024];
+
+NTSTATUS
+SampleServiceKernelMemoryHandler(
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ size_t InputBufferLength,
+ _Out_writes_bytes_to_(OuputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ size_t OutputBufferLength,
+ _Out_ size_t* BytesWritten
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine handles OS service requests sent to kernel memory service.
+
+ Arguments:
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the request's input buffer,
+ if an input buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ OutputBuffer - Supplies a pointer to the request's output buffer,
+ if an output buffer is available.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ BytesWritten - Supplies a pointer to the variable where number of bytes
+ actually written to the output buffer. In case the
+ output buffer is too small to contain all the data, the
+ required size will be written.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UCHAR PreviousValue;
+ NTSTATUS Status;
+ PKERNEL_MEMORY_SAFE_RANGE SafeRange;
+ PKERNEL_MEMORY_WRITE_BYTE WriteByte;
+
+ PAGED_CODE();
+
+ switch (FunctionCode) {
+ case KERNEL_MEMORY_SERVICE_GET_SAFE_RANGE:
+ if (OutputBufferLength < sizeof(KERNEL_MEMORY_SAFE_RANGE)) {
+ *BytesWritten = sizeof(KERNEL_MEMORY_SAFE_RANGE);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ SafeRange = (PKERNEL_MEMORY_SAFE_RANGE)OutputBuffer;
+ SafeRange->Base = (ULONG64)(ULONG_PTR)&ScratchMemory;
+ SafeRange->Length = sizeof(ScratchMemory);
+ *BytesWritten = sizeof(KERNEL_MEMORY_SAFE_RANGE);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KERNEL_MEMORY_SERVICE_WRITE_BYTE:
+ if (InputBufferLength < sizeof(KERNEL_MEMORY_WRITE_BYTE)) {
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ *BytesWritten = sizeof(UCHAR);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ WriteByte = (PKERNEL_MEMORY_WRITE_BYTE)InputBuffer;
+ PreviousValue = *(PUCHAR)(ULONG_PTR)WriteByte->Address;
+ *(PUCHAR)(ULONG_PTR)WriteByte->Address = WriteByte->Value;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KERNEL_MEMORY_SERVICE_READ_BYTE:
+ if (InputBufferLength < sizeof(ULONG64)) {
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ *BytesWritten = sizeof(UCHAR);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ *(PUCHAR)OutputBuffer = *(PUCHAR)(ULONG_PTR)*(PULONG64)InputBuffer;
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+SampleServiceKernelMemoryHandlerEnd:
+ return Status;
+}
diff --git a/TrEE/OSService/SampleOSService.rc b/TrEE/OSService/SampleOSService.rc
new file mode 100644
index 00000000..55dd3bef
--- /dev/null
+++ b/TrEE/OSService/SampleOSService.rc
@@ -0,0 +1,14 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
+#define VER_FILEDESCRIPTION_STR "Sample TREE Service Driver"
+#define VER_INTERNALNAME_STR "TrEEOSServiceSample.sys"
+
+#include "common.ver"
+
+
diff --git a/TrEE/OSService/TrEEOSServiceSample.inf b/TrEE/OSService/TrEEOSServiceSample.inf
new file mode 100644
index 00000000..e14149b9
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.inf
Binary files differ
diff --git a/TrEE/OSService/TrEEOSServiceSample.vcxproj b/TrEE/OSService/TrEEOSServiceSample.vcxproj
new file mode 100644
index 00000000..d3afa66a
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.vcxproj
@@ -0,0 +1,222 @@
+<?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>{7661C397-614D-4562-9CC7-6178B246DB17}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{CF6545FF-8EA5-4A78-8776-59E492F8C276}</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>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</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>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleosservice.c" />
+ <ResourceCompile Include="sampleosservice.rc" />
+ </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/OSService/TrEEOSServiceSample.vcxproj.Filters b/TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters
new file mode 100644
index 00000000..61542807
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters
@@ -0,0 +1,31 @@
+<?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>{AB2DD0E2-5CC9-4127-B1D4-1DBD5877932E}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{A955E202-DE30-4FFA-B5B6-8149773C178D}</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>{A338803C-3BF5-4F17-BD90-3269E83E92C5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{FFB2F3A5-5400-4D41-9B69-7A1B94C27388}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleosservice.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="sampleosservice.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
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
diff --git a/TrEE/TrEESample.sln b/TrEE/TrEESample.sln
new file mode 100644
index 00000000..45e6561d
--- /dev/null
+++ b/TrEE/TrEESample.sln
@@ -0,0 +1,73 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Miniport", "Miniport", "{E3F88200-7D31-4C70-97A6-83885195E581}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OSService", "OSService", "{EF1FA66C-82A9-4572-ACC7-76DEBA085FF2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{420587AA-51DE-4966-B692-C428836BF8B2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrEEMiniportSample", "Miniport\TrEEMiniportSample.vcxproj", "{C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrEEOSServiceSample", "OSService\TrEEOSServiceSample.vcxproj", "{7661C397-614D-4562-9CC7-6178B246DB17}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrEESampleTest", "Test\TrEESampleTest.vcxproj", "{DDA508B0-8C40-47C1-BC1C-AD6717E895EF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ Debug|Arm = Debug|Arm
+ Release|Arm = Release|Arm
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|Win32.Build.0 = Debug|Win32
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|Win32.ActiveCfg = Release|Win32
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|Win32.Build.0 = Release|Win32
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|x64.ActiveCfg = Debug|x64
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|x64.Build.0 = Debug|x64
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|x64.ActiveCfg = Release|x64
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|x64.Build.0 = Release|x64
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|Arm.ActiveCfg = Debug|Arm
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Debug|Arm.Build.0 = Debug|Arm
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|Arm.ActiveCfg = Release|Arm
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C}.Release|Arm.Build.0 = Release|Arm
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|Win32.Build.0 = Debug|Win32
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|Win32.ActiveCfg = Release|Win32
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|Win32.Build.0 = Release|Win32
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|x64.ActiveCfg = Debug|x64
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|x64.Build.0 = Debug|x64
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|x64.ActiveCfg = Release|x64
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|x64.Build.0 = Release|x64
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|Arm.ActiveCfg = Debug|Arm
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Debug|Arm.Build.0 = Debug|Arm
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|Arm.ActiveCfg = Release|Arm
+ {7661C397-614D-4562-9CC7-6178B246DB17}.Release|Arm.Build.0 = Release|Arm
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|Win32.Build.0 = Debug|Win32
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|Win32.ActiveCfg = Release|Win32
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|Win32.Build.0 = Release|Win32
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|x64.ActiveCfg = Debug|x64
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|x64.Build.0 = Debug|x64
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|x64.ActiveCfg = Release|x64
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|x64.Build.0 = Release|x64
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|Arm.ActiveCfg = Debug|Arm
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Debug|Arm.Build.0 = Debug|Arm
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|Arm.ActiveCfg = Release|Arm
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF}.Release|Arm.Build.0 = Release|Arm
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C1B22B3C-BE1A-40CE-82D0-8AE1628C297C} = {E3F88200-7D31-4C70-97A6-83885195E581}
+ {7661C397-614D-4562-9CC7-6178B246DB17} = {EF1FA66C-82A9-4572-ACC7-76DEBA085FF2}
+ {DDA508B0-8C40-47C1-BC1C-AD6717E895EF} = {420587AA-51DE-4966-B692-C428836BF8B2}
+ EndGlobalSection
+EndGlobal
diff --git a/TrEE/inc/SampleOSService.h b/TrEE/inc/SampleOSService.h
new file mode 100644
index 00000000..57811456
--- /dev/null
+++ b/TrEE/inc/SampleOSService.h
@@ -0,0 +1,66 @@
+#pragma once
+
+//
+// Echo service
+// GUID {33C7FF13-50B0-454A-8BEB-F73EED6C0AF9}
+//
+DEFINE_GUID(GUID_ECHO_SERVICE,
+ 0x33c7ff13, 0x50b0, 0x454a, 0x8b, 0xeb, 0xf7, 0x3e, 0xed, 0x6c, 0xa, 0xf9);
+
+//
+// Copies the content of input buffer to output buffer
+//
+#define ECHO_SERVICE_ECHO 1
+
+//
+// Repeats the content of input buffer to output buffer
+//
+#define ECHO_SERVICE_REPEAT 2
+
+//
+// Copies the bytes of input buffer to output buffer in reverse order
+//
+#define ECHO_SERVICE_REVERSE 3
+
+//
+// Kernel memory service
+// {D28698A4-3B07-4F34-B65E-AE3DA6ACF2AC}
+//
+DEFINE_GUID(GUID_KERNEL_MEMORY_SERVICE,
+ 0xd28698a4, 0x3b07, 0x4f34, 0xb6, 0x5e, 0xae, 0x3d, 0xa6, 0xac, 0xf2, 0xac);
+
+//
+// Get a safe range of kernel address space that can be read from
+//
+// Input: None
+// Output: KERNEL_MEMORY_SAFE_RANGE
+//
+
+typedef struct _KERNEL_MEMORY_SAFE_RANGE {
+ ULONG64 Base;
+ ULONG Length;
+} KERNEL_MEMORY_SAFE_RANGE, *PKERNEL_MEMORY_SAFE_RANGE;
+
+#define KERNEL_MEMORY_SERVICE_GET_SAFE_RANGE 1
+
+//
+// Write a byte to kernel address space
+//
+// Input: KERNEL_MEMORY_WRITE_BYTE
+// Output: Previous UCHAR value at the address
+//
+
+typedef struct _KERNEL_MEMORY_WRITE_BYTE {
+ ULONG64 Address;
+ UCHAR Value;
+} KERNEL_MEMORY_WRITE_BYTE, *PKERNEL_MEMORY_WRITE_BYTE;
+
+#define KERNEL_MEMORY_SERVICE_WRITE_BYTE 2
+
+//
+// Read a byte from kernel address space
+//
+// Input: ULONG64 address of kernel memory to read
+// Output: UCHAR
+//
+#define KERNEL_MEMORY_SERVICE_READ_BYTE 3 \ No newline at end of file
diff --git a/TrEE/inc/SampleSecureService.h b/TrEE/inc/SampleSecureService.h
new file mode 100644
index 00000000..66ab6141
--- /dev/null
+++ b/TrEE/inc/SampleSecureService.h
@@ -0,0 +1,72 @@
+#pragma once
+
+//
+// Sample test service
+// {4AFA2AF5-0912-407B-8B12-AFFF4047672A}
+//
+DEFINE_GUID(GUID_SAMPLE_TEST_SERVICE,
+ 0x4afa2af5, 0x912, 0x407b, 0x8b, 0x12, 0xaf, 0xff, 0x40, 0x47, 0x67, 0x2a);
+
+//
+// Writes classic L"Hello, world!" message to output buffer.
+//
+#define TEST_SERVICE_HELLO_WORLD 1
+
+//
+// Writes 64-bit timestamp returned from KeQueryInterruptTimePrecise to output
+// buffer.
+//
+#define TEST_SERVICE_GET_INTERRUPT_TIME 2
+
+//
+// A request that is only available from kernel mode
+//
+// Input: None
+// Output: None
+#define TEST_SERVICE_KERNEL_ONLY 3
+
+//
+// The request will be completed asynchronously after given delay
+//
+// Input: ULONG (delay in msec)
+// Output: ULONG (0x12345678)
+#define TEST_SERVICE_DELAYED_COMPLETION 4
+
+//
+// Sample test service consuming sample OS service
+// {D69482F9-7347-431A-8409-F625BEB3469D}
+//
+DEFINE_GUID(GUID_SAMPLE_TEST2_SERVICE,
+ 0xd69482f9, 0x7347, 0x431a, 0x84, 0x9, 0xf6, 0x25, 0xbe, 0xb3, 0x46, 0x9d);
+
+//
+// Copies contents of input buffer to output buffer
+//
+#define TEST2_SERVICE_ECHO 1
+
+//
+// Copies contents of input buffer to output buffer twice, reversed
+//
+#define TEST2_SERVICE_ECHO_TWICE_REVERSED 2
+
+//
+// Other service I/O example
+//
+
+//
+// The request will be complete asynchronously after 1 second
+// Input : NULL-terminated WCHAR[], size includes the terminating NULL character
+// Output : None
+//
+#define IOCTL_TEST_DELAYED_COMPLETION CTL_CODE(FILE_DEVICE_TRUST_ENV, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+//
+// Other device I/O example
+//
+
+//
+// Prints a string to debugger through DbgPrintEx
+// Input : NULL-terminated WCHAR[], size includes the terminating NULL character
+// Output : None
+//
+#define IOCTL_SAMPLE_DBGPRINT CTL_CODE(FILE_DEVICE_TRUST_ENV, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) \ No newline at end of file