|
|
/*++
Copyright (c) 1996-2000 Microsoft Corporation
Module Name:
UdfInit.c
Abstract:
This module implements the DRIVER_INITIALIZATION routine for Udfs
// @@BEGIN_DDKSPLIT
Author:
Dan Lovinger [DanLo] 24-May-1996 Tom Jolly [tomjolly] 21-Jan-2000 Revision History:
// @@END_DDKSPLIT
--*/
#include "UdfProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (UDFS_BUG_CHECK_UDFINIT)
//
// The local debug trace level
//
#define Dbg (UDFS_DEBUG_LEVEL_UDFINIT)
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );
VOID UdfInitializeGlobalData ( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT *FileSystemDeviceObjects );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(INIT, UdfInitializeGlobalData)
#endif
//
// Local support routine
//
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
/*++
Routine Description:
This is the initialization routine for the UDF 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 UdfsFileSystemDeviceObjects[NUMBER_OF_FS_OBJECTS]; PDEVICE_OBJECT UdfsDiskFileSystemDeviceObject;
//
// Create the device objects for both device "types". Since
// UDF is a legitimate filesystem for media underlying device
// drivers claiming both DVD/CDROMs and disks, we must register
// this filesystem twice.
//
ASSERT( NUMBER_OF_FS_OBJECTS >= 2 ); RtlZeroMemory( UdfsFileSystemDeviceObjects, sizeof(PDEVICE_OBJECT) * NUMBER_OF_FS_OBJECTS ); RtlInitUnicodeString( &UnicodeString, L"\\UdfsCdRom" );
Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &UdfsFileSystemDeviceObjects[0] );
if (!NT_SUCCESS( Status )) { return Status; } RtlInitUnicodeString( &UnicodeString, L"\\UdfsDisk" );
Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &UdfsFileSystemDeviceObjects[1] );
if (!NT_SUCCESS( Status )) {
ObDereferenceObject( UdfsFileSystemDeviceObjects[0] ); return Status; } try {
Status = STATUS_SUCCESS;
//
// Initialize the global data structures
//
UdfInitializeGlobalData( DriverObject, UdfsFileSystemDeviceObjects );
//
// Note that because of the way data caching is done, we set neither
// the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If
// data is not in the cache, or the request is not buffered, we may,
// set up for Direct I/O by hand.
//
//
// Initialize the driver object with this driver's entry points.
//
// NOTE - Each entry in the dispatch table must have an entry in
// the Fsp/Fsd dispatch switch statements.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) UdfFsdDispatch;
DriverObject->FastIoDispatch = &UdfFastIoDispatch; //
// Register the file system with the I/O system
//
IoRegisterFileSystem( UdfsFileSystemDeviceObjects[0] ); IoRegisterFileSystem( UdfsFileSystemDeviceObjects[1] );
} except (FsRtlIsNtstatusExpected(GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
ObDereferenceObject( UdfsFileSystemDeviceObjects[0] ); ObDereferenceObject( UdfsFileSystemDeviceObjects[1] );
Status = GetExceptionCode(); } //
// And return to our caller
//
return Status; }
//
// Local support routine
//
#define NPagedInit(L,S,T) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, 0); }
#define PagedInit(L,S,T) { ExInitializePagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, 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.
--*/
{ TIMESTAMP UdfTime;
//
// Initialize the CRC table. Per UDF 1.01, we use the seed 10041 octal (4129 dec).
// We do this first because it can raise (allocates memory)
//
UdfInitializeCrc16( 4129 );
//
// 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
UdfFastIoDispatch.MdlRead = FsRtlMdlReadDev; UdfFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; UdfFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; UdfFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;
//
// 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 );
ExInitializeResourceLite( &UdfData.DataResource );
#ifdef UDF_CAPTURE_BACKTRACES
//
// Initialize debugging stack backtrace support.
//
UdfData.A.BufferPage = FsRtlAllocatePoolWithTag( UdfPagedPool, PAGE_SIZE, TAG_CDROM_TOC);
UdfData.B.BufferPage = FsRtlAllocatePoolWithTag( UdfPagedPool, PAGE_SIZE, TAG_CDROM_TOC);
ExInitializeFastMutex( &UdfData.ExceptionInfoMutex);
#endif
//
// 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: UdfData.MaxDelayedCloseCount = 10; UdfData.MinDelayedCloseCount = 2; break;
case MmLargeSystem:
UdfData.MaxDelayedCloseCount = 72; UdfData.MinDelayedCloseCount = 18; break;
default: case MmMediumSystem: UdfData.MaxDelayedCloseCount = 32; UdfData.MinDelayedCloseCount = 8; break; }
NPagedInit( &UdfIrpContextLookasideList, sizeof( IRP_CONTEXT ), TAG_IRP_CONTEXT); NPagedInit( &UdfFcbNonPagedLookasideList, sizeof( FCB_NONPAGED ), TAG_FCB_NONPAGED);
PagedInit( &UdfCcbLookasideList, sizeof( CCB ), TAG_CCB ); PagedInit( &UdfFcbIndexLookasideList, SIZEOF_FCB_INDEX, TAG_FCB_INDEX ); PagedInit( &UdfFcbDataLookasideList, SIZEOF_FCB_DATA, TAG_FCB_DATA ); PagedInit( &UdfLcbLookasideList, SIZEOF_LOOKASIDE_LCB, TAG_LCB);
//
// Initialize our default time which we use when enumerating FIDs whose
// associated FEs are toast.
//
RtlZeroMemory( &UdfTime, sizeof( TIMESTAMP)); UdfTime.Day = 25; UdfTime.Month = 7; UdfTime.Year = 1974; UdfConvertUdfTimeToNtTime( NULL, &UdfTime, &UdfCorruptFileTime); }
|