Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/**
 *	创建线程
 */
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 );
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 5
0
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);
	}
}
Exemplo n.º 6
0
/* 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;
  }
Exemplo n.º 7
0
// Reset the event
void NeoReset(NEO_EVENT *event)
{
	// Validate arguments
	if (event == NULL)
	{
		return;
	}

	KeResetEvent(event->event);
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
BOOL
ShareLockKImp::ResetShareEvent() {

	switch(m_LockType) {
	case LockTypeEvent:
		return KeResetEvent(&m_LockObject.m_Event.m_Event);
		break;
	default:
		break;
	}
	return FALSE;
}
Exemplo n.º 10
0
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;
}	
Exemplo n.º 11
0
/* 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;
  }
Exemplo n.º 12
0
Arquivo: wsk2.c Projeto: airhigh/wdrbd
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;
}
Exemplo n.º 13
0
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
                        );

    }

}
Exemplo n.º 14
0
// 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
}
Exemplo n.º 15
0
/****************************************************************************
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);
}
Exemplo n.º 16
0
Arquivo: io.c Projeto: GYGit/reactos
/*
 * @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;
}
Exemplo n.º 17
0
// 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;
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
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;
}
Exemplo n.º 24
0
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;
}