NTSTATUS DokanStartEventNotificationThread( __in PDEVICE_EXTENSION DeviceExtension) { NTSTATUS status; HANDLE thread; DDbgPrint("==> DokanStartEventNotificationThread\n"); KeResetEvent(&DeviceExtension->ReleaseEvent); status = PsCreateSystemThread(&thread, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE)NotificationThread, DeviceExtension); if (!NT_SUCCESS(status)) { return status; } ObReferenceObjectByHandle(thread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&DeviceExtension->EventNotificationThread, NULL); ZwClose(thread); DDbgPrint("<== DokanStartEventNotificationThread\n"); return STATUS_SUCCESS; }
/** * 创建线程 */ BOOLEAN ipfirewall_create_install_thread() { NTSTATUS ntStatus; __try { // 初始化事件句柄 KeInitializeEvent( &g_ipfirewall_hkEvent, NotificationEvent, FALSE ); // 设置事件句柄为未激发状态,使得 KeWaitForSingleObject 阻塞等待 KeResetEvent( &g_ipfirewall_hkEvent ); // 是否开始 g_ipfirewall_bThreadStart = FALSE; // 创建线程 ntStatus = PsCreateSystemThread( &g_ipfirewall_hThread, 0, NULL, NULL, NULL, ipfirewall_install_thread_proc, NULL ); } __except( EXCEPTION_EXECUTE_HANDLER ) { KdPrint(("EXCEPTION_EXECUTE_HANDLER in: ipfirewall_create_install_thread")); } // ... return NT_SUCCESS( ntStatus ); }
BOOLEAN ChewCreate(VOID (*Worker)(PVOID), PVOID WorkerContext) { PWORK_ITEM Item; Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(WORK_ITEM), CHEW_TAG); if (Item) { Item->WorkItem = IoAllocateWorkItem(WorkQueueDevice); if (!Item->WorkItem) { ExFreePool(Item); return FALSE; } Item->Worker = Worker; Item->WorkerContext = WorkerContext; ExInterlockedInsertTailList(&WorkQueue, &Item->Entry, &WorkQueueLock); KeResetEvent(&WorkQueueClear); IoQueueWorkItem(Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item); return TRUE; } else { return FALSE; } }
VOID KStreamClear(PKSTREAM pStream) { ASSERT_KSTREAM(pStream); KStreamLock(pStream); // ASSERT(pStream->Length == 0); while (!IsListEmpty(&pStream->BuffersListHead)) { PLBUFFER lBuffer = CONTAINING_RECORD(pStream->BuffersListHead.Flink, LBUFFER, Entry); RemoveEntryList(&lBuffer->Entry); ExFreeToNPagedLookasideList(&pStream->Buffers, lBuffer); } pStream->Length = 0; pStream->Position = 0; // Seting DataReadyEvent to satisfy all waiters KeSetEvent(&pStream->DataReadyEvent, 0, FALSE); // Reseting the event to indicate that stream is clean KeResetEvent(&pStream->DataReadyEvent); KStreamUnlock(pStream); }
VOID DestroyNodeEventHandlerVisitor(PVOID context, UINT key, PVOID value) { NTSTATUS status; PIRP irp = NULL; unsigned int i = 0; KEVENT irp_complete_event; IO_STATUS_BLOCK io_status_block; NodeEventHandler* node_event_handler = NULL; EventHandlerManager* event_handler_manager = NULL; node_event_handler = (NodeEventHandler*)value; event_handler_manager = (EventHandlerManager*)context; if(node_event_handler == NULL || event_handler_manager == NULL ) return; KeInitializeEvent(&irp_complete_event, NotificationEvent, FALSE); // For each hooked event handler send an IRP to set the event handler // back to what it originally was for(i = 0; i < TDI_EVENT_HANDLERS_MAX; i++) { PFILE_OBJECT node = node_event_handler->handlers[i].node; TdiEventHandler* original_handler = &node_event_handler->handlers[i].original_handler; if(original_handler->EventHandler == NULL) continue; irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, event_handler_manager->connection_manager->device, node, &irp_complete_event, &io_status_block); if(irp == NULL) continue; TdiBuildSetEventHandler(irp, event_handler_manager->connection_manager->device, node, NULL, NULL, original_handler->EventType, original_handler->EventHandler, original_handler->EventContext); status = IoCallDriver(event_handler_manager->connection_manager->next_device, irp); if(status == STATUS_PENDING) { // Wait for the IRP to finish KeWaitForSingleObject((PVOID)&irp_complete_event, Executive, KernelMode, TRUE, NULL); status = io_status_block.Status; } if(status == STATUS_SUCCESS) { DbgPrint("EventHandlerManager: Successfully set original event handler n=%08x t=%08x\n", node, original_handler->EventType); } else { DbgPrint("EventHandlerManager: Failed to set original event handler - code=%08x n=%08x t=%08x\n", status, node, original_handler->EventType); } KeResetEvent(&irp_complete_event); } }
/* A filedisk's thread routine. */ static VOID STDCALL WvFilediskThread_(IN OUT WVL_SP_THREAD_ITEM item) { WV_SP_FILEDISK_T filedisk = CONTAINING_RECORD( item, WV_S_FILEDISK_T, Thread[0].Main ); LARGE_INTEGER timeout; WVL_SP_THREAD_ITEM work_item; PLIST_ENTRY irp_item; /* Wake up at least every 30 seconds. */ timeout.QuadPart = -300000000LL; while ( (filedisk->Thread->State == WvlThreadStateStarted) || (filedisk->Thread->State == WvlThreadStateStopping) ) { /* Wait for the work signal or the timeout. */ KeWaitForSingleObject( &filedisk->Thread->Signal, Executive, KernelMode, FALSE, &timeout ); /* Reset the work signal. */ KeResetEvent(&filedisk->Thread->Signal); /* Process work items. One of these might be a stopper. */ while (work_item = WvlThreadGetItem(filedisk->Thread)) work_item->Func(work_item); /* Process SCSI IRPs. */ while (irp_item = ExInterlockedRemoveHeadList( filedisk->Irps, filedisk->IrpsLock )) { PIRP irp; PIO_STACK_LOCATION io_stack_loc; irp = CONTAINING_RECORD(irp_item, IRP, Tail.Overlay.ListEntry); io_stack_loc = IoGetCurrentIrpStackLocation(irp); if (io_stack_loc->MajorFunction != IRP_MJ_SCSI) { DBG("Non-SCSI IRP!\n"); continue; } WvlDiskScsi(filedisk->Dev->Self, irp, filedisk->disk); } /* Are we finished? */ if (filedisk->Thread->State == WvlThreadStateStopping) filedisk->Thread->State = WvlThreadStateStopped; } /* while thread started or stopping. */ /* Close any open file handle. */ if (filedisk->file) ZwClose(filedisk->file); return; }
// Reset the event void NeoReset(NEO_EVENT *event) { // Validate arguments if (event == NULL) { return; } KeResetEvent(event->event); }
NTSTATUS v2v_nc2_prep_message(struct v2v_channel *channel, size_t msg_size, unsigned char type, unsigned char flags, volatile void **payload) { volatile struct netchannel2_msg_hdr *hdr; unsigned short size; unsigned short rounded_size; XM_ASSERT(channel != NULL); XM_ASSERT(payload != NULL); msg_size += sizeof(*hdr); if ( ((msg_size + 7) & ~7) > channel->nc2_rings.producer_payload_bytes ) return STATUS_INVALID_PARAMETER; if (type >= NETCHANNEL2_MSG_PAD) return STATUS_NOT_IMPLEMENTED; size = (unsigned short)msg_size; rounded_size = (size + 7) & ~7; if (channel->nc2_rings.remote_endpoint->consumer_active) v2v_nc2_send_messages(channel); if (!nc2_can_send_payload_bytes(&channel->nc2_rings, rounded_size)) { if (channel->is_sync) KeResetEvent(&channel->s.sync.send_event); if (!nc2_can_send_payload_bytes(&channel->nc2_rings, rounded_size)) return STATUS_RETRY; if (channel->is_sync) KeSetEvent(&channel->s.sync.send_event, IO_NO_INCREMENT, FALSE); } __nc2_avoid_ring_wrap(&channel->nc2_rings, rounded_size); hdr = __nc2_get_message_ptr(&channel->nc2_rings); hdr->size = size; hdr->type = type; hdr->flags = flags; *payload = hdr + 1; channel->nc2_rings.local_prod_pvt += rounded_size; channel->nc2_rings.local_prod_bytes_available -= rounded_size; if (channel->nc2_rings.remote_endpoint->consumer_active && !channel->nc2_rings.local_producer_active && __nc2_flush_would_trigger_event(&channel->nc2_rings)) { channel->nc2_rings.local_endpoint->producer_active = 1; channel->nc2_rings.local_producer_active = 1; XM_ASSERT(!is_null_EVTCHN_PORT(channel->send_evtchn_port)); EvtchnNotifyRemote(channel->send_evtchn_port); } return STATUS_SUCCESS; }
BOOL ShareLockKImp::ResetShareEvent() { switch(m_LockType) { case LockTypeEvent: return KeResetEvent(&m_LockObject.m_Event.m_Event); break; default: break; } return FALSE; }
NTSTATUS WaitForUserAnswer() { if (EventKernelWait && EventKernelSet) { if (CreateIsProgressing) return STATUS_ACCESS_DENIED; // 防止混乱 CreateIsProgressing=TRUE; KeSetEvent(EventKernelSet,0,FALSE); KeWaitForSingleObject(EventKernelWait,Executive,KernelMode,FALSE,NULL); KeResetEvent(EventKernelSet); CreateIsProgressing=FALSE; return (CreateAllowed?STATUS_SUCCESS:STATUS_ACCESS_DENIED); } return STATUS_SUCCESS; }
/* The thread responsible for hot-swapping filedisks. */ static VOID STDCALL WvFilediskHotSwapThread_(IN OUT WVL_SP_THREAD_ITEM item) { LARGE_INTEGER timeout; WVL_SP_THREAD thread = CONTAINING_RECORD(item, WVL_S_THREAD, Main); WVL_SP_THREAD_ITEM work_item; WV_SP_FILEDISK_HOT_SWAPPER_ info; /* Wake up at least every 10 seconds. */ timeout.QuadPart = -100000000LL; while ( (thread->State == WvlThreadStateStarted) || (thread->State == WvlThreadStateStopping) ) { /* Wait for the work signal or the timeout. */ KeWaitForSingleObject( &thread->Signal, Executive, KernelMode, FALSE, &timeout ); work_item = WvlThreadGetItem(thread); if (!work_item) continue; if (work_item->Func != WvFilediskHotSwapThread_) { DBG("Unknown work item.\n"); continue; } info = CONTAINING_RECORD( work_item, WV_S_FILEDISK_HOT_SWAPPER_, item[0] ); /* Attempt a hot swap. */ if (WvFilediskHotSwap_(info->filedisk, info->filename)) { /* Success. */ RtlFreeUnicodeString(info->filename); wv_free(info); } else { /* Re-enqueue. */ WvlThreadAddItem(thread, info->item); } /* Reset the work signal. */ KeResetEvent(&thread->Signal); } /* while thread is running. */ return; }
VOID ReInitWskData( __out PIRP* pIrp, __out PKEVENT CompletionEvent ) { ASSERT(pIrp); ASSERT(CompletionEvent); KeResetEvent(CompletionEvent); IoReuseIrp(*pIrp, STATUS_UNSUCCESSFUL); IoSetCompletionRoutine(*pIrp, CompletionRoutine, CompletionEvent, TRUE, TRUE, TRUE); return; }
VOID ArcReferencePackage(VOID) { ACQUIRE_SPIN_LOCK(&ArcReferenceLock); ArcReferenceCount++; if (ArcReferenceCount == 1) { KeResetEvent( &ArcPagedInEvent ); RELEASE_SPIN_LOCK(&ArcReferenceLock); // // Page in all the functions // ArcImageHandle = MmLockPagableCodeSection(ArcCreateFilter); // // Signal to everyone to go // KeSetEvent( &ArcPagedInEvent, 0L, FALSE ); } else { RELEASE_SPIN_LOCK(&ArcReferenceLock); // // Wait for everything to be paged in // KeWaitForSingleObject( &ArcPagedInEvent, Executive, KernelMode, TRUE, NULL ); } }
// Reset the event void NeoReset(NEO_EVENT *event) { // Validate arguments if (event == NULL) { return; } #ifndef WIN9X KeResetEvent(event->event); #else // WIN9X if (event->win32_event != 0) { DWORD h = event->win32_event; _asm mov eax, h; VxDCall(_VWIN32_ResetWin32Event); } #endif // WIN9X }
/**************************************************************************** REMARKS: Main driver thread for executing all registered heartbeat callbacks. Win2K/XP does not allow waiting for semaphores inside DPCs, so instead the DPC must signal a timeout event to wake up a driver helper thread. ****************************************************************************/ VOID _PM_heartBeatThread( PVOID pContext) { int i; _PM_heartBeat_t *hb = (_PM_heartBeat_t*)pContext; while (hb->bThreadRunning) { // Yield thread until DPC timer signalled state KeWaitForSingleObject(&_PM_hb->kTimerEvent,Executive,KernelMode,FALSE,NULL); // Lock the SNAP subsystem and process all the registered callbacks PM_lockSNAPAccess(-1,true); for (i = 0; i < hb->numHeartBeatCallbacks; i++) (*hb->heartBeat[i])(hb->heartBeatData[i]); PM_unlockSNAPAccess(-1); // Reset signal for next DPC timeout KeResetEvent(&_PM_hb->kTimerEvent); } // Exit driver thread PsTerminateSystemThread(STATUS_SUCCESS); }
/* * @implemented */ NDIS_STATUS EXPORT NdisMAllocateMapRegisters( IN NDIS_HANDLE MiniportAdapterHandle, IN UINT DmaChannel, IN NDIS_DMA_SIZE DmaSize, IN ULONG BaseMapRegistersNeeded, IN ULONG MaximumBufferSize) /* * FUNCTION: Allocate map registers for use in DMA transfers * ARGUMENTS: * MiniportAdapterHandle: Passed in to MiniportInitialize * DmaChannel: DMA channel to use * DmaSize: bit width of DMA transfers * BaseMapRegistersNeeded: number of base map registers requested * MaximumBufferSize: largest single buffer transferred * RETURNS: * NDIS_STATUS_SUCCESS on success * NDIS_STATUS_RESOURCES on failure * NOTES: * - the win2k ddk and the nt4 ddk have conflicting prototypes for this. * I'm implementing the 2k one. * - do not confuse a "base map register" with a "map register" - they * are different. Only NDIS seems to use the base concept. The idea * is that a miniport supplies the number of base map registers it will * need, which is equal to the number of DMA send buffers it manages. * NDIS then allocates a number of map registers to go with each base * map register, so that a driver just has to send the base map register * number during dma operations and NDIS can find the group of real * map registers that represent the transfer. * - Because of the above sillyness, you can only specify a few base map * registers at most. a 1514-byte packet is two map registers at 4k * page size. * - NDIS limits the total number of allocated map registers to 64, * which (in the case of the above example) limits the number of base * map registers to 32. */ { DEVICE_DESCRIPTION Description; PDMA_ADAPTER AdapterObject = 0; UINT MapRegistersPerBaseRegister = 0; ULONG AvailableMapRegisters; NTSTATUS NtStatus; PLOGICAL_ADAPTER Adapter; PDEVICE_OBJECT DeviceObject = 0; KEVENT AllocationEvent; KIRQL OldIrql; NDIS_DbgPrint(MAX_TRACE, ("called: Handle 0x%x, DmaChannel 0x%x, DmaSize 0x%x, BaseMapRegsNeeded: 0x%x, MaxBuffer: 0x%x.\n", MiniportAdapterHandle, DmaChannel, DmaSize, BaseMapRegistersNeeded, MaximumBufferSize)); memset(&Description,0,sizeof(Description)); Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; ASSERT(Adapter); /* only bus masters may call this routine */ if(!(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_BUS_MASTER)) { NDIS_DbgPrint(MIN_TRACE, ("Not a bus master\n")); return NDIS_STATUS_NOT_SUPPORTED; } DeviceObject = Adapter->NdisMiniportBlock.DeviceObject; KeInitializeEvent(&AllocationEvent, NotificationEvent, FALSE); Adapter->NdisMiniportBlock.AllocationEvent = &AllocationEvent; /* * map registers correlate to physical pages. ndis documents a * maximum of 64 map registers that it will return. * at 4k pages, a 1514-byte buffer can span not more than 2 pages. * * the number of registers required for a given physical mapping * is (first register + last register + one per page size), * given that physical mapping is > 2. */ /* unhandled corner case: {1,2}-byte max buffer size */ ASSERT(MaximumBufferSize > 2); MapRegistersPerBaseRegister = ((MaximumBufferSize-2) / (2*PAGE_SIZE)) + 2; Description.Version = DEVICE_DESCRIPTION_VERSION; Description.Master = TRUE; /* implied by calling this function */ Description.ScatterGather = TRUE; /* XXX UNTRUE: All BM DMA are S/G (ms seems to do this) */ Description.BusNumber = Adapter->NdisMiniportBlock.BusNumber; Description.InterfaceType = Adapter->NdisMiniportBlock.BusType; Description.DmaChannel = DmaChannel; Description.MaximumLength = MaximumBufferSize; if(DmaSize == NDIS_DMA_64BITS) Description.Dma64BitAddresses = TRUE; else if(DmaSize == NDIS_DMA_32BITS) Description.Dma32BitAddresses = TRUE; AdapterObject = IoGetDmaAdapter( Adapter->NdisMiniportBlock.PhysicalDeviceObject, &Description, &AvailableMapRegisters); if(!AdapterObject) { NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate an adapter object; bailing out\n")); return NDIS_STATUS_RESOURCES; } Adapter->NdisMiniportBlock.SystemAdapterObject = AdapterObject; if(AvailableMapRegisters < MapRegistersPerBaseRegister) { NDIS_DbgPrint(MIN_TRACE, ("Didn't get enough map registers from hal - requested 0x%x, got 0x%x\n", MapRegistersPerBaseRegister, AvailableMapRegisters)); AdapterObject->DmaOperations->PutDmaAdapter(AdapterObject); Adapter->NdisMiniportBlock.SystemAdapterObject = NULL; return NDIS_STATUS_RESOURCES; } /* allocate & zero space in the miniport block for the registers */ Adapter->NdisMiniportBlock.MapRegisters = ExAllocatePool(NonPagedPool, BaseMapRegistersNeeded * sizeof(MAP_REGISTER_ENTRY)); if(!Adapter->NdisMiniportBlock.MapRegisters) { NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n")); AdapterObject->DmaOperations->PutDmaAdapter(AdapterObject); Adapter->NdisMiniportBlock.SystemAdapterObject = NULL; return NDIS_STATUS_RESOURCES; } memset(Adapter->NdisMiniportBlock.MapRegisters, 0, BaseMapRegistersNeeded * sizeof(MAP_REGISTER_ENTRY)); Adapter->NdisMiniportBlock.BaseMapRegistersNeeded = (USHORT)BaseMapRegistersNeeded; while(BaseMapRegistersNeeded) { NDIS_DbgPrint(MAX_TRACE, ("iterating, basemapregistersneeded = %d\n", BaseMapRegistersNeeded)); BaseMapRegistersNeeded--; Adapter->NdisMiniportBlock.CurrentMapRegister = (USHORT)BaseMapRegistersNeeded; KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); { NtStatus = AdapterObject->DmaOperations->AllocateAdapterChannel( AdapterObject, DeviceObject, MapRegistersPerBaseRegister, NdisBusMasterMapRegisterCallback, Adapter); } KeLowerIrql(OldIrql); if(!NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MIN_TRACE, ("IoAllocateAdapterChannel failed: 0x%x\n", NtStatus)); ExFreePool(Adapter->NdisMiniportBlock.MapRegisters); AdapterObject->DmaOperations->PutDmaAdapter(AdapterObject); Adapter->NdisMiniportBlock.CurrentMapRegister = Adapter->NdisMiniportBlock.BaseMapRegistersNeeded = 0; Adapter->NdisMiniportBlock.SystemAdapterObject = NULL; return NDIS_STATUS_RESOURCES; } NDIS_DbgPrint(MAX_TRACE, ("waiting on event\n")); NtStatus = KeWaitForSingleObject(&AllocationEvent, Executive, KernelMode, FALSE, 0); if(!NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MIN_TRACE, ("KeWaitForSingleObject failed: 0x%x\n", NtStatus)); ExFreePool(Adapter->NdisMiniportBlock.MapRegisters); AdapterObject->DmaOperations->PutDmaAdapter(AdapterObject); Adapter->NdisMiniportBlock.CurrentMapRegister = Adapter->NdisMiniportBlock.BaseMapRegistersNeeded = 0; Adapter->NdisMiniportBlock.SystemAdapterObject = NULL; return NDIS_STATUS_RESOURCES; } NDIS_DbgPrint(MAX_TRACE, ("resetting event\n")); KeResetEvent(&AllocationEvent); } NDIS_DbgPrint(MAX_TRACE, ("returning success\n")); return NDIS_STATUS_SUCCESS; }
// Send a USB command to device and then waiting for this command to complete. NTSTATUS UsbDev::SendAwaitUrb(PURB Urb) { //2010/8/25 03:13下午 /*NTSTATUS ntStatus, status = STATUS_SUCCESS; PIRP irp; KEVENT TimeoutEvent; PIO_STACK_LOCATION nextStack; KeWaitForSingleObject(&CallUSBSemaphore,Executive,KernelMode,FALSE,NULL); // Initialize the event we'll wait on // KeInitializeEvent(&TimeoutEvent,SynchronizationEvent,FALSE); // Allocate the Irp // irp = IoAllocateIrp(m_pLdo->StackSize, FALSE); if (irp == NULL){ ntStatus = STATUS_UNSUCCESSFUL; goto Exit_CallUSB; } // // Set the Irp parameters // nextStack = IoGetNextIrpStackLocation(irp); //ASSERT(nextStack != NULL); nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; nextStack->Parameters.Others.Argument1 = Urb; // // Set the completion routine. // IoSetCompletionRoutine(irp,SyncCompletionRoutine,&TimeoutEvent, TRUE, TRUE,TRUE); // // pass the irp down usb stack // ntStatus = IoCallDriver(m_pLdo,irp); if (ntStatus == STATUS_PENDING) { // Irp i spending. we have to wait till completion.. LARGE_INTEGER timeout; // Specify a timeout of 5 seconds to wait for this call to complete. // timeout.QuadPart = -10000 * 5000; ntStatus = KeWaitForSingleObject(&TimeoutEvent, Executive,KernelMode,FALSE, &timeout); if (ntStatus == STATUS_TIMEOUT) { ntStatus = STATUS_IO_TIMEOUT; // Cancel the Irp we just sent. // IoCancelIrp(irp); // And wait until the cancel completes // KeWaitForSingleObject(&TimeoutEvent,Executive, KernelMode, FALSE,NULL); } else { ntStatus = irp->IoStatus.Status; } } // Done with the Irp, now free it. // IoFreeIrp(irp); Exit_CallUSB: KeReleaseSemaphore(&CallUSBSemaphore,LOW_REALTIME_PRIORITY,1,FALSE); if (NT_ERROR(ntStatus)) { DBGU_TRACE("***Error*** SendAwaitUrb (%x) (%x)\n", ntStatus,Urb->UrbHeader.Status); } return ntStatus; */ DBGU_TRACE("UsbDev::SendAwaitUrb\n"); NTSTATUS ntStatus = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus; KEVENT event; PIRP Irp; PIO_STACK_LOCATION nextStack; LARGE_INTEGER dueTime; //UINT retry = 0; KeInitializeEvent(&event, NotificationEvent, FALSE); // ------------------ 2006/09/27 [Saxen Ko] ------------------ // fix DELL bug, that we might re-use the Urb to sent commands! //for (retry = 0; retry < 3; ++retry) { Irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, m_pLdo, NULL, 0, NULL, 0, TRUE, &event, &ioStatus); if((Irp != NULL) && ((nextStack = IoGetNextIrpStackLocation(Irp)) != NULL)) {//(Irp != NULL) && (nextStack != NULL) nextStack->Parameters.Others.Argument1 = Urb; // // Set the completion routine, which will signal the event // IoSetCompletionRoutine(Irp, SyncCompletionRoutine, &event, FALSE, // InvokeOnSuccess FALSE, // InvokeOnError TRUE); // InvokeOnCancel ntStatus = IoCallDriver(m_pLdo, Irp); if (ntStatus == STATUS_PENDING) {//ntStatus == STATUS_PENDING dueTime.QuadPart = (-10000 * USB_COMMAND_TIMEOUT); ntStatus = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, &dueTime); if (ntStatus == STATUS_TIMEOUT) { ntStatus = STATUS_IO_TIMEOUT; DBGU_TRACE("UsbDev::SendAwaitUrb STATUS_IO_TIMEOUT, We cancel this IRP!\n"); // Reset the Event, then Cancel the Irp we just sent. KeResetEvent(&event); IoCancelIrp(Irp); // And wait until the cancel completes KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); } else ntStatus = ioStatus.Status; }//ntStatus == STATUS_PENDING //else //{ // ioStatus.Status = ntStatus; //} }//(Irp != NULL) && (nextStack != NULL) else {//Irp == NULL ntStatus = STATUS_INSUFFICIENT_RESOURCES; }//Irp == NULL DBGU_TRACE("SendAwaitUrb: ntStatus(%X) !\n", ntStatus); if(!NT_SUCCESS(ntStatus)) { DBGU_TRACE("SendAwaitUrb: UrbStatus(%X) !\n", Urb->UrbHeader.Status); // make it more significant if (ntStatus == STATUS_UNSUCCESSFUL) ntStatus = Urb->UrbHeader.Status; } //if ((STATUS_UNSUCCESSFUL == ntStatus) && (USBD_STATUS_DEV_NOT_RESPONDING == Urb->UrbHeader.Status)) //{ // KeResetEvent(&event); // DBGU_TRACE("SendAwaitUrb: retry(%d)\n", (retry + 1)); //} //else //{ // break; //} } return ntStatus; }
ULONG KStreamRead(PKSTREAM pStream, PCHAR Data, ULONG Length) { PLBUFFER lBuffer; // current buffer ULONG bRead = 0; // bytes already read ULONG bSize; // bytes we can read from current buffer ULONG bOffset; // offset within the buffer to start reading from ASSERT_KSTREAM(pStream); KStreamLock(pStream); bOffset = pStream->Position; ASSERT(bOffset == 0 || pStream->Length != 0); while((Length) && (pStream->Length)) { ASSERT(!IsListEmpty(&pStream->BuffersListHead)); // Determine how many bytes we can copy now bSize = KSTREAM_BUFFER_SIZE - bOffset; if (bSize > pStream->Length) bSize = pStream->Length; if (bSize > Length) bSize = Length; // Take the first buffer from the list lBuffer = CONTAINING_RECORD(pStream->BuffersListHead.Flink, LBUFFER, Entry); ASSERT(bSize <= pStream->Length); memcpy(Data + bRead, (PCHAR)&lBuffer->Data + bOffset, bSize); Length -= bSize; pStream->Length -= bSize; bRead += bSize; if ((bOffset + bSize) == KSTREAM_BUFFER_SIZE || pStream->Length == 0) { // Current buffer is empty RemoveEntryList(&lBuffer->Entry); ExFreeToNPagedLookasideList(&pStream->Buffers, lBuffer); pStream->Position = 0; } else { ASSERT(pStream->Length == 0 || Length == 0); pStream->Position = bOffset + bSize; } bOffset = 0; } if (pStream->Length == 0) { ASSERT(IsListEmpty(&pStream->BuffersListHead)); ASSERT(pStream->Position == 0); KeResetEvent(&pStream->DataReadyEvent); } else { ASSERT(!IsListEmpty(&pStream->BuffersListHead)); } KStreamUnlock(pStream); return(bRead); }
typedef struct _OC_CR_SECTION_VIEW{ // // the start and end adress in the system process // ULONG_PTR BaseAddress; ULONG_PTR EndAddress; // // where the mapped view starts in a file // ULARGE_INTEGER ViewStartInFile; // // where the mapped view ends in a file // ULARGE_INTEGER ViewEndInFile; // // the current pointer // ULONG_PTR CurrentPointer; // // a referenced section object // POC_CR_MAPPED_FILE_SECTION FileSectionObject; } //-------------------------------------------------- NTSTATUS OcCrCreateShadowFile( IN PUNICODE_STRING FileName, IN PULARGE_INTEGER ThresholdFileSize, IN PKEVENT ReferencedServiceEvent OPTIONAL, IN PKEVENT ReferencedEventToSetWhenReleasingFile OPTIONAL, IN PULARGE_INTEGER MaximumSizeDueToQuota OPTIONAL ) { NTSTATUS RC = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; HANDLE FileHandle = NULL; PFILE_OBJECT FileObject = NULL; USHORT usCompressionFormat = COMPRESSION_FORMAT_NONE; HANDLE EventHandle; PKEVENT EventObject; BOOLEAN UseCache = FALSE; ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); // // align the maximum size to the page boundary, this restriction // is imposed by our proprietary cache // if( NULL != MaximumSizeDueToQuota ){ MaximumSizeDueToQuota->LowPart = MaximumSizeDueToQuota->LowPart & ~( PAGE_SIZE - 0x1 ); } // // always use fast write! // UseCache = TRUE;//!( g_ShadowLevel > ShadowLevelBase ); //RtlInitUnicodeString( &uFileName, L"\\DosDevices\\C:\\shadow_pio.dat" ); InitializeObjectAttributes( &ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); // // TO DO - Protect file from changing attributes and other file information. // RC = ZwCreateFile( &FileHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0x0,// sharing is disabled FILE_SUPERSEDE,// replace the file if exist, because we must be the first and the last file owner FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION | ( UseCache ? 0x0 : FILE_NO_INTERMEDIATE_BUFFERING ), NULL, 0 ); ASSERT( RC != STATUS_PENDING ); if( !NT_SUCCESS( RC ) ) goto __exit; EventObject = IoCreateSynchronizationEvent( NULL, &EventHandle ); if( NULL != EventObject ){ // // Event is created in the signal state // KeResetEvent( EventObject ); // // disable the compression // RC = ZwFsControlFile( FileHandle, EventHandle,//Event NULL,//Apc NULL,//Apc Context &IoStatus, FSCTL_SET_COMPRESSION, &usCompressionFormat, sizeof( usCompressionFormat ), NULL, 0 ); if( STATUS_PENDING == RC ){ KeWaitForSingleObject( EventObject, Executive, KernelMode, FALSE, NULL ); }//if( STATUS_PENDING == RC ) ZwClose( EventHandle ); }//if( NULL != EventObject ){ // // the FSD may not support the compression set request // or the event creation failed, in any case I set // FILE_NO_COMPRESSION attribute, hope this is enough. // RC = STATUS_SUCCESS; RC = ObReferenceObjectByHandle( FileHandle, FILE_ANY_ACCESS, *IoFileObjectType, KernelMode, //to avoid a security check set mode to Kernel (PVOID *)&FileObject, NULL ); ASSERT( NT_SUCCESS( RC ) ); if( !NT_SUCCESS( RC ) ) goto __exit; RC = DldSetNewBuffersFile( FileHandle, FileObject, ThresholdFileSize, ReferencedServiceEvent, ReferencedEventToSetWhenReleasingFile, MaximumSizeDueToQuota ); // // Set file handle to NULL, because it has been grabed by // the DldSetNewBuffersFile and will be closed // when it is no longer needed. // FileHandle = NULL; if( !NT_SUCCESS( RC ) ) goto __exit; __exit: ASSERT( NT_SUCCESS( RC ) ); if( !NT_SUCCESS( RC ) ){ if( NULL != FileObject ){ ObDereferenceObject( FileObject ); } if( NULL != FileHandle ){ ZwClose( FileHandle ); } } else { ASSERT( NULL == FileHandle ); ASSERT( FileObject ); ObDereferenceObject( FileObject ); } return RC; }
NTSTATUS NtResetEvent ( IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL ) /*++ Routine Description: This function sets an event object to a Not-Signaled state. Arguments: EventHandle - Supplies a handle to an event object. PreviousState - Supplies an optional pointer to a variable that will receive the previous state of the event object. Return Value: TBS --*/ { PVOID Event; KPROCESSOR_MODE PreviousMode; LONG State; NTSTATUS Status; // // Establish an exception handler, probe the previous state address if // specified, reference the event object, and reset the event object. If // the probe fails, then return the exception code as the service status. // Otherwise return the status value returned by the reference object by // handle routine. // try { // // Get previous processor mode and probe previous state address // if necessary. // PreviousMode = KeGetPreviousMode(); if ((PreviousMode != KernelMode) && (ARGUMENT_PRESENT(PreviousState))) { ProbeForWriteLong(PreviousState); } // // Reference event object by handle. // Status = ObReferenceObjectByHandle(EventHandle, EVENT_MODIFY_STATE, ExEventObjectType, PreviousMode, &Event, NULL); // // If the reference was successful, then set the state of the event // object to Not-Signaled, dereference event object, and write the // previous state value if specified. If the write of the previous // state fails, then do not report an error. When the caller attempts // to access the previous state value, an access violation will occur. // if (NT_SUCCESS(Status)) { State = KeResetEvent((PKEVENT)Event); ObDereferenceObject(Event); if (ARGUMENT_PRESENT(PreviousState)) { try { *PreviousState = State; } except(ExSystemExceptionFilter()) { } } } // // If an exception occurs during the probe of the previous state, then // always handle the exception and return the exception code as the status // value. // } except(ExSystemExceptionFilter()) { return GetExceptionCode(); } // // Return service status. // return Status; }
static VOID TestEventFunctional( IN PKEVENT Event, IN EVENT_TYPE Type, IN KIRQL OriginalIrql) { LONG State; PKTHREAD Thread = KeGetCurrentThread(); memset(Event, 0x55, sizeof *Event); KeInitializeEvent(Event, Type, FALSE); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); memset(Event, 0x55, sizeof *Event); KeInitializeEvent(Event, Type, TRUE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); Event->Header.SignalState = 0x12345678L; CheckEvent(Event, Type, 0x12345678L, FALSE, OriginalIrql, (PVOID *)NULL, 0); State = KePulseEvent(Event, 0, FALSE); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x12345678L); Event->Header.SignalState = 0x12345678L; KeClearEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); State = KeSetEvent(Event, 0, FALSE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0L); State = KeResetEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 1L); Event->Header.SignalState = 0x23456789L; State = KeSetEvent(Event, 0, FALSE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x23456789L); Event->Header.SignalState = 0x3456789AL; State = KeResetEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x3456789AL); /* Irql is raised to DISPATCH_LEVEL here, which kills checked build, * a spinlock is acquired and never released, which kills MP build */ if ((OriginalIrql <= DISPATCH_LEVEL || !KmtIsCheckedBuild) && !KmtIsMultiProcessorBuild) { Event->Header.SignalState = 0x456789ABL; State = KeSetEvent(Event, 0, TRUE); CheckEvent(Event, Type, 1L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0); ok_eq_long(State, 0x456789ABL); ok_eq_uint(Thread->WaitIrql, OriginalIrql); /* repair the "damage" */ Thread->WaitNext = FALSE; KmtSetIrql(OriginalIrql); Event->Header.SignalState = 0x56789ABCL; State = KePulseEvent(Event, 0, TRUE); CheckEvent(Event, Type, 0L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0); ok_eq_long(State, 0x56789ABCL); ok_eq_uint(Thread->WaitIrql, OriginalIrql); /* repair the "damage" */ Thread->WaitNext = FALSE; KmtSetIrql(OriginalIrql); } ok_irql(OriginalIrql); KmtSetIrql(OriginalIrql); }
dVoid kdi_LockUnlockDMA ( /* INPUT PARAMETERS: */ KdiContextPtr kdi_context, dBoolean lock /* UPDATE PARAMETERS: */ /* OUTPUT PARAMETERS: */ ) /* COMMENTS: ***************************************************************** * * DEFINITIONS: *************************************************************/ { /* DATA: ********************************************************************/ KIRQL old_irql; /* CODE: ********************************************************************/ if (kdi_context->adapter_object) { if (lock) { if (!kdi_context->adapter_locked) { /* Allocate an adapter channel for the I/O. */ (dVoid) KeResetEvent( &kdi_context->allocate_adapter_channel_event ); KeRaiseIrql( DISPATCH_LEVEL, &old_irql ); IoAllocateAdapterChannel( kdi_context->adapter_object, kdi_context->device_object, kdi_context->number_of_map_registers, kdi_AllocateAdapterChannel, kdi_context ); KeLowerIrql( old_irql ); /* Wait for the adapter to be allocated. No */ /* timeout; we trust the system to do it */ /* properly - so KeWaitForSingleObject can't */ /* return an error. */ (dVoid) KeWaitForSingleObject( &kdi_context->allocate_adapter_channel_event, Executive, KernelMode, dFALSE, (dSDDWordPtr) dNULL_PTR ); kdi_context->adapter_locked = dTRUE; } } else { if (kdi_context->adapter_locked) { /* Free the adapter channel that we just used. */ KeRaiseIrql( DISPATCH_LEVEL, &old_irql ); IoFreeAdapterChannel( kdi_context->adapter_object ); KeLowerIrql( old_irql ); kdi_context->adapter_locked = dFALSE; } } } return; }
NTSTATUS v2v_nc2_get_message(struct v2v_channel *channel, const volatile void **msg, size_t *out_size, unsigned *type, unsigned *flags) { RING_IDX prod; RING_IDX cons_pvt; const volatile struct netchannel2_msg_hdr *hdr; unsigned size; unsigned counter; XM_ASSERT(channel != NULL); XM_ASSERT((msg != NULL)&&(out_size != NULL)&&(type != NULL)&&(flags != NULL)); counter = 0; retry: cons_pvt = channel->nc2_rings.local_cons_pvt; prod = channel->nc2_rings.remote_endpoint->prod; rmb(); if (prod == cons_pvt) { if (channel->nc2_rings.remote_endpoint->producer_active && counter < CONSUMER_SPIN_LIMIT) { channel->nc2_rings.local_endpoint->consumer_spinning = 1; while (channel->nc2_rings.remote_endpoint->producer_active && counter++ < CONSUMER_SPIN_LIMIT) ; channel->nc2_rings.local_endpoint->consumer_spinning = 0; /* The write to local_endpoint->consumer_spinning needs to come before any write of prod_event which might happen shortly. Fortunately, they're both volatile, so happen in-order, and we don't need any explicit barriers. */ goto retry; } if (channel->is_sync) KeResetEvent(&channel->s.sync.receive_event); if (nc2_final_check_for_messages(&channel->nc2_rings, prod)) { if (channel->is_sync) KeSetEvent(&channel->s.sync.receive_event, IO_NO_INCREMENT, FALSE); goto retry; } return STATUS_NO_MORE_ENTRIES; } hdr = __nc2_incoming_message(&channel->nc2_rings); if (!__nc2_contained_in_cons_ring(&channel->nc2_rings, hdr, sizeof(*hdr))) { /* This can't happen, unless the other end is misbehaving. */ invalid_message: return STATUS_DATA_ERROR; } size = hdr->size; if (size < sizeof(*hdr) || !__nc2_contained_in_cons_ring(&channel->nc2_rings, hdr, size)) goto invalid_message; if (hdr->type == NETCHANNEL2_MSG_PAD) { /* Discard pad message */ channel->nc2_rings.local_cons_pvt += size; goto retry; } *msg = hdr + 1; *out_size = channel->current_message_size = size - sizeof(*hdr); *type = hdr->type; *flags = hdr->flags; return STATUS_SUCCESS; }
NTSTATUS otLwfEventProcessingStart( _In_ PMS_FILTER pFilter ) { NTSTATUS status = STATUS_SUCCESS; HANDLE threadHandle = NULL; LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p, TimeIncrement = %u", pFilter, KeQueryTimeIncrement()); pFilter->NextAlarmTickCount.QuadPart = 0; NT_ASSERT(pFilter->EventWorkerThread == NULL); if (pFilter->EventWorkerThread != NULL) { status = STATUS_ALREADY_REGISTERED; goto error; } // Make sure to reset the necessary events KeResetEvent(&pFilter->EventWorkerThreadStopEvent); KeResetEvent(&pFilter->SendNetBufferListComplete); KeResetEvent(&pFilter->EventWorkerThreadEnergyScanComplete); // Start the worker thread status = PsCreateSystemThread( &threadHandle, // ThreadHandle THREAD_ALL_ACCESS, // DesiredAccess NULL, // ObjectAttributes NULL, // ProcessHandle NULL, // ClientId otLwfEventWorkerThread, // StartRoutine pFilter // StartContext ); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "PsCreateSystemThread failed, %!STATUS!", status); goto error; } // Grab the object reference to the worker thread status = ObReferenceObjectByHandle( threadHandle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &pFilter->EventWorkerThread, NULL ); if (!NT_VERIFYMSG("ObReferenceObjectByHandle can't fail with a valid kernel handle", NT_SUCCESS(status))) { LogError(DRIVER_DEFAULT, "ObReferenceObjectByHandle failed, %!STATUS!", status); KeSetEvent(&pFilter->EventWorkerThreadStopEvent, IO_NO_INCREMENT, FALSE); } ZwClose(threadHandle); error: if (!NT_SUCCESS(status)) { ExSetTimerResolution(0, FALSE); } LogFuncExitNT(DRIVER_DEFAULT, status); return status; }