// We must NOT call without VCB lcok PDokanFCB DokanAllocateFCB( __in PDokanVCB Vcb ) { PDokanFCB fcb = ExAllocatePool(sizeof(DokanFCB)); if (fcb == NULL) { return NULL; } ASSERT(fcb != NULL); ASSERT(Vcb != NULL); RtlZeroMemory(fcb, sizeof(DokanFCB)); fcb->Identifier.Type = FCB; fcb->Identifier.Size = sizeof(DokanFCB); fcb->Vcb = Vcb; ExInitializeResourceLite(&fcb->MainResource); ExInitializeResourceLite(&fcb->PagingIoResource); ExInitializeFastMutex(&fcb->AdvancedFCBHeaderMutex); #if _WIN32_WINNT >= 0x0501 FsRtlSetupAdvancedHeader(&fcb->AdvancedFCBHeader, &fcb->AdvancedFCBHeaderMutex); #else if (DokanFsRtlTeardownPerStreamContexts) { FsRtlSetupAdvancedHeader(&fcb->AdvancedFCBHeader, &fcb->AdvancedFCBHeaderMutex); } #endif fcb->AdvancedFCBHeader.ValidDataLength.LowPart = 0xffffffff; fcb->AdvancedFCBHeader.ValidDataLength.HighPart = 0x7fffffff; fcb->AdvancedFCBHeader.Resource = &fcb->MainResource; fcb->AdvancedFCBHeader.PagingIoResource = &fcb->PagingIoResource; fcb->AdvancedFCBHeader.AllocationSize.QuadPart = 4096; fcb->AdvancedFCBHeader.FileSize.QuadPart = 4096; fcb->AdvancedFCBHeader.IsFastIoPossible = FastIoIsNotPossible; ExInitializeResourceLite(&fcb->Resource); InitializeListHead(&fcb->NextCCB); InsertTailList(&Vcb->NextFCB, &fcb->NextFCB); InterlockedIncrement(&Vcb->FcbAllocated); return fcb; }
PFCB NTAPI FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFCB ParentDcb, IN FF_FILE *FileHandle) { PFCB Fcb; /* Allocate it and zero it */ Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); RtlZeroMemory(Fcb, sizeof(FCB)); /* Set node types */ Fcb->Header.NodeTypeCode = FAT_NTC_DCB; Fcb->Header.NodeByteSize = sizeof(FCB); Fcb->Condition = FcbGood; /* Initialize resources */ Fcb->Header.Resource = &Fcb->Resource; ExInitializeResourceLite(Fcb->Header.Resource); Fcb->Header.PagingIoResource = &Fcb->PagingIoResource; ExInitializeResourceLite(Fcb->Header.PagingIoResource); /* Initialize mutexes */ Fcb->Header.FastMutex = &Fcb->HeaderMutex; ExInitializeFastMutex(&Fcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); /* Insert into parent's DCB list */ InsertHeadList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks); /* Set backlinks */ Fcb->ParentFcb = ParentDcb; Fcb->Vcb = Vcb; /* Initialize parent dcb list */ InitializeListHead(&Fcb->Dcb.ParentDcbList); /* Set FullFAT handle */ Fcb->FatHandle = FileHandle; /* Set names */ if (FileHandle) { FatSetFcbNames(IrpContext, Fcb); /* Ensure the full name is set */ FatSetFullFileNameInFcb(IrpContext, Fcb); } return Fcb; }
PFCB NTAPI FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFCB ParentDcb, IN FF_FILE *FileHandle) { PFCB Fcb; /* Allocate it and zero it */ Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); RtlZeroMemory(Fcb, sizeof(FCB)); /* Set node types */ Fcb->Header.NodeTypeCode = FAT_NTC_FCB; Fcb->Header.NodeByteSize = sizeof(FCB); Fcb->Condition = FcbGood; /* Initialize resources */ Fcb->Header.Resource = &Fcb->Resource; ExInitializeResourceLite(Fcb->Header.Resource); Fcb->Header.PagingIoResource = &Fcb->PagingIoResource; ExInitializeResourceLite(Fcb->Header.PagingIoResource); /* Initialize mutexes */ Fcb->Header.FastMutex = &Fcb->HeaderMutex; ExInitializeFastMutex(&Fcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); /* Insert into parent's DCB list */ InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks); /* Set backlinks */ Fcb->ParentFcb = ParentDcb; Fcb->Vcb = Vcb; /* Set file handle and sizes */ Fcb->Header.FileSize.LowPart = FileHandle->Filesize; Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize; Fcb->FatHandle = FileHandle; /* Initialize locks */ FsRtlInitializeFileLock(&Fcb->Fcb.Lock, NULL, NULL); FsRtlInitializeOplock(&Fcb->Fcb.Oplock); /* Set names */ FatSetFcbNames(IrpContext, Fcb); return Fcb; }
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, ULONG ExtraSize, FSP_FILE_NODE **PFileNode) { PAGED_CODE(); *PFileNode = 0; FSP_FILE_NODE_NONPAGED *NonPaged = FspAllocNonPaged(sizeof *NonPaged); if (0 == NonPaged) return STATUS_INSUFFICIENT_RESOURCES; FSP_FILE_NODE *FileNode = FspAlloc(sizeof *FileNode + ExtraSize); if (0 == FileNode) { FspFree(NonPaged); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(NonPaged, sizeof *NonPaged); ExInitializeResourceLite(&NonPaged->Resource); ExInitializeResourceLite(&NonPaged->PagingIoResource); ExInitializeFastMutex(&NonPaged->HeaderFastMutex); KeInitializeSpinLock(&NonPaged->DirInfoSpinLock); RtlZeroMemory(FileNode, sizeof *FileNode + ExtraSize); FileNode->Header.NodeTypeCode = FspFileNodeFileKind; FileNode->Header.NodeByteSize = sizeof *FileNode; FileNode->Header.IsFastIoPossible = FastIoIsNotPossible; FileNode->Header.Resource = &NonPaged->Resource; FileNode->Header.PagingIoResource = &NonPaged->PagingIoResource; FileNode->Header.ValidDataLength.QuadPart = MAXLONGLONG; /* disable ValidDataLength functionality */ FsRtlSetupAdvancedHeader(&FileNode->Header, &NonPaged->HeaderFastMutex); FileNode->NonPaged = NonPaged; FileNode->RefCount = 1; FileNode->FsvolDeviceObject = DeviceObject; FspDeviceReference(FileNode->FsvolDeviceObject); RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0); *PFileNode = FileNode; return STATUS_SUCCESS; }
NTSTATUS AFSInitRootFcb( IN ULONGLONG ProcessID, IN AFSVolumeCB *VolumeCB) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSFcb *pFcb = NULL; AFSNonPagedFcb *pNPFcb = NULL; IO_STATUS_BLOCK stIoStatus = {0,0}; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; __Enter { // // Initialize the root fcb // pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool, sizeof( AFSFcb), AFS_FCB_ALLOCATION_TAG); if( pFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRootFcb Failed to allocate the root fcb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pFcb, sizeof( AFSFcb)); pFcb->Header.NodeByteSize = sizeof( AFSFcb); pFcb->Header.NodeTypeCode = AFS_ROOT_FCB; pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSNonPagedFcb), AFS_FCB_NP_ALLOCATION_TAG); if( pNPFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitRootFcb Failed to allocate the non-paged fcb\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pNPFcb, sizeof( AFSNonPagedFcb)); pNPFcb->Size = sizeof( AFSNonPagedFcb); pNPFcb->Type = AFS_NON_PAGED_FCB; // // OK, initialize the entry // ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex); FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex); ExInitializeResourceLite( &pNPFcb->Resource); AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n", &pNPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pNPFcb->Resource, TRUE); ExInitializeResourceLite( &pNPFcb->PagingResource); ExInitializeResourceLite( &pNPFcb->CcbListLock); pFcb->Header.Resource = &pNPFcb->Resource; pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; pFcb->NPFcb = pNPFcb; // // Initialize enumeration information // KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent, NotificationEvent, FALSE); // // Save the root Fcb in the VolumeCB // VolumeCB->ObjectInformation.Fcb = pFcb; VolumeCB->ObjectInformation.VolumeCB = VolumeCB; VolumeCB->RootFcb = pFcb; pFcb->ObjectInformation = &VolumeCB->ObjectInformation; try_exit: if( !NT_SUCCESS( ntStatus)) { if( pFcb != NULL) { AFSRemoveRootFcb( pFcb); } } } return ntStatus; }
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 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; }
PNDAS_FCB ReadonlyAllocateFcb ( IN PFILESPY_DEVICE_EXTENSION DevExt, IN PUNICODE_STRING FullFileName, IN BOOLEAN IsPagingFile ) { PNDAS_FCB fcb; fcb = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(NDAS_FCB), LFS_FCB_TAG ); if (fcb == NULL) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb\n") ); return NULL; } RtlZeroMemory( fcb, sizeof(NDAS_FCB) ); fcb->NonPaged = LfsAllocateNonPagedFcb(); if (fcb->NonPaged == NULL) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->NonPaged\n") ); ExFreePool( fcb ); return NULL; } RtlZeroMemory( fcb->NonPaged, sizeof(NON_PAGED_FCB) ); #define FAT_NTC_FCB (0x0502) fcb->Header.NodeTypeCode = FAT_NTC_FCB; fcb->Header.IsFastIoPossible = FastIoIsPossible; fcb->Header.Resource = LfsAllocateResource(); fcb->Header.PagingIoResource = NULL; //fcb->Header.Resource; if (fcb->Header.Resource == NULL) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->Header.Resource\n") ); ExFreePool( fcb->NonPaged ); ExFreePool( fcb ); return NULL; } if (LfsFsRtlTeardownPerStreamContexts) { ExInitializeFastMutex( &fcb->NonPaged->AdvancedFcbHeaderMutex ); FsRtlSetupAdvancedHeader( &fcb->Header, &fcb->NonPaged->AdvancedFcbHeaderMutex ); if (IsPagingFile) { ClearFlag( fcb->Header.Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS ); } } FsRtlInitializeFileLock( &fcb->FileLock, NULL, NULL ); fcb->ReferenceCount = 1; InitializeListHead( &fcb->ListEntry ); fcb->Readonly = DevExt->LfsDeviceExt.Readonly; RtlInitEmptyUnicodeString( &fcb->FullFileName, fcb->FullFileNameBuffer, sizeof(fcb->FullFileNameBuffer) ); RtlCopyUnicodeString( &fcb->FullFileName, FullFileName ); RtlInitEmptyUnicodeString( &fcb->CaseInSensitiveFullFileName, fcb->CaseInSensitiveFullFileNameBuffer, sizeof(fcb->CaseInSensitiveFullFileNameBuffer) ); RtlDowncaseUnicodeString( &fcb->CaseInSensitiveFullFileName, &fcb->FullFileName, FALSE ); if(FullFileName->Length) if(FullFileName->Buffer[0] != L'\\') ASSERT( LFS_BUG ); return fcb; }
static NTSTATUS TestIrpHandler( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack) { NTSTATUS Status; PTEST_FCB Fcb; CACHE_UNINITIALIZE_EVENT CacheUninitEvent; PAGED_CODE(); DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction); ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP || IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_READ); Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; if (IoStack->MajorFunction == IRP_MJ_CREATE) { if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR)) { TestDeviceObject = DeviceObject; TestFileObject = IoStack->FileObject; } Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI'); RtlZeroMemory(Fcb, sizeof(*Fcb)); ExInitializeFastMutex(&Fcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) && IoStack->FileObject->FileName.Buffer[1] == 'B') { Fcb->Header.AllocationSize.QuadPart = 1000000; Fcb->Header.FileSize.QuadPart = 1000000; Fcb->Header.ValidDataLength.QuadPart = 1000000; } else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) && IoStack->FileObject->FileName.Buffer[1] == 'S') { Fcb->Header.AllocationSize.QuadPart = 3000; Fcb->Header.FileSize.QuadPart = 3000; Fcb->Header.ValidDataLength.QuadPart = 3000; } else { Fcb->Header.AllocationSize.QuadPart = 512; Fcb->Header.FileSize.QuadPart = 512; Fcb->Header.ValidDataLength.QuadPart = 512; } Fcb->Header.IsFastIoPossible = FALSE; IoStack->FileObject->FsContext = Fcb; IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; CcInitializeCacheMap(IoStack->FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize, FALSE, &Callbacks, NULL); Irp->IoStatus.Information = FILE_OPENED; Status = STATUS_SUCCESS; } else if (IoStack->MajorFunction == IRP_MJ_READ) { BOOLEAN Ret; ULONG Length; PVOID Buffer; LARGE_INTEGER Offset; Offset = IoStack->Parameters.Read.ByteOffset; Length = IoStack->Parameters.Read.Length; Fcb = IoStack->FileObject->FsContext; ok_eq_pointer(DeviceObject, TestDeviceObject); ok_eq_pointer(IoStack->FileObject, TestFileObject); if (!FlagOn(Irp->Flags, IRP_NOCACHE)) { ok(Offset.QuadPart % 512 != 0, "Offset is aligned: %I64i\n", Offset.QuadPart); ok(Length % 512 != 0, "Length is aligned: %I64i\n", Length); Buffer = MapUserBuffer(Irp); ok(Buffer != NULL, "Null pointer!\n"); _SEH2_TRY { Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer, &Irp->IoStatus); ok_bool_true(Ret, "CcCopyRead"); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Irp->IoStatus.Status = _SEH2_GetExceptionCode(); } _SEH2_END; Status = Irp->IoStatus.Status; }
VOID NTAPI FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb) { PFCB Dcb; /* Make sure it's not already created */ ASSERT(!Vcb->RootDcb); /* Allocate the DCB */ Dcb = FsRtlAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); /* Zero it */ RtlZeroMemory(Dcb, sizeof(FCB)); /* Assign it to the VCB */ Vcb->RootDcb = Dcb; /* Set its header */ Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB; Dcb->Header.NodeByteSize = sizeof(FCB); /* FCB is in a good condition */ Dcb->Condition = FcbGood; /* Initialize FCB's resource */ Dcb->Header.Resource = &Dcb->Resource; ExInitializeResourceLite(&Dcb->Resource); /* Initialize Paging Io resource*/ Dcb->Header.PagingIoResource = &Dcb->PagingIoResource; ExInitializeResourceLite(&Dcb->PagingIoResource); /* Initialize a list of parent DCBs*/ InitializeListHead(&Dcb->ParentDcbLinks); /* Set VCB */ Dcb->Vcb = Vcb; /* Initialize parent's DCB list */ InitializeListHead(&Dcb->Dcb.ParentDcbList); /* Initialize the full file name */ Dcb->FullFileName.Buffer = L"\\"; Dcb->FullFileName.Length = 1 * sizeof(WCHAR); Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR); Dcb->ShortName.Name.Ansi.Buffer = "\\"; Dcb->ShortName.Name.Ansi.Length = 1; Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR); /* Fill dirent attribute byte copy */ Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY; /* Initialize advanced FCB header fields */ ExInitializeFastMutex(&Dcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex); /* Set up first cluster field depending on FAT type */ if (TRUE/*FatIsFat32(Vcb)*/) { /* First cluster is really the first cluster of this volume */ Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster; /* Calculate size of FAT32 root dir */ Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF; //FatLookupFileAllocationSize(IrpContext, Dcb); DPRINT1("Calculation of a size of a root dir is missing!\n"); Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart; } else { #if 0 /* Add MCB entry */ FatAddMcbEntry(Vcb, &Dcb->Mcb, 0, FatRootDirectoryLbo(&Vcb->Bpb), FatRootDirectorySize(&Vcb->Bpb)); /* Set a real size of the root directory */ Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb); Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart; #endif UNIMPLEMENTED; } }
NTSTATUS DokanCreateDiskDevice( __in PDRIVER_OBJECT DriverObject, __in ULONG MountId, __in PWCHAR BaseGuid, __in PDOKAN_GLOBAL DokanGlobal, __in DEVICE_TYPE DeviceType, __in ULONG DeviceCharacteristics, __out PDokanDCB* Dcb ) { WCHAR diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR fsDeviceNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH]; PDEVICE_OBJECT diskDeviceObject; PDEVICE_OBJECT fsDeviceObject; PDokanDCB dcb; PDokanVCB vcb; UNICODE_STRING diskDeviceName; NTSTATUS status; BOOLEAN isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM); // make DeviceName and SymboliLink if (isNetworkFileSystem) { #ifdef DOKAN_NET_PROVIDER RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCopyW(fsDeviceNameBuf, 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(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCatW(fsDeviceNameBuf, 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(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_FS_DEVICE_NAME); RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_SYMBOLIC_LINK_NAME); RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); } RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf); // // make a DeviceObject for 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(" IoCreateDevice (DISK_DEVICE) failed: 0x%x\n", status); return status; } DDbgPrint("DokanDiskDevice: %wZ created\n", &diskDeviceName); // // 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->SymbolicLinkName = AllocateUnicodeString(symbolicLinkNameBuf); dcb->DiskDeviceName = AllocateUnicodeString(diskDeviceNameBuf); dcb->FileSystemDeviceName = AllocateUnicodeString(fsDeviceNameBuf); status = IoCreateDeviceSecure( DriverObject, // DriverObject sizeof(DokanVCB), // DeviceExtensionSize dcb->FileSystemDeviceName, // DeviceName DeviceType, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &sddl, // Default SDDL String NULL, // Device Class GUID &fsDeviceObject); // DeviceObject if (!NT_SUCCESS(status)) { DDbgPrint(" IoCreateDevice (FILE_SYSTEM_DEVICE) failed: 0x%x\n", status); IoDeleteDevice(diskDeviceObject); return status; } DDbgPrint("DokanFileSystemDevice: %wZ created\n", dcb->FileSystemDeviceName); vcb = fsDeviceObject->DeviceExtension; vcb->Identifier.Type = VCB; vcb->Identifier.Size = sizeof(DokanVCB); vcb->DeviceObject = fsDeviceObject; 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 // // Establish user-buffer access method. // fsDeviceObject->Flags |= DO_DIRECT_IO; if (diskDeviceObject->Vpb) { // NOTE: This can be done by IoRegisterFileSystem + IRP_MN_MOUNT_VOLUME, // however that causes BSOD inside filter manager on Vista x86 after mount // (mouse hover on file). // Probably FS_FILTER_CALLBACKS.PreAcquireForSectionSynchronization is // not correctly called in that case. diskDeviceObject->Vpb->DeviceObject = fsDeviceObject; diskDeviceObject->Vpb->RealDevice = fsDeviceObject; diskDeviceObject->Vpb->Flags |= VPB_MOUNTED; diskDeviceObject->Vpb->VolumeLabelLength = (USHORT)wcslen(VOLUME_LABEL) * sizeof(WCHAR); RtlStringCchCopyW(diskDeviceObject->Vpb->VolumeLabel, sizeof(diskDeviceObject->Vpb->VolumeLabel) / sizeof(WCHAR), VOLUME_LABEL); diskDeviceObject->Vpb->SerialNumber = 0x19831116; } ObReferenceObject(fsDeviceObject); ObReferenceObject(diskDeviceObject); // // Create a symbolic link for userapp to interact with the driver. // status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName); if (!NT_SUCCESS(status)) { if (diskDeviceObject->Vpb) { diskDeviceObject->Vpb->DeviceObject = NULL; diskDeviceObject->Vpb->RealDevice = NULL; diskDeviceObject->Vpb->Flags = 0; } IoDeleteDevice(diskDeviceObject); IoDeleteDevice(fsDeviceObject); DDbgPrint(" IoCreateSymbolicLink returned 0x%x\n", status); return status; } DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName, dcb->DiskDeviceName); // Mark devices as initialized diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; fsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; //IoRegisterFileSystem(fsDeviceObject); 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); } } //DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb); dcb->Mounted = 1; //DokanSendVolumeArrivalNotification(&deviceName); //DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb); return STATUS_SUCCESS; }