summaryrefslogtreecommitdiff
path: root/TrEE/Miniport
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/Miniport
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'TrEE/Miniport')
-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
7 files changed, 2383 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