void cp_parallelized_crypt( int is_encrypt, xts_key *key, fc_callback on_complete, void *param, const unsigned char *in, unsigned char *out, u32 len, u64 offset) { req_item *item; req_part *part; u32 part_sz; u32 part_of; if ( (len < F_OP_THRESOLD) || ((item = ExAllocateFromNPagedLookasideList(&pool_req_mem)) == NULL) ) { if (is_encrypt != 0) { xts_encrypt(in, out, len, offset, key); } else { xts_decrypt(in, out, len, offset, key); } on_complete(param); return; } item->is_encrypt = is_encrypt; item->length = len; item->in = in; item->out = out; item->offset = offset; item->on_complete = on_complete; item->param = param; item->key = key; part_sz = _align(len / dc_cpu_count, F_MIN_REQ); part_of = 0; part = &item->parts[0]; do { part_sz = min(part_sz, len); part->item = item; part->offset = part_of; part->length = part_sz; InterlockedPushEntrySList(&pool_head, &part->entry); part_of += part_sz; len -= part_sz; part++; } while (len != 0); KeSetEvent(&pool_signal_event, IO_NO_INCREMENT, FALSE); }
/*++ * @name ExQueueWorkItem * @implemented NT4 * * The ExQueueWorkItem routine acquires rundown protection for * the specified descriptor. * * @param WorkItem * Pointer to an initialized Work Queue Item structure. This structure * must be located in nonpaged pool memory. * * @param QueueType * Type of the queue to use for this item. Can be one of the following: * - DelayedWorkQueue * - CriticalWorkQueue * - HyperCriticalWorkQueue * * @return None. * * @remarks This routine is obsolete. Use IoQueueWorkItem instead. * * Callers of this routine must be running at IRQL <= DISPATCH_LEVEL. * *--*/ VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType) { PEX_WORK_QUEUE WorkQueue = &ExWorkerQueue[QueueType]; ASSERT(QueueType < MaximumWorkQueue); ASSERT(WorkItem->List.Flink == NULL); /* Don't try to trick us */ if ((ULONG_PTR)WorkItem->WorkerRoutine < MmUserProbeAddress) { /* Bugcheck the system */ KeBugCheckEx(WORKER_INVALID, 1, (ULONG_PTR)WorkItem, (ULONG_PTR)WorkItem->WorkerRoutine, 0); } /* Insert the Queue */ KeInsertQueue(&WorkQueue->WorkerQueue, &WorkItem->List); ASSERT(!WorkQueue->Info.QueueDisabled); /* * Check if we need a new thread. Our decision is as follows: * - This queue type must support Dynamic Threads (duh!) * - It actually has to have unprocessed items * - We have CPUs which could be handling another thread * - We haven't abused our usage of dynamic threads. */ if ((WorkQueue->Info.MakeThreadsAsNecessary) && (!IsListEmpty(&WorkQueue->WorkerQueue.EntryListHead)) && (WorkQueue->WorkerQueue.CurrentCount < WorkQueue->WorkerQueue.MaximumCount) && (WorkQueue->DynamicThreadCount < 16)) { /* Let the balance manager know about it */ DPRINT1("Requesting a new thread. CurrentCount: %lu. MaxCount: %lu\n", WorkQueue->WorkerQueue.CurrentCount, WorkQueue->WorkerQueue.MaximumCount); KeSetEvent(&ExpThreadSetManagerEvent, 0, FALSE); } }
//保证每一次操作完成。 PDEVICE_OBJECT FileDiskDeleteDevice ( IN PDEVICE_OBJECT DeviceObject ) { PDEVICE_EXTENSION device_extension; PDEVICE_OBJECT next_device_object; PAGED_CODE(); ASSERT(DeviceObject != NULL); device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; device_extension->terminate_thread = TRUE; KeSetEvent( &device_extension->request_event, (KPRIORITY) 0, FALSE ); KeWaitForSingleObject( device_extension->thread_pointer, Executive, KernelMode, FALSE, NULL ); ObDereferenceObject(device_extension->thread_pointer); if (device_extension->security_client_context != NULL) { SeDeleteClientSecurity(device_extension->security_client_context); ExFreePool(device_extension->security_client_context); } next_device_object = DeviceObject->NextDevice; IoDeleteDevice(DeviceObject); return next_device_object; }
VOID FileDiskCleanupLogicalUnit( __in PNDAS_LOGICALUNIT_EXTENSION LogicalUnitExtension) { PFILEDISK_EXTENSION fileDiskExtension; PAGED_CODE(); fileDiskExtension = FileDiskGetExtension(LogicalUnitExtension); ASSERT(NULL != fileDiskExtension); ASSERT(NULL == fileDiskExtension->CurrentSrb); fileDiskExtension->ThreadShouldStop = TRUE; KeSetEvent( &fileDiskExtension->ThreadNotificationEvent, IO_NO_INCREMENT, FALSE); KeWaitForSingleObject( &fileDiskExtension->ThreadCompleteEvent, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(fileDiskExtension->ThreadObject); ZwClose(fileDiskExtension->ThreadHandle); fileDiskExtension->ThreadObject = NULL; fileDiskExtension->ThreadHandle = NULL; FileDiskCloseDataFile(fileDiskExtension); ExFreePoolWithTag( fileDiskExtension->FilePath.Buffer, FILEDISK_EXT_TAG); fileDiskExtension->FilePath.Buffer = NULL; fileDiskExtension->FilePath.Length = 0; fileDiskExtension->FilePath.MaximumLength = 0; }
static NTSTATUS V2vkListenerProcessInternalSyncTx(V2VK_LISTENER_CONTEXT *vlc) { NTSTATUS status; unsigned available; volatile UCHAR *msg; V2V_LISTENER_RESP_ITEM *vlri; DbgPrint("%s listener(%p) sending internal response #%d\n", V2VDRV_LOGTAG, vlc, vlc->txCounter + 1); available = v2v_nc2_producer_bytes_available(vlc->channel); DbgPrint("%s listener(%p) channel indicates minimum bytes available: 0x%x\n", V2VDRV_LOGTAG, vlc, available); ASSERT(vlc->u.xferInternal.respList); /* No resizing fixed responses for fastrx */ status = v2v_nc2_prep_message(vlc->channel, sizeof(V2V_RESP_INTERNAL), V2V_MESSAGE_TYPE_INTERNAL, 0, &msg); if (!NT_SUCCESS(status)) { if (status == STATUS_RETRY) { /* No room right now, return and try again later */ DbgPrint("%s listener(%p) not enough buffer space to send response #%d; retry\n", V2VDRV_LOGTAG, vlc, vlc->txCounter + 1); return STATUS_RETRY; } DbgPrint("%s listener(%p) transmit internal response failure; abort processing - error: 0x%x\n", V2VDRV_LOGTAG, vlc, status); return status; /* failure */ } vlc->txCounter++; /* next message */ vlri = vlc->u.xferInternal.respList; vlc->u.xferInternal.respList = vlri->next; if (!vlc->u.xferInternal.respList) vlc->u.xferInternal.respTail = NULL; /* Response already formed, just copy it in */ RtlCopyMemory((void*)msg, vlri, sizeof(V2V_RESP_INTERNAL)); ExFreePoolWithTag(vlri, V2VDRV_TAG); v2v_nc2_send_messages(vlc->channel); /* Keep the send loop going by setting the event. If there is no more room, the prep message call will return ERROR_RETRY and just land us back in the wait. */ KeSetEvent(v2v_get_send_event(vlc->channel), IO_NO_INCREMENT, FALSE); return STATUS_SUCCESS; }
VOID NTAPI ChewWorkItem(PDEVICE_OBJECT DeviceObject, PVOID ChewItem) { PWORK_ITEM WorkItem = ChewItem; KIRQL OldIrql; WorkItem->Worker(WorkItem->WorkerContext); IoFreeWorkItem(WorkItem->WorkItem); KeAcquireSpinLock(&WorkQueueLock, &OldIrql); RemoveEntryList(&WorkItem->Entry); if (IsListEmpty(&WorkQueue)) KeSetEvent(&WorkQueueClear, 0, FALSE); KeReleaseSpinLock(&WorkQueueLock, OldIrql); ExFreePoolWithTag(WorkItem, CHEW_TAG); }
// Set the event void NeoSet(NEO_EVENT *event) { // Validate arguments if (event == NULL) { return; } #ifndef WIN9X KeSetEvent(event->event, 0, FALSE); #else // WIN9X if (event->win32_event != 0) { DWORD h = event->win32_event; _asm mov eax, h; VxDCall(_VWIN32_SetWin32Event); } #endif // WIN9X }
NTSTATUS DF_DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDF_DEVICE_EXTENSION DevExt; DevExt = (PDF_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (DevExt->bIsProtected == TRUE) { IoMarkIrpPending(Irp); // Queue this IRP ExInterlockedInsertTailList(&DevExt->RwList, &Irp->Tail.Overlay.ListEntry, &DevExt->RwListSpinLock); // Set Event KeSetEvent(&DevExt->RwThreadStartEvent, IO_NO_INCREMENT, FALSE); return STATUS_PENDING; } IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->LowerDeviceObject, Irp); }
RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem) { /* * Validate input. */ PRTSEMEVENTINTERNAL pThis = hEventSem; if (pThis == NIL_RTSEMEVENT) return VINF_SUCCESS; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); /* * Invalidate it and signal the object just in case. */ ASMAtomicIncU32(&pThis->u32Magic); KeSetEvent(&pThis->Event, 0xfff, FALSE); rtR0SemEventNtRelease(pThis); return VINF_SUCCESS; }
VOID DokanStopEventNotificationThreadInternal(__in PDEVICE_OBJECT DeviceObject, __in PVOID Context) { PDokanDCB Dcb; UNREFERENCED_PARAMETER(Context); DDbgPrint("==> DokanStopEventNotificationThreadInternal\n"); Dcb = DeviceObject->DeviceExtension; if (KeSetEvent(&Dcb->ReleaseEvent, 0, FALSE) > 0 && Dcb->EventNotificationThread) { KeWaitForSingleObject(Dcb->EventNotificationThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(Dcb->EventNotificationThread); Dcb->EventNotificationThread = NULL; } DDbgPrint("<== DokanStopEventNotificationThreadInternal\n"); }
VOID NPF_UnbindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext ) { POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext; TRACE_ENTER(); ASSERT(Open != NULL); // // The following code has been disabled bcause the kernel dump feature has been disabled. // //// //// Awake a possible pending read on this instance //// TODO should be ok. //// // if(Open->mode & MODE_DUMP) // NdisSetEvent(&Open->DumpEvent); // else if (Open->ReadEvent != NULL) KeSetEvent(Open->ReadEvent,0,FALSE); // // The following code has been disabled bcause the kernel dump feature has been disabled. // //// //// If this instance is in dump mode, complete the dump and close the file //// TODO needs to be checked again. //// // if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) // NPF_CloseDumpFile(Open); *Status = NDIS_STATUS_SUCCESS; NPF_CloseBinding(Open); TRACE_EXIT(); return; }
/* * Remove the current PnP event from the tail of the event queue * and signal IopPnpNotifyEvent if there is yet another event in the queue. */ static NTSTATUS IopRemovePlugPlayEvent(VOID) { /* Remove a pnp event entry from the tail of the queue */ if (!IsListEmpty(&IopPnpEventQueueHead)) { ExFreePool(CONTAINING_RECORD(RemoveTailList(&IopPnpEventQueueHead), PNP_EVENT_ENTRY, ListEntry)); } /* Signal the next pnp event in the queue */ if (!IsListEmpty(&IopPnpEventQueueHead)) { KeSetEvent(&IopPnpNotifyEvent, 0, FALSE); } return STATUS_SUCCESS; }
VOID ReadonlyDismountVolumeThreadProc ( IN PREADONLY Readonly ) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyDismountVolumeThreadProc: Start Readonly = %p\n", Readonly) ); Readonly_Reference( Readonly ); KeSetEvent( &Readonly->DiskmountReadyEvent, IO_DISK_INCREMENT, FALSE ); ReadonlyDismountVolume( Readonly->LfsDeviceExt ); Readonly->DismountThreadHandle = NULL; Readonly_Dereference( Readonly ); PsTerminateSystemThread( STATUS_SUCCESS ); }
NTSTATUS FilterStartCompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++ Routine Description: A completion routine for use when calling the lower device objects to which our filter deviceobject is attached. Arguments: DeviceObject - Pointer to deviceobject Irp - Pointer to a PnP Irp. Context - NULL Return Value: NT Status is returned. --*/ { PKEVENT event = (PKEVENT)Context; UNREFERENCED_PARAMETER (DeviceObject); // // If the lower driver didn't return STATUS_PENDING, we don't need to // set the event because we won't be waiting on it. // This optimization avoids grabbing the dispatcher lock, and improves perf. // if (Irp->PendingReturned == TRUE) { KeSetEvent (event, IO_NO_INCREMENT, FALSE); } // // The dispatch routine will have to call IoCompleteRequest // return STATUS_MORE_PROCESSING_REQUIRED; }
static void ReleasePoolBuffer (EncryptedIoQueue *queue, void *address) { EncryptedIoQueueBuffer *buffer; AcquireBufferPoolMutex (queue); for (buffer = queue->FirstPoolBuffer; buffer != NULL; buffer = buffer->NextBuffer) { if (buffer->Address == address) { ASSERT (buffer->InUse); buffer->InUse = FALSE; break; } } ReleaseBufferPoolMutex (queue); KeSetEvent (&queue->PoolBufferFreeEvent, IO_DISK_INCREMENT, FALSE); }
VOID ImScsiFreeGlobalResources() { KdPrint(("PhDskMnt::ImScsiFreeGlobalResources: Unloading.\n")); if (pMPDrvInfoGlobal != NULL) { KdPrint(("PhDskMnt::ImScsiFreeGlobalResources: Ready to stop worker threads and free global data.\n")); if ((pMPDrvInfoGlobal->GlobalsInitialized) && (pMPDrvInfoGlobal->WorkerThread != NULL)) { KdPrint(("PhDskMnt::ImScsiFreeGlobalResources: Waiting for global worker thread %p.\n", pMPDrvInfoGlobal->WorkerThread)); #pragma warning(suppress: 28160) KeSetEvent(&pMPDrvInfoGlobal->StopWorker, (KPRIORITY)0, TRUE); KeWaitForSingleObject( pMPDrvInfoGlobal->WorkerThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pMPDrvInfoGlobal->WorkerThread); pMPDrvInfoGlobal->WorkerThread = NULL; } #ifdef USE_SCSIPORT if (pMPDrvInfoGlobal->ControllerObject != NULL) { ObDereferenceObject(pMPDrvInfoGlobal->ControllerObject); pMPDrvInfoGlobal->ControllerObject = NULL; } #endif #ifndef MP_DrvInfo_Inline ExFreePoolWithTag(pMPDrvInfoGlobal, MP_TAG_GENERAL); #endif } }
/************************************************************************* * * Function: Ext2MultiSyncCompletionRoutine() * * Description: * Synchronous I/O Completion Routine * * Expected Interrupt Level (for execution) : * * ? * * Return Value: NTSTATUS - STATUS_SUCCESS(always) * *************************************************************************/ NTSTATUS NTAPI Ext2MultiSyncCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt ) { PEXT2_IO_CONTEXT PtrContext = Contxt; ASSERT( PtrContext ); if( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } if (!NT_SUCCESS( Irp->IoStatus.Status )) { PtrContext->PtrMasterIrp->IoStatus.Status = Irp->IoStatus.Status; } if (InterlockedDecrement( &PtrContext->Count ) == 0) { if ( NT_SUCCESS( PtrContext->PtrMasterIrp->IoStatus.Status ) ) { PtrContext->PtrMasterIrp->IoStatus.Information = PtrContext->ReadWriteLength; } else { PtrContext->PtrMasterIrp->IoStatus.Information = 0; } KeSetEvent( PtrContext->PtrSyncEvent, 0, FALSE ); DebugTrace( DEBUG_TRACE_FREE, "Freeing = %lX [io]", PtrContext ); ExFreePool( PtrContext ); } // // The master Irp will be automatically completed // when all the associated IRPs are completed // return STATUS_SUCCESS; }
BOOLEAN NetEvtTerminate(PNETEVTCTX NetEvtCtx) { VOID *ThreadObject ; LARGE_INTEGER TimeOut ; NTSTATUS ntStatus ; ASSERT(KeGetCurrentIrql() <= PASSIVE_LEVEL) ; KeSetEvent(&NetEvtCtx->ShutdownEvent, IO_NO_INCREMENT, FALSE) ; ntStatus = ObReferenceObjectByHandle( NetEvtCtx->HThread, FILE_READ_DATA, NULL, KernelMode, &ThreadObject, NULL ) ; if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEvtTerminate: referencing to the thread object failed\n")) ; goto out ; } TimeOut.QuadPart = - 20 * 10000 ; // 20 sec ntStatus = KeWaitForSingleObject( ThreadObject, Executive, KernelMode, FALSE, &TimeOut ) ; if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEvtTerminate: waiting for the thread failed\n")) ; } ObDereferenceObject(ThreadObject) ; SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEvtTerminate: Shut down successfully.\n")) ; out: return TRUE ; }
VOID FileDiskCreateThreadWorkItemRoutine( __in PDEVICE_OBJECT DeviceObject, __in PVOID Context) { PFILEDISK_EXTENSION fileDiskExtension; OBJECT_ATTRIBUTES threadAttributes; InitializeObjectAttributes( &threadAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); fileDiskExtension = (PFILEDISK_EXTENSION) Context; fileDiskExtension->ThreadStatus = PsCreateSystemThread( &fileDiskExtension->ThreadHandle, 0, &threadAttributes, NULL, NULL, FileDiskThreadRoutine, fileDiskExtension); if (NT_SUCCESS(fileDiskExtension->ThreadStatus)) { ObReferenceObjectByHandle( fileDiskExtension->ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&fileDiskExtension->ThreadObject, NULL); } KeSetEvent( &fileDiskExtension->ThreadCompleteEvent, IO_NO_INCREMENT, FALSE); }
VOID VolDo_Dereference ( IN PVOLUME_DEVICE_OBJECT VolDo ) { LONG result; result = InterlockedDecrement( &VolDo->ReferenceCount ); ASSERT( result >= 0 ); //DbgPrint("voldo->Reference = %d\n", VolDo->ReferenceCount); if (result == 0) { //DebugTrace2( 0, SPYDEBUG_DISPLAY_ATTACHMENT_NAMES, // ("******** FilterDriver_Dereference: System Freed *******\n") ); KeSetEvent( &VolDo->ReferenceZeroEvent, IO_DISK_INCREMENT, FALSE ); } }
NTSTATUS XixFsdPnpCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt ) { PKEVENT Event = (PKEVENT) Contxt; DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT), ("Enter XixFsdPnpCompletionRoutine \n")); KeSetEvent( Event, 0, FALSE ); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT), ("Exit XixFsdPnpCompletionRoutine \n")); return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS FPFilterIrpCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PKEVENT Event = (PKEVENT) Context; if (Irp->PendingReturned) IoMarkIrpPending(Irp); UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp); KeSetEvent(Event, IO_NO_INCREMENT, FALSE); return(STATUS_MORE_PROCESSING_REQUIRED); }
/************************************************************************* * * Function: Ext2SingleSyncCompletionRoutine() * * Description: * Synchronous I/O Completion Routine * * Expected Interrupt Level (for execution) : * * ? * * Return Value: NTSTATUS - STATUS_SUCCESS(always) * *************************************************************************/ NTSTATUS NTAPI Ext2SingleSyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt ) { PEXT2_IO_CONTEXT PtrContext = Contxt; if( Irp->PendingReturned ) IoMarkIrpPending( Irp ); ASSERT( PtrContext ); ASSERT( PtrContext->NodeIdentifier.NodeType == EXT2_NODE_TYPE_IO_CONTEXT ); KeSetEvent( PtrContext->PtrSyncEvent, 0, FALSE ); DebugTrace( DEBUG_TRACE_FREE, "Freeing = %lX [io]", PtrContext ); ExFreePool( PtrContext ); return STATUS_SUCCESS; }
NTSTATUS SyncCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: If the Irp is one we allocated ourself, DeviceObject is NULL. --*/ { PKEVENT kevent = (PKEVENT)Context; KeSetEvent(kevent, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; }
static NTSTATUS NTAPI CompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT CompletionEvent ) { ASSERT(CompletionEvent); UNREFERENCED_PARAMETER(Irp); UNREFERENCED_PARAMETER(DeviceObject); TRACE_ENTER(); KeSetEvent(CompletionEvent, IO_NO_INCREMENT, FALSE); TRACE_EXIT(); return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS MouFilter_Complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: Generic completion routine that allows the driver to send the irp down the stack, catch it on the way up, and do more processing at the original IRQL. --*/ { PKEVENT event; event = (PKEVENT) Context; // this is a unique way to "reference" a parameter // to avoid compile-time warnings, but still avoid using it // //It's defined as: #define UNREFERENCED_PARAMETER(P) (P) UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp); DbgPrint(("MouFilter_Complete() called\n")); // // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // // Wake this event. We set it previously. KeSetEvent(event, 0, FALSE); // // Allows the event we just woke to do something to the IRP // before it gets sent on its way // return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS OnPollComplete(PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx) { PIO_STACK_LOCATION stack; KIRQL OldIrql; PIRP ReadIrp; ULONG len, count; NTSTATUS status; stack = IoGetNextIrpStackLocation(Irp); KeAcquireSpinLock(&pdx->PollLock, &OldIrql); pdx->PollPending = FALSE; KeReleaseSpinLock(&pdx->PollLock, OldIrql); if(NT_SUCCESS(Irp->IoStatus.Status)){ len = pdx->PollingUrb.UrbBulkOrInterruptTransfer.TransferBufferLength; // Data comes into the driver here, where we write it into the fifo. // The fifo will complete queued read IRPs if needed count = CopyToFifo(pdx, &pdx->PollingBuffer[0], len); CompleteQueuedReads(pdx); if(FALSE == Irp->Cancel) { // if we haven't been cancelled then keep going status = StartPolling(pdx); } } else { // fail current outstanding reads CleanupReads(pdx, NULL, Irp->IoStatus.Status); // wake up the recovery thread KeSetEvent(&pdx->RecoveryEvent, 0, FALSE); } IoReleaseRemoveLock(&pdx->RemoveLock, Irp); // tell the io manager not to perform default handling of irp return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) { PMM_ALLOCATION_REQUEST Request; PLIST_ENTRY Entry; KIRQL OldIrql; if (Page == 0) { DPRINT1("Tried to release page zero.\n"); KeBugCheck(MEMORY_MANAGEMENT); } if (MmGetReferenceCountPage(Page) == 1) { if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL) { OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); MmDereferencePage(Page); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); } else { Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); MiZeroPhysicalPage(Page); Request->Page = Page; KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); } } else { OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); MmDereferencePage(Page); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); } return(STATUS_SUCCESS); }
/* *@unimplemented */ VOID __cdecl StreamClassDeviceNotification( IN STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN PHW_STREAM_REQUEST_BLOCK pSrb, IN PKSEVENT_ENTRY EventEntry, IN GUID *EventSet, IN ULONG EventId) { PHW_STREAM_REQUEST_BLOCK_EXT RequestBlock; if (NotificationType == DeviceRequestComplete) { RequestBlock = (PHW_STREAM_REQUEST_BLOCK_EXT)pSrb; KeSetEvent(&RequestBlock->Event, 0, FALSE); return; } UNIMPLEMENTED }
NTSTATUS NTAPI Bus_CompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { UNREFERENCED_PARAMETER (DeviceObject); // // If the lower driver didn't return STATUS_PENDING, we don't need to // set the event because we won't be waiting on it. // This optimization avoids grabbing the dispatcher lock and improves perf. // if (Irp->PendingReturned == TRUE) { KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE); } return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP }