BOOLEAN PiInitPhase0( VOID ) /*++ Routine Description: This function performs Phase 0 initializaion of the Plug and Play Manager component of the NT system. It initializes the PnP registry and bus list resources, and initializes the bus list head to empty. Arguments: None. Return Value: TRUE - Initialization succeeded. FALSE - Initialization failed. --*/ { #if _PNP_POWER_ // // Initialize the Plug and Play bus list resource. // ExInitializeResource( &PpBusResource ); // // Initialize the Plug and Play bus list head. // InitializeListHead( &PpBusListHead ); #endif // _PNP_POWER_ // // Initialize the device-specific, Plug and Play registry resource. // ExInitializeResource( &PpRegistryDeviceResource ); return TRUE; }
VOID BowserInitializeTraceLog() { PAGED_CODE(); ExInitializeResource(&BrowserTraceLock); }
VOID MsInitializeData( VOID ) /*++ Routine Description: This function initializes all MSFS global data. Arguments: None. Return Value: None. --*/ { PAGED_CODE(); #ifdef MSDBG MsDebugTraceLevel = 0; MsDebugTraceIndent = 0; #endif MsGlobalResource = FsRtlAllocatePoolWithTag (NonPagedPoolMustSucceed, sizeof(ERESOURCE) * 3, 'sFsM'); MsPrefixTableResource = MsGlobalResource + 1; MsCcbListResource = MsGlobalResource + 2; ExInitializeResource ( MsGlobalResource ); ExInitializeResource ( MsPrefixTableResource ); ExInitializeResource ( MsCcbListResource ); }
BOOLEAN ExpUuidInitialization ( VOID ) /*++ Routine Description: This function initializes the UUID allocation. Arguments: None. Return Value: A value of TRUE is returned if the initialization is successfully completed. Otherwise, a value of FALSE is returned. --*/ { NTSTATUS Status; PAGED_CODE(); ExInitializeResource(&ExpUuidLock); ExInitializeResource(&ExpSequenceLock); ExpUuidSequenceNumberValid = FALSE; // We can use the current time since we'll be changing the sequence number. KeQuerySystemTime(&ExpUuidLastTimeAllocated); return TRUE; }
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; } }
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; }
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 ); }
VOID MsInitializeVcb ( IN PVCB Vcb ) /*++ Routine Description: This routine initializes new Vcb record. The Vcb record "hangs" off the end of the Msfs device object and must be allocated by our caller. Arguments: Vcb - Supplies the address of the Vcb record being initialized. Return Value: None. --*/ { PAGED_CODE(); DebugTrace(+1, Dbg, "MsInitializeVcb, Vcb = %08lx\n", (ULONG)Vcb); // // We start by first zeroing out all of the VCB, this will guarantee // that any stale data is wiped clean. // RtlZeroMemory( Vcb, sizeof(VCB) ); // // Set the node type code, node byte size, and reference count. // Vcb->Header.NodeTypeCode = MSFS_NTC_VCB; Vcb->Header.NodeByteSize = sizeof(VCB); Vcb->Header.ReferenceCount = 1; Vcb->Header.NodeState = NodeStateActive; // // Initialize the Volume name // Vcb->FileSystemName.Buffer = MSFS_NAME_STRING; Vcb->FileSystemName.Length = sizeof( MSFS_NAME_STRING ) - sizeof( WCHAR ); Vcb->FileSystemName.MaximumLength = sizeof( MSFS_NAME_STRING ); // // Initialize the Prefix table // RtlInitializeUnicodePrefix( &Vcb->PrefixTable ); // // Initialize the resource variable for the VCB. // ExInitializeResource( &Vcb->Resource ); // // Return to the caller. // DebugTrace(-1, Dbg, "MsInitializeVcb -> VOID\n", 0); return; }
PCCB MsCreateCcb ( IN PFCB Fcb ) /*++ Routine Description: This routine creates a new CCB record. Arguments: Fcb - Supplies a pointer to the FCB to which we are attached. Return Value: PCCB - returns a pointer to the newly allocate CCB. --*/ { PCCB ccb; PAGED_CODE(); DebugTrace(+1, Dbg, "MsCreateCcb\n", 0); ASSERT( Fcb->Header.NodeState == NodeStateActive ); // // Allocate a new CCB record and zero its fields. // ccb = FsRtlAllocatePool( NonPagedPool, sizeof(CCB) ); RtlZeroMemory( ccb, sizeof(CCB) ); // // Set the proper node type code, node byte size, and reference count. // ccb->Header.NodeTypeCode = MSFS_NTC_CCB; ccb->Header.NodeByteSize = sizeof(CCB); ccb->Header.ReferenceCount = 1; ccb->Header.NodeState = NodeStateActive; // // Insert ourselves in the list of ccb for the fcb, and reference // the fcb. // MsAcquireCcbListLock(); InsertTailList( &Fcb->Specific.Fcb.CcbQueue, &ccb->CcbLinks ); MsReleaseCcbListLock(); ccb->Fcb = Fcb; MsAcquireGlobalLock(); MsReferenceNode( &Fcb->Header ); MsReleaseGlobalLock(); // // Initialize the CCB's resource. // ExInitializeResource( &ccb->Resource ); // // Return to the caller. // DebugTrace(-1, Dbg, "MsCreateCcb -> %08lx\n", (ULONG)ccb); return ccb; }
PROOT_DCB MsCreateRootDcb ( IN PVCB Vcb ) /*++ Routine Description: This routine allocates, initializes, and inserts a new root DCB record into the in memory data structure. Arguments: Vcb - Supplies the Vcb to associate the new DCB under Return Value: PROOT_DCB - returns pointer to the newly allocated root DCB. --*/ { PROOT_DCB rootDcb; PAGED_CODE(); DebugTrace(+1, Dbg, "MsCreateRootDcb, Vcb = %08lx\n", (ULONG)Vcb); // // Make sure we don't already have a root dcb for this vcb // rootDcb = Vcb->RootDcb; if (rootDcb != NULL) { DebugDump("Error trying to create multiple root dcbs\n", 0, Vcb); KeBugCheck( MAILSLOT_FILE_SYSTEM ); } // // Allocate a new DCB and zero its fields. // rootDcb = FsRtlAllocatePool( NonPagedPool, sizeof(DCB) ); RtlZeroMemory( rootDcb, sizeof(DCB)); // // Set the proper node type code, node byte size, and reference count. // rootDcb->Header.NodeTypeCode = MSFS_NTC_ROOT_DCB; rootDcb->Header.NodeByteSize = sizeof(ROOT_DCB); rootDcb->Header.ReferenceCount = 1; rootDcb->Header.NodeState = NodeStateActive; // // The root Dcb has an empty parent dcb links field // InitializeListHead( &rootDcb->ParentDcbLinks ); // // Set the Vcb and give it a pointer to the new root DCB. // rootDcb->Vcb = Vcb; Vcb->RootDcb = rootDcb; // // Initialize the notify queues, and the parent dcb queue. // InitializeListHead( &rootDcb->Specific.Dcb.NotifyFullQueue ); InitializeListHead( &rootDcb->Specific.Dcb.NotifyPartialQueue ); InitializeListHead( &rootDcb->Specific.Dcb.ParentDcbQueue ); // // Set the full file name // { PWCH Name; Name = FsRtlAllocatePool(PagedPool, 2 * sizeof(WCHAR)); Name[0] = L'\\'; Name[1] = L'\0'; RtlInitUnicodeString( &rootDcb->FullFileName, Name ); RtlInitUnicodeString( &rootDcb->LastFileName, Name ); } // // Insert this DCB into the prefix table. // MsAcquirePrefixTableLock(); if (!RtlInsertUnicodePrefix( &Vcb->PrefixTable, &rootDcb->FullFileName, &rootDcb->PrefixTableEntry )) { DebugDump("Error trying to insert root dcb into prefix table\n", 0, Vcb); KeBugCheck( MAILSLOT_FILE_SYSTEM ); } MsReleasePrefixTableLock(); // // Initialize the resource variable. // ExInitializeResource( &(rootDcb->Resource) ); // // Return to the caller. // DebugTrace(-1, Dbg, "MsCreateRootDcb -> %8lx\n", (ULONG)rootDcb); return rootDcb; }
PFCB MsCreateFcb ( IN PVCB Vcb, IN PDCB ParentDcb, IN PUNICODE_STRING FileName, IN PEPROCESS CreatorProcess, IN ULONG MailslotQuota, IN ULONG MaximumMessageSize ) /*++ Routine Description: This routine allocates, initializes, and inserts a new Fcb record into the in memory data structures. Arguments: Vcb - Supplies the Vcb to associate the new FCB under. ParentDcb - Supplies the parent dcb that the new FCB is under. FileName - Supplies the file name of the file relative to the directory it's in (e.g., the file \config.sys is called "CONFIG.SYS" without the preceding backslash). CreatorProcess - Supplies a pointer to our creator process MailslotQuota - Supplies the initial quota MaximumMessageSize - Supplies the size of the largest message that can be written to the mailslot Return Value: PFCB - Returns a pointer to the newly allocated FCB --*/ { PFCB fcb; PAGED_CODE(); DebugTrace(+1, Dbg, "MsCreateFcb\n", 0); // // Allocate a new FCB record, and zero its fields. // fcb = FsRtlAllocatePool( NonPagedPool, sizeof(FCB) ); RtlZeroMemory( fcb, sizeof(FCB) ); // // Set the proper node type code, node byte size, and reference count. // fcb->Header.NodeTypeCode = MSFS_NTC_FCB; fcb->Header.NodeByteSize = sizeof(FCB); fcb->Header.ReferenceCount = 1; fcb->Header.NodeState = NodeStateActive; // // Insert this FCB into our parent DCB's queue. // InsertTailList( &ParentDcb->Specific.Dcb.ParentDcbQueue, &fcb->ParentDcbLinks ); // // Initialize other FCB fields. // fcb->ParentDcb = ParentDcb; fcb->Vcb = Vcb; MsAcquireGlobalLock(); MsReferenceNode ( &Vcb->Header ); if (Vcb->Header.ReferenceCount == 2) { // // Set the driver paging back to normal // MmResetDriverPaging(MsCreateFcb); } MsReleaseGlobalLock(); fcb->CreatorProcess = CreatorProcess; ExInitializeResource( &(fcb->Resource) ); // // Initialize the CCB queue. // InitializeListHead( &fcb->Specific.Fcb.CcbQueue ); // // Set the file name. // { PWCH Name; ULONG Length; Length = FileName->Length; Name = FsRtlAllocatePool( PagedPool, Length + 2 ); RtlMoveMemory( Name, FileName->Buffer, Length ); *(PWCH)( (PCH)Name + Length ) = L'\0'; RtlInitUnicodeString( &fcb->FullFileName, Name ); RtlInitUnicodeString( &fcb->LastFileName, &Name[1] ); } // // Insert this FCB into the prefix table. // MsAcquirePrefixTableLock(); if (!RtlInsertUnicodePrefix( &Vcb->PrefixTable, &fcb->FullFileName, &fcb->PrefixTableEntry )) { DebugDump("Error trying to name into prefix table\n", 0, fcb); KeBugCheck( MAILSLOT_FILE_SYSTEM ); } MsReleasePrefixTableLock(); // // Initialize the data queue. // MsInitializeDataQueue( &fcb->DataQueue, CreatorProcess, MailslotQuota, MaximumMessageSize); // // Return to the caller. // DebugTrace(-1, Dbg, "MsCreateFcb -> %08lx\n", (ULONG)fcb); return fcb; }
PLFCB LfsAllocateLfcb ( ) /*++ Routine Description: This routine allocates and initializes a log file control block. Arguments: Return Value: PLFCB - A pointer to the log file control block just allocated and initialized. --*/ { PLFCB Lfcb = NULL; ULONG Count; PLBCB NextLbcb; PAGED_CODE(); DebugTrace( +1, Dbg, "LfsAllocateLfcb: Entered\n", 0 ); // // Use a try-finally to facilitate cleanup. // try { // // Allocate and zero the structure for the Lfcb. // Lfcb = FsRtlAllocatePool( PagedPool, sizeof( LFCB )); // // Zero out the structure initially. // RtlZeroMemory( Lfcb, sizeof( LFCB )); // // Initialize the log file control block. // Lfcb->NodeTypeCode = LFS_NTC_LFCB; Lfcb->NodeByteSize = sizeof( LFCB ); // // Initialize the client links. // InitializeListHead( &Lfcb->LchLinks ); // // Initialize the Lbcb links. // InitializeListHead( &Lfcb->LbcbWorkque ); InitializeListHead( &Lfcb->LbcbActive ); // // Initialize and allocate the spare Lbcb queue. // InitializeListHead( &Lfcb->SpareLbcbList ); for (Count = 0; Count < LFCB_RESERVE_LBCB_COUNT; Count++ ) { NextLbcb = ExAllocatePoolWithTag( PagedPool, sizeof( LBCB ), ' sfL' ); if (NextLbcb != NULL) { InsertHeadList( &Lfcb->SpareLbcbList, (PLIST_ENTRY) NextLbcb ); Lfcb->SpareLbcbCount += 1; } } // // Allocate the Lfcb synchronization event. // Lfcb->Sync = FsRtlAllocatePool( NonPagedPool, sizeof( LFCB_SYNC )); ExInitializeResource( &Lfcb->Sync->Resource ); // // Initialize the pseudo Lsn for the restart Lbcb's // Lfcb->NextRestartLsn = LfsLi1; // // Initialize the event to the signalled state. // KeInitializeEvent( &Lfcb->Sync->Event, NotificationEvent, TRUE ); Lfcb->Sync->UserCount = 0; } finally { DebugUnwind( LfsAllocateFileControlBlock ); if (AbnormalTermination() && Lfcb != NULL) { LfsDeallocateLfcb( Lfcb, TRUE ); Lfcb = NULL; } DebugTrace( -1, Dbg, "LfsAllocateLfcb: Exit -> %08lx\n", Lfcb ); } return Lfcb; }
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; }
BOOLEAN FsRtlInitSystem ( ) { ULONG i; ULONG Value; UNICODE_STRING ValueName; extern KSEMAPHORE FsRtlpUncSemaphore; PAGED_CODE(); // // Allocate and initialize all the paging Io resources // FsRtlPagingIoResources = FsRtlAllocatePool( NonPagedPool, FSRTL_NUMBER_OF_RESOURCES * sizeof(ERESOURCE) ); for (i=0; i < FSRTL_NUMBER_OF_RESOURCES; i++) { ExInitializeResource( &FsRtlPagingIoResources[i] ); } // // Initialize the global tunneling structures. // FsRtlInitializeTunnels(); // // Initialize the global filelock structures. // FsRtlInitializeFileLocks(); // // Initialize the global largemcb structures. // FsRtlInitializeLargeMcbs(); // // Initialize the semaphore used to guard loading of the MUP // KeInitializeSemaphore( &FsRtlpUncSemaphore, 1, MAXLONG ); // // Pull the bit from the registry telling us whether to do a safe // or dangerous extension truncation. // ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME; ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME); if (NT_SUCCESS(FsRtlGetCompatibilityModeValue( &ValueName, &Value )) && (Value != 0)) { FsRtlSafeExtensions = FALSE; } // // Initialize the FsRtl stack overflow work QueueObject and thread. // if (!NT_SUCCESS(FsRtlInitializeWorkerThread())) { return FALSE; } return TRUE; }
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 ); }
//---------------------------------------------------------------------------- NTSTATUS InitNotOs( void ) /*++ Routine Description: This is the initialization routine for the Non-OS Specific side of the NBT device driver. pNbtGlobConfig must be initialized before this is called! Arguments: Return Value: NTSTATUS - The function value is the final status from the initialization operation. --*/ { NTSTATUS status = STATUS_SUCCESS; ULONG i; CTEPagedCode(); // // for multihomed hosts, this tracks the number of adapters as each one // is created. // NbtConfig.AdapterCount = 0; NbtConfig.MultiHomed = FALSE; NbtConfig.SingleResponse = FALSE; // // Initialize the name statistics // CTEZeroMemory( &NameStatsInfo,sizeof(tNAMESTATS_INFO) ); InitializeListHead(&pNbtGlobConfig->DeviceContexts); #ifndef _IO_DELETE_DEVICE_SUPPORTED InitializeListHead(&pNbtGlobConfig->FreeDevCtx); #endif InitializeListHead(&NbtConfig.AddressHead); InitializeListHead(&NbtConfig.PendingNameQueries); #ifdef VXD InitializeListHead(&NbtConfig.DNSDirectNameQueries); #endif // initialize the spin lock CTEInitLock(&pNbtGlobConfig->SpinLock); CTEInitLock(&pNbtGlobConfig->JointLock.SpinLock); NbtConfig.LockNumber = NBTCONFIG_LOCK; NbtConfig.JointLock.LockNumber = JOINT_LOCK; NbtMemoryAllocated = 0; #if DBG for (i=0;i<MAXIMUM_PROCESSORS ;i++ ) { NbtConfig.CurrentLockNumber[i] = 0; } #endif InitializeListHead(&UsedTrackers); InitializeListHead(&UsedIrps); // create the hash tables for storing names in. status = CreateHashTable(&pNbtGlobConfig->pLocalHashTbl, pNbtGlobConfig->uNumBucketsLocal, NBT_LOCAL); if ( !NT_SUCCESS( status ) ) { ASSERTMSG("NBT:Unable to create hash tables for Netbios Names\n", (status == STATUS_SUCCESS)); return status ; } // we always have a remote hash table, but if we are a Proxy, it is // a larger table. In the Non-proxy case the remote table just caches // names resolved with the NS. In the Proxy case it also holds names // resolved for all other clients on the local broadcast area. // The node size registry parameter controls the number of remote buckets. status = InitRemoteHashTable(pNbtGlobConfig, pNbtGlobConfig->uNumBucketsRemote, pNbtGlobConfig->uNumRemoteNames); if ( !NT_SUCCESS( status ) ) return status ; // // initialize the linked lists associated with the global configuration // data structures // InitializeListHead(&NbtConfig.NodeStatusHead); InitializeListHead(&NbtConfig.DgramTrackerFreeQ); #ifndef VXD InitializeListHead(&NbtConfig.IrpFreeList); pWinsInfo = 0; { // // Setup the default disconnect timeout - 10 seconds - convert // to negative 100 Ns. // DefaultDisconnectTimeout.QuadPart = Int32x32To64(DEFAULT_DISC_TIMEOUT, MILLISEC_TO_100NS); DefaultDisconnectTimeout.QuadPart = -(DefaultDisconnectTimeout.QuadPart); } #else DefaultDisconnectTimeout = DEFAULT_DISC_TIMEOUT * 1000; // convert to milliseconds InitializeListHead(&NbtConfig.SendTimeoutHead) ; InitializeListHead(&NbtConfig.SessionBufferFreeList) ; InitializeListHead(&NbtConfig.SendContextFreeList) ; InitializeListHead(&NbtConfig.RcvContextFreeList) ; // // For session headers, since they are only four bytes and we can't // change the size of the structure, we'll covertly add enough for // a full LIST_ENTRY and treat it like a standalone LIST_ENTRY structure // when adding and removing from the list. // NbtConfig.iBufferSize[eNBT_SESSION_HDR] = sizeof(tSESSIONHDR) + sizeof( LIST_ENTRY ) - sizeof(tSESSIONHDR) ; NbtConfig.iBufferSize[eNBT_SEND_CONTEXT] = sizeof(TDI_SEND_CONTEXT); NbtConfig.iBufferSize[eNBT_RCV_CONTEXT] = sizeof(RCV_CONTEXT); NbtConfig.iCurrentNumBuff[eNBT_SESSION_HDR] = NBT_INITIAL_NUM; status = NbtInitQ( &NbtConfig.SessionBufferFreeList, NbtConfig.iBufferSize[eNBT_SESSION_HDR], NBT_INITIAL_NUM); if ( !NT_SUCCESS( status ) ) return status ; NbtConfig.iCurrentNumBuff[eNBT_SEND_CONTEXT] = NBT_INITIAL_NUM; status = NbtInitQ( &NbtConfig.SendContextFreeList, sizeof( TDI_SEND_CONTEXT ), NBT_INITIAL_NUM); if ( !NT_SUCCESS( status ) ) return status ; NbtConfig.iCurrentNumBuff[eNBT_RCV_CONTEXT] = NBT_INITIAL_NUM; status = NbtInitQ( &NbtConfig.RcvContextFreeList, sizeof( RCV_CONTEXT ), NBT_INITIAL_NUM); if ( !NT_SUCCESS( status ) ) return status ; #endif // // create trackers List // pNbtGlobConfig->iBufferSize[eNBT_DGRAM_TRACKER] = sizeof(tDGRAM_SEND_TRACKING); NbtConfig.iCurrentNumBuff[eNBT_DGRAM_TRACKER] = 0; status = NbtInitTrackerQ( &NbtConfig.DgramTrackerFreeQ,NBT_INITIAL_NUM); if ( !NT_SUCCESS( status ) ) return status ; CTEZeroMemory(&LmHostQueries,sizeof(tLMHOST_QUERIES)); InitializeListHead(&DomainNames.DomainList); InitializeListHead(&LmHostQueries.ToResolve); #ifndef VXD // set up a list for connections when we run out of resources and need to // disconnect these connections. An Irp is also needed for this list, and // it is allocated in Driver.C after we have created the connections to the // transport and therefore know our Irp Stack Size. // InitializeListHead(&NbtConfig.OutOfRsrc.ConnectionHead); // use this resources to synchronize access to the security info between // assigning security and checking it - when adding names to the // name local name table through NbtregisterName. This also insures // that the name is in the local hash table (from a previous Registration) // before the next registration is allowed to proceed and check for // the name in the table. // ExInitializeResource(&NbtConfig.Resource); // // this resource is used to synchronize access to the Dns structure // CTEZeroMemory(&DnsQueries,sizeof(tDNS_QUERIES)); InitializeListHead(&DnsQueries.ToResolve); // // this resource is used to synchronize access to the Dns structure // CTEZeroMemory(&CheckAddr,sizeof(tCHECK_ADDR)); InitializeListHead(&CheckAddr.ToResolve); #endif // VXD return status ; }
BOOLEAN INIT_FUNCTION NTAPI IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { LARGE_INTEGER ExpireTime; NTSTATUS Status; CHAR Buffer[256]; ANSI_STRING NtBootPath, RootString; /* Initialize empty NT Boot Path */ RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer)); /* Initialize the lookaside lists */ IopInitLookasideLists(); /* Initialize all locks and lists */ ExInitializeResource(&IopDatabaseResource); ExInitializeResource(&IopSecurityResource); KeInitializeGuardedMutex(&PnpNotifyListLock); InitializeListHead(&IopDiskFileSystemQueueHead); InitializeListHead(&IopCdRomFileSystemQueueHead); InitializeListHead(&IopTapeFileSystemQueueHead); InitializeListHead(&IopNetworkFileSystemQueueHead); InitializeListHead(&DriverBootReinitListHead); InitializeListHead(&DriverReinitListHead); InitializeListHead(&PnpNotifyListHead); InitializeListHead(&ShutdownListHead); InitializeListHead(&LastChanceShutdownListHead); InitializeListHead(&IopFsNotifyChangeQueueHead); InitializeListHead(&IopErrorLogListHead); KeInitializeSpinLock(&IoStatisticsLock); KeInitializeSpinLock(&DriverReinitListLock); KeInitializeSpinLock(&DriverBootReinitListLock); KeInitializeSpinLock(&ShutdownListLock); KeInitializeSpinLock(&IopLogListLock); /* Initialize Timer List Lock */ KeInitializeSpinLock(&IopTimerLock); /* Initialize Timer List */ InitializeListHead(&IopTimerQueueHead); /* Initialize the DPC/Timer which will call the other Timer Routines */ ExpireTime.QuadPart = -10000000; KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL); KeInitializeTimerEx(&IopTimer, SynchronizationTimer); KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc); /* Create Object Types */ if (!IopCreateObjectTypes()) { DPRINT1("IopCreateObjectTypes failed!\n"); return FALSE; } /* Create Object Directories */ if (!IopCreateRootDirectories()) { DPRINT1("IopCreateRootDirectories failed!\n"); return FALSE; } /* Initialize PnP manager */ IopInitializePlugPlayServices(); /* Initialize HAL Root Bus Driver */ HalInitPnpDriver(); /* Make loader block available for the whole kernel */ IopLoaderBlock = LoaderBlock; /* Load boot start drivers */ IopInitializeBootDrivers(); /* Call back drivers that asked for */ IopReinitializeBootDrivers(); /* Check if this was a ramdisk boot */ if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) { /* Initialize the ramdisk driver */ IopStartRamdisk(LoaderBlock); } /* No one should need loader block any longer */ IopLoaderBlock = NULL; /* Create ARC names for boot devices */ Status = IopCreateArcNames(LoaderBlock); if (!NT_SUCCESS(Status)) { DPRINT1("IopCreateArcNames failed: %lx\n", Status); return FALSE; } /* Mark the system boot partition */ if (!IopMarkBootPartition(LoaderBlock)) { DPRINT1("IopMarkBootPartition failed!\n"); return FALSE; } /* Initialize PnP root relations */ IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject); #ifndef _WINKD_ /* Read KDB Data */ KdbInit(); /* I/O is now setup for disk access, so phase 3 */ KdInitSystem(3, LoaderBlock); #endif /* Load services for devices found by PnP manager */ IopInitializePnpServices(IopRootDeviceNode); /* Load system start drivers */ IopInitializeSystemDrivers(); PnpSystemInit = TRUE; /* Reinitialize drivers that requested it */ IopReinitializeDrivers(); /* Convert SystemRoot from ARC to NT path */ Status = IopReassignSystemRoot(LoaderBlock, &NtBootPath); if (!NT_SUCCESS(Status)) { DPRINT1("IopReassignSystemRoot failed: %lx\n", Status); return FALSE; } /* Set the ANSI_STRING for the root path */ RootString.MaximumLength = NtSystemRoot.MaximumLength / sizeof(WCHAR); RootString.Length = 0; RootString.Buffer = ExAllocatePoolWithTag(PagedPool, RootString.MaximumLength, TAG_IO); /* Convert the path into the ANSI_STRING */ Status = RtlUnicodeStringToAnsiString(&RootString, &NtSystemRoot, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlUnicodeStringToAnsiString failed: %lx\n", Status); return FALSE; } /* Assign drive letters */ IoAssignDriveLetters(LoaderBlock, &NtBootPath, (PUCHAR)RootString.Buffer, &RootString); /* Update system root */ Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAnsiStringToUnicodeString failed: %lx\n", Status); return FALSE; } /* Load the System DLL and its Entrypoints */ Status = PsLocateSystemDll(); if (!NT_SUCCESS(Status)) { DPRINT1("PsLocateSystemDll failed: %lx\n", Status); return FALSE; } /* Return success */ return TRUE; }
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; }