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; }
/* * 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; LARGE_INTEGER Timeout; NTSTATUS Status; int rc = 0; BOOLEAN linux_lib_inited = FALSE; BOOLEAN journal_module_inited = FALSE; /* Verify ERESOURCE alignment in structures */ ASSERT((FIELD_OFFSET(EXT2_GLOBAL, Resource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_VCB, MainResource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_VCB, PagingIoResource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_VCB, MetaLock) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_VCB, McbLock) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_FCBVCB, MainResource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_FCBVCB, PagingIoResource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_FCB, MainResource) & 7) == 0); ASSERT((FIELD_OFFSET(EXT2_FCB, PagingIoResource) & 7) == 0); /* 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)); /* Reaper thread engine event */ KeInitializeEvent(&Ext2Global->Reaper.Engine, SynchronizationEvent, FALSE); /* query registry settings */ Ext2QueryGlobalParameters(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; } /* start resource reaper thread */ Status= Ext2StartReaperThread(); if (!NT_SUCCESS(Status)) { goto errorout; } /* make sure Reaperthread is started */ Timeout.QuadPart = (LONGLONG)-10*1000*1000*10; /* 10 seconds */ Status = KeWaitForSingleObject( &(Ext2Global->Reaper.Engine), Executive, KernelMode, FALSE, &Timeout ); if (Status != STATUS_SUCCESS) { Status = STATUS_INSUFFICIENT_RESOURCES; 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->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; // // 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; }