VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context) { ULONG ActiveProcessorCount; ULONG i; highsync_info_t *highsync_info; KIRQL old_irql; UNREFERENCED_PARAMETER(context); FUNCTION_ENTER(); highsync_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(highsync_info_t), XENPCI_POOL_TAG); RtlZeroMemory(highsync_info, sizeof(highsync_info_t)); KeInitializeEvent(&highsync_info->highsync_complete_event, SynchronizationEvent, FALSE); highsync_info->function0 = function0; highsync_info->functionN = functionN; highsync_info->context = context; highsync_info->sync_level = HIGH_LEVEL; #if (NTDDI_VERSION >= NTDDI_WINXP) ActiveProcessorCount = (ULONG)KeNumberProcessors; #else ActiveProcessorCount = (ULONG)*KeNumberProcessors; #endif /* Go to HIGH_LEVEL to prevent any races with Dpc's on the current processor */ KeRaiseIrql(highsync_info->sync_level, &old_irql); highsync_info->do_spin = TRUE; for (i = 0; i < ActiveProcessorCount; i++) { if (i == 0) KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunction0, highsync_info); else KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunctionN, highsync_info); KeSetTargetProcessorDpc(&highsync_info->dpcs[i], (CCHAR)i); KeSetImportanceDpc(&highsync_info->dpcs[i], HighImportance); KdPrint((__DRIVER_NAME " queuing Dpc for CPU %d\n", i)); KeInsertQueueDpc(&highsync_info->dpcs[i], NULL, NULL); } KdPrint((__DRIVER_NAME " All Dpc's queued\n")); KeMemoryBarrier(); KeLowerIrql(old_irql); KdPrint((__DRIVER_NAME " Waiting for highsync_complete_event\n")); KeWaitForSingleObject(&highsync_info->highsync_complete_event, Executive, KernelMode, FALSE, NULL); #if (NTDDI_VERSION >= NTDDI_WINXP) KeFlushQueuedDpcs(); #else { /* just wait 1 second until all DPC's finish - not ideal but it's only for W2K */ LARGE_INTEGER interval; interval.QuadPart = -1 * 1000 * 1000 * 10; /* 1 second */ KeDelayExecutionThread(KernelMode, FALSE, &interval); } #endif ExFreePoolWithTag(highsync_info, XENPCI_POOL_TAG); FUNCTION_EXIT(); }
VOID AllocTimeouts(PC0C_IO_PORT pIoPort) { KeInitializeTimer(&pIoPort->timerReadTotal); KeInitializeTimer(&pIoPort->timerReadInterval); KeInitializeTimer(&pIoPort->timerWriteTotal); KeInitializeTimer(&pIoPort->timerClose); KeInitializeDpc(&pIoPort->timerReadTotalDpc, TimeoutReadTotal, pIoPort); KeInitializeDpc(&pIoPort->timerReadIntervalDpc, TimeoutReadInterval, pIoPort); KeInitializeDpc(&pIoPort->timerWriteTotalDpc, TimeoutWriteTotal, pIoPort); KeInitializeDpc(&pIoPort->timerCloseDpc, TimeoutClose, pIoPort); }
VOID LlcInitializeTimerSystem( VOID ) /*++ Routine Description: This routine initializes the lightweight timer system for the data link driver. Arguments: None. Return Value: None. --*/ { ASSUME_IRQL(PASSIVE_LEVEL); KeInitializeDpc(&TimerSystemDpc, ScanTimersDpc, NULL); KeInitializeTimer(&SystemTimer); KeSetTimer(&SystemTimer, DueTime, &TimerSystemDpc); }
NTSTATUS NotifierInitialize( IN PXENVIF_FRONTEND Frontend, OUT PXENVIF_NOTIFIER *Notifier ) { NTSTATUS status; *Notifier = __NotifierAllocate(sizeof (XENVIF_NOTIFIER)); status = STATUS_NO_MEMORY; if (*Notifier == NULL) goto fail1; (*Notifier)->Frontend = Frontend; KeInitializeSpinLock(&(*Notifier)->Lock); KeInitializeDpc(&(*Notifier)->Dpc, NotifierDpc, *Notifier); return STATUS_SUCCESS; fail1: Error("fail1 (%08x)\n", status); return status; }
/**************************************************************************** REMARKS: Function to register a driver heart beat callback function. The first function that is called sets the interval for all the callback functions and they will be called in the order they were registered. This function will implement this mechanism in whatever way is appropriate for the device driver environment. Note that currently there is no mechanism to specify the timer intervals at run-time, so we use a pre-determined value of 32 milliseconds that will be useful for NT display driver polling and DPVL update functions. ****************************************************************************/ void PMAPI PM_registerHeartBeatCallback( PM_heartBeat_cb cb, void *data) { // Kernel objects must always be resident in memory if (_PM_hb == NULL) { _PM_hb = ExAllocatePool(NonPagedPool, sizeof(_PM_heartBeat_t)); if (_PM_hb == NULL) return; RtlZeroMemory(_PM_hb, sizeof(_PM_heartBeat_t)); } // If first time called, start periodic timer (pre-determined intervals) if (_PM_hb->numHeartBeatCallbacks == 0) { KeInitializeTimer(&_PM_hb->kTimer); KeInitializeDpc(&_PM_hb->kTimerDpc,_PM_heartBeatTimeout,(void*)_PM_hb); KeSetTimerEx(&_PM_hb->kTimer,RtlConvertLongToLargeInteger(-10000*HEART_BEAT_MS), HEART_BEAT_MS,&_PM_hb->kTimerDpc); KeInitializeEvent(&_PM_hb->kTimerEvent,NotificationEvent,FALSE); // Callbacks will be executed within driver helper thread, not DPC _PM_hb->bThreadRunning = true; PsCreateSystemThread(&_PM_hb->hDriverThread,THREAD_ALL_ACCESS,NULL, NULL,NULL,_PM_heartBeatThread,(void*)_PM_hb); } // Add heart beat callback to list PM_lockSNAPAccess(-1,true); if (_PM_hb->numHeartBeatCallbacks < MAX_HEART_BEAT_CALLBACKS) { _PM_hb->heartBeat[_PM_hb->numHeartBeatCallbacks] = cb; _PM_hb->heartBeatData[_PM_hb->numHeartBeatCallbacks] = data; _PM_hb->numHeartBeatCallbacks++; } PM_unlockSNAPAccess(-1); }
VOID CmpInitializeDelayedCloseTable() /*++ Routine Description: Initialize delayed close table; allocation + LRU list initialization. Arguments: Return Value: NONE. --*/ { ExInitializeWorkItem(&CmpDelayCloseWorkItem, CmpDelayCloseWorker, NULL); KeInitializeGuardedMutex(&CmpDelayedCloseTableLock); InitializeListHead(&(CmpDelayedLRUListHead)); KeInitializeDpc(&CmpDelayCloseDpc, CmpDelayCloseDpcRoutine, NULL); KeInitializeTimer(&CmpDelayCloseTimer); }
NTSTATUS EventLogStart(PEVENT_LOG EventLog) { LARGE_INTEGER TimerDueTime; NTSTATUS Status; RtlZeroMemory(EventLog, sizeof(EVENT_LOG)); InitializeListHead(&EventLog->EventListHead); KeInitializeSpinLock(&EventLog->EventListLock); KeInitializeTimer(&EventLog->Timer); KeInitializeDpc(&EventLog->TimerDpc, EventLogTimerDpcRoutine, EventLog); SysWorkerInit(&EventLog->Worker); Status = SysWorkerStart(&EventLog->Worker); if (!NT_SUCCESS(Status)) { goto start_failed; } TimerDueTime.QuadPart = 0; KeSetTimerEx(&EventLog->Timer, TimerDueTime, 500, &EventLog->TimerDpc); return STATUS_SUCCESS; start_failed: EventLog->Stopping = 1; KeCancelTimer(&EventLog->Timer); KeFlushQueuedDpcs(); SysWorkerStop(&EventLog->Worker); EventLogFlush(EventLog); return Status; }
void init_redirection(struct scsifilt *sf) { InitializeListHead(&sf->redirect_srb_list); InitializeListHead(&sf->redirect_complete_list); KeInitializeDpc(&sf->redirect_srb_dpc, redirect_srb_dpc, sf); }
NTSTATUS InitializeEventing(CEncoderDevice* pEncDevice) { // First, allocate buffers NTSTATUS ntStatus = STATUS_SUCCESS; if(!EventHandler) { EventHandler = (PEventHandlerData)ExAllocatePoolWithTag(NonPagedPool, sizeof(EventHandlerData), MS_SAMPLE_ANALOG_POOL_TAG); if (!EventHandler) { ntStatus = STATUS_UNSUCCESSFUL; return ntStatus; } pEncDevice->EventData = reinterpret_cast<PVOID>(EventHandler); KeInitializeEvent(&(EventHandler->InitEvent), SynchronizationEvent, FALSE); KeInitializeEvent(&(EventHandler->TuneEvent), SynchronizationEvent, FALSE); KeInitializeEvent(&(EventHandler->ThreadEvent), SynchronizationEvent, FALSE); KeInitializeSpinLock(&(EventHandler->LockAccess)); KeInitializeDpc (&(EventHandler->DPCObject), reinterpret_cast <PKDEFERRED_ROUTINE>(TimerDpcInterrupt), EventHandler); KeInitializeTimerEx(&(EventHandler->timer), SynchronizationTimer); } KeClearEvent(&(EventHandler->InitEvent)); KeClearEvent(&(EventHandler->TuneEvent)); KeClearEvent(&(EventHandler->ThreadEvent)); return ntStatus; }
void dtrace_hook_int(UCHAR ivec, void (*InterruptHandler)( void ), uintptr_t *paddr) { INT_VECTOR OrgVec; int i; PRKDPC Dpc; cpunos = 0; if (paddr != 0) { BackupInterrupt(ivec, &OrgVec); #ifdef _AMD64_ *(ULONG64 *)paddr = VEC_OFFSET_TO_ADDR(OrgVec); #else *(ULONG32 *)paddr = VEC_OFFSET_TO_ADDR(OrgVec); #endif } Dpc = (PRKDPC) ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC)*KeNumberProcessors, 'Tag1'); for (i = 0; i < KeNumberProcessors; i++) { KeInitializeDpc(&Dpc[i], hook_init, NULL); } KeInitializeEvent(&SyncIDT, NotificationEvent, FALSE); for (i=0; i < KeNumberProcessors; i++) { KeSetTargetProcessorDpc(&Dpc[i], (char) i); KeSetImportanceDpc(&Dpc[i], HighImportance); KeInsertQueueDpc(&Dpc[i], (PVOID) ivec, (PVOID)InterruptHandler); } KeWaitForSingleObject(&SyncIDT,Executive,KernelMode,0,NULL); KeClearEvent(&SyncIDT); ExFreePoolWithTag(Dpc, 'Tag1'); }
VOID SendEachProcessorDpc ( PKDEFERRED_ROUTINE Routine, PVOID Context, PVOID SysArg1, PVOID SysArg2 ) /*++ Routine Description This routine sends DPC to each processor in multiprocessor system Arguments Routine Deferred routine Context, SysArg1, SysArg2 Parameters, see MSDN doc for KeInitializeDpc, KeInsertQueueDpc Return Value None --*/ { UNICODE_STRING u; RtlInitUnicodeString (&u, L"KeFlushQueuedDpcs"); *(PVOID*)&pKeFlushQueuedDpcs = MmGetSystemRoutineAddress (&u); for (CCHAR i=0; i<KeNumberProcessors; i++) { KDPC Dpc; KdPrint(("SendEachProcessorDpc: processor [%d] in queue\n", i)); KeInitializeDpc (&Dpc, Routine, Context); KeSetTargetProcessorDpc (&Dpc, i); KeInsertQueueDpc (&Dpc, SysArg1, SysArg2); KdPrint(("SendEachProcessorDpc: processor [%d] completed its DPC\n", i)); } if (pKeFlushQueuedDpcs) { // Ensure that all DPCs are delivered. pKeFlushQueuedDpcs (); } else { KdPrint(("pKeFlushQueuedDpcs = NULL!!!\n")); } KdPrint(("SendEachProcessorDpc: all completed\n")); }
VOID KiInitializeInterruptTimers( VOID ) { LARGE_INTEGER DueTime; // // If not timing ISRs, nothing to do. // if (KiTimeLimitIsrMicroseconds == 0) { return; } // // The kernel is initialized. Use a timer to determine the amount // the Time Stamp Counter advances by in 10 seconds, then use that // result to set the ISR time limit. // if ((KeFeatureBits & KF_RDTSC) == 0) { // // Processor doesn't support the RDTSC instruction, don't attempt // to time ISRs. // return; } KiIsrTimerInit = ExAllocatePoolWithTag(NonPagedPool, sizeof(*KiIsrTimerInit), ' eK'); if (KiIsrTimerInit == NULL) { // // Couldn't allocate memory for timer? Skip ISR timing. // return; } KeInitializeTimerEx(&KiIsrTimerInit->SampleTimer, SynchronizationTimer); KeInitializeDpc(&KiIsrTimerInit->Dpc, &KiInitializeInterruptTimersDpc, NULL); // // Relative time in 100 nanoseconds = 10 seconds. // DueTime.QuadPart = -(10 * 10 * 1000 * 1000); KeSetTimerEx(&KiIsrTimerInit->SampleTimer, DueTime, // 10000, // repeat in 10 seconds. &KiIsrTimerInit->Dpc); }
VOID MPCreateThread(VOID (*FunctionPointer)(IN PKDPC, IN PVOID, IN PVOID, IN PVOID)) { /* * * Multi-Processor Consideration :: * * Each processor has it's own IDT. * */ CCHAR i; long currentProcessor =0; PKDPC pkDpc =NULL; KIRQL oldIrql, currentIrql; allProcessorDone =0; currentIrql = KeGetCurrentIrql(); if (currentIrql < DISPATCH_LEVEL) KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); InterlockedAnd(&allProcessorDone, 0); pkDpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool, KeNumberProcessors * sizeof(KDPC), (ULONG)' pni'); if (!pkDpc) { DbgPrint("Insufficient Resource error\n"); return; } currentProcessor = KeGetCurrentProcessorNumber(); for (i = 0; i < KeNumberProcessors; i++) { cpuNum[i] =i; KeInitializeDpc(&pkDpc[i], FunctionPointer, &cpuNum[i]); KeSetTargetProcessorDpc(&pkDpc[i], i); KeInsertQueueDpc(&pkDpc[i], NULL, NULL); } // wait for all of the processor's hooking initialization. while(InterlockedCompareExchange(&allProcessorDone, KeNumberProcessors - 1, KeNumberProcessors - 1) != KeNumberProcessors - 1) { _asm pause; } if (currentIrql < DISPATCH_LEVEL) KeLowerIrql(oldIrql); if (pkDpc) { ExFreePool(pkDpc); pkDpc = NULL; } }
NTSTATUS KrnlHlprDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn, _In_ CLASSIFY_DATA* pClassifyData, _In_ REDIRECT_DATA* pRedirectData, _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprDPCQueue()\n"); #endif /// DBG NT_ASSERT(pDPCFn); NT_ASSERT(pClassifyData); NT_ASSERT(pRedirectData); NTSTATUS status = STATUS_SUCCESS; DPC_DATA* pDPCData = 0; status = KrnlHlprDPCDataCreate(&pDPCData, pClassifyData, pRedirectData, pContext); HLPR_BAIL_ON_FAILURE(status); KeInitializeDpc(&(pDPCData->kdpc), pDPCFn, 0); KeInsertQueueDpc(&(pDPCData->kdpc), pDPCData, 0); HLPR_BAIL_LABEL: #pragma warning(push) #pragma warning(disable: 6001) /// pDPCData initialized with call to KrnlHlprDPCDataCreate if(status != STATUS_SUCCESS && pDPCData) KrnlHlprDPCDataDestroy(&pDPCData); #pragma warning(pop) #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprDPCQueue() [status: %#x]\n", status); #endif /// DBG return status; }
VOID natInitFwSession() { LARGE_INTEGER DueTime; KeInitializeTimer(&g_FwSessionTimer); KeInitializeDpc(&g_FwSessionDpc, natFwSessionTimerFunction, NULL); InitializeListHead(&g_FwSessionList); NdisAllocateSpinLock(&g_FwSessionLock); DueTime.QuadPart = -1; KeSetTimerEx(&g_FwSessionTimer, DueTime, INIT_SESSION_TIMEOUT_SEC*1000 ,&g_FwSessionDpc); }
VOID CmpInitDelayDerefKCBEngine() { InitializeListHead(&CmpDelayDerefKCBListHead); KeInitializeGuardedMutex(&CmpDelayDerefKCBLock); ExInitializeWorkItem(&CmpDelayDerefKCBWorkItem, CmpDelayDerefKCBWorker, NULL); KeInitializeDpc(&CmpDelayDerefKCBDpc, CmpDelayDerefKCBDpcRoutine, NULL); KeInitializeTimer(&CmpDelayDerefKCBTimer); }
VOID SrvSetTimer ( IN PSRV_TIMER Timer, IN PLARGE_INTEGER Timeout, IN PKDEFERRED_ROUTINE TimeoutHandler, IN PVOID Context ) /*++ Routine Description: This routine starts a timer. Arguments: Timer -- pointer to the timer Timeout -- number of milliseconds to wait TimeoutHandler -- routine to call if the timer expires Context -- context value for the timer routine Return Value: None. --*/ { PRKDPC Dpc = &Timer->Dpc; PAGED_CODE( ); // // Initialize the DPC associated with the timer. Reset the event // that indicates that the timer routine has run. Set the timer. // KeInitializeDpc( Dpc, TimeoutHandler, Context ); KeSetTargetProcessorDpc( Dpc, (CCHAR)KeGetCurrentProcessorNumber() ); KeClearEvent( &Timer->Event ); KeSetTimer( &Timer->Timer, *Timeout, Dpc ); return; } // SrvSetTimer
NTSTATUS KrnlHlprDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprDPCQueue()\n"); #endif /// DBG NT_ASSERT(pDPCFn); NTSTATUS status = STATUS_SUCCESS; DPC_DATA* pDPCData = 0; HLPR_NEW(pDPCData, DPC_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(pDPCData, status); KeInitializeDpc(&(pDPCData->kdpc), pDPCFn, 0); KeInsertQueueDpc(&(pDPCData->kdpc), pDPCData, 0); HLPR_BAIL_LABEL: #pragma warning(push) #pragma warning(disable: 6001) /// pDPCData initialized with call to HLPR_NEW if(status != STATUS_SUCCESS && pDPCData) KrnlHlprDPCDataDestroy(&pDPCData); #pragma warning(pop) #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprDPCQueue() [status: %#x]\n", status); #endif /// DBG return status; }
CHardwareSimulation:: CHardwareSimulation ( IN IHardwareSink *HardwareSink ) : m_HardwareSink (HardwareSink), m_ScatterGatherMappingsMax (SCATTER_GATHER_MAPPINGS_MAX) /*++ Routine Description: Construct a hardware simulation Arguments: HardwareSink - The hardware sink interface. This is used to trigger fake interrupt service routines from. Return Value: Success / Failure --*/ { PAGED_CODE(); // // Initialize the DPC's, timer's, and locks necessary to simulate // this capture hardware. // KeInitializeDpc ( &m_IsrFakeDpc, SimulatedInterrupt, this ); KeInitializeEvent ( &m_HardwareEvent, SynchronizationEvent, FALSE ); KeInitializeTimer (&m_IsrTimer); KeInitializeSpinLock (&m_ListLock); }
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { Debug(("Enter DriverEntry\n")); pDriverObject->DriverUnload = DriverUnload; pDriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreate; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose; pDriverObject->MajorFunction[IRP_MJ_WRITE] = DriverWrite; pDriverObject->MajorFunction[IRP_MJ_READ] = DriverRead; //创建设备 PDEVICE_OBJECT tDev; UNICODE_STRING tDevName; RtlInitUnicodeString(&tDevName,DEVICE_NAME); NTSTATUS tRetStatus; tRetStatus = IoCreateDevice(pDriverObject, sizeof(MyDeviceExtend), &tDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &tDev); if(false == NT_SUCCESS(tRetStatus)) { Debug("IoCreateDevice fail"); return tRetStatus; } //创建符号链接 UNICODE_STRING tSymbolicName; RtlInitUnicodeString(&tSymbolicName,DEVICE_SYMBOLICLINK); tRetStatus = IoCreateSymbolicLink(&tSymbolicName,&tDevName); if(false == NT_SUCCESS(tRetStatus)) { Debug("IoCreateSymbolicLink fail"); IoDeleteDevice(tDev); return tRetStatus; } tDev->Flags |= DO_BUFFERED_IO; MyDeviceExtend* tMyDevExtend = (MyDeviceExtend*)tDev->DeviceExtension; KeInitializeTimer(&tMyDevExtend->Timer); KeInitializeDpc(&tMyDevExtend->DPC,OnTimeDPC,(void*)tDev); return STATUS_SUCCESS; }
VOID NTAPI CmpCmdInit(IN BOOLEAN SetupBoot) { LARGE_INTEGER DueTime; PAGED_CODE(); /* Setup the lazy DPC */ KeInitializeDpc(&CmpLazyFlushDpc, CmpLazyFlushDpcRoutine, NULL); /* Setup the lazy timer */ KeInitializeTimer(&CmpLazyFlushTimer); /* Setup the lazy worker */ ExInitializeWorkItem(&CmpLazyWorkItem, CmpLazyFlushWorker, NULL); /* Setup the forced-lazy DPC and timer */ KeInitializeDpc(&CmpEnableLazyFlushDpc, CmpEnableLazyFlushDpcRoutine, NULL); KeInitializeTimer(&CmpEnableLazyFlushTimer); /* Enable lazy flushing after 10 minutes */ DueTime.QuadPart = Int32x32To64(600, -10 * 1000 * 1000); KeSetTimer(&CmpEnableLazyFlushTimer, DueTime, &CmpEnableLazyFlushDpc); /* Setup flush variables */ CmpNoWrite = CmpMiniNTBoot; CmpWasSetupBoot = SetupBoot; /* Testing: Force Lazy Flushing */ CmpHoldLazyFlush = FALSE; /* Setup the hive list */ CmpInitializeHiveList(SetupBoot); }
VOID TransferPacketQueueRetryDpc(PTRANSFER_PACKET Pkt) { KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt); if (Pkt->RetryIn100nsUnits == 0){ KeInsertQueueDpc(&Pkt->RetryTimerDPC, NULL, NULL); } else { LARGE_INTEGER timerPeriod; NT_ASSERT(Pkt->RetryIn100nsUnits < 100 * 1000 * 1000 * 10); // sanity check -- 100 seconds is normally too long timerPeriod.QuadPart = -(Pkt->RetryIn100nsUnits); KeInitializeTimer(&Pkt->RetryTimer); KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC); } }
VOID NTAPI INIT_FUNCTION PoInitializePrcb(IN PKPRCB Prcb) { /* Initialize the Power State */ RtlZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState)); Prcb->PowerState.Idle0KernelTimeLimit = 0xFFFFFFFF; Prcb->PowerState.CurrentThrottle = 100; Prcb->PowerState.CurrentThrottleIndex = 0; Prcb->PowerState.IdleFunction = PopIdle0; /* Initialize the Perf DPC and Timer */ KeInitializeDpc(&Prcb->PowerState.PerfDpc, PopPerfIdleDpc, Prcb); KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->Number); KeInitializeTimerEx(&Prcb->PowerState.PerfTimer, SynchronizationTimer); }
VOID Ext2StartFloppyFlushDpc ( PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject ) { LARGE_INTEGER OneSecond; PEXT2_FLPFLUSH_CONTEXT Context; ASSERT(IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)); Context = Ext2AllocatePool( NonPagedPool, sizeof(EXT2_FLPFLUSH_CONTEXT), EXT2_FLPFLUSH_MAGIC ); if (!Context) { DEBUG(DL_ERR, ( "Ex2StartFloppy...: failed to allocate Context\n")); DbgBreak(); return; } KeInitializeTimer(&Context->Timer); KeInitializeDpc( &Context->Dpc, Ext2FloppyFlushDpc, Context ); ExInitializeWorkItem( &Context->Item, Ext2FloppyFlush, Context ); Context->Vcb = Vcb; Context->Fcb = Fcb; Context->FileObject = FileObject; if (FileObject) { ObReferenceObject(FileObject); } OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10; KeSetTimer( &Context->Timer, OneSecond, &Context->Dpc ); }
// Locks all other processors and returns exclusivity pointer. This function // should never be called before the last exclusivity is released. _Use_decl_annotations_ EXTERN_C void *ExclGainExclusivity() { NT_ASSERT(InterlockedAdd(&g_ExclpNumberOfLockedProcessors, 0) == 0); _InterlockedAnd(&g_ExclpReleaseAllProcessors, 0); const auto numberOfProcessors = KeQueryActiveProcessorCount(nullptr); // Allocates DPCs for all processors. auto context = reinterpret_cast<ExclusivityContext *>(ExAllocatePoolWithTag( NonPagedPoolNx, sizeof(void *) + (numberOfProcessors * sizeof(KDPC)), EXCLP_POOL_TAG)); if (!context) { return nullptr; } // Execute a lock DPC for all processors but this. context->OldIrql = KeRaiseIrqlToDpcLevel(); const auto currentCpu = KeGetCurrentProcessorNumber(); for (auto i = 0ul; i < numberOfProcessors; i++) { if (i == currentCpu) { continue; } // Queue a lock DPC. KeInitializeDpc(&context->Dpcs[i], ExclpRaiseIrqlAndWaitDpc, nullptr); KeSetTargetProcessorDpc(&context->Dpcs[i], static_cast<CCHAR>(i)); KeInsertQueueDpc(&context->Dpcs[i], nullptr, nullptr); } // Wait until all other processors were halted. const auto needToBeLocked = numberOfProcessors - 1; while (_InterlockedCompareExchange(&g_ExclpNumberOfLockedProcessors, needToBeLocked, needToBeLocked) != static_cast<LONG>(needToBeLocked)) { KeStallExecutionProcessor(10); } return context; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtDpcInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtDpcInit(DtDpc* pDpc, pDtDpcWorker pWorker, Bool QueueIfRunning) { DtStatus Result = DT_STATUS_OK; // Store settings pDpc->m_pWorker = pWorker; pDpc->m_QueueIfRunning = QueueIfRunning; pDpc->m_State = 0; #ifdef _DEBUG pDpc->m_SchedulingEnabled = TRUE; #endif // Initialize kernel DPC/tasklet #ifdef WINBUILD KeInitializeDpc(&pDpc->m_Kdpc, DtDpcWorker, pDpc); #else tasklet_init(&pDpc->m_Tasklet, DtDpcWorker, (unsigned long)pDpc); #endif return Result; }
RTDECL(int) RTMpPokeCpu(RTCPUID idCpu) { if (!RTMpIsCpuOnline(idCpu)) return !RTMpIsCpuPossible(idCpu) ? VERR_CPU_NOT_FOUND : VERR_CPU_OFFLINE; int rc = g_pfnrtSendIpi(idCpu); if (rc == VINF_SUCCESS) return rc; /* Fallback. */ if (!fPokeDPCsInitialized) { for (unsigned i = 0; i < RT_ELEMENTS(aPokeDpcs); i++) { KeInitializeDpc(&aPokeDpcs[i], rtMpNtPokeCpuDummy, NULL); KeSetImportanceDpc(&aPokeDpcs[i], HighImportance); KeSetTargetProcessorDpc(&aPokeDpcs[i], (int)i); } fPokeDPCsInitialized = true; } /* Raise the IRQL to DISPATCH_LEVEL so we can't be rescheduled to another cpu. * KeInsertQueueDpc must also be executed at IRQL >= DISPATCH_LEVEL. */ KIRQL oldIrql; KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); KeSetImportanceDpc(&aPokeDpcs[idCpu], HighImportance); KeSetTargetProcessorDpc(&aPokeDpcs[idCpu], (int)idCpu); /* Assuming here that high importance DPCs will be delivered immediately; or at least an IPI will be sent immediately. * @note: not true on at least Vista & Windows 7 */ BOOLEAN bRet = KeInsertQueueDpc(&aPokeDpcs[idCpu], 0, 0); KeLowerIrql(oldIrql); return (bRet == TRUE) ? VINF_SUCCESS : VERR_ACCESS_DENIED /* already queued */; }
VOID FFSStartFloppyFlushDpc( PFFS_VCB Vcb, PFFS_FCB Fcb, PFILE_OBJECT FileObject) { LARGE_INTEGER OneSecond; PFFS_FLPFLUSH_CONTEXT Context; ASSERT(IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)); Context = ExAllocatePool(NonPagedPool, sizeof(PFFS_FLPFLUSH_CONTEXT)); if (!Context) { FFSBreakPoint(); return; } KeInitializeTimer(&Context->Timer); KeInitializeDpc(&Context->Dpc, FFSFloppyFlushDpc, Context); Context->Vcb = Vcb; Context->Fcb = Fcb; Context->FileObject = FileObject; if (FileObject) { ObReferenceObject(FileObject); } OneSecond.QuadPart = (LONGLONG) - 1 * 1000 * 1000 * 10; KeSetTimer(&Context->Timer, OneSecond, &Context->Dpc); }
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT) ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), CONN_ENDPT_TAG); if (!Connection) return Connection; TI_DbgPrint(DEBUG_CPOINT, ("Connection point file object allocated at (0x%X).\n", Connection)); RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); /* Initialize spin lock that protects the connection endpoint file object */ KeInitializeSpinLock(&Connection->Lock); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); InitializeListHead(&Connection->SendRequest); InitializeListHead(&Connection->ShutdownRequest); InitializeListHead(&Connection->PacketQueue); /* Initialize disconnect timer */ KeInitializeTimer(&Connection->DisconnectTimer); KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection); /* Save client context pointer */ Connection->ClientContext = ClientContext; Connection->RefCount = 1; Connection->Free = ConnectionFree; /* Add connection endpoint to global list */ ExInterlockedInsertTailList(&ConnectionEndpointListHead, &Connection->ListEntry, &ConnectionEndpointListLock); return Connection; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvInitializeQueue // Sets up a driver managed IRP queue. // // Arguments: // IN Queue // An instance of our queue structure // // IN StartIoRoutine // Routine where queue IRPs are sent to be processed // // IN DeviceObject // Device object for our driver // // IN bUsetestdrvStartIoDpc // Flag to indicate that the queue should use queue a DPC for // calling StartIo if StartIo recursion is possible // // Return Value: // none // VOID testdrvInitializeQueue( IN PTESTDRV_QUEUE Queue, IN PTESTDRV_QUEUE_STARTIO StartIoRoutine, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN bUsetestdrvStartIoDpc ) { // must provide StartIo routine ASSERT(StartIoRoutine != NULL); // save off the user info Queue->StartIoRoutine = StartIoRoutine; Queue->DeviceObject = DeviceObject; Queue->bUsetestdrvStartIoDpc = bUsetestdrvStartIoDpc; // queues are created in a stalled state // Start device will unstall them Queue->StallCount = 1; // initialize our queue lock KeInitializeSpinLock(&Queue->QueueLock); // initialize our IRP list InitializeListHead(&Queue->IrpQueue); // initialize our testdrvStartIoDpc if (bUsetestdrvStartIoDpc) { KeInitializeDpc(&Queue->testdrvStartIoDpc, testdrvStartIoDpc, Queue); } // initialize stop event KeInitializeEvent(&Queue->StopEvent, NotificationEvent, FALSE); Queue->ErrorStatus = STATUS_SUCCESS; return; }