NTSTATUS FireShockIoReadQueueInitialize( WDFDEVICE Device ) { PDEVICE_CONTEXT pDeviceContext; NTSTATUS status; WDF_IO_QUEUE_CONFIG queueConfig; pDeviceContext = DeviceGetContext(Device); WDF_IO_QUEUE_CONFIG_INIT( &queueConfig, WdfIoQueueDispatchManual ); status = WdfIoQueueCreate( Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->IoReadQueue ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status); return status; } return status; }
void FileObjectContext::CreateCallback( _In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDFFILEOBJECT FileObject ) { TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE); DeviceContext* deviceContext = DeviceGetContext(Device); FileObjectContext* fileContext = FileObjectGetContext(FileObject); // Initialize class (using placement new operator). new (fileContext) FileObjectContext(); fileContext->_FileObject = FileObject; fileContext->_DeviceContext = deviceContext; NTSTATUS status = fileContext->Create(); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "Create failed. %!STATUS!", status); WdfRequestComplete(Request, status); } WdfRequestComplete(Request, STATUS_SUCCESS); TRACE_FUNCTION_SUCCESS(LEVEL_VERBOSE); }
void DeviceContext::ShutdownCallback( _In_ WDFOBJECT Object ) { DeviceContext* deviceContext = DeviceGetContext(Object); deviceContext->Shutdown(); }
void DeviceContext::DestroyCallback( _In_ WDFOBJECT Object ) { DeviceContext* deviceContext = DeviceGetContext(Object); deviceContext->~DeviceContext(); }
NTSTATUS DeviceContext::D0EntryCallback( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState ) { DeviceContext* deviceContext = DeviceGetContext(Device); return deviceContext->D0Entry(PreviousState); }
NTSTATUS DeviceContext::D0ExitCallback( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState ) { DeviceContext* deviceContext = DeviceGetContext(Device); return deviceContext->D0Exit(TargetState); }
void DeviceContext::WriteNciPacketCallback( _In_ WDFDEVICE Device, _In_ WDFREQUEST Request ) { DeviceContext* deviceContext = DeviceGetContext(Device); deviceContext->WriteNciPacket(Request); }
void MouseTrapEvtIoInternalDeviceControl(WDFQUEUE queue, WDFREQUEST request, size_t outputBufferLength, size_t inputBufferLength, ULONG ioControlCode) { UNREFERENCED_PARAMETER(outputBufferLength); UNREFERENCED_PARAMETER(inputBufferLength); NTSTATUS status = STATUS_SUCCESS; PAGED_CODE(); // Ensure paging is allowed in current IRQL // Get extension data WDFDEVICE hDevice = WdfIoQueueGetDevice(queue); PDEVICE_CONTEXT context = DeviceGetContext(hDevice); if(ioControlCode == IOCTL_INTERNAL_MOUSE_CONNECT) { // Only allow one connection. if(context->UpperConnectData.ClassService == NULL) { // Copy the connection parameters to the device extension. PCONNECT_DATA connectData; size_t length; status = WdfRequestRetrieveInputBuffer(request, sizeof(CONNECT_DATA), &connectData, &length); if(NT_SUCCESS(status)) { // Hook into the report chain (I am not sure this is correct) context->UpperConnectData = *connectData; connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice); #pragma warning(push) #pragma warning(disable:4152) connectData->ClassService = MouseTrapServiceCallback; #pragma warning(pop) } else { DebugPrint(("[MouseTrap] WdfRequestRetrieveInputBuffer failed %x\n", status)); } } else { status = STATUS_SHARING_VIOLATION; } } else if(ioControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT) { status = STATUS_NOT_IMPLEMENTED; } // Complete on error if(!NT_SUCCESS(status)) { WdfRequestComplete(request, status); return; } // Dispatch to higher level driver WDF_REQUEST_SEND_OPTIONS options; WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); if(WdfRequestSend(request, WdfDeviceGetIoTarget(hDevice), &options) == FALSE) { NTSTATUS status = WdfRequestGetStatus(request); DebugPrint(("[MouseTrap] WdfRequestSend failed: 0x%x\n", status)); WdfRequestComplete(request, status); } }
NTSTATUS SmplDeviceEvtD0Entry( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState ) { PDEVICE_CONTEXT pSmplDeviceContext = DeviceGetContext(Device); Hw8250Init(pSmplDeviceContext->pPortAddress, 1200, 7, 1, 0); DbgPrintEx( DPFLTR_IHVDRIVER_ID,1234,"SmplDeviceEvtD0Entry . \n"); return STATUS_SUCCESS; }
VOID FireShockEvtIoWrite( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t Length ) { NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; LPVOID buffer; size_t bufferLength; size_t transferred = 0; pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue)); switch (pDeviceContext->DeviceType) { case DualShock3: status = WdfRequestRetrieveInputBuffer( Request, DS3_HID_OUTPUT_REPORT_SIZE, &buffer, &bufferLength); if (NT_SUCCESS(status) && Length == bufferLength) { status = SendControlRequest( pDeviceContext, BmRequestHostToDevice, BmRequestClass, SetReport, USB_SETUP_VALUE(HidReportRequestTypeOutput, HidReportRequestIdOne), 0, buffer, (ULONG)bufferLength); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "SendControlRequest failed with status %!STATUS!", status); break; } transferred = bufferLength; } break; default: status = STATUS_NOT_SUPPORTED; break; } WdfRequestCompleteWithInformation(Request, status, transferred); }
void DeviceContext::SequenceHandlerCallback( _In_ WDFDEVICE Device, _In_ NFC_CX_SEQUENCE Sequence, _In_ PFN_NFC_CX_SEQUENCE_COMPLETION_ROUTINE CompletionRoutine, _In_opt_ WDFCONTEXT CompletionContext ) { DeviceContext* deviceContext = DeviceGetContext(Device); deviceContext->SequenceHandler(Sequence, CompletionRoutine, CompletionContext); }
/////////////////////////////////////////////////////////////////////////////// // SmplInterruptEvtDisable /////////////////////////////////////////////////////////////////////////////// NTSTATUS SmplInterruptEvtDisable( __in WDFINTERRUPT Interrupt, __in WDFDEVICE AssociatedDevice ) { PDEVICE_CONTEXT pDeviceContext = DeviceGetContext(WdfInterruptGetDevice(Interrupt)); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplInterruptEvtDisable\n"); WRITE_INTERRUPT_ENABLE( pDeviceContext->pPortAddress, 0); return STATUS_SUCCESS; } // end SmplInterruptEvtDisable
void DeviceContext::DeviceIoCallback( _In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) { DeviceContext* deviceContext = DeviceGetContext(Device); deviceContext->DeviceIo(Request, OutputBufferLength, InputBufferLength, IoControlCode); }
/////////////////////////////////////////////////////////////////////////////// // SmplPoFxComponentActiveConditionCallback // This callback is invoked by Power Framework to notify driver that one of its // components has become active. /////////////////////////////////////////////////////////////////////////////// VOID SmplPoFxComponentActiveConditionCallback( _In_ PVOID Context, _In_ ULONG Component ) { DEVICE_CONTEXT *pDeviceContext = DeviceGetContext((WDFDEVICE) Context); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplPoFxComponentActiveConditionCallback Component:%d\n", Component); WdfIoQueueStart(pDeviceContext->Queue); } // end SmplPoFxComponentActiveConditionCallback
NTSTATUS SmplDeviceQueueInitialize( _In_ WDFDEVICE Device ) /*++ Routine Description: The I/O dispatch callbacks for the frameworks device object are configured in this function. A single default I/O Queue is configured for parallel request processing, and a driver context memory allocation is created to hold our structure QUEUE_CONTEXT. Arguments: Device - Handle to a framework device object. Return Value: VOID --*/ { NTSTATUS status; WDF_IO_QUEUE_CONFIG queueConfig; PDEVICE_CONTEXT pDeviceContext = DeviceGetContext(Device); PAGED_CODE(); // // Configure a default queue so that requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto // other queues get dispatched here. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate( Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &(pDeviceContext->Queue)); if( !NT_SUCCESS(status) ) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status); return status; } return status; }
/////////////////////////////////////////////////////////////////////////////// // Interrupt Service Routine (ISR) event callback function // processing on IRQL_DIRQL /////////////////////////////////////////////////////////////////////////////// BOOLEAN SmplInterruptEvtIsr( __in WDFINTERRUPT Interrupt, __in ULONG MessageID ) { WDFDEVICE Device = WdfInterruptGetDevice(Interrupt); PDEVICE_CONTEXT pSmplDeviceContext = DeviceGetContext(Device); BOOLEAN bReturnValue = FALSE; #pragma warning(push) #pragma warning(disable:4127) // warning C4127: conditional expression is constant while(TRUE) #pragma warning(pop) { // First check: Is it ours??? UCHAR rcvd; UCHAR IntId = READ_INTERRUPT_IDENTIFICATION(pSmplDeviceContext->pPortAddress); if (IntId & IIR_NOT_FIRED) { break; } DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"Interrupt\n"); bReturnValue = TRUE; switch (IntId) { case IIR_RECEIVER_FULL: rcvd = READ_RECEIVER_BUFFER (pSmplDeviceContext->pPortAddress); if (FALSE == RingbufferInsertCharacter(pSmplDeviceContext->pRingBuffer, rcvd)) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"Ringbuffer overflow %x\n", rcvd); } break; case IIR_RECEIVER_ERROR: case IIR_TRANSMITTER_EMPTY: case IIR_STATUS_CHANGE: default: ; } // end switch } // end while if(TRUE == bReturnValue) WdfInterruptQueueDpcForIsr(Interrupt); return bReturnValue; } // end SmplInterruptEvtIsr
/////////////////////////////////////////////////////////////////////////////// // This callback is invoked by Power Framework to notify driver about any // F-state transition. /////////////////////////////////////////////////////////////////////////////// VOID SmplPoFxComponentIdleStateCallback( _In_ PVOID Context, _In_ ULONG Component, _In_ ULONG State ) { DEVICE_CONTEXT *pDeviceContext = DeviceGetContext((WDFDEVICE)Context); // // Note the new F-state. PEP may direct to any of the F-states directly. // Transition to any Fx state happens from F0 (and not another Fx state). // DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplPoFxComponentIdleStateCallback Component:%d F%d\n", Component, State); PoFxCompleteIdleState(pDeviceContext->PoHandle, Component); } // end SmplPoFxComponentIdleStateCallback
/////////////////////////////////////////////////////////////////////////////// // SmplPoFxComponentIdleConditionCallback // // IMPORTANT NOTE // ============== // Given that the idle transition does not complete until all the power- // managed queues have been stopped, it is extremely important for the // driver to ensure that stopping of power-managed queues is reasonably // quick. If the driver fails to ensure this, the power framework can remain // stuck in the idle transition for a long time, which could hamper its // ability to put the component in a low-power F-state. This could // negatively impact any power savings that can be gained via component // power management. // // In order to ensure that idle transitions can complete quickly, the driver // should quickly process any requests that are dispatched to it via a // power-managed queue. If the driver forwards a request (that was received // via a power-managed queue) to an I/O target that might keep the request // pending for a long time, then the driver should cancel the request when // the component idle condition callback is invoked. This is because the // power-managed queue cannot be stopped while the request is pending in the // I/O target. // /////////////////////////////////////////////////////////////////////////////// VOID SmplPoFxComponentIdleConditionCallback( _In_ PVOID Context, _In_ ULONG Component ) { DEVICE_CONTEXT *pDeviceContext = DeviceGetContext((WDFDEVICE) Context); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplPoFxComponentIdleConditionCallback Component:%d\n", Component); WdfIoQueueStop(pDeviceContext->Queue, SmplQueueEvtStatePoFxStopComplete, NULL); // // The idle transition will complete asynchronously. We'll call // PoFxCompleteIdleCondition to complete it when all the queues have been // stopped. } // end SmplPoFxComponentIdleConditionCallback
/////////////////////////////////////////////////////////////////////////////// // Deferred procedure call (DPC) event callback function // for postprocessing after interrupt on IRQL_DISPATCH_LEVEL /////////////////////////////////////////////////////////////////////////////// VOID SmplInterruptEvtDpc( IN WDFINTERRUPT Interrupt, IN WDFOBJECT AssociatedObject ) { WDFDEVICE Device = WdfInterruptGetDevice(Interrupt); PDEVICE_CONTEXT pSmplDeviceContext = DeviceGetContext(Device); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplInterruptEvtDpc >>\n"); WdfObjectAcquireLock(pSmplDeviceContext->Queue); while(TRUE == SmplIoQueueRequestTryComplete(pSmplDeviceContext)); WdfObjectReleaseLock(pSmplDeviceContext->Queue); } // end SmplInterruptEvtDpc
void MouseTrapServiceCallback(DEVICE_OBJECT* deviceObject, MOUSE_INPUT_DATA* inputDataStart, MOUSE_INPUT_DATA* inputDataEnd, ULONG* inputDataConsumed) { // Get context data WDFDEVICE hDevice = WdfWdmDeviceGetWdfDeviceHandle(deviceObject); PDEVICE_CONTEXT context = DeviceGetContext(hDevice); // Invert all scroll actions for(PMOUSE_INPUT_DATA current = inputDataStart; current != inputDataEnd; current++) { if(current->ButtonFlags & MOUSE_WHEEL) { short value = (short)current->ButtonData; current->ButtonData = (USHORT)(-value); } } // Call parent #pragma warning(push) #pragma warning(disable:4055) (*(PSERVICE_CALLBACK_ROUTINE)context->UpperConnectData.ClassService)(context->UpperConnectData.ClassDeviceObject, inputDataStart, inputDataEnd, inputDataConsumed); #pragma warning(pop) }
/////////////////////////////////////////////////////////////////////////////// // SmplDeviceEvtWdmPostPoFxRegisterDevice // KMDF calls this routine after it has registered with the Power Framework // and supplies the registration handle that driver can use directly. /////////////////////////////////////////////////////////////////////////////// NTSTATUS SmplDeviceEvtWdmPostPoFxRegisterDevice( _In_ WDFDEVICE Device, _In_ POHANDLE PoHandle ) { DEVICE_CONTEXT *pDeviceContext = DeviceGetContext(Device); pDeviceContext->PoHandle = PoHandle; // // Set latency and residency hints so that the power framework chooses lower // powered F-states when we are idle. // The values used here are for illustration purposes only. The driver // should use values that are appropriate for its device. // PoFxSetComponentLatency(PoHandle, 0, (WDF_ABS_TIMEOUT_IN_MS(DEEPEST_FSTATE_LATENCY_IN_MS) + 1)); PoFxSetComponentResidency(PoHandle, 0, (WDF_ABS_TIMEOUT_IN_SEC(DEEPEST_FSTATE_RESIDENCY_IN_SEC) + 1)); return STATUS_SUCCESS; } // end SmplDeviceEvtWdmPostPoFxRegisterDevice
VOID FireShockEvtIoRead( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t Length ) { NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; UNREFERENCED_PARAMETER(Length); pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue)); status = WdfRequestForwardToIoQueue(Request, pDeviceContext->IoReadQueue); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfRequestForwardToIoQueue failed with status %!STATUS!", status); WdfRequestComplete(Request, status); } }
NTSTATUS tgwinkQueueInitialize( _In_ WDFDEVICE Device ) { NTSTATUS status; WDF_IO_QUEUE_CONFIG queueConfig; PDEVICE_CONTEXT deviceContext; PAGED_CODE(); WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &queueConfig, WdfIoQueueDispatchSequential ); queueConfig.EvtIoDeviceControl = tgwinkEvtIoDeviceControl; queueConfig.EvtIoStop = tgwinkEvtIoStop; queueConfig.EvtIoRead = tgwinkEvtIoRead; queueConfig.EvtIoWrite = tgwinkEvtIoWrite; deviceContext = DeviceGetContext(Device); status = WdfIoQueueCreate( Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->IoDefaultQueue ); WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate( Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->NotificationQueue); return status; }
VOID tgwinkEvtIoRead( WDFQUEUE Queue, WDFREQUEST Request, size_t Length ) { NTSTATUS status; WDFMEMORY mem; WDF_REQUEST_PARAMETERS params; ULONG offset; ULONG result; PDEVICE_CONTEXT context; WDFDEVICE device; device = WdfIoQueueGetDevice(Queue); context = DeviceGetContext(device); WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters(Request, ¶ms); offset = (ULONG)params.Parameters.Read.DeviceOffset; status = WdfRequestRetrieveOutputMemory(Request, &mem); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoRead could not get request memory buffer, status 0x%x\n", status); WdfVerifierDbgBreakPoint(); WdfRequestCompleteWithInformation(Request, status, 0); return; } result = context->busInterface.GetBusData(context->busInterface.Context, PCI_WHICHSPACE_CONFIG, WdfMemoryGetBuffer(mem, NULL), offset, (ULONG)Length); WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, (ULONG_PTR)result); }
/////////////////////////////////////////////////////////////////////////////// // Private local helper function that parses the translated resource list // and extracts the data needed for the port address. /////////////////////////////////////////////////////////////////////////////// NTSTATUS SmplDeviceHwResourcesGet( IN WDFDEVICE Device, IN WDFCMRESLIST ResourceListTranslated ) { NTSTATUS Status = STATUS_SUCCESS; ULONG index = 0; PCM_PARTIAL_RESOURCE_DESCRIPTOR pCMResourceDescPartial; PDEVICE_CONTEXT pSmplDeviceContext = NULL; pSmplDeviceContext = DeviceGetContext(Device); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplDeviceHwResourcesGet >>\n"); if (NULL != pSmplDeviceContext) { for (index = 0; index < WdfCmResourceListGetCount(ResourceListTranslated); index++) { pCMResourceDescPartial = WdfCmResourceListGetDescriptor(ResourceListTranslated, index); if (NULL == pCMResourceDescPartial) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"pCMResourceDescPartial is NULL!!!\n"); return STATUS_DEVICE_CONFIGURATION_ERROR; } switch (pCMResourceDescPartial->Type) { case CmResourceTypePort: // // Handle port resources here. // DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypePort 0x%x %d\n", pCMResourceDescPartial->u.Port.Start.LowPart, pCMResourceDescPartial->u.Port.Length); pSmplDeviceContext->pPortAddress = (PUCHAR) pCMResourceDescPartial->u.Port.Start.LowPart; pSmplDeviceContext->PortAddressLength = pCMResourceDescPartial->u.Port.Length; break; case CmResourceTypeMemory: // // Handle memory resources here. // DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypeMemory Desc\n"); break; case CmResourceTypeInterrupt: // // Handle interrupt resources here. // DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypeInterrupt\n"); break; default: // // Ignore all other descriptors. // DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceType unknown\n"); break; } // end switch } // end for loop } // end if return Status; } // end SmplDeviceHwResourcesGet
NTSTATUS RoboDeviceCreateDevice( _Inout_ PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Worker routine called to create a device and its software resources. Arguments: DeviceInit - Pointer to an opaque init structure. Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds. So don't access the structure after that point. Return Value: NTSTATUS --*/ { DEVICE_CONTEXT* pCtx; WDF_OBJECT_ATTRIBUTES attributes; WDFDEVICE device; NTSTATUS status; PAGED_CODE(); scope { // pnpPowerCallbacks structure WDF_PNPPOWER_EVENT_CALLBACKS pnpPwrCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS_INIT( &pnpPwrCallbacks ); pnpPwrCallbacks.EvtDevicePrepareHardware = RoboDeviceEvtDevicePrepareHardware; pnpPwrCallbacks.EvtDeviceReleaseHardware = RoboDeviceEvtDeviceReleaseHardware; pnpPwrCallbacks.EvtDeviceD0Entry = RoboDeviceEvtDeviceD0Entry; pnpPwrCallbacks.EvtDeviceD0Exit = RoboDeviceEvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPwrCallbacks); } { // power policy callback used to arm/disarm hardware to handle wait-wake WDF_POWER_POLICY_EVENT_CALLBACKS powerPolicyCallbacks; WDF_POWER_POLICY_EVENT_CALLBACKS_INIT( &powerPolicyCallbacks ); powerPolicyCallbacks.EvtDeviceArmWakeFromS0 = RoboDeviceEvtDeviceArmWakeFromS0; powerPolicyCallbacks.EvtDeviceDisarmWakeFromS0 = RoboDeviceEvtDeviceDisarmWakeFromS0; powerPolicyCallbacks.EvtDeviceWakeFromS0Triggered = RoboDeviceEvtDeviceWakeFromS0Triggered; powerPolicyCallbacks.EvtDeviceArmWakeFromSx = RoboDeviceEvtDeviceArmWakeFromSx; powerPolicyCallbacks.EvtDeviceDisarmWakeFromSx = RoboDeviceEvtDeviceDisarmWakeFromSx; powerPolicyCallbacks.EvtDeviceWakeFromSxTriggered = RoboDeviceEvtDeviceWakeFromSxTriggered; WdfDeviceInitSetPowerPolicyEventCallbacks( DeviceInit, &powerPolicyCallbacks ); } WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &attributes, DEVICE_CONTEXT ); attributes.EvtCleanupCallback = RoboDeviceEvtDeviceContextCleanup; status = WdfDeviceCreate( &DeviceInit, &attributes, &device ); if( !NT_SUCCESS(status) ) { DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "WdfDeviceCreate failed: 0x%x", status ); return status; } // Initialize the context pCtx = DeviceGetContext( device ); pCtx->PrivateDeviceData = 0; status = WdfDeviceCreateDeviceInterface( device, &GUID_DEVINTERFACE_RoboDevice, NULL ); if( !NT_SUCCESS(status) ) { DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Error Create device interface: 0x%x", status ); return status; } status = RoboDeviceQueueInitialize( device ); /* scope { WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT( &idleSettings, IdleCannotWakeFromS0 ); idleSettings.IdleTimeout = 60000; status = WdfDeviceAssignS0IdleSettings( device, &idleSettings ); } scope { WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings; WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT( &wakeSettings ); WdfDeviceAssignSxWakeSettings( device, &wakeSettings ); } */ return status; }
NTSTATUS SmplDeviceCreateDevice( _Inout_ PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Worker routine called to create a device and its software resources. Arguments: DeviceInit - Pointer to an opaque init structure. Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds. So don't access the structure after that point. Return Value: NTSTATUS --*/ { WDF_OBJECT_ATTRIBUTES deviceAttributes; PDEVICE_CONTEXT deviceContext; WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks; WDFDEVICE device; NTSTATUS status; PAGED_CODE(); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); deviceAttributes.SynchronizationScope = WdfSynchronizationScopeQueue; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpPowerEventCallbacks); PnpPowerEventCallbacks.EvtDevicePrepareHardware = SmplDeviceEvtPrepareHardware; PnpPowerEventCallbacks.EvtDeviceReleaseHardware = SmplDeviceEvtReleaseHardware; PnpPowerEventCallbacks.EvtDeviceD0Entry = SmplDeviceEvtD0Entry; PnpPowerEventCallbacks.EvtDeviceD0Exit = SmplDeviceEvtD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks( DeviceInit, &PnpPowerEventCallbacks); status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (NT_SUCCESS(status)) { // // Get the device context and initialize it. DeviceGetContext is an // inline function generated by WDF_DECLARE_CONTEXT_TYPE macro in the // device.h header file. This function will do the type checking and return // the device context. If you pass a wrong object handle // it will return NULL and assert if run under framework verifier mode. // deviceContext = DeviceGetContext(device); // // Create a device interface so that applications can find and talk // to us. // status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_SMPLDEVICE, NULL); if (NT_SUCCESS(status)) { // // Initialize the I/O Package and any Queues // status = SmplDeviceQueueInitialize(device); } if (NT_SUCCESS(status)) { WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS PowerPolicyIdleSettings; WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&PowerPolicyIdleSettings, IdleCannotWakeFromS0); PowerPolicyIdleSettings.IdleTimeoutType = SystemManagedIdleTimeout; status = WdfDeviceAssignS0IdleSettings(device, &PowerPolicyIdleSettings); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"WdfDeviceAssignS0IdleSettings failed! 0x%x\n", status); } } if (NT_SUCCESS(status)) { SmplPoFxSingleComponentInitialize(device); } if (NT_SUCCESS(status)) { WDFINTERRUPT Interrupt; WDF_INTERRUPT_CONFIG Configuration; WDF_INTERRUPT_CONFIG_INIT(&Configuration, SmplInterruptEvtIsr, SmplInterruptEvtDpc); Configuration.EvtInterruptEnable = SmplInterruptEvtEnable; Configuration.EvtInterruptDisable = SmplInterruptEvtDisable; status = WdfInterruptCreate(device, &Configuration, WDF_NO_OBJECT_ATTRIBUTES, &Interrupt); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234, "WdfInterruptCreate failed! 0x%x\n", status); } } } return status; }
NTSTATUS CVWindowsInternalsCreateDevice( _Inout_ PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Worker routine called to create a device and its software resources. Arguments: DeviceInit - Pointer to an opaque init structure. Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds. So don't access the structure after that point. Return Value: NTSTATUS --*/ { WDF_OBJECT_ATTRIBUTES deviceAttributes; PDEVICE_CONTEXT deviceContext; WDFDEVICE device; NTSTATUS status; PAGED_CODE(); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (NT_SUCCESS(status)) { // // Get a pointer to the device context structure that we just associated // with the device object. We define this structure in the device.h // header file. DeviceGetContext is an inline function generated by // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h. // This function will do the type checking and return the device context. // If you pass a wrong object handle it will return NULL and assert if // run under framework verifier mode. // deviceContext = DeviceGetContext(device); // // Initialize the context. // deviceContext->PrivateDeviceData = 0; // // Create a device interface so that applications can find and talk // to us. // status = WdfDeviceCreateDeviceInterface( device, &GUID_DEVINTERFACE_CVWindowsInternals, NULL // ReferenceString ); if (NT_SUCCESS(status)) { // // Initialize the I/O Package and any Queues // status = CVWindowsInternalsQueueInitialize(device); } } return status; }
VOID FireShockEvtIoDeviceControl( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) /*++ Routine Description: This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - Size of the output buffer in bytes InputBufferLength - Size of the input buffer in bytes IoControlCode - I/O control code. Return Value: VOID --*/ { NTSTATUS status = STATUS_SUCCESS; size_t bufferLength; size_t transferred = 0; PDEVICE_CONTEXT pDeviceContext; PFIRESHOCK_GET_HOST_BD_ADDR pGetHostAddr; PFIRESHOCK_GET_DEVICE_BD_ADDR pGetDeviceAddr; PFIRESHOCK_SET_HOST_BD_ADDR pSetHostAddr; PFIRESHOCK_GET_DEVICE_TYPE pGetDeviceType; TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d", Queue, Request, (int)OutputBufferLength, (int)InputBufferLength, IoControlCode); pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue)); switch (IoControlCode) { #pragma region IOCTL_FIRESHOCK_GET_HOST_BD_ADDR case IOCTL_FIRESHOCK_GET_HOST_BD_ADDR: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "IOCTL_FIRESHOCK_GET_HOST_BD_ADDR"); status = WdfRequestRetrieveOutputBuffer( Request, sizeof(FIRESHOCK_GET_HOST_BD_ADDR), (LPVOID)&pGetHostAddr, &bufferLength); if (NT_SUCCESS(status) && OutputBufferLength == sizeof(FIRESHOCK_GET_HOST_BD_ADDR)) { transferred = OutputBufferLength; RtlCopyMemory(&pGetHostAddr->Host, &pDeviceContext->HostAddress, sizeof(BD_ADDR)); } break; #pragma endregion #pragma region IOCTL_FIRESHOCK_GET_DEVICE_BD_ADDR case IOCTL_FIRESHOCK_GET_DEVICE_BD_ADDR: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "IOCTL_FIRESHOCK_GET_DEVICE_BD_ADDR"); status = WdfRequestRetrieveOutputBuffer( Request, sizeof(FIRESHOCK_GET_DEVICE_BD_ADDR), (LPVOID)&pGetDeviceAddr, &bufferLength); if (NT_SUCCESS(status) && OutputBufferLength == sizeof(FIRESHOCK_GET_DEVICE_BD_ADDR)) { transferred = OutputBufferLength; RtlCopyMemory(&pGetDeviceAddr->Device, &pDeviceContext->DeviceAddress, sizeof(BD_ADDR)); } break; #pragma endregion #pragma region IOCTL_FIRESHOCK_SET_HOST_BD_ADDR case IOCTL_FIRESHOCK_SET_HOST_BD_ADDR: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "IOCTL_FIRESHOCK_SET_HOST_BD_ADDR"); status = WdfRequestRetrieveInputBuffer( Request, sizeof(FIRESHOCK_SET_HOST_BD_ADDR), (LPVOID)&pSetHostAddr, &bufferLength); if (NT_SUCCESS(status) && InputBufferLength == sizeof(FIRESHOCK_SET_HOST_BD_ADDR)) { UCHAR controlBuffer[SET_HOST_BD_ADDR_CONTROL_BUFFER_LENGTH]; RtlZeroMemory(controlBuffer, SET_HOST_BD_ADDR_CONTROL_BUFFER_LENGTH); RtlCopyMemory(&controlBuffer[2], &pSetHostAddr->Host, sizeof(BD_ADDR)); status = SendControlRequest( pDeviceContext, BmRequestHostToDevice, BmRequestClass, SetReport, Ds3FeatureHostAddress, 0, controlBuffer, SET_HOST_BD_ADDR_CONTROL_BUFFER_LENGTH); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "Setting host address failed with %!STATUS!", status); break; } RtlCopyMemory(&pDeviceContext->HostAddress, &pSetHostAddr->Host, sizeof(BD_ADDR)); } break; #pragma endregion #pragma region IOCTL_FIRESHOCK_GET_DEVICE_TYPE case IOCTL_FIRESHOCK_GET_DEVICE_TYPE: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "IOCTL_FIRESHOCK_GET_DEVICE_TYPE"); status = WdfRequestRetrieveOutputBuffer( Request, sizeof(FIRESHOCK_GET_DEVICE_TYPE), (LPVOID)&pGetDeviceType, &bufferLength); if (NT_SUCCESS(status) && OutputBufferLength == sizeof(FIRESHOCK_GET_DEVICE_TYPE)) { transferred = OutputBufferLength; pGetDeviceType->DeviceType = pDeviceContext->DeviceType; } break; #pragma endregion } WdfRequestCompleteWithInformation(Request, status, transferred); }
// Sets up a new device. NTSTATUS DeviceContext::DeviceAdd( _Inout_ PWDFDEVICE_INIT DeviceInit ) { TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE); NTSTATUS status; NFC_CX_CLIENT_CONFIG nfcCxConfig; NFC_CX_CLIENT_CONFIG_INIT(&nfcCxConfig, NFC_CX_TRANSPORT_CUSTOM); nfcCxConfig.EvtNfcCxWriteNciPacket = WriteNciPacketCallback; nfcCxConfig.EvtNfcCxDeviceIoControl = DeviceIoCallback; nfcCxConfig.DriverFlags = NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION | NFC_CX_DRIVER_POWER_AND_LINK_CONTROL_SUPPORTED; status = NfcCxDeviceInitConfig(DeviceInit, &nfcCxConfig); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "NfcCxDeviceInitConfig failed. %!STATUS!", status); return status; } WDF_OBJECT_ATTRIBUTES deviceObjectAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceObjectAttributes, DeviceContext); deviceObjectAttributes.EvtCleanupCallback = ShutdownCallback; deviceObjectAttributes.EvtDestroyCallback = DestroyCallback; WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); pnpCallbacks.EvtDeviceD0Entry = D0EntryCallback; pnpCallbacks.EvtDeviceD0Exit = D0ExitCallback; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); FileObjectContext::DeviceInit(DeviceInit); WDFDEVICE device; status = WdfDeviceCreate(&DeviceInit, &deviceObjectAttributes, &device); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "WdfDeviceCreate failed. %!STATUS!", status); return status; } // Initialize device context. DeviceContext* deviceContext = DeviceGetContext(device); new (deviceContext) DeviceContext(); deviceContext->_Device = device; status = NfcCxDeviceInitialize(device); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "NfcCxDeviceInitialize failed. %!STATUS!", status); return status; } // Create lock for clients (and sequence handling). WDF_OBJECT_ATTRIBUTES lockAttributes; WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfWaitLockCreate(&lockAttributes, &deviceContext->_ClientLock); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "WdfWaitLockCreate failed. %!STATUS!", status); return status; } // Initialize RF discovery 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; status = NfcCxSetRfDiscoveryConfig(device, &discoveryConfig); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "NfcCxSetRfDiscoveryConfig failed. %!STATUS!", status); return status; } // Set the sequence handlers. for (int sequenceType = 0; sequenceType != SequenceMaximum; ++sequenceType) { status = NfcCxRegisterSequenceHandler(device, NFC_CX_SEQUENCE(sequenceType), SequenceHandlerCallback); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "NfcCxRegisterSequenceHandler failed. %!STATUS!", status); return status; } } // Initialize callbacks manager. status = deviceContext->_ApiCallbacksManager.Initialize(device); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "CallbacksManager::Initialize failed. %!STATUS!", status); return status; } // Create device interface for NciSim DECLARE_CONST_UNICODE_STRING(interfaceName, FILE_NAMESPACE_NCI_SIMULATOR); status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_NCI_SIMULATOR, &interfaceName); if (!NT_SUCCESS(status)) { TRACE_LINE(LEVEL_ERROR, "WdfDeviceCreateDeviceInterface failed. %!STATUS!", status); return status; } TRACE_FUNCTION_SUCCESS(LEVEL_VERBOSE); return STATUS_SUCCESS; }