NTSTATUS Ext2QueueRequest (IN PEXT2_IRP_CONTEXT IrpContext) { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT))); /* set the flags of "can wait" and "queued" */ SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED); /* make sure the buffer is kept valid in system context */ Ext2LockIrp(IrpContext, IrpContext->Irp); /* initialize workite*/ ExInitializeWorkItem( &IrpContext->WorkQueueItem, Ext2DeQueueRequest, IrpContext ); /* dispatch it */ ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); return STATUS_PENDING; }
VOID CmpDoQueueLateUnloadWorker(IN PCMHIVE CmHive) { PWORK_QUEUE_ITEM WorkItem; CM_PAGED_CODE(); ASSERT( CmHive->RootKcb != NULL ); // // NB: Hive lock has higher precedence; We don't need the kcb lock as we are only checking the refcount // CmLockHive(CmHive); if( (CmHive->RootKcb->RefCount == 1) && (CmHive->UnloadWorkItem == NULL) ) { // // the only reference on the rookcb is the one that we artificially created // queue a work item to late unload the hive // WorkItem = ExAllocatePool(NonPagedPool, sizeof(WORK_QUEUE_ITEM)); if( InterlockedCompareExchangePointer(&(CmHive->UnloadWorkItem),WorkItem,NULL) == NULL ) { ExInitializeWorkItem(CmHive->UnloadWorkItem, CmpLateUnloadHiveWorker, CmHive); ExQueueWorkItem(CmHive->UnloadWorkItem, DelayedWorkQueue); } else { ExFreePool(WorkItem); } } CmUnlockHive(CmHive); }
VOID ExpCheckSystemInformation ( PVOID Context, PVOID InformationClass, PVOID Argument2 ) /*++ Routine Description: Callback function invoked when something in the system information may have changed. Arguments: Context - Where invoked from. InformationClass - which class for the given context was set (ignored for now) Argument2 Return Value: --*/ { ExQueueWorkItem (&ExpCheckSystemInfoWorkItem, DelayedWorkQueue); }
NTSTATUS DeviceArrivalCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { PHUB_DEVICE_EXTENSION DeviceExtension; LONG i; PWORKITEMDATA WorkItemData; DeviceExtension = (PHUB_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension; for (i=0; i < DeviceExtension->UsbExtHubInfo.NumberOfPorts; i++) DPRINT1("Port %x DeviceExtension->PortStatus %x\n",i+1, DeviceExtension->PortStatus[i]); IoFreeIrp(Irp); WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEMDATA)); if (!WorkItemData) { DPRINT1("Failed to allocate memory\n"); return STATUS_NO_MEMORY; } RtlZeroMemory(WorkItemData, sizeof(WORKITEMDATA)); WorkItemData->Context = Context; ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)WorkerThread, (PVOID)WorkItemData); ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue); return STATUS_MORE_PROCESSING_REQUIRED; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem( IN PKSWORKER Worker, IN PWORK_QUEUE_ITEM WorkItem) { PKSIWORKER KsWorker; KIRQL OldIrql; /* check for all parameters */ if (!Worker || !WorkItem) return STATUS_INVALID_PARAMETER; /* get ks worker implementation */ KsWorker = (PKSIWORKER)Worker; /* lock the work queue */ KeAcquireSpinLock(&KsWorker->Lock, &OldIrql); /* insert work item to list */ InsertTailList(&KsWorker->QueuedWorkItems, &WorkItem->List); /* increment active count */ InterlockedIncrement(&KsWorker->QueuedWorkItemCount); /* is this the first work item */ if (KsWorker->QueuedWorkItemCount == 1) { /* clear event */ KeClearEvent(&KsWorker->Event); /* it is, queue it */ ExQueueWorkItem(&KsWorker->WorkItem, KsWorker->Type); } /* release lock */ KeReleaseSpinLock(&KsWorker->Lock, OldIrql); return STATUS_SUCCESS; }
VOID NTAPI CcScheduleReadAhead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length) { PWORK_QUEUE_WITH_READ_AHEAD WorkItem; DPRINT("Schedule read ahead %08x%08x:%x %wZ\n", FileOffset->HighPart, FileOffset->LowPart, Length, &FileObject->FileName); WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem)); if (!WorkItem) KeBugCheck(0); ObReferenceObject(FileObject); WorkItem->FileObject = FileObject; WorkItem->FileOffset = *FileOffset; WorkItem->Length = Length; ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem); ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); DPRINT("Done\n"); }
VOID FFSQueueCloseRequest( IN PFFS_IRP_CONTEXT IrpContext) { PAGED_CODE(); ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == FFSICX) && (IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT))); if (!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE); IrpContext->Fcb = (PFFS_FCB)IrpContext->FileObject->FsContext; IrpContext->Ccb = (PFFS_CCB)IrpContext->FileObject->FsContext2; IrpContext->FileObject = NULL; } // IsSynchronous means we can block (so we don't requeue it) IrpContext->IsSynchronous = TRUE; ExInitializeWorkItem( &IrpContext->WorkQueueItem, FFSDeQueueCloseRequest, IrpContext); ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); }
VOID Ext2QueueCloseRequest (IN PEXT2_IRP_CONTEXT IrpContext) { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT))); if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) { if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FILE_BUSY)) { Ext2Sleep(500); /* 0.5 sec*/ } else { Ext2Sleep(50); /* 0.05 sec*/ } } else { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE); IrpContext->Fcb = (PEXT2_FCB) IrpContext->FileObject->FsContext; IrpContext->Ccb = (PEXT2_CCB) IrpContext->FileObject->FsContext2; } ExInitializeWorkItem( &IrpContext->WorkQueueItem, Ext2DeQueueCloseRequest, IrpContext); ExQueueWorkItem(&IrpContext->WorkQueueItem, DelayedWorkQueue); }
NTSTATUS FFSQueueRequest( IN PFFS_IRP_CONTEXT IrpContext) { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == FFSICX) && (IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT))); // IsSynchronous means we can block (so we don't requeue it) IrpContext->IsSynchronous = TRUE; SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED); IoMarkIrpPending(IrpContext->Irp); ExInitializeWorkItem( &IrpContext->WorkQueueItem, FFSDeQueueRequest, IrpContext); ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); return STATUS_PENDING; }
/* * @implemented */ VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry) { PERROR_LOG_ENTRY LogEntry; KIRQL Irql; /* Get the main header */ LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY)); /* Get time stamp */ KeQuerySystemTime(&LogEntry->TimeStamp); /* Acquire the lock and insert this write in the list */ KeAcquireSpinLock(&IopLogListLock, &Irql); InsertHeadList(&IopErrorLogListHead, &LogEntry->ListEntry); /* Check if the worker is running */ if (!IopLogWorkerRunning) { #if 0 /* It's not, initialize it and queue it */ ExInitializeWorkItem(&IopErrorLogWorkItem, IopLogWorker, &IopErrorLogWorkItem); ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue); IopLogWorkerRunning = TRUE; #endif } /* Release the lock and return */ KeReleaseSpinLock(&IopLogListLock, Irql); }
BOOLEAN CmpClaimGlobalQuota( IN ULONG Size ) /*++ Routine Description: If CmpGlobalQuotaUsed + Size >= CmpGlobalQuotaAllowed, return false. Otherwise, increment CmpGlobalQuotaUsed, in effect claiming the requested GlobalQuota. Arguments: Size - number of bytes of GlobalQuota caller wants to claim Return Value: TRUE - Claim succeeded, and has been counted in Used GQ FALSE - Claim failed, nothing counted in GQ. --*/ { LONG available; PWORK_QUEUE_ITEM WorkItem; // // compute available space, then see if size <. This prevents overflows. // Note that this must be signed. Since quota is not enforced until logon, // it is possible for the available bytes to be negative. // available = (LONG)CmpGlobalQuotaAllowed - (LONG)CmpGlobalQuotaUsed; if ((LONG)Size < available) { CmpGlobalQuotaUsed += Size; if ((CmpGlobalQuotaUsed > CmpGlobalQuotaWarning) && (!CmpQuotaWarningPopupDisplayed) && (ExReadyForErrors)) { // // Queue work item to display popup // WorkItem = ExAllocatePool(NonPagedPool, sizeof(WORK_QUEUE_ITEM)); if (WorkItem != NULL) { CmpQuotaWarningPopupDisplayed = TRUE; ExInitializeWorkItem(WorkItem, CmpQuotaWarningWorker, WorkItem); ExQueueWorkItem(WorkItem, DelayedWorkQueue); } } return TRUE; } else { return FALSE; } }
/* * @implemented */ VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName) { KIRQL OldIrql; PONLINE_NOTIFICATION_WORK_ITEM WorkItem; /* Allocate a notification work item */ WorkItem = AllocatePool(sizeof(ONLINE_NOTIFICATION_WORK_ITEM)); if (!WorkItem) { return; } WorkItem->List.Flink = NULL; WorkItem->DeviceExtension = DeviceExtension; WorkItem->WorkerRoutine = SendOnlineNotificationWorker; WorkItem->Parameter = WorkItem; WorkItem->SymbolicName.Length = SymbolicName->Length; WorkItem->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(WCHAR); WorkItem->SymbolicName.Buffer = AllocatePool(WorkItem->SymbolicName.MaximumLength); if (!WorkItem->SymbolicName.Buffer) { FreePool(WorkItem); return; } RtlCopyMemory(WorkItem->SymbolicName.Buffer, SymbolicName->Buffer, SymbolicName->Length); WorkItem->SymbolicName.Buffer[SymbolicName->Length / sizeof(WCHAR)] = UNICODE_NULL; KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql); DeviceExtension->OnlineNotificationCount++; /* If no worker are active */ if (DeviceExtension->OnlineNotificationWorkerActive == 0) { /* Queue that one for execution */ DeviceExtension->OnlineNotificationWorkerActive = 1; ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); } else { /* Otherwise, just put it in the queue list */ InsertTailList(&(DeviceExtension->OnlineNotificationListHead), &(WorkItem->List)); } KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql); return; }
VOID NTAPI CmpLazyFlushDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { /* Check if we should queue the lazy flush worker */ if ((!CmpLazyFlushPending) && (!CmpHoldLazyFlush)) { CmpLazyFlushPending = TRUE; ExQueueWorkItem(&CmpLazyWorkItem, DelayedWorkQueue); } }
VOID NTAPI IopLogDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { /* If we have a DPC, free it */ if (Dpc) ExFreePool(Dpc); /* Initialize and queue the work item */ ExInitializeWorkItem(&IopErrorLogWorkItem, IopLogWorker, NULL); ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue); }
VOID NTAPI CmpLazyFlushDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { /* Check if we should queue the lazy flush worker */ DPRINT("Flush pending: %s, Holding lazy flush: %s.\n", CmpLazyFlushPending ? "yes" : "no", CmpHoldLazyFlush ? "yes" : "no"); if ((!CmpLazyFlushPending) && (!CmpHoldLazyFlush)) { CmpLazyFlushPending = TRUE; ExQueueWorkItem(&CmpLazyWorkItem, DelayedWorkQueue); } }
VOID Ext2FloppyFlushDpc ( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) { PEXT2_FLPFLUSH_CONTEXT Context; Context = (PEXT2_FLPFLUSH_CONTEXT) DeferredContext; DEBUG(DL_FLP, ("Ext2FloppyFlushDpc is to be started...\n")); ExQueueWorkItem(&Context->Item, CriticalWorkQueue); }
NOT PAGEABLE -- MsReadTimeoutHandler #endif VOID MsReadTimeoutHandler ( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) /*++ Routine Description: This routine is handles read timeouts. It is called as a DPC whenever a read timer expires. *** Non-Pageable *** Arguments: Dpc - A pointer to the DPC object. DeferredContext - A pointer to the data queue entry associated with this timer. SystemArgument1, SystemArgument2 - Unused. Return Value: None. --*/ { PWORK_CONTEXT workContext; Dpc, SystemArgument1, SystemArgument2; // prevent warnings // // Enqueue this packet to an ex worker thread. // workContext = DeferredContext; ExQueueWorkItem( &workContext->WorkItem, CriticalWorkQueue ); }
/* * @implemented */ VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter) { KIRQL OldIrql; PLIST_ENTRY Head; PDEVICE_EXTENSION DeviceExtension; PONLINE_NOTIFICATION_WORK_ITEM WorkItem; PONLINE_NOTIFICATION_WORK_ITEM NewWorkItem; WorkItem = (PONLINE_NOTIFICATION_WORK_ITEM)Parameter; DeviceExtension = WorkItem->DeviceExtension; /* First, send the notification */ SendOnlineNotification(&(WorkItem->SymbolicName)); KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql); /* If there are no notifications running any longer, reset event */ if (--DeviceExtension->OnlineNotificationCount == 0) { KeSetEvent(&(DeviceExtension->OnlineNotificationEvent), 0, FALSE); } /* If there are still notifications in queue */ if (!IsListEmpty(&(DeviceExtension->OnlineNotificationListHead))) { /* Queue a new one for execution */ Head = RemoveHeadList(&(DeviceExtension->OnlineNotificationListHead)); NewWorkItem = CONTAINING_RECORD(Head, ONLINE_NOTIFICATION_WORK_ITEM, List); KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql); NewWorkItem->List.Blink = NULL; NewWorkItem->List.Flink = NULL; ExQueueWorkItem((PWORK_QUEUE_ITEM)NewWorkItem, DelayedWorkQueue); } else { /* Mark it's over */ DeviceExtension->OnlineNotificationWorkerActive = 0; KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql); } FreePool(WorkItem->SymbolicName.Buffer); FreePool(WorkItem); return; }
VOID CmpRaiseSelfHealWarningWorker( IN PVOID Arg ) { PVOID ErrorParameters; ULONG ErrorResponse; PCM_SELF_HEAL_WORK_ITEM_PARAMETER Param; Param = (PCM_SELF_HEAL_WORK_ITEM_PARAMETER)Arg; ErrorParameters = &(Param->HiveName); ExRaiseHardError( STATUS_REGISTRY_HIVE_RECOVERED, 1, 1, (PULONG_PTR)&ErrorParameters, OptionOk, &ErrorResponse ); // // free what we have allocated // ExFreePool(Param->WorkItem); ExFreePool(Param); // // see if there are other self heal warnings to be posted. // LOCK_SELF_HEAL_QUEUE(); CmpSelfHealWorkerActive = FALSE; if( IsListEmpty(&CmpSelfHealQueueListHead) == FALSE ) { // // remove head and queue it. // Param = (PCM_SELF_HEAL_WORK_ITEM_PARAMETER)RemoveHeadList(&CmpSelfHealQueueListHead); Param = CONTAINING_RECORD( Param, CM_SELF_HEAL_WORK_ITEM_PARAMETER, SelfHealQueueListEntry ); ExQueueWorkItem(Param->WorkItem, DelayedWorkQueue); CmpSelfHealWorkerActive = TRUE; } UNLOCK_SELF_HEAL_QUEUE(); }
NTSTATUS dc_probe_mount(dev_hook *hook, PIRP irp) { mount_ctx *mnt; if ( (mnt = mm_pool_alloc(sizeof(mount_ctx))) == NULL ) { return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES); } IoMarkIrpPending(irp); mnt->irp = irp; mnt->hook = hook; ExInitializeWorkItem(&mnt->wrk_item, mount_item_proc, mnt); ExQueueWorkItem(&mnt->wrk_item, DelayedWorkQueue); return STATUS_PENDING; }
VOID IopErrorLogDpc( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) /*++ Routine Description: This routine queues a work request to the worker thread to process logged errors. It is called by a timer DPC when the error log port cannot be connected. The DPC structure itself is freed by this routine. Arguments: Dpc - Supplies a pointer to the DPC structure. This structure is freed by this routine. DeferredContext - Unused. SystemArgument1 - Unused. SystemArgument2 - Unused. Return Value: None --*/ { // // Free the DPC structure if there is one. // if (Dpc != NULL) { ExFreePool(Dpc); } ExInitializeWorkItem( &IopErrorLogWorkItem, IopErrorLogThread, NULL ); ExQueueWorkItem( &IopErrorLogWorkItem, DelayedWorkQueue ); }
NTSTATUS USBSTOR_QueueWorkItem( PIRP_CONTEXT Context, PIRP Irp) { PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData; // // Allocate Work Item Data // ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG); if (!ErrorHandlerWorkItemData) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // error handling started // Context->FDODeviceExtension->SrbErrorHandlingActive = TRUE; // // srb error handling finished // Context->FDODeviceExtension->TimerWorkQueueEnabled = FALSE; // // Initialize and queue the work item to handle the error // ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, ErrorHandlerWorkItemRoutine, ErrorHandlerWorkItemData); ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject; ErrorHandlerWorkItemData->Context = Context; ErrorHandlerWorkItemData->Irp = Irp; ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject; DPRINT1("Queuing WorkItemROutine\n"); ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue); return STATUS_MORE_PROCESSING_REQUIRED; }
VOID NTAPI FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext, IN PFAT_OPERATION_HANDLER OperationHandler) { /* Save the worker routine. */ IrpContext->QueuedOperationHandler = OperationHandler; /* Indicate if top level IRP was set. */ if (IoGetTopLevelIrp() == IrpContext->Irp) SetFlag(IrpContext->Flags, IRPCONTEXT_TOPLEVEL); /* Initialize work item. */ ExInitializeWorkItem(&IrpContext->WorkQueueItem, FatDequeueRequest, IrpContext); ExQueueWorkItem(&IrpContext->WorkQueueItem, DelayedWorkQueue); }
void dc_unmount_async(dev_hook *hook) { mount_ctx *mnt; DbgMsg("dc_unmount_async at IRQL %d\n", KeGetCurrentIrql()); if (mnt = mm_pool_alloc(sizeof(mount_ctx))) { mnt->hook = hook; dc_reference_hook(hook); if (KeGetCurrentIrql() != PASSIVE_LEVEL) { ExInitializeWorkItem(&mnt->wrk_item, unmount_item_proc, mnt); ExQueueWorkItem(&mnt->wrk_item, DelayedWorkQueue); } else { unmount_item_proc(mnt); } } }
VOID FFSFloppyFlushDpc( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PFFS_FLPFLUSH_CONTEXT Context; Context = (PFFS_FLPFLUSH_CONTEXT)DeferredContext; FFSPrint((DBG_USER, "FFSFloppyFlushDpc is to be started...\n")); ExInitializeWorkItem(&Context->Item, FFSFloppyFlush, Context); ExQueueWorkItem(&Context->Item, CriticalWorkQueue); }
/* * @implemented */ VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context) { /* Make sure we're called at DISPATCH or lower */ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Reference the device object */ ObReferenceObject(IoWorkItem->DeviceObject); /* Setup the work item */ IoWorkItem->WorkerRoutine = WorkerRoutine; IoWorkItem->Context = Context; /* Queue the work item */ ExQueueWorkItem(&IoWorkItem->Item, QueueType); }
VOID APCInjectRoutine(PKAPC pkaApc, PKNORMAL_ROUTINE*, PVOID*, PVOID*, PVOID*) { WI_INJECT wiiItem; ExFreePool(pkaApc); wiiItem.pktThread = KeGetCurrentThread(); wiiItem.pepProcess = IoGetCurrentProcess(); wiiItem.hProcessID = PsGetCurrentProcessId(); KeInitializeEvent(&wiiItem.keEvent, NotificationEvent, FALSE); ExInitializeWorkItem(&wiiItem.qiItem, InjectorWorkItem, &wiiItem); ExQueueWorkItem(&wiiItem.qiItem, DelayedWorkQueue); //was KernelMode not work do UserMode and work KeWaitForSingleObject(&wiiItem.keEvent, Executive, UserMode, TRUE, 0); return; }
VOID CmpDelayCloseDpcRoutine( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) /*++ Routine Description: This is the DPC routine triggered by the delayclose timer. is queue a work item to an executive worker thread. Arguments: Dpc - Supplies a pointer to the DPC object. DeferredContext - not used SystemArgument1 - not used SystemArgument2 - not used Return Value: None. --*/ { UNREFERENCED_PARAMETER (Dpc); UNREFERENCED_PARAMETER (DeferredContext); UNREFERENCED_PARAMETER (SystemArgument1); UNREFERENCED_PARAMETER (SystemArgument2); ASSERT(CmpDelayCloseWorkItemActive); ExQueueWorkItem(&CmpDelayCloseWorkItem, DelayedWorkQueue); }
VOID CcPostWorkQueue( IN PWORK_QUEUE_ENTRY WorkItem, IN PLIST_ENTRY WorkQueue) { KIRQL OldIrql; PWORK_QUEUE_ITEM ThreadToSpawn; /* First of all, insert the item in the queue */ OldIrql = KeAcquireQueuedSpinLock(LockQueueWorkQueueLock); InsertTailList(WorkQueue, &WorkItem->WorkQueueLinks); /* Now, define whether we have to spawn a new work thread * We will spawn a new one if: * - There's no throttle in action * - There's still at least one idle thread */ ThreadToSpawn = NULL; if (!CcQueueThrottle && !IsListEmpty(&CcIdleWorkerThreadList)) { PLIST_ENTRY ListEntry; /* Get the idle thread */ ListEntry = RemoveHeadList(&CcIdleWorkerThreadList); ThreadToSpawn = CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List); /* We're going to have one more! */ CcNumberActiveWorkerThreads += 1; } KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql); /* If we have a thread to spawn, do it! */ if (ThreadToSpawn != NULL) { /* We NULLify it to be consistent with initialization */ ThreadToSpawn->List.Flink = NULL; ExQueueWorkItem(ThreadToSpawn, CriticalWorkQueue); } }
NTSTATUS dc_power_irp(dev_hook *hook, PIRP irp) { pw_irp_ctx *pwc; if (KeGetCurrentIrql() == PASSIVE_LEVEL) { return dc_process_power_irp(hook, irp); } if ( (pwc = mm_alloc(sizeof(pw_irp_ctx), 0)) == NULL ) { PoStartNextPowerIrp(irp); return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES); } pwc->hook = hook; pwc->irp = irp; IoMarkIrpPending(irp); ExInitializeWorkItem(&pwc->wrk_item, dc_power_irp_worker, pwc); ExQueueWorkItem(&pwc->wrk_item, DelayedWorkQueue); return STATUS_PENDING; }