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