VOID DriverUnload (IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DosDeviceName; DEBUG(DL_FUN, ( "Ext2Fsd: Unloading routine.\n")); /* * stop reaper thread ... */ /* * removing memory allocations and objects */ RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME); IoDeleteSymbolicLink(&DosDeviceName); Ext2UnloadAllNls(); ExDeleteResourceLite(&Ext2Global->Resource); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2DentryLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2ExtLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2McbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2CcbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2FcbLookasideList)); ExDeleteNPagedLookasideList(&(Ext2Global->Ext2IrpContextLookasideList)); ObDereferenceObject(Ext2Global->DiskdevObject); ObDereferenceObject(Ext2Global->CdromdevObject); /* cleanup journal related caches */ UNLOAD_MODULE(journal_exit); /* cleanup linux lib */ ext2_destroy_linux(); Ext2FreePool(Ext2Global, 'LG2E'); Ext2Global = NULL; }
/* * 函数说明: * 卸载模块,清理卷实例时,会调用该模块,释放卷信息链表 * * 参数: * 无 * * 返回值: * 无 * * 备注: * 加锁 */ BOOLEAN CFileName::Unload() { BOOLEAN bRet = FALSE; LPVOLUME_NAME_INFO lpVolNameInfo = NULL; KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"begin"); __try { GetLock(); while (!IsListEmpty(&ms_ListHead)) { lpVolNameInfo = CONTAINING_RECORD(ms_ListHead.Flink, VOLUME_NAME_INFO, List); if (!lpVolNameInfo) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"CONTAINING_RECORD failed"); __leave; } RemoveEntryList(&lpVolNameInfo->List); delete lpVolNameInfo; lpVolNameInfo = NULL; } bRet = TRUE; } __finally { FreeLock(); ExDeleteResourceLite(&ms_Lock); RtlZeroMemory(&ms_Lock, sizeof(ms_Lock)); } KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"end"); return bRet; }
VOID CdUnload( __in PDRIVER_OBJECT DriverObject ) /*++ Routine Description: This routine unload routine for CDFS. Arguments: DriverObject - Supplies the driver object for CDFS. Return Value: None. --*/ { PIRP_CONTEXT IrpContext; PAGED_CODE(); UNREFERENCED_PARAMETER( DriverObject ); // // Free any IRP contexts // while (1) { IrpContext = (PIRP_CONTEXT) PopEntryList( &CdData.IrpContextList) ; if (IrpContext == NULL) { break; } CdFreePool(&IrpContext); } IoFreeWorkItem (CdData.CloseItem); ExDeleteResourceLite( &CdData.DataResource ); ObDereferenceObject (CdData.FileSystemDeviceObject); }
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive) { /* Remove the hive from the list */ ExAcquirePushLockExclusive(&CmpHiveListHeadLock); RemoveEntryList(&CmHive->HiveList); ExReleasePushLock(&CmpHiveListHeadLock); /* Delete the flusher lock */ ExDeleteResourceLite(CmHive->FlusherLock); ExFreePoolWithTag(CmHive->FlusherLock, TAG_CM); /* Delete the view lock */ ExFreePoolWithTag(CmHive->ViewLock, TAG_CM); /* Free the hive */ HvFree(&CmHive->Hive); return STATUS_SUCCESS; }
static VOID _DymArraySynchronizationFree(PUTILS_DYM_ARRAY Array) { DEBUG_ENTER_FUNCTION("Array=0x%p", Array); switch (Array->PoolType) { case PagedPool: ExDeleteResourceLite(Array->LockPaged); HeapMemoryFree(Array->LockPaged); break; case NonPagedPool: HeapMemoryFree(Array->LockNonPaged); break; default: DEBUG_ERROR("Invalid pool type of the array (%u)", Array->PoolType); KeBugCheck(0); break; } DEBUG_EXIT_FUNCTION_VOID(); return; }
VOID HandleTableDestroy(PCHANDLE_TABLE HandleTable) { DEBUG_ENTER_FUNCTION("HandleTable=0x%p", HandleTable); HashTableDestroy(HandleTable->HashTable); switch (HandleTable->HandleTableType) { case httPassiveLevel: ExDeleteResourceLite(&HandleTable->LockP); break; case httDispatchLevel: break; case httNoSynchronization: break; default: break; } HeapMemoryFree(HandleTable); DEBUG_EXIT_FUNCTION_VOID(); return; }
EXTERN_C static void LogpFinalizeBufferInfo( _In_opt_ PDEVICE_OBJECT DeviceObject, _In_ LogBufferInfo *Info) { PAGED_CODE(); NT_ASSERT(Info); // Closing the log buffer flush thread. if (Info->BufferFlushThreadHandle) { Info->BufferFlushThreadShouldBeAlive = false; auto status = ZwWaitForSingleObject(Info->BufferFlushThreadHandle, FALSE, nullptr); if (!NT_SUCCESS(status)) { DBG_BREAK(); } ZwClose(Info->BufferFlushThreadHandle); Info->BufferFlushThreadHandle = nullptr; } // Cleaning up other things. if (Info->LogFileHandle) { ZwClose(Info->LogFileHandle); Info->LogFileHandle = nullptr; } if (Info->LogBuffer2) { ExFreePoolWithTag(Info->LogBuffer2, LOGP_POOL_TAG_NAME); Info->LogBuffer2 = nullptr; } if (Info->LogBuffer1) { ExFreePoolWithTag(Info->LogBuffer1, LOGP_POOL_TAG_NAME); Info->LogBuffer1 = nullptr; } if (DeviceObject) { IoUnregisterShutdownNotification(DeviceObject); } if (Info->ResourceInitialized) { ExDeleteResourceLite(&Info->Resource); Info->ResourceInitialized = false; } }
VOID NTAPI FatUnload( #ifndef __REACTOS__ _In_ _Unreferenced_parameter_ PDRIVER_OBJECT DriverObject #else _In_ PDRIVER_OBJECT DriverObject #endif ) /*++ Routine Description: This is the unload routine for the filesystem Arguments: DriverObject - Pointer to driver object created by the system. Return Value: None --*/ { UNREFERENCED_PARAMETER( DriverObject ); ExDeleteNPagedLookasideList (&FatEResourceLookasideList); ExDeleteNPagedLookasideList (&FatNonPagedFcbLookasideList); ExDeleteNPagedLookasideList (&FatIrpContextLookasideList); ExDeleteResourceLite( &FatData.Resource ); IoFreeWorkItem (FatData.FatCloseItem); ObDereferenceObject( FatDiskFileSystemDeviceObject); ObDereferenceObject( FatCdromFileSystemDeviceObject); }
VOID NTAPI NpDeleteCcb(IN PNP_CCB Ccb, IN PLIST_ENTRY ListEntry) { PNP_ROOT_DCB_FCB RootDcbCcb; PAGED_CODE(); RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb; if (Ccb->NodeType == NPFS_NTC_CCB) { RemoveEntryList(&Ccb->CcbEntry); --Ccb->Fcb->CurrentInstances; NpDeleteEventTableEntry(&NpVcb->EventTable, Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END]); NpDeleteEventTableEntry(&NpVcb->EventTable, Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_SERVER_END]); NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]); NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND]); NpCheckForNotify(Ccb->Fcb->ParentDcb, FALSE, ListEntry); ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock); NpUninitializeSecurity(Ccb); if (Ccb->ClientSession) { ExFreePool(Ccb->ClientSession); Ccb->ClientSession = NULL; } ExFreePool(Ccb->NonPagedCcb); } else if (RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown) { ExFreePool(RootDcbCcb->Unknown); } ExFreePool(Ccb); }
VOID NcFreeEResource( _In_ PERESOURCE Lock ) /*++ Routine Description: This function frees an ERESOURCE. Arguments: Lock - Points to an ERESOURCE allocated previously via NcAllocateEResource that needs to be torn down. Return Value: Returns the status of the operation. --*/ { ExDeleteResourceLite( Lock ); ExFreePoolWithTag( Lock, NC_LOCK_TAG ); }
void AFSRemoveFcb( IN AFSFcb *Fcb) { // // Uninitialize the file lock if it is a file // AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSRemoveFcb Removing Fcb %08lX\n", Fcb); if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB) { FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock); // // The resource we allocated // ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource ); ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock); } else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB) { } // // Tear down the FM specific contexts // FsRtlTeardownPerStreamContexts( &Fcb->Header); // // Delete the resources // ExDeleteResourceLite( &Fcb->NPFcb->Resource); ExDeleteResourceLite( &Fcb->NPFcb->PagingResource); ExDeleteResourceLite( &Fcb->NPFcb->CcbListLock); // // The non paged region // AFSExFreePool( Fcb->NPFcb); // // And the Fcb itself, which includes the name // AFSExFreePool( Fcb); return; }
NTSTATUS AFSInitRDRDevice() { NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING uniDeviceName; AFSDeviceExt *pDeviceExt = NULL; UNICODE_STRING uniFsRtlRegisterUncProviderEx; FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL; RTL_OSVERSIONINFOW sysVersion; ULONG ulDeviceCharacteristics = FILE_REMOTE_DEVICE; __Enter { RtlZeroMemory( &sysVersion, sizeof( RTL_OSVERSIONINFOW)); sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW); RtlGetVersion( &sysVersion); RtlInitUnicodeString( &uniDeviceName, AFS_RDR_DEVICE_NAME); RtlInitUnicodeString( &uniFsRtlRegisterUncProviderEx, L"FsRtlRegisterUncProviderEx"); pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx); // // On 32-bit Windows XP, do not set FILE_DEVICE_SECURE_OPEN // flag as it interferes with initial access to \\afs from // limited user accounts. // if(!(sysVersion.dwMajorVersion == 5 && sysVersion.dwMinorVersion == 1)) { ulDeviceCharacteristics |= FILE_DEVICE_SECURE_OPEN; } ntStatus = IoCreateDevice( AFSDriverObject, sizeof( AFSDeviceExt), pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, ulDeviceCharacteristics, FALSE, &AFSRDRDeviceObject); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice IoCreateDevice failure %08lX\n", ntStatus)); try_return( ntStatus); } pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; RtlZeroMemory( pDeviceExt, sizeof( AFSDeviceExt)); // // Initialize resources // pDeviceExt->Specific.RDR.VolumeTree.TreeLock = &pDeviceExt->Specific.RDR.VolumeTreeLock; ExInitializeResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); pDeviceExt->Specific.RDR.VolumeTree.TreeHead = NULL; ExInitializeResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); pDeviceExt->Specific.RDR.VolumeListHead = NULL; pDeviceExt->Specific.RDR.VolumeListTail = NULL; KeInitializeEvent( &pDeviceExt->Specific.RDR.QueuedReleaseExtentEvent, NotificationEvent, TRUE); ExInitializeResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); pDeviceExt->Specific.RDR.RootCellTree.TreeLock = &pDeviceExt->Specific.RDR.RootCellTreeLock; pDeviceExt->Specific.RDR.RootCellTree.TreeHead = NULL; ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); ntStatus = AFSInitRdrFcb( &pDeviceExt->Fcb); if ( !NT_SUCCESS(ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice AFSInitRdrFcb failure %08lX\n", ntStatus)); try_return( ntStatus); } // // Clear the initializing bit // AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; // // Increase the StackSize to support the extra stack frame required // for use of IoCompletion routines. // AFSRDRDeviceObject->StackSize++; // // Register this device with MUP with FilterMgr if Vista or above // if( pFsRtlRegisterUncProviderEx) { ntStatus = pFsRtlRegisterUncProviderEx( &AFSMUPHandle, &uniDeviceName, AFSRDRDeviceObject, 0); if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", ntStatus)); } } else { ntStatus = FsRtlRegisterUncProvider( &AFSMUPHandle, &uniDeviceName, FALSE); if ( NT_SUCCESS( ntStatus)) { IoRegisterFileSystem( AFSRDRDeviceObject); } else { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", ntStatus)); } } // // Good to go, all registered and ready to start receiving requests // try_exit: if( !NT_SUCCESS( ntStatus)) { // // Delete our device and bail // ExDeleteResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); IoDeleteDevice( AFSRDRDeviceObject); AFSRDRDeviceObject = NULL; try_return( ntStatus); } } return ntStatus; }
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) /* * 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 Status; UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME); TRACE_(NTFS, "DriverEntry(%p, '%wZ')\n", DriverObject, RegistryPath); /* Initialize global data */ NtfsGlobalData = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_GLOBAL_DATA), 'GRDN'); if (!NtfsGlobalData) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ErrorEnd; } RtlZeroMemory(NtfsGlobalData, sizeof(NTFS_GLOBAL_DATA)); NtfsGlobalData->Identifier.Type = NTFS_TYPE_GLOBAL_DATA; NtfsGlobalData->Identifier.Size = sizeof(NTFS_GLOBAL_DATA); ExInitializeResourceLite(&NtfsGlobalData->Resource); /* Keep trace of Driver Object */ NtfsGlobalData->DriverObject = DriverObject; /* Initialize IRP functions array */ NtfsInitializeFunctionPointers(DriverObject); /* Initialize CC functions array */ NtfsGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = NtfsAcqLazyWrite; NtfsGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = NtfsRelLazyWrite; NtfsGlobalData->CacheMgrCallbacks.AcquireForReadAhead = NtfsAcqReadAhead; NtfsGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = NtfsRelReadAhead; /* Driver can't be unloaded */ DriverObject->DriverUnload = NULL; Status = IoCreateDevice(DriverObject, sizeof(NTFS_GLOBAL_DATA), &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &NtfsGlobalData->DeviceObject); if (!NT_SUCCESS(Status)) { WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status); goto ErrorEnd; } NtfsGlobalData->DeviceObject->Flags |= DO_DIRECT_IO; /* Register file system */ IoRegisterFileSystem(NtfsGlobalData->DeviceObject); ObReferenceObject(NtfsGlobalData->DeviceObject); ErrorEnd: if (!NT_SUCCESS(Status)) { if (NtfsGlobalData) { ExDeleteResourceLite(&NtfsGlobalData->Resource); ExFreePoolWithTag(NtfsGlobalData, 'GRDN'); } } return Status; }
VOID FatUnload( IN PDRIVER_OBJECT DriverObject ) /*++ Routine Description: This is the unload routine for the filesystem Arguments: DriverObject - Pointer to driver object created by the system. Return Value: None --*/ { #if __NDAS_FAT__ UNICODE_STRING linkString; #endif #if DBG DbgPrint( "FastFat FatUnload %s %s\n", __DATE__, __TIME__ ); #endif ExDeleteNPagedLookasideList (&FatEResourceLookasideList); ExDeleteNPagedLookasideList (&FatNonPagedFcbLookasideList); ExDeleteNPagedLookasideList (&FatIrpContextLookasideList); ExDeleteResourceLite( &FatData.Resource ); IoFreeWorkItem (FatData.FatCloseItem); ObDereferenceObject( FatDiskFileSystemDeviceObject); #if __NDAS_FAT__ if (FatCdromFileSystemDeviceObject) #endif ObDereferenceObject( FatCdromFileSystemDeviceObject); #if __NDAS_FAT__ RtlInitUnicodeString( &linkString, NDAS_FAT_CONTROL_LINK_NAME ); IoDeleteSymbolicLink( &linkString ); DebugTrace2( 0, Dbg2, ("NdasFatUnload occured NdasFatControlDeviceObject->ReferenceCount = %x\n", FatControlDeviceObject->ReferenceCount) ); IoDeleteDevice( FatControlDeviceObject ); DebugTrace2( 0, Dbg2, ("NdasFatUnload occured NdasFatFileSystemDeviceObject->ReferenceCount = %x\n", FatDiskFileSystemDeviceObject->ReferenceCount) ); IoDeleteDevice( FatDiskFileSystemDeviceObject ); if (FatCdromFileSystemDeviceObject) IoDeleteDevice( FatCdromFileSystemDeviceObject ); #endif }
NTSTATUS AFSRemoveVolume( IN AFSVolumeCB *VolumeCB) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; __Enter { // // Remove the volume from the tree and list // Don't process the list information for reserved entries // if( VolumeCB->ObjectInformation.FileId.Cell != 0) { if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE)) { AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead, &VolumeCB->TreeEntry); } if( VolumeCB->ListEntry.fLink == NULL) { pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink; if( pDeviceExt->Specific.RDR.VolumeListTail != NULL) { pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL; } } else { ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink; } if( VolumeCB->ListEntry.bLink == NULL) { pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink; if( pDeviceExt->Specific.RDR.VolumeListHead != NULL) { pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL; } } else { ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink; } } // // Remove any PIOctl objects we have // if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL) { if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL) { AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb); } AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation); AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB); } if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE)) { // // Release the fid in the service // AFSReleaseFid( &VolumeCB->ObjectInformation.FileId); } // // Free up the memory // if( VolumeCB->NonPagedVcb != NULL) { if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock)) { AFSReleaseResource( VolumeCB->VolumeLock); } ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock); ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock); AFSExFreePool( VolumeCB->NonPagedVcb); } if( VolumeCB->ObjectInformation.NonPagedInfo != NULL) { ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock); AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo); } if( VolumeCB->DirectoryCB != NULL) { if( VolumeCB->DirectoryCB->NonPaged != NULL) { ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock); AFSExFreePool( VolumeCB->DirectoryCB->NonPaged); } AFSExFreePool( VolumeCB->DirectoryCB); } AFSExFreePool( VolumeCB); } return ntStatus; }
NTSTATUS AFSInitRDRDevice() { NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING uniDeviceName; ULONG ulIndex = 0; AFSDeviceExt *pDeviceExt = NULL; AFSFileID stRootFid; UNICODE_STRING uniFsRtlRegisterUncProviderEx; FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL; __Enter { RtlInitUnicodeString( &uniDeviceName, AFS_RDR_DEVICE_NAME); RtlInitUnicodeString( &uniFsRtlRegisterUncProviderEx, L"FsRtlRegisterUncProviderEx"); pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx); ntStatus = IoCreateDevice( AFSDriverObject, sizeof( AFSDeviceExt), pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE, FALSE, &AFSRDRDeviceObject); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice IoCreateDevice failure %08lX\n", ntStatus); try_return( ntStatus); } pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; RtlZeroMemory( pDeviceExt, sizeof( AFSDeviceExt)); // // Initialize resources // pDeviceExt->Specific.RDR.VolumeTree.TreeLock = &pDeviceExt->Specific.RDR.VolumeTreeLock; ExInitializeResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); pDeviceExt->Specific.RDR.VolumeTree.TreeHead = NULL; ExInitializeResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); pDeviceExt->Specific.RDR.VolumeListHead = NULL; pDeviceExt->Specific.RDR.VolumeListTail = NULL; KeInitializeEvent( &pDeviceExt->Specific.RDR.QueuedReleaseExtentEvent, NotificationEvent, TRUE); ExInitializeResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); pDeviceExt->Specific.RDR.RootCellTree.TreeLock = &pDeviceExt->Specific.RDR.RootCellTreeLock; pDeviceExt->Specific.RDR.RootCellTree.TreeHead = NULL; ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); // // Clear the initializing bit // AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; // // Register this device with MUP with FilterMgr if Vista or above // if( pFsRtlRegisterUncProviderEx) { ntStatus = pFsRtlRegisterUncProviderEx( &AFSMUPHandle, &uniDeviceName, AFSRDRDeviceObject, 0); if ( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", ntStatus); } } else { ntStatus = FsRtlRegisterUncProvider( &AFSMUPHandle, &uniDeviceName, FALSE); if ( NT_SUCCESS( ntStatus)) { IoRegisterFileSystem( AFSRDRDeviceObject); } else { AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", ntStatus); } } if( !NT_SUCCESS( ntStatus)) { // // Delete our device and bail // ExDeleteResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); ExDeleteResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); IoDeleteDevice( AFSRDRDeviceObject); AFSRDRDeviceObject = NULL; try_return( ntStatus); } // // Good to go, all registered and ready to start receiving requests // try_exit: if( !NT_SUCCESS( ntStatus)) { } } return ntStatus; }
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; }
VOID FFSFreeFcb( IN PFFS_FCB Fcb) { PFFS_VCB Vcb; ASSERT(Fcb != NULL); ASSERT((Fcb->Identifier.Type == FFSFCB) && (Fcb->Identifier.Size == sizeof(FFS_FCB))); Vcb = Fcb->Vcb; FsRtlUninitializeFileLock(&Fcb->FileLockAnchor); ExDeleteResourceLite(&Fcb->MainResource); ExDeleteResourceLite(&Fcb->PagingIoResource); Fcb->FFSMcb->FFSFcb = NULL; if(IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) { if (Fcb->FFSMcb) { FFSDeleteMcbNode(Vcb, Fcb->FFSMcb->Parent, Fcb->FFSMcb); FFSFreeMcb(Fcb->FFSMcb); } } if (Fcb->LongName.Buffer) { ExFreePool(Fcb->LongName.Buffer); Fcb->LongName.Buffer = NULL; } #if DBG ExFreePool(Fcb->AnsiFileName.Buffer); #endif if (FS_VERSION == 1) { ExFreePool(Fcb->dinode1); } else { ExFreePool(Fcb->dinode2); } Fcb->Header.NodeTypeCode = (SHORT)0xCCCC; Fcb->Header.NodeByteSize = (SHORT)0xC0C0; if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) { ExFreePool(Fcb); } else { ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); } #if DBG ExAcquireResourceExclusiveLite( &FFSGlobal->CountResource, TRUE); FFSGlobal->FcbAllocated--; ExReleaseResourceForThreadLite( &FFSGlobal->CountResource, ExGetCurrentResourceThread()); #endif }
VOID FASTCALL CleanupUserImpl(VOID) { ExDeleteResourceLite(&UserLock); }
NTSTATUS NcAllocateEResource( _Out_ PERESOURCE * OutputLock ) /*++ Routine Description: This function allocates a new ERESOURCE. Arguments: OutputLock - On output, points to a newly allocated ERESOURCE. This value is undefined on failure. Caller is responsible for deleting this with a call to NcFreeEResource. Return Value: Returns the status of the operation. --*/ { NTSTATUS Status; PERESOURCE Lock = NULL; BOOLEAN DeleteLock = FALSE; PAGED_CODE(); Lock = ExAllocatePoolWithTag( NonPagedPool, sizeof(ERESOURCE), NC_LOCK_TAG ); if (Lock == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto NcAllocateEResourceCleanup; } Status = ExInitializeResourceLite( Lock ); if (!NT_SUCCESS( Status )) { goto NcAllocateEResourceCleanup; } Status = STATUS_SUCCESS; DeleteLock = TRUE; *OutputLock = Lock; NcAllocateEResourceCleanup: if (!NT_SUCCESS( Status )) { if (Lock) { if (DeleteLock) { ExDeleteResourceLite( Lock ); } ExFreePoolWithTag( Lock, NC_LOCK_TAG ); } } return Status; }
NTSTATUS AFSInitVolume( IN GUID *AuthGroup, IN AFSFileID *RootFid, OUT AFSVolumeCB **VolumeCB) { NTSTATUS ntStatus = STATUS_SUCCESS; IO_STATUS_BLOCK stIoStatus = {0,0}; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; AFSNonPagedVolumeCB *pNonPagedVcb = NULL; AFSVolumeCB *pVolumeCB = NULL; AFSNonPagedObjectInfoCB *pNonPagedObject = NULL; ULONGLONG ullIndex = 0; BOOLEAN bReleaseLocks = FALSE; AFSVolumeInfoCB stVolumeInformation; AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL; __Enter { // // Before grabbing any locks ask the service for the volume information // This may be a waste but we need to get this information prior to // taking any volume tree locks. Don't do this for any 'reserved' cell entries // if( RootFid->Cell != 0) { RtlZeroMemory( &stVolumeInformation, sizeof( AFSVolumeInfoCB)); ntStatus = AFSRetrieveVolumeInformation( AuthGroup, RootFid, &stVolumeInformation); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n", ntStatus); try_return( ntStatus); } // // Grab our tree locks and see if we raced with someone else // AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock, TRUE); AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock, TRUE); bReleaseLocks = TRUE; ullIndex = AFSCreateHighIndex( RootFid); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead, ullIndex, (AFSBTreeEntry **)&pVolumeCB); if( NT_SUCCESS( ntStatus) && pVolumeCB != NULL) { // // So we don't lock with an invalidation call ... // InterlockedIncrement( &pVolumeCB->VolumeReferenceCount); AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock); bReleaseLocks = FALSE; AFSAcquireExcl( pVolumeCB->VolumeLock, TRUE); InterlockedDecrement( &pVolumeCB->VolumeReferenceCount); *VolumeCB = pVolumeCB; try_return( ntStatus); } // // Revert our status from the above call back to success. // ntStatus = STATUS_SUCCESS; } // // For the global root we allocate out volume node and insert it // into the volume tree ... // pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSVolumeCB), AFS_VCB_ALLOCATION_TAG); if( pVolumeCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitVolume Failed to allocate the root volume cb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pVolumeCB, sizeof( AFSVolumeCB)); // // The non paged portion // pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSNonPagedVolumeCB), AFS_VCB_ALLOCATION_TAG); if( pNonPagedVcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitVolume Failed to allocate the root non paged volume cb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pNonPagedVcb, sizeof( AFSNonPagedVolumeCB)); ExInitializeResourceLite( &pNonPagedVcb->VolumeLock); ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock); pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSNonPagedObjectInfoCB), AFS_VCB_ALLOCATION_TAG); if( pNonPagedObject == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitVolume Failed to allocate the root non paged object cb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pNonPagedObject, sizeof( AFSNonPagedObjectInfoCB)); ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock); pVolumeCB->NonPagedVcb = pNonPagedVcb; pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject; pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock; pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock; pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock; // // Bias our reference by 1 // AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSInitVolume Initializing count (1) on volume %08lX\n", pVolumeCB); pVolumeCB->VolumeReferenceCount = 1; AFSAcquireExcl( pVolumeCB->VolumeLock, TRUE); pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool, sizeof( AFSDirectoryCB) + sizeof( WCHAR), AFS_DIR_ENTRY_TAG); if( pVolumeCB->DirectoryCB == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSNonPagedDirectoryCB), AFS_DIR_ENTRY_NP_TAG); if( pNonPagedDirEntry == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pVolumeCB->DirectoryCB, sizeof( AFSDirectoryCB) + sizeof( WCHAR)); RtlZeroMemory( pNonPagedDirEntry, sizeof( AFSNonPagedDirectoryCB)); ExInitializeResourceLite( &pNonPagedDirEntry->Lock); pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry; // // Initialize the non-paged portion of the directory entry // KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime); KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime); KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime); pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY; SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME); pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell; pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume; pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode; pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique; pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash; pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR); pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length; pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB)); RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer, L"\\", sizeof( WCHAR)); // // Copy in the volume information retrieved above // RtlCopyMemory( &pVolumeCB->VolumeInformation, &stVolumeInformation, sizeof( AFSVolumeInfoCB)); // // Setup pointers // pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation; pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB; // // Insert the volume into our volume tree. Don't insert any reserved entries // if( RootFid->Cell != 0) { pVolumeCB->TreeEntry.HashIndex = ullIndex; if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL) { pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry; SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE); } else { if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead, &pVolumeCB->TreeEntry))) { SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE); } } if( pDeviceExt->Specific.RDR.VolumeListHead == NULL) { pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB; } else { pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB; pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail; } pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB; } *VolumeCB = pVolumeCB; try_exit: if( !NT_SUCCESS( ntStatus)) { if( pNonPagedVcb != NULL) { AFSReleaseResource( pVolumeCB->VolumeLock); ExDeleteResourceLite( &pNonPagedVcb->VolumeLock); ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock); AFSExFreePool( pNonPagedVcb); } if( pNonPagedObject != NULL) { ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock); AFSExFreePool( pNonPagedObject); } if( pVolumeCB != NULL) { if( pVolumeCB->DirectoryCB != NULL) { AFSExFreePool( pVolumeCB->DirectoryCB); } AFSExFreePool( pVolumeCB); } if( pNonPagedDirEntry != NULL) { ExDeleteResourceLite( &pNonPagedDirEntry->Lock); AFSExFreePool( pNonPagedDirEntry); } } if( bReleaseLocks) { AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock); } } return ntStatus; }
VOID FFSFreeVcb( IN PFFS_VCB Vcb) { ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == FFSVCB) && (Vcb->Identifier.Size == sizeof(FFS_VCB))); FsRtlNotifyUninitializeSync(&Vcb->NotifySync); if (Vcb->StreamObj) { if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED)) { IO_STATUS_BLOCK IoStatus; CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus); ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED); } if (Vcb->StreamObj->PrivateCacheMap) FFSSyncUninitializeCacheMap(Vcb->StreamObj); ObDereferenceObject(Vcb->StreamObj); Vcb->StreamObj = NULL; } #if DBG if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0) { LONGLONG DirtyVba; LONGLONG DirtyLba; LONGLONG DirtyLength; int i; for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++) { FFSPrint((DBG_INFO, "DirtyVba = %I64xh\n", DirtyVba)); FFSPrint((DBG_INFO, "DirtyLba = %I64xh\n", DirtyLba)); FFSPrint((DBG_INFO, "DirtyLen = %I64xh\n\n", DirtyLength)); } FFSBreakPoint(); } #endif FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs)); FFSFreeMcbTree(Vcb->McbTree); if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } ExDeleteResourceLite(&Vcb->McbResource); ExDeleteResourceLite(&Vcb->PagingIoResource); ExDeleteResourceLite(&Vcb->MainResource); IoDeleteDevice(Vcb->DeviceObject); }
NTSTATUS AFSInitFcb( IN AFSDirectoryCB *DirEntry, IN OUT AFSFcb **Fcb) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; AFSFcb *pFcb = NULL; AFSNonPagedFcb *pNPFcb = NULL; IO_STATUS_BLOCK stIoSb = {0,0}; BOOLEAN bUninitFileLock = FALSE; USHORT usFcbLength = 0; ULONGLONG ullIndex = 0; AFSDirEnumEntry *pDirEnumCB = NULL; AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL; AFSVolumeCB *pVolumeCB = NULL; __Enter { pObjectInfo = DirEntry->ObjectInformation; pParentObjectInfo = pObjectInfo->ParentObjectInformation; pVolumeCB = pObjectInfo->VolumeCB; // // Allocate the Fcb and the nonpaged portion of the Fcb. // AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE_2, "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n", &DirEntry->NameInformation.FileName, pObjectInfo->FileId.Cell, pObjectInfo->FileId.Volume, pObjectInfo->FileId.Vnode, pObjectInfo->FileId.Unique); usFcbLength = sizeof( AFSFcb); pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool, usFcbLength, AFS_FCB_ALLOCATION_TAG); if( pFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitFcb Failed to allocate fcb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pFcb, usFcbLength); pFcb->Header.NodeByteSize = usFcbLength; pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSNonPagedFcb), AFS_FCB_NP_ALLOCATION_TAG); if( pNPFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitFcb Failed to allocate non-paged fcb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pNPFcb, sizeof( AFSNonPagedFcb)); pNPFcb->Size = sizeof( AFSNonPagedFcb); pNPFcb->Type = AFS_NON_PAGED_FCB; // // Initialize the advanced header // ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex); FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex); // // OK, initialize the entry // ExInitializeResourceLite( &pNPFcb->Resource); ExInitializeResourceLite( &pNPFcb->PagingResource); ExInitializeResourceLite( &pNPFcb->CcbListLock); pFcb->Header.Resource = &pNPFcb->Resource; pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; // // Grab the Fcb for processing // AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n", &pNPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pNPFcb->Resource, TRUE); pFcb->NPFcb = pNPFcb; // // Initialize some fields in the Fcb // pFcb->ObjectInformation = pObjectInfo; pObjectInfo->Fcb = pFcb; // // Set type specific information // if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY) { // // Reset the type to a directory type // pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB; // // Initialize enumeration information // KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent, NotificationEvent, FALSE); } else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE) { pFcb->Header.NodeTypeCode = AFS_FILE_FCB; // // Initialize the file specific information // FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock, NULL, NULL); bUninitFileLock = TRUE; // // Initialize the header file sizes to our dir entry information // pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart; pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart; pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart; // // Initialize the Extents resources and so forth. The // quiescent state is that no one has the extents for // IO (do the extents are not busy) and there is no // extents request outstanding (and hence the "last // one" is complete). // ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource ); KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete, NotificationEvent, TRUE ); for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++) { InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]); } pNPFcb->Specific.File.DirtyListHead = NULL; pNPFcb->Specific.File.DirtyListTail = NULL; ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock); KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent, SynchronizationEvent, TRUE); KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent, NotificationEvent, TRUE); } else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME) { pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB; } else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL) { pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB; } else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK) { pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB; } else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT) { pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB; } else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK) { pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB; } else { pFcb->Header.NodeTypeCode = AFS_INVALID_FCB; } // // And return the Fcb // *Fcb = pFcb; AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSInitFcb Initialized Fcb %08lX Name %wZ\n", pFcb, &DirEntry->NameInformation.FileName); try_exit: if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitFcb Failed to initialize fcb Status %08lX\n", ntStatus); if( pFcb != NULL) { if( bUninitFileLock) { FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock); } if( pNPFcb != NULL) { AFSReleaseResource( &pNPFcb->Resource); ExDeleteResourceLite( &pNPFcb->PagingResource); ExDeleteResourceLite( &pNPFcb->CcbListLock); ExDeleteResourceLite( &pNPFcb->Resource); } AFSExFreePool( pFcb); } if( pNPFcb != NULL) { AFSExFreePool( pNPFcb); } if( Fcb != NULL) { *Fcb = NULL; } } } return ntStatus; }
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { NTSTATUS status; // // This defines what we want to filter with FltMgr // CONST FLT_REGISTRATION filterRegistration = { sizeof( FLT_REGISTRATION ), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags NULL, // Context NULL, // Operation callbacks CdoUnload, // MiniFilterUnload CdoInstanceSetup, // InstanceSetup NULL, // InstanceQueryTeardown NULL, // InstanceTeardownStart NULL, // InstanceTeardownComplete NULL,NULL // NameProvider callbacks }; RtlZeroMemory( &Globals, sizeof( Globals ) ); #if DBG // // Initialize global debug level // CdoInitializeDebugLevel( RegistryPath ); #else UNREFERENCED_PARAMETER( RegistryPath ); #endif DebugTrace( DEBUG_TRACE_LOAD_UNLOAD, ("[Cdo]: Driver being loaded\n") ); // // Initialize the resource // ExInitializeResourceLite( &Globals.Resource ); // // Record the driver object // Globals.FilterDriverObject = DriverObject; // // Register with FltMgr to tell it our callback routines // status = FltRegisterFilter( DriverObject, &filterRegistration, &Globals.Filter ); if (!NT_SUCCESS( status )) { ExDeleteResourceLite( &Globals.Resource ); return status; } // // Now create our control device object // status = CdoCreateControlDeviceObject( DriverObject ); if (!NT_SUCCESS( status )) { FltUnregisterFilter( Globals.Filter ); ExDeleteResourceLite( &Globals.Resource ); return status; } // // Start filtering i/o // status = FltStartFiltering( Globals.Filter ); if (!NT_SUCCESS( status )) { CdoDeleteControlDeviceObject(); FltUnregisterFilter( Globals.Filter ); ExDeleteResourceLite( &Globals.Resource ); return status; } return status; }
NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *RegistryHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags) { PCMHIVE Hive; FILE_STANDARD_INFORMATION FileInformation; IO_STATUS_BLOCK IoStatusBlock; FILE_FS_SIZE_INFORMATION FileSizeInformation; NTSTATUS Status; ULONG Cluster; /* Assume failure */ *RegistryHive = NULL; /* * The following are invalid: * An external hive that is also internal. * A log hive that's not a primary hive too. * A volatile hive that's linked to permanent storage. * An in-memory initialization without hive data. * A log hive that's not linked to a correct file type. */ if (((External) && ((Primary) || (Log))) || ((Log) && !(Primary)) || ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || ((OperationType == HINIT_MEMORY) && (!HiveData)) || ((Log) && (FileType != HFILE_TYPE_LOG))) { /* Fail the request */ return STATUS_INVALID_PARAMETER; } /* Check if this is a primary hive */ if (Primary) { /* Get the cluster size */ Status = ZwQueryVolumeInformationFile(Primary, &IoStatusBlock, &FileSizeInformation, sizeof(FILE_FS_SIZE_INFORMATION), FileFsSizeInformation); if (!NT_SUCCESS(Status)) return Status; /* Make sure it's not larger then the block size */ if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) { /* Fail */ return STATUS_REGISTRY_IO_FAILED; } /* Otherwise, calculate the cluster */ Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; Cluster = max(1, Cluster); } else { /* Otherwise use cluster 1 */ Cluster = 1; } /* Allocate the hive */ Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CMHIVE); if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; /* Setup null fields */ Hive->UnloadEvent = NULL; Hive->RootKcb = NULL; Hive->Frozen = FALSE; Hive->UnloadWorkItem = NULL; Hive->GrowOnlyMode = FALSE; Hive->GrowOffset = 0; Hive->CellRemapArray = NULL; Hive->UseCountLog.Next = 0; Hive->LockHiveLog.Next = 0; Hive->FileObject = NULL; Hive->NotifyList.Flink = NULL; Hive->NotifyList.Blink = NULL; /* Set loading flag */ Hive->HiveIsLoading = TRUE; /* Set the current thread as creator */ Hive->CreatorOwner = KeGetCurrentThread(); /* Initialize lists */ InitializeListHead(&Hive->KcbConvertListHead); InitializeListHead(&Hive->KnodeConvertListHead); InitializeListHead(&Hive->TrustClassEntry); /* Allocate the view log */ Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(KGUARDED_MUTEX), TAG_CMHIVE); if (!Hive->ViewLock) { /* Cleanup allocation and fail */ ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate the flush lock */ Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), TAG_CMHIVE); if (!Hive->FlusherLock) { /* Cleanup allocations and fail */ ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_INSUFFICIENT_RESOURCES; } /* Setup the handles */ Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; Hive->FileHandles[HFILE_TYPE_LOG] = Log; Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External; /* Initailize the guarded mutex */ KeInitializeGuardedMutex(Hive->ViewLock); Hive->ViewLockOwner = NULL; /* Initialize the flush lock */ ExInitializeResourceLite(Hive->FlusherLock); /* Setup hive locks */ ExInitializePushLock(&Hive->HiveLock); Hive->HiveLockOwner = NULL; ExInitializePushLock(&Hive->WriterLock); Hive->WriterLockOwner = NULL; ExInitializePushLock(&Hive->SecurityLock); Hive->HiveSecurityLockOwner = NULL; /* Clear file names */ RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0); RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0); /* Initialize the view list */ CmpInitHiveViewList(Hive); /* Initailize the security cache */ CmpInitSecurityCache(Hive); /* Setup flags */ Hive->Flags = 0; Hive->FlushCount = 0; /* Set flags */ Hive->Flags = HiveFlags; /* Check if this is a primary */ if (Primary) { /* Check how large the file is */ ZwQueryInformationFile(Primary, &IoStatusBlock, &FileInformation, sizeof(FileInformation), FileStandardInformation); Cluster = FileInformation.EndOfFile.LowPart; } /* Initialize it */ Status = HvInitialize(&Hive->Hive, OperationType, FileType, HiveFlags, HiveData, CmpAllocate, CmpFree, CmpFileSetSize, CmpFileWrite, CmpFileRead, CmpFileFlush, Cluster, FileName); if (!NT_SUCCESS(Status)) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE); ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return Status; } /* Check if we should verify the registry */ if ((OperationType == HINIT_FILE) || (OperationType == HINIT_MEMORY) || (OperationType == HINIT_MEMORY_INPLACE) || (OperationType == HINIT_MAPFILE)) { /* Verify integrity */ ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags); if (CheckStatus != 0) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE); ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_REGISTRY_CORRUPT; } } /* Lock the hive list */ ExAcquirePushLockExclusive(&CmpHiveListHeadLock); /* Insert this hive */ InsertHeadList(&CmpHiveListHead, &Hive->HiveList); /* Release the lock */ ExReleasePushLock(&CmpHiveListHeadLock); /* Return the hive and success */ *RegistryHive = (PCMHIVE)Hive; return STATUS_SUCCESS; }
NTSTATUS FFSInitializeVcb( IN PFFS_IRP_CONTEXT IrpContext, IN PFFS_VCB Vcb, IN PFFS_SUPER_BLOCK FFSSb, IN PDEVICE_OBJECT TargetDevice, IN PDEVICE_OBJECT VolumeDevice, IN PVPB Vpb) { BOOLEAN VcbResourceInitialized = FALSE; USHORT VolumeLabelLength; ULONG IoctlSize; BOOLEAN NotifySyncInitialized = FALSE; LONGLONG DiskSize; LONGLONG PartSize; NTSTATUS Status = STATUS_UNSUCCESSFUL; UNICODE_STRING RootNode; USHORT Buffer[2]; ULONG ChangeCount; __try { if (!Vpb) { Status = STATUS_DEVICE_NOT_READY; __leave; } Buffer[0] = L'\\'; Buffer[1] = 0; RootNode.Buffer = Buffer; RootNode.MaximumLength = RootNode.Length = 2; Vcb->McbTree = FFSAllocateMcb(Vcb, &RootNode, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL); if (!Vcb->McbTree) { __leave; } #if FFS_READ_ONLY SetFlag(Vcb->Flags, VCB_READ_ONLY); #endif //READ_ONLY if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) { SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA); } if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) { SetFlag(Vcb->Flags, VCB_FLOPPY_DISK); } #if 0 if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { ClearFlag(Vcb->Flags, VCB_READ_ONLY); } else { SetFlag(Vcb->Flags, VCB_READ_ONLY); } } else #endif { SetFlag(Vcb->Flags, VCB_READ_ONLY); } ExInitializeResourceLite(&Vcb->MainResource); ExInitializeResourceLite(&Vcb->PagingIoResource); ExInitializeResourceLite(&Vcb->McbResource); VcbResourceInitialized = TRUE; Vcb->McbTree->Inode = FFS_ROOT_INO; Vcb->Vpb = Vpb; Vcb->RealDevice = Vpb->RealDevice; Vpb->DeviceObject = VolumeDevice; { UNICODE_STRING LabelName; OEM_STRING OemName; LabelName.MaximumLength = 16 * 2; LabelName.Length = 0; LabelName.Buffer = Vcb->Vpb->VolumeLabel; RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength); VolumeLabelLength = 16; while((VolumeLabelLength > 0) && ((FFSSb->fs_volname[VolumeLabelLength-1] == 0x00) || (FFSSb->fs_volname[VolumeLabelLength-1] == 0x20))) { VolumeLabelLength--; } OemName.Buffer = FFSSb->fs_volname; OemName.MaximumLength = 16; OemName.Length = VolumeLabelLength; Status = FFSOEMToUnicode(&LabelName, &OemName); if (!NT_SUCCESS(Status)) { __leave; } Vpb->VolumeLabelLength = LabelName.Length; } Vpb->SerialNumber = ((ULONG*)FFSSb->fs_id)[0] + ((ULONG*)FFSSb->fs_id)[1] + ((ULONG*)FFSSb->fs_id)[2]; Vcb->StreamObj = IoCreateStreamFileObject(NULL, Vcb->Vpb->RealDevice); if (Vcb->StreamObj) { Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject); Vcb->StreamObj->Vpb = Vcb->Vpb; Vcb->StreamObj->ReadAccess = TRUE; if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } else { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } Vcb->StreamObj->FsContext = (PVOID) Vcb; Vcb->StreamObj->FsContext2 = NULL; Vcb->StreamObj->Vpb = Vcb->Vpb; SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING); } else { __leave; } InitializeListHead(&Vcb->FcbList); InitializeListHead(&Vcb->NotifyList); FsRtlNotifyInitializeSync(&Vcb->NotifySync); NotifySyncInitialized = TRUE; Vcb->DeviceObject = VolumeDevice; Vcb->TargetDeviceObject = TargetDevice; Vcb->OpenFileHandleCount = 0; Vcb->ReferenceCount = 0; Vcb->ffs_super_block = FFSSb; Vcb->Header.NodeTypeCode = (USHORT) FFSVCB; Vcb->Header.NodeByteSize = sizeof(FFS_VCB); Vcb->Header.IsFastIoPossible = FastIoIsNotPossible; Vcb->Header.Resource = &(Vcb->MainResource); Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource); Vcb->Vpb->SerialNumber = 'PS'; DiskSize = Vcb->DiskGeometry.Cylinders.QuadPart * Vcb->DiskGeometry.TracksPerCylinder * Vcb->DiskGeometry.SectorsPerTrack * Vcb->DiskGeometry.BytesPerSector; IoctlSize = sizeof(PARTITION_INFORMATION); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &Vcb->PartitionInformation, &IoctlSize); PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart; if (!NT_SUCCESS(Status)) { Vcb->PartitionInformation.StartingOffset.QuadPart = 0; Vcb->PartitionInformation.PartitionLength.QuadPart = DiskSize; PartSize = DiskSize; Status = STATUS_SUCCESS; } IoctlSize = sizeof(ULONG); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_CHECK_VERIFY, NULL, 0, &ChangeCount, &IoctlSize); if (!NT_SUCCESS(Status)) { __leave; } Vcb->ChangeCount = ChangeCount; Vcb->Header.AllocationSize.QuadPart = Vcb->Header.FileSize.QuadPart = PartSize; Vcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff); /* Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(ffs_super_block->s_blocks_count - ffs_super_block->s_free_blocks_count) * (FFS_MIN_BLOCK << ffs_super_block->s_log_block_size); Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart; */ { CC_FILE_SIZES FileSizes; FileSizes.AllocationSize.QuadPart = FileSizes.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff); CcInitializeCacheMap(Vcb->StreamObj, &FileSizes, TRUE, &(FFSGlobal->CacheManagerNoOpCallbacks), Vcb); } #if 0 // LoadGroup XXX if (!FFSLoadGroup(Vcb)) { Status = STATUS_UNSUCCESSFUL; __leave; } #endif FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool); InitializeListHead(&(Vcb->McbList)); if (IsFlagOn(FFSGlobal->Flags, FFS_CHECKING_BITMAP)) { FFSCheckBitmapConsistency(IrpContext, Vcb); } { ULONG dwData[FFS_BLOCK_TYPES] = {NDADDR, 1, 1, 1}; ULONG dwMeta[FFS_BLOCK_TYPES] = {0, 0, 0, 0}; ULONG i; if (FS_VERSION == 1) { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } else { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 3) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 3)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } } SetFlag(Vcb->Flags, VCB_INITIALIZED); } __finally { if (!NT_SUCCESS(Status)) { if (NotifySyncInitialized) { FsRtlNotifyUninitializeSync(&Vcb->NotifySync); } if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } if (VcbResourceInitialized) { ExDeleteResourceLite(&Vcb->MainResource); ExDeleteResourceLite(&Vcb->PagingIoResource); } } } return Status; }
/* * 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; }
VOID Secondary_Dereference ( IN PSECONDARY Secondary ) { LONG result; result = InterlockedDecrement (&Secondary->ReferenceCount); ASSERT (result >= 0); if (result == 0) { PVOLUME_DEVICE_OBJECT volDo = Secondary->VolDo; #if __NDAS_FAT_DBG__ BOOLEAN acquired; acquired = SecondaryAcquireResourceExclusiveLite( NULL, &Secondary->RecoveryResource, TRUE ); if (acquired) SecondaryReleaseResourceLite( NULL, &Secondary->RecoveryResource ); else ASSERT( FALSE ); acquired = SecondaryAcquireResourceExclusiveLite( NULL, &Secondary->Resource, TRUE ); if (acquired) SecondaryReleaseResourceLite( NULL, &Secondary->Resource ); else ASSERT( FALSE ); acquired = SecondaryAcquireResourceExclusiveLite( NULL, &Secondary->CreateResource, TRUE ); if (acquired) SecondaryReleaseResourceLite( NULL, &Secondary->CreateResource ); else ASSERT( FALSE ); acquired = SecondaryAcquireResourceExclusiveLite( NULL, &Secondary->SessionResource, TRUE ); if (acquired) SecondaryReleaseResourceLite( NULL, &Secondary->SessionResource ); else ASSERT( FALSE ); #endif ASSERT( Secondary->TryCloseActive == FALSE ); if (Secondary->TryCloseWorkItem) IoFreeWorkItem( Secondary->TryCloseWorkItem ); ExDeleteResourceLite( &Secondary->RecoveryResource ); ExDeleteResourceLite( &Secondary->Resource ); ExDeleteResourceLite( &Secondary->CreateResource ); ExDeleteResourceLite( &Secondary->SessionResource ); ExFreePoolWithTag( Secondary, NDFAT_ALLOC_TAG ); DebugTrace2( 0, Dbg2, ("Secondary_Dereference: Secondary is Freed Secondary = %p\n", Secondary) ); DebugTrace2( 0, Dbg2, ("Secondary_Dereference: voldo->Reference = %d\n", volDo->ReferenceCount) ); VolDo_Dereference( volDo ); } }
NTSTATUS CdoUnload ( _In_ FLT_FILTER_UNLOAD_FLAGS Flags ) /*++ Routine Description: This is the unload routine for this filter driver. This is called when the minifilter is about to be unloaded. We can fail this unload request if this is not a mandatory unloaded indicated by the Flags parameter. Arguments: Flags - Indicating if this is a mandatory unload. Return Value: Returns the final status of this operation. --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER( Flags ); DebugTrace( DEBUG_TRACE_LOAD_UNLOAD, ("[Cdo]: Unloading driver\n") ); // // If the CDO is still referenced and the unload is not mandatry // then fail the unload // CdoAcquireResourceShared( &Globals.Resource ); if (FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_REF) && !FlagOn(Flags,FLTFL_FILTER_UNLOAD_MANDATORY)) { DebugTrace( DEBUG_TRACE_LOAD_UNLOAD | DEBUG_TRACE_ERROR, ("[Cdo]: Fail unloading driver since the unload is optional and the CDO is open\n") ); CdoReleaseResource( &Globals.Resource ); return STATUS_FLT_DO_NOT_DETACH; } // // Cleanup and unload // FltUnregisterFilter( Globals.Filter ); Globals.Filter = NULL; CdoDeleteControlDeviceObject(); CdoReleaseResource( &Globals.Resource ); ExDeleteResourceLite( &Globals.Resource ); return STATUS_SUCCESS; }
NTSTATUS DokanCreateDiskDevice(__in PDRIVER_OBJECT DriverObject, __in ULONG MountId, __in PWCHAR MountPoint, __in PWCHAR UNCName, __in PWCHAR BaseGuid, __in PDOKAN_GLOBAL DokanGlobal, __in DEVICE_TYPE DeviceType, __in ULONG DeviceCharacteristics, __in BOOLEAN UseMountManager, __out PDokanDCB *Dcb) { WCHAR diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR mountPointBuf[MAXIMUM_FILENAME_LENGTH]; PDEVICE_OBJECT diskDeviceObject; PDEVICE_OBJECT volDeviceObject; PDokanDCB dcb; PDokanVCB vcb; UNICODE_STRING diskDeviceName; NTSTATUS status; BOOLEAN isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM); DOKAN_CONTROL dokanControl; // make DeviceName and SymboliLink if (isNetworkFileSystem) { #ifdef DOKAN_NET_PROVIDER RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME); #else RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME); RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); #endif } else { RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_DISK_DEVICE_NAME); RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_SYMBOLIC_LINK_NAME); RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); } RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf); // // Create DeviceObject for the Disk Device // if (!isNetworkFileSystem) { status = IoCreateDeviceSecure(DriverObject, // DriverObject sizeof(DokanDCB), // DeviceExtensionSize &diskDeviceName, // DeviceName FILE_DEVICE_DISK, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &sddl, // Default SDDL String NULL, // Device Class GUID &diskDeviceObject); // DeviceObject } else { status = IoCreateDevice(DriverObject, // DriverObject sizeof(DokanDCB), // DeviceExtensionSize NULL, // DeviceName FILE_DEVICE_UNKNOWN, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &diskDeviceObject); // DeviceObject } if (!NT_SUCCESS(status)) { DDbgPrint(" %s failed: 0x%x\n", isNetworkFileSystem ? "IoCreateDevice(FILE_DEVICE_UNKNOWN)" : "IoCreateDeviceSecure(FILE_DEVICE_DISK)", status); return status; } // // Initialize the device extension. // dcb = diskDeviceObject->DeviceExtension; *Dcb = dcb; dcb->DeviceObject = diskDeviceObject; dcb->Global = DokanGlobal; dcb->Identifier.Type = DCB; dcb->Identifier.Size = sizeof(DokanDCB); dcb->MountId = MountId; dcb->DeviceType = FILE_DEVICE_DISK; dcb->DeviceCharacteristics = DeviceCharacteristics; KeInitializeEvent(&dcb->KillEvent, NotificationEvent, FALSE); // // Establish user-buffer access method. // diskDeviceObject->Flags |= DO_DIRECT_IO; // initialize Event and Event queue DokanInitIrpList(&dcb->PendingIrp); DokanInitIrpList(&dcb->PendingEvent); DokanInitIrpList(&dcb->NotifyEvent); KeInitializeEvent(&dcb->ReleaseEvent, NotificationEvent, FALSE); // "0" means not mounted dcb->Mounted = 0; ExInitializeResourceLite(&dcb->Resource); dcb->CacheManagerNoOpCallbacks.AcquireForLazyWrite = &DokanNoOpAcquire; dcb->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &DokanNoOpRelease; dcb->CacheManagerNoOpCallbacks.AcquireForReadAhead = &DokanNoOpAcquire; dcb->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &DokanNoOpRelease; dcb->UseMountManager = UseMountManager; if (wcscmp(MountPoint, L"") != 0) { RtlStringCchCopyW(mountPointBuf, MAXIMUM_FILENAME_LENGTH, L"\\DosDevices\\"); if (wcslen(MountPoint) < 4) { mountPointBuf[12] = towupper(MountPoint[0]); mountPointBuf[13] = L':'; mountPointBuf[14] = L'\0'; if (isNetworkFileSystem) { dcb->UseMountManager = FALSE; } } else { dcb->UseMountManager = FALSE; RtlStringCchCatW(mountPointBuf, MAXIMUM_FILENAME_LENGTH, MountPoint); } } else { RtlStringCchCopyW(mountPointBuf, MAXIMUM_FILENAME_LENGTH, L""); } dcb->DiskDeviceName = DokanAllocateUnicodeString(diskDeviceNameBuf); dcb->SymbolicLinkName = DokanAllocateUnicodeString(symbolicLinkNameBuf); dcb->MountPoint = DokanAllocateUnicodeString(mountPointBuf); if (UNCName != NULL) { dcb->UNCName = DokanAllocateUnicodeString(UNCName); } if (dcb->DiskDeviceName == NULL || dcb->SymbolicLinkName == NULL || dcb->MountPoint == NULL || (dcb->UNCName == NULL && UNCName != NULL)) { DDbgPrint(" Failed to allocate memory for device naming"); FreeDcbNames(dcb); ExDeleteResourceLite(&dcb->Resource); IoDeleteDevice(diskDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } DDbgPrint("DiskDeviceName: %wZ - SymbolicLinkName: %wZ - MountPoint: %wZ\n", dcb->DiskDeviceName, dcb->SymbolicLinkName, dcb->MountPoint); DDbgPrint(" IoCreateDevice DeviceType: %d\n", DeviceType); // Directly create volume device and init vcb here because it has strong // dependency with fs/disk // Otherwise we would have done this work when mounting the volume if (!isNetworkFileSystem) { status = IoCreateDevice(DriverObject, // DriverObject sizeof(DokanVCB), // DeviceExtensionSize NULL, // DeviceName DeviceType, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &volDeviceObject); // DeviceObject } else { status = IoCreateDeviceSecure(DriverObject, // DriverObject sizeof(DokanVCB), // DeviceExtensionSize &diskDeviceName, // DeviceName DeviceType, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &sddl, // Default SDDL String NULL, // Device Class GUID &volDeviceObject); // DeviceObject } if (!NT_SUCCESS(status)) { DDbgPrint(" IoCreateDevice failed: 0x%x\n", status); ExDeleteResourceLite(&dcb->Resource); IoDeleteDevice(diskDeviceObject); FreeDcbNames(dcb); return status; } vcb = volDeviceObject->DeviceExtension; vcb->Identifier.Type = VCB; vcb->Identifier.Size = sizeof(DokanVCB); vcb->DeviceObject = volDeviceObject; vcb->Dcb = dcb; dcb->Vcb = vcb; InitializeListHead(&vcb->NextFCB); InitializeListHead(&vcb->DirNotifyList); FsRtlNotifyInitializeSync(&vcb->NotifySync); ExInitializeFastMutex(&vcb->AdvancedFCBHeaderMutex); #if _WIN32_WINNT >= 0x0501 FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex); #else if (DokanFsRtlTeardownPerStreamContexts) { FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex); } #endif // // Create a symbolic link for userapp to interact with the driver. // status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName); if (!NT_SUCCESS(status)) { ExDeleteResourceLite(&dcb->Resource); IoDeleteDevice(diskDeviceObject); FreeDcbNames(dcb); DDbgPrint(" IoCreateSymbolicLink returned 0x%x\n", status); return status; } DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName, dcb->DiskDeviceName); // // Establish user-buffer access method. // volDeviceObject->Flags |= DO_DIRECT_IO; DokanInitVpb(diskDeviceObject->Vpb, diskDeviceObject, volDeviceObject); // Mark devices as initialized diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; volDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; ObReferenceObject(volDeviceObject); ObReferenceObject(diskDeviceObject); // DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb); // Save to the global mounted list RtlZeroMemory(&dokanControl, sizeof(dokanControl)); RtlStringCchCopyW(dokanControl.DeviceName, sizeof(dokanControl.DeviceName) / sizeof(WCHAR), diskDeviceNameBuf); RtlStringCchCopyW(dokanControl.MountPoint, sizeof(dokanControl.MountPoint) / sizeof(WCHAR), mountPointBuf); dokanControl.Type = DeviceType; dokanControl.DeviceObject = volDeviceObject; InsertMountEntry(DokanGlobal, &dokanControl); dcb->Mounted = 1; if (dcb->UseMountManager) { status = DokanSendVolumeArrivalNotification(dcb->DiskDeviceName); if (!NT_SUCCESS(status)) { DDbgPrint(" DokanSendVolumeArrivalNotification failed: 0x%x\n", status); if (diskDeviceObject->Vpb) { diskDeviceObject->Vpb->DeviceObject = NULL; diskDeviceObject->Vpb->RealDevice = NULL; diskDeviceObject->Vpb->Flags = 0; } ExDeleteResourceLite(&dcb->Resource); IoDeleteDevice(diskDeviceObject); FreeDcbNames(dcb); return status; } } DokanCreateMountPoint(dcb); if (isNetworkFileSystem) { // Run FsRtlRegisterUncProvider in System thread. HANDLE handle; PKTHREAD thread; OBJECT_ATTRIBUTES objectAttribs; InitializeObjectAttributes(&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = PsCreateSystemThread( &handle, THREAD_ALL_ACCESS, &objectAttribs, NULL, NULL, (PKSTART_ROUTINE)DokanRegisterUncProvider, dcb); if (!NT_SUCCESS(status)) { DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status); } else { ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL, KernelMode, &thread, NULL); ZwClose(handle); KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(thread); } } // DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb); return STATUS_SUCCESS; }