Beispiel #1
0
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;
}
Beispiel #2
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
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;
}