Пример #1
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;

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

    /* 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->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;
}
Пример #2
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the Fat file system
    device driver.  This routine creates the device object for the FileSystem
    device and performs all other driver initialization.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

    NTSTATUS - The function value is the final status from the initialization
        operation.

--*/

{
    USHORT MaxDepth;
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    FS_FILTER_CALLBACKS FilterCallbacks;
    UNICODE_STRING ValueName;
    ULONG Value;

#if __NDAS_FAT__
	UNICODE_STRING	linkString;
	UNICODE_STRING	functionName;
	UNICODE_STRING	tempUnicode;
#endif

#if DBG
	DbgPrint( "NdasFat DriverEntry %s %s\n", __DATE__, __TIME__ );
#endif

#if __NDAS_FAT_DBG__

	FatDebugTraceLevel |= DEBUG_TRACE_ERROR;
	FatDebugTraceLevel |= DEBUG_TRACE_CLEANUP;
	FatDebugTraceLevel |= DEBUG_TRACE_CLOSE;
	FatDebugTraceLevel |= DEBUG_TRACE_CREATE;
	FatDebugTraceLevel |= DEBUG_TRACE_DIRCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_EA;
	FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO;
	FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_LOCKCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_READ;
	FatDebugTraceLevel |= DEBUG_TRACE_VOLINFO;
	FatDebugTraceLevel |= DEBUG_TRACE_WRITE;
	FatDebugTraceLevel |= DEBUG_TRACE_DEVCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_FLUSH;
	FatDebugTraceLevel |= DEBUG_TRACE_PNP;
	FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN;
	
	FatDebugTraceLevel = 0x00000009;

	//FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL;
	//FatDebugTraceLevel |= DEBUG_INFO_DEVCTRL;
	FatDebugTraceLevel |= DEBUG_INFO_FSCTRL;
	FatDebugTraceLevel |= DEBUG_INFO_READ;
	FatDebugTraceLevel |= DEBUG_INFO_SECONDARY;
	//FatDebugTraceLevel |= DEBUG_INFO_PRIMARY;
	FatDebugTraceLevel |= DEBUG_INFO_FILOBSUP;
	FatDebugTraceLevel |= DEBUG_TRACE_PNP;
	FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN;
	FatDebugTraceLevel |= DEBUG_INFO_FILEINFO;
	FatDebugTraceLevel |= DEBUG_INFO_CREATE;
	FatDebugTraceLevel |= DEBUG_INFO_STRUCSUP;
	FatDebugTraceLevel |= DEBUG_INFO_CLEANUP;
	FatDebugTraceLevel |= DEBUG_INFO_CLOSE;
	FatDebugTraceLevel |= DEBUG_INFO_ALL;
	FatDebugTraceLevel |= DEBUG_INFO_WRITE;
	//FatDebugTraceLevel |= DEBUG_TRACE_WRITE;
	FatDebugTraceLevel &= ~DEBUG_TRACE_UNWIND;
	//FatDebugTraceLevel = 0xFFFFFFFFFFFFFFFF;
	//FatDebugTraceLevel |= DEBUG_TRACE_STRUCSUP;
	FatDebugTraceLevel |= DEBUG_INFO_FILEINFO;
	//FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO;

	DebugTrace2( 0, DEBUG_INFO_ALL, ("sizeof(NDFS_WINXP_REPLY_HEADER) = %d\n", sizeof(NDFS_WINXP_REPLY_HEADER)) );

#endif

#if __NDAS_FAT_WIN2K_SUPPORT__

	PsGetVersion( &gOsMajorVersion,
                  &gOsMinorVersion,
                  NULL,
                  NULL );

	RtlInitUnicodeString( &functionName, L"SeFilterToken" );
	NdasFatSeFilterToken = MmGetSystemRoutineAddress( &functionName );

	if (IS_WINDOWSXP_OR_LATER()) { // to prevent incomprehensible error
	
		RtlInitUnicodeString( &functionName, L"CcMdlWriteAbort" ); 
		NdasFatCcMdlWriteAbort = MmGetSystemRoutineAddress( &functionName );
	}

	RtlInitUnicodeString( &functionName, L"KeAreApcsDisabled" );
	NdasFatKeAreApcsDisabled = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"KeAreAllApcsDisabled" );
	NdasFatKeAreAllApcsDisabled = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"FsRtlRegisterFileSystemFilterCallbacks" );
	NdasFatFsRtlRegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"FsRtlAreVolumeStartupApplicationsComplete" );
	NdasFatFsRtlAreVolumeStartupApplicationsComplete = MmGetSystemRoutineAddress( &functionName );
	
	RtlInitUnicodeString( &functionName, L"MmDoesFileHaveUserWritableReferences" );
	NdasFatMmDoesFileHaveUserWritableReferences = MmGetSystemRoutineAddress( &functionName );

#endif

#if __NDAS_FAT__
	
    RtlInitUnicodeString( &UnicodeString, NDAS_FAT_CONTROL_DEVICE_NAME );

    Status = IoCreateDevice( DriverObject,
                             0,                 //  has no device extension
                             &UnicodeString,
                             FILE_DEVICE_NULL,
                             0,
                             FALSE,
                             &FatControlDeviceObject );

	if (!NT_SUCCESS( Status )) {

		return Status;
	}

    RtlInitUnicodeString( &linkString, NDAS_FAT_CONTROL_LINK_NAME );
    Status = IoCreateSymbolicLink( &linkString, &UnicodeString );

    if (!NT_SUCCESS(Status)) {
		
        IoDeleteDevice( FatControlDeviceObject );
	    return Status;
    }

#endif

#if __NDAS_FAT__

    RtlInitUnicodeString( &UnicodeString, NDAS_FAT_DEVICE_NAME );

    Status = IoCreateDevice( DriverObject,
                             sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT),
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatDiskFileSystemDeviceObject );

	if (!NT_SUCCESS(Status)) {
		
        IoDeleteSymbolicLink( &linkString );
        IoDeleteDevice( FatControlDeviceObject );
	    return Status;
    }

	RtlZeroMemory( (PUCHAR)FatDiskFileSystemDeviceObject+sizeof(DEVICE_OBJECT), 
				   sizeof(VOLUME_DEVICE_OBJECT)-sizeof(DEVICE_OBJECT) );

#else

    //
    // Create the device object for disks.  To avoid problems with filters who
    // know this name, we must keep it.
    //

    RtlInitUnicodeString( &UnicodeString, L"\\Fat" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatDiskFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        return Status;
    }

#endif

#if !__NDAS_FAT__

    //
    // Create the device object for "cdroms".
    //

    RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_CD_ROM_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatCdromFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        IoDeleteDevice( FatDiskFileSystemDeviceObject);
        return Status;
    }

#endif

    DriverObject->DriverUnload = FatUnload;

    //
    //  Note that because of the way data caching is done, we set neither
    //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    //  data is not in the cache, or the request is not buffered, we may,
    //  set up for Direct I/O by hand.
    //

    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = (PDRIVER_DISPATCH)FatFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)FatFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)FatFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = (PDRIVER_DISPATCH)FatFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = (PDRIVER_DISPATCH)FatFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = (PDRIVER_DISPATCH)FatFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = (PDRIVER_DISPATCH)FatFsdQueryEa;
    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = (PDRIVER_DISPATCH)FatFsdSetEa;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = (PDRIVER_DISPATCH)FatFsdFlushBuffers;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = (PDRIVER_DISPATCH)FatFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = (PDRIVER_DISPATCH)FatFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = (PDRIVER_DISPATCH)FatFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = (PDRIVER_DISPATCH)FatFsdLockControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = (PDRIVER_DISPATCH)FatFsdDeviceControl;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = (PDRIVER_DISPATCH)FatFsdShutdown;
    DriverObject->MajorFunction[IRP_MJ_PNP]                      = (PDRIVER_DISPATCH)FatFsdPnp;

    DriverObject->FastIoDispatch = &FatFastIoDispatch;

    RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch));

    FatFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    FatFastIoDispatch.FastIoCheckIfPossible =   FatFastIoCheckIfPossible;  //  CheckForFastIo
    FatFastIoDispatch.FastIoRead =              FsRtlCopyRead;             //  Read
    FatFastIoDispatch.FastIoWrite =             FsRtlCopyWrite;            //  Write
    FatFastIoDispatch.FastIoQueryBasicInfo =    FatFastQueryBasicInfo;     //  QueryBasicInfo
    FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo;       //  QueryStandardInfo
    FatFastIoDispatch.FastIoLock =              FatFastLock;               //  Lock
    FatFastIoDispatch.FastIoUnlockSingle =      FatFastUnlockSingle;       //  UnlockSingle
    FatFastIoDispatch.FastIoUnlockAll =         FatFastUnlockAll;          //  UnlockAll
    FatFastIoDispatch.FastIoUnlockAllByKey =    FatFastUnlockAllByKey;     //  UnlockAllByKey
    FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo;
    FatFastIoDispatch.AcquireForCcFlush =       FatAcquireForCcFlush;
    FatFastIoDispatch.ReleaseForCcFlush =       FatReleaseForCcFlush;
    FatFastIoDispatch.MdlRead =                 FsRtlMdlReadDev;
    FatFastIoDispatch.MdlReadComplete =         FsRtlMdlReadCompleteDev;
    FatFastIoDispatch.PrepareMdlWrite =         FsRtlPrepareMdlWriteDev;
    FatFastIoDispatch.MdlWriteComplete =        FsRtlMdlWriteCompleteDev;
    
#if __NDAS_FAT_SECONDARY__

	RtlZeroMemory(&FatFastIoDispatch, sizeof(FAST_IO_DISPATCH));
	FatFastIoDispatch.SizeOfFastIoDispatch			 =	sizeof(FAST_IO_DISPATCH);

	//FatFastIoDispatch.FastIoCheckIfPossible			=	FatFastIoCheckIfPossible;  //  CheckForFastIo
	//FatFastIoDispatch.AcquireForModWrite				=	FatAcquireFileForModWrite;
	//FatFastIoDispatch.AcquireFileForNtCreateSection	=  FatAcquireForCreateSection;
	//FatFastIoDispatch.ReleaseFileForNtCreateSection	=  FatReleaseForCreateSection;

	FatFastIoDispatch.AcquireForCcFlush				=  FatAcquireForCcFlush;
	FatFastIoDispatch.ReleaseForCcFlush				=  FatReleaseForCcFlush;

#endif

    //
    //  Initialize the filter callbacks we use.
    //

#if __NDAS_FAT__

	if (IS_WINDOWSVISTA_OR_LATER()) {

#if __NDAS_FAT_WIN2K_SUPPORT__

	if (NdasFatFsRtlRegisterFileSystemFilterCallbacks) {

		RtlZeroMemory( &FilterCallbacks,
		               sizeof(FS_FILTER_CALLBACKS) );

		FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);

		FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection;

	    Status = NdasFatFsRtlRegisterFileSystemFilterCallbacks( DriverObject,
															  &FilterCallbacks );

	    if (!NT_SUCCESS( Status )) {

		    IoDeleteDevice( FatDiskFileSystemDeviceObject );
			IoDeleteDevice( FatCdromFileSystemDeviceObject );
			return Status;
		}
	}

#else

    RtlZeroMemory( &FilterCallbacks,
                   sizeof(FS_FILTER_CALLBACKS) );

    FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
    FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection;

    Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject,
                                                     &FilterCallbacks );

    if (!NT_SUCCESS( Status )) {

        IoDeleteDevice( FatDiskFileSystemDeviceObject );
        IoDeleteDevice( FatCdromFileSystemDeviceObject );
        return Status;
    }

#endif

	}

#endif

    //
    //  Initialize the global data structures
    //

    //
    //  The FatData record
    //

    RtlZeroMemory( &FatData, sizeof(FAT_DATA));

    FatData.NodeTypeCode = FAT_NTC_DATA_HEADER;
    FatData.NodeByteSize = sizeof(FAT_DATA);

    InitializeListHead(&FatData.VcbQueue);

    FatData.DriverObject = DriverObject;
    FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject;
    FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject;

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &FatData.AsyncCloseList );
    InitializeListHead( &FatData.DelayedCloseList );
    
    FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject);

    if (FatData.FatCloseItem == NULL) {
        IoDeleteDevice (FatDiskFileSystemDeviceObject);
#if __NDAS_FAT__
		if (FatCdromFileSystemDeviceObject)
#endif
        IoDeleteDevice (FatCdromFileSystemDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    //  Now initialize our general purpose spinlock (gag) and figure out how
    //  deep and wide we want our delayed lists (along with fooling ourselves
    //  about the lookaside depths).
    //

    KeInitializeSpinLock( &FatData.GeneralSpinLock );

    switch ( MmQuerySystemSize() ) {

    case MmSmallSystem:

        MaxDepth = 4;
        FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES;
        break;

    case MmMediumSystem:

        MaxDepth = 8;
        FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES;
        break;

    case MmLargeSystem:

        MaxDepth = 16;
        FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES;
        break;
    }


    //
    //  Initialize the cache manager callback routines
    //

    FatData.CacheManagerCallbacks.AcquireForLazyWrite  = &FatAcquireFcbForLazyWrite;
    FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite;
    FatData.CacheManagerCallbacks.AcquireForReadAhead  = &FatAcquireFcbForReadAhead;
    FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead;

    FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease;
    FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease;

    //
    //  Set up global pointer to our process.
    //

    FatData.OurProcess = PsGetCurrentProcess();

    //
    //  Read the registry to determine if we are in ChicagoMode.
    //

    ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
    ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.ChicagoMode = FALSE;

    } else {

        FatData.ChicagoMode = TRUE;
    }

    //
    //  Read the registry to determine if we are going to generate LFNs
    //  for valid 8.3 names with extended characters.
    //

    ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME;
    ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.CodePageInvariant = FALSE;

    } else {

        FatData.CodePageInvariant = TRUE;
    }

    //
    //  Initialize our global resource and fire up the lookaside lists.
    //

    ExInitializeResourceLite( &FatData.Resource );

    ExInitializeNPagedLookasideList( &FatIrpContextLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(IRP_CONTEXT),
                                     TAG_IRP_CONTEXT,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(NON_PAGED_FCB),
                                     TAG_FCB_NONPAGED,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatEResourceLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(ERESOURCE),
                                     TAG_ERESOURCE,
                                     MaxDepth );

    ExInitializeSListHead( &FatCloseContextSList );
    ExInitializeFastMutex( &FatCloseQueueMutex );
    KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE );

    //
    //  Register the file system with the I/O system
    //

    IoRegisterFileSystem(FatDiskFileSystemDeviceObject);
    ObReferenceObject (FatDiskFileSystemDeviceObject);
#if __NDAS_FAT__
	if (FatCdromFileSystemDeviceObject) {

		IoRegisterFileSystem(FatCdromFileSystemDeviceObject);
		ObReferenceObject (FatCdromFileSystemDeviceObject);
	}
#else
    IoRegisterFileSystem(FatCdromFileSystemDeviceObject);
    ObReferenceObject (FatCdromFileSystemDeviceObject);
#endif

#if __NDAS_FAT__

	FatData.FileSystemRegistered = TRUE;

	RtlInitEmptyUnicodeString( &FatData.Root, 
							   FatData.RootBuffer,
							   sizeof(FatData.RootBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\" );
	RtlCopyUnicodeString( &FatData.Root, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.MountMgrRemoteDatabase, 
							   FatData.MountMgrRemoteDatabaseBuffer,
							   sizeof(FatData.MountMgrRemoteDatabaseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\:$MountMgrRemoteDatabase" );
	RtlCopyUnicodeString( &FatData.MountMgrRemoteDatabase, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.ExtendReparse, 
							   FatData.ExtendReparseBuffer,
							   sizeof(FatData.ExtendReparseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION" );
	RtlCopyUnicodeString( &FatData.ExtendReparse, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.MountPointManagerRemoteDatabase, 
							   FatData.MountPointManagerRemoteDatabaseBuffer,
							   sizeof(FatData.MountPointManagerRemoteDatabaseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\System Volume Information\\MountPointManagerRemoteDatabase" );
	RtlCopyUnicodeString( &FatData.MountPointManagerRemoteDatabase, &tempUnicode );

#endif

    //
    //  Find out if we are running an a FujitsuFMR machine.
    //

    FatData.FujitsuFMR = FatIsFujitsuFMR();

#if __NDAS_FAT__

    //
    //  Check to see if new kernel is present to decide if we want
    //  to support advance fcb headers
    //

    RtlInitUnicodeString( &UnicodeString, L"FsRtlTeardownPerStreamContexts" );
    FatFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress( &UnicodeString );

#endif

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
Пример #3
0
NTSTATUS
DriverEntry(
	__in PDRIVER_OBJECT  DriverObject,
	__in PUNICODE_STRING RegistryPath
	)

/*++

Routine Description:

	This routine gets called by the system to initialize the driver.

Arguments:

	DriverObject	- the system supplied driver object.
	RegistryPath	- the system supplied registry path for this driver.

Return Value:

	NTSTATUS

--*/

{
	PDEVICE_OBJECT		deviceObject;
	NTSTATUS			status;
	PFAST_IO_DISPATCH	fastIoDispatch;
	UNICODE_STRING		functionName;
	FS_FILTER_CALLBACKS filterCallbacks;
	PDOKAN_GLOBAL		dokanGlobal = NULL;

	DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__, __TIME__);

	status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal);

	if (status != STATUS_SUCCESS) {
		return status;
	}
	//
	// Set up dispatch entry points for the driver.
	//
	DriverObject->DriverUnload								= DokanUnload;

	DriverObject->MajorFunction[IRP_MJ_CREATE]				= DokanDispatchCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE]				= DokanDispatchClose;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] 			= DokanDispatchCleanup;

	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]		= DokanDispatchDeviceControl;
	DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanDispatchFileSystemControl;
	DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]   = DokanDispatchDirectoryControl;

	DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]   = DokanDispatchQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]     = DokanDispatchSetInformation;

    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]	= DokanDispatchQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]		= DokanDispatchSetVolumeInformation;

	DriverObject->MajorFunction[IRP_MJ_READ]				= DokanDispatchRead;
	DriverObject->MajorFunction[IRP_MJ_WRITE]				= DokanDispatchWrite;
	DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]		= DokanDispatchFlush;

	DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]            = DokanDispatchShutdown;
	DriverObject->MajorFunction[IRP_MJ_PNP]					= DokanDispatchPnp;

	DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]		= DokanDispatchLock;

	DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY]		= DokanDispatchQuerySecurity;
	DriverObject->MajorFunction[IRP_MJ_SET_SECURITY]		= DokanDispatchSetSecurity;

	fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH));
	// TODO: check fastIoDispatch

	RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH));

	fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
    fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible;
    //fastIoDispatch->FastIoRead = DokanFastIoRead;
	fastIoDispatch->FastIoRead = FsRtlCopyRead;
	fastIoDispatch->FastIoWrite = FsRtlCopyWrite;
	fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection;
	fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection;
    fastIoDispatch->MdlRead = FsRtlMdlReadDev;
    fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev;
    fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
    fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev;

	DriverObject->FastIoDispatch = fastIoDispatch;


	ExInitializeNPagedLookasideList(
		&DokanIrpEntryLookasideList, NULL, NULL, 0, sizeof(IRP_ENTRY), TAG, 0);


#if _WIN32_WINNT < 0x0501
    RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts");
    DokanFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress(&functionName);
#endif

    RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS));

	// only be used by filter driver?
	filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
	filterCallbacks.PreAcquireForSectionSynchronization = DokanFilterCallbackAcquireForCreateSection;

	status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks);

	if (!NT_SUCCESS(status)) {
		IoDeleteDevice(dokanGlobal->DeviceObject);
		DDbgPrint("  FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n", status);
		return status;
	}


	DDbgPrint("<== DriverEntry\n");

	return( status );
}
Пример #4
0
NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the Fat file system
    device driver.  This routine creates the device object for the FileSystem
    device and performs all other driver initialization.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

    NTSTATUS - The function value is the final status from the initialization
        operation.

--*/

{
    USHORT MaxDepth;
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    FS_FILTER_CALLBACKS FilterCallbacks;
    UNICODE_STRING ValueName;
    ULONG Value;

    UNREFERENCED_PARAMETER( RegistryPath );

    //
    // Create the device object for disks.  To avoid problems with filters who
    // know this name, we must keep it.
    //

    RtlInitUnicodeString( &UnicodeString, L"\\Fat" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatDiskFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        return Status;
    }

    //
    // Create the device object for "cdroms".
    //

    RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_CD_ROM_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatCdromFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        IoDeleteDevice( FatDiskFileSystemDeviceObject);
        return Status;
    }

#pragma prefast( push )
#pragma prefast( disable:28155, "these are all correct" )
#pragma prefast( disable:28169, "these are all correct" )
#pragma prefast( disable:28175, "this is a filesystem, touching FastIoDispatch is allowed" )

    DriverObject->DriverUnload = FatUnload;

    //
    //  Note that because of the way data caching is done, we set neither
    //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    //  data is not in the cache, or the request is not buffered, we may,
    //  set up for Direct I/O by hand.
    //

    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = (PDRIVER_DISPATCH)FatFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)FatFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)FatFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = (PDRIVER_DISPATCH)FatFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = (PDRIVER_DISPATCH)FatFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = (PDRIVER_DISPATCH)FatFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = (PDRIVER_DISPATCH)FatFsdQueryEa;
    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = (PDRIVER_DISPATCH)FatFsdSetEa;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = (PDRIVER_DISPATCH)FatFsdFlushBuffers;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = (PDRIVER_DISPATCH)FatFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = (PDRIVER_DISPATCH)FatFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = (PDRIVER_DISPATCH)FatFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = (PDRIVER_DISPATCH)FatFsdLockControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = (PDRIVER_DISPATCH)FatFsdDeviceControl;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = (PDRIVER_DISPATCH)FatFsdShutdown;
    DriverObject->MajorFunction[IRP_MJ_PNP]                      = (PDRIVER_DISPATCH)FatFsdPnp;

    DriverObject->FastIoDispatch = &FatFastIoDispatch;

    RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch));

    FatFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    FatFastIoDispatch.FastIoCheckIfPossible =   FatFastIoCheckIfPossible;  //  CheckForFastIo
    FatFastIoDispatch.FastIoRead =              FsRtlCopyRead;             //  Read
    FatFastIoDispatch.FastIoWrite =             FsRtlCopyWrite;            //  Write
    FatFastIoDispatch.FastIoQueryBasicInfo =    FatFastQueryBasicInfo;     //  QueryBasicInfo
    FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo;       //  QueryStandardInfo
    FatFastIoDispatch.FastIoLock =              FatFastLock;               //  Lock
    FatFastIoDispatch.FastIoUnlockSingle =      FatFastUnlockSingle;       //  UnlockSingle
    FatFastIoDispatch.FastIoUnlockAll =         FatFastUnlockAll;          //  UnlockAll
    FatFastIoDispatch.FastIoUnlockAllByKey =    FatFastUnlockAllByKey;     //  UnlockAllByKey
    FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo;
    FatFastIoDispatch.AcquireForCcFlush =       FatAcquireForCcFlush;
    FatFastIoDispatch.ReleaseForCcFlush =       FatReleaseForCcFlush;
    FatFastIoDispatch.MdlRead =                 FsRtlMdlReadDev;
    FatFastIoDispatch.MdlReadComplete =         FsRtlMdlReadCompleteDev;
    FatFastIoDispatch.PrepareMdlWrite =         FsRtlPrepareMdlWriteDev;
    FatFastIoDispatch.MdlWriteComplete =        FsRtlMdlWriteCompleteDev;

#pragma prefast( pop )
    
    //
    //  Initialize the filter callbacks we use.
    //

    RtlZeroMemory( &FilterCallbacks,
                   sizeof(FS_FILTER_CALLBACKS) );

    FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
    FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection;

    Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject,
                                                     &FilterCallbacks );

    if (!NT_SUCCESS( Status )) {

        IoDeleteDevice( FatDiskFileSystemDeviceObject );
        IoDeleteDevice( FatCdromFileSystemDeviceObject );
        return Status;
    }

    //
    //  Initialize the global data structures
    //

    //
    //  The FatData record
    //

    RtlZeroMemory( &FatData, sizeof(FAT_DATA));

    FatData.NodeTypeCode = FAT_NTC_DATA_HEADER;
    FatData.NodeByteSize = sizeof(FAT_DATA);

    InitializeListHead(&FatData.VcbQueue);

    FatData.DriverObject = DriverObject;
    FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject;
    FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject;

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &FatData.AsyncCloseList );
    InitializeListHead( &FatData.DelayedCloseList );
    
    FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject);

    if (FatData.FatCloseItem == NULL) {
        IoDeleteDevice (FatDiskFileSystemDeviceObject);
        IoDeleteDevice (FatCdromFileSystemDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    //  Allocate the zero page
    //

    FatData.ZeroPage = ExAllocatePoolWithTag( NonPagedPoolNx, PAGE_SIZE, 'ZtaF' );
    if (FatData.ZeroPage == NULL) {
        IoDeleteDevice (FatDiskFileSystemDeviceObject);
        IoDeleteDevice (FatCdromFileSystemDeviceObject);        
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlZeroMemory( FatData.ZeroPage, PAGE_SIZE );


    //
    //  Now initialize our general purpose spinlock (gag) and figure out how
    //  deep and wide we want our delayed lists (along with fooling ourselves
    //  about the lookaside depths).
    //

    KeInitializeSpinLock( &FatData.GeneralSpinLock );

    switch ( MmQuerySystemSize() ) {

    case MmSmallSystem:

        MaxDepth = 4;
        FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES;
        break;

    case MmMediumSystem:

        MaxDepth = 8;
        FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES;
        break;

    case MmLargeSystem:
    default:
        
        MaxDepth = 16;
        FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES;
        break;
    }


    //
    //  Initialize the cache manager callback routines
    //

    FatData.CacheManagerCallbacks.AcquireForLazyWrite  = &FatAcquireFcbForLazyWrite;
    FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite;
    FatData.CacheManagerCallbacks.AcquireForReadAhead  = &FatAcquireFcbForReadAhead;
    FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead;

    FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease;
    FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease;

    //
    //  Set up global pointer to our process.
    //

    FatData.OurProcess = PsGetCurrentProcess();

    // 
    //  Setup the number of processors we support for statistics as the current number 
    //  running.
    //

#if (NTDDI_VERSION >= NTDDI_VISTA)
    FatData.NumberProcessors = KeQueryActiveProcessorCount( NULL );
#else
    FatData.NumberProcessors = KeNumberProcessors;
#endif


    //
    //  Read the registry to determine if we are in ChicagoMode.
    //

    ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
    ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.ChicagoMode = FALSE;

    } else {

        FatData.ChicagoMode = TRUE;
    }

    //
    //  Read the registry to determine if we are going to generate LFNs
    //  for valid 8.3 names with extended characters.
    //

    ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME;
    ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.CodePageInvariant = FALSE;

    } else {

        FatData.CodePageInvariant = TRUE;
    }

    //
    //  Initialize our global resource and fire up the lookaside lists.
    //

    ExInitializeResourceLite( &FatData.Resource );

    ExInitializeNPagedLookasideList( &FatIrpContextLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(IRP_CONTEXT),
                                     TAG_IRP_CONTEXT,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(NON_PAGED_FCB),
                                     TAG_FCB_NONPAGED,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatEResourceLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_NX_ALLOCATION | POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(ERESOURCE),
                                     TAG_ERESOURCE,
                                     MaxDepth );

    ExInitializeSListHead( &FatCloseContextSList );
    ExInitializeFastMutex( &FatCloseQueueMutex );
    KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE );

    //
    //  Register the file system with the I/O system
    //

    IoRegisterFileSystem(FatDiskFileSystemDeviceObject);
    ObReferenceObject (FatDiskFileSystemDeviceObject);
    IoRegisterFileSystem(FatCdromFileSystemDeviceObject);
    ObReferenceObject (FatCdromFileSystemDeviceObject);

    //
    //  Find out if we are running an a FujitsuFMR machine.
    //

    FatData.FujitsuFMR = FatIsFujitsuFMR();

#if (NTDDI_VERSION >= NTDDI_WIN8)

    //
    //  Find out global disk accounting state, cache the result
    //

    FatDiskAccountingEnabled = PsIsDiskCountersEnabled();

#endif

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
Пример #5
0
NTSTATUS
DriverEntry(
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
)

/*++

Routine Description:

    This is the initialization routine for the Cdrom file system
    device driver.  This routine creates the device object for the FileSystem
    device and performs all other driver initialization.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

    NTSTATUS - The function value is the final status from the initialization
        operation.

--*/

{
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    PDEVICE_OBJECT CdfsFileSystemDeviceObject;
    FS_FILTER_CALLBACKS FilterCallbacks;

    UNREFERENCED_PARAMETER( RegistryPath );

    //
    // Create the device object.
    //

    RtlInitUnicodeString( &UnicodeString, L"\\Cdfs" );

    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_CD_ROM_FILE_SYSTEM,
                             0,
                             FALSE,
                             &CdfsFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        return Status;
    }

#pragma prefast(push)
#pragma prefast(disable: 28155, "the dispatch routine has the correct type, prefast is just being paranoid.")
#pragma prefast(disable: 28168, "the dispatch routine has the correct type, prefast is just being paranoid.")
#pragma prefast(disable: 28169, "the dispatch routine has the correct type, prefast is just being paranoid.")
#pragma prefast(disable: 28175, "we're allowed to change these.")

    DriverObject->DriverUnload = CdUnload;

    //
    //  Note that because of the way data caching is done, we set neither
    //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    //  data is not in the cache, or the request is not buffered, we may,
    //  set up for Direct I/O by hand.
    //

    //
    //  Initialize the driver object with this driver's entry points.
    //
    //  NOTE - Each entry in the dispatch table must have an entry in
    //  the Fsp/Fsd dispatch switch statements.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]                  =
        DriverObject->MajorFunction[IRP_MJ_CLOSE]                   =
            DriverObject->MajorFunction[IRP_MJ_READ]                    =
                DriverObject->MajorFunction[IRP_MJ_WRITE]                   =
                    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]       =
                        DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]         =
                            DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]=
                                DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]       =
                                    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]     =
                                        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]          =
                                            DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]            =
                                                    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                 =
                                                            DriverObject->MajorFunction[IRP_MJ_PNP]                     =
                                                                    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                = (PDRIVER_DISPATCH) CdFsdDispatch;
#pragma prefast(pop)

#pragma prefast(suppress: 28175, "this is a file system driver, we're allowed to touch FastIoDispatch.")
    DriverObject->FastIoDispatch = &CdFastIoDispatch;

    //
    //  Initialize the filter callbacks we use.
    //

    RtlZeroMemory( &FilterCallbacks,
                   sizeof(FS_FILTER_CALLBACKS) );

    FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
    FilterCallbacks.PreAcquireForSectionSynchronization = CdFilterCallbackAcquireForCreateSection;

    Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject,
             &FilterCallbacks );

    if (!NT_SUCCESS( Status )) {

        IoDeleteDevice( CdfsFileSystemDeviceObject );
        return Status;
    }

    //
    //  Initialize the global data structures
    //

    Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject );
    if (!NT_SUCCESS (Status)) {
        IoDeleteDevice (CdfsFileSystemDeviceObject);
        return Status;
    }

    //
    //  Register the file system as low priority with the I/O system.  This will cause
    //  CDFS to receive mount requests after a) other filesystems currently registered
    //  and b) other normal priority filesystems that may be registered later.
    //

    CdfsFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM;

    IoRegisterFileSystem( CdfsFileSystemDeviceObject );
    ObReferenceObject (CdfsFileSystemDeviceObject);

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
Пример #6
0
NTSTATUS
DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath)

/*++

Routine Description:

        This routine gets called by the system to initialize the driver.

Arguments:

        DriverObject    - the system supplied driver object.
        RegistryPath    - the system supplied registry path for this driver.

Return Value:

        NTSTATUS

--*/

{
  NTSTATUS status;
  PFAST_IO_DISPATCH fastIoDispatch;
  FS_FILTER_CALLBACKS filterCallbacks;
  PDOKAN_GLOBAL dokanGlobal = NULL;

  UNREFERENCED_PARAMETER(RegistryPath);

  DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__,
            __TIME__);

  status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal);

  if (NT_ERROR(status)) {
    return status;
  }
  //
  // Set up dispatch entry points for the driver.
  //
  DriverObject->DriverUnload = DokanUnload;

  DriverObject->MajorFunction[IRP_MJ_CREATE] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_CLOSE] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
      DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
      DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_READ] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_WRITE] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_PNP] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DokanBuildRequest;

  DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = DokanBuildRequest;
  DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = DokanBuildRequest;

  fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH));
  if (!fastIoDispatch) {
    CleanupGlobalDiskDevice(dokanGlobal);
    DDbgPrint("  ExAllocatePool failed");
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH));

  fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
  fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible;
  // fastIoDispatch->FastIoRead = DokanFastIoRead;
  fastIoDispatch->FastIoRead = FsRtlCopyRead;
  fastIoDispatch->FastIoWrite = FsRtlCopyWrite;
  fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection;
  fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection;
  fastIoDispatch->MdlRead = FsRtlMdlReadDev;
  fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev;
  fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
  fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev;

  DriverObject->FastIoDispatch = fastIoDispatch;
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
  ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL,
                                  POOL_NX_ALLOCATION, sizeof(IRP_ENTRY), TAG,
                                  0);
#else
  ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, 0,
                                  sizeof(IRP_ENTRY), TAG, 0);
#endif

#if _WIN32_WINNT < 0x0501
  RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts");
  DokanFsRtlTeardownPerStreamContexts =
      MmGetSystemRoutineAddress(&functionName);
#endif

  RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS));

  // only be used by filter driver?
  filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
  filterCallbacks.PreAcquireForSectionSynchronization =
      DokanFilterCallbackAcquireForCreateSection;

  status =
      FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks);

  if (!NT_SUCCESS(status)) {
    CleanupGlobalDiskDevice(dokanGlobal);
    ExFreePool(DriverObject->FastIoDispatch);
    DDbgPrint("  FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n",
              status);
    return status;
  }

  if (!DokanLookasideCreate(&g_DokanCCBLookasideList, sizeof(DokanCCB))) {
    DDbgPrint("  DokanLookasideCreate g_DokanCCBLookasideList  failed");
    CleanupGlobalDiskDevice(dokanGlobal);
    ExFreePool(DriverObject->FastIoDispatch);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  if (!DokanLookasideCreate(&g_DokanFCBLookasideList, sizeof(DokanFCB))) {
    DDbgPrint("  DokanLookasideCreate g_DokanFCBLookasideList  failed");
    CleanupGlobalDiskDevice(dokanGlobal);
    ExFreePool(DriverObject->FastIoDispatch);
    ExDeleteLookasideListEx(&g_DokanCCBLookasideList);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  if (!DokanLookasideCreate(&g_DokanEResourceLookasideList,
                            sizeof(ERESOURCE))) {
    DDbgPrint("  DokanLookasideCreate g_DokanEResourceLookasideList  failed");
    CleanupGlobalDiskDevice(dokanGlobal);
    ExFreePool(DriverObject->FastIoDispatch);
    ExDeleteLookasideListEx(&g_DokanCCBLookasideList);
    ExDeleteLookasideListEx(&g_DokanFCBLookasideList);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  DDbgPrint("<== DriverEntry\n");

  return (status);
}