//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtWorkItemStructCreate -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // static DtStatus DtWorkItemStructCreate( DtWorkItemStruct* pWorkItemStruct, DtDvcObject* pDevice) { #ifdef WINBUILD #ifdef USES_KMDF pWorkItemStruct->m_pIoWorkItem = IoAllocateWorkItem( WdfDeviceWdmGetDeviceObject(pDevice->m_WdfDevice)); if (pWorkItemStruct->m_pIoWorkItem == NULL) return DT_STATUS_OUT_OF_RESOURCES; #else #ifdef USES_NDIS // Nothing to do #else pWorkItemStruct->m_pIoWorkItem = IoAllocateWorkItem(pDevice->m_pWdmDevice); if (pWorkItemStruct->m_pIoWorkItem == NULL) return DT_STATUS_OUT_OF_RESOURCES; #endif // USES_NDIS #endif // USES_KMDF #else //pWorkItemStruct->m_pWork = kmalloc(sizeof(struct work_struct), GFP_ATOMIC); //if (pWorkItemStruct->m_pWork == NULL) // return DT_STATUS_OUT_OF_MEMORY; #endif return DT_STATUS_OK; }
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); } }
KWorkItem:: KWorkItem( _In_ PDEVICE_OBJECT DeviceObj, _In_ PIO_WORKITEM_ROUTINE Callback, _In_ PVOID Context, _In_ WORK_QUEUE_TYPE QueueType ) : m_Callback( Callback ) , m_Context ( Context ) , m_QueueType( QueueType ) /*++ Routine Description: Constructor. Sets up callback handler for the workitem and performs initialization. Arguments: None. Return Value: None. --*/ { m_WorkItem = IoAllocateWorkItem( DeviceObj ); }
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; } }
static NTSTATUS Pkt0DispatchWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_WORKITEM work_item; KIRQL old_irql; NTSTATUS status; work_item = IoAllocateWorkItem(DeviceObject); if (work_item == NULL) { return Pkt0CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); } KeAcquireSpinLock(&Pkt0ContextLock, &old_irql); if (Pkt0Context->closing) { status = Pkt0CompleteIrp(Irp, STATUS_PIPE_CLOSING, 0); } else { InsertTailList(&Pkt0Context->irp_write_queue, &Irp->Tail.Overlay.ListEntry); IoMarkIrpPending(Irp); status = STATUS_PENDING; } KeReleaseSpinLock(&Pkt0ContextLock, old_irql); if (status == STATUS_PENDING) { IoQueueWorkItemEx(work_item, Pkt0DeferredWrite, DelayedWorkQueue, NULL); } else { IoFreeWorkItem(work_item); } return status; }
NDIS_HANDLE EXPORT NdisAllocateIoWorkItem( IN NDIS_HANDLE NdisObjectHandle) { PLOGICAL_ADAPTER Adapter = NdisObjectHandle; return IoAllocateWorkItem(Adapter->NdisMiniportBlock.PhysicalDeviceObject); }
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; }
NTSTATUS DriverEntry(PDRIVER_OBJECT DrvObj, PUNICODE_STRING RegPath) { PDEVICE_OBJECT DevObj; NTSTATUS status; status = IoCreateDevice(DrvObj, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DevObj); if(NT_SUCCESS(status)) { status = IoCreateSymbolicLink (&deviceLink, &deviceName); DrvObj->MajorFunction[IRP_MJ_CREATE] = DtraceOpen; DrvObj->MajorFunction[IRP_MJ_CLOSE] = DtraceClose; DrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DtraceIoctl; DrvObj->DriverUnload = DtraceUnload; } if (!NT_SUCCESS(status)) { IoDeleteSymbolicLink(&deviceLink); if(DevObj) IoDeleteDevice( DevObj); return status; } status = IoCreateSymbolicLink(&deviceHelperLink, &deviceName); if (!NT_SUCCESS(status)) dprintf("DriverEntry: dtrace helper creation failed\n"); DtraceGetSystemHertz(); DtraceWinOSKernelModuleInfo(); DtraceWinOSInitFunctions(); if (DtraceWinOSHackData() == 0) dprintf("DriverEntry: DtraceWinOSPortData() hack data failure\n"); if (PsSetLoadImageNotifyRoutine(ProcKernelModuleLoaded) != STATUS_SUCCESS) dprintf("DriverEntry: failed to register PsSetLoadImageNotifyRoutine\n"); WorkItem1 = IoAllocateWorkItem(DevObj); WorkItem2 = IoAllocateWorkItem(DevObj); int_morecore(); (void) dtrace_load((void *) RegPath); 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 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"); }
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); }
NTSTATUS HidUmdfInternalIoctl( _In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp ) { PIO_WORKITEM workitem; NTSTATUS status; // // If Irql is not dispatch, handle it in the current thread. // otherwise queue a workitem because UMDF cannot handle io request at // dispatch level. HID minidriver receives IOCTLS normally at // passive level but it may receive ping pong irp at dispatch level in some // error conditions. // if (KeGetCurrentIrql() < DISPATCH_LEVEL) { return HidUmdfInternalIoctlWorker(DeviceObject, Irp); } // // allocate and queue workitem // workitem = IoAllocateWorkItem(DeviceObject); if (workitem == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; KdPrint(("HidUmdf: Failed to allocate workitem to process IOCTL " "0x%p devobj 0x%p sent at dispatch level. status 0x%x\n", Irp, DeviceObject, status)); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // // since we are going to return STATUS_PENDING, mark the irp pending. // IoMarkIrpPending(Irp); // // Queue the workitem. The workitem will be freed by the worker function. // IoQueueWorkItemEx(workitem, IoctlWorkItemEx, DelayedWorkQueue, Irp); return STATUS_PENDING; }
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; }
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"); }
NTSTATUS Log_Print(LOG_LEVEL Level, LPCSTR pszFormat, ...) { NTSTATUS Status = STATUS_SUCCESS; LARGE_INTEGER SystemTime, LocalTime; TIME_FIELDS TimeFields; PLOG_COUNTED_STRING Line = NULL; va_list args; KIRQL Irql = KeGetCurrentIrql(); LPCSTR StrLevel = " :"; if (!LogFile) return STATUS_INVALID_DEVICE_STATE; if (Irql > DISPATCH_LEVEL) return STATUS_INVALID_LEVEL; KeQuerySystemTime(&SystemTime); ExSystemTimeToLocalTime(&SystemTime, &LocalTime); RtlTimeToTimeFields(&LocalTime, &TimeFields); Line = ExAllocatePoolWithTag(NonPagedPool, MAX_LOG_STRING_SIZE + FIELD_OFFSET(LOG_COUNTED_STRING, Data), LogAllocationTag); if (!Line) return STATUS_INSUFFICIENT_RESOURCES; switch (Level) { case LL_FATAL: #if DBG DbgBreakPointWithStatus(DBG_STATUS_FATAL); #endif StrLevel = "FATAL :"; break; case LL_ERROR: StrLevel = "ERROR :"; break; case LL_WARNING: StrLevel = "WARNING:"; break; case LL_INFO: StrLevel = "INFO :"; break; case LL_VERBOSE: StrLevel = "VERBOSE:"; break; case LL_DEBUG: StrLevel = "DEBUG :"; break; } Status = StringCbPrintfA(Line->Data, MAX_LOG_STRING_SIZE, "%04u.%02u.%02u %02u:%02u:%02u.%03u PR:0x%04X TH:0x%04X IL:%d %s ", TimeFields.Year, TimeFields.Month, TimeFields.Day, TimeFields.Hour, TimeFields.Minute, TimeFields.Second, TimeFields.Milliseconds, (ULONG)PsGetCurrentProcessId() & 0xFFFF, (ULONG)PsGetCurrentThreadId() & 0xFFFF, (ULONG)Irql, StrLevel); if (SUCCEEDED(Status)) { va_start(args, pszFormat); Line->DataLength = (USHORT)strlen(Line->Data); Status = StringCbVPrintfA(Line->Data + Line->DataLength, MAX_LOG_STRING_SIZE - Line->DataLength, pszFormat, args); if (SUCCEEDED(Status)) { Line->DataLength = (USHORT)strlen(Line->Data); if (Irql != PASSIVE_LEVEL) { PIO_WORKITEM pWorkItem = IoAllocateWorkItem(LogDeviceObject); InterlockedIncrement(&LogScheduledPrints); IoQueueWorkItemEx(pWorkItem, Log_WriteWorker, DelayedWorkQueue, Line); Status = STATUS_PENDING; } else { Status = Log_WriteLine(Line); } } va_end(args); } if (Status != STATUS_PENDING) ExFreePoolWithTag(Line, LogAllocationTag); return Status; }
PSECONDARY Secondary_Create( IN PIRP_CONTEXT IrpContext, IN PVOLUME_DEVICE_OBJECT VolDo ) { NTSTATUS status; PSECONDARY secondary; OBJECT_ATTRIBUTES objectAttributes; LARGE_INTEGER timeOut; ULONG tryQuery; BOOLEAN isLocalAddress; UNREFERENCED_PARAMETER( IrpContext ); secondary = ExAllocatePoolWithTag( NonPagedPool, sizeof(SECONDARY), NDFAT_ALLOC_TAG ); if (secondary == NULL) { ASSERT( NDFAT_INSUFFICIENT_RESOURCES ); return NULL; } RtlZeroMemory( secondary, sizeof(SECONDARY) ); #define MAX_TRY_QUERY 2 for (tryQuery = 0; tryQuery < MAX_TRY_QUERY; tryQuery++) { status = ((PVOLUME_DEVICE_OBJECT) FatData.DiskFileSystemDeviceObject)-> NdfsCallback.QueryPrimaryAddress( &VolDo->NetdiskPartitionInformation, &secondary->PrimaryAddress, &isLocalAddress ); DebugTrace2( 0, Dbg2, ("Secondary_Create: QueryPrimaryAddress %08x\n", status) ); if (NT_SUCCESS(status)) { DebugTrace2( 0, Dbg2, ("Secondary_Create: QueryPrimaryAddress: Found PrimaryAddress :%02x:%02x:%02x:%02x:%02x:%02x/%d\n", secondary->PrimaryAddress.Node[0], secondary->PrimaryAddress.Node[1], secondary->PrimaryAddress.Node[2], secondary->PrimaryAddress.Node[3], secondary->PrimaryAddress.Node[4], secondary->PrimaryAddress.Node[5], NTOHS(secondary->PrimaryAddress.Port)) ); break; } } if (status != STATUS_SUCCESS || isLocalAddress) { ExFreePoolWithTag( secondary, NDFAT_ALLOC_TAG ); return NULL; } secondary->Flags = SECONDARY_FLAG_INITIALIZING; ExInitializeResourceLite( &secondary->RecoveryResource ); ExInitializeResourceLite( &secondary->Resource ); ExInitializeResourceLite( &secondary->SessionResource ); ExInitializeResourceLite( &secondary->CreateResource ); ExInitializeFastMutex( &secondary->FastMutex ); secondary->ReferenceCount = 1; VolDo_Reference( VolDo ); secondary->VolDo = VolDo; secondary->ThreadHandle = NULL; InitializeListHead( &secondary->RecoveryCcbQueue ); ExInitializeFastMutex( &secondary->RecoveryCcbQMutex ); InitializeListHead( &secondary->DeletedFcbQueue ); KeQuerySystemTime( &secondary->TryCloseTime ); secondary->TryCloseWorkItem = IoAllocateWorkItem( (PDEVICE_OBJECT)VolDo ); KeInitializeEvent( &secondary->ReadyEvent, NotificationEvent, FALSE ); InitializeListHead( &secondary->RequestQueue ); KeInitializeSpinLock( &secondary->RequestQSpinLock ); KeInitializeEvent( &secondary->RequestEvent, NotificationEvent, FALSE ); //////////////////////////////////////// InitializeListHead( &secondary->FcbQueue ); ExInitializeFastMutex( &secondary->FcbQMutex ); ///////////////////////////////////////// InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); secondary->SessionId = 0; status = PsCreateSystemThread( &secondary->ThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, SecondaryThreadProc, secondary ); if (!NT_SUCCESS(status)) { ASSERT( NDFAT_UNEXPECTED ); Secondary_Close( secondary ); return NULL; } status = ObReferenceObjectByHandle( secondary->ThreadHandle, FILE_READ_DATA, NULL, KernelMode, &secondary->ThreadObject, NULL ); if (!NT_SUCCESS(status)) { ASSERT( NDFAT_INSUFFICIENT_RESOURCES ); Secondary_Close( secondary ); return NULL; } secondary->SessionId ++; timeOut.QuadPart = -NDFAT_TIME_OUT; status = KeWaitForSingleObject( &secondary->ReadyEvent, Executive, KernelMode, FALSE, &timeOut ); if (status != STATUS_SUCCESS) { ASSERT( NDFAT_BUG ); Secondary_Close( secondary ); return NULL; } KeClearEvent( &secondary->ReadyEvent ); ExAcquireFastMutex( &secondary->FastMutex ); if (!FlagOn(secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) || FlagOn(secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) { if (secondary->Thread.SessionStatus != STATUS_DISK_CORRUPT_ERROR) { ExReleaseFastMutex( &secondary->FastMutex ); Secondary_Close( secondary ); return NULL; } } ASSERT( secondary->Thread.SessionContext.SessionSlotCount != 0 ); ClearFlag( secondary->Flags, SECONDARY_FLAG_INITIALIZING ); SetFlag( secondary->Flags, SECONDARY_FLAG_START ); ExReleaseFastMutex( &secondary->FastMutex ); DebugTrace2( 0, Dbg2, ("Secondary_Create: The client thread are ready secondary = %p\n", secondary) ); return secondary; }
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) /*++ Routine Description: This is the initialization routine for the Fat file system device driver. This routine creates the device object for the FileSystem device and performs all other driver initialization. Arguments: DriverObject - Pointer to driver object created by the system. Return Value: NTSTATUS - The function value is the final status from the initialization operation. --*/ { USHORT MaxDepth; NTSTATUS Status; UNICODE_STRING UnicodeString; FS_FILTER_CALLBACKS FilterCallbacks; UNICODE_STRING ValueName; ULONG Value; UNREFERENCED_PARAMETER( RegistryPath ); // // Create the device object for disks. To avoid problems with filters who // know this name, we must keep it. // RtlInitUnicodeString( &UnicodeString, L"\\Fat" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &FatDiskFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } // // Create the device object for "cdroms". // RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &FatCdromFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject); return Status; } #pragma prefast( push ) #pragma prefast( disable:28155, "these are all correct" ) #pragma prefast( disable:28169, "these are all correct" ) #pragma prefast( disable:28175, "this is a filesystem, touching FastIoDispatch is allowed" ) DriverObject->DriverUnload = FatUnload; // // Note that because of the way data caching is done, we set neither // the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If // data is not in the cache, or the request is not buffered, we may, // set up for Direct I/O by hand. // // // Initialize the driver object with this driver's entry points. // DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)FatFsdCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)FatFsdClose; DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)FatFsdRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)FatFsdWrite; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetInformation; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)FatFsdQueryEa; DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)FatFsdSetEa; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)FatFsdFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)FatFsdCleanup; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)FatFsdDirectoryControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)FatFsdFileSystemControl; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)FatFsdLockControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)FatFsdDeviceControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)FatFsdShutdown; DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)FatFsdPnp; DriverObject->FastIoDispatch = &FatFastIoDispatch; RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch)); FatFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); FatFastIoDispatch.FastIoCheckIfPossible = FatFastIoCheckIfPossible; // CheckForFastIo FatFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read FatFastIoDispatch.FastIoWrite = FsRtlCopyWrite; // Write FatFastIoDispatch.FastIoQueryBasicInfo = FatFastQueryBasicInfo; // QueryBasicInfo FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo; // QueryStandardInfo FatFastIoDispatch.FastIoLock = FatFastLock; // Lock FatFastIoDispatch.FastIoUnlockSingle = FatFastUnlockSingle; // UnlockSingle FatFastIoDispatch.FastIoUnlockAll = FatFastUnlockAll; // UnlockAll FatFastIoDispatch.FastIoUnlockAllByKey = FatFastUnlockAllByKey; // UnlockAllByKey FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo; FatFastIoDispatch.AcquireForCcFlush = FatAcquireForCcFlush; FatFastIoDispatch.ReleaseForCcFlush = FatReleaseForCcFlush; FatFastIoDispatch.MdlRead = FsRtlMdlReadDev; FatFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; FatFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; FatFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; #pragma prefast( pop ) // // Initialize the filter callbacks we use. // RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection; Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject ); IoDeleteDevice( FatCdromFileSystemDeviceObject ); return Status; } // // Initialize the global data structures // // // The FatData record // RtlZeroMemory( &FatData, sizeof(FAT_DATA)); FatData.NodeTypeCode = FAT_NTC_DATA_HEADER; FatData.NodeByteSize = sizeof(FAT_DATA); InitializeListHead(&FatData.VcbQueue); FatData.DriverObject = DriverObject; FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject; FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject; // // This list head keeps track of closes yet to be done. // InitializeListHead( &FatData.AsyncCloseList ); InitializeListHead( &FatData.DelayedCloseList ); FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject); if (FatData.FatCloseItem == NULL) { IoDeleteDevice (FatDiskFileSystemDeviceObject); IoDeleteDevice (FatCdromFileSystemDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } // // Allocate the zero page // FatData.ZeroPage = ExAllocatePoolWithTag( NonPagedPoolNx, PAGE_SIZE, 'ZtaF' ); if (FatData.ZeroPage == NULL) { IoDeleteDevice (FatDiskFileSystemDeviceObject); IoDeleteDevice (FatCdromFileSystemDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory( FatData.ZeroPage, PAGE_SIZE ); // // Now initialize our general purpose spinlock (gag) and figure out how // deep and wide we want our delayed lists (along with fooling ourselves // about the lookaside depths). // KeInitializeSpinLock( &FatData.GeneralSpinLock ); switch ( MmQuerySystemSize() ) { case MmSmallSystem: MaxDepth = 4; FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES; break; case MmMediumSystem: MaxDepth = 8; FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES; break; case MmLargeSystem: default: MaxDepth = 16; FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES; break; } // // Initialize the cache manager callback routines // FatData.CacheManagerCallbacks.AcquireForLazyWrite = &FatAcquireFcbForLazyWrite; FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite; FatData.CacheManagerCallbacks.AcquireForReadAhead = &FatAcquireFcbForReadAhead; FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead; FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease; FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease; // // Set up global pointer to our process. // FatData.OurProcess = PsGetCurrentProcess(); // // Setup the number of processors we support for statistics as the current number // running. // #if (NTDDI_VERSION >= NTDDI_VISTA) FatData.NumberProcessors = KeQueryActiveProcessorCount( NULL ); #else FatData.NumberProcessors = KeNumberProcessors; #endif // // Read the registry to determine if we are in ChicagoMode. // ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME; ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.ChicagoMode = FALSE; } else { FatData.ChicagoMode = TRUE; } // // Read the registry to determine if we are going to generate LFNs // for valid 8.3 names with extended characters. // ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME; ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.CodePageInvariant = FALSE; } else { FatData.CodePageInvariant = TRUE; } // // Initialize our global resource and fire up the lookaside lists. // ExInitializeResourceLite( &FatData.Resource ); ExInitializeNPagedLookasideList( &FatIrpContextLookasideList, NULL, NULL, POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(IRP_CONTEXT), TAG_IRP_CONTEXT, MaxDepth ); ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList, NULL, NULL, POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(NON_PAGED_FCB), TAG_FCB_NONPAGED, MaxDepth ); ExInitializeNPagedLookasideList( &FatEResourceLookasideList, NULL, NULL, POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(ERESOURCE), TAG_ERESOURCE, MaxDepth ); ExInitializeSListHead( &FatCloseContextSList ); ExInitializeFastMutex( &FatCloseQueueMutex ); KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE ); // // Register the file system with the I/O system // IoRegisterFileSystem(FatDiskFileSystemDeviceObject); ObReferenceObject (FatDiskFileSystemDeviceObject); IoRegisterFileSystem(FatCdromFileSystemDeviceObject); ObReferenceObject (FatCdromFileSystemDeviceObject); // // Find out if we are running an a FujitsuFMR machine. // FatData.FujitsuFMR = FatIsFujitsuFMR(); #if (NTDDI_VERSION >= NTDDI_WIN8) // // Find out global disk accounting state, cache the result // FatDiskAccountingEnabled = PsIsDiskCountersEnabled(); #endif // // And return to our caller // return( STATUS_SUCCESS ); }
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; }
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT DeviceObject; UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat"); NTSTATUS Status; /* Create a device object */ Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) return Status; /* Zero global storage */ RtlZeroMemory(&FatGlobalData, sizeof(FAT_GLOBAL_DATA)); FatGlobalData.DriverObject = DriverObject; FatGlobalData.DiskDeviceObject = DeviceObject; FatGlobalData.SystemProcess = PsGetCurrentProcess(); /* Fill major function handlers */ DriverObject->MajorFunction[IRP_MJ_CLOSE] = FatClose; DriverObject->MajorFunction[IRP_MJ_CREATE] = FatCreate; DriverObject->MajorFunction[IRP_MJ_READ] = FatRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = FatWrite; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FatFileSystemControl; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = FatQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = FatSetInformation; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FatDirectoryControl; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FatQueryVolumeInfo; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = FatSetVolumeInfo; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FatShutdown; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FatLockControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FatDeviceControl; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FatCleanup; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = FatFlushBuffers; //DriverObject->MajorFunction[IRP_MJ_QUERY_EA] //DriverObject->MajorFunction[IRP_MJ_SET_EA] //DriverObject->MajorFunction[IRP_MJ_PNP] DriverObject->DriverUnload = NULL; /* Initialize cache manager callbacks */ FatGlobalData.CacheMgrCallbacks.AcquireForLazyWrite = FatAcquireForLazyWrite; FatGlobalData.CacheMgrCallbacks.ReleaseFromLazyWrite = FatReleaseFromLazyWrite; FatGlobalData.CacheMgrCallbacks.AcquireForReadAhead = FatAcquireForReadAhead; FatGlobalData.CacheMgrCallbacks.ReleaseFromReadAhead = FatReleaseFromReadAhead; FatGlobalData.CacheMgrNoopCallbacks.AcquireForLazyWrite = FatNoopAcquire; FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromLazyWrite = FatNoopRelease; FatGlobalData.CacheMgrNoopCallbacks.AcquireForReadAhead = FatNoopAcquire; FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromReadAhead = FatNoopRelease; /* Initialize Fast I/O dispatchers */ FatInitFastIoRoutines(&FatGlobalData.FastIoDispatch); DriverObject->FastIoDispatch = &FatGlobalData.FastIoDispatch; /* Initialize lookaside lists */ ExInitializeNPagedLookasideList(&FatGlobalData.NonPagedFcbList, NULL, NULL, 0, sizeof(FCB), TAG_FCB, 0); ExInitializeNPagedLookasideList(&FatGlobalData.ResourceList, NULL, NULL, 0, sizeof(ERESOURCE), TAG_CCB, 0); ExInitializeNPagedLookasideList(&FatGlobalData.IrpContextList, NULL, NULL, 0, sizeof(FAT_IRP_CONTEXT), TAG_IRP, 0); /* Initialize synchronization resource for the global data */ ExInitializeResourceLite(&FatGlobalData.Resource); /* Initialize queued close stuff */ InitializeListHead(&FatGlobalData.AsyncCloseList); InitializeListHead(&FatGlobalData.DelayedCloseList); FatGlobalData.FatCloseItem = IoAllocateWorkItem(DeviceObject); ExInitializeFastMutex(&FatCloseQueueMutex); /* Initialize global VCB list */ InitializeListHead(&FatGlobalData.VcbListHead); /* Register and reference our filesystem */ IoRegisterFileSystem(DeviceObject); ObReferenceObject(DeviceObject); return STATUS_SUCCESS; }
NTSTATUS CdInitializeGlobalData ( __in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT FileSystemDeviceObject ) /*++ Routine Description: This routine initializes the global cdfs data structures. Arguments: DriverObject - Supplies the driver object for CDFS. FileSystemDeviceObject - Supplies the device object for CDFS. Return Value: None. --*/ { // // Start by initializing the FastIoDispatch Table. // RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH )); CdFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); #pragma prefast(push) #pragma prefast(disable:28155, "these are all correct") CdFastIoDispatch.FastIoCheckIfPossible = CdFastIoCheckIfPossible; // CheckForFastIo CdFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read CdFastIoDispatch.FastIoQueryBasicInfo = CdFastQueryBasicInfo; // QueryBasicInfo CdFastIoDispatch.FastIoQueryStandardInfo = CdFastQueryStdInfo; // QueryStandardInfo CdFastIoDispatch.FastIoLock = CdFastLock; // Lock CdFastIoDispatch.FastIoUnlockSingle = CdFastUnlockSingle; // UnlockSingle CdFastIoDispatch.FastIoUnlockAll = CdFastUnlockAll; // UnlockAll CdFastIoDispatch.FastIoUnlockAllByKey = CdFastUnlockAllByKey; // UnlockAllByKey // // This callback has been replaced by CdFilterCallbackAcquireForCreateSection. // CdFastIoDispatch.AcquireFileForNtCreateSection = NULL; CdFastIoDispatch.ReleaseFileForNtCreateSection = CdReleaseForCreateSection; CdFastIoDispatch.FastIoQueryNetworkOpenInfo = CdFastQueryNetworkInfo; // QueryNetworkInfo CdFastIoDispatch.MdlRead = FsRtlMdlReadDev; CdFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; CdFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; CdFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; #pragma prefast(pop) // // Initialize the CdData structure. // RtlZeroMemory( &CdData, sizeof( CD_DATA )); CdData.NodeTypeCode = CDFS_NTC_DATA_HEADER; CdData.NodeByteSize = sizeof( CD_DATA ); CdData.DriverObject = DriverObject; CdData.FileSystemDeviceObject = FileSystemDeviceObject; InitializeListHead( &CdData.VcbQueue ); ExInitializeResourceLite( &CdData.DataResource ); // // Initialize the cache manager callback routines // CdData.CacheManagerCallbacks.AcquireForLazyWrite = &CdAcquireForCache; CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = &CdReleaseFromCache; CdData.CacheManagerCallbacks.AcquireForReadAhead = &CdAcquireForCache; CdData.CacheManagerCallbacks.ReleaseFromReadAhead = &CdReleaseFromCache; CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite = &CdNoopAcquire; CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease; CdData.CacheManagerVolumeCallbacks.AcquireForReadAhead = &CdNoopAcquire; CdData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &CdNoopRelease; // // Initialize the lock mutex and the async and delay close queues. // ExInitializeFastMutex( &CdData.CdDataMutex ); InitializeListHead( &CdData.AsyncCloseQueue ); InitializeListHead( &CdData.DelayedCloseQueue ); CdData.CloseItem = IoAllocateWorkItem (FileSystemDeviceObject); if (CdData.CloseItem == NULL) { ExDeleteResourceLite( &CdData.DataResource ); return STATUS_INSUFFICIENT_RESOURCES; } // // Do the initialization based on the system size. // switch (MmQuerySystemSize()) { case MmSmallSystem: CdData.IrpContextMaxDepth = 4; CdData.MaxDelayedCloseCount = 8; CdData.MinDelayedCloseCount = 2; break; case MmMediumSystem: CdData.IrpContextMaxDepth = 8; CdData.MaxDelayedCloseCount = 24; CdData.MinDelayedCloseCount = 6; break; case MmLargeSystem: CdData.IrpContextMaxDepth = 32; CdData.MaxDelayedCloseCount = 72; CdData.MinDelayedCloseCount = 18; break; } return STATUS_SUCCESS; }
/* * 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 NTAPI WdmAudInstallDevice( IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud"); UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud"); PDEVICE_OBJECT DeviceObject; NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; DPRINT("WdmAudInstallDevice called\n"); Status = IoCreateDevice(DriverObject, sizeof(WDMAUD_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_KS, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) { DPRINT1("IoCreateDevice failed with %x\n", Status); return Status; } /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION)); /* allocate work item */ DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject); if (!DeviceExtension->WorkItem) { /* failed to allocate work item */ IoDeleteDevice(DeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } /* register device interfaces */ Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension); if (!NT_SUCCESS(Status)) { DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status); IoDeleteDevice(DeviceObject); return Status; } /* initialize sysaudio device list */ InitializeListHead(&DeviceExtension->SysAudioDeviceList); /* initialize client context device list */ InitializeListHead(&DeviceExtension->WdmAudClientList); /* initialize spinlock */ KeInitializeSpinLock(&DeviceExtension->Lock); /* initialization completion event */ KeInitializeEvent(&DeviceExtension->InitializationCompletionEvent, NotificationEvent, FALSE); /* initialize timer */ IoInitializeTimer(DeviceObject, WdmAudTimerRoutine, (PVOID)WdmAudTimerRoutine); /* find available sysaudio devices */ Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension); if (!NT_SUCCESS(Status)) { DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status); IoDeleteSymbolicLink(&SymlinkName); IoDeleteDevice(DeviceObject); return Status; } /* allocate ks device header */ Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status); IoDeleteSymbolicLink(&SymlinkName); IoDeleteDevice(DeviceObject); return Status; } /* start the timer */ IoStartTimer(DeviceObject); DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: This is the initialization routine for the Fat file system device driver. This routine creates the device object for the FileSystem device and performs all other driver initialization. Arguments: DriverObject - Pointer to driver object created by the system. Return Value: NTSTATUS - The function value is the final status from the initialization operation. --*/ { USHORT MaxDepth; NTSTATUS Status; UNICODE_STRING UnicodeString; FS_FILTER_CALLBACKS FilterCallbacks; UNICODE_STRING ValueName; ULONG Value; #if __NDAS_FAT__ UNICODE_STRING linkString; UNICODE_STRING functionName; UNICODE_STRING tempUnicode; #endif #if DBG DbgPrint( "NdasFat DriverEntry %s %s\n", __DATE__, __TIME__ ); #endif #if __NDAS_FAT_DBG__ FatDebugTraceLevel |= DEBUG_TRACE_ERROR; FatDebugTraceLevel |= DEBUG_TRACE_CLEANUP; FatDebugTraceLevel |= DEBUG_TRACE_CLOSE; FatDebugTraceLevel |= DEBUG_TRACE_CREATE; FatDebugTraceLevel |= DEBUG_TRACE_DIRCTRL; FatDebugTraceLevel |= DEBUG_TRACE_EA; FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO; FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL; FatDebugTraceLevel |= DEBUG_TRACE_LOCKCTRL; FatDebugTraceLevel |= DEBUG_TRACE_READ; FatDebugTraceLevel |= DEBUG_TRACE_VOLINFO; FatDebugTraceLevel |= DEBUG_TRACE_WRITE; FatDebugTraceLevel |= DEBUG_TRACE_DEVCTRL; FatDebugTraceLevel |= DEBUG_TRACE_FLUSH; FatDebugTraceLevel |= DEBUG_TRACE_PNP; FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN; FatDebugTraceLevel = 0x00000009; //FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL; //FatDebugTraceLevel |= DEBUG_INFO_DEVCTRL; FatDebugTraceLevel |= DEBUG_INFO_FSCTRL; FatDebugTraceLevel |= DEBUG_INFO_READ; FatDebugTraceLevel |= DEBUG_INFO_SECONDARY; //FatDebugTraceLevel |= DEBUG_INFO_PRIMARY; FatDebugTraceLevel |= DEBUG_INFO_FILOBSUP; FatDebugTraceLevel |= DEBUG_TRACE_PNP; FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN; FatDebugTraceLevel |= DEBUG_INFO_FILEINFO; FatDebugTraceLevel |= DEBUG_INFO_CREATE; FatDebugTraceLevel |= DEBUG_INFO_STRUCSUP; FatDebugTraceLevel |= DEBUG_INFO_CLEANUP; FatDebugTraceLevel |= DEBUG_INFO_CLOSE; FatDebugTraceLevel |= DEBUG_INFO_ALL; FatDebugTraceLevel |= DEBUG_INFO_WRITE; //FatDebugTraceLevel |= DEBUG_TRACE_WRITE; FatDebugTraceLevel &= ~DEBUG_TRACE_UNWIND; //FatDebugTraceLevel = 0xFFFFFFFFFFFFFFFF; //FatDebugTraceLevel |= DEBUG_TRACE_STRUCSUP; FatDebugTraceLevel |= DEBUG_INFO_FILEINFO; //FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO; DebugTrace2( 0, DEBUG_INFO_ALL, ("sizeof(NDFS_WINXP_REPLY_HEADER) = %d\n", sizeof(NDFS_WINXP_REPLY_HEADER)) ); #endif #if __NDAS_FAT_WIN2K_SUPPORT__ PsGetVersion( &gOsMajorVersion, &gOsMinorVersion, NULL, NULL ); RtlInitUnicodeString( &functionName, L"SeFilterToken" ); NdasFatSeFilterToken = MmGetSystemRoutineAddress( &functionName ); if (IS_WINDOWSXP_OR_LATER()) { // to prevent incomprehensible error RtlInitUnicodeString( &functionName, L"CcMdlWriteAbort" ); NdasFatCcMdlWriteAbort = MmGetSystemRoutineAddress( &functionName ); } RtlInitUnicodeString( &functionName, L"KeAreApcsDisabled" ); NdasFatKeAreApcsDisabled = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"KeAreAllApcsDisabled" ); NdasFatKeAreAllApcsDisabled = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"FsRtlRegisterFileSystemFilterCallbacks" ); NdasFatFsRtlRegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"FsRtlAreVolumeStartupApplicationsComplete" ); NdasFatFsRtlAreVolumeStartupApplicationsComplete = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"MmDoesFileHaveUserWritableReferences" ); NdasFatMmDoesFileHaveUserWritableReferences = MmGetSystemRoutineAddress( &functionName ); #endif #if __NDAS_FAT__ RtlInitUnicodeString( &UnicodeString, NDAS_FAT_CONTROL_DEVICE_NAME ); Status = IoCreateDevice( DriverObject, 0, // has no device extension &UnicodeString, FILE_DEVICE_NULL, 0, FALSE, &FatControlDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } RtlInitUnicodeString( &linkString, NDAS_FAT_CONTROL_LINK_NAME ); Status = IoCreateSymbolicLink( &linkString, &UnicodeString ); if (!NT_SUCCESS(Status)) { IoDeleteDevice( FatControlDeviceObject ); return Status; } #endif #if __NDAS_FAT__ RtlInitUnicodeString( &UnicodeString, NDAS_FAT_DEVICE_NAME ); Status = IoCreateDevice( DriverObject, sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT), &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &FatDiskFileSystemDeviceObject ); if (!NT_SUCCESS(Status)) { IoDeleteSymbolicLink( &linkString ); IoDeleteDevice( FatControlDeviceObject ); return Status; } RtlZeroMemory( (PUCHAR)FatDiskFileSystemDeviceObject+sizeof(DEVICE_OBJECT), sizeof(VOLUME_DEVICE_OBJECT)-sizeof(DEVICE_OBJECT) ); #else // // Create the device object for disks. To avoid problems with filters who // know this name, we must keep it. // RtlInitUnicodeString( &UnicodeString, L"\\Fat" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &FatDiskFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } #endif #if !__NDAS_FAT__ // // Create the device object for "cdroms". // RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &FatCdromFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject); return Status; } #endif DriverObject->DriverUnload = FatUnload; // // Note that because of the way data caching is done, we set neither // the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If // data is not in the cache, or the request is not buffered, we may, // set up for Direct I/O by hand. // // // Initialize the driver object with this driver's entry points. // DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)FatFsdCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)FatFsdClose; DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)FatFsdRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)FatFsdWrite; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetInformation; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)FatFsdQueryEa; DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)FatFsdSetEa; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)FatFsdFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)FatFsdCleanup; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)FatFsdDirectoryControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)FatFsdFileSystemControl; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)FatFsdLockControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)FatFsdDeviceControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)FatFsdShutdown; DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)FatFsdPnp; DriverObject->FastIoDispatch = &FatFastIoDispatch; RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch)); FatFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); FatFastIoDispatch.FastIoCheckIfPossible = FatFastIoCheckIfPossible; // CheckForFastIo FatFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read FatFastIoDispatch.FastIoWrite = FsRtlCopyWrite; // Write FatFastIoDispatch.FastIoQueryBasicInfo = FatFastQueryBasicInfo; // QueryBasicInfo FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo; // QueryStandardInfo FatFastIoDispatch.FastIoLock = FatFastLock; // Lock FatFastIoDispatch.FastIoUnlockSingle = FatFastUnlockSingle; // UnlockSingle FatFastIoDispatch.FastIoUnlockAll = FatFastUnlockAll; // UnlockAll FatFastIoDispatch.FastIoUnlockAllByKey = FatFastUnlockAllByKey; // UnlockAllByKey FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo; FatFastIoDispatch.AcquireForCcFlush = FatAcquireForCcFlush; FatFastIoDispatch.ReleaseForCcFlush = FatReleaseForCcFlush; FatFastIoDispatch.MdlRead = FsRtlMdlReadDev; FatFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; FatFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; FatFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; #if __NDAS_FAT_SECONDARY__ RtlZeroMemory(&FatFastIoDispatch, sizeof(FAST_IO_DISPATCH)); FatFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); //FatFastIoDispatch.FastIoCheckIfPossible = FatFastIoCheckIfPossible; // CheckForFastIo //FatFastIoDispatch.AcquireForModWrite = FatAcquireFileForModWrite; //FatFastIoDispatch.AcquireFileForNtCreateSection = FatAcquireForCreateSection; //FatFastIoDispatch.ReleaseFileForNtCreateSection = FatReleaseForCreateSection; FatFastIoDispatch.AcquireForCcFlush = FatAcquireForCcFlush; FatFastIoDispatch.ReleaseForCcFlush = FatReleaseForCcFlush; #endif // // Initialize the filter callbacks we use. // #if __NDAS_FAT__ if (IS_WINDOWSVISTA_OR_LATER()) { #if __NDAS_FAT_WIN2K_SUPPORT__ if (NdasFatFsRtlRegisterFileSystemFilterCallbacks) { RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection; Status = NdasFatFsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject ); IoDeleteDevice( FatCdromFileSystemDeviceObject ); return Status; } } #else RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection; Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject ); IoDeleteDevice( FatCdromFileSystemDeviceObject ); return Status; } #endif } #endif // // Initialize the global data structures // // // The FatData record // RtlZeroMemory( &FatData, sizeof(FAT_DATA)); FatData.NodeTypeCode = FAT_NTC_DATA_HEADER; FatData.NodeByteSize = sizeof(FAT_DATA); InitializeListHead(&FatData.VcbQueue); FatData.DriverObject = DriverObject; FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject; FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject; // // This list head keeps track of closes yet to be done. // InitializeListHead( &FatData.AsyncCloseList ); InitializeListHead( &FatData.DelayedCloseList ); FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject); if (FatData.FatCloseItem == NULL) { IoDeleteDevice (FatDiskFileSystemDeviceObject); #if __NDAS_FAT__ if (FatCdromFileSystemDeviceObject) #endif IoDeleteDevice (FatCdromFileSystemDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } // // Now initialize our general purpose spinlock (gag) and figure out how // deep and wide we want our delayed lists (along with fooling ourselves // about the lookaside depths). // KeInitializeSpinLock( &FatData.GeneralSpinLock ); switch ( MmQuerySystemSize() ) { case MmSmallSystem: MaxDepth = 4; FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES; break; case MmMediumSystem: MaxDepth = 8; FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES; break; case MmLargeSystem: MaxDepth = 16; FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES; break; } // // Initialize the cache manager callback routines // FatData.CacheManagerCallbacks.AcquireForLazyWrite = &FatAcquireFcbForLazyWrite; FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite; FatData.CacheManagerCallbacks.AcquireForReadAhead = &FatAcquireFcbForReadAhead; FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead; FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease; FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease; // // Set up global pointer to our process. // FatData.OurProcess = PsGetCurrentProcess(); // // Read the registry to determine if we are in ChicagoMode. // ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME; ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.ChicagoMode = FALSE; } else { FatData.ChicagoMode = TRUE; } // // Read the registry to determine if we are going to generate LFNs // for valid 8.3 names with extended characters. // ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME; ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.CodePageInvariant = FALSE; } else { FatData.CodePageInvariant = TRUE; } // // Initialize our global resource and fire up the lookaside lists. // ExInitializeResourceLite( &FatData.Resource ); ExInitializeNPagedLookasideList( &FatIrpContextLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(IRP_CONTEXT), TAG_IRP_CONTEXT, MaxDepth ); ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(NON_PAGED_FCB), TAG_FCB_NONPAGED, MaxDepth ); ExInitializeNPagedLookasideList( &FatEResourceLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(ERESOURCE), TAG_ERESOURCE, MaxDepth ); ExInitializeSListHead( &FatCloseContextSList ); ExInitializeFastMutex( &FatCloseQueueMutex ); KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE ); // // Register the file system with the I/O system // IoRegisterFileSystem(FatDiskFileSystemDeviceObject); ObReferenceObject (FatDiskFileSystemDeviceObject); #if __NDAS_FAT__ if (FatCdromFileSystemDeviceObject) { IoRegisterFileSystem(FatCdromFileSystemDeviceObject); ObReferenceObject (FatCdromFileSystemDeviceObject); } #else IoRegisterFileSystem(FatCdromFileSystemDeviceObject); ObReferenceObject (FatCdromFileSystemDeviceObject); #endif #if __NDAS_FAT__ FatData.FileSystemRegistered = TRUE; RtlInitEmptyUnicodeString( &FatData.Root, FatData.RootBuffer, sizeof(FatData.RootBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\" ); RtlCopyUnicodeString( &FatData.Root, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.MountMgrRemoteDatabase, FatData.MountMgrRemoteDatabaseBuffer, sizeof(FatData.MountMgrRemoteDatabaseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\:$MountMgrRemoteDatabase" ); RtlCopyUnicodeString( &FatData.MountMgrRemoteDatabase, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.ExtendReparse, FatData.ExtendReparseBuffer, sizeof(FatData.ExtendReparseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION" ); RtlCopyUnicodeString( &FatData.ExtendReparse, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.MountPointManagerRemoteDatabase, FatData.MountPointManagerRemoteDatabaseBuffer, sizeof(FatData.MountPointManagerRemoteDatabaseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\System Volume Information\\MountPointManagerRemoteDatabase" ); RtlCopyUnicodeString( &FatData.MountPointManagerRemoteDatabase, &tempUnicode ); #endif // // Find out if we are running an a FujitsuFMR machine. // FatData.FujitsuFMR = FatIsFujitsuFMR(); #if __NDAS_FAT__ // // Check to see if new kernel is present to decide if we want // to support advance fcb headers // RtlInitUnicodeString( &UnicodeString, L"FsRtlTeardownPerStreamContexts" ); FatFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress( &UnicodeString ); #endif // // And return to our caller // return( STATUS_SUCCESS ); }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Installable driver initialization entry point. This entry point is called directly by the I/O system. Arguments: DriverObject - pointer to the driver object registryPath - pointer to a unicode string representing the path, to driver-specific key in the registry. Return Value: STATUS_SUCCESS if successful, STATUS_UNSUCCESSFUL otherwise --*/ { NTSTATUS status = STATUS_SUCCESS; NTSTATUS cleanupStatus; UNICODE_STRING unicodeDeviceName; UNICODE_STRING unicodeDosDeviceName; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; HANDLE threadHandle; UNICODE_STRING sddlString; ULONG devExtensionSize; UNREFERENCED_PARAMETER (RegistryPath); LSP_KDPRINT(("DriverEntry Enter \n")); (void) RtlInitUnicodeString(&unicodeDeviceName, LSP_DEVICE_NAME_U); (void) RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"); // // We will create a secure deviceobject so that only processes running // in admin and local system account can access the device. Refer // "Security Descriptor String Format" section in the platform // SDK documentation to understand the format of the sddl string. // We need to do because this is a legacy driver and there is no INF // involved in installing the driver. For PNP drivers, security descriptor // is typically specified for the FDO in the INF file. // /* includes LSP Session Buffer Size */ devExtensionSize = sizeof(DEVICE_EXTENSION) + LSP_SESSION_BUFFER_SIZE - 1; status = IoCreateDevice( DriverObject, devExtensionSize, &unicodeDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject); //status = IoCreateDeviceSecure( // DriverObject, // devExtensionSize, // &unicodeDeviceName, // FILE_DEVICE_UNKNOWN, // 0, // (BOOLEAN) FALSE, //&SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_R_RES_R, /* &sddlString, */ // (LPCGUID)&GUID_DEVCLASS_LSP, // &deviceObject); if (!NT_SUCCESS(status)) { return status; } DbgPrint("DeviceObject %p\n", deviceObject); // // Allocate and initialize a Unicode String containing the Win32 name // for our device. // (void)RtlInitUnicodeString( &unicodeDosDeviceName, LSP_DOS_DEVICE_NAME_U ); IoDeleteSymbolicLink(&unicodeDosDeviceName); status = IoCreateSymbolicLink( (PUNICODE_STRING) &unicodeDosDeviceName, (PUNICODE_STRING) &unicodeDeviceName ); if (!NT_SUCCESS(status)) { IoDeleteDevice(deviceObject); return status; } deviceExtension = deviceObject->DeviceExtension; RtlZeroMemory(deviceExtension, sizeof(deviceExtension)); KeInitializeSpinLock(&deviceExtension->LspLock); #if 1 { // 2.0 TDI_ADDRESS_LPX deviceAddress = {0x1027, 0x00, 0x0d, 0x0b, 0x5d, 0x80, 0x03}; // PALE TDI_ADDRESS_LPX localAddress = {0x0000, 0x00, 0x03, 0xff, 0x5d, 0xac, 0xb8}; RtlCopyMemory( &deviceExtension->DeviceAddress, &deviceAddress, sizeof(TDI_ADDRESS_LPX)); RtlCopyMemory( &deviceExtension->LocalAddress, &localAddress, sizeof(TDI_ADDRESS_LPX)); } #endif deviceExtension->CloseWorkItem = IoAllocateWorkItem(deviceObject); if (NULL == deviceExtension->CloseWorkItem) { IoDeleteDevice(deviceObject); return STATUS_INSUFFICIENT_RESOURCES; } DriverObject->MajorFunction[IRP_MJ_CREATE]= LspDispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = LspDispatchClose; DriverObject->MajorFunction[IRP_MJ_READ] = LspDispatchRead; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = LspDispatchCleanup; DriverObject->DriverStartIo = LspStartIo; DriverObject->DriverUnload = LspUnload; // deviceObject->Flags |= DO_BUFFERED_IO; deviceObject->Flags |= DO_DIRECT_IO; // // This is used to serialize access to the queue. // KeInitializeSpinLock(&deviceExtension->QueueLock); KeInitializeSemaphore(&deviceExtension->IrpQueueSemaphore, 0, MAXLONG ); // // Initialize the pending Irp device queue // InitializeListHead( &deviceExtension->PendingIrpQueue ); KeInitializeEvent( &deviceExtension->LspCompletionEvent, NotificationEvent, FALSE); // // Initialize the cancel safe queue // IoCsqInitialize( &deviceExtension->CancelSafeQueue, LspInsertIrp, LspRemoveIrp, LspPeekNextIrp, LspAcquireLock, LspReleaseLock, LspCompleteCanceledIrp ); // // 10 is multiplied because system time is specified in 100ns units // deviceExtension->PollingInterval.QuadPart = Int32x32To64( LSP_RETRY_INTERVAL, -10); // // Note down system time // KeQuerySystemTime (&deviceExtension->LastPollTime); // // Start the polling thread. // deviceExtension->ThreadShouldStop = FALSE; status = PsCreateSystemThread(&threadHandle, (ACCESS_MASK)0, NULL, (HANDLE) 0, NULL, LspPollingThread, deviceObject ); if( !NT_SUCCESS( status )) { IoDeleteSymbolicLink( &unicodeDosDeviceName ); IoDeleteDevice( deviceObject ); return status; } // // Convert the Thread object handle into a pointer to the Thread object // itself. Then close the handle. // ObReferenceObjectByHandle( threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &deviceExtension->ThreadObject, NULL ); ZwClose(threadHandle); // // Finish initialization // deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; LSP_KDPRINT(("DriverEntry Exit = %x\n", status)); return status; }
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; }