Esempio n. 1
0
void rnd_reseed_now()
{
	seed_data seed;

	KeQuerySystemTime(&seed.seed20);
	
	seed.seed1  = PsGetCurrentProcess();
	seed.seed2  = PsGetCurrentProcessId();
	seed.seed3  = KeGetCurrentThread();
	seed.seed4  = PsGetCurrentThreadId();
	seed.seed5  = KeGetCurrentProcessorNumber();
	seed.seed6  = KeQueryInterruptTime();
	seed.seed10 = KeQueryPerformanceCounter(NULL);
	seed.seed11 = __rdtsc();
	seed.seed12 = ExGetPreviousMode();	
	seed.seed14 = IoGetTopLevelIrp();
	seed.seed15 = MmQuerySystemSize();
	seed.seed24 = KeGetCurrentIrql();
	
	if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
		seed.seed7  = KeQueryPriorityThread(seed.seed3);
		seed.seed17 = ExUuidCreate(&seed.seed18);
		seed.seed19 = RtlRandom(&seed.seed8);
	}
	if (KeGetCurrentIrql() <= APC_LEVEL) {
		seed.seed13 = IoGetInitialStack();
		seed.seed16 = PsGetProcessExitTime();
		IoGetStackLimits(&seed.seed22, &seed.seed23);
	}	
	KeQueryTickCount(&seed.seed21);
	
	rnd_add_buff(&seed, sizeof(seed));
	
	/* Prevent leaks */	
	zeroauto(&seed, sizeof(seed));
}
Esempio n. 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;

    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;
}
Esempio n. 3
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 );
}
Esempio n. 4
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the Ntfs 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 DeviceObject;

    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    ULONG Value;

    UNREFERENCED_PARAMETER( RegistryPath );

    PAGED_CODE();

    //
    //  Compute the last access increment.  We convert the number of
    //  minutes to number of 1/100 of nanoseconds.  We have to be careful
    //  not to overrun 32 bits for any multiplier.
    //
    //  To reach 1/100 of nanoseconds per minute we take
    //
    //      1/100 nanoseconds * 10      = 1 microsecond
    //                        * 1000    = 1 millesecond
    //                        * 1000    = 1 second
    //                        * 60      = 1 minute
    //
    //  Then multiply this by the last access increment in minutes.
    //

    NtfsLastAccess = Int32x32To64( ( 10 * 1000 * 1000 * 60 ), LAST_ACCESS_INCREMENT_MINUTES );

    //
    // Create the device object.
    //

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

    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &DeviceObject );

    if (!NT_SUCCESS( Status )) {

        return Status;
    }

    //
    //  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)NtfsFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)NtfsFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)NtfsFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = (PDRIVER_DISPATCH)NtfsFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = (PDRIVER_DISPATCH)NtfsFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = (PDRIVER_DISPATCH)NtfsFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = (PDRIVER_DISPATCH)NtfsFsdQueryEa;
    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = (PDRIVER_DISPATCH)NtfsFsdSetEa;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = (PDRIVER_DISPATCH)NtfsFsdFlushBuffers;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NtfsFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = (PDRIVER_DISPATCH)NtfsFsdSetVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = (PDRIVER_DISPATCH)NtfsFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = (PDRIVER_DISPATCH)NtfsFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = (PDRIVER_DISPATCH)NtfsFsdDeviceControl;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = (PDRIVER_DISPATCH)NtfsFsdLockControl;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = (PDRIVER_DISPATCH)NtfsFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY]           = (PDRIVER_DISPATCH)NtfsFsdQuerySecurityInfo;
    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY]             = (PDRIVER_DISPATCH)NtfsFsdSetSecurityInfo;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = (PDRIVER_DISPATCH)NtfsFsdShutdown;

    DriverObject->FastIoDispatch = &NtfsFastIoDispatch;

    NtfsFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    NtfsFastIoDispatch.FastIoCheckIfPossible =   NtfsFastIoCheckIfPossible;  //  CheckForFastIo
    NtfsFastIoDispatch.FastIoRead =              NtfsCopyReadA;              //  Read
    NtfsFastIoDispatch.FastIoWrite =             NtfsCopyWriteA;             //  Write
    NtfsFastIoDispatch.FastIoQueryBasicInfo =    NtfsFastQueryBasicInfo;     //  QueryBasicInfo
    NtfsFastIoDispatch.FastIoQueryStandardInfo = NtfsFastQueryStdInfo;       //  QueryStandardInfo
    NtfsFastIoDispatch.FastIoLock =              NtfsFastLock;               //  Lock
    NtfsFastIoDispatch.FastIoUnlockSingle =      NtfsFastUnlockSingle;       //  UnlockSingle
    NtfsFastIoDispatch.FastIoUnlockAll =         NtfsFastUnlockAll;          //  UnlockAll
    NtfsFastIoDispatch.FastIoUnlockAllByKey =    NtfsFastUnlockAllByKey;     //  UnlockAllByKey
    NtfsFastIoDispatch.FastIoDeviceControl =     NULL;                       //  IoDeviceControl
    NtfsFastIoDispatch.FastIoDetachDevice            = NULL;
    NtfsFastIoDispatch.FastIoQueryNetworkOpenInfo    = NtfsFastQueryNetworkOpenInfo;
    NtfsFastIoDispatch.AcquireFileForNtCreateSection =  NtfsAcquireForCreateSection;
    NtfsFastIoDispatch.ReleaseFileForNtCreateSection =  NtfsReleaseForCreateSection;
    NtfsFastIoDispatch.AcquireForModWrite =          NtfsAcquireFileForModWrite;
    NtfsFastIoDispatch.MdlRead =                     NtfsMdlReadA;
    NtfsFastIoDispatch.MdlReadComplete =             FsRtlMdlReadCompleteDev;
    NtfsFastIoDispatch.PrepareMdlWrite =             NtfsPrepareMdlWriteA;
    NtfsFastIoDispatch.MdlWriteComplete =            FsRtlMdlWriteCompleteDev;
#ifdef _CAIRO_
    NtfsFastIoDispatch.FastIoReadCompressed =        NtfsCopyReadC;
    NtfsFastIoDispatch.FastIoWriteCompressed =       NtfsCopyWriteC;
    NtfsFastIoDispatch.MdlReadCompleteCompressed =   NtfsMdlReadCompleteCompressed;
    NtfsFastIoDispatch.MdlWriteCompleteCompressed =  NtfsMdlWriteCompleteCompressed;
#endif _CAIRO_
    NtfsFastIoDispatch.FastIoQueryOpen =             NtfsNetworkOpenCreate;
    NtfsFastIoDispatch.AcquireForCcFlush =           NtfsAcquireFileForCcFlush;
    NtfsFastIoDispatch.ReleaseForCcFlush =           NtfsReleaseFileForCcFlush;

    //
    //  Initialize the global ntfs data structure
    //

    NtfsInitializeNtfsData( DriverObject );

    ExInitializeFastMutex( &StreamFileCreationFastMutex );

    //
    //  Initialize the Ntfs Mcb global data queue and variables
    //

    ExInitializeFastMutex( &NtfsMcbFastMutex );
    InitializeListHead( &NtfsMcbLruQueue );
    NtfsMcbCleanupInProgress = FALSE;

    switch ( MmQuerySystemSize() ) {

    case MmSmallSystem:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;

    case MmMediumSystem:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;

    case MmLargeSystem:
    default:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;
    }

    //
    //  Allocate and initialize the free Eresource array
    //

    if ((NtfsData.FreeEresourceArray =
         ExAllocatePoolWithTag(NonPagedPool, (NtfsData.FreeEresourceTotal * sizeof(PERESOURCE)), 'rftN')) == NULL) {

        KeBugCheck( NTFS_FILE_SYSTEM );
    }

    RtlZeroMemory( NtfsData.FreeEresourceArray, NtfsData.FreeEresourceTotal * sizeof(PERESOURCE) );

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

    IoRegisterFileSystem(DeviceObject);

    //
    //  Initialize logging.
    //

    NtfsInitializeLogging();

    //
    //  Initialize global variables.  (ntfsdata.c assumes 2-digit value for
    //  $FILE_NAME)
    //

    ASSERT(($FILE_NAME >= 0x10) && ($FILE_NAME < 0x100));

    RtlInitUnicodeString( &NtfsFileNameIndex, NtfsFileNameIndexName );

    //
    //  Support extended character in shortname
    //

    //
    //  Read the registry to determine if we are to create short names.
    //

    KeyName.Buffer = COMPATIBILITY_MODE_KEY_NAME;
    KeyName.Length = sizeof( COMPATIBILITY_MODE_KEY_NAME ) - sizeof( WCHAR );
    KeyName.MaximumLength = sizeof( COMPATIBILITY_MODE_KEY_NAME );

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

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then create the 8.3
    //  names.
    //

    if (!NT_SUCCESS( Status ) || Value == 0) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_CREATE_8DOT3_NAMES );
    }

    //
    //  Read the registry to determine if we allow extended character in short name.
    //

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

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then does not allow
    //  extended character in 8.3 names.
    //

    if (NT_SUCCESS( Status ) && Value == 1) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_ALLOW_EXTENDED_CHAR );
    }

    //
    //  Read the registry to determine if we should disable last access updates.
    //

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

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then does not allow
    //  extended character in 8.3 names.
    //

    if (NT_SUCCESS( Status ) && Value == 1) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_DISABLE_LAST_ACCESS );
    }

    //
    //  Setup the CheckPointAllVolumes callback item, timer, dpc, and
    //  status.
    //

    ExInitializeWorkItem( &NtfsData.VolumeCheckpointItem,
                          NtfsCheckpointAllVolumes,
                          (PVOID)NULL );

    KeInitializeTimer( &NtfsData.VolumeCheckpointTimer );

    KeInitializeDpc( &NtfsData.VolumeCheckpointDpc,
                     NtfsVolumeCheckpointDpc,
                     NULL );
    NtfsData.TimerStatus = TIMER_NOT_SET;

    //
    //  Allocate first reserved buffer for USA writes
    //

    NtfsReserved1 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    NtfsReserved2 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    NtfsReserved3 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    ExInitializeFastMutex( &NtfsReservedBufferMutex );
    ExInitializeResource( &NtfsReservedBufferResource );

    //
    //  Zero out the global upcase table, that way we'll fill it in on
    //  our first successful mount
    //

    NtfsData.UpcaseTable = NULL;
    NtfsData.UpcaseTableSize = 0;

#ifdef _CAIRO_

    ExInitializeFastMutex( &NtfsScavengerLock );
    NtfsScavengerWorkList = NULL;
    NtfsScavengerRunning = FALSE;

    //
    // Request the load add-on routine be called after all the drivers have
    // initialized.
    //

    IoRegisterDriverReinitialization( DriverObject, NtfsLoadAddOns, NULL);

#endif

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
Esempio n. 5
0
VOID
NtfsInitializeNtfsData (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine initializes the global ntfs data record

Arguments:

    DriverObject - Supplies the driver object for NTFS

Return Value:

    None.

--*/

{
    USHORT FileLockMaxDepth;
    USHORT IoContextMaxDepth;
    USHORT IrpContextMaxDepth;
    USHORT KeventMaxDepth;
    USHORT ScbNonpagedMaxDepth;
    USHORT ScbSnapshotMaxDepth;

    USHORT CcbDataMaxDepth;
    USHORT CcbMaxDepth;
    USHORT DeallocatedRecordsMaxDepth;
    USHORT FcbDataMaxDepth;
    USHORT FcbIndexMaxDepth;
    USHORT IndexContextMaxDepth;
    USHORT LcbMaxDepth;
    USHORT NukemMaxDepth;
    USHORT ScbDataMaxDepth;

    PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
    BOOLEAN CapturedSubjectContext = FALSE;

    PACL SystemDacl = NULL;
    ULONG SystemDaclLength;

    PSID AdminSid = NULL;
    PSID SystemSid = NULL;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    DebugTrace( +1, Dbg, ("NtfsInitializeNtfsData\n") );

    //
    //  Zero the record and set its node type code and size
    //

    RtlZeroMemory( &NtfsData, sizeof(NTFS_DATA));

    NtfsData.NodeTypeCode = NTFS_NTC_DATA_HEADER;
    NtfsData.NodeByteSize = sizeof(NTFS_DATA);

    //
    //  Initialize the queue of mounted Vcbs
    //

    InitializeListHead(&NtfsData.VcbQueue);

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

    InitializeListHead( &NtfsData.AsyncCloseList );
    InitializeListHead( &NtfsData.DelayedCloseList );

    ExInitializeWorkItem( &NtfsData.NtfsCloseItem,
                          (PWORKER_THREAD_ROUTINE)NtfsFspClose,
                          NULL );

    //
    //  Set the driver object, device object, and initialize the global
    //  resource protecting the file system
    //

    NtfsData.DriverObject = DriverObject;

    ExInitializeResource( &NtfsData.Resource );

    //
    //  Now allocate and initialize the s-list structures used as our pool
    //  of IRP context records.  The size of the zone is based on the
    //  system memory size.  We also initialize the spin lock used to protect
    //  the zone.
    //

    KeInitializeSpinLock( &NtfsData.StrucSupSpinLock );
    {

        switch ( MmQuerySystemSize() ) {

        case MmSmallSystem:

            NtfsData.FreeEresourceTotal = 14;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 4;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 8;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 4;
            CcbMaxDepth                = 4;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 8;
            FcbIndexMaxDepth           = 4;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 4;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 4;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_SMALL_SYSTEM );
            NtfsMaxDelayedCloseCount = MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmMediumSystem:

            NtfsData.FreeEresourceTotal = 30;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 8;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 30;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 12;
            CcbMaxDepth                = 6;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 30;
            FcbIndexMaxDepth           = 12;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 12;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 12;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_MEDIUM_SYSTEM );
            NtfsMaxDelayedCloseCount = 4 * MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmLargeSystem:

            SetFlag( NtfsData.Flags, NTFS_FLAGS_LARGE_SYSTEM );
            NtfsMaxDelayedCloseCount = 16 * MAX_DELAYED_CLOSE_COUNT;

            if (MmIsThisAnNtAsSystem()) {

                NtfsData.FreeEresourceTotal = 256;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 256;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 128;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 40;
                CcbMaxDepth                = 20;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 128;
                FcbIndexMaxDepth           = 40;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 40;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 40;

            } else {

                NtfsData.FreeEresourceTotal = 128;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 64;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 64;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 20;
                CcbMaxDepth                = 10;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 64;
                FcbIndexMaxDepth           = 20;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 20;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 20;
            }

            break;
        }

        NtfsMinDelayedCloseCount = NtfsMaxDelayedCloseCount * 4 / 5;

    }

    //
    //  Initialize our various lookaside lists.  To make it a bit more readable we'll
    //  define two quick macros to do the initialization
    //

#if DBG && i386 && defined (NTFSPOOLCHECK)
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#else   //  DBG && i386
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#endif  //  DBG && i386

    NPagedInit( &NtfsFileLockLookasideList,    sizeof(FILE_LOCK),       'kftN', FileLockMaxDepth );
    NPagedInit( &NtfsIoContextLookasideList,   sizeof(NTFS_IO_CONTEXT), 'IftN', IoContextMaxDepth );
    NPagedInit( &NtfsIrpContextLookasideList,  sizeof(IRP_CONTEXT),     'iftN', IrpContextMaxDepth );
    NPagedInit( &NtfsKeventLookasideList,      sizeof(KEVENT),          'KftN', KeventMaxDepth );
    NPagedInit( &NtfsScbNonpagedLookasideList, sizeof(SCB_NONPAGED),    'nftN', ScbNonpagedMaxDepth );
    NPagedInit( &NtfsScbSnapshotLookasideList, sizeof(SCB_SNAPSHOT),    'TftN', ScbSnapshotMaxDepth );

    PagedInit(  &NtfsCcbLookasideList,                sizeof(CCB),                 'CftN', CcbMaxDepth );
    PagedInit(  &NtfsCcbDataLookasideList,            sizeof(CCB_DATA),            'cftN', CcbDataMaxDepth );
    PagedInit(  &NtfsDeallocatedRecordsLookasideList, sizeof(DEALLOCATED_RECORDS), 'DftN', DeallocatedRecordsMaxDepth );
    PagedInit(  &NtfsFcbDataLookasideList,            sizeof(FCB_DATA),            'fftN', FcbDataMaxDepth );
    PagedInit(  &NtfsFcbIndexLookasideList,           sizeof(FCB_INDEX),           'FftN', FcbIndexMaxDepth );
    PagedInit(  &NtfsIndexContextLookasideList,       sizeof(INDEX_CONTEXT),       'EftN', IndexContextMaxDepth );
    PagedInit(  &NtfsLcbLookasideList,                sizeof(LCB),                 'lftN', LcbMaxDepth );
    PagedInit(  &NtfsNukemLookasideList,              sizeof(NUKEM),               'NftN', NukemMaxDepth );
    PagedInit(  &NtfsScbDataLookasideList,            SIZEOF_SCB_DATA,             'sftN', ScbDataMaxDepth );

    //
    //  Initialize the cache manager callback routines,  First are the routines
    //  for normal file manipulations, followed by the routines for
    //  volume manipulations.
    //

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireScbForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseScbFromLazyWrite;
        Callbacks->AcquireForReadAhead  = &NtfsAcquireScbForReadAhead;
        Callbacks->ReleaseFromReadAhead = &NtfsReleaseScbFromReadAhead;
    }

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerVolumeCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireVolumeFileForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseVolumeFileFromLazyWrite;
        Callbacks->AcquireForReadAhead  = NULL;
        Callbacks->ReleaseFromReadAhead = NULL;
    }

    //
    //  Initialize the queue of read ahead threads
    //

    InitializeListHead(&NtfsData.ReadAheadThreads);

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

    NtfsData.OurProcess = PsGetCurrentProcess();

    //
    //  Use a try-finally to cleanup on errors.
    //

    try {

        SECURITY_DESCRIPTOR NewDescriptor;
        SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;

        SubjectContext = NtfsAllocatePool( PagedPool, sizeof( SECURITY_SUBJECT_CONTEXT ));
        SeCaptureSubjectContext( SubjectContext );
        CapturedSubjectContext = TRUE;

        //
        //  Build the default security descriptor which gives full access to
        //  system and administrator.
        //

        AdminSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 2 ));
        RtlInitializeSid( AdminSid, &Authority, 2 );
        *(RtlSubAuthoritySid( AdminSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
        *(RtlSubAuthoritySid( AdminSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;

        SystemSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 1 ));
        RtlInitializeSid( SystemSid, &Authority, 1 );
        *(RtlSubAuthoritySid( SystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;

        SystemDaclLength = sizeof( ACL ) +
                           (2 * sizeof( ACCESS_ALLOWED_ACE )) +
                           SeLengthSid( AdminSid ) +
                           SeLengthSid( SystemSid ) +
                           8; // The 8 is just for good measure

        SystemDacl = NtfsAllocatePool( PagedPool, SystemDaclLength );

        Status = RtlCreateAcl( SystemDacl, SystemDaclLength, ACL_REVISION2 );

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

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SystemSid );

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

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         AdminSid );

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

        Status = RtlCreateSecurityDescriptor( &NewDescriptor,
                                              SECURITY_DESCRIPTOR_REVISION1 );

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

        Status = RtlSetDaclSecurityDescriptor( &NewDescriptor,
                                               TRUE,
                                               SystemDacl,
                                               FALSE );

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

        Status = SeAssignSecurity( NULL,
                                   &NewDescriptor,
                                   &NtfsData.DefaultDescriptor,
                                   FALSE,
                                   SubjectContext,
                                   IoGetFileObjectGenericMapping(),
                                   PagedPool );

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

        NtfsData.DefaultDescriptorLength = RtlLengthSecurityDescriptor( NtfsData.DefaultDescriptor );

        ASSERT( SeValidSecurityDescriptor( NtfsData.DefaultDescriptorLength,
                                           NtfsData.DefaultDescriptor ));

    } finally {

        if (CapturedSubjectContext) {

            SeReleaseSubjectContext( SubjectContext );
        }

        if (SubjectContext != NULL) { NtfsFreePool( SubjectContext ); }

        if (SystemDacl != NULL) { NtfsFreePool( SystemDacl ); }

        if (AdminSid != NULL) { NtfsFreePool( AdminSid ); }

        if (SystemSid != NULL) { NtfsFreePool( SystemSid ); }
    }

    //
    //  Raise if we hit an error building the security descriptor.
    //

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

    //
    //  And return to our caller
    //

    DebugTrace( -1, Dbg, ("NtfsInitializeNtfsData -> VOID\n") );

    return;
}
Esempio n. 6
0
BOOLEAN
ObInitSystem(
    VOID
    )

/*++

Routine Description:

    This function performs the system initialization for the object
    manager.  The object manager data structures are self describing
    with the exception of the root directory, the type object type and
    the directory object type.  The initialization code then constructs
    these objects by hand to get the ball rolling.

Arguments:

    None.

Return Value:

    TRUE if successful and FALSE if an error occurred.

    The following errors can occur:

    - insufficient memory

--*/

{

    USHORT CreateInfoMaxDepth;
    USHORT NameBufferMaxDepth;
    ULONG RegionSegmentSize;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    UNICODE_STRING TypeTypeName;
    UNICODE_STRING SymbolicLinkTypeName;
    UNICODE_STRING DosDevicesDirectoryName;
    UNICODE_STRING DirectoryTypeName;
    UNICODE_STRING RootDirectoryName;
    UNICODE_STRING TypeDirectoryName;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE RootDirectoryHandle;
    HANDLE TypeDirectoryHandle;
    PLIST_ENTRY Next, Head;
    POBJECT_HEADER ObjectTypeHeader;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    MM_SYSTEMSIZE SystemSize;
    SECURITY_DESCRIPTOR AuditSd;
    PSECURITY_DESCRIPTOR EffectiveSd;
    PACL    AuditAllAcl;
    UCHAR   AuditAllBuffer[250];  // Ample room for the ACL
    ULONG   AuditAllLength;
    PACE_HEADER Ace;

    //
    // PHASE 0 Initialization
    //

    if (InitializationPhase == 0) {

        //
        // Determine the the size of the object creation and the name buffer
        // lookaside lists.
        //

        SystemSize = MmQuerySystemSize();
        if (SystemSize == MmLargeSystem) {
            if (MmIsThisAnNtAsSystem()) {
                CreateInfoMaxDepth = 64;
                NameBufferMaxDepth = 32;

            } else {
                CreateInfoMaxDepth = 32;
                NameBufferMaxDepth = 16;
            }

        } else {
            CreateInfoMaxDepth = 3;
            NameBufferMaxDepth = 3;
        }

        //
        // Initialize the object creation lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpCreateInfoLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(OBJECT_CREATE_INFORMATION),
                                        'iCbO',
                                        CreateInfoMaxDepth);

        //
        // Initialize the name buffer lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpNameBufferLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        OBJECT_NAME_BUFFER_SIZE,
                                        'mNbO',
                                        NameBufferMaxDepth);

        InitializeListHead( &ObpRemoveObjectQueue );

        //
        // Initialize security descriptor cache
        //

        ObpInitSecurityDescriptorCache();

        KeInitializeMutant( &ObpInitKillMutant, FALSE );
        KeInitializeEvent( &ObpDefaultObject, NotificationEvent, TRUE );
        KeInitializeSpinLock( &ObpLock );
        PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
        PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

        //
        // Initialize the quota block
        //

        KeInitializeSpinLock(&PspDefaultQuotaBlock.QuotaLock);
        PspDefaultQuotaBlock.ReferenceCount = 1;
        PspDefaultQuotaBlock.QuotaPoolLimit[PagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.QuotaPoolLimit[NonPagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.PagefileLimit = (ULONG)-1;

        PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;

        PsGetCurrentProcess()->ObjectTable =
            ExCreateHandleTable( NULL,
                                 0,
                                 0
                               );

        RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
        ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
        ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
        ObjectTypeInitializer.PoolType = NonPagedPool;

        RtlInitUnicodeString( &TypeTypeName, L"Type" );
        ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_TYPE );
        ObjectTypeInitializer.MaintainTypeList = TRUE;
        ObjectTypeInitializer.UseDefaultObject = TRUE;
        ObCreateObjectType( &TypeTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpTypeObjectType
                          );

        RtlInitUnicodeString( &DirectoryTypeName, L"Directory" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_DIRECTORY );
        ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
        ObjectTypeInitializer.MaintainTypeList = FALSE;
        ObCreateObjectType( &DirectoryTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpDirectoryObjectType
                          );

        RtlInitUnicodeString( &SymbolicLinkTypeName, L"SymbolicLink" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_SYMBOLIC_LINK );
        ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
        ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
        ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
        ObCreateObjectType( &SymbolicLinkTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpSymbolicLinkObjectType
                          );

        ExInitializeResourceLite( &ObpRootDirectoryMutex );

#if i386 && !FPO
        ObpCurCachedGrantedAccessIndex = 0;
        ObpMaxCachedGrantedAccessIndex = PAGE_SIZE / sizeof( ACCESS_MASK );
        ObpCachedGrantedAccesses = ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, 'gAbO' );
#endif // i386 && !FPO

#if DBG
        ObpCreateObjectEventId = RtlCreateEventId( NULL,
                                                   0,
                                                   "CreateObject",
                                                   6,
                                                   RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Type", 0,
                                                   RTL_EVENT_ULONG_PARAM, "PagedPool", 0,
                                                   RTL_EVENT_ULONG_PARAM, "NonPagedPool", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0,
                                                   RTL_EVENT_FLAGS_PARAM, "", 5,
                                                     OBJ_INHERIT, "Inherit",
                                                     OBJ_PERMANENT, "Permanent",
                                                     OBJ_OPENIF, "OpenIf",
                                                     OBJ_CASE_INSENSITIVE, "CaseInsenitive",
                                                     OBJ_EXCLUSIVE, "Exclusive"
                                                 );
        ObpFreeObjectEventId = RtlCreateEventId( NULL,
                                                 0,
                                                 "FreeObject",
                                                 3,
                                                 RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                 RTL_EVENT_ULONG_PARAM, "Type", 0,
                                                 RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0
                                               );
#endif // DBG

        }             // End of Phase 0 Initializtion


    //
    // PHASE 1 Initialization
    //

    if (InitializationPhase == 1) {


        EffectiveSd = SePublicDefaultSd;

        //
        // This code is only executed if base auditing is turned on.
        //

        if ((ObpAuditBaseDirectories != 0) || (ObpAuditBaseObjects != 0)) {

            //
            // build an SACL to audit
            //
            AuditAllAcl = (PACL)AuditAllBuffer;
            AuditAllLength = (ULONG)sizeof(ACL) +
                               ((ULONG)sizeof(SYSTEM_AUDIT_ACE)) +
                               SeLengthSid(SeWorldSid);
            ASSERT( sizeof(AuditAllBuffer)   >   AuditAllLength );
            Status = RtlCreateAcl( AuditAllAcl, AuditAllLength, ACL_REVISION2);
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlAddAuditAccessAce (
                         AuditAllAcl,
                         ACL_REVISION2,
                         GENERIC_ALL,
                         SeWorldSid,
                         TRUE,  TRUE        //Audit success and failure
                         );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlGetAce( AuditAllAcl, 0,  (PVOID)&Ace );
            ASSERT( NT_SUCCESS(Status) );

            if (ObpAuditBaseDirectories != 0) {
                Ace->AceFlags |= (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
                }

            if (ObpAuditBaseObjects != 0) {
                Ace->AceFlags |= (OBJECT_INHERIT_ACE    |
                                  CONTAINER_INHERIT_ACE |
                                  INHERIT_ONLY_ACE);
                }



            //
            // Now create a security descriptor that looks just like
            // the public default, but has auditing in it as well.

            EffectiveSd = (PSECURITY_DESCRIPTOR)&AuditSd;
            Status = RtlCreateSecurityDescriptor( EffectiveSd,
                                                  SECURITY_DESCRIPTOR_REVISION1 );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlSetDaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   SePublicDefaultDacl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlSetSaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   AuditAllAcl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            }


        //
        // We only need to use the EffectiveSd on the root.  The SACL
        // will be inherited by all other objects.
        //

        RtlInitUnicodeString( &RootDirectoryName, L"\\" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &RootDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    EffectiveSd
                                  );
        Status = NtCreateDirectoryObject( &RootDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( RootDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpRootDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( RootDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        RtlInitUnicodeString( &TypeDirectoryName, L"\\ObjectTypes" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &TypeDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    NULL
                                  );
        Status = NtCreateDirectoryObject( &TypeDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( TypeDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpTypeDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( TypeDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        ObpEnterRootDirectoryMutex();

        Head = &ObpTypeObjectType->TypeList;
        Next = Head->Flink;
        while (Next != Head) {
            CreatorInfo = CONTAINING_RECORD( Next,
                                             OBJECT_HEADER_CREATOR_INFO,
                                             TypeList
                                           );
            ObjectTypeHeader = (POBJECT_HEADER)(CreatorInfo+1);
            NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectTypeHeader );
            if (NameInfo != NULL && NameInfo->Directory == NULL) {
                if (!ObpLookupDirectoryEntry( ObpTypeDirectoryObject,
                                              &NameInfo->Name,
                                              OBJ_CASE_INSENSITIVE
                                            )
                   ) {
                    ObpInsertDirectoryEntry( ObpTypeDirectoryObject,
                                             &ObjectTypeHeader->Body
                                           );
                    }
                }

            Next = Next->Flink;
            }

        ObpLeaveRootDirectoryMutex();

        //
        // Create \DosDevices object directory for drive letters and Win32 device names
        //
        Status = ObpCreateDosDevicesDirectory();
        if (!NT_SUCCESS( Status )) {
            return FALSE;
            }
        }

    return TRUE;
}
Esempio n. 7
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 );
}
Esempio n. 8
0
NTSTATUS
CdInitializeGlobalData (
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT FileSystemDeviceObject
)

/*++

Routine Description:

    This routine initializes the global cdfs data structures.

Arguments:

    DriverObject - Supplies the driver object for CDFS.

    FileSystemDeviceObject - Supplies the device object for CDFS.

Return Value:

    None.

--*/

{
    //
    //  Start by initializing the FastIoDispatch Table.
    //

    RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH ));

    CdFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);

#pragma prefast(push)
#pragma prefast(disable:28155, "these are all correct")

    CdFastIoDispatch.FastIoCheckIfPossible =   CdFastIoCheckIfPossible;  //  CheckForFastIo
    CdFastIoDispatch.FastIoRead =              FsRtlCopyRead;            //  Read
    CdFastIoDispatch.FastIoQueryBasicInfo =    CdFastQueryBasicInfo;     //  QueryBasicInfo
    CdFastIoDispatch.FastIoQueryStandardInfo = CdFastQueryStdInfo;       //  QueryStandardInfo
    CdFastIoDispatch.FastIoLock =              CdFastLock;               //  Lock
    CdFastIoDispatch.FastIoUnlockSingle =      CdFastUnlockSingle;       //  UnlockSingle
    CdFastIoDispatch.FastIoUnlockAll =         CdFastUnlockAll;          //  UnlockAll
    CdFastIoDispatch.FastIoUnlockAllByKey =    CdFastUnlockAllByKey;     //  UnlockAllByKey

    //
    //  This callback has been replaced by CdFilterCallbackAcquireForCreateSection.
    //

    CdFastIoDispatch.AcquireFileForNtCreateSection =  NULL;
    CdFastIoDispatch.ReleaseFileForNtCreateSection =  CdReleaseForCreateSection;
    CdFastIoDispatch.FastIoQueryNetworkOpenInfo =     CdFastQueryNetworkInfo;   //  QueryNetworkInfo

    CdFastIoDispatch.MdlRead = FsRtlMdlReadDev;
    CdFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev;
    CdFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
    CdFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;

#pragma prefast(pop)

    //
    //  Initialize the CdData structure.
    //

    RtlZeroMemory( &CdData, sizeof( CD_DATA ));

    CdData.NodeTypeCode = CDFS_NTC_DATA_HEADER;
    CdData.NodeByteSize = sizeof( CD_DATA );

    CdData.DriverObject = DriverObject;
    CdData.FileSystemDeviceObject = FileSystemDeviceObject;

    InitializeListHead( &CdData.VcbQueue );

    ExInitializeResourceLite( &CdData.DataResource );

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

    CdData.CacheManagerCallbacks.AcquireForLazyWrite  = &CdAcquireForCache;
    CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = &CdReleaseFromCache;
    CdData.CacheManagerCallbacks.AcquireForReadAhead  = &CdAcquireForCache;
    CdData.CacheManagerCallbacks.ReleaseFromReadAhead = &CdReleaseFromCache;

    CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite  = &CdNoopAcquire;
    CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease;
    CdData.CacheManagerVolumeCallbacks.AcquireForReadAhead  = &CdNoopAcquire;
    CdData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &CdNoopRelease;

    //
    //  Initialize the lock mutex and the async and delay close queues.
    //

    ExInitializeFastMutex( &CdData.CdDataMutex );
    InitializeListHead( &CdData.AsyncCloseQueue );
    InitializeListHead( &CdData.DelayedCloseQueue );

    CdData.CloseItem = IoAllocateWorkItem (FileSystemDeviceObject);
    if (CdData.CloseItem == NULL) {

        ExDeleteResourceLite( &CdData.DataResource );
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    //
    //  Do the initialization based on the system size.
    //

    switch (MmQuerySystemSize()) {

    case MmSmallSystem:

        CdData.IrpContextMaxDepth = 4;
        CdData.MaxDelayedCloseCount = 8;
        CdData.MinDelayedCloseCount = 2;
        break;

    case MmMediumSystem:

        CdData.IrpContextMaxDepth = 8;
        CdData.MaxDelayedCloseCount = 24;
        CdData.MinDelayedCloseCount = 6;
        break;

    case MmLargeSystem:

        CdData.IrpContextMaxDepth = 32;
        CdData.MaxDelayedCloseCount = 72;
        CdData.MinDelayedCloseCount = 18;
        break;
    }
    return STATUS_SUCCESS;
}
Esempio n. 9
0
BOOLEAN
PspInitPhase0 (
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine performs phase 0 process structure initialization.
    During this phase, the initial system process, phase 1 initialization
    thread, and reaper threads are created. All object types and other
    process structures are created and initialized.

Arguments:

    None.

Return Value:

    TRUE - Initialization was successful.

    FALSE - Initialization Failed.

--*/

{

    PLDR_DATA_TABLE_ENTRY DataTableEntry1;
    PLDR_DATA_TABLE_ENTRY DataTableEntry2;
    UNICODE_STRING NameString;
    PLIST_ENTRY NextEntry;
    OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    HANDLE ThreadHandle;
    PETHREAD Thread;
    MM_SYSTEMSIZE SystemSize;

    PsPrioritySeperation = 2;
    SystemSize = MmQuerySystemSize();
    PspDefaultPagefileLimit = (ULONG)-1;

    if ( sizeof(TEB) > 4096 || sizeof(PEB) > 4096 ) {
        KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,sizeof(TEB),sizeof(PEB),99);
        }

    switch ( SystemSize ) {

        case MmMediumSystem :
            PsMinimumWorkingSet += 10;
            PsMaximumWorkingSet += 100;
            break;

        case MmLargeSystem :
            PsMinimumWorkingSet += 30;
            PsMaximumWorkingSet += 300;
            break;

        case MmSmallSystem :
        default:
            break;
        }

    if ( MmIsThisAnNtAsSystem() ) {
        PspForegroundQuantum[0] = 6*THREAD_QUANTUM;
        PspForegroundQuantum[1] = 6*THREAD_QUANTUM;
        PspForegroundQuantum[2] = 6*THREAD_QUANTUM;
        }
    else {

        //
        // For Workstation:
        //
        // BG is THREAD_QUANTUM
        // FG is THREAD_QUANTUM                 50/50 fg/bg
        // FG is 2 * THREAD_QUANTUM             65/35 fg/bg
        // FG is 3 * THREAD_QUANTUM             75/25 fg/bg
        //

        PspForegroundQuantum[0] = THREAD_QUANTUM;
        PspForegroundQuantum[1] = 2*THREAD_QUANTUM;
        PspForegroundQuantum[2] = 3*THREAD_QUANTUM;
        }
    //
    // Quotas grow as needed automatically
    //

    if ( !PspDefaultPagedLimit ) {
        PspDefaultPagedLimit = 0;
        }
    if ( !PspDefaultNonPagedLimit ) {
        PspDefaultNonPagedLimit = 0;
        }

    if ( PspDefaultNonPagedLimit == 0 && PspDefaultPagedLimit == 0) {
        PspDoingGiveBacks = TRUE;
        }
    else {
        PspDoingGiveBacks = FALSE;
        }


    PspDefaultPagedLimit *= PSP_1MB;
    PspDefaultNonPagedLimit *= PSP_1MB;

    if (PspDefaultPagefileLimit != -1) {
        PspDefaultPagefileLimit *= PSP_1MB;
        }

    //
    // Initialize the process security fields lock and the process lock.
    //

    ExInitializeFastMutex( &PspProcessLockMutex );
    ExInitializeFastMutex( &PspProcessSecurityLock );

    //
    // Initialize the loaded module list executive resource and spin lock.
    //

    ExInitializeResource( &PsLoadedModuleResource );
    KeInitializeSpinLock( &PsLoadedModuleSpinLock );
    KeInitializeSpinLock( &PspEventPairLock );

    //
    // Initialize the loaded module listheads.
    //

    PsIdleProcess = PsGetCurrentProcess();
    PsIdleProcess->Pcb.KernelTime = 0;
    PsIdleProcess->Pcb.KernelTime = 0;


    InitializeListHead(&PsLoadedModuleList);

    //
    // Scan the loaded module list and allocate and initialize a data table
    // entry for each module. The data table entry is inserted in the loaded
    // module list and the initialization order list in the order specified
    // in the loader parameter block. The data table entry is inserted in the
    // memory order list in memory order.
    //

    NextEntry = LoaderBlock->LoadOrderListHead.Flink;
    DataTableEntry2 = CONTAINING_RECORD(NextEntry,
                                        LDR_DATA_TABLE_ENTRY,
                                        InLoadOrderLinks);
    PsNtosImageBase = DataTableEntry2->DllBase;

    DataTableEntry2 = (PLDR_DATA_TABLE_ENTRY) NextEntry->Flink;
    DataTableEntry2 = CONTAINING_RECORD(DataTableEntry2,
                                        LDR_DATA_TABLE_ENTRY,
                                        InLoadOrderLinks);
    PsHalImageBase = DataTableEntry2->DllBase;

    while (NextEntry != &LoaderBlock->LoadOrderListHead) {


        DataTableEntry2 = CONTAINING_RECORD(NextEntry,
                                            LDR_DATA_TABLE_ENTRY,
                                            InLoadOrderLinks);

        //
        // Allocate a data table entry.
        //

        DataTableEntry1 = ExAllocatePool(NonPagedPool,
                                         sizeof(LDR_DATA_TABLE_ENTRY) +
                               DataTableEntry2->FullDllName.MaximumLength +
                                 DataTableEntry2->BaseDllName.MaximumLength +
                                 sizeof(ULONG) + sizeof(ULONG));

        if (DataTableEntry1 == NULL) {
            return FALSE;
        }

        //
        // Copy the data table entry.
        //

        *DataTableEntry1 = *DataTableEntry2;

        //
        // Copy the strings.
        //

        DataTableEntry1->FullDllName.Buffer = (PWSTR)((PCHAR)DataTableEntry1 +
                                     ROUND_UP(sizeof(LDR_DATA_TABLE_ENTRY),
                                              sizeof(ULONG)));

        RtlMoveMemory (DataTableEntry1->FullDllName.Buffer,
                       DataTableEntry2->FullDllName.Buffer,
                       DataTableEntry1->FullDllName.MaximumLength);

        DataTableEntry1->BaseDllName.Buffer =
                        (PWSTR)((PCHAR)DataTableEntry1->FullDllName.Buffer +
                          ROUND_UP(DataTableEntry1->FullDllName.MaximumLength,
                                   sizeof(ULONG)));

        RtlMoveMemory (DataTableEntry1->BaseDllName.Buffer,
                       DataTableEntry2->BaseDllName.Buffer,
                       DataTableEntry1->BaseDllName.MaximumLength);

        //
        // Insert the data table entry in the load order list in the order
        // they are specified.
        //

        InsertTailList(&PsLoadedModuleList,
                       &DataTableEntry1->InLoadOrderLinks);

        NextEntry = NextEntry->Flink;
    }


    //
    // Initialize the common fields of the Object Type Prototype record
    //

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObjectTypeInitializer.SecurityRequired = TRUE;
    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT |
                                              OBJ_EXCLUSIVE |
                                              OBJ_OPENIF;


    //
    // Create Object types for Thread and Process Objects.
    //

    RtlInitUnicodeString(&NameString, L"Process");
    ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_PROCESS_PAGED_CHARGE;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_PROCESS_NONPAGED_CHARGE;
    ObjectTypeInitializer.DeleteProcedure = PspProcessDelete;
    ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
    ObjectTypeInitializer.GenericMapping = PspProcessMapping;

    if ( !NT_SUCCESS(ObCreateObjectType(&NameString,
                                     &ObjectTypeInitializer,
                                     (PSECURITY_DESCRIPTOR) NULL,
                                     &PsProcessType
                                     )) ){
        return FALSE;
    }

    RtlInitUnicodeString(&NameString, L"Thread");
    ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_THREAD_PAGED_CHARGE;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_THREAD_NONPAGED_CHARGE;
    ObjectTypeInitializer.DeleteProcedure = PspThreadDelete;
    ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
    ObjectTypeInitializer.GenericMapping = PspThreadMapping;

    if ( !NT_SUCCESS(ObCreateObjectType(&NameString,
                                     &ObjectTypeInitializer,
                                     (PSECURITY_DESCRIPTOR) NULL,
                                     &PsThreadType
                                     )) ){
        return FALSE;
    }

    //
    // Initialize active process list head and mutex
    //

    InitializeListHead(&PsActiveProcessHead);
    ExInitializeFastMutex(&PspActiveProcessMutex);

    //
    // Initialize CID handle table.
    //
    // N.B. The CID handle table is removed from the handle table list so
    //      it will not be enumerated for object handle queries.
    //

    PspCidTable = ExCreateHandleTable(NULL, 0, 0);
    if ( ! PspCidTable ) {
        return FALSE;
    }
    ExRemoveHandleTable(PspCidTable);

#ifdef i386

    //
    // Ldt Initialization
    //

    if ( !NT_SUCCESS(PspLdtInitialize()) ) {
        return FALSE;
    }

    //
    // Vdm support Initialization
    //

    if ( !NT_SUCCESS(PspVdmInitialize()) ) {
        return FALSE;
    }

#endif

    //
    // Initialize Reaper Data Structures
    //

    InitializeListHead(&PsReaperListHead);
    ExInitializeWorkItem(&PsReaperWorkItem, PspReaper, NULL);

    //
    // Get a pointer to the system access token.
    // This token is used by the boot process, so we can take the pointer
    // from there.
    //

    PspBootAccessToken = PsGetCurrentProcess()->Token;

    InitializeObjectAttributes( &ObjectAttributes,
                                NULL,
                                0,
                                NULL,
                                NULL
                              ); // FIXFIX

    if ( !NT_SUCCESS(PspCreateProcess(
                    &PspInitialSystemProcessHandle,
                    PROCESS_ALL_ACCESS,
                    &ObjectAttributes,
                    0L,
                    FALSE,
                    0L,
                    0L,
                    0L
                    )) ) {
        return FALSE;
    }

    if ( !NT_SUCCESS(ObReferenceObjectByHandle(
                                        PspInitialSystemProcessHandle,
                                        0L,
                                        PsProcessType,
                                        KernelMode,
                                        (PVOID *)&PsInitialSystemProcess,
                                        NULL
                                        )) ) {

        return FALSE;
    }

    strcpy(&PsGetCurrentProcess()->ImageFileName[0],"Idle");
    strcpy(&PsInitialSystemProcess->ImageFileName[0],"System");

    //
    // Phase 1 System initialization
    //

    if ( !NT_SUCCESS(PsCreateSystemThread(
                    &ThreadHandle,
                    THREAD_ALL_ACCESS,
                    &ObjectAttributes,
                    0L,
                    NULL,
                    Phase1Initialization,
                    (PVOID)LoaderBlock
                    )) ) {
        return FALSE;
    }


    if ( !NT_SUCCESS(ObReferenceObjectByHandle(
                        ThreadHandle,
                        0L,
                        PsThreadType,
                        KernelMode,
                        (PVOID *)&Thread,
                        NULL
                        )) ) {

        return FALSE;
    }

    ZwClose( ThreadHandle );

#if DBG
    PspExitProcessEventId = RtlCreateEventId( NULL,
                                              0,
                                              "ExitProcess",
                                              1,
                                              RTL_EVENT_STATUS_PARAM, "ExitStatus", 0
                                            );
    PspPageFaultEventId = RtlCreateEventId( NULL,
                                            0,
                                            "PageFault",
                                            3,
                                            RTL_EVENT_STATUS_PARAM, "", 0,
                                            RTL_EVENT_ADDRESS_PARAM, "PC", 0,
                                            RTL_EVENT_ADDRESS_PARAM, "Va", 0
                                          );
#endif // DBG

    return TRUE;
}
Esempio n. 10
0
NTSTATUS
ExpWorkerInitialization (
    VOID
    )
{
    ULONG Index;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG NumberOfDelayedThreads;
    ULONG NumberOfCriticalThreads;
    ULONG NumberOfThreads;
    NTSTATUS Status;
    HANDLE Thread;
    BOOLEAN NtAs;
    WORK_QUEUE_TYPE WorkQueueType;

    ExInitializeFastMutex (&ExpWorkerSwapinMutex);
    InitializeListHead (&ExpWorkerListHead);
    ExpWorkersCanSwap = TRUE;

    //
    // Set the number of worker threads based on the system size.
    //

    NtAs = MmIsThisAnNtAsSystem();

    NumberOfCriticalThreads = MEDIUM_NUMBER_OF_THREADS;

    //
    // Incremented boot time number of delayed threads.
    // We did this in Windows XP, because 3COM NICs would take a long
    // time with the network stack tying up the delayed worker threads.
    // When Mm would need a worker thread to load a driver on the critical
    // path of boot, it would also get stuck for a few seconds and hurt
    // boot times. Ideally we'd spawn new delayed threads as necessary as
    // well to prevent such contention from hurting boot and resume.
    //

    NumberOfDelayedThreads = MEDIUM_NUMBER_OF_THREADS + 4;

    switch (MmQuerySystemSize()) {

        case MmSmallSystem:
            break;

        case MmMediumSystem:
            if (NtAs) {
                NumberOfCriticalThreads += MEDIUM_NUMBER_OF_THREADS;
            }
            break;

        case MmLargeSystem:
            NumberOfCriticalThreads = LARGE_NUMBER_OF_THREADS;
            if (NtAs) {
                NumberOfCriticalThreads += LARGE_NUMBER_OF_THREADS;
            }
            break;

        default:
            break;
    }

    //
    // Initialize the work Queue objects.
    //

    if (ExpAdditionalCriticalWorkerThreads > MAX_ADDITIONAL_THREADS) {
        ExpAdditionalCriticalWorkerThreads = MAX_ADDITIONAL_THREADS;
    }

    if (ExpAdditionalDelayedWorkerThreads > MAX_ADDITIONAL_THREADS) {
        ExpAdditionalDelayedWorkerThreads = MAX_ADDITIONAL_THREADS;
    }

    //
    // Initialize the ExWorkerQueue[] array.
    //

    RtlZeroMemory (&ExWorkerQueue[0], MaximumWorkQueue * sizeof(EX_WORK_QUEUE));

    for (WorkQueueType = 0; WorkQueueType < MaximumWorkQueue; WorkQueueType += 1) {

        KeInitializeQueue (&ExWorkerQueue[WorkQueueType].WorkerQueue, 0);
        ExWorkerQueue[WorkQueueType].Info.WaitMode = UserMode;
    }

    //
    // Always make stack for this thread resident
    // so that worker pool deadlock magic can run
    // even when what we are trying to do is inpage
    // the hyper critical worker thread's stack.
    // Without this fix, we hold the process lock
    // but this thread's stack can't come in, and
    // the deadlock detection cannot create new threads
    // to break the system deadlock.
    //

    ExWorkerQueue[HyperCriticalWorkQueue].Info.WaitMode = KernelMode;

    if (NtAs) {
        ExWorkerQueue[CriticalWorkQueue].Info.WaitMode = KernelMode;
    }

    //
    // We only create dynamic threads for the critical work queue (note
    // this doesn't apply to dynamic threads created to break deadlocks.)
    //
    // The rationale is this: folks who use the delayed work queue are
    // not time critical, and the hypercritical queue is used rarely
    // by folks who are non-blocking.
    //

    ExWorkerQueue[CriticalWorkQueue].Info.MakeThreadsAsNecessary = 1;

    //
    // Initialize the global thread set manager events
    //

    KeInitializeEvent (&ExpThreadSetManagerEvent,
                       SynchronizationEvent,
                       FALSE);

    KeInitializeEvent (&ExpThreadSetManagerShutdownEvent,
                       SynchronizationEvent,
                       FALSE);

    //
    // Create the desired number of executive worker threads for each
    // of the work queues.
    //

    //
    // Create the builtin critical worker threads.
    //

    NumberOfThreads = NumberOfCriticalThreads + ExpAdditionalCriticalWorkerThreads;
    for (Index = 0; Index < NumberOfThreads; Index += 1) {

        //
        // Create a worker thread to service the critical work queue.
        //

        Status = ExpCreateWorkerThread (CriticalWorkQueue, FALSE);

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

    ExCriticalWorkerThreads += Index;

    //
    // Create the delayed worker threads.
    //

    NumberOfThreads = NumberOfDelayedThreads + ExpAdditionalDelayedWorkerThreads;
    for (Index = 0; Index < NumberOfThreads; Index += 1) {

        //
        // Create a worker thread to service the delayed work queue.
        //

        Status = ExpCreateWorkerThread (DelayedWorkQueue, FALSE);

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

    ExDelayedWorkerThreads += Index;

    //
    // Create the hypercritical worker thread.
    //

    Status = ExpCreateWorkerThread (HyperCriticalWorkQueue, FALSE);

    //
    // Create the worker thread set manager thread.
    //

    InitializeObjectAttributes (&ObjectAttributes, NULL, 0, NULL, NULL);

    Status = PsCreateSystemThread (&Thread,
                                   THREAD_ALL_ACCESS,
                                   &ObjectAttributes,
                                   0,
                                   NULL,
                                   ExpWorkerThreadBalanceManager,
                                   NULL);

    if (NT_SUCCESS(Status)) {
        Status = ObReferenceObjectByHandle (Thread,
                                            SYNCHRONIZE,
                                            NULL,
                                            KernelMode,
                                            &ExpWorkerThreadBalanceManagerPtr,
                                            NULL);
        ZwClose (Thread);
    }

    return Status;
}
Esempio n. 11
0
NTSTATUS FdoPortOpen(IN PC0C_FDOPORT_EXTENSION pDevExt)
{
  LIST_ENTRY queueToComplete;
  PUCHAR pBase;
  ULONG size;
  KIRQL oldIrql;
  PC0C_IO_PORT pIoPort;

  if (InterlockedIncrement(&pDevExt->openCount) != 1) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  pIoPort = pDevExt->pIoPortLocal;

  if (pIoPort->plugInMode && !pIoPort->pIoPortRemote->isOpen) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  if (pIoPort->exclusiveMode)
    IoInvalidateDeviceRelations(pIoPort->pPhDevObj, BusRelations);

  switch (MmQuerySystemSize()) {
  case MmLargeSystem:
    size = 4096;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmMediumSystem:
    size = 1024;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmSmallSystem:
    size = 128;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  default:
    size = 0;
    pBase = NULL;
  }

  InitializeListHead(&queueToComplete);

#if ENABLE_TRACING
  if (pIoPort->amountInWriteQueue) {
    NTSTATUS status;
    UNICODE_STRING msg;

    status = STATUS_SUCCESS;
    RtlInitUnicodeString(&msg, NULL);
    StrAppendStr0(&status, &msg, L"!!!WARNING!!! amountInWriteQueue = ");
    StrAppendNum(&status, &msg, pIoPort->amountInWriteQueue, 10);

    Trace0((PC0C_COMMON_EXTENSION)pDevExt, msg.Buffer);

    StrFree(&msg);
  }
#endif /* ENABLE_TRACING */

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  InitBuffer(&pIoPort->readBuf, pBase, size);

  pIoPort->amountInWriteQueue = 0;
  pIoPort->tryWrite = FALSE;
  pIoPort->errors = 0;
  pIoPort->waitMask = 0;
  pIoPort->eventMask = 0;
  RtlZeroMemory(&pIoPort->perfStats, sizeof(pIoPort->perfStats));
  pIoPort->handFlow.XoffLimit = size >> 3;
  pIoPort->handFlow.XonLimit = size >> 1;
  pIoPort->pIoPortRemote->brokeIdleChars = 0;

  SetHandFlow(pIoPort, NULL, &queueToComplete);
  SetModemControl(pIoPort, C0C_MCR_OPEN, C0C_MCR_OPEN, &queueToComplete);

  if (pIoPort->pIoPortRemote->pWriteDelay && pIoPort->pIoPortRemote->brokeCharsProbability > 0)
    StartWriteDelayTimer(pIoPort->pIoPortRemote->pWriteDelay);

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  pIoPort->isOpen = TRUE;

  if (pIoPort->pIoPortRemote->plugInMode)
    IoInvalidateDeviceRelations(pIoPort->pIoPortRemote->pPhDevObj, BusRelations);

  FdoPortCompleteQueue(&queueToComplete);

  return STATUS_SUCCESS;
}
Esempio n. 12
0
VOID
UdfInitializeGlobalData (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT *UdfsFileSystemDeviceObjects
    )

/*++

Routine Description:

    This routine initializes the global Udfs data structures.

Arguments:

    DriverObject - Supplies the driver object for UDFS.

    FileSystemDeviceObjects - Supplies a vector of device objects for UDFS.

Return Value:

    None.

--*/

{
    USHORT CcbMaxDepth;
    USHORT FcbDataMaxDepth;
    USHORT FcbIndexMaxDepth;
    USHORT FcbNonPagedMaxDepth;
    USHORT IrpContextMaxDepth;
    USHORT LcbMaxDepth;

    //
    //  Start by initializing the FastIoDispatch Table.
    //

    RtlZeroMemory( &UdfFastIoDispatch, sizeof( FAST_IO_DISPATCH ));

    UdfFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);

    UdfFastIoDispatch.AcquireFileForNtCreateSection =   UdfAcquireForCreateSection;
    UdfFastIoDispatch.ReleaseFileForNtCreateSection =   UdfReleaseForCreateSection;
    UdfFastIoDispatch.FastIoCheckIfPossible =           UdfFastIoCheckIfPossible;   //  CheckForFastIo
    UdfFastIoDispatch.FastIoRead =                      FsRtlCopyRead;              //  Read
    
    UdfFastIoDispatch.FastIoQueryBasicInfo =            NULL;                       //  QueryBasicInfo
    UdfFastIoDispatch.FastIoQueryStandardInfo =         NULL;                       //  QueryStandardInfo
    UdfFastIoDispatch.FastIoLock =                      NULL;                       //  Lock
    UdfFastIoDispatch.FastIoUnlockSingle =              NULL;                       //  UnlockSingle
    UdfFastIoDispatch.FastIoUnlockAll =                 NULL;                       //  UnlockAll
    UdfFastIoDispatch.FastIoUnlockAllByKey =            NULL;                       //  UnlockAllByKey
    UdfFastIoDispatch.FastIoQueryNetworkOpenInfo =      NULL;                       //  QueryNetworkInfo
    
    //
    //  Initialize the CRC table. Per UDF 1.01, we use the seed 10041 octal (4129 dec).
    //

    UdfInitializeCrc16( 4129 );

    //
    //  Initialize the UdfData structure.
    //

    RtlZeroMemory( &UdfData, sizeof( UDF_DATA ));

    UdfData.NodeTypeCode = UDFS_NTC_DATA_HEADER;
    UdfData.NodeByteSize = sizeof( UDF_DATA );

    UdfData.DriverObject = DriverObject;
    RtlCopyMemory( &UdfData.FileSystemDeviceObjects,
                   UdfsFileSystemDeviceObjects,
                   sizeof(PDEVICE_OBJECT) * NUMBER_OF_FS_OBJECTS );

    InitializeListHead( &UdfData.VcbQueue );

    ExInitializeResource( &UdfData.DataResource );

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

    UdfData.CacheManagerCallbacks.AcquireForLazyWrite  = &UdfAcquireForCache;
    UdfData.CacheManagerCallbacks.ReleaseFromLazyWrite = &UdfReleaseFromCache;
    UdfData.CacheManagerCallbacks.AcquireForReadAhead  = &UdfAcquireForCache;
    UdfData.CacheManagerCallbacks.ReleaseFromReadAhead = &UdfReleaseFromCache;

    UdfData.CacheManagerVolumeCallbacks.AcquireForLazyWrite  = &UdfNoopAcquire;
    UdfData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &UdfNoopRelease;
    UdfData.CacheManagerVolumeCallbacks.AcquireForReadAhead  = &UdfNoopAcquire;
    UdfData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &UdfNoopRelease;

    //
    //  Initialize the lock mutex and the async and delay close queues.
    //

    ExInitializeFastMutex( &UdfData.UdfDataMutex );
    InitializeListHead( &UdfData.AsyncCloseQueue );
    InitializeListHead( &UdfData.DelayedCloseQueue );

    ExInitializeWorkItem( &UdfData.CloseItem,
                          (PWORKER_THREAD_ROUTINE) UdfFspClose,
                          NULL );

    //
    //  Do the initialization based on the system size.
    //

    switch (MmQuerySystemSize()) {

    case MmSmallSystem:
        
        IrpContextMaxDepth = 4;
        UdfData.MaxDelayedCloseCount = 10;
        UdfData.MinDelayedCloseCount = 2;
        break;

    case MmLargeSystem:

        IrpContextMaxDepth = 24;
        UdfData.MaxDelayedCloseCount = 72;
        UdfData.MinDelayedCloseCount = 18;
        break;

    default:
    case MmMediumSystem:
    
        IrpContextMaxDepth = 8;
        UdfData.MaxDelayedCloseCount = 32;
        UdfData.MinDelayedCloseCount = 8;
        break;
    
    }

    //
    //  Size lookasides to match what will commonly be dumped into them when we
    //  run down the delayed close queues.
    //
    
    LcbMaxDepth =
    CcbMaxDepth =
    FcbDataMaxDepth =
    FcbNonPagedMaxDepth = (USHORT) (UdfData.MaxDelayedCloseCount - UdfData.MinDelayedCloseCount);

    //
    //  We should tend to have fewer indices than files.
    //
    
    FcbIndexMaxDepth = FcbNonPagedMaxDepth / 2;

#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }

    NPagedInit( &UdfIrpContextLookasideList, sizeof( IRP_CONTEXT ), TAG_IRP_CONTEXT, IrpContextMaxDepth );
    NPagedInit( &UdfFcbNonPagedLookasideList, sizeof( FCB_NONPAGED ), TAG_FCB_NONPAGED, FcbNonPagedMaxDepth );

    PagedInit( &UdfCcbLookasideList, sizeof( CCB ), TAG_CCB, CcbMaxDepth );
    PagedInit( &UdfFcbIndexLookasideList, SIZEOF_FCB_INDEX, TAG_FCB_INDEX, FcbIndexMaxDepth );
    PagedInit( &UdfFcbDataLookasideList, SIZEOF_FCB_DATA, TAG_FCB_DATA, FcbDataMaxDepth );
    PagedInit( &UdfLcbLookasideList, SIZEOF_LOOKASIDE_LCB, TAG_LCB, LcbMaxDepth );
}
Esempio n. 13
0
NTSTATUS
SerialDeviceFileCreateWorker (
    IN WDFDEVICE Device
    )
{
    NTSTATUS status;
    PSERIAL_DEVICE_EXTENSION extension = SerialGetDeviceExtension (Device);

    //
    // Create a buffer for the RX data when no reads are outstanding.
    //

    extension->InterruptReadBuffer = NULL;
    extension->BufferSize = 0;

    switch (MmQuerySystemSize()) {

        case MmLargeSystem: {

            extension->BufferSize = 4096;
            extension->InterruptReadBuffer = ExAllocatePoolWithTag(
                                                 NonPagedPool,
                                                 extension->BufferSize,
                                                 POOL_TAG
                                                 );

            if (extension->InterruptReadBuffer) {
                break;
            }

        }

        case MmMediumSystem: {

            extension->BufferSize = 1024;
            extension->InterruptReadBuffer = ExAllocatePoolWithTag(
                                                 NonPagedPool,
                                                 extension->BufferSize,
                                                 POOL_TAG
                                                 );

            if (extension->InterruptReadBuffer) {
                break;
            }

        }

        case MmSmallSystem: {

            extension->BufferSize = 128;
            extension->InterruptReadBuffer = ExAllocatePoolWithTag(
                                                 NonPagedPool,
                                                 extension->BufferSize,
                                                 POOL_TAG
                                                 );

        }

    }

    if (!extension->InterruptReadBuffer) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // By taking a power reference by calling WdfDeviceStopIdle, we prevent the
    // framework from powering down our device due to idle timeout when there
    // is an open handle.  Power reference also moves the device to D0 if we are
    // idled out. If you fail create anywhere later in this routine, do make sure
    // drop the reference.
    //
    status = WdfDeviceStopIdle(Device, TRUE);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // wakeup is not currently enabled
    //

    extension->IsWakeEnabled = FALSE;

    //
    // On a new open we "flush" the read queue by initializing the
    // count of characters.
    //

    extension->CharsInInterruptBuffer = 0;
    extension->LastCharSlot = extension->InterruptReadBuffer +
                              (extension->BufferSize - 1);

    extension->ReadBufferBase = extension->InterruptReadBuffer;
    extension->CurrentCharSlot = extension->InterruptReadBuffer;
    extension->FirstReadableChar = extension->InterruptReadBuffer;

    extension->TotalCharsQueued = 0;

    //
    // We set up the default xon/xoff limits.
    //

    extension->HandFlow.XoffLimit = extension->BufferSize >> 3;
    extension->HandFlow.XonLimit = extension->BufferSize >> 1;

    extension->WmiCommData.XoffXmitThreshold = extension->HandFlow.XoffLimit;
    extension->WmiCommData.XonXmitThreshold = extension->HandFlow.XonLimit;

    extension->BufferSizePt8 = ((3*(extension->BufferSize>>2))+
                                   (extension->BufferSize>>4));

    //
    // Mark the device as busy for WMI
    //

    extension->WmiCommData.IsBusy = TRUE;

    extension->IrpMaskLocation = NULL;
    extension->HistoryMask = 0;
    extension->IsrWaitMask = 0;

    extension->SendXonChar = FALSE;
    extension->SendXoffChar = FALSE;

#if !DBG
    //
    // Clear out the statistics.
    //

    WdfInterruptSynchronize(
        extension->WdfInterrupt,
        SerialClearStats,
        extension
        );
#endif

    //
    // The escape char replacement must be reset upon every open.
    //

    extension->EscapeChar = 0;

    //
    // We don't want the device to be removed or stopped when there is an handle
    //
    // Note to anyone copying this sample as a starting point:
    //
    // This works in this driver simply because this driver supports exactly
    // one open handle at a time.  If it supported more, then it would need
    // counting logic to determine when all the reasons for failing Stop/Remove
    // were gone.
    //
    WdfDeviceSetStaticStopRemove(Device, FALSE);

    //
    // Synchronize with the ISR and let it know that the device
    // has been successfully opened.
    //

    WdfInterruptSynchronize(
        extension->WdfInterrupt,
        SerialMarkOpen,
        extension
        );

    return STATUS_SUCCESS;

}
Esempio n. 14
0
VOID
CdInitializeGlobalData (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT FileSystemDeviceObject
    )

/*++

Routine Description:

    This routine initializes the global cdfs data structures.

Arguments:

    DriverObject - Supplies the driver object for CDFS.

    FileSystemDeviceObject - Supplies the device object for CDFS.

Return Value:

    None.

--*/

{
    //
    //  Start by initializing the FastIoDispatch Table.
    //

    RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH ));

    CdFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    CdFastIoDispatch.FastIoCheckIfPossible =   CdFastIoCheckIfPossible;  //  CheckForFastIo
    CdFastIoDispatch.FastIoRead =              FsRtlCopyRead;            //  Read
    CdFastIoDispatch.FastIoQueryBasicInfo =    CdFastQueryBasicInfo;     //  QueryBasicInfo
    CdFastIoDispatch.FastIoQueryStandardInfo = CdFastQueryStdInfo;       //  QueryStandardInfo
    CdFastIoDispatch.FastIoLock =              CdFastLock;               //  Lock
    CdFastIoDispatch.FastIoUnlockSingle =      CdFastUnlockSingle;       //  UnlockSingle
    CdFastIoDispatch.FastIoUnlockAll =         CdFastUnlockAll;          //  UnlockAll
    CdFastIoDispatch.FastIoUnlockAllByKey =    CdFastUnlockAllByKey;     //  UnlockAllByKey
    CdFastIoDispatch.AcquireFileForNtCreateSection =  CdAcquireForCreateSection;
    CdFastIoDispatch.ReleaseFileForNtCreateSection =  CdReleaseForCreateSection;
    CdFastIoDispatch.FastIoQueryNetworkOpenInfo =     CdFastQueryNetworkInfo;   //  QueryNetworkInfo

    //
    //  Initialize the CdData structure.
    //

    RtlZeroMemory( &CdData, sizeof( CD_DATA ));

    CdData.NodeTypeCode = CDFS_NTC_DATA_HEADER;
    CdData.NodeByteSize = sizeof( CD_DATA );

    CdData.DriverObject = DriverObject;
    CdData.FileSystemDeviceObject = FileSystemDeviceObject;

    InitializeListHead( &CdData.VcbQueue );

    ExInitializeResource( &CdData.DataResource );

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

    CdData.CacheManagerCallbacks.AcquireForLazyWrite  = &CdAcquireForCache;
    CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = &CdReleaseFromCache;
    CdData.CacheManagerCallbacks.AcquireForReadAhead  = &CdAcquireForCache;
    CdData.CacheManagerCallbacks.ReleaseFromReadAhead = &CdReleaseFromCache;

    CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite  = &CdNoopAcquire;
    CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease;
    CdData.CacheManagerVolumeCallbacks.AcquireForReadAhead  = &CdNoopAcquire;
    CdData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &CdNoopRelease;

    //
    //  Initialize the lock mutex and the async and delay close queues.
    //

    ExInitializeFastMutex( &CdData.CdDataMutex );
    InitializeListHead( &CdData.AsyncCloseQueue );
    InitializeListHead( &CdData.DelayedCloseQueue );

    ExInitializeWorkItem( &CdData.CloseItem,
                          (PWORKER_THREAD_ROUTINE) CdFspClose,
                          NULL );

    //
    //  Do the initialization based on the system size.
    //

    switch (MmQuerySystemSize()) {

    case MmSmallSystem:

        CdData.IrpContextMaxDepth = 4;
        CdData.MaxDelayedCloseCount = 8;
        CdData.MinDelayedCloseCount = 2;
        break;

    case MmMediumSystem:

        CdData.IrpContextMaxDepth = 8;
        CdData.MaxDelayedCloseCount = 24;
        CdData.MinDelayedCloseCount = 6;
        break;

    case MmLargeSystem:

        CdData.IrpContextMaxDepth = 32;
        CdData.MaxDelayedCloseCount = 72;
        CdData.MinDelayedCloseCount = 18;
        break;
    }
}
Esempio n. 15
-1
NTSTATUS
DfsDriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
) {
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    PDEVICE_OBJECT DeviceObject;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PWSTR p;
    int i;
    HANDLE hTemp;
    HANDLE DirHandle;
    IO_STATUS_BLOCK iosb;

    //
    // See if someone else has already created a File System Device object
    // with the name we intend to use. If so, we bail.
    //

    RtlInitUnicodeString( &UnicodeString, DFS_DRIVER_NAME );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &UnicodeString,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL);

    Status = ZwCreateFile(
                 &hTemp,
                 SYNCHRONIZE,
                 &ObjectAttributes,
                 &iosb,
                 NULL,
                 FILE_ATTRIBUTE_NORMAL,
                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                 FILE_OPEN,
                 0,
                 NULL,
                 0);

    if (NT_SUCCESS(Status)) {
        ZwClose( hTemp );
        DfsDbgTrace(0, Dbg, "Dfs driver already loaded!\n", 0);
        return( STATUS_UNSUCCESSFUL );
    }

    //
    // Create the filesystem device object.
    //

    Status = IoCreateDevice( DriverObject,
             0,
             &UnicodeString,
             FILE_DEVICE_DFS_FILE_SYSTEM,
             FILE_REMOTE_DEVICE,
             FALSE,
             &DeviceObject );
    if ( !NT_SUCCESS( Status ) ) {
        return Status;
    }

    //
    // Create a permanent object directory in which the logical root
    // device objects will reside.  Make the directory temporary, so
    // we can just close the handle to make it go away.
    //

    UnicodeString.Buffer = p = LogicalRootDevPath;
    UnicodeString.Length = 0;
    UnicodeString.MaximumLength = MAX_LOGICAL_ROOT_LEN;
    while (*p++ != UNICODE_NULL)
        UnicodeString.Length += sizeof (WCHAR);

    InitializeObjectAttributes(
        &ObjectAttributes,
        &UnicodeString,
        OBJ_PERMANENT,
        NULL,
        NULL );

    Status = ZwCreateDirectoryObject(
                &DirHandle,
                DIRECTORY_ALL_ACCESS,
                &ObjectAttributes);

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

    ZwMakeTemporaryObject(DirHandle);

    p[-1] = UNICODE_PATH_SEP;
    UnicodeString.Length += sizeof (WCHAR);

    //
    // Initialize the driver object with this driver's entry points.
    // Most are simply passed through to some other device driver.
    //

    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = DfsVolumePassThrough;
    }

    DriverObject->MajorFunction[IRP_MJ_CREATE]      = (PDRIVER_DISPATCH)DfsFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]       = (PDRIVER_DISPATCH)DfsFsdClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]     = (PDRIVER_DISPATCH)DfsFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)DfsFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdSetVolumeInformation;

    DriverObject->FastIoDispatch = &FastIoDispatch;

    //
    //  Initialize the global data structures
    //

    RtlZeroMemory(&DfsData, sizeof (DFS_DATA));

    DfsData.NodeTypeCode = DSFS_NTC_DATA_HEADER;
    DfsData.NodeByteSize = sizeof( DFS_DATA );

    InitializeListHead( &DfsData.VcbQueue );
    InitializeListHead( &DfsData.DeletedVcbQueue );

    InitializeListHead( &DfsData.Credentials );
    InitializeListHead( &DfsData.DeletedCredentials );

    DfsData.DriverObject = DriverObject;
    DfsData.FileSysDeviceObject = DeviceObject;

    DfsData.LogRootDevName = UnicodeString;

    ExInitializeResource( &DfsData.Resource );
    KeInitializeEvent( &DfsData.PktWritePending, NotificationEvent, TRUE );
    KeInitializeSemaphore( &DfsData.PktReferralRequests, 1, 1 );

    DfsData.MachineState = DFS_CLIENT;

    //
    //  Allocate Provider structures.
    //

    DfsData.pProvider = ExAllocatePool( PagedPool,
                       sizeof ( PROVIDER_DEF ) * MAX_PROVIDERS);

    for (i = 0; i < MAX_PROVIDERS; i++) {
        DfsData.pProvider[i].NodeTypeCode = DSFS_NTC_PROVIDER;
        DfsData.pProvider[i].NodeByteSize = sizeof ( PROVIDER_DEF );
    }

    DfsData.cProvider = 0;
    DfsData.maxProvider = MAX_PROVIDERS;

    //
    //  Initialize the system wide PKT
    //

    PktInitialize(&DfsData.Pkt);

    {
    ULONG SystemSizeMultiplier;
    ULONG ZoneSegmentSize;

    switch (MmQuerySystemSize()) {
    default:
    case MmSmallSystem:
        SystemSizeMultiplier = 4;
        break;
    case MmMediumSystem:
        SystemSizeMultiplier = 8;
        break;

    case MmLargeSystem:
        SystemSizeMultiplier = 16;
        break;
    }

    //
    //  Allocate the DFS_FCB hash table structure.  The number of hash buckets
    //  will depend upon the memory size of the system.
    //

    Status = DfsInitFcbs(SystemSizeMultiplier * 2);

    //
    //  Now initialize the zone structures for allocating IRP context
    //  records.  The size of the zone will depend upon the memory
    //  available in the system.
    //

    KeInitializeSpinLock( &DfsData.IrpContextSpinLock );

    ZoneSegmentSize = (SystemSizeMultiplier *
               QuadAlign(sizeof(IRP_CONTEXT))) +
              sizeof(ZONE_SEGMENT_HEADER);

    (VOID) ExInitializeZone( &DfsData.IrpContextZone,
                 QuadAlign(sizeof(IRP_CONTEXT)),
                 FsRtlAllocatePool( NonPagedPool,
                            ZoneSegmentSize ),
                 ZoneSegmentSize );

    }

    //
    //  Set up global pointer to the system process.
    //

    DfsData.OurProcess = PsGetCurrentProcess();

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

    IoRegisterFileSystem( DeviceObject );

    //
    //  Initialize the provider definitions from the registry.
    //

    if (!NT_SUCCESS( ProviderInit() )) {

        DfsDbgTrace(0,DEBUG_TRACE_ERROR,
               "Could not initialize some or all providers!\n", 0);

    }

    //
    // Initialize the logical roots device objects. These are what form the
    // link between the outside world and the Dfs driver.
    //

    Status = DfsInitializeLogicalRoot( DD_DFS_DEVICE_NAME, NULL, NULL, 0);

    if (!NT_SUCCESS(Status)) {
      DfsDbgTrace(-1, DEBUG_TRACE_ERROR, "Failed creation of root logical root %08lx\n", Status);
      return(Status);
    }

    //
    // Let us start off the Timer Routine.
    //

    RtlZeroMemory(&DfsTimerContext, sizeof(DFS_TIMER_CONTEXT));
    DfsTimerContext.InUse = FALSE;
    DfsTimerContext.TickCount = 0;
    IoInitializeTimer(DeviceObject, DfsIoTimerRoutine, &DfsTimerContext);
    DfsDbgTrace(0, Dbg, "Initialized the Timer routine\n", 0);

    //
    //  Let us start the timer now.
    //

    IoStartTimer(DeviceObject);

    return STATUS_SUCCESS;
}