summaryrefslogtreecommitdiff
path: root/TrEE/OSService
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/OSService
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'TrEE/OSService')
-rw-r--r--TrEE/OSService/SampleOSService.c928
-rw-r--r--TrEE/OSService/SampleOSService.rc14
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.infbin0 -> 4572 bytes
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.vcxproj222
-rw-r--r--TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters31
5 files changed, 1195 insertions, 0 deletions
diff --git a/TrEE/OSService/SampleOSService.c b/TrEE/OSService/SampleOSService.c
new file mode 100644
index 00000000..b75cfb88
--- /dev/null
+++ b/TrEE/OSService/SampleOSService.c
@@ -0,0 +1,928 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+ sampleservice.c
+
+Abstract:
+
+ This file demonstrates a simple service plugin for the TREE class extension driver.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <ntstrsafe.h>
+#include <initguid.h>
+#include <wdmguid.h>
+#include <TrustedRuntimeClx.h>
+#include <SampleOSService.h>
+
+typedef enum _SAMPLE_SERVICE_TYPE {
+ SampleServiceEcho,
+ SampleServiceKernelMemory
+} SAMPLE_SERVICE_TYPE;
+
+typedef struct _SAMPLE_SERVICE_FILE_CONTEXT {
+ SAMPLE_SERVICE_TYPE ServiceType;
+} SAMPLE_SERVICE_FILE_CONTEXT, *PSAMPLE_SERVICE_FILE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE(SAMPLE_SERVICE_FILE_CONTEXT);
+
+typedef
+NTSTATUS
+SAMPLE_SERVICE_REQUEST_HANDLER(
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ size_t InputBufferLength,
+ _Out_writes_bytes_to_(OutputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ size_t OutputBufferLength,
+ _Out_ size_t* BytesWritten
+ );
+
+//
+// Driver entry point
+//
+
+DRIVER_INITIALIZE DriverEntry;
+
+//
+// Device callbacks
+//
+
+EVT_WDF_DRIVER_UNLOAD DriverUnload;
+EVT_WDF_DRIVER_DEVICE_ADD SampleServiceEvtAddDevice;
+EVT_WDF_DEVICE_D0_ENTRY SampleServiceEvtD0Entry;
+EVT_WDF_DEVICE_D0_EXIT SampleServiceEvtD0Exit;
+EVT_WDF_DEVICE_FILE_CREATE SampleServiceEvtCreateFile;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtInternalIoctl;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtQuery;
+EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL SampleServiceEvtExecute;
+SAMPLE_SERVICE_REQUEST_HANDLER SampleServiceEchoHandler;
+SAMPLE_SERVICE_REQUEST_HANDLER SampleServiceKernelMemoryHandler;
+
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, DriverUnload)
+#pragma alloc_text(PAGE, SampleServiceEvtAddDevice)
+#pragma alloc_text(PAGE, SampleServiceEvtCreateFile)
+#pragma alloc_text(PAGE, SampleServiceEvtInternalIoctl)
+#pragma alloc_text(PAGE, SampleServiceEvtQuery)
+#pragma alloc_text(PAGE, SampleServiceEvtExecute)
+#pragma alloc_text(PAGE, SampleServiceEchoHandler)
+#pragma alloc_text(PAGE, SampleServiceKernelMemoryHandler)
+
+#pragma data_seg("PAGED")
+
+DECLARE_CONST_UNICODE_STRING(GUID_ECHO_SERVICE_STRING,
+ L"{33C7FF13-50B0-454A-8BEB-F73EED6C0AF9}");
+
+DECLARE_CONST_UNICODE_STRING(GUID_KERNEL_MEMORY_SERVICE_STRING,
+ L"{D28698A4-3B07-4F34-B65E-AE3DA6ACF2AC}");
+
+#pragma data_seg()
+
+volatile ULONG RandomSeed;
+
+_Use_decl_annotations_
+NTSTATUS
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the initialization routine for the device driver. This routine
+ creates the driver object for the sample OS service.
+
+ Arguments:
+
+ DriverObject - Pointer to driver object created by the system.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDRIVER Driver;
+ WDF_DRIVER_CONFIG DriverConfig;
+ NTSTATUS Status;
+
+ Driver = NULL;
+
+ //
+ // Create the WDF driver object
+ //
+
+ WDF_DRIVER_CONFIG_INIT(&DriverConfig, SampleServiceEvtAddDevice);
+ DriverConfig.EvtDriverUnload = DriverUnload;
+ DriverConfig.DriverPoolTag = 'SOMS';
+
+ Status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &DriverConfig,
+ &Driver);
+
+ if (!NT_SUCCESS(Status)) {
+ goto DriverEntryEnd;
+ }
+
+DriverEntryEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+VOID
+DriverUnload(
+ WDFDRIVER Driver
+ )
+
+/*++
+
+ Routine Description:
+
+ This is the cleanup function called when the driver is unloaded.
+
+ Arguments:
+
+ Driver - Supplies a handle to WDFDRIVER object created in DriverEntry.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtAddDevice(
+ WDFDRIVER Driver,
+ PWDFDEVICE_INIT DeviceInit
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the driver is being attached to a specific
+ device.
+
+ Arguments:
+
+ Driver - Supplies a handle to the framework driver object.
+
+ DeviceInit - Supplies a pointer to the device initialization parameters.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ WDFDEVICE Device;
+ WDF_FILEOBJECT_CONFIG FileConfig;
+ WDF_OBJECT_ATTRIBUTES ObjectAttributes;
+ WDF_PNPPOWER_EVENT_CALLBACKS PowerCallbacks;
+ WDFQUEUE Queue;
+ WDF_IO_QUEUE_CONFIG QueueConfig;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
+ WdfDeviceInitSetDeviceType(DeviceInit, 32999);
+ WdfDeviceInitSetPowerNotPageable(DeviceInit);
+
+ //
+ // Initialize file context and register file creation handler
+ //
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ObjectAttributes,
+ SAMPLE_SERVICE_FILE_CONTEXT);
+
+ ObjectAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+ WDF_FILEOBJECT_CONFIG_INIT(&FileConfig,
+ &SampleServiceEvtCreateFile,
+ WDF_NO_EVENT_CALLBACK,
+ WDF_NO_EVENT_CALLBACK);
+
+ FileConfig.FileObjectClass = WdfFileObjectWdfCanUseFsContext;
+ WdfDeviceInitSetFileObjectConfig(DeviceInit,
+ &FileConfig,
+ &ObjectAttributes);
+
+ //
+ // Device interface will be enabled/disabled in these callbacks
+ //
+
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PowerCallbacks);
+ PowerCallbacks.EvtDeviceD0Entry = SampleServiceEvtD0Entry;
+ PowerCallbacks.EvtDeviceD0Exit = SampleServiceEvtD0Exit;
+
+ Status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &Device);
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ //
+ // Create a default queue to process requests
+ //
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&ObjectAttributes);
+ ObjectAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&QueueConfig,
+ WdfIoQueueDispatchParallel);
+
+ QueueConfig.EvtIoInternalDeviceControl = SampleServiceEvtInternalIoctl;
+ Status = WdfIoQueueCreate(Device,
+ &QueueConfig,
+ &ObjectAttributes,
+ &Queue);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ //
+ // This tells TrEE driver that this OS service is available. Two services
+ // are served by this device, and they are distinguished by filename.
+ //
+ Status = WdfDeviceCreateDeviceInterface(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+ Status = WdfDeviceCreateDeviceInterface(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtAddDeviceEnd;
+ }
+
+SampleServiceEvtAddDeviceEnd:
+ return Status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtD0Entry(
+ WDFDEVICE Device,
+ WDF_POWER_DEVICE_STATE PreviousState
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is coming back from a lower
+ power state to D0.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device was in.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(PreviousState);
+
+ RandomSeed = (ULONG)(KeQueryInterruptTime() >> 8);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING,
+ TRUE);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ TRUE);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEvtD0Exit(
+ WDFDEVICE Device,
+ WDF_POWER_DEVICE_STATE TargetState
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is going down to a lower
+ power state.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device is going to.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(TargetState);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_ECHO_SERVICE,
+ &GUID_ECHO_SERVICE_STRING,
+ FALSE);
+
+ WdfDeviceSetDeviceInterfaceState(Device,
+ &GUID_KERNEL_MEMORY_SERVICE,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ FALSE);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtCreateFile(
+ WDFDEVICE Device,
+ WDFREQUEST Request,
+ WDFFILEOBJECT FileObject
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device is coming back from a lower
+ power state to D0.
+
+ Arguments:
+
+ Device - Supplies a handle to device object.
+
+ PreviousState - Supplies the power state the device was in.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ UNICODE_STRING Filename;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Device);
+
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Filename = *WdfFileObjectGetFileName(FileObject);
+ if (Filename.Buffer[0] == L'\\') {
+ ++Filename.Buffer;
+ Filename.Length -= sizeof(WCHAR);
+ Filename.MaximumLength -= sizeof(WCHAR);
+ }
+
+ //
+ // Record what service is this create request is for
+ //
+ if (RtlCompareUnicodeString(&Filename,
+ &GUID_ECHO_SERVICE_STRING,
+ TRUE) == 0) {
+
+ FileContext->ServiceType = SampleServiceEcho;
+ Status = STATUS_SUCCESS;
+
+ } else if (RtlCompareUnicodeString(&Filename,
+ &GUID_KERNEL_MEMORY_SERVICE_STRING,
+ TRUE) == 0) {
+
+ FileContext->ServiceType = SampleServiceKernelMemory;
+ Status = STATUS_SUCCESS;
+
+ } else {
+
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtInternalIoctl(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives an OS service request
+ from TrEE class extension, which is sent as an internal device control
+ request.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ PAGED_CODE();
+
+ switch (IoControlCode) {
+ case IOCTL_TR_SERVICE_QUERY:
+ SampleServiceEvtQuery(Queue,
+ Request,
+ OutputBufferLength,
+ InputBufferLength,
+ IoControlCode);
+
+ return;
+
+ case IOCTL_TR_EXECUTE_FUNCTION:
+ SampleServiceEvtExecute(Queue,
+ Request,
+ OutputBufferLength,
+ InputBufferLength,
+ IoControlCode);
+
+ return;
+
+ default:
+ WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
+ }
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtQuery(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives a query request from
+ TrEE class extension. OS service provider fills up information about
+ the service.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ WDFFILEOBJECT FileObject;
+ PTR_SERVICE_INFORMATION ServiceInformation;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(IoControlCode);
+
+ FileObject = WdfRequestGetFileObject(Request);
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Status = WdfRequestRetrieveOutputBuffer(Request,
+ sizeof(TR_SERVICE_INFORMATION),
+ (PVOID*)&ServiceInformation,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalQueryFail;
+ }
+
+ ServiceInformation->InterfaceVersion = 1;
+ ServiceInformation->ServiceMajorVersion = 1;
+ ServiceInformation->ServiceMinorVersion = 1;
+ WdfRequestCompleteWithInformation(Request,
+ STATUS_SUCCESS,
+ sizeof(TR_SERVICE_INFORMATION));
+
+ return;
+
+SampleServiceEvtInternalQueryFail:
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+VOID
+SampleServiceEvtExecute(
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t OutputBufferLength,
+ size_t InputBufferLength,
+ ULONG IoControlCode
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine is called when the device receives an OS service execute
+ request from TrEE miniport.
+
+ Arguments:
+
+ Queue - Supplies a handle to the framework queue object that is
+ associated with the I/O request.
+
+ Request - Supplies a handle to a framework request object.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - Supplies the driver-defined or system-defined I/O
+ control code (IOCTL) that is associated with the
+ request.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ size_t BytesWritten;
+ PSAMPLE_SERVICE_FILE_CONTEXT FileContext;
+ WDFFILEOBJECT FileObject;
+ PTR_SERVICE_REQUEST ServiceRequest;
+ PTR_SERVICE_REQUEST_RESPONSE ServiceResponse;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(IoControlCode);
+
+ FileObject = WdfRequestGetFileObject(Request);
+ FileContext = WdfObjectGet_SAMPLE_SERVICE_FILE_CONTEXT(FileObject);
+ Status = WdfRequestRetrieveInputBuffer(Request,
+ sizeof(TR_SERVICE_REQUEST),
+ (PVOID*)&ServiceRequest,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ Status = WdfRequestRetrieveOutputBuffer(Request,
+ sizeof(TR_SERVICE_REQUEST_RESPONSE),
+ (PVOID*)&ServiceResponse,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ switch (FileContext->ServiceType) {
+ case SampleServiceEcho:
+ Status = SampleServiceEchoHandler(ServiceRequest->FunctionCode,
+ ServiceRequest->InputBuffer,
+ (size_t)ServiceRequest->InputBufferSize,
+ ServiceRequest->OutputBuffer,
+ (size_t)ServiceRequest->OutputBufferSize,
+ &BytesWritten);
+
+ break;
+
+ case SampleServiceKernelMemory:
+ Status = SampleServiceKernelMemoryHandler(ServiceRequest->FunctionCode,
+ ServiceRequest->InputBuffer,
+ (size_t)ServiceRequest->InputBufferSize,
+ ServiceRequest->OutputBuffer,
+ (size_t)ServiceRequest->OutputBufferSize,
+ &BytesWritten);
+ break;
+
+ default:
+ //
+ // Shouldn't reach here
+ //
+ NT_ASSERT(FALSE);
+
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceEvtInternalIoctlFail;
+ }
+
+ //
+ // Bytes written to the output buffer of the service request goes into here
+ //
+ ServiceResponse->BytesWritten = BytesWritten;
+
+ //
+ // Number of bytes written to WDF request's output buffer is always
+ // sizeof(TR_SERVICE_REQUEST_RESPONSE)
+ //
+ WdfRequestCompleteWithInformation(Request,
+ Status,
+ sizeof(TR_SERVICE_REQUEST_RESPONSE));
+
+ return;
+
+SampleServiceEvtInternalIoctlFail:
+ WdfRequestComplete(Request, Status);
+}
+
+_Use_decl_annotations_
+NTSTATUS
+SampleServiceEchoHandler(
+ ULONG FunctionCode,
+ PVOID InputBuffer,
+ size_t InputBufferLength,
+ PVOID OutputBuffer,
+ size_t OutputBufferLength,
+ size_t* BytesWritten
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine handles OS service requests sent to echo service.
+
+ Arguments:
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the request's input buffer,
+ if an input buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ OutputBuffer - Supplies a pointer to the request's output buffer,
+ if an output buffer is available.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ BytesWritten - Supplies a pointer to the variable where number of bytes
+ actually written to the output buffer. In case the
+ output buffer is too small to contain all the data, the
+ required size will be written.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+ ULONG Index;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ switch (FunctionCode) {
+ case ECHO_SERVICE_ECHO:
+ if (OutputBufferLength < InputBufferLength) {
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceEchoHandlerEnd;
+ }
+
+ RtlCopyMemory(OutputBuffer, InputBuffer, InputBufferLength);
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ECHO_SERVICE_REPEAT:
+ *BytesWritten = 0;
+ while (OutputBufferLength >= InputBufferLength) {
+ RtlCopyMemory(OutputBuffer, InputBuffer, InputBufferLength);
+
+ OutputBuffer = (PVOID)(((ULONG_PTR)OutputBuffer) + InputBufferLength);
+ OutputBufferLength -= InputBufferLength;
+ *BytesWritten += InputBufferLength;
+ }
+
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ECHO_SERVICE_REVERSE:
+ if (OutputBufferLength < InputBufferLength) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceEchoHandlerEnd;
+ }
+
+ for (Index = 0; Index < InputBufferLength; ++Index) {
+ ((PUCHAR)OutputBuffer)[Index] = ((PUCHAR)InputBuffer)[InputBufferLength - Index - 1];
+ }
+
+ *BytesWritten = InputBufferLength;
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+SampleServiceEchoHandlerEnd:
+ return Status;
+}
+
+UCHAR ScratchMemory[1024];
+
+NTSTATUS
+SampleServiceKernelMemoryHandler(
+ _In_ ULONG FunctionCode,
+ _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
+ _In_ size_t InputBufferLength,
+ _Out_writes_bytes_to_(OuputBufferLength, *BytesWritten) PVOID OutputBuffer,
+ _In_ size_t OutputBufferLength,
+ _Out_ size_t* BytesWritten
+ )
+
+/*++
+
+ Routine Description:
+
+ This routine handles OS service requests sent to kernel memory service.
+
+ Arguments:
+
+ FunctionCode - Supplies the function code of the request.
+
+ InputBuffer - Supplies a pointer to the request's input buffer,
+ if an input buffer is available.
+
+ InputBufferLength - Supplies the length of the request's input buffer,
+ if an input buffer is available.
+
+ OutputBuffer - Supplies a pointer to the request's output buffer,
+ if an output buffer is available.
+
+ OutputBufferLength - Supplies the length of the request's output
+ buffer, if an output buffer is available.
+
+ BytesWritten - Supplies a pointer to the variable where number of bytes
+ actually written to the output buffer. In case the
+ output buffer is too small to contain all the data, the
+ required size will be written.
+
+ Return Value:
+
+ NTSTATUS code.
+
+--*/
+
+{
+
+ UCHAR PreviousValue;
+ NTSTATUS Status;
+ PKERNEL_MEMORY_SAFE_RANGE SafeRange;
+ PKERNEL_MEMORY_WRITE_BYTE WriteByte;
+
+ PAGED_CODE();
+
+ switch (FunctionCode) {
+ case KERNEL_MEMORY_SERVICE_GET_SAFE_RANGE:
+ if (OutputBufferLength < sizeof(KERNEL_MEMORY_SAFE_RANGE)) {
+ *BytesWritten = sizeof(KERNEL_MEMORY_SAFE_RANGE);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ SafeRange = (PKERNEL_MEMORY_SAFE_RANGE)OutputBuffer;
+ SafeRange->Base = (ULONG64)(ULONG_PTR)&ScratchMemory;
+ SafeRange->Length = sizeof(ScratchMemory);
+ *BytesWritten = sizeof(KERNEL_MEMORY_SAFE_RANGE);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KERNEL_MEMORY_SERVICE_WRITE_BYTE:
+ if (InputBufferLength < sizeof(KERNEL_MEMORY_WRITE_BYTE)) {
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ *BytesWritten = sizeof(UCHAR);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ WriteByte = (PKERNEL_MEMORY_WRITE_BYTE)InputBuffer;
+ PreviousValue = *(PUCHAR)(ULONG_PTR)WriteByte->Address;
+ *(PUCHAR)(ULONG_PTR)WriteByte->Address = WriteByte->Value;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KERNEL_MEMORY_SERVICE_READ_BYTE:
+ if (InputBufferLength < sizeof(ULONG64)) {
+ Status = STATUS_INVALID_PARAMETER;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ *BytesWritten = sizeof(UCHAR);
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto SampleServiceKernelMemoryHandlerEnd;
+ }
+
+ *(PUCHAR)OutputBuffer = *(PUCHAR)(ULONG_PTR)*(PULONG64)InputBuffer;
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+SampleServiceKernelMemoryHandlerEnd:
+ return Status;
+}
diff --git a/TrEE/OSService/SampleOSService.rc b/TrEE/OSService/SampleOSService.rc
new file mode 100644
index 00000000..55dd3bef
--- /dev/null
+++ b/TrEE/OSService/SampleOSService.rc
@@ -0,0 +1,14 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
+#define VER_FILEDESCRIPTION_STR "Sample TREE Service Driver"
+#define VER_INTERNALNAME_STR "TrEEOSServiceSample.sys"
+
+#include "common.ver"
+
+
diff --git a/TrEE/OSService/TrEEOSServiceSample.inf b/TrEE/OSService/TrEEOSServiceSample.inf
new file mode 100644
index 00000000..e14149b9
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.inf
Binary files differ
diff --git a/TrEE/OSService/TrEEOSServiceSample.vcxproj b/TrEE/OSService/TrEEOSServiceSample.vcxproj
new file mode 100644
index 00000000..d3afa66a
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.vcxproj
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Arm">
+ <Configuration>Debug</Configuration>
+ <Platform>Arm</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Arm">
+ <Configuration>Release</Configuration>
+ <Platform>Arm</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{7661C397-614D-4562-9CC7-6178B246DB17}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{CF6545FF-8EA5-4A78-8776-59E492F8C276}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>TrEEOSServiceSample</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Arm'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleosservice.c" />
+ <ResourceCompile Include="sampleosservice.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters b/TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters
new file mode 100644
index 00000000..61542807
--- /dev/null
+++ b/TrEE/OSService/TrEEOSServiceSample.vcxproj.Filters
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{AB2DD0E2-5CC9-4127-B1D4-1DBD5877932E}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{A955E202-DE30-4FFA-B5B6-8149773C178D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{A338803C-3BF5-4F17-BD90-3269E83E92C5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{FFB2F3A5-5400-4D41-9B69-7A1B94C27388}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="sampleosservice.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="sampleosservice.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file