Exemplo n.º 1
0
VOID
DokanStopCheckThread(
	__in PDokanDCB	Dcb)
/*++

Routine Description:

	exits DokanTimeoutThread

--*/
{
    PIO_WORKITEM      workItem;

	DDbgPrint("==> DokanStopCheckThread\n");

    workItem = IoAllocateWorkItem(Dcb->DeviceObject);
    if (workItem != NULL) {
        IoQueueWorkItem(workItem, DokanStopCheckThreadInternal, DelayedWorkQueue, workItem);

        KeSetEvent(&Dcb->KillEvent, 0, FALSE);

        if (Dcb->TimeoutThread) {
            KeWaitForSingleObject(Dcb->TimeoutThread, Executive,
                KernelMode, FALSE, NULL);
            ObDereferenceObject(Dcb->TimeoutThread);
            Dcb->TimeoutThread = NULL;
        }
    } else {
        DDbgPrint("Can't create work item.");
    }
	
	DDbgPrint("<== DokanStopCheckThread\n");
}
Exemplo n.º 2
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;
    }
}
Exemplo n.º 3
0
VOID
LsuWriteLogErrorEntry(
	IN PDEVICE_OBJECT		DeviceObject,
    IN PLSU_ERROR_LOG_ENTRY ErrorLogEntry
){


	if(KeGetCurrentIrql() > PASSIVE_LEVEL) {
		PIO_WORKITEM	workitem;
		PLSU_ERRORLOGCTX	context;

		context = ExAllocatePoolWithTag(NonPagedPool, sizeof(LSU_ERRORLOGCTX), LSU_POOLTAG_ERRORLOGWORKER);
		if(context == NULL) {
			KDPrintM(DBG_OTHER_ERROR, ("Allocating context failed.\n"));
			return;
		}

		RtlCopyMemory(&context->ErrorLogEntry, ErrorLogEntry, sizeof(LSU_ERROR_LOG_ENTRY));


		workitem = IoAllocateWorkItem(DeviceObject);
		if(workitem == NULL) {
			KDPrintM(DBG_OTHER_ERROR, ("IoAllocateWorkItem() failed.\n"));
			return;
		}

		context->IoWorkItem = workitem;

		IoQueueWorkItem(workitem, WriteErrorLogWorker, DelayedWorkQueue, context);

	} else {
		_WriteLogErrorEntry(DeviceObject, ErrorLogEntry);
	}
}
NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice,
                               _In_ IO_WORKITEM_ROUTINE* pWorkItemFn)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprWorkItemQueue()\n");

#endif /// DBG
   
   NT_ASSERT(pWDMDevice);
   NT_ASSERT(pWorkItemFn);

   NTSTATUS     status      = STATUS_SUCCESS;
   PIO_WORKITEM pIOWorkItem = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in pWorkItemFn

   pIOWorkItem = IoAllocateWorkItem(pWDMDevice);
   if(pIOWorkItem == 0)
   {
      status = STATUS_UNSUCCESSFUL;

      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

#pragma warning(pop)

   IoQueueWorkItem(pIOWorkItem,
                   pWorkItemFn,
                   DelayedWorkQueue,
                   (PVOID)pIOWorkItem);

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS &&
      pIOWorkItem)
      IoFreeWorkItem(pIOWorkItem);

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprWorkItemQueue() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}
Exemplo n.º 5
0
static NTSTATUS
XenStub_QueueWorkItem(PDEVICE_OBJECT device_object, PIO_WORKITEM_ROUTINE routine, PVOID context)
{
  PIO_WORKITEM work_item;
  NTSTATUS status = STATUS_SUCCESS;

  work_item = IoAllocateWorkItem(device_object);
  IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
	
  return status;
}
Exemplo n.º 6
0
static VOID
XenNet_SuspendResume(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
{
  struct xennet_info *xi = context;
  KIRQL old_irql;
  PIO_WORKITEM resume_work_item;

  UNREFERENCED_PARAMETER(dpc);
  UNREFERENCED_PARAMETER(arg1);
  UNREFERENCED_PARAMETER(arg2);

  FUNCTION_ENTER();
  
  switch (xi->device_state->suspend_resume_state_pdo)
  {
  case SR_STATE_SUSPENDING:
    KdPrint((__DRIVER_NAME "     New state SUSPENDING\n"));
    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
    if (xi->rx_id_free == NET_RX_RING_SIZE)
    {  
      xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
    }
    KeReleaseSpinLock(&xi->rx_lock, old_irql);
    break;
  case SR_STATE_RESUMING:
    KdPrint((__DRIVER_NAME "     New state SR_STATE_RESUMING\n"));
    /* do it like this so we don't race and double-free the work item */
    resume_work_item = IoAllocateWorkItem(xi->fdo);
    KeAcquireSpinLock(&xi->resume_lock, &old_irql);
    if (xi->resume_work_item || xi->device_state->suspend_resume_state_fdo == SR_STATE_RESUMING)
    {
      KeReleaseSpinLock(&xi->resume_lock, old_irql);
      IoFreeWorkItem(resume_work_item);
      return;
    }
    xi->resume_work_item = resume_work_item;
    KeReleaseSpinLock(&xi->resume_lock, old_irql);
    IoQueueWorkItem(xi->resume_work_item, XenNet_ResumeWorkItem, DelayedWorkQueue, xi);
    break;
  default:
    KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->suspend_resume_state_fdo));
    xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
    break;
  }
  KeMemoryBarrier();
  
  FUNCTION_EXIT();
}
Exemplo n.º 7
0
NTSTATUS NTAPI HoldIoRequests(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{
    NTSTATUS               ntStatus;
    PIO_WORKITEM           item;
    PDEVICE_EXTENSION      deviceExtension;
    PWORKER_THREAD_CONTEXT context;

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequests: Entered\n"));

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    deviceExtension->QueueState = HoldRequests;

    context = (PWORKER_THREAD_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(WORKER_THREAD_CONTEXT));
    if(context)
    {
        item = IoAllocateWorkItem(DeviceObject);

        context->Irp = Irp;
        context->DeviceObject = DeviceObject;
        context->WorkItem = item;

        if (item)
        {
            IoMarkIrpPending(Irp);
            IoQueueWorkItem(item, HoldIoRequestsWorkerRoutine, DelayedWorkQueue, context);
            ntStatus = STATUS_PENDING;

        }

        else
        {
            FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequests: Failed to allocate memory for workitem\n"));
            ExFreePool(context);
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        }

    }

    else
    {
        FreeBT_DbgPrint(1, ("FBTUSB: HoldIoRequests: Failed to alloc memory for worker thread context\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

    }

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequests: Leaving\n"));

    return ntStatus;

}
Exemplo n.º 8
0
NTSTATUS LklPostRequest(PIRPCONTEXT irp_context, PIRP irp)
{

	ASSERT(irp_context);
	ASSERT(irp_context->id.type == IRP_CONTEXT && irp_context->id.size == sizeof(IRPCONTEXT));
	IoMarkIrpPending(irp);
	
	irp_context->work_item = IoAllocateWorkItem(irp_context->target_device);
	IoQueueWorkItem(irp_context->work_item, LklDequeueRequest, CriticalWorkQueue ,irp_context);

	FreeIrpContext(irp_context);
	return STATUS_PENDING;
}
Exemplo n.º 9
0
VOID
EXPORT
NdisQueueIoWorkItem(
    IN NDIS_HANDLE NdisIoWorkItemHandle,
    IN NDIS_IO_WORKITEM_ROUTINE Routine,
    IN PVOID WorkItemContext)
{
   PNDIS_IO_WORKITEM WorkItem = NdisIoWorkItemHandle;

   IoQueueWorkItem(WorkItem,
                   Routine,
                   DelayedWorkQueue,
                   WorkItemContext);
}
Exemplo n.º 10
0
static VOID
V4vStartDehibernateWorkItem(PDEVICE_OBJECT fdo)
{
    PIO_WORKITEM wi;

    TraceNotice(("starting dehibrination work item.\n"));

    wi = IoAllocateWorkItem(fdo);
    if (wi == NULL) {   
        TraceError(("failed to allocate dehibernate work item - out of memory.\n"));
        return;
    }

    IoQueueWorkItem(wi, V4vDehibernateWorkItem, DelayedWorkQueue, wi);
}
Exemplo n.º 11
0
VOID DokanStopEventNotificationThread(__in PDokanDCB Dcb) {
  PIO_WORKITEM workItem;

  DDbgPrint("==> DokanStopEventNotificationThread\n");

  workItem = IoAllocateWorkItem(Dcb->DeviceObject);
  if (workItem != NULL) {
    IoQueueWorkItem(workItem, DokanStopEventNotificationThreadInternal,
                    DelayedWorkQueue, workItem);
  } else {
    DDbgPrint("Can't create work item.");
  }

  DDbgPrint("<== DokanStopEventNotificationThread\n");
}
Exemplo n.º 12
0
VOID
NTAPI
WdmAudTimerRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Context)
{
    PWDMAUD_DEVICE_EXTENSION DeviceExtension;

    /* get device extension */
    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    if (InterlockedCompareExchange((volatile long *)&DeviceExtension->WorkItemActive, 1, 0) == 0)
    {
        /* queue work item */
        IoQueueWorkItem(DeviceExtension->WorkItem, WdmAudInitWorkerRoutine, DelayedWorkQueue, (PVOID)DeviceExtension);
    }
}
Exemplo n.º 13
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject,
                               IN PIRP Irp,
                               IN PVOID Context)
{
    PUNIQUE_ID_WORK_ITEM WorkItem = Context;

    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);

    /* Simply queue the work item */
    IoQueueWorkItem(WorkItem->WorkItem,
                    UniqueIdChangeNotifyWorker,
                    DelayedWorkQueue,
                    WorkItem);

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Exemplo n.º 14
0
static NTSTATUS vboxUsbPwrIoWaitCompletionAndPostAsync(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
{
    NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
    PVBOXUSB_IOASYNC_CTX pCtx = (PVBOXUSB_IOASYNC_CTX)vboxUsbMemAlloc(sizeof (*pCtx));
    Assert(pCtx);
    if (pCtx)
    {
        PIO_WORKITEM pWrkItem = IoAllocateWorkItem(pDevExt->pFDO);
        Assert(pWrkItem);
        if (pWrkItem)
        {
            pCtx->pWrkItem = pWrkItem;
            pCtx->pIrp = pIrp;
            IoMarkIrpPending(pIrp);
            IoQueueWorkItem(pWrkItem, vboxUsbPwrIoWaitCompletionAndPostAsyncWorker, DelayedWorkQueue, pCtx);
            return STATUS_PENDING;
        }
        vboxUsbMemFree(pCtx);
    }
    return Status;
}
Exemplo n.º 15
0
/* Return TRUE if it was a power key */
static BOOLEAN
HandlePowerKeys(
	IN PI8042_KEYBOARD_EXTENSION DeviceExtension)
{
	PKEYBOARD_INPUT_DATA InputData;
	ULONG KeyPress;

	InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1;
	if (!(InputData->Flags & KEY_E0))
		return FALSE;

	switch (InputData->MakeCode)
	{
		case KEYBOARD_POWER_CODE:
			KeyPress = SYS_BUTTON_POWER;
			break;
		case KEYBOARD_SLEEP_CODE:
			KeyPress = SYS_BUTTON_SLEEP;
			break;
		case KEYBOARD_WAKE_CODE:
			KeyPress = SYS_BUTTON_WAKE;
			break;
		default:
			return FALSE;
	}

    if (InputData->Flags & KEY_BREAK)
		/* We already took care of the key press */
		return TRUE;

	/* Our work can only be done at passive level, so use a workitem */
	DeviceExtension->NewCaps |= KeyPress;
	InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, KeyPress);
	IoQueueWorkItem(
		DeviceExtension->PowerWorkItem,
		&i8042PowerWorkItem,
		DelayedWorkQueue,
		DeviceExtension);
	return TRUE;
}
Exemplo n.º 16
0
/*
 * this function is for mainly deferring a task to the another thread because
 * we don't want to be in the scope of HAL lock.
 */
static int32_t
usbd_taskadd(irp *ip, unsigned type)
{
	device_t dev = IRP_NDIS_DEV(ip);
	struct ndis_softc *sc = device_get_softc(dev);
	struct ndisusb_task *nt;

	nt = malloc(sizeof(struct ndisusb_task), M_USBDEV, M_NOWAIT | M_ZERO);
	if (nt == NULL)
		return (USBD_STATUS_NO_MEMORY);
	nt->nt_type = type;
	nt->nt_ctx = ip;

	KeAcquireSpinLockAtDpcLevel(&sc->ndisusb_tasklock);
	InsertTailList((&sc->ndisusb_tasklist), (&nt->nt_tasklist));
	KeReleaseSpinLockFromDpcLevel(&sc->ndisusb_tasklock);

	IoQueueWorkItem(sc->ndisusb_taskitem,
	    (io_workitem_func)usbd_task_wrap, WORKQUEUE_CRITICAL, sc);

	return (USBD_STATUS_SUCCESS);
}
Exemplo n.º 17
0
static void
usbd_xfer_complete(struct ndis_softc *sc, struct ndisusb_ep *ne,
    struct ndisusb_xfer *nx, usb_error_t status)
{
	struct ndisusb_xferdone *nd;
	uint8_t irql;

	nd = malloc(sizeof(struct ndisusb_xferdone), M_USBDEV,
	    M_NOWAIT | M_ZERO);
	if (nd == NULL) {
		device_printf(sc->ndis_dev, "out of memory");
		return;
	}
	nd->nd_xfer = nx;
	nd->nd_status = status;

	KeAcquireSpinLock(&sc->ndisusb_xferdonelock, &irql);
	InsertTailList((&sc->ndisusb_xferdonelist), (&nd->nd_donelist));
	KeReleaseSpinLock(&sc->ndisusb_xferdonelock, irql);

	IoQueueWorkItem(sc->ndisusb_xferdoneitem,
	    (io_workitem_func)usbd_xfertask_wrap, WORKQUEUE_CRITICAL, sc);
}
Exemplo n.º 18
0
BOOLEAN
KWorkItem::
Start()
/*++

Routine Description:

    Enqueue this workitem and acquires a reference on the object.

Arguments:

    None.

Return Value:

    TRUE - a workitem was scheduled.

--*/
{
    //  Make sure construction succeeded.
    if( m_WorkItem )
    {
        //  Make sure the work item isn't already in flight and acquire the lock.
        //  This is to make sure this KWorkItem doesn't get destroyed until
        //  the callback is complete.
        if( Acquire() )
        {
            //  Schedule the work item.
            IoQueueWorkItem( m_WorkItem, &KWorkItem::Handler, m_QueueType, this );

            //  Note: Release() is called in Handler.
            return TRUE;
        }
    }
    return FALSE;
}
Exemplo n.º 19
0
VOID
DokanStopCheckThread(
    __in PDokanDCB	Dcb)
/*++

Routine Description:

	exits DokanTimeoutThread

--*/
{
    PIO_WORKITEM      workItem;

    DDbgPrint("==> DokanStopCheckThread\n");

    workItem = IoAllocateWorkItem(Dcb->DeviceObject);
    if (workItem != NULL) {
        IoQueueWorkItem(workItem, DokanStopCheckThreadInternal, DelayedWorkQueue, workItem);
    } else {
        DDbgPrint("Can't create work item.");
    }

    DDbgPrint("<== DokanStopCheckThread\n");
}
Exemplo n.º 20
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverEntry 
//      Installable driver initialization entry point.
//      This entry point is called directly by the I/O system.
//
//  Arguments:
//      IN  DriverObject
//              pointer to the driver object
//
//      IN  RegistryPath
//              pointer to a unicode string representing the path,
//              to driver-specific key in the registry.
//
//  Return Value:
//      Status
//
NTSTATUS DriverEntry(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS                            status;
    PDEVICE_OBJECT                      deviceObject;
    PTESTDRV_DEVICE_EXTENSION   deviceExtension;
    UNICODE_STRING                      ntName;
    UNICODE_STRING                      win32Name;

    testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++");
    testdrvDebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__);

#ifdef DBG
//    DbgBreakPoint();
#endif

#ifdef TESTDRV_WMI_TRACE 
    WPP_INIT_TRACING(DriverObject, RegistryPath);
#endif

    RtlZeroMemory(&g_Data, sizeof(TESTDRV_DATA));

    // save registry path
    g_Data.RegistryPath.Length = RegistryPath->Length;
    g_Data.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
    g_Data.RegistryPath.Buffer = (PWCHAR)ExAllocatePoolWithTag(
                                            PagedPool,
                                            g_Data.RegistryPath.MaximumLength,
                                            TESTDRV_POOL_TAG
                                            );

    if (g_Data.RegistryPath.Buffer == NULL)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__": Failed to allocate memory for RegistryPath");

        return status;
    }

    RtlCopyUnicodeString(&g_Data.RegistryPath, RegistryPath);

    // setup our dispatch function table in the driver object
    DriverObject->MajorFunction[IRP_MJ_CREATE] = testdrvCreateDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = testdrvCloseDispatch;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = testdrvDeviceIoControlDispatch;
    DriverObject->MajorFunction[IRP_MJ_READ] = testdrvReadDispatch;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = testdrvWriteDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = testdrvCleanupDispatch;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = testdrvShutdownDispatch;
    DriverObject->DriverUnload = testdrvUnload;

    // initialize device name
    RtlInitUnicodeString(&ntName, L"\\Device\\testdrvDevice");

	ExInitializeFastMutex(&qemu_output_lock);

	// Create our function device object.
    status = IoCreateDevice(
                DriverObject,
                sizeof (TESTDRV_DEVICE_EXTENSION),
                &ntName,
                FILE_DEVICE_UNKNOWN,
                0,
                FALSE,
                &deviceObject
                );

    if (!NT_SUCCESS (status)) 
    {
        ExFreePool(g_Data.RegistryPath.Buffer);
        g_Data.RegistryPath.Buffer = NULL;

        testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. STATUS %x", status);

        return status;
    }

    // Initialize the device extension.
    deviceExtension = (PTESTDRV_DEVICE_EXTENSION)deviceObject->DeviceExtension;

    // Zero the memory
    RtlZeroMemory(deviceExtension, sizeof(TESTDRV_DEVICE_EXTENSION));

    // save our device object pointer
    deviceExtension->DeviceObject = deviceObject;

    // This flag sets the buffering method for reads and writes
    // to METHOD_DIRECT.  IOCTLs are handled by IO control codes
    // independent of the value of this flag.
    deviceObject->Flags |= DO_DIRECT_IO;

    RtlInitUnicodeString(&win32Name, L"\\??\\testdrvDevice");
    status = IoCreateSymbolicLink(&win32Name, &ntName);
    if (!NT_SUCCESS(status))
    {
        IoDeleteDevice(deviceObject);

        ExFreePool(g_Data.RegistryPath.Buffer);
        g_Data.RegistryPath.Buffer = NULL;

        return status;
    }

    IoRegisterShutdownNotification(deviceObject);

	InitializeListHead(&ModuleListHead);


	g_WorkItem = IoAllocateWorkItem(deviceObject);
	if(!g_WorkItem)
		return STATUS_INSUFFICIENT_RESOURCES;

	IoQueueWorkItem(g_WorkItem, GetSysModInfo, DelayedWorkQueue, g_WorkItem);
	//UpdateSysModuleList();


	PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
	PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE);


    testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);

    return status;
}
NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice,
                               _In_ IO_WORKITEM_ROUTINE* pWorkItemFn,
                               _In_ CLASSIFY_DATA* pClassifyData,
                               _In_ REDIRECT_DATA* pRedirectData,
                               _In_opt_ VOID* pContext)               /* 0 */
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprWorkItemQueue()\n");

#endif /// DBG
   
   NT_ASSERT(pWDMDevice);
   NT_ASSERT(pWorkItemFn);
   NT_ASSERT(pClassifyData);
   NT_ASSERT(pRedirectData);

   NTSTATUS       status        = STATUS_SUCCESS;
   PIO_WORKITEM   pIOWorkItem   = 0;
   WORKITEM_DATA* pWorkItemData = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy

   pIOWorkItem = IoAllocateWorkItem(pWDMDevice);
   if(pIOWorkItem == 0)
   {
      status = STATUS_UNSUCCESSFUL;

      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

#pragma warning(pop)

   status = KrnlHlprWorkItemDataCreate(&pWorkItemData,
                                       pClassifyData,
                                       pRedirectData,
                                       pIOWorkItem,
                                       pContext);
   HLPR_BAIL_ON_FAILURE(status);

   IoQueueWorkItem(pWorkItemData->pIOWorkItem,
                   pWorkItemFn,
                   DelayedWorkQueue,
                   (PVOID)pWorkItemData);

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS &&
      pWorkItemData)
      KrnlHlprWorkItemDataDestroy(&pWorkItemData);

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprWorkItemQueue() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}
Exemplo n.º 22
0
/*
 * Runs the keyboard IOCTL_INTERNAL dispatch.
 */
NTSTATUS NTAPI
i8042KbdInternalDeviceControl(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp)
{
	PIO_STACK_LOCATION Stack;
	PI8042_KEYBOARD_EXTENSION DeviceExtension;
	NTSTATUS Status;

	Stack = IoGetCurrentIrpStackLocation(Irp);
	Irp->IoStatus.Information = 0;
	DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension;

	switch (Stack->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_INTERNAL_KEYBOARD_CONNECT:
		{
			SIZE_T Size;
			PIO_WORKITEM WorkItem = NULL;
			PI8042_HOOK_WORKITEM WorkItemData = NULL;

			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
			if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA))
			{
				Status = STATUS_INVALID_PARAMETER;
				goto cleanup;
			}

			DeviceExtension->KeyboardData =
				*((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);

			/* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */
			WorkItem = IoAllocateWorkItem(DeviceObject);
			if (!WorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			WorkItemData = ExAllocatePoolWithTag(
				NonPagedPool,
				sizeof(I8042_HOOK_WORKITEM),
				I8042PRT_TAG);
			if (!WorkItemData)
			{
				WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
				Status = STATUS_NO_MEMORY;
				goto cleanup;
			}
			WorkItemData->WorkItem = WorkItem;
			WorkItemData->Irp = Irp;

			/* Initialize extension */
			DeviceExtension->Common.Type = Keyboard;
			Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA);
			DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag(
				NonPagedPool,
				Size,
				I8042PRT_TAG);
			if (!DeviceExtension->KeyboardBuffer)
			{
				WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
				Status = STATUS_NO_MEMORY;
				goto cleanup;
			}
			RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size);
			KeInitializeDpc(
				&DeviceExtension->DpcKeyboard,
				i8042KbdDpcRoutine,
				DeviceExtension);
			DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject);
			if (!DeviceExtension->PowerWorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject);
			if (!DeviceExtension->DebugWorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension;
			DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED;

            i8042InitializeKeyboardAttributes(DeviceExtension);

			IoMarkIrpPending(Irp);
			/* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */
			DeviceExtension->KeyboardHook.QueueKeyboardPacket = i8042KbdQueuePacket;
			DeviceExtension->KeyboardHook.CallContext = DeviceExtension;
			IoQueueWorkItem(WorkItem,
				i8042SendHookWorkItem,
				DelayedWorkQueue,
				WorkItemData);
			Status = STATUS_PENDING;
			break;

cleanup:
			if (DeviceExtension->KeyboardBuffer)
				ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG);
			if (DeviceExtension->PowerWorkItem)
				IoFreeWorkItem(DeviceExtension->PowerWorkItem);
			if (DeviceExtension->DebugWorkItem)
				IoFreeWorkItem(DeviceExtension->DebugWorkItem);
			if (WorkItem)
				IoFreeWorkItem(WorkItem);
			if (WorkItemData)
				ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
			break;
		}
		case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n");
			/* MSDN says that operation is to implemented.
			 * To implement it, we just have to do:
			 * DeviceExtension->KeyboardData.ClassService = NULL;
			 */
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n");
			/* Nothing to do here */
			Status = STATUS_SUCCESS;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
		{
		    PKEYBOARD_ATTRIBUTES KeyboardAttributes;

            /* FIXME: KeyboardAttributes are not initialized anywhere */
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
			if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

            KeyboardAttributes = Irp->AssociatedIrp.SystemBuffer;
            *KeyboardAttributes = DeviceExtension->KeyboardAttributes;

			Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES);
			Status = STATUS_SUCCESS;
			break;

			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
		{
			DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n");
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_SET_TYPEMATIC:
		{
			DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n");
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n");

			/* We should check the UnitID, but it's kind of pointless as
			 * all keyboards are supposed to have the same one
			 */
			if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					Irp->AssociatedIrp.SystemBuffer,
					&IndicatorTranslation,
					sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));
				Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
				Status = STATUS_SUCCESS;
			}
			break;
		}
		case IOCTL_KEYBOARD_QUERY_INDICATORS:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n");

			if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					Irp->AssociatedIrp.SystemBuffer,
					&DeviceExtension->KeyboardIndicators,
					sizeof(KEYBOARD_INDICATOR_PARAMETERS));
				Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
				Status = STATUS_SUCCESS;
			}
			break;
		}
		case IOCTL_KEYBOARD_SET_INDICATORS:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n");

			if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					&DeviceExtension->KeyboardIndicators,
					Irp->AssociatedIrp.SystemBuffer,
					sizeof(KEYBOARD_INDICATOR_PARAMETERS));
				Status = STATUS_PENDING;
				IoMarkIrpPending(Irp);
				IoStartPacket(DeviceObject, Irp, NULL, NULL);
			}
			break;
		}
		default:
		{
			ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
				Stack->Parameters.DeviceIoControl.IoControlCode);
			ASSERT(FALSE);
			return ForwardIrpAndForget(DeviceObject, Irp);
		}
	}

	Irp->IoStatus.Status = Status;
	if (Status != STATUS_PENDING)
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return Status;
}
Exemplo n.º 23
0
NTSTATUS
FileDiskInitializeLogicalUnit(
    __in PNDAS_LOGICALUNIT_DESCRIPTOR LogicalUnitDescriptor,
    __in PNDAS_LOGICALUNIT_EXTENSION LogicalUnitExtension)
{
    NTSTATUS status;
    PFILEDISK_EXTENSION fileDiskExtension;
    PFILEDISK_DESCRIPTOR fileDiskDescriptor;
    size_t dataFilePathLength;
    BOOLEAN newDataFileCreated;

    PAGED_CODE();

    fileDiskExtension = FileDiskGetExtension(LogicalUnitExtension);

    if (sizeof(NDAS_LOGICALUNIT_DESCRIPTOR) != LogicalUnitDescriptor->Version)
    {
        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL,
                      "LogicalUnitDescriptor version is invalid. Version=%d, Expected=%d\n",
                      LogicalUnitDescriptor->Version,
                      sizeof(NDAS_LOGICALUNIT_DESCRIPTOR));

        return STATUS_INVALID_PARAMETER;
    }
    if (LogicalUnitDescriptor->Size < FIELD_OFFSET(FILEDISK_DESCRIPTOR, FilePath))
    {
        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL,
                      "FileDiskDescriptor Size is invalid. Size=%d, Expected=%d\n",
                      LogicalUnitDescriptor->Size,
                      sizeof(FILEDISK_DESCRIPTOR));

        return STATUS_INVALID_PARAMETER;
    }

    NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL,
                  "Initializing FileDisk Logical Unit\n");

    fileDiskDescriptor = (PFILEDISK_DESCRIPTOR) LogicalUnitDescriptor;

    fileDiskExtension->FileDiskFlags = fileDiskDescriptor->FileDiskFlags;

    status = RtlStringCbLengthW(
                 fileDiskDescriptor->FilePath,
                 LogicalUnitDescriptor->Size - FIELD_OFFSET(FILEDISK_DESCRIPTOR, FilePath),
                 &dataFilePathLength);

    if (!NT_SUCCESS(status))
    {
        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL,
                      "FileDiskDescriptor FilePath length is invalid. Status=%08X\n",
                      status);

        return status;
    }

    NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION,
                  "FilePath=%ws\n", fileDiskDescriptor->FilePath);

    dataFilePathLength += sizeof(WCHAR); // additional NULL

    fileDiskExtension->FilePath.Buffer = (PWSTR) ExAllocatePoolWithTag(
            NonPagedPool,
            dataFilePathLength,
            FILEDISK_EXT_TAG);

    if (NULL == fileDiskExtension->FilePath.Buffer)
    {
        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING,
                      "Memory allocation failed for data file path (%d bytes).\n",
                      dataFilePathLength);

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyMemory(
        fileDiskExtension->FilePath.Buffer,
        fileDiskDescriptor->FilePath,
        dataFilePathLength);

    fileDiskExtension->FilePath.Length = dataFilePathLength - sizeof(WCHAR);
    fileDiskExtension->FilePath.MaximumLength = (USHORT)dataFilePathLength;

    fileDiskExtension->LogicalUnitAddress = LogicalUnitDescriptor->Address.Address;
    fileDiskExtension->LogicalBlockAddress.QuadPart = fileDiskDescriptor->LogicalBlockAddress.QuadPart;
    fileDiskExtension->BytesPerBlock = fileDiskDescriptor->BytesPerBlock;

    fileDiskExtension->ThreadShouldStop = FALSE;

    KeInitializeEvent(
        &fileDiskExtension->ThreadNotificationEvent,
        NotificationEvent,
        FALSE);

    KeInitializeEvent(
        &fileDiskExtension->ThreadCompleteEvent,
        NotificationEvent,
        FALSE);

    FileDiskInitializeIoScsiCapabilities(fileDiskExtension);
    FileDiskInitializeInquiryData(fileDiskExtension);

    fileDiskExtension->StorageBusType = BusTypeScsi;
    fileDiskExtension->StorageBusMajorVersion = 2;
    fileDiskExtension->StorageBusMinorVersion = 0;

    status = FileDiskCreateDataFile(
                 fileDiskExtension,
                 &fileDiskExtension->FilePath,
                 &newDataFileCreated);

    if (!NT_SUCCESS(status))
    {
        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING,
                      "FileDiskCreateDataFile failed, Status=%08X\n",
                      status);

        goto error1;
    }

    //
    // For Windows 2000, PsCreateSystemThread should be called
    // from the system process context.
    //
    if (IoIsWdmVersionAvailable(0x01, 0x20))
    {
        FileDiskCreateThreadWorkItemRoutine(NULL, fileDiskExtension);
    }
    else
    {
        PIO_WORKITEM workItem;
        workItem = NdasPortExAllocateWorkItem(LogicalUnitExtension);
        if (NULL == workItem)
        {
            NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING,
                          "NdasPortExAllocateWorkItem failed with out of resource error.\n");

            status = STATUS_INSUFFICIENT_RESOURCES;

            goto error2;
        }

        IoQueueWorkItem(
            workItem,
            FileDiskCreateThreadWorkItemRoutine,
            DelayedWorkQueue,
            fileDiskExtension);

        KeWaitForSingleObject(
            &fileDiskExtension->ThreadCompleteEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL);

        IoFreeWorkItem(workItem);
    }

    if (!NT_SUCCESS(fileDiskExtension->ThreadStatus))
    {
        status = fileDiskExtension->ThreadStatus;

        NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION,
                      "FileDisk file creation failed, Status=%08X\n",
                      status);

        goto error3;
    }

    NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION,
                  "FileDisk created successfully at LogicalUnitAddress=%08X.\n",
                  fileDiskExtension->LogicalUnitAddress);

    return STATUS_SUCCESS;

error3:
error2:

    FileDiskCloseDataFile(fileDiskExtension);

    if (newDataFileCreated)
    {
        FileDiskDeleteDataFile(&fileDiskExtension->FilePath);
    }

error1:

    ExFreePoolWithTag(
        fileDiskExtension->FilePath.Buffer,
        FILEDISK_EXT_TAG);

    fileDiskExtension->FilePath.Buffer = NULL;
    fileDiskExtension->FilePath.Length = 0;
    fileDiskExtension->FilePath.MaximumLength = 0;

    return status;
}
Exemplo n.º 24
0
VOID
CdQueueClose (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN ULONG UserReference,
    IN BOOLEAN DelayedClose
    )

/*++

Routine Description:

    This routine is called to queue a request to either the async or delayed
    close queue.  For the delayed queue we need to allocate a smaller
    structure to contain the information about the file object.  We do
    that so we don't put the larger IrpContext structures into this long
    lived queue.  If we can allocate this structure then we put this
    on the async queue instead.

Arguments:

    Fcb - Fcb for this file object.

    UserReference - Number of user references for this file object.  This is
        zero for an internal stream.

    DelayedClose - Indicates whether this should go on the async or delayed
        close queue.

Return Value:

    None

--*/

{
    PIRP_CONTEXT_LITE IrpContextLite = NULL;
    BOOLEAN StartWorker = FALSE;

    PAGED_CODE();

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_FCB( Fcb );

    //
    //  Start with the delayed queue request.  We can move this to the async
    //  queue if there is an allocation failure.
    //

    if (DelayedClose) {

        //
        //  Try to allocate non-paged pool for the IRP_CONTEXT_LITE.
        //

        IrpContextLite = CdCreateIrpContextLite( IrpContext );
    }

    //
    //  We want to clear the top level context in this thread if
    //  necessary.  Call our cleanup routine to do the work.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
    CdCleanupIrpContext( IrpContext, TRUE );

    //
    //  Synchronize with the CdData lock.
    //

    CdLockCdData();

    //
    //  If we have an IrpContext then put the request on the delayed close queue.
    //

    if (IrpContextLite != NULL) {

        //
        //  Initialize the IrpContextLite.
        //

        IrpContextLite->NodeTypeCode = CDFS_NTC_IRP_CONTEXT_LITE;
        IrpContextLite->NodeByteSize = sizeof( IRP_CONTEXT_LITE );
        IrpContextLite->Fcb = Fcb;
        IrpContextLite->UserReference = UserReference;
        IrpContextLite->RealDevice = IrpContext->RealDevice;

        //
        //  Add this to the delayed close list and increment
        //  the count.
        //

        InsertTailList( &CdData.DelayedCloseQueue,
                        &IrpContextLite->DelayedCloseLinks );

        CdData.DelayedCloseCount += 1;

        //
        //  If we are above our threshold then start the delayed
        //  close operation.
        //

        if (CdData.DelayedCloseCount > CdData.MaxDelayedCloseCount) {

            CdData.ReduceDelayedClose = TRUE;

            if (!CdData.FspCloseActive) {

                CdData.FspCloseActive = TRUE;
                StartWorker = TRUE;
            }
        }

        //
        //  Unlock the CdData.
        //

        CdUnlockCdData();

        //
        //  Cleanup the IrpContext.
        //

        CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );

    //
    //  Otherwise drop into the async case below.
    //

    } else {

        //
        //  Store the information about the file object into the IrpContext.
        //

        IrpContext->Irp = (PIRP) Fcb;
        IrpContext->ExceptionStatus = (NTSTATUS) UserReference;

        //
        //  Add this to the async close list and increment the count.
        //

        InsertTailList( &CdData.AsyncCloseQueue,
                        &IrpContext->WorkQueueItem.List );

        CdData.AsyncCloseCount += 1;

        //
        //  Remember to start the Fsp close thread if not currently started.
        //

        if (!CdData.FspCloseActive) {

            CdData.FspCloseActive = TRUE;

            StartWorker = TRUE;
        }

        //
        //  Unlock the CdData.
        //

        CdUnlockCdData();
    }

    //
    //  Start the FspClose thread if we need to.
    //

    if (StartWorker) {

        IoQueueWorkItem( CdData.CloseItem, CdCloseWorker, CriticalWorkQueue, NULL );
    }

    //
    //  Return to our caller.
    //

    return;
}
Exemplo n.º 25
0
NDIS_STATUS
XenNet_SetInformation(
  IN NDIS_HANDLE MiniportAdapterContext,
  IN NDIS_OID Oid,
  IN PVOID InformationBuffer,
  IN ULONG InformationBufferLength,
  OUT PULONG BytesRead,
  OUT PULONG BytesNeeded
  )
{
  NTSTATUS status;
  ULONG i;
  struct xennet_info *xi = MiniportAdapterContext;
  PULONG64 data = InformationBuffer;
  PNDIS_TASK_OFFLOAD_HEADER ntoh;
  PNDIS_TASK_OFFLOAD nto;
  PNDIS_TASK_TCP_IP_CHECKSUM nttic = NULL;
  PNDIS_TASK_TCP_LARGE_SEND nttls = NULL;
  UCHAR *multicast_list;
  int offset;

  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));

  UNREFERENCED_PARAMETER(MiniportAdapterContext);
  UNREFERENCED_PARAMETER(InformationBufferLength);
  UNREFERENCED_PARAMETER(BytesRead);
  UNREFERENCED_PARAMETER(BytesNeeded);

  switch(Oid)
  {
    case OID_GEN_SUPPORTED_LIST:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_SUPPORTED_LIST\n"));
      break;
    case OID_GEN_HARDWARE_STATUS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_HARDWARE_STATUS\n"));
      break;
    case OID_GEN_MEDIA_SUPPORTED:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MEDIA_SUPPORTED\n"));
      break;
    case OID_GEN_MEDIA_IN_USE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MEDIA_IN_USE\n"));
      break;
    case OID_GEN_MAXIMUM_LOOKAHEAD:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD %d\n", *(ULONG *)data));
      break;
    case OID_GEN_MAXIMUM_FRAME_SIZE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MAXIMUM_FRAME_SIZE\n"));
      break;
    case OID_GEN_LINK_SPEED:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_LINK_SPEED\n"));
      break;
    case OID_GEN_TRANSMIT_BUFFER_SPACE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_TRANSMIT_BUFFER_SPACE\n"));
      break;
    case OID_GEN_RECEIVE_BUFFER_SPACE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_RECEIVE_BUFFER_SPACE\n"));
      break;
    case OID_GEN_TRANSMIT_BLOCK_SIZE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_TRANSMIT_BLOCK_SIZE\n"));
      break;
    case OID_GEN_RECEIVE_BLOCK_SIZE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_RECEIVE_BLOCK_SIZE\n"));
      break;
    case OID_GEN_VENDOR_ID:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_VENDOR_ID\n"));
      break;
    case OID_GEN_VENDOR_DESCRIPTION:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
      break;
    case OID_GEN_CURRENT_PACKET_FILTER:
      KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER (xi = %p)\n", xi));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_DIRECTED)
        KdPrint(("  NDIS_PACKET_TYPE_DIRECTED\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_MULTICAST)
        KdPrint(("  NDIS_PACKET_TYPE_MULTICAST\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_MULTICAST)
        KdPrint(("  NDIS_PACKET_TYPE_ALL_MULTICAST\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_BROADCAST)
        KdPrint(("  NDIS_PACKET_TYPE_BROADCAST\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_PROMISCUOUS)
        KdPrint(("  NDIS_PACKET_TYPE_PROMISCUOUS\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
        KdPrint(("  NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_LOCAL)
        KdPrint(("  NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));  
      if (*(ULONG *)data & NDIS_PACKET_TYPE_FUNCTIONAL)
        KdPrint(("  NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n"));
      if (*(ULONG *)data & NDIS_PACKET_TYPE_GROUP)
        KdPrint(("  NDIS_PACKET_TYPE_GROUP (not supported)\n"));
      if (*(ULONG *)data & ~SUPPORTED_PACKET_FILTERS)
      {
        status = NDIS_STATUS_NOT_SUPPORTED;
        KdPrint(("  returning NDIS_STATUS_NOT_SUPPORTED\n"));
        break;
      }
      xi->packet_filter = *(ULONG *)data;
      status = NDIS_STATUS_SUCCESS;
      break;
    case OID_GEN_CURRENT_LOOKAHEAD:
      xi->current_lookahead = *(ULONG *)data;
      KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi));
      status = NDIS_STATUS_SUCCESS;
      break;
    case OID_GEN_DRIVER_VERSION:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_DRIVER_VERSION\n"));
      break;
    case OID_GEN_MAXIMUM_TOTAL_SIZE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
      break;
    case OID_GEN_PROTOCOL_OPTIONS:
      KdPrint(("Unsupported set OID_GEN_PROTOCOL_OPTIONS\n"));
      // TODO - actually do this...
      status = NDIS_STATUS_SUCCESS;
      break;
    case OID_GEN_MAC_OPTIONS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MAC_OPTIONS\n"));
      break;
    case OID_GEN_MEDIA_CONNECT_STATUS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MEDIA_CONNECT_STATUS\n"));
      break;
    case OID_GEN_MAXIMUM_SEND_PACKETS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_MAXIMUM_SEND_PACKETS\n"));
      break;
    case OID_GEN_XMIT_OK:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_XMIT_OK\n"));
      break;
    case OID_GEN_RCV_OK:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_RCV_OK\n"));
      break;
    case OID_GEN_XMIT_ERROR:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_XMIT_ERROR\n"));
      break;
    case OID_GEN_RCV_ERROR:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_RCV_ERROR\n"));
      break;
    case OID_GEN_RCV_NO_BUFFER:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_GEN_RCV_NO_BUFFER\n"));
      break;
    case OID_802_3_PERMANENT_ADDRESS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_802_3_PERMANENT_ADDRESS\n"));
      break;
    case OID_802_3_CURRENT_ADDRESS:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_802_3_CURRENT_ADDRESS\n"));
      break;
    case OID_802_3_MULTICAST_LIST:
      KdPrint(("     Set OID_802_3_MULTICAST_LIST\n"));
      KdPrint(("       Length = %d\n", InformationBufferLength));
      KdPrint(("       Entries = %d\n", InformationBufferLength / 6));
      if (InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
      {
        status = NDIS_STATUS_MULTICAST_FULL;
        break;
      }
      
      if (InformationBufferLength % 6 != 0)
      {
        status = NDIS_STATUS_MULTICAST_FULL;
        break;
      }
      multicast_list = InformationBuffer;
      for (i = 0; i < InformationBufferLength / 6; i++)
      {
        if (!(multicast_list[i * 6 + 0] & 0x01))
        {
          KdPrint(("       Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
            (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1], 
            (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3], 
            (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]));
          /* the docs say that we should return NDIS_STATUS_MULTICAST_FULL if we get an invalid multicast address but I'm not sure if that's the case... */
        }
      }
      memcpy(xi->multicast_list, InformationBuffer, InformationBufferLength);
      xi->multicast_list_size = InformationBufferLength / 6;
      status = NDIS_STATUS_SUCCESS;
      break;
    case OID_802_3_MAXIMUM_LIST_SIZE:
      status = NDIS_STATUS_NOT_SUPPORTED;
      KdPrint(("Unsupported set OID_802_3_MAXIMUM_LIST_SIZE\n"));
      break;
    case OID_TCP_TASK_OFFLOAD:
      status = NDIS_STATUS_SUCCESS;
      KdPrint(("Set OID_TCP_TASK_OFFLOAD\n"));
      // we should disable everything here, then enable what has been set
      ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
      if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION)
      {
        KdPrint(("Invalid version (%d passed but must be %d)\n", ntoh->Version, NDIS_TASK_OFFLOAD_VERSION));
        status = NDIS_STATUS_INVALID_DATA;
        break;
      }
      if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION || ntoh->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER))
      {
        KdPrint(("Invalid size (%d passed but must be %d)\n", ntoh->Size, sizeof(NDIS_TASK_OFFLOAD_HEADER)));
        status = NDIS_STATUS_INVALID_DATA;
        break;
      }
      *BytesRead = sizeof(NDIS_TASK_OFFLOAD_HEADER);
      offset = ntoh->OffsetFirstTask;
      nto = (PNDIS_TASK_OFFLOAD)ntoh; // not really, just to get the first offset right
      while (offset != 0)
      {
        *BytesRead += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer);
        nto = (PNDIS_TASK_OFFLOAD)(((PUCHAR)nto) + offset);
        switch (nto->Task)
        {
        case TcpIpChecksumNdisTask:
          *BytesRead += sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
          nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
          KdPrint(("TcpIpChecksumNdisTask\n"));
          KdPrint(("  V4Transmit.IpOptionsSupported  = %d\n", nttic->V4Transmit.IpOptionsSupported));
          KdPrint(("  V4Transmit.TcpOptionsSupported = %d\n", nttic->V4Transmit.TcpOptionsSupported));
          KdPrint(("  V4Transmit.TcpChecksum         = %d\n", nttic->V4Transmit.TcpChecksum));
          KdPrint(("  V4Transmit.UdpChecksum         = %d\n", nttic->V4Transmit.UdpChecksum));
          KdPrint(("  V4Transmit.IpChecksum          = %d\n", nttic->V4Transmit.IpChecksum));
          KdPrint(("  V4Receive.IpOptionsSupported   = %d\n", nttic->V4Receive.IpOptionsSupported));
          KdPrint(("  V4Receive.TcpOptionsSupported  = %d\n", nttic->V4Receive.TcpOptionsSupported));
          KdPrint(("  V4Receive.TcpChecksum          = %d\n", nttic->V4Receive.TcpChecksum));
          KdPrint(("  V4Receive.UdpChecksum          = %d\n", nttic->V4Receive.UdpChecksum));
          KdPrint(("  V4Receive.IpChecksum           = %d\n", nttic->V4Receive.IpChecksum));
          KdPrint(("  V6Transmit.IpOptionsSupported  = %d\n", nttic->V6Transmit.IpOptionsSupported));
          KdPrint(("  V6Transmit.TcpOptionsSupported = %d\n", nttic->V6Transmit.TcpOptionsSupported));
          KdPrint(("  V6Transmit.TcpChecksum         = %d\n", nttic->V6Transmit.TcpChecksum));
          KdPrint(("  V6Transmit.UdpChecksum         = %d\n", nttic->V6Transmit.UdpChecksum));
          KdPrint(("  V6Receive.IpOptionsSupported   = %d\n", nttic->V6Receive.IpOptionsSupported));
          KdPrint(("  V6Receive.TcpOptionsSupported  = %d\n", nttic->V6Receive.TcpOptionsSupported));
          KdPrint(("  V6Receive.TcpChecksum          = %d\n", nttic->V6Receive.TcpChecksum));
          KdPrint(("  V6Receive.UdpChecksum          = %d\n", nttic->V6Receive.UdpChecksum));
          /* check for stuff we outright don't support */
          if (nttic->V6Transmit.IpOptionsSupported ||
            nttic->V6Transmit.TcpOptionsSupported ||
            nttic->V6Transmit.TcpChecksum ||
            nttic->V6Transmit.UdpChecksum ||
            nttic->V6Receive.IpOptionsSupported ||
            nttic->V6Receive.TcpOptionsSupported ||
            nttic->V6Receive.TcpChecksum ||
            nttic->V6Receive.UdpChecksum)
          {
            KdPrint(("IPv6 offload not supported\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttic = NULL;
            break;
          }
          if (nttic->V4Transmit.IpOptionsSupported ||
            nttic->V4Transmit.IpChecksum)
          {
            KdPrint(("IPv4 IP Transmit offload not supported\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttic = NULL;
            break;
          }
          if (nttic->V4Receive.IpOptionsSupported &&
            !nttic->V4Receive.IpChecksum)
          {
            KdPrint(("Invalid combination\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttic = NULL;
            break;
          }
          if (nttic->V4Transmit.TcpOptionsSupported &&
            !nttic->V4Transmit.TcpChecksum)
          {
            KdPrint(("Invalid combination\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttic = NULL;
            break;
          }
          if (nttic->V4Receive.TcpOptionsSupported &&
            !nttic->V4Receive.TcpChecksum)
          {
            KdPrint(("Invalid combination\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttic = NULL;
            break;
          }
          break;
        case TcpLargeSendNdisTask:
          *BytesRead += sizeof(NDIS_TASK_TCP_LARGE_SEND);
          KdPrint(("TcpLargeSendNdisTask\n"));
          nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
          KdPrint(("  MaxOffLoadSize                 = %d\n", nttls->MaxOffLoadSize));
          KdPrint(("  MinSegmentCount                = %d\n", nttls->MinSegmentCount));
          KdPrint(("  TcpOptions                     = %d\n", nttls->TcpOptions));
          KdPrint(("  IpOptions                      = %d\n", nttls->IpOptions));
          if (nttls->MinSegmentCount != MIN_LARGE_SEND_SEGMENTS)
          {
            KdPrint(("     MinSegmentCount should be %d\n", MIN_LARGE_SEND_SEGMENTS));
            status = NDIS_STATUS_INVALID_DATA;
            nttls = NULL;
            break;
          }
          if (nttls->IpOptions)
          {
            KdPrint(("     IpOptions not supported\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttls = NULL;
            break;
          }
          if (nttls->TcpOptions)
          {
            KdPrint(("     TcpOptions not supported\n"));
            status = NDIS_STATUS_INVALID_DATA;
            nttls = NULL;
            break;
          }
          break;
        default:
          KdPrint(("     Unknown Task %d\n", nto->Task));
        }
        offset = nto->OffsetNextTask;
      }
      if (nttic != NULL)
        xi->setting_csum = *nttic;
      else
      {
        RtlZeroMemory(&xi->setting_csum, sizeof(NDIS_TASK_TCP_IP_CHECKSUM));
        KdPrint(("     csum offload disabled\n", nto->Task));
      }        
      if (nttls != NULL)
        xi->setting_max_offload = nttls->MaxOffLoadSize;
      else
      {
        xi->setting_max_offload = 0;
        KdPrint(("     LSO disabled\n", nto->Task));
      }
      break;
    case OID_PNP_SET_POWER:
      KdPrint(("     Set OID_PNP_SET_POWER\n"));
      xi->new_power_state = *(PNDIS_DEVICE_POWER_STATE)InformationBuffer;
      IoQueueWorkItem(xi->power_workitem, XenNet_SetPower, DelayedWorkQueue, xi);
      status = NDIS_STATUS_PENDING;
      break;
    default:
      KdPrint(("Set Unknown OID 0x%x\n", Oid));
      status = NDIS_STATUS_NOT_SUPPORTED;
      break;
  }
  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  return status;
}
Exemplo n.º 26
0
VOID
LspStartIo(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp)
{
	NTSTATUS status;
	lsp_status_t lspStatus;
	PIO_STACK_LOCATION irpStack;
	PDEVICE_EXTENSION deviceExtension;

	LSP_KDPRINT(("LspStartIo: Irp=%p\n", Irp));

	irpStack = IoGetCurrentIrpStackLocation(Irp);
	deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

	switch (irpStack->MajorFunction)
	{
	case IRP_MJ_CREATE:
		{
			deviceExtension->LspTransferCount = 0;
			deviceExtension->CurrentIrp = NULL;

			IoQueueWorkItem(
				deviceExtension->CloseWorkItem,
				LspCreateWorkItem,
				DelayedWorkQueue,
				Irp);
		}
		break;
	case IRP_MJ_CLOSE:
		{
			deviceExtension->LspTransferCount = 0;
			deviceExtension->CurrentIrp = NULL;

			IoQueueWorkItem(
				deviceExtension->CloseWorkItem, 
				LspCloseWorkItem, 
				DelayedWorkQueue, 
				Irp);
		}
		break;
	case IRP_MJ_READ:
		{
			LARGE_INTEGER location;
			PVOID dataBuffer;
			ULONG dataLength;
			KIRQL oldIrql;

			static ULONG random = 0;

			location.QuadPart = random++;

			dataLength = irpStack->Parameters.Read.Length;
			dataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

			if (NULL == dataBuffer)
			{
				Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
				Irp->IoStatus.Information = 0;
				IoCompleteRequest(Irp, IO_NO_INCREMENT);
				return;
			}

			if (0 != (dataLength % 512))
			{
				Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
				Irp->IoStatus.Information = 0;
				IoCompleteRequest(Irp, IO_NO_INCREMENT);
				return;
			}

			// KeAcquireSpinLock(&deviceExtension->LspLock, &oldIrql);

			deviceExtension->LspTransferCount = 0;
			deviceExtension->CurrentIrp = Irp;

			deviceExtension->LspStatus = lsp_ide_read(
				deviceExtension->LspHandle,
				(lsp_large_integer_t*)&location,
				(lsp_int16_t)(dataLength >> 9),
				dataBuffer,
				dataLength);

			Irp->IoStatus.Information = dataLength;
			// KeReleaseSpinLock(&deviceExtension->LspLock, oldIrql);

			status = LspProcessNext(DeviceObject, &deviceExtension->LspStatus);
			if (STATUS_PENDING != status)
			{
				deviceExtension->CurrentIrp = NULL;
				Irp->IoStatus.Status = status;
				IoCompleteRequest(Irp, IO_NO_INCREMENT);
				IoStartNextPacket(DeviceObject, TRUE);
				return;
			}
		}
		break;
	default:
		ASSERT(FALSE);
	}
}
Exemplo n.º 27
0
VOID	WSCatcherPacketCallback(PVOID pb)
{
	PNDIS_PACKET	pPacket	=	(PNDIS_PACKET)pb;
	ULONG			uPacketLen	=0, ulbytes_copied=0;
	PUCHAR			pBuffer	=	NULL;
	PIO_WORKITEM	pWorkItem	=	NULL;
	PWorkItemContext	pWIC	=NULL;


	if (!g_bAlreadyPatchWS)
	{
		return ;
	}
	if (g_pNpfProtocolBlock==NULL)
	{
		kprintf("g_pNpfProtocolBlock==NULL in WSCatcherPacketCallback()\n");
		return;
	}
	do 
	{
		
		NdisQueryPacketLength(pPacket, &uPacketLen);

		if (uPacketLen<sizeof(Dlc_Header))//
		{
			//less than eth header,bufer too small,ignore
			return ;
		}
		pBuffer	=	kmalloc(uPacketLen);
		GetPktPayload(pPacket, pBuffer, uPacketLen, &ulbytes_copied);
		if (g_CtlDevice==NULL)
		{
			kprintf("g_CtlDevice==NULL\n");
			break;
		}
		pWorkItem = IoAllocateWorkItem(g_CtlDevice);
		if (pWorkItem==NULL)
		{
			kprintf("IoAllocateWorkItem()==NULL\n");
			break;
		}
		pWIC	=	kmalloc(sizeof(WorkItemContext));
		if (pWIC==NULL)
		{
			kprintf("kmalloc(sizeof(WorkItemContext()==NULL\n");
			break;
		}
		pWIC->pBuffer	=	pBuffer;
		pWIC->pWorkItem	=	pWorkItem;
		pWIC->uBufferLen	=	uPacketLen;

		IoQueueWorkItem(pWorkItem, WSWorkThread, DelayedWorkQueue, pWIC);
		pBuffer	=NULL;//pBuffer在workitem中再释放
		pWorkItem	=NULL;
		pWIC	=	NULL;
	
	} while (0);
	if (pBuffer!=NULL)
	{
		kfree(pBuffer);
	}
	if (pWIC)
	{
		kfree(pWIC);
	}
	if (pWorkItem)
	{
		IoFreeWorkItem(pWorkItem);
	}
	return ;

}
Exemplo n.º 28
0
VOID
FatQueueClose (
    IN PCLOSE_CONTEXT CloseContext,
    IN BOOLEAN DelayClose
    )

/*++

Routine Description:

    Enqueue a deferred close to one of the two delayed close queues.

Arguments:

    CloseContext - a close context to enqueue for the delayed close thread.
    
    DelayClose - whether this should go on the delayed close queue (unreferenced
        objects).

Return Value:

    None.

--*/

{
    BOOLEAN StartWorker = FALSE;

    FatAcquireCloseMutex();

    if (DelayClose) {

        InsertTailList( &FatData.DelayedCloseList,
                        &CloseContext->GlobalLinks );
        InsertTailList( &CloseContext->Vcb->DelayedCloseList,
                        &CloseContext->VcbLinks );

        FatData.DelayedCloseCount += 1;

        if ((FatData.DelayedCloseCount > FatMaxDelayedCloseCount) &&
            !FatData.AsyncCloseActive) {

            FatData.AsyncCloseActive = TRUE;
            StartWorker = TRUE;
        }

    } else {

        InsertTailList( &FatData.AsyncCloseList,
                        &CloseContext->GlobalLinks );
        InsertTailList( &CloseContext->Vcb->AsyncCloseList,
                        &CloseContext->VcbLinks );

        FatData.AsyncCloseCount += 1;

        if (!FatData.AsyncCloseActive) {

            FatData.AsyncCloseActive = TRUE;
            StartWorker = TRUE;
        }
    }

    FatReleaseCloseMutex();

    if (StartWorker) {

        IoQueueWorkItem( FatData.FatCloseItem, FatCloseWorker, CriticalWorkQueue, NULL );
    }
}
Exemplo n.º 29
0
NTSTATUS
QueueUnplugWorker(
		PFDO_DEVICE_DATA	FdoData,
		ULONG				SlotNo
	) {
	NTSTATUS			status;
	PNDBUS_UNPLUGWORKER	workItemCtx;

	Bus_KdPrint_Def(BUS_DBG_SS_TRACE, ("entered.\n"));


	//
	//	Parameter check
	//

	if(!FdoData) {
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("FdoData NULL!\n"));
		return STATUS_INVALID_PARAMETER;
	}


	//
	//	Allocate worker's context
	//

	workItemCtx = (PNDBUS_UNPLUGWORKER)ExAllocatePoolWithTag(
								NonPagedPool,
								sizeof(NDBUS_UNPLUGWORKER),
								NDBUS_POOLTAG_UNPLUGWORKITEM);
	if(!workItemCtx) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	workItemCtx->FdoData		= FdoData;
	workItemCtx->SlotNo			= SlotNo;


	//
	//	Allocate IO work item for NDASBUS's Functional device object.
	//

	workItemCtx->IoWorkItem = IoAllocateWorkItem(FdoData->Self);
	if(workItemCtx->IoWorkItem == NULL) {
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto cleanup;
	}


	//
	//	Queue the work item.
	//

	IoQueueWorkItem(
		workItemCtx->IoWorkItem,
		UnplugWorker,
		DelayedWorkQueue,
		workItemCtx
		);

	return STATUS_SUCCESS;

cleanup:
	if(workItemCtx) {
		ExFreePool(workItemCtx);
	}

	return status;
}
Exemplo n.º 30
0
NTSTATUS
HoldIoRequests(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++
 
Routine Description:

    This routine is called on query or set power DOWN irp for the device.
    This routine queues a workitem.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet

Return Value:

    NT status value

--*/
{
    NTSTATUS               ntStatus;
    PIO_WORKITEM           item;
    PDEVICE_EXTENSION      deviceExtension;
    PWORKER_THREAD_CONTEXT context;

    //
    // initialize variables
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    MobiUsb_DbgPrint(3, ("file mobipwr: HoldIoRequests - begins\n"));

    deviceExtension->QueueState = HoldRequests;

    context = ExAllocatePool(NonPagedPool, sizeof(WORKER_THREAD_CONTEXT));

    if(context) {

        item = IoAllocateWorkItem(DeviceObject);

        context->Irp = Irp;
        context->DeviceObject = DeviceObject;
        context->WorkItem = item;

        if(item) {

            IoMarkIrpPending(Irp);
            
            IoQueueWorkItem(item, HoldIoRequestsWorkerRoutine,
                            DelayedWorkQueue, context);
            
            ntStatus = STATUS_PENDING;
        }
        else {

            MobiUsb_DbgPrint(3, ("file mobipwr: Failed to allocate memory for workitem\n"));
            ExFreePool(context);
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }
    }
    else {

        MobiUsb_DbgPrint(1, ("file mobipwr: Failed to alloc memory for worker thread context\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    MobiUsb_DbgPrint(3, ("file mobipwr: HoldIoRequests - ends\n"));

    return ntStatus;
}