diff options
| author | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
|---|---|---|
| committer | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
| commit | 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch) | |
| tree | ad5f3ede5cbcd6b598677ce41bcf8318471bdd92 /TrEE/Miniport | |
| parent | 687b274aa38fd05c8c26e3068932121876d7f745 (diff) | |
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'TrEE/Miniport')
| -rw-r--r-- | TrEE/Miniport/SampleMiniport.c | 732 | ||||
| -rw-r--r-- | TrEE/Miniport/SampleMiniport.h | 30 | ||||
| -rw-r--r-- | TrEE/Miniport/SampleMiniport.rc | 14 | ||||
| -rw-r--r-- | TrEE/Miniport/TestService.c | 1332 | ||||
| -rw-r--r-- | TrEE/Miniport/TrEEMiniportSample.inf | bin | 0 -> 4652 bytes | |||
| -rw-r--r-- | TrEE/Miniport/TrEEMiniportSample.vcxproj | 241 | ||||
| -rw-r--r-- | TrEE/Miniport/TrEEMiniportSample.vcxproj.Filters | 34 |
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 Binary files differnew file mode 100644 index 00000000..c1ba30a2 --- /dev/null +++ b/TrEE/Miniport/TrEEMiniportSample.inf 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 |
