reactos/drivers/filesystems/ext2/src/init.c
Pierre Schweitzer a1d7e9936d
[EXT2] Upgrade to 0.69
CORE-13980
2017-11-12 10:48:17 +01:00

840 lines
28 KiB
C

/*
* 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 ***********************************************************/
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;
}