diff options
| author | Adonais Romero González <[email protected]> | 2019-01-10 11:12:43 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-01-10 11:12:43 -0800 |
| commit | 51be355e90ba5333cbea0e257dcb8a547d2881a7 (patch) | |
| tree | c8a9021226b8fb1ff6ccdda2c6231ba7920ded29 | |
| parent | 0e4c634898f02a512046957bf92adb49f03dd02c (diff) | |
| parent | c400fd8f0b50f3b5b2c51ba2b16eb8e90e7f0700 (diff) | |
Merge pull request #330 from cwize1/user/chrisgun/NfcCxSample
Add NFC CX sample driver.
| -rw-r--r-- | nfc/NfcCxSample/README.md | 49 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc.sln | 51 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp | 343 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h | 74 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp | 41 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf | bin | 0 -> 3832 bytes | |||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj | 95 | ||||
| -rw-r--r-- | nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters | 13 |
8 files changed, 666 insertions, 0 deletions
diff --git a/nfc/NfcCxSample/README.md b/nfc/NfcCxSample/README.md new file mode 100644 index 00000000..fe2abbc8 --- /dev/null +++ b/nfc/NfcCxSample/README.md @@ -0,0 +1,49 @@ +--- +topic: sample +name: NFC CX client driver sample +description: Sample code for creating a NFC driver using the NFC Class Extension. +generateZip: true +author: windows-driver-content +languages: +- cpp +products: +- windows +technologies: +- WDF +- UMDF2 +--- + +# NFC CX client driver sample + +A template for creating an NFC functional driver using the NFC Class Extension (CX) driver. + +This is a complete version of the code created in the [NFC CX quick start guide](https://docs.microsoft.com/windows-hardware/drivers/nfc/nfc-class-extension-quickstart). + +## Prerequisites + +To use the NFC CX, your NFC Controller must implement NFC Forum's [NFC Controller Interface (NCI)](https://nfc-forum.org/our-work/specifications-and-application-documents/specifications/nfc-controller-interface-nci-specification/) protocol. + +In addition, the NFC CX requires the driver to use the [UMDF 2](https://docs.microsoft.com/windows-hardware/drivers/wdf/overview-of-the-umdf) framework. + +## Universal windows driver compliant + +This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP. + +## File manifest + +### WDK + +- [NfcCx.h](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/) - The NFC CX's client driver API. (This file is included in the WDK.) + +### Project + +- [Driver.cpp](windows-drivertemplate-nfc/Driver.cpp) + - `DriverEntry` - Driver initialization. + +- [Device.cpp](windows-drivertemplate-nfc/Device.cpp) + - `DeviceContext::AddDevice` - Device initialization, including initializing the NFC CX driver. + - `DeviceContext::WriteNciPacket` - The implementation of the [`EvtNfcCxWriteNciPacket`](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_write_nci_packet) callback function. + - `DeviceContext::ReadNciPacket` - Demonstrates calling [`NfcCxNciReadNotification`](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nf-nfccx-nfccxncireadnotification). + +- [Device.h](windows-drivertemplate-nfc/Device.h) + - `DeviceContext` - The class that stores the device instance's state. diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc.sln b/nfc/NfcCxSample/windows-drivertemplate-nfc.sln new file mode 100644 index 00000000..c2a7a8bf --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2048 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows-drivertemplate-nfc", "windows-drivertemplate-nfc\windows-drivertemplate-nfc.vcxproj", "{E84EF126-888E-4B14-93A3-3B7776036D01}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.ActiveCfg = Debug|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.Build.0 = Debug|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.Deploy.0 = Debug|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.Build.0 = Debug|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.ActiveCfg = Debug|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.Build.0 = Debug|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.Deploy.0 = Debug|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.ActiveCfg = Debug|Win32 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.Build.0 = Debug|Win32 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.Deploy.0 = Debug|Win32 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.ActiveCfg = Release|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.Build.0 = Release|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.Deploy.0 = Release|ARM + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.ActiveCfg = Release|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.Build.0 = Release|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.Deploy.0 = Release|ARM64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.ActiveCfg = Release|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.Build.0 = Release|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.Deploy.0 = Release|x64 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.ActiveCfg = Release|Win32 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.Build.0 = Release|Win32 + {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E67B0F62-B28A-4B28-845C-B31B2614CF22} + EndGlobalSection +EndGlobal diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp new file mode 100644 index 00000000..5429d2a8 --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp @@ -0,0 +1,343 @@ +#include <new> + +#include "Device.h" + +// [Required] +// Called when the device is provisioned during system boot or when a new device is plugged-in while the +// system is running. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdriver/nc-wdfdriver-evt_wdf_driver_device_add +NTSTATUS DeviceContext::AddDevice( + _In_ WDFDRIVER Driver, + _Inout_ PWDFDEVICE_INIT DeviceInit) +{ + (void)Driver; + + NTSTATUS status; + + // Configure the NFC Class Extension. + // Note: The NFC_CX_TRANSPORT_TYPE is only used for telemetry purposes. It does not affect the behavior of + // the driver. + NFC_CX_CLIENT_CONFIG nfcCxConfig; + NFC_CX_CLIENT_CONFIG_INIT(&nfcCxConfig, NFC_CX_TRANSPORT_CUSTOM); + +#ifdef ENABLE_IF_IMPLEMENTING_CUSTOM_IOCTLS + nfcCxConfig.EvtNfcCxDeviceIoControl = IoControl; +#endif + + // Provide the NCI Write callback, which is called by the NFC CX when it has an NCI packet that needs to + // be sent to the NFC Controller. + nfcCxConfig.EvtNfcCxWriteNciPacket = WriteNciPacket; + + // Instruct the NFC CX to read the existing NCI configuration values and only update them if necessary. + nfcCxConfig.DriverFlags = NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION; + + status = NfcCxDeviceInitConfig(DeviceInit, &nfcCxConfig); + if (!NT_SUCCESS(status)) + { + return status; + } + + // Create the PnP power callbacks configuration. + WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); + pnpCallbacks.EvtDevicePrepareHardware = PrepareHardware; + pnpCallbacks.EvtDeviceReleaseHardware = ReleaseHardware; + pnpCallbacks.EvtDeviceD0Entry = D0Entry; + pnpCallbacks.EvtDeviceD0Exit = D0Exit; + + // Set the PnP power callbacks. + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); + + // Create WDF object attributes for the device. + WDF_OBJECT_ATTRIBUTES deviceAttributes; + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DeviceContext); + deviceAttributes.EvtDestroyCallback = Destroy; + + // Create the device. + WDFDEVICE device; + status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); + if (!NT_SUCCESS(status)) + { + return status; + } + + // Get a pointer to the raw memory that WDF allocated for the Device class. + DeviceContext* context = DeviceGetContext(device); + + // Initialize the raw memory using C++'s placement new operator. + // https://en.cppreference.com/w/cpp/language/new + new (context) DeviceContext(device); + + // Let the NFC Class Extension initialize the device. + status = NfcCxDeviceInitialize(device); + if (!NT_SUCCESS(status)) + { + return status; + } + + // Create the RF config. (Enable everything.) + NFC_CX_RF_DISCOVERY_CONFIG discoveryConfig; + NFC_CX_RF_DISCOVERY_CONFIG_INIT(&discoveryConfig); + discoveryConfig.PollConfig = NFC_CX_POLL_NFC_A | NFC_CX_POLL_NFC_B | NFC_CX_POLL_NFC_F_212 | NFC_CX_POLL_NFC_F_424 | NFC_CX_POLL_NFC_15693 | NFC_CX_POLL_NFC_ACTIVE | NFC_CX_POLL_NFC_A_KOVIO; + discoveryConfig.NfcIPMode = NFC_CX_NFCIP_NFC_A | NFC_CX_NFCIP_NFC_F_212 | NFC_CX_NFCIP_NFC_F_424 | NFC_CX_NFCIP_NFC_ACTIVE | NFC_CX_NFCIP_NFC_ACTIVE_A | NFC_CX_NFCIP_NFC_ACTIVE_F_212 | NFC_CX_NFCIP_NFC_ACTIVE_F_424; + discoveryConfig.NfcIPTgtMode = NFC_CX_NFCIP_TGT_NFC_A | NFC_CX_NFCIP_TGT_NFC_F | NFC_CX_NFCIP_TGT_NFC_ACTIVE_A | NFC_CX_NFCIP_TGT_NFC_ACTIVE_F; + discoveryConfig.NfcCEMode = NFC_CX_CE_NFC_A | NFC_CX_CE_NFC_B | NFC_CX_CE_NFC_F; + + // Set the RF config. + status = NfcCxSetRfDiscoveryConfig(device, &discoveryConfig); + if (!NT_SUCCESS(status)) + { + return status; + } + +#ifdef ENABLE_IF_USING_SEQUENCE_HANDLER_CALLBACKS + // Set the NFC Class Extension sequence handlers. + for (int sequenceType = 0; sequenceType != SequenceMaximum; ++sequenceType) + { + status = NfcCxRegisterSequenceHandler(device, NFC_CX_SEQUENCE(sequenceType), SequenceHandler); + if (!NT_SUCCESS(status)) + { + return status; + } + } +#endif + + return STATUS_SUCCESS; +} + +DeviceContext::DeviceContext(_In_ WDFDEVICE Device) : + _Device(Device) +{ +} + +// [Required] +// Called when the memory for the class is about to be freed by WDF. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfobject/nc-wdfobject-evt_wdf_object_context_destroy +void DeviceContext::Destroy( + _In_ WDFOBJECT Object) +{ + // Manually call the destructor for the class. + // This mirrors the use of the placement new operator in `DeviceContext::AddDevice`. + DeviceContext* context = DeviceGetContext(Object); + context->~DeviceContext(); +} + +// [Likely required] +// Called when the device's hardware resources are ready to be initialized. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_prepare_hardware +NTSTATUS DeviceContext::PrepareHardware( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesRaw, + _In_ WDFCMRESLIST ResourcesTranslated) +{ + (void)Device; + (void)ResourcesRaw; + (void)ResourcesTranslated; + + // FIX ME: + // Initialize the hardware so that it is ready to accept NCI packets. + + return STATUS_SUCCESS; +} + +// [Likely required] +// Called when the device's hardware resources are no longer accessible. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_release_hardware +NTSTATUS DeviceContext::ReleaseHardware( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesTranslated) +{ + (void)Device; + (void)ResourcesTranslated; + + // FIX ME: + // If neccessary, free any resources created by PrepareHardware. + + return STATUS_SUCCESS; +} + +// [Likely required] +// Called when the NFC Controller is entering the fully powered-on state. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_d0_entry +NTSTATUS DeviceContext::D0Entry( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE PreviousState) +{ + (void)PreviousState; + + NTSTATUS status; + + // Invoke the HostActionStart event, so that the NFC Class Extension initializes the NFC Controller (by + // sending the relevant NCI packets). + NFC_CX_HARDWARE_EVENT eventArgs = {}; + eventArgs.HostAction = HostActionStart; + + status = NfcCxHardwareEvent(Device, &eventArgs); + if (!NT_SUCCESS(status)) + { + return status; + } + + return STATUS_SUCCESS; +} + +// [Likely required] +// Called when the NFC Controller is entering a low power state. +// +// By default, the NFC Class Extension will prevent this callback from being invoked if there is an client +// process that may be using the NFC Controller. So it is okay for the NFC Controller to be fully +// uninitialized here. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_d0_exit +NTSTATUS DeviceContext::D0Exit( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE TargetState) +{ + (void)TargetState; + + NTSTATUS status; + + // Invoke the HostActionStop event, so that the NFC Class Extension uninitializes the NFC Controller (by sending + // the relevant NCI packets). + NFC_CX_HARDWARE_EVENT eventArgs = {}; + eventArgs.HostAction = HostActionStop; + + status = NfcCxHardwareEvent(Device, &eventArgs); + if (!NT_SUCCESS(status)) + { + return status; + } + + return STATUS_SUCCESS; +} + +// [Optional] +// Called when certain state transitions occur within the NFC Class Extension state machine. This can be used to send +// custom commands to the NFC Controller if neccessary. +// +// https://docs.microsoft.com/windows-hardware/drivers/nfc/sequence-handling +void DeviceContext::SequenceHandler( + _In_ WDFDEVICE Device, + _In_ NFC_CX_SEQUENCE Sequence, + _In_ PFN_NFC_CX_SEQUENCE_COMPLETION_ROUTINE CompletionRoutine, + _In_opt_ WDFCONTEXT CompletionContext) +{ + (void)Sequence; + + // Nothing to do. So complete the sequence handler immediately. + // Note: CompletionRoutine may be called asynchronously. + CompletionRoutine(Device, STATUS_SUCCESS, 0, CompletionContext); +} + +// [Optional] +// Can be used to implement custom IOCTLs. +// +// The NFC Class Extension registers for the default I/O queue and so it gets the first crack at handling all I/O requests. +// If this callback is enabled, any IOCTL the NFC Class Extension doesn't recognize will be forwarded here. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_device_io_control +void DeviceContext::IoControl( + _In_ WDFDEVICE Device, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode) +{ + (void)Device; + (void)OutputBufferLength; + (void)InputBufferLength; + (void)IoControlCode; + + // No custom IOCTLs are currently supported. So complete all I/O requests with a standard error. + WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE); +} + +// [Required] +// Called by the NFC Class Extension when an NCI packet must be sent to the NFC Controller. +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_write_nci_packet +void DeviceContext::WriteNciPacket( + _In_ WDFDEVICE Device, + _In_ WDFREQUEST Request) +{ + (void)Device; + + NTSTATUS status; + + // Get the NCI packet. + void* nciPacket; + size_t nciPacketLength; + status = WdfRequestRetrieveInputBuffer(Request, 0, &nciPacket, &nciPacketLength); + if (!NT_SUCCESS(status)) + { + WdfRequestComplete(Request, status); + return; + } + + // FIX ME: + // Send NCI packet to NFC Controller hardware using the relevant bus API. + // For example, + // - I2C or SPI: https://docs.microsoft.com/windows-hardware/drivers/spb/spb-peripheral-device-drivers + // - USB: https://docs.microsoft.com/windows-hardware/drivers/usbcon/usb-driver-development-guide + + // FIX ME: + // Complete I/O request with STATUS_SUCCESS if NCI packet is succesfully sent to the NFC Controller. + WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED); +} + +// FIX ME: +// Ensure NfcCxNciReadNotification is called when the NFC Controller needs to send an NCI packet to the driver. +// This is usually done in response to a hardware notification. For example, +// - GPIO interrupt (I2C or SPI): https://docs.microsoft.com/windows-hardware/drivers/gpio/gpio-interrupts +// - USB continuous reader: https://docs.microsoft.com/windows-hardware/drivers/usbcon/how-to-use-the-continous-reader-for-getting-data-from-a-usb-endpoint--umdf-/ +// +// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nf-nfccx-nfccxncireadnotification + +// A helper function that forwards NCI packets from the NFC Controller to the NFC Class Extension driver. +// +// NOTE: If the NCI packet is already packaged within an existing WDFMEMORY, then the NfcCxNciReadNotification +// function can be called directly. +NTSTATUS DeviceContext::ReadNciPacket( + _In_reads_bytes_(nciPacketLength) void* nciPacket, + _In_ size_t nciPacketLength) +{ + NTSTATUS status; + + if (!_NciReadMemory) + { + // Create the WDFMEMORY object that will be used for all NCI reads. + WDF_OBJECT_ATTRIBUTES memoryAttributes; + WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); + memoryAttributes.ParentObject = _Device; + + status = WdfMemoryCreatePreallocated(&memoryAttributes, nciPacket, nciPacketLength, &_NciReadMemory); + if (!NT_SUCCESS(status)) + { + return status; + } + } + else + { + // Re-assign the WDFMEMORY to point to the new NCI packet. + status = WdfMemoryAssignBuffer(_NciReadMemory, nciPacket, nciPacketLength); + if (!NT_SUCCESS(status)) + { + return status; + } + } + + // Note: NfcCxNciReadNotification does not store a reference to the WDFMEMORY object passed to it. So it + // is safe to free the NCI packet's memory after the call has completed. + status = NfcCxNciReadNotification(_Device, _NciReadMemory); + if (!NT_SUCCESS(status)) + { + return status; + } + + return STATUS_SUCCESS; +} diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h new file mode 100644 index 00000000..5d373d11 --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h @@ -0,0 +1,74 @@ +#pragma once + +#include <windows.h> +#include <wdf.h> +#include <NfcCx.h> + +class DeviceContext +{ +public: + // Implementation of `EvtDriverDeviceAdd`. + static NTSTATUS AddDevice( + _In_ WDFDRIVER Driver, + _Inout_ PWDFDEVICE_INIT DeviceInit); + +private: + DeviceContext(_In_ WDFDEVICE Device); + ~DeviceContext() = default; + + // Implementation of `EvtDestroyCallback`. + static void Destroy( + _In_ WDFOBJECT Object); + + // Implementation of `EvtDevicePrepareHardware`. + static NTSTATUS PrepareHardware( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesRaw, + _In_ WDFCMRESLIST ResourcesTranslated); + + // Implementation of `EvtDeviceReleaseHardware`. + static NTSTATUS ReleaseHardware( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesTranslated); + + // Implementation of `EvtDeviceD0Entry`. + static NTSTATUS D0Entry( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE PreviousState); + + // Implementation of `EvtDeviceD0Exit`. + static NTSTATUS D0Exit( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE TargetState); + + // Implementation of `EvtNfcCxSequenceHandler`. + static void SequenceHandler( + _In_ WDFDEVICE Device, + _In_ NFC_CX_SEQUENCE Sequence, + _In_ PFN_NFC_CX_SEQUENCE_COMPLETION_ROUTINE CompletionRoutine, + _In_opt_ WDFCONTEXT CompletionContext); + + static void IoControl( + _In_ WDFDEVICE Device, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode); + + // Implementation of `EvtNfcCxWriteNciPacket`. + static void WriteNciPacket( + _In_ WDFDEVICE Device, + _In_ WDFREQUEST Request); + + NTSTATUS ReadNciPacket( + _In_reads_bytes_(nciPacketLength) void* nciPacket, + _In_ size_t nciPacketLength); + + const WDFDEVICE _Device = nullptr; + WDFMEMORY _NciReadMemory = nullptr; +}; + +// Define the DeviceGetContext() function which can be used to get a pointer the DeviceContext from a WDFDEVICE object. +// Equivalent to: +// DeviceContext* DeviceGetContext(WDFOBJECT Handle) { ... } +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DeviceContext, DeviceGetContext); diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp b/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp new file mode 100644 index 00000000..c07eabe8 --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp @@ -0,0 +1,41 @@ +#include <windows.h> +#include <wdf.h> + +#include "Device.h" + +extern "C" DRIVER_INITIALIZE DriverEntry; + +// [Required] +// The entry point for the driver. +// +// In general, almost nothing should be done during driver initialization. Instead, almost all resources should +// be associated with a specific device. +// +// https://docs.microsoft.com/windows-hardware/drivers/wdf/driverentry-for-kmdf-drivers +extern "C" NTSTATUS DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +{ + NTSTATUS status; + + // Specify `DeviceContext::AddDevice` as the `EvtDriverDeviceAdd` callback function + // for the driver. + WDF_DRIVER_CONFIG driverConfig; + WDF_DRIVER_CONFIG_INIT(&driverConfig, DeviceContext::AddDevice); + + // Initialize WDF. + status = WdfDriverCreate( + DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &driverConfig, + WDF_NO_HANDLE + ); + if (!NT_SUCCESS(status)) + { + return status; + } + + return STATUS_SUCCESS; +} diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf Binary files differnew file mode 100644 index 00000000..d6070a8c --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj new file mode 100644 index 00000000..ce9fe362 --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj @@ -0,0 +1,95 @@ +<?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> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <Inf Include="windows-drivertemplate-nfc.inf" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{E84EF126-888E-4B14-93A3-3B7776036D01}</ProjectGuid> + <TemplateGuid>{2177f19c-eb4c-4687-9e7f-f9eec1f12cf1}</TemplateGuid> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <Configuration>Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <RootNamespace>windows_drivertemplate_nfc</RootNamespace> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> + </PropertyGroup> + <PropertyGroup Label="PropertySheets"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + <NfcDriver>true</NfcDriver> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup> + <RunCodeAnalysis>true</RunCodeAnalysis> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <EnablePREfast>true</EnablePREfast> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <FilesToPackage Include="$(TargetPath)" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Device.cpp" /> + <ClCompile Include="Driver.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Device.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters new file mode 100644 index 00000000..c02665df --- /dev/null +++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="Driver.cpp" /> + <ClCompile Include="Device.cpp" /> + </ItemGroup> + <ItemGroup> + <Inf Include="windows-drivertemplate-nfc.inf" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Device.h" /> + </ItemGroup> +</Project>
\ No newline at end of file |
