summaryrefslogtreecommitdiff
path: root/prm
diff options
context:
space:
mode:
Diffstat (limited to 'prm')
-rw-r--r--prm/PrmFunc/prmfuncsample.c511
-rw-r--r--prm/PrmFunc/prmfuncsample.h64
-rw-r--r--prm/PrmFunc/prmfuncsample.inf55
-rw-r--r--prm/PrmFunc/prmfuncsample.vcxproj170
-rw-r--r--prm/PrmFunc/prmfuncsample.vcxproj.Filters31
-rw-r--r--prm/README.md17
-rw-r--r--prm/prmsample.sln33
7 files changed, 881 insertions, 0 deletions
diff --git a/prm/PrmFunc/prmfuncsample.c b/prm/PrmFunc/prmfuncsample.c
new file mode 100644
index 00000000..c7eed1eb
--- /dev/null
+++ b/prm/PrmFunc/prmfuncsample.c
@@ -0,0 +1,511 @@
+/*--
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+
+Module Name:
+
+ PrmFuncSample.c
+
+Abstract:
+
+ This module implements a sample that utilizes the
+ Windows PRM direct call interface.
+
+Environment:
+
+ Kernel mode only.
+
+--*/
+
+#include "prmfuncsample.h"
+
+//
+// General client/class interfaces
+//
+
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_DEVICE_ADD PrmFuncTestEvtDeviceAdd;
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text (INIT, DriverEntry)
+#pragma alloc_text (PAGE, PrmFuncTestEvtDeviceAdd)
+#pragma alloc_text (PAGE, PrmFuncTestEvtIoDeviceControl)
+#endif
+
+HANDLE FileHandle = NULL;
+
+NTSTATUS
+DriverEntry (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+ )
+
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry configures and creates a WDF driver
+ object.
+ .
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+
+{
+ WDF_DRIVER_CONFIG Config;
+ WDFDRIVER Driver;
+ NTSTATUS Status;
+
+ KdPrint(("PRM Function Test Driver - Driver Framework Edition.\n"));
+
+ WDF_DRIVER_CONFIG_INIT(
+ &Config,
+ PrmFuncTestEvtDeviceAdd);
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+
+ Status = WdfDriverCreate(
+ DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES, // Driver Attributes
+ &Config, // Driver Config Info
+ &Driver);
+
+ if (!NT_SUCCESS(Status)) {
+ KdPrint(("WdfDriverCreate failed with status 0x%x\n", Status));
+ return Status;
+ }
+
+ return Status;
+}
+
+NTSTATUS
+PrmFuncTestEvtDeviceAdd (
+ _In_ WDFDRIVER Driver,
+ _In_ PWDFDEVICE_INIT DeviceInit
+ )
+
+/*++
+
+Routine Description:
+
+ ToasterEvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a WDF device object to
+ represent a new instance of toaster device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+
+{
+ NTSTATUS Status;
+ WDF_IO_QUEUE_CONFIG QueueConfig;
+ WDFDEVICE Device;
+ WDFQUEUE Queue;
+ WDF_FILEOBJECT_CONFIG FileConfig;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ PAGED_CODE();
+
+ KdPrint(("PrmFuncTestEvtDeviceAdd called\n"));
+
+ //
+ // Initialize WDF_FILEOBJECT_CONFIG_INIT struct to tell the
+ // framework whether you are interested in handling Create, Close and
+ // Cleanup requests that gets genereate when an application or another
+ // kernel component opens an handle to the device. If you don't register,
+ // the framework default behaviour would be complete these requests
+ // with STATUS_SUCCESS. A driver might be interested in registering these
+ // events if it wants to do security validation and also wants to maintain
+ // per handle (fileobject) context.
+ //
+
+ WDF_FILEOBJECT_CONFIG_INIT(
+ &FileConfig,
+ PrmFuncTestEvtDeviceFileCreate,
+ NULL,
+ NULL);
+
+ FileConfig.FileObjectClass = WdfFileObjectNotRequired;
+ WdfDeviceInitSetFileObjectConfig(
+ DeviceInit,
+ &FileConfig,
+ WDF_NO_OBJECT_ATTRIBUTES);
+
+ //
+ // Create a framework device object.This call will in turn create
+ // a WDM device object, attach to the lower stack, and set the
+ // appropriate flags and attributes.
+ //
+
+ Status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &Device);
+ if (!NT_SUCCESS(Status)) {
+ KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tell the Framework that this device will need an interface
+ //
+
+ Status = WdfDeviceCreateDeviceInterface(
+ Device,
+ (LPGUID) &GUID_DEVINTERFACE_PRMFUNCTEST,
+ NULL);
+
+ if (!NT_SUCCESS (Status)) {
+ KdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", Status));
+ return Status;
+ }
+
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&QueueConfig, WdfIoQueueDispatchParallel);
+ QueueConfig.EvtIoDeviceControl = PrmFuncTestEvtIoDeviceControl;
+ Status = WdfIoQueueCreate(
+ Device,
+ &QueueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &Queue
+ );
+
+ if (!NT_SUCCESS (Status)) {
+ KdPrint( ("WdfIoQueueCreate failed 0x%x\n", Status));
+ return Status;
+ }
+
+ return Status;
+}
+
+VOID
+PrmFuncTestEvtDeviceFileCreate (
+ _In_ WDFDEVICE Device,
+ _In_ WDFREQUEST Request,
+ _In_ WDFFILEOBJECT FileObject
+ )
+
+/*++
+
+Routine Description:
+
+ The framework calls a driver's EvtDeviceFileCreate callback
+ when the framework receives an IRP_MJ_CREATE request.
+ The system sends this request when a user application opens the
+ device to perform an I/O operation, such as reading or writing to a device.
+ This callback is called in the context of the thread
+ that created the IRP_MJ_CREATE request.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+ FileObject - Pointer to fileobject that represents the open handle.
+ CreateParams - Parameters for create
+
+Return Value:
+
+ NT status code
+
+--*/
+
+{
+
+ PIRP Irp;
+ WDFIOTARGET IoTarget;
+ WDF_REQUEST_SEND_OPTIONS RequestSendOptions;
+ UNICODE_STRING FilePath;
+ OBJECT_ATTRIBUTES ObjA;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PWSTR DeviceNames;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(FileObject);
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint( ("PrmFuncTestEvtDeviceFileCreate %p\n", Device));
+
+ DeviceNames = NULL;
+ Irp = WdfRequestWdmGetIrp(Request);
+ if (Irp->RequestorMode == KernelMode) {
+
+ //
+ // Forward the IRP if coming from kernel-mode
+ //
+
+ IoTarget = WdfDeviceGetIoTarget(Device);
+ WdfRequestFormatRequestUsingCurrentType(Request);
+ WDF_REQUEST_SEND_OPTIONS_INIT(
+ &RequestSendOptions,
+ WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET
+ );
+
+ WdfRequestSend(Request, IoTarget, &RequestSendOptions);
+
+ } else {
+ Status = IoGetDeviceInterfaces(
+ &GUID_DEVINTERFACE_PRMFUNCTEST,
+ WdfDeviceWdmGetPhysicalDevice(Device),
+ 0,
+ &DeviceNames
+ );
+
+ if (NT_SUCCESS(Status)) {
+ if (DeviceNames == NULL || DeviceNames[0] == UNICODE_NULL) {
+ Status = STATUS_DEVICE_DOES_NOT_EXIST;
+
+ } else {
+ RtlInitUnicodeString(&FilePath, DeviceNames);
+ InitializeObjectAttributes(&ObjA,
+ &FilePath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ Status = ZwCreateFile(&FileHandle,
+ GENERIC_WRITE,
+ &ObjA,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_WRITE,
+ FILE_OPEN_IF,
+ 0,
+ NULL,
+ 0);
+ }
+ }
+
+ WdfRequestComplete(Request, Status);
+ }
+
+ if (DeviceNames != NULL) {
+ ExFreePool(DeviceNames);
+ }
+
+ return;
+}
+
+VOID
+PrmFuncTestEvtIoDeviceControl(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode
+ )
+
+/*++
+
+Routine Description:
+
+ This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
+ requests from the system.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - length of the request's output buffer,
+ if an output buffer is available.
+ InputBufferLength - length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - the driver-defined or system-defined I/O control code
+ (IOCTL) that is associated with the request.
+
+Return Value:
+
+ VOID
+
+--*/
+
+{
+
+ ULONG BytesReturned;
+ PVOID InputBuffer;
+ PVOID OutputBuffer;
+ WDFMEMORY InputMemory;
+ WDFMEMORY OutputMemory;
+ size_t InputSize;
+ size_t OutputSize;
+ NTSTATUS Status;
+ PPRM_DIRECT_CALL_PARAMETERS TestParameters;
+ PPRM_TEST_RESULT PrmResult;
+ PRM_INTERFACE PrmInterface;
+ ULONG64 EfiStatus;
+ BOOLEAN Found;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Queue);
+
+ Status = STATUS_SUCCESS;
+ InputBuffer = NULL;
+ OutputBuffer = NULL;
+ BytesReturned = 0;
+ InputSize = 0;
+ OutputSize = 0;
+
+ //
+ // VAlidate the input and output buffers
+ //
+
+ if (InputBufferLength != 0) {
+ Status = WdfRequestRetrieveInputMemory(Request, &InputMemory);
+ if (!NT_SUCCESS(Status)) {
+ goto EvtIoDeviceControlEnd;
+ }
+
+ InputBuffer = WdfMemoryGetBuffer(InputMemory, &InputSize);
+ }
+
+ if (OutputBufferLength != 0) {
+ Status = WdfRequestRetrieveOutputMemory(Request, &OutputMemory);
+ if (!NT_SUCCESS(Status)) {
+ goto EvtIoDeviceControlEnd;
+ }
+
+ OutputBuffer = WdfMemoryGetBuffer(OutputMemory, &OutputSize);
+ }
+
+ //
+ // Use WdfRequestRetrieveInputBuffer and WdfRequestRetrieveOutputBuffer
+ // to get the request buffers.
+ //
+
+ switch (IoControlCode) {
+ case IOCTL_PRMFUNCTEST_DIRECT_CALL_TEST:
+ if (InputSize < sizeof(PRM_DIRECT_CALL_PARAMETERS)) {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (OutputSize < sizeof(PRM_TEST_RESULT)) {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ TestParameters = (PPRM_DIRECT_CALL_PARAMETERS)InputBuffer;
+ PrmResult = (PPRM_TEST_RESULT)OutputBuffer;
+
+ //
+ // Acquire the direct-call PRM interface, which is defined in
+ // prminterface.h.
+ //
+ // typedef struct _PRM_INTERFACE {
+ // ULONG Version;
+ // PPRM_UNLOCK_MODULE UnlockModule;
+ // PPRM_LOCK_MODULE LockModule;
+ // PPRM_INVOKE_HANDLER InvokeHandler;
+ // PPRM_QUERY_HANDLER QueryHandler;
+ // } PRM_INTERFACE, *PPRM_INTERFACE;
+ //
+
+ Status = ExGetPrmInterface(1, &PrmInterface);
+ if (!NT_SUCCESS(Status)) {
+ break;
+ }
+
+ //
+ // Lock the handler's PRM module to synchronize against any potential
+ // runtime update to the PRM module.
+ //
+ // N.B. Note that technically this is only needed if a series of PRM
+ // handlers need to be called transactionally (thus preventing
+ // interleaving of PRM module updates). However, we will do it here
+ // as an example of how it could be done.
+ //
+
+ Status = PrmInterface.LockModule(
+ (LPGUID)&TestParameters->Guid);
+
+ if (!NT_SUCCESS(Status)) {
+ break;
+ }
+
+ //
+ // Query for the presence of the PRM handler.
+ //
+
+ Status = PrmInterface.QueryHandler(
+ (LPGUID)&TestParameters->Guid,
+ &Found);
+
+ if ((!NT_SUCCESS(Status)) || (Found == FALSE)) {
+ break;
+ }
+
+ //
+ // Invoke the PRM handler
+ //
+
+ Status = PrmInterface.InvokeHandler(
+ (LPGUID)&TestParameters->Guid,
+ TestParameters->ParameterBuffer,
+ 0,
+ &EfiStatus);
+
+ if (!NT_SUCCESS(Status)) {
+ break;
+ }
+
+ //
+ // Unlock the PRM module
+ //
+ // N.B. Note that technically this is only needed if a series of PRM
+ // handlers need to be called as part of transaction. However, we will
+ // do it here as an example of how it could be done.
+ //
+
+ Status = PrmInterface.UnlockModule(
+ (LPGUID)&TestParameters->Guid);
+
+ if (!NT_SUCCESS(Status)) {
+ break;
+ }
+
+ PrmResult->Status = Status;
+ PrmResult->EfiStatus = EfiStatus;
+ Status = STATUS_SUCCESS;
+ BytesReturned = sizeof(PRM_TEST_RESULT);
+ break;
+
+ default:
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+EvtIoDeviceControlEnd:
+ WdfRequestCompleteWithInformation(Request, Status, BytesReturned);
+} \ No newline at end of file
diff --git a/prm/PrmFunc/prmfuncsample.h b/prm/PrmFunc/prmfuncsample.h
new file mode 100644
index 00000000..117b008d
--- /dev/null
+++ b/prm/PrmFunc/prmfuncsample.h
@@ -0,0 +1,64 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ prmfuncsample.h
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#if !defined(_PRMFUNCTEST_H_)
+#define _PRMFUNCTEST_H_
+
+#include <ntddk.h>
+#include <wdf.h>
+
+#define NTSTRSAFE_LIB
+#include <ntstrsafe.h>
+#include <initguid.h>
+#include "prminterface.h"
+
+#define PRMFUNCTEST_POOL_TAG (ULONG) 'fmrP'
+
+DRIVER_INITIALIZE DriverEntry;
+
+EVT_WDF_DRIVER_DEVICE_ADD PrmFuncTestEvtDeviceAdd;
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL PrmFuncTestEvtIoDeviceControl;
+EVT_WDF_DEVICE_FILE_CREATE PrmFuncTestEvtDeviceFileCreate;
+
+DEFINE_GUID(GUID_DEVINTERFACE_PRMFUNCTEST,
+ 0x9f87349b, 0x4429, 0x4e4c, 0xb1, 0xf4, 0x30, 0x74, 0x99, 0x97, 0x0a, 0x1b);
+
+#define PRMFUNCTEST_IOCTL(_index_) \
+ CTL_CODE (FILE_DEVICE_UNKNOWN, _index_, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_PRMFUNCTEST_DIRECT_CALL_TEST PRMFUNCTEST_IOCTL(0xF00)
+#define PRM_PARAMETER_BUFFER_SIZE 308
+
+typedef struct _PRM_TEST_PARAMETERS {
+ GUID Guid;
+ UCHAR ParameterBuffer[PRM_PARAMETER_BUFFER_SIZE];
+} PRM_TEST_PARAMETERS, *PPRM_TEST_PARAMETERS;
+
+typedef struct _PRM_DIRECT_CALL_PARAMETERS {
+ GUID Guid;
+ UCHAR ParameterBuffer[PRM_PARAMETER_BUFFER_SIZE];
+} PRM_DIRECT_CALL_PARAMETERS, *PPRM_DIRECT_CALL_PARAMETERS;
+
+typedef struct _PRM_TEST_RESULT {
+ NTSTATUS Status;
+ ULONG64 EfiStatus;
+ UCHAR Buffer[PRM_PARAMETER_BUFFER_SIZE];
+} PRM_TEST_RESULT, *PPRM_TEST_RESULT;
+
+#endif
diff --git a/prm/PrmFunc/prmfuncsample.inf b/prm/PrmFunc/prmfuncsample.inf
new file mode 100644
index 00000000..f583ca59
--- /dev/null
+++ b/prm/PrmFunc/prmfuncsample.inf
@@ -0,0 +1,55 @@
+[Version]
+Signature="$WINDOWS NT$"
+Class=System
+ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
+Provider=%ProviderName%
+DriverVer=2/1/2023
+CatalogFile=prmfuncsample.cat
+PnpLockdown=1
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+prmfuncsample.sys = 1,,
+
+[DestinationDirs]
+Drivers_Dir = 13
+
+[ControlFlags]
+ExcludeFromSelect = *
+
+[Manufacturer]
+%ManufacturerName%=Standard,NT$ARCH$.10.0...26048
+
+[Standard.NT$ARCH$.10.0...26048]
+%PMT10000.DeviceDesc% = PrmFuncSample_Inst,*PMT10000
+
+[PrmFuncSample_Inst.NT.Services]
+AddService = PrmFuncSample,%SPSVCINST_ASSOCSERVICE%,PrmFuncSample_Service_Inst
+
+[PrmFuncSample_Inst.NT]
+CopyFiles = Drivers_Dir
+
+[Drivers_Dir]
+prmfuncsample.sys
+
+[PrmFuncSample_Service_Inst]
+DisplayName = %PRMFUNCSAMPLE.SvcDesc%
+ServiceType = %SERVICE_KERNEL_DRIVER%
+StartType = %SERVICE_SYSTEM_START%
+ErrorControl = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %13%\prmfuncsample.sys
+LoadOrderGroup = Extended Base
+
+[strings]
+ProviderName = "TODO-Set-Provider"
+ManufacturerName = "TODO-Set-Manufacturer"
+DiskId1 = "PRM Func Sample Driver Installation Disk #1"
+PMT10000.DeviceDesc = "PRM Func Sample Device"
+PRMFUNCSAMPLE.SvcDesc = "PRM Func Sample Driver"
+
+SPSVCINST_ASSOCSERVICE = 0x00000002
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_SYSTEM_START = 1
+SERVICE_ERROR_NORMAL = 1
diff --git a/prm/PrmFunc/prmfuncsample.vcxproj b/prm/PrmFunc/prmfuncsample.vcxproj
new file mode 100644
index 00000000..a159bb27
--- /dev/null
+++ b/prm/PrmFunc/prmfuncsample.vcxproj
@@ -0,0 +1,170 @@
+<?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|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <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)'=='Release|ARM64'">
+ <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)'=='Debug|ARM64'">
+ <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|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|ARM64'">
+ <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)'=='Debug|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <Inf Include=".\prmfuncsample.inf">
+ <DateStamp>*</DateStamp>
+ <SpecifyDriverVerDirectiveDate>true</SpecifyDriverVerDirectiveDate>
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\prmfuncsample.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>prmfuncsample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <TargetName>prmfuncsample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>prmfuncsample</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <TargetName>prmfuncsample</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ksguid.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(KIT_SHARED_INC_PATH_WDK)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ksguid.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(KIT_SHARED_INC_PATH_WDK)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ksguid.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(KIT_SHARED_INC_PATH_WDK)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ksguid.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(KIT_SHARED_INC_PATH_WDK)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="prmfuncsample.c" />
+ </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>
diff --git a/prm/PrmFunc/prmfuncsample.vcxproj.Filters b/prm/PrmFunc/prmfuncsample.vcxproj.Filters
new file mode 100644
index 00000000..f8ca8c78
--- /dev/null
+++ b/prm/PrmFunc/prmfuncsample.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>{E10CB9FB-4852-4353-85F5-667D4D2A13DD}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{EC8940D8-5E2B-49AB-AB85-7CABCAE698D1}</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>{42A1FDF4-6DB4-41B2-9423-8002A20D1B0D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{FD9F921C-D1EF-421B-A692-F23423B32E64}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="prmfuncsample.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/prm/README.md b/prm/README.md
new file mode 100644
index 00000000..3475d78e
--- /dev/null
+++ b/prm/README.md
@@ -0,0 +1,17 @@
+---
+page_type: sample
+description: "Demonstrates how to write a KMDF driver to utlize the Windows Platform Runtime Mechanism (PRM) direct-call interface."
+languages:
+- cpp
+products:
+- windows
+- windows-wdk
+---
+
+# PrmFunc sample application
+
+The *PRMFunc* sample demonstrates how to write a KMDF driver to utlize the Windows Platform Runtime Mechanism (PRM) direct-call interface.
+
+## Related topics
+
+[Platform Runtime Mechanism Specification](https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mechanism%20-%20with%20legal%20notice.pdf/)
diff --git a/prm/prmsample.sln b/prm/prmsample.sln
new file mode 100644
index 00000000..286753fe
--- /dev/null
+++ b/prm/prmsample.sln
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34414.90
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prmfuncsample", "prmfunc\prmfuncsample.vcxproj", "{A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM64 = Debug|ARM64
+ Release|ARM64 = Release|ARM64
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Release|ARM64.Build.0 = Release|ARM64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Debug|x64.ActiveCfg = Debug|x64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Debug|x64.Build.0 = Debug|x64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Debug|x64.Deploy.0 = Debug|x64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Release|x64.ActiveCfg = Release|x64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Release|x64.Build.0 = Release|x64
+ {A80FE9DD-C140-40F6-A3F4-55A2A55BFAD4}.Release|x64.Deploy.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E71959C9-929E-4552-B267-ED7ABEE1B330}
+ EndGlobalSection
+EndGlobal