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 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 ); }