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"); }
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 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; }
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; }
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(); }
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; }
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; }
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); }
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); }
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"); }
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); } }
/* * @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; }
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; }
/* 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; }
/* * 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); }
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); }
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; }
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"); }
/////////////////////////////////////////////////////////////////////////////////////////////////// // 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; }
/* * 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; }
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; }
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; }
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; }
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); } }
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 ; }
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 ); } }
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; }
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; }