// Called by Sensor CLX to set sampling rate of the sensor. NTSTATUS CustomSensorDevice::OnSetDataInterval( _In_ SENSOROBJECT SensorInstance, // sensor device object _In_ ULONG DataRateMs // sampling rate in milliseconds ) { PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance); NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); if (nullptr == pDevice || Cstm_Default_MinDataInterval_Ms > DataRateMs) { Status = STATUS_INVALID_PARAMETER; TraceError("CSTM %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT) SensorInstance, Status); goto Exit; } pDevice->m_Interval = DataRateMs; // reschedule sample to return as soon as possible if it's started if (FALSE != pDevice->m_Started) { pDevice->m_Started = FALSE; WdfTimerStop(pDevice->m_Timer, TRUE); pDevice->m_Started = TRUE; pDevice->m_FirstSample = TRUE; WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Cstm_Default_MinDataInterval_Ms)); } Exit: SENSOR_FunctionExit(Status); return Status; }
// Called by Sensor CLX to begin continously sampling the sensor. NTSTATUS CustomSensorDevice::OnStart( _In_ SENSOROBJECT SensorInstance // sensor device object ) { PHardwareSimulator pSimulator = nullptr; PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance); NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); if (nullptr == pDevice) { Status = STATUS_INVALID_PARAMETER; TraceError("PED %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT)SensorInstance, Status); } if (NT_SUCCESS(Status)) { // Get the simulator context pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); } } if (NT_SUCCESS(Status)) { // Start the simulator pSimulator->Start(); pDevice->m_FirstSample = TRUE; // Start polling pDevice->m_Started = TRUE; InitPropVariantFromUInt32(SensorState_Active, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); // Start the sample polling timer. // Note1: the WDF timer is only as precise as the system resolution allows it to be. // In the case of the CO2 sensor, the reporting interval is 200 milliseconds. The default // system resolution (15.6 milliseconds) is therefore fine enough to guarantee an accurate sample // reporting interval. Some sensors using a lower reporting interval may want to reduce the system // time resolution by calling into timeBeginPeriod() before starting the polling timer. // // Important consideration: calling into timeBeginPeriod() should be used with care as it has // an adverse on the system performance and power consumption. // // Note2: The polling timer is configured to allow for the first sample to be reported immediately. // Some hardware may want to delay the first sample report a little to account for hardware start time. WdfTimerStart(pDevice->m_Timer, 0); } SENSOR_FunctionExit(Status); return Status; }
NTSTATUS TpmEvtDeviceD0Entry( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE PreviousState ) { PTPM_CONTEXT TpmContext; NTSTATUS status; UNREFERENCED_PARAMETER(PreviousState); KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "TpmEvtDeviceD0Entry: Enter\n")); TpmContext = GetTpmContext(Device); TpmContext->AccessRegister = FALSE; TpmContinueSelfTest(TpmContext); #if _NT_TARGET_VERSION >= 0x601 TpmProvideEntropy(TpmContext); if(TpmContext->TimeOutSecond) { WdfTimerStart(TpmContext->timerHandle, WDF_REL_TIMEOUT_IN_MS(TpmContext->TimeOutSecond)); } #endif TpmUpdateTpmState(TpmContext,StAvailable,IdPowerup); return STATUS_SUCCESS; }
/** * @brief Transition to fully powered state with interrupts enabled. * This is the first chance we have to interact with a fully functional device, * so collect the device configuration so we can create a USB pdo that can be * enumerated by PnP. * * Allow failures to "succeed" (return STATUS_SUCCESS) so that the * dreaded Yellow Bang does not occur. Instead, this device will appear * normally in Windows Device Manager, however it will not instantiate * its child RootHub PDO. * * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd(). * * @returns NTSTATUS value indicating success or failure. * */ NTSTATUS FdoEvtDeviceD0EntryPostInterruptsEnabled( IN WDFDEVICE device, IN WDF_POWER_DEVICE_STATE) { NTSTATUS status = STATUS_SUCCESS; PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(device); BOOLEAN online = XenCheckOnline(fdoContext->Xen); if (!online) { /* Backend device disappeared behind our back (while guest was in S3, for example), clean it up.. */ CleanupDisconnectedDevice(fdoContext); return STATUS_SUCCESS; } if (!fdoContext->XenConfigured) { status = XenConfigure(fdoContext); if (!NT_SUCCESS(status)) { return status; } WdfTimerStart(fdoContext->WatchdogTimer, WDF_REL_TIMEOUT_IN_SEC(2)); } return status; }
// Called by Sensor CLX to begin keeping history NTSTATUS ActivityDevice::OnStartHistory(_In_ SENSOROBJECT sensorInstance) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance); if (nullptr == pDevice) { status = STATUS_INVALID_PARAMETER; TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status); } else if (0 == pDevice->m_HistorySizeInRecords) { status = STATUS_NOT_SUPPORTED; TraceError("ACT %!FUNC! Sensor does not support History"); } else if (FALSE == pDevice->m_PoweredOn) { status = STATUS_DEVICE_NOT_READY; TraceError("ACT %!FUNC! Sensor is not powered on! %!STATUS!", status); } else { // Start keeping history pDevice->m_HistoryStarted = TRUE; WdfTimerStart(pDevice->m_HistoryTimer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_HistoryIntervalInMs)); } SENSOR_FunctionExit(status); return status; }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback reads current value, compare value to threshold, // pushes it up to CLX framework, and schedule next wake up time. VOID ActivityDevice::OnTimerExpire(_In_ WDFTIMER timer) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(timer)); if (nullptr == pDevice) { status = STATUS_INSUFFICIENT_RESOURCES; TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status); } else { // Get data and push to clx WdfWaitLockAcquire(pDevice->m_Lock, NULL); status = pDevice->GetData(); if (!NT_SUCCESS(status) && STATUS_DATA_NOT_ACCEPTED != status) { TraceError("ACT %!FUNC! GetAccData Failed %!STATUS!", status); } WdfWaitLockRelease(pDevice->m_Lock); // Schedule next wake up time if (Act_Default_MinDataInterval_Ms <= pDevice->m_Interval && FALSE != pDevice->m_PoweredOn && FALSE != pDevice->m_Started) { WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval)); } } SENSOR_FunctionExit(status); }
// This callback is called when the simulator wait time has expired and the simulator // is ready to switch to the next sample. The callback updates the sample index and // schedules the next wake up time. VOID HardwareSimulator::OnTimerExpire( _In_ WDFTIMER Timer) // WDF timer object { HardwareSimulator *pSimulator = nullptr; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); pSimulator = GetHardwareSimulatorContextFromInstance(WdfTimerGetParentObject(Timer)); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); } if (NT_SUCCESS(Status)) { // Increment the sample index, roll over if the index reach the end of the array WdfWaitLockAcquire(pSimulator->m_Lock, NULL); pSimulator->m_Index++; pSimulator->m_Index = pSimulator->m_Index % ARRAYSIZE(SimulatorData); WdfWaitLockRelease(pSimulator->m_Lock); WdfTimerStart(pSimulator->m_Timer, WDF_REL_TIMEOUT_IN_MS(SIMULATOR_HARDWARE_INTERVAL_MS)); } SENSOR_FunctionExit(Status); }
BOOLEAN SerialSetTimer(IN WDFTIMER Timer, IN LARGE_INTEGER DueTime) /*++ Routine Description: This function must be called to set timers for the serial driver. Arguments: Timer - pointer to timer dispatcher object DueTime - time at which the timer should expire Return Value: Kicks up return value from KeSetTimerEx() --*/ { BOOLEAN result; // // If the timer object was already in the system timer queue, WdfTimerStart returns TRUE // result = WdfTimerStart(Timer, DueTime.QuadPart); return result; }
VOID NICStartWatchDogTimer( IN PFDO_DATA FdoData ) { LARGE_INTEGER dueTime; if(!FdoData->CheckForHang){ // // Set the link detection flag to indicate that NICWatchDogEvtTimerFunc // is first doing link-detection. // MP_SET_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION); FdoData->CheckForHang = FALSE; FdoData->bLinkDetectionWait = FALSE; FdoData->bLookForLink = FALSE; dueTime.QuadPart = NIC_LINK_DETECTION_DELAY; } else { dueTime.QuadPart = NIC_CHECK_FOR_HANG_DELAY; } WdfTimerStart(FdoData->WatchDogTimer, dueTime.QuadPart ); }
VOID Toastmon_EvtTimerPostRequests( IN WDFTIMER Timer ) /*++ Routine Description: Passive timer event to post read and write reqeuests. Return Value: None --*/ { PTARGET_DEVICE_INFO targetInfo; WDFIOTARGET ioTarget = GetTimerContext(Timer)->IoTarget; targetInfo = GetTargetDeviceInfo(ioTarget); // // Even though this routine and the completion routine check the // ReadRequest/WriteRequest field outside a lock, no harm is done. // Depending on how far the completion-routine has run, timer // may miss an opportunity to post a request. Even if we use a lock, // this race condition will still exist. // // // Send a read request to the target device // if(targetInfo->ReadRequest) { ToastMon_PostReadRequests(ioTarget); } // // Send a write request to the target device // if(targetInfo->WriteRequest) { ToastMon_PostWriteRequests(ioTarget); } // // Restart the passive timer. // WdfTimerStart(targetInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); return; }
VOID ToastMon_EvtIoTargetRemoveCanceled( WDFIOTARGET IoTarget ) /*++ Routine Description: Called when the Target device received IRP_MN_CANCEL_REMOVE. This happens if another app or driver talking to the target device doesn't close handle or veto query-remove notification. Arguments: IoTarget - Return Value: --*/ { PTARGET_DEVICE_INFO targetDeviceInfo = NULL; WDF_IO_TARGET_OPEN_PARAMS openParams; NTSTATUS status; PAGED_CODE(); KdPrint((("Device Removal (remove cancelled) Notification\n"))); targetDeviceInfo = GetTargetDeviceInfo(IoTarget); // // Reopen the Target. // WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN(&openParams); status = WdfIoTargetOpen(IoTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetOpen failed 0x%x\n", status)); WdfObjectDelete(IoTarget); return; } // // Restart the timer. // WdfTimerStart(targetDeviceInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); }
// Called by Sensor CLX to begin continuously sampling the sensor. NTSTATUS PedometerDevice::OnStart( _In_ SENSOROBJECT SensorInstance // Sensor device object ) { PHardwareSimulator pSimulator = nullptr; PPedometerDevice pDevice = GetPedometerContextFromSensorInstance(SensorInstance); NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); if (nullptr == pDevice) { Status = STATUS_INVALID_PARAMETER; TraceError("PED %!FUNC! Sensor(0x%p) parameter is invalid. Failed %!STATUS!", SensorInstance, Status); goto Exit; } // Get the simulator context pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); } if (NT_SUCCESS(Status)) { // Start the simulator pSimulator->Start(); pDevice->m_FirstSample = TRUE; // Start polling pDevice->m_Started = TRUE; InitPropVariantFromUInt32(SensorState_Active, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); // Start the sample polling timer. // // Note: The polling timer is configured to allow for the first sample to be reported immediately. // Some hardware may want to delay the first sample report a little to account for hardware start time. WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Pedometer_Default_MinDataInterval_Ms)); } Exit: SENSOR_FunctionExit(Status); return Status; }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback stores activity data in history buffer, // and schedules next wake up time. VOID ActivityDevice::OnHistoryTimerExpire(_In_ WDFTIMER historyTimer) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(historyTimer)); if (nullptr == pDevice) { status = STATUS_INSUFFICIENT_RESOURCES; TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status); } else { ActivitySample data = {}; if (NULL != pDevice->m_SimulatorInstance) { PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance); if (nullptr != pSimulator) { status = pSimulator->GetSample(&data); } else { status = STATUS_INVALID_PARAMETER; } } GetSystemTimePreciseAsFileTime(&(data.Timestamp)); if (NT_SUCCESS(status)) { // Add data to the buffer WdfWaitLockAcquire(pDevice->m_HistoryLock, NULL); status = pDevice->AddDataElementToHistoryBuffer(&data); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! AddDataElementToHistoryBuffer Failed %!STATUS!", status); } WdfWaitLockRelease(pDevice->m_HistoryLock); } // Schedule next wake up time if (FALSE != pDevice->m_HistoryStarted) { WdfTimerStart(pDevice->m_HistoryTimer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_HistoryIntervalInMs)); } } SENSOR_FunctionExit(status); }
// This routine starts the simulator // Returns an NTSTATUS code NTSTATUS HardwareSimulator::Start() { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); if (SimulatorState_Initialized == m_State) { WdfTimerStart(m_Timer, WDF_REL_TIMEOUT_IN_MS(HardwareSimulator_HardwareInterval)); m_State = SimulatorState_Started; } SENSOR_FunctionExit(status); return status; }
NTSTATUS Ds4_AddQueryInterfaces(WDFDEVICE Device) { NTSTATUS status; WDF_QUERY_INTERFACE_CONFIG ifaceCfg; INTERFACE devinterfaceHid; devinterfaceHid.Size = sizeof(INTERFACE); devinterfaceHid.Version = 1; devinterfaceHid.Context = (PVOID)Device; devinterfaceHid.InterfaceReference = WdfDeviceInterfaceReferenceNoOp; devinterfaceHid.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp; // Expose GUID_DEVINTERFACE_HID so HIDUSB can initialize WDF_QUERY_INTERFACE_CONFIG_INIT(&ifaceCfg, (PINTERFACE)&devinterfaceHid, &GUID_DEVINTERFACE_HID, NULL); status = WdfDeviceAddQueryInterface(Device, &ifaceCfg); if (!NT_SUCCESS(status)) { KdPrint(("WdfDeviceAddQueryInterface failed status 0x%x\n", status)); return status; } PDS4_DEVICE_DATA ds4Data = Ds4GetData(Device); // Set default HID input report (everything zero`d) UCHAR DefaultHidReport[DS4_HID_REPORT_SIZE] = { 0x01, 0x82, 0x7F, 0x7E, 0x80, 0x08, 0x00, 0x58, 0x00, 0x00, 0xFD, 0x63, 0x06, 0x03, 0x00, 0xFE, 0xFF, 0xFC, 0xFF, 0x79, 0xFD, 0x1B, 0x14, 0xD1, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }; // Initialize HID reports to defaults RtlCopyBytes(ds4Data->HidInputReport, DefaultHidReport, DS4_HID_REPORT_SIZE); RtlZeroMemory(&ds4Data->OutputReport, sizeof(DS4_OUTPUT_REPORT)); // Start pending IRP queue flush timer WdfTimerStart(ds4Data->PendingUsbInRequestsTimer, DS4_QUEUE_FLUSH_PERIOD); return STATUS_SUCCESS; }
NTSTATUS EchoEvtDeviceSelfManagedIoStart( IN WDFDEVICE Device ) /*++ Routine Description: This event is called by the Framework when the device is started or restarted after a suspend operation. This function is not marked pageable because this function is in the device power up path. When a function is marked pagable and the code section is paged out, it will generate a page fault which could impact the fast resume behavior because the client driver will have to wait until the system drivers can service this page fault. Arguments: Device - Handle to a framework device object. Return Value: NTSTATUS - Failures will result in the device stack being torn down. --*/ { PQUEUE_CONTEXT queueContext = QueueGetContext(WdfDeviceGetDefaultQueue(Device)); LARGE_INTEGER DueTime; KdPrint(("--> EchoEvtDeviceSelfManagedIoInit\n")); // // Restart the queue and the periodic timer. We stopped them before going // into low power state. // WdfIoQueueStart(WdfDeviceGetDefaultQueue(Device)); DueTime.QuadPart = WDF_REL_TIMEOUT_IN_MS(100); WdfTimerStart(queueContext->Timer, DueTime.QuadPart); KdPrint(( "<-- EchoEvtDeviceSelfManagedIoInit\n")); return STATUS_SUCCESS; }
// Called by Sensor CLX to begin continously sampling the sensor. NTSTATUS ActivityDevice::OnStart(_In_ SENSOROBJECT sensorInstance) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance); if (nullptr == pDevice) { status = STATUS_INVALID_PARAMETER; TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status); } else { if (FALSE == pDevice->m_PoweredOn) { status = STATUS_DEVICE_NOT_READY; TraceError("ACT %!FUNC! Sensor is not powered on! %!STATUS!", status); } else { // Start simulation if (NULL != pDevice->m_SimulatorInstance) { PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance); if (nullptr != pSimulator) { pSimulator->Start(); } } // Start sensing pDevice->m_FirstSample = TRUE; pDevice->m_Started = TRUE; InitPropVariantFromUInt32(SensorState_Active, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Act_Default_MinDataInterval_Ms)); } } SENSOR_FunctionExit(status); return status; }
NTSTATUS BOOTTRACKPAD( _In_ PDEVICE_CONTEXT pDevice ) { NTSTATUS status = 0; static char bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; static char bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; cyapa_boot_regs boot; FuncEntry(TRACE_FLAG_WDFLOADING); SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot)); if ((boot.stat & CYAPA_STAT_RUNNING) == 0) { if (boot.error & CYAPA_ERROR_BOOTLOADER) SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_deactivate, sizeof(bl_deactivate)); else SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_exit, sizeof(bl_exit)); } WDF_TIMER_CONFIG timerConfig; WDFTIMER hTimer; WDF_OBJECT_ATTRIBUTES attributes; WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaBootTimer); WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = pDevice->FxDevice; status = WdfTimerCreate(&timerConfig, &attributes, &hTimer); WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(75)); FuncExit(TRACE_FLAG_WDFLOADING); return status; }
/** * @brief Watchdog timer * checks the operational state of the xen interface and initiates surprise removal if * the interface is not operational and the device is not unplugged. * * @param[in] Timer handle to timer allocated by FdoDeviceAdd() * */ VOID FdoEvtTimerFunc( IN WDFTIMER Timer) { PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(WdfTimerGetParentObject(Timer)); // XenCheckOperationalState waits on an event. Must be called at < DISPATCH_LEVEL. BOOLEAN operational = XenCheckOperationalState(fdoContext->Xen); AcquireFdoLock(fdoContext); if (!fdoContext->DeviceUnplugged) { if (operational) { // restart the timer. WdfTimerStart(Timer, WDF_REL_TIMEOUT_IN_SEC(1)); } else { TraceEvents(TRACE_LEVEL_WARNING, TRACE_DEVICE, __FUNCTION__": %s Device %p unplug detected by watchdog\n", fdoContext->FrontEndPath, fdoContext->WdfDevice); FdoUnplugDevice(fdoContext); ReleaseFdoLock(fdoContext); return; } } ReleaseFdoLock(fdoContext); // // @todo run the dpc - if this fixes anything fix the bug! // if (!fdoContext->DeviceUnplugged) { // // --XT-- Now passing the FDO context directly. // FdoEvtDeviceDpcFunc(fdoContext); } }
NTSTATUS OnD0Entry( _In_ WDFDEVICE FxDevice, _In_ WDF_POWER_DEVICE_STATE FxPreviousState ) /*++ Routine Description: This routine allocates objects needed by the driver. Arguments: FxDevice - a handle to the framework device object FxPreviousState - previous power state Return Value: Status --*/ { FuncEntry(TRACE_FLAG_WDFLOADING); UNREFERENCED_PARAMETER(FxPreviousState); PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice); NTSTATUS status = STATUS_SUCCESS; WdfTimerStart(pDevice->Timer, WDF_REL_TIMEOUT_IN_MS(10)); BOOTTRACKPAD(pDevice); pDevice->RegsSet = false; pDevice->ConnectInterrupt = true; FuncExit(TRACE_FLAG_WDFLOADING); return status; }
VOID TpmEvtEntropyTimer(IN WDFTIMER Timer) { #if _NT_TARGET_VERSION >= 0x601 ULONG Interval; PTPM_CONTEXT TpmContext; PAGED_CODE(); TpmContext = GetTimerContext(Timer)->TpmContext; KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "TpmEvtEntropyTimer().\n")); if(TpmContext->bUseTimeOut) { TpmContext->PendingEntropy = TRUE; if(NT_SUCCESS(TpmUpdateTpmState(TpmContext,StBusy,IdEntropy))) { TpmProvideEntropy(TpmContext); TpmUpdateTpmState(TpmContext,StAvailable,IdEntropy); } } else { if(NT_SUCCESS(TpmGetEntropyInterval(&Interval))) { TpmContext->TimeOutSecond = 60000 * Interval; TpmContext->bUseTimeOut = TRUE; } } if(TpmContext->TimeOutSecond) { WdfTimerStart(TpmContext->timerHandle, WDF_REL_TIMEOUT_IN_MS(TpmContext->TimeOutSecond)); } #endif }
VOID EchoEvtTimerFunc( IN WDFTIMER Timer ) /*++ Routine Description: This is the TimerDPC the driver sets up to complete requests. This function is registered when the WDFTIMER object is created, and will automatically synchronize with the I/O Queue callbacks and cancel routine. Arguments: Timer - Handle to a framework Timer object. Return Value: VOID --*/ { NTSTATUS Status; WDFREQUEST Request; WDFQUEUE queue; PQUEUE_CONTEXT queueContext ; queue = WdfTimerGetParentObject(Timer); queueContext = QueueGetContext(queue); // // DPC is automatically synchronized to the Queue lock, // so this is race free without explicit driver managed locking. // Request = queueContext->CurrentRequest; if( Request != NULL ) { // // Attempt to remove cancel status from the request. // // The request is not completed if it is already cancelled // since the EchoEvtIoCancel function has run, or is about to run // and we are racing with it. // Status = WdfRequestUnmarkCancelable(Request); if( Status != STATUS_CANCELLED ) { queueContext->CurrentRequest = NULL; Status = queueContext->CurrentStatus; KdPrint(("CustomTimerDPC Completing request 0x%p, Status 0x%x \n", Request,Status)); WdfRequestComplete(Request, Status); } else { KdPrint(("CustomTimerDPC Request 0x%p is STATUS_CANCELLED, not completing\n", Request)); } } // // Restart the Timer since WDF does not allow periodic timer // with autosynchronization at passive level // WdfTimerStart(Timer, TIMER_PERIOD); return; }
NDIS_STATUS StaAssociate( __in PSTATION pStation, __in PSTA_BSS_ENTRY pAPEntry, __in ULONG AssociateTimeout ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PUCHAR pAssocPacket = NULL; USHORT AssocPacketLength; ULONG StatusCode = 0; MpEntry; do { // // Create the associate packet // ndisStatus = StaCreateAssociateRequestPacket( pStation, pAPEntry, &pAssocPacket, &AssocPacketLength ); if (ndisStatus != NDIS_STATUS_SUCCESS) { // // Complete the association process // StatusCode = ndisStatus; NdisAcquireSpinLock(&(pStation->ConnectContext.Lock)); if (pStation->ConnectContext.AssociateState == ASSOC_STATE_RECEIVED_AUTHENTICATE) { // // Reset ourselves to ready to original state // pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION; } NdisReleaseSpinLock(&(pStation->ConnectContext.Lock)); break; } NdisAcquireSpinLock(&(pStation->ConnectContext.Lock)); if ((pStation->ConnectContext.ConnectState >= CONN_STATE_READY_TO_CONNECT) && (pStation->ConnectContext.AssociateState == ASSOC_STATE_RECEIVED_AUTHENTICATE)) { // // Packet will be sent means we will be waiting for packet response // pStation->ConnectContext.AssociateState = ASSOC_STATE_WAITING_FOR_ASSOCIATE; // // Save association request packet inside the AP entry. This will be freed // on association completion indication // NdisDprAcquireSpinLock(&(pAPEntry->Lock)); pAPEntry->pAssocRequest = pAssocPacket; pAPEntry->AssocRequestLength = AssocPacketLength; NdisDprReleaseSpinLock(&(pAPEntry->Lock)); NdisReleaseSpinLock(&(pStation->ConnectContext.Lock)); } else { // // Reset, disconnect, deauthenticated by AP after authentication succeeded // NdisReleaseSpinLock(&(pStation->ConnectContext.Lock)); MpTrace(COMP_ASSOC, DBG_LOUD, ("Reset/Disconnect/Deauth while starting association\n")); // // Assoc packet pointer isnt saved, free it // StaFreeAssociateRequestPacket( pStation, pAPEntry, pAssocPacket, AssocPacketLength ); // // Abort association // StatusCode = (ULONG)STATUS_CANCELLED; break; } // // Send the association request packet // ndisStatus = Hw11SendMgmtPacket( pStation->pNic, pAPEntry, pAssocPacket, AssocPacketLength ); if (ndisStatus != NDIS_STATUS_SUCCESS) { MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Unable to send Association Request packet\n")); StatusCode = ndisStatus; NdisAcquireSpinLock(&(pStation->ConnectContext.Lock)); if (pStation->ConnectContext.AssociateState == ASSOC_STATE_WAITING_FOR_AUTHENTICATE) { // // Reset ourselves to ready to original state // pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION; } NdisReleaseSpinLock(&(pStation->ConnectContext.Lock)); break; } else { // Add an extra refcount for the association timer STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount); // // Set the timeout timer for associate failure case. // //NdisMSetTimer(&(pStation->ConnectContext.Timer_AssociateTimeout), AssociateTimeout); WdfTimerStart(pStation->ConnectContext.Timer_AssociateTimeout, WDF_REL_TIMEOUT_IN_MS(AssociateTimeout)); } // // We dont let the hardware pend the request since we will be // freeing the packet // MPVERIFY(ndisStatus != NDIS_STATUS_PENDING); }while (FALSE); // // Fail the association if we failed inline, etc // if (StatusCode != 0) { StaAssociateComplete(pStation, DOT11_ASSOC_STATUS_SYSTEM_ERROR); } return ndisStatus; }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback reads current value, // pushes it up to CLX framework, and schedule next wake up time. VOID CustomSensorDevice::OnTimerExpire( _In_ WDFTIMER Timer // WDF timer object ) { PCustomSensorDevice pDevice = nullptr; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); pDevice = GetCustomSensorContextFromSensorInstance(WdfTimerGetParentObject(Timer)); if (nullptr == pDevice) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("CSTM %!FUNC! GetCustomSensorContextFromSensorInstance failed %!STATUS!", Status); } if (NT_SUCCESS(Status)) { // Get data and push to clx WdfWaitLockAcquire(pDevice->m_Lock, NULL); Status = pDevice->GetData(); if (!NT_SUCCESS(Status) && Status != STATUS_DATA_NOT_ACCEPTED) { TraceError("CSTM %!FUNC! GetCstmData Failed %!STATUS!", Status); } WdfWaitLockRelease(pDevice->m_Lock); // Schedule next wake up time if (FALSE != pDevice->m_PoweredOn && FALSE != pDevice->m_Started) { LONGLONG WaitTimeHundredNanoseconds = 0; // in unit of 100ns if (0 == pDevice->m_StartTime) { // in case we fail to get sensor start time, use static wait time WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { ULONG CurrentTimeMs = 0; // dynamically calculate wait time to avoid jitter Status = GetPerformanceTime(&CurrentTimeMs); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! GetPerformanceTime %!STATUS!", Status); WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { WaitTimeHundredNanoseconds = pDevice->m_Interval - ((CurrentTimeMs - pDevice->m_StartTime) % pDevice->m_Interval); WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(WaitTimeHundredNanoseconds); } } WdfTimerStart(pDevice->m_Timer, WaitTimeHundredNanoseconds); } } SENSOR_FunctionExit(Status); }
// This the completion routine of the continuous reader. This can called concurrently on multiprocessor system if there are // more than one readers configured. So make sure to protect access to global resources. // void HidFx2EvtUsbInterruptPipeReadComplete( WDFUSBPIPE hPipe, WDFMEMORY hBuffer, size_t cNumBytesTransferred, WDFCONTEXT pContext ) { PDEVICE_EXTENSION pDevContext = pContext; BOOLEAN fInTimerQueue; unsigned char *pbSwitchState = NULL; unsigned char bCurrentSwitchState = 0; unsigned char bPrevSwitchState = 0; unsigned char bToggledSwitch = 0; UNREFERENCED_PARAMETER(cNumBytesTransferred); UNREFERENCED_PARAMETER(hPipe); TraceVerbose(DBG_INIT, "(%!FUNC!) Enter\n"); // Interrupt endpoints sends switch state when first started or when resuming from suspend. // We need to ignore that data since user did not change the switch state. if (pDevContext->fIsPowerUpSwitchState) { pDevContext->fIsPowerUpSwitchState = FALSE; TraceInfo(DBG_INIT, "(%!FUNC!) Dropping interrupt message since received during powerup/resume\n"); return; } // Make sure that there is data in the read packet. // Depending on the device specification, it is possible for it to return a 0 length read in certain conditions. if (cNumBytesTransferred == 0) { TraceWarning(DBG_INIT, "(%!FUNC!) Zero length read occured on the Interrupt Pipe's Continuous Reader\n"); return; } pbSwitchState = WdfMemoryGetBuffer(hBuffer, NULL); bCurrentSwitchState = ~(*pbSwitchState); // switchs are inverted on hardware boards bCurrentSwitchState &= RADIO_SWITCH_BUTTONS_BIT_MASK; //Mask off everything except the actual radio switch bit bPrevSwitchState = pDevContext->bCurrentSwitchState; if (bPrevSwitchState ^ bCurrentSwitchState) // make sure we toggled the radio switch { switch(pDevContext->driverMode) { // If it's a slider switch we want 0->1 and 1->0 transitions. case DM_SLIDER_SWITCH: case DM_SLIDER_SWITCH_AND_LED: bToggledSwitch = bCurrentSwitchState; // A timer is started for 10 ms everytime there is a switch toggled fInTimerQueue = WdfTimerStart(pDevContext->hDebounceTimer, WDF_REL_TIMEOUT_IN_MS(SWITCHPACK_DEBOUNCE_TIME)); TraceInfo(DBG_INIT, "(%!FUNC!) Debounce Timer started. Existing -%!bool!\n", fInTimerQueue); break; //If it's a button so we only report 0->1 transitions case DM_BUTTON: case DM_BUTTON_AND_LED: bToggledSwitch = (bPrevSwitchState ^ bCurrentSwitchState) & bCurrentSwitchState; if (bToggledSwitch != 0) { // A timer is started for 10 ms everytime there is a switch toggled on fInTimerQueue = WdfTimerStart(pDevContext->hDebounceTimer, WDF_REL_TIMEOUT_IN_MS(SWITCHPACK_DEBOUNCE_TIME)); TraceInfo(DBG_INIT, "(%!FUNC!) Debounce Timer started. Existing -%!bool!\n", fInTimerQueue); } break; // Ignore button presses if LED only case DM_LED_ONLY: default: break; } // Store switch state in device context pDevContext->bCurrentSwitchState = bCurrentSwitchState; pDevContext->bLatestToggledSwitch = bToggledSwitch; } else { TraceInfo(DBG_INIT, "(%!FUNC!) Not a radio switch toggle\n"); } TraceInfo(DBG_INIT, "(%!FUNC!) Switch 0x%x, prevSwitch:0x%x, X0R:0x%x\n", bCurrentSwitchState, bPrevSwitchState, bToggledSwitch); TraceVerbose(DBG_INIT, "(%!FUNC!) Exit\n"); }
VOID NICWatchDogEvtTimerFunc( IN WDFTIMER Timer ) /*++ Routine Description: This DPC is used to do both link detection during hardware init and after that for hardware hang detection. Arguments: Return Value: None --*/ { PFDO_DATA FdoData = NULL; LARGE_INTEGER DueTime; NTSTATUS status = STATUS_SUCCESS; FdoData = FdoGetData(WdfTimerGetParentObject(Timer)); DueTime.QuadPart = NIC_CHECK_FOR_HANG_DELAY; if(!FdoData->CheckForHang){ // // We are still doing link detection // status = NICLinkDetection(FdoData); if(status == STATUS_PENDING) { // Wait for 100 ms FdoData->bLinkDetectionWait = TRUE; DueTime.QuadPart = NIC_LINK_DETECTION_DELAY; }else { FdoData->CheckForHang = TRUE; } }else { // // Link detection is over, let us check to see // if the hardware is stuck. // if(NICCheckForHang(FdoData)){ status = NICReset(FdoData); if(!NT_SUCCESS(status)){ goto Exit; } } } WdfTimerStart(FdoData->WatchDogTimer, // Timer DueTime.QuadPart // DueTime ); return; Exit: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WatchDogTimer is exiting %x\n", status); return; }
VOID HidFx2EvtUsbInterruptPipeReadComplete( WDFUSBPIPE Pipe, WDFMEMORY Buffer, size_t NumBytesTransferred, WDFCONTEXT Context ) /*++ Routine Description: This the completion routine of the continuous reader. This can called concurrently on multiprocessor system if there are more than one readers configured. So make sure to protect access to global resources. Arguments: Pipe - Handle to WDF USB pipe object Buffer - This buffer is freed when this call returns. If the driver wants to delay processing of the buffer, it can take an additional referrence. NumBytesTransferred - number of bytes of data that are in the read buffer. Context - Provided in the WDF_USB_CONTINUOUS_READER_CONFIG_INIT macro Return Value: NT status value --*/ { PDEVICE_EXTENSION devContext = Context; UCHAR toggledSwitch = 0; PUCHAR switchState = NULL; UCHAR currentSwitchState = 0; UCHAR previousSwitchState = 0; UNREFERENCED_PARAMETER(NumBytesTransferred); UNREFERENCED_PARAMETER(Pipe); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "HidFx2EvtUsbInterruptPipeReadComplete Enter\n"); // // Interrupt endpoints sends switch state when first started // or when resuming from suspend. We need to ignore that data since // user did not change the switch state. // if (devContext->IsPowerUpSwitchState) { devContext->IsPowerUpSwitchState = FALSE; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "Dropping interrupt message since received during powerup/resume\n"); return; } // // Make sure that there is data in the read packet. Depending on the device // specification, it is possible for it to return a 0 length read in // certain conditions. // if (NumBytesTransferred == 0) { TraceEvents(TRACE_LEVEL_WARNING, DBG_INIT, "HidFx2EvtUsbInterruptPipeReadComplete Zero length read " "occured on the Interrupt Pipe's Continuous Reader\n" ); return; } switchState = WdfMemoryGetBuffer(Buffer, NULL); currentSwitchState = *switchState; previousSwitchState = devContext->CurrentSwitchState; // // we want to know which switch got toggled from 0 to 1 // Since the device returns the state of all the swicthes and not just the // one that got toggled, we need to store previous state and xor // it with current state to know whcih one swicth got toggled. // Further, the toggle is considered "on" only when it changes from 0 to 1 // (and not when it changes from 1 to 0). // toggledSwitch = (previousSwitchState ^ currentSwitchState) & currentSwitchState; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "HidFx2EvtUsbInterruptPipeReadComplete SwitchState %x, " "prevSwitch:0x%x, x0R:0x%x\n", currentSwitchState, previousSwitchState, toggledSwitch ); // // Store switch state in device context // devContext->CurrentSwitchState = *switchState; //if (toggledSwitch != 0) { devContext->LatestToggledSwitch = toggledSwitch; //} // // Complete pending Read requests if there is at least one switch toggled // to on position. // if (toggledSwitch != 0) { BOOLEAN inTimerQueue; // // Debounce the switchpack. A simple logic is used for debouncing. // A timer is started for 10 ms everytime there is a switch toggled on. // If within 10 ms same or another switch gets toggled, the timer gets // reset for another 10 ms. The HID read request is completed in timer // function if there is still a switch in toggled-on state. Note that // debouncing happens at the whole switch pack level (not individual // switches) which means if two different switches are toggled-on within // 10 ms only one of them (later one in this case) will get accepted and // sent to hidclass driver // inTimerQueue = WdfTimerStart( devContext->DebounceTimer, WDF_REL_TIMEOUT_IN_MS(SWICTHPACK_DEBOUNCE_TIME_IN_MS) ); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "Debounce Timer started with timeout of %d ms" " (TimerReturnValue:%d)\n", SWICTHPACK_DEBOUNCE_TIME_IN_MS, inTimerQueue); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "HidFx2EvtUsbInterruptPipeReadComplete Exit\n"); }
NTSTATUS LateSetup(IN WDFDEVICE Device) { PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(Device); NTSTATUS status = STATUS_SUCCESS; // // set up the XEN connection. // if (!fdoContext->NxprepBoot) { status = XenConfigure(fdoContext); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": Device %p xen configuration error %x", fdoContext->WdfDevice, status); return status; } // // get the USB device config data. // status = GetUsbConfigData(fdoContext); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s GetUsbConfigData error %x\n", fdoContext->FrontEndPath, status); } else if (fdoContext->BlacklistDevice) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s Device is blacklisted. No PDO.\n", fdoContext->FrontEndPath); } else { fdoContext->PortConnected = TRUE; } } if (fdoContext->PortConnected || fdoContext->NxprepBoot) { // // create a child device. // status = CreateRootHubPdo(fdoContext); if (NT_SUCCESS(status) && !fdoContext->NxprepBoot) { WdfTimerStart(fdoContext->WatchdogTimer, WDF_REL_TIMEOUT_IN_SEC(2)); } } TraceEvents(NT_SUCCESS(status) ? TRACE_LEVEL_INFORMATION : TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s Device %p status %x\n", fdoContext->FrontEndPath, fdoContext->WdfDevice, status); return status; }
NTSTATUS Toastmon_OpenDevice( WDFDEVICE Device, PUNICODE_STRING SymbolicLink, WDFIOTARGET *Target ) /*++ Routine Description: Open the I/O target and preallocate any resources required to communicate with the target device. Arguments: Return Value: NTSTATUS --*/ { NTSTATUS status = STATUS_SUCCESS; PTARGET_DEVICE_INFO targetDeviceInfo = NULL; WDF_IO_TARGET_OPEN_PARAMS openParams; WDFIOTARGET ioTarget; WDF_OBJECT_ATTRIBUTES attributes; PDEVICE_EXTENSION deviceExtension = GetDeviceExtension(Device); WDF_TIMER_CONFIG wdfTimerConfig; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TARGET_DEVICE_INFO); status = WdfIoTargetCreate(deviceExtension->WdfDevice, &attributes, &ioTarget); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetCreate failed 0x%x\n", status)); return status; } targetDeviceInfo = GetTargetDeviceInfo(ioTarget); targetDeviceInfo->DeviceExtension = deviceExtension; // // Warning: It's not recommended to open the targetdevice // from a pnp notification callback routine, because if // the target device initiates any kind of PnP action as // a result of this open, the PnP manager could deadlock. // You should queue a workitem to do that. // For example, SWENUM devices in conjunction with KS // initiate an enumeration of a device when you do the // open on the device interface. // We can open the target device here because we know the // toaster function driver doesn't trigger any pnp action. // WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( &openParams, SymbolicLink, STANDARD_RIGHTS_ALL); openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ; // // Framework provides default action for all of these if you don't register // these callbacks -it will close the handle to the target when the device is // being query-removed and reopen it if the query-remove fails. // In this sample, we use a periodic timers to post requests to the target. // So we need to register these callbacks so that we can start and stop // the timer when the state of the target device changes. Since we are // registering these callbacks, we are now responsbile for closing and // reopening the target. // openParams.EvtIoTargetQueryRemove = ToastMon_EvtIoTargetQueryRemove; openParams.EvtIoTargetRemoveCanceled = ToastMon_EvtIoTargetRemoveCanceled; openParams.EvtIoTargetRemoveComplete = ToastMon_EvtIoTargetRemoveComplete; status = WdfIoTargetOpen(ioTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetOpen failed with status 0x%x\n", status)); WdfObjectDelete(ioTarget); return status; } KdPrint(("Target Device 0x%x, PDO 0x%x, Fileobject 0x%x, Filehandle 0x%x\n", WdfIoTargetWdmGetTargetDeviceObject(ioTarget), WdfIoTargetWdmGetTargetPhysicalDevice(ioTarget), WdfIoTargetWdmGetTargetFileObject(ioTarget), WdfIoTargetWdmGetTargetFileHandle(ioTarget))); // // Create two requests - one for read and one for write. // WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = ioTarget; status = WdfRequestCreate(&attributes, ioTarget, &targetDeviceInfo->ReadRequest); if (!NT_SUCCESS(status)) { WdfObjectDelete(ioTarget); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = ioTarget; status = WdfRequestCreate(&attributes, ioTarget, &targetDeviceInfo->WriteRequest); if (!NT_SUCCESS(status)) { WdfObjectDelete(ioTarget); return status; } // // Create a passive timer to post requests to the I/O target. // WDF_TIMER_CONFIG_INIT(&wdfTimerConfig, Toastmon_EvtTimerPostRequests); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TIMER_CONTEXT); // // Make IoTarget as parent of the timer to prevent the ioTarget // from deleted until the dpc has runto completion. // attributes.ParentObject = ioTarget; // // By specifying WdfExecutionLevelPassive the framework will invoke // the timer callback Toastmon_EvtTimerPostRequests at PASSIVE_LEVEL. // attributes.ExecutionLevel = WdfExecutionLevelPassive; // // Setting the AutomaticSerialization to FALSE prevents // WdfTimerCreate to fail if the parent device object's // execution level is set to WdfExecutionLevelPassive. // wdfTimerConfig.AutomaticSerialization = FALSE; status = WdfTimerCreate(&wdfTimerConfig, &attributes, &targetDeviceInfo->TimerForPostingRequests ); if(!NT_SUCCESS(status)) { KdPrint(("WdfTimerCreate failed 0x%x\n", status)); WdfObjectDelete(ioTarget); return status; } GetTimerContext(targetDeviceInfo->TimerForPostingRequests)->IoTarget = ioTarget; // // Start the passive timer. The first timer will be queued after 1ms interval and // after that it will be requeued in the timer callback function. // The value of 1 ms (lowest timer resoltion allowed on NT) is chosen here so // that timer would fire right away. // WdfTimerStart(targetDeviceInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_MS(1)); *Target = ioTarget; return status; }
VOID ToastMon_EvtIoTargetRemoveCanceled( WDFIOTARGET IoTarget ) /*++ Routine Description: Called when the Target device received IRP_MN_CANCEL_REMOVE. This happens if another app or driver talking to the target device doesn't close handle or veto query-remove notification. Arguments: IoTarget - Return Value: --*/ { PTARGET_DEVICE_INFO targetDeviceInfo = NULL; WDFWAITLOCK targetDeviceCollectionLock; WDF_IO_TARGET_OPEN_PARAMS openParams; NTSTATUS status; PAGED_CODE(); KdPrint((("Device Removal (remove cancelled) Notification\n"))); targetDeviceInfo = GetTargetDeviceInfo(IoTarget); // // Reopen the Target. // WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN(&openParams); status = WdfIoTargetOpen(IoTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetOpen failed 0x%x\n", status)); WdfObjectDelete(IoTarget); return; } targetDeviceCollectionLock = targetDeviceInfo->DeviceExtension->TargetDeviceCollectionLock; // // The query remove has failed and the target has been successfully reopened. Set Opened // back to TRUE to reflect the state change. // WdfWaitLockAcquire(targetDeviceCollectionLock, NULL); targetDeviceInfo->Opened = TRUE; WdfWaitLockRelease(targetDeviceCollectionLock); // // Restart the timer. // WdfTimerStart(targetDeviceInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); }