Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: init.c * PROGRAMMER: Matt Wu <mattwu@163.com> * 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 ***********************************************************/
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifDriverEntry( 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 */#ifdef __REACTOS__VOID NTAPI#elseVOID#endifDriverUnload (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
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2RegistryQueryCallback( 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;}
NTSTATUSExt2QueryGlobalParameters(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);}
BOOLEANExt2QueryRegistrySettings(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
VOIDExt2EresourceAlignmentChecking(){ /* 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 */#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifDriverEntry ( 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;}