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; }
NTSTATUS TpmEntropyInit(PTPM_CONTEXT TpmContext) { NTSTATUS status = STATUS_SUCCESS; #if _NT_TARGET_VERSION >= 0x601 // win7 WDF_TIMER_CONFIG timerConfig; WDF_OBJECT_ATTRIBUTES timerAttributes; WDFTIMER timerHandle; PTPM_ENTROPY_TIMER_CONTEXT TimerContext; PAGED_CODE(); status = EntropyRegisterSource(&TpmContext->hEntropySource, ENTROPY_SOURCE_TYPE_TPM, CNG_ENTROPY_NAME); TpmContext->EntropyDensity = TpmGetEntropyDensity(); TpmContext->TimeOutSecond = 60000; timerConfig.TolerableDelay = 60000; TpmContext->bUseTimeOut = FALSE; TpmContext->PendingEntropy = FALSE; WDF_TIMER_CONFIG_INIT(&timerConfig, TpmEvtEntropyTimer); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timerAttributes,TPM_ENTROPY_TIMER_CONTEXT); timerAttributes.ParentObject = TpmContext->Device; status = WdfTimerCreate( &timerConfig, &timerAttributes, &TpmContext->timerHandle ); if(NT_SUCCESS(status)) { TimerContext = GetTimerContext(TpmContext->timerHandle); TimerContext->TpmContext = TpmContext; } #endif 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 }
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; }