/* * NAME: DriverEntry * FUNCTION: Called by the system to initalize the driver * * ARGUMENTS: * DriverObject = object describing this driver * RegistryPath = path to our configuration entries * RETURNS: Success or failure */ NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT DiskdevObject = NULL; PDEVICE_OBJECT CdromdevObject = NULL; UNICODE_STRING DeviceName; UNICODE_STRING DosDeviceName; PFAST_IO_DISPATCH FastIoDispatch; PCACHE_MANAGER_CALLBACKS CacheManagerCallbacks; NTSTATUS Status; int rc = 0; BOOLEAN linux_lib_inited = FALSE; BOOLEAN journal_module_inited = FALSE; /* Verity super block ... */ ASSERT(sizeof(EXT2_SUPER_BLOCK) == 1024); ASSERT(FIELD_OFFSET(EXT2_SUPER_BLOCK, s_magic) == 56); DbgPrint( "Ext2Fsd --" #ifdef _WIN2K_TARGET_ " Win2k --" #endif " Version " EXT2FSD_VERSION #if EXT2_DEBUG " Checked" #else " Free" #endif " -- " __DATE__ " " __TIME__ ".\n"); DEBUG(DL_FUN, ( "Ext2 DriverEntry ...\n")); /* initialize winlib structures */ if (ext2_init_linux()) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } linux_lib_inited = TRUE; /* initialize journal module structures */ LOAD_MODULE(journal_init); if (rc != 0) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } journal_module_inited = TRUE; /* allocate memory for Ext2Global */ Ext2Global = Ext2AllocatePool(NonPagedPool, sizeof(EXT2_GLOBAL), 'LG2E'); if (!Ext2Global) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } /* initialize Ext2Global */ RtlZeroMemory(Ext2Global, sizeof(EXT2_GLOBAL)); Ext2Global->Identifier.Type = EXT2FGD; Ext2Global->Identifier.Size = sizeof(EXT2_GLOBAL); InitializeListHead(&(Ext2Global->VcbList)); ExInitializeResourceLite(&(Ext2Global->Resource)); /* query registry settings */ Ext2QueryRegistrySettings(RegistryPath); /* create Ext2Fsd cdrom fs deivce */ RtlInitUnicodeString(&DeviceName, CDROM_NAME); Status = IoCreateDevice( DriverObject, 0, &DeviceName, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &CdromdevObject ); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "IoCreateDevice cdrom device object error.\n")); goto errorout; } /* create Ext2Fsd disk fs deivce */ RtlInitUnicodeString(&DeviceName, DEVICE_NAME); Status = IoCreateDevice( DriverObject, 0, &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &DiskdevObject ); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "IoCreateDevice disk device object error.\n")); goto errorout; } Status= Ext2StartReaper( &Ext2Global->FcbReaper, Ext2FcbReaperThread); if (!NT_SUCCESS(Status)) { goto errorout; } /* start resource reaper thread */ Status= Ext2StartReaper( &Ext2Global->McbReaper, Ext2McbReaperThread); if (!NT_SUCCESS(Status)) { Ext2StopReaper(&Ext2Global->FcbReaper); goto errorout; } Status= Ext2StartReaper( &Ext2Global->bhReaper, Ext2bhReaperThread); if (!NT_SUCCESS(Status)) { Ext2StopReaper(&Ext2Global->FcbReaper); Ext2StopReaper(&Ext2Global->McbReaper); goto errorout; } /* initializing */ Ext2Global->DiskdevObject = DiskdevObject; Ext2Global->CdromdevObject = CdromdevObject; DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_READ] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2BuildRequest; #if (_WIN32_WINNT >= 0x0500) DriverObject->MajorFunction[IRP_MJ_PNP] = Ext2BuildRequest; #endif //(_WIN32_WINNT >= 0x0500) #if EXT2_UNLOAD DriverObject->DriverUnload = DriverUnload; #else DriverObject->DriverUnload = NULL; #endif // // Initialize the fast I/O entry points // FastIoDispatch = &(Ext2Global->FastIoDispatch); FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); FastIoDispatch->FastIoCheckIfPossible = Ext2FastIoCheckIfPossible; FastIoDispatch->FastIoRead = Ext2FastIoRead; FastIoDispatch->FastIoWrite = Ext2FastIoWrite; FastIoDispatch->FastIoQueryBasicInfo = Ext2FastIoQueryBasicInfo; FastIoDispatch->FastIoQueryStandardInfo = Ext2FastIoQueryStandardInfo; FastIoDispatch->FastIoLock = Ext2FastIoLock; FastIoDispatch->FastIoUnlockSingle = Ext2FastIoUnlockSingle; FastIoDispatch->FastIoUnlockAll = Ext2FastIoUnlockAll; FastIoDispatch->FastIoUnlockAllByKey = Ext2FastIoUnlockAllByKey; FastIoDispatch->FastIoQueryNetworkOpenInfo = Ext2FastIoQueryNetworkOpenInfo; FastIoDispatch->AcquireForModWrite = Ext2AcquireFileForModWrite; FastIoDispatch->ReleaseForModWrite = Ext2ReleaseFileForModWrite; FastIoDispatch->AcquireForModWrite = Ext2AcquireFileForModWrite; FastIoDispatch->ReleaseForModWrite = Ext2ReleaseFileForModWrite; FastIoDispatch->AcquireForCcFlush = Ext2AcquireFileForCcFlush; FastIoDispatch->ReleaseForCcFlush = Ext2ReleaseFileForCcFlush; FastIoDispatch->AcquireFileForNtCreateSection = Ext2AcquireForCreateSection; FastIoDispatch->ReleaseFileForNtCreateSection = Ext2ReleaseForCreateSection; DriverObject->FastIoDispatch = FastIoDispatch; // // initializing structure sizes for statistics // 1 means flexible/not fixed for all allocations (for different volumes). // Ext2Global->PerfStat.Magic = EXT2_PERF_STAT_MAGIC; Ext2Global->PerfStat.Version = EXT2_PERF_STAT_VER2; Ext2Global->PerfStat.Length = sizeof(EXT2_PERF_STATISTICS_V2); Ext2Global->PerfStat.Unit.Slot[PS_IRP_CONTEXT] = sizeof(EXT2_IRP_CONTEXT); /* 0 */ Ext2Global->PerfStat.Unit.Slot[PS_VCB] = sizeof(EXT2_VCB); /* 1 */ Ext2Global->PerfStat.Unit.Slot[PS_FCB] = sizeof(EXT2_FCB); /* 2 */ Ext2Global->PerfStat.Unit.Slot[PS_CCB] = sizeof(EXT2_CCB); /* 3 */ Ext2Global->PerfStat.Unit.Slot[PS_MCB] = sizeof(EXT2_MCB); /* 4 */ Ext2Global->PerfStat.Unit.Slot[PS_EXTENT] = sizeof(EXT2_EXTENT); /* 5 */ Ext2Global->PerfStat.Unit.Slot[PS_RW_CONTEXT] = sizeof(EXT2_RW_CONTEXT); /* 6 */ Ext2Global->PerfStat.Unit.Slot[PS_VPB] = sizeof(VPB); /* 7 */ Ext2Global->PerfStat.Unit.Slot[PS_FILE_NAME] = 1; /* 8 */ Ext2Global->PerfStat.Unit.Slot[PS_MCB_NAME] = 1; /* 9 */ Ext2Global->PerfStat.Unit.Slot[PS_INODE_NAME] = 1; /* a */ Ext2Global->PerfStat.Unit.Slot[PS_DIR_ENTRY] = sizeof(EXT2_DIR_ENTRY2); /* b */ Ext2Global->PerfStat.Unit.Slot[PS_DIR_PATTERN] = 1; /* c */ Ext2Global->PerfStat.Unit.Slot[PS_DISK_EVENT] = sizeof(KEVENT); /* d */ Ext2Global->PerfStat.Unit.Slot[PS_DISK_BUFFER] = 1; /* e */ Ext2Global->PerfStat.Unit.Slot[PS_BLOCK_DATA] = 1; /* f */ Ext2Global->PerfStat.Unit.Slot[PS_EXT2_INODE] = 1; /* 10 */ Ext2Global->PerfStat.Unit.Slot[PS_DENTRY] = sizeof(struct dentry); /* 11 */ Ext2Global->PerfStat.Unit.Slot[PS_BUFF_HEAD] = sizeof(struct buffer_head); /* 12 */ switch ( MmQuerySystemSize() ) { case MmSmallSystem: Ext2Global->MaxDepth = 64; break; case MmMediumSystem: Ext2Global->MaxDepth = 128; break; case MmLargeSystem: Ext2Global->MaxDepth = 256; break; } // // Initialize the Cache Manager callbacks // CacheManagerCallbacks = &(Ext2Global->CacheManagerCallbacks); CacheManagerCallbacks->AcquireForLazyWrite = Ext2AcquireForLazyWrite; CacheManagerCallbacks->ReleaseFromLazyWrite = Ext2ReleaseFromLazyWrite; CacheManagerCallbacks->AcquireForReadAhead = Ext2AcquireForReadAhead; CacheManagerCallbacks->ReleaseFromReadAhead = Ext2ReleaseFromReadAhead; Ext2Global->CacheManagerNoOpCallbacks.AcquireForLazyWrite = Ext2NoOpAcquire; Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = Ext2NoOpRelease; Ext2Global->CacheManagerNoOpCallbacks.AcquireForReadAhead = Ext2NoOpAcquire; Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = Ext2NoOpRelease; #ifndef _WIN2K_TARGET_ // // Initialize FS Filter callbacks // RtlZeroMemory(&Ext2Global->FilterCallbacks, sizeof(FS_FILTER_CALLBACKS)); Ext2Global->FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); Ext2Global->FilterCallbacks.PreAcquireForSectionSynchronization = Ext2PreAcquireForCreateSection; FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &Ext2Global->FilterCallbacks ); #endif // // Initialize the global data // ExInitializeNPagedLookasideList( &(Ext2Global->Ext2IrpContextLookasideList), NULL, NULL, 0, sizeof(EXT2_IRP_CONTEXT), 'PRIE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2FcbLookasideList), NULL, NULL, 0, sizeof(EXT2_FCB), 'BCFE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2CcbLookasideList), NULL, NULL, 0, sizeof(EXT2_CCB), 'BCCE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2McbLookasideList), NULL, NULL, 0, sizeof(EXT2_MCB), 'BCME', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2ExtLookasideList), NULL, NULL, 0, sizeof(EXT2_EXTENT), 'STXE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2DentryLookasideList), NULL, NULL, 0, sizeof(struct dentry), 'TNED', 0 ); RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME); IoCreateSymbolicLink(&DosDeviceName, &DeviceName); #if EXT2_DEBUG ProcessNameOffset = Ext2GetProcessNameOffset(); #endif Ext2LoadAllNls(); Ext2Global->Codepage.PageTable = load_nls(Ext2Global->Codepage.AnsiName); /* register file system devices for disk and cdrom */ IoRegisterFileSystem(DiskdevObject); ObReferenceObject(DiskdevObject); IoRegisterFileSystem(CdromdevObject); ObReferenceObject(CdromdevObject); errorout: if (!NT_SUCCESS(Status)) { /* * stop reaper thread ... */ /* * cleanup resources ... */ if (Ext2Global) { ExDeleteResourceLite(&Ext2Global->Resource); Ext2FreePool(Ext2Global, 'LG2E'); } if (CdromdevObject) { IoDeleteDevice(CdromdevObject); } if (DiskdevObject) { IoDeleteDevice(DiskdevObject); } if (journal_module_inited) { /* cleanup journal related caches */ UNLOAD_MODULE(journal_exit); } if (linux_lib_inited) { /* cleanup linux lib */ ext2_destroy_linux(); } } return Status; }
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: This routine gets called by the system to initialize the driver. Arguments: DriverObject - the system supplied driver object. RegistryPath - the system supplied registry path for this driver. Return Value: NTSTATUS --*/ { PDEVICE_OBJECT deviceObject; NTSTATUS status; PFAST_IO_DISPATCH fastIoDispatch; UNICODE_STRING functionName; FS_FILTER_CALLBACKS filterCallbacks; PDOKAN_GLOBAL dokanGlobal = NULL; DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__, __TIME__); status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal); if (status != STATUS_SUCCESS) { return status; } // // Set up dispatch entry points for the driver. // DriverObject->DriverUnload = DokanUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DokanDispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DokanDispatchClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DokanDispatchCleanup; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DokanDispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanDispatchFileSystemControl; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DokanDispatchDirectoryControl; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DokanDispatchQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DokanDispatchSetInformation; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = DokanDispatchQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = DokanDispatchSetVolumeInformation; DriverObject->MajorFunction[IRP_MJ_READ] = DokanDispatchRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = DokanDispatchWrite; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DokanDispatchFlush; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DokanDispatchShutdown; DriverObject->MajorFunction[IRP_MJ_PNP] = DokanDispatchPnp; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DokanDispatchLock; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = DokanDispatchQuerySecurity; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = DokanDispatchSetSecurity; fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH)); // TODO: check fastIoDispatch RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible; //fastIoDispatch->FastIoRead = DokanFastIoRead; fastIoDispatch->FastIoRead = FsRtlCopyRead; fastIoDispatch->FastIoWrite = FsRtlCopyWrite; fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection; fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection; fastIoDispatch->MdlRead = FsRtlMdlReadDev; fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev; fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev; fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev; DriverObject->FastIoDispatch = fastIoDispatch; ExInitializeNPagedLookasideList( &DokanIrpEntryLookasideList, NULL, NULL, 0, sizeof(IRP_ENTRY), TAG, 0); #if _WIN32_WINNT < 0x0501 RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts"); DokanFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress(&functionName); #endif RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS)); // only be used by filter driver? filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); filterCallbacks.PreAcquireForSectionSynchronization = DokanFilterCallbackAcquireForCreateSection; status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks); if (!NT_SUCCESS(status)) { IoDeleteDevice(dokanGlobal->DeviceObject); DDbgPrint(" FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n", status); return status; } DDbgPrint("<== DriverEntry\n"); return( status ); }
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 DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath ) /*++ Routine Description: This is the initialization routine for the Cdrom 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. --*/ { NTSTATUS Status; UNICODE_STRING UnicodeString; PDEVICE_OBJECT CdfsFileSystemDeviceObject; FS_FILTER_CALLBACKS FilterCallbacks; UNREFERENCED_PARAMETER( RegistryPath ); // // Create the device object. // RtlInitUnicodeString( &UnicodeString, L"\\Cdfs" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &CdfsFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } #pragma prefast(push) #pragma prefast(disable: 28155, "the dispatch routine has the correct type, prefast is just being paranoid.") #pragma prefast(disable: 28168, "the dispatch routine has the correct type, prefast is just being paranoid.") #pragma prefast(disable: 28169, "the dispatch routine has the correct type, prefast is just being paranoid.") #pragma prefast(disable: 28175, "we're allowed to change these.") DriverObject->DriverUnload = CdUnload; // // 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. // // NOTE - Each entry in the dispatch table must have an entry in // the Fsp/Fsd dispatch switch statements. // DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DriverObject->MajorFunction[IRP_MJ_PNP] = DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH) CdFsdDispatch; #pragma prefast(pop) #pragma prefast(suppress: 28175, "this is a file system driver, we're allowed to touch FastIoDispatch.") DriverObject->FastIoDispatch = &CdFastIoDispatch; // // Initialize the filter callbacks we use. // RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = CdFilterCallbackAcquireForCreateSection; Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( CdfsFileSystemDeviceObject ); return Status; } // // Initialize the global data structures // Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject ); if (!NT_SUCCESS (Status)) { IoDeleteDevice (CdfsFileSystemDeviceObject); return Status; } // // Register the file system as low priority with the I/O system. This will cause // CDFS to receive mount requests after a) other filesystems currently registered // and b) other normal priority filesystems that may be registered later. // CdfsFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM; IoRegisterFileSystem( CdfsFileSystemDeviceObject ); ObReferenceObject (CdfsFileSystemDeviceObject); // // And return to our caller // return( STATUS_SUCCESS ); }
NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine gets called by the system to initialize the driver. Arguments: DriverObject - the system supplied driver object. RegistryPath - the system supplied registry path for this driver. Return Value: NTSTATUS --*/ { NTSTATUS status; PFAST_IO_DISPATCH fastIoDispatch; FS_FILTER_CALLBACKS filterCallbacks; PDOKAN_GLOBAL dokanGlobal = NULL; UNREFERENCED_PARAMETER(RegistryPath); DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__, __TIME__); status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal); if (NT_ERROR(status)) { return status; } // // Set up dispatch entry points for the driver. // DriverObject->DriverUnload = DokanUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_READ] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_WRITE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_PNP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = DokanBuildRequest; fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH)); if (!fastIoDispatch) { CleanupGlobalDiskDevice(dokanGlobal); DDbgPrint(" ExAllocatePool failed"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible; // fastIoDispatch->FastIoRead = DokanFastIoRead; fastIoDispatch->FastIoRead = FsRtlCopyRead; fastIoDispatch->FastIoWrite = FsRtlCopyWrite; fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection; fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection; fastIoDispatch->MdlRead = FsRtlMdlReadDev; fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev; fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev; fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev; DriverObject->FastIoDispatch = fastIoDispatch; #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, POOL_NX_ALLOCATION, sizeof(IRP_ENTRY), TAG, 0); #else ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, 0, sizeof(IRP_ENTRY), TAG, 0); #endif #if _WIN32_WINNT < 0x0501 RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts"); DokanFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress(&functionName); #endif RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS)); // only be used by filter driver? filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); filterCallbacks.PreAcquireForSectionSynchronization = DokanFilterCallbackAcquireForCreateSection; status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks); if (!NT_SUCCESS(status)) { CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); DDbgPrint(" FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n", status); return status; } if (!DokanLookasideCreate(&g_DokanCCBLookasideList, sizeof(DokanCCB))) { DDbgPrint(" DokanLookasideCreate g_DokanCCBLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanFCBLookasideList, sizeof(DokanFCB))) { DDbgPrint(" DokanLookasideCreate g_DokanFCBLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanEResourceLookasideList, sizeof(ERESOURCE))) { DDbgPrint(" DokanLookasideCreate g_DokanEResourceLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); ExDeleteLookasideListEx(&g_DokanFCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } DDbgPrint("<== DriverEntry\n"); return (status); }