/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: init.c * PROGRAMMER: Matt Wu * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */ /* INCLUDES *****************************************************************/ #include "ext2fs.h" /* GLOBALS ***************************************************************/ PEXT2_GLOBAL Ext2Global = NULL; /* * Ext2Fsd version, building date/time */ CHAR gVersion[] = EXT2FSD_VERSION; CHAR gTime[] = __TIME__; CHAR gDate[] = __DATE__; /* DEFINITIONS ***********************************************************/ NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, Ext2QueryGlobalParameters) #pragma alloc_text(INIT, Ext2QueryRegistrySettings) #pragma alloc_text(INIT, DriverEntry) #if EXT2_UNLOAD #pragma alloc_text(PAGE, DriverUnload) #endif #endif /* FUNCTIONS ***************************************************************/ DECLARE_INIT(journal_init); DECLARE_EXIT(journal_exit); #if EXT2_UNLOAD /* * FUNCTION: Called by the system to unload the driver * ARGUMENTS: * DriverObject = object describing this driver * RETURNS: None */ VOID NTAPI DriverUnload (IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DosDeviceName; DEBUG(DL_FUN, ( "Ext2Fsd: Unloading routine.\n")); /* * stop reaper thread ... */ /* * removing memory allocations and objects */ RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME); IoDeleteSymbolicLink(&DosDeviceName); Ext2UnloadAllNls(); ExDeleteResourceLite(&Ext2Global->Resource); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2DentryLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2ExtLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2McbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2CcbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2FcbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2IrpContextLookasideList)); ObDereferenceObject(Ext2Global->DiskdevObject); ObDereferenceObject(Ext2Global->CdromdevObject); /* cleanup journal related caches */ UNLOAD_MODULE(journal_exit); /* cleanup linux lib */ ext2_destroy_linux(); Ext2FreePool(Ext2Global, 'LG2E'); Ext2Global = NULL; } #endif NTSTATUS NTAPI Ext2RegistryQueryCallback( IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext ) { ULONG i = 0; BYTE *s, *t; if (NULL == ValueName || NULL == ValueData) return STATUS_SUCCESS; if (ValueType == REG_DWORD && wcslen(ValueName) == wcslen(WRITING_SUPPORT) && _wcsnicmp(ValueName, WRITING_SUPPORT, wcslen(WRITING_SUPPORT)) == 0) { if (ValueData && ValueLength == sizeof(DWORD)) { if (*((PULONG)ValueData)) { SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } } } else if (ValueType == REG_DWORD && wcslen(ValueName) == wcslen(CHECKING_BITMAP) && _wcsnicmp(ValueName, CHECKING_BITMAP, wcslen(CHECKING_BITMAP)) == 0) { if (ValueData && ValueLength == sizeof(DWORD)) { if (*((PULONG)ValueData)) { SetLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP); } else { ClearLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP); } } } else if (ValueType == REG_DWORD && wcslen(ValueName) == wcslen(EXT3_FORCEWRITING) && _wcsnicmp(ValueName, EXT3_FORCEWRITING, wcslen(EXT3_FORCEWRITING)) == 0) { if (ValueData && ValueLength == sizeof(DWORD)) { if (*((PULONG)ValueData)) { SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } } } else if (ValueType == REG_DWORD && wcslen(ValueName) == wcslen(AUTO_MOUNT) && _wcsnicmp(ValueName, AUTO_MOUNT, wcslen(AUTO_MOUNT)) == 0) { if (ValueData && ValueLength == sizeof(DWORD)) { if (*((PULONG)ValueData)) { SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } else { ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } } } else if (ValueType == REG_SZ && wcslen(ValueName) == wcslen(CODEPAGE_NAME) && _wcsnicmp(ValueName, CODEPAGE_NAME, wcslen(CODEPAGE_NAME)) == 0) { if (ValueData && ValueLength <= sizeof(WCHAR) * CODEPAGE_MAXLEN) { RtlCopyMemory(&Ext2Global->Codepage.PageName[0], ValueData, ValueLength); } } else if (ValueType == REG_SZ && wcslen(ValueName) == wcslen(HIDING_PREFIX) && _wcsnicmp(ValueName, HIDING_PREFIX, wcslen(HIDING_PREFIX)) == 0) { if (ValueData && ValueLength <= sizeof(WCHAR) * HIDINGPAT_LEN) { RtlCopyMemory(&Ext2Global->wHidingPrefix[0], ValueData, ValueLength); } } else if (ValueType == REG_SZ && wcslen(ValueName) == wcslen(HIDING_SUFFIX) && _wcsnicmp(ValueName, HIDING_SUFFIX, wcslen(HIDING_SUFFIX)) == 0) { if (ValueData && ValueLength <= sizeof(WCHAR) * HIDINGPAT_LEN) { RtlCopyMemory(&Ext2Global->wHidingSuffix[0], ValueData, ValueLength); } } return STATUS_SUCCESS; } NTSTATUS Ext2QueryGlobalParameters(IN PUNICODE_STRING RegistryPath) { RTL_QUERY_REGISTRY_TABLE QueryTable[8]; int i = 0; NTSTATUS Status; RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 8); /* * 1 writing support */ QueryTable[i].Flags = 0; QueryTable[i].Name = WRITING_SUPPORT; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 2 checking bitmap */ QueryTable[i].Flags = 0; QueryTable[i].Name = CHECKING_BITMAP; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 3 force writing */ QueryTable[i].Flags = 0; QueryTable[i].Name = EXT3_FORCEWRITING; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 4 automount */ QueryTable[i].Flags = 0; QueryTable[i].Name = AUTO_MOUNT; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 5 codepage */ QueryTable[i].Flags = 0; QueryTable[i].Name = CODEPAGE_NAME; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 6 hidden prefix */ QueryTable[i].Flags = 0; QueryTable[i].Name = HIDING_PREFIX; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; /* * 7 hidden suffix */ QueryTable[i].Flags = 0; QueryTable[i].Name = HIDING_SUFFIX; QueryTable[i].DefaultType = REG_NONE; QueryTable[i].DefaultLength = 0; QueryTable[i].DefaultData = NULL; QueryTable[i].EntryContext = NULL; QueryTable[i].QueryRoutine = Ext2RegistryQueryCallback; i++; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, RegistryPath->Buffer, &QueryTable[0], NULL, NULL ); return NT_SUCCESS(Status); } BOOLEAN Ext2QueryRegistrySettings(IN PUNICODE_STRING RegistryPath) { UNICODE_STRING ParameterPath; UNICODE_STRING UniName; ANSI_STRING AnsiName; ULONG WritingSupport = 0; ULONG CheckingBitmap = 0; ULONG Ext3ForceWriting = 0; ULONG AutoMount = 0; WCHAR UniBuffer[CODEPAGE_MAXLEN]; USHORT Buffer[HIDINGPAT_LEN]; NTSTATUS Status; ParameterPath.Length = 0; ParameterPath.MaximumLength = RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR); ParameterPath.Buffer = (PWSTR) Ext2AllocatePool( PagedPool, ParameterPath.MaximumLength, 'LG2E' ); if (!ParameterPath.Buffer) { DbgBreak(); DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n")); return FALSE; } RtlCopyUnicodeString(&ParameterPath, RegistryPath); RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY); /* enable automount of ext2/3/4 volumes */ SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); /* query parameter settings from registry */ Ext2QueryGlobalParameters(&ParameterPath); /* set global codepage settings */ if (wcslen(&Ext2Global->Codepage.PageName[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->Codepage.PageName[0]); UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->Codepage.PageName[0]; AnsiName.MaximumLength = CODEPAGE_MAXLEN; AnsiName.Length = 0; AnsiName.Buffer = &Ext2Global->Codepage.AnsiName[0]; Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName)); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n")); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0; /* set global hidden prefix pattern */ if (wcslen(&Ext2Global->wHidingPrefix[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingPrefix[0]); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->wHidingPrefix[0]; AnsiName.MaximumLength = HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingPrefix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; /* set global hidden suffix pattern */ if (wcslen(&Ext2Global->wHidingSuffix[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingSuffix[0]); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->wHidingSuffix[0]; AnsiName.MaximumLength = HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingSuffix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer; Ext2Global->RegistryPath.Length = 0; Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength; RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath); RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY); return TRUE; } #define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo) #ifndef __REACTOS__ #define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \ (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ (NLS_MB_CODE_PAGE_TAG && \ (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ ) #endif VOID Ext2EresourceAlignmentChecking() { /* Verify ERESOURCE alignment in structures */ CL_ASSERT((FIELD_OFFSET(EXT2_GLOBAL, Resource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, MainResource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, PagingIoResource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, MetaInode) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, MetaBlock) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, McbLock) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, FcbLock) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, bd.bd_bh_lock) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_VCB, sbi.s_gd_lock) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_FCBVCB, MainResource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_FCBVCB, PagingIoResource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_FCB, MainResource) & 7) == 0); CL_ASSERT((FIELD_OFFSET(EXT2_FCB, PagingIoResource) & 7) == 0); } /* * 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 NTAPI 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; } #ifdef _PNP_POWER_ DiskdevObject->DeviceObjectExtension->PowerControlNeeded = FALSE; CdromdevObject->DeviceObjectExtension->PowerControlNeeded = FALSE; #endif /* 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_QUERY_EA] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_EA] = 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; }