我一直被問題困擾了3個星期,並且真的想要 轉移到填充文件系統代碼的「真正的移植」工作。我是 試圖模擬動態安裝請求,從用戶發佈到 內核驅動程序。所以它是關於內核端代碼的。Windows驅動程序,從內核創建/掛載一個磁盤設備
我一直在閱讀Dokan的源碼,win-btrfs 和其他一些其他類似的東西。即,創建一個新的假 磁盤設備,並以某種方式得到它具有被分配 一個驅動器號「音量」以及文件系統請求進入澆築......
我願意相信(哈),其我很接近...我儘可能簡化了 源,以幫助閱讀,並且類似地 清理了日誌,用變量名替換了十六進制地址。
我生成基於名稱的uuid,並且我在調用之前將 評論中使用的名稱。由程序生成
handle_mount_request_and_create_volume()
{
deviceCharacteristics = FILE_DEVICE_IS_MOUNTED;
deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
// First create the disk device object,
// WIN_DriverObject is the DriverEntry object
status = IoCreateDeviceSecure(WIN_DriverObject,
sizeof(myfs_mount_object_t),
// '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
&diskDeviceName,
FILE_DEVICE_DISK,
deviceCharacteristics,
FALSE,
&SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R,
NULL,
&diskDeviceObject);
myfs_mount_object_t *zmo_dcb = diskDeviceObject->DeviceExtension;
// '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
AsciiStringToUnicodeString(buf, &zmo_dcb->device_name);
// '\DosDevices\Global\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
AsciiStringToUnicodeString(buf, &zmo_dcb->symlink_name);
// '\Device\Myfs{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
AsciiStringToUnicodeString(buf, &zmo_dcb->fs_name);
diskDeviceObject->Flags |= DO_DIRECT_IO;
// Now create the filesystem device object
status = IoCreateDeviceSecure(
WIN_DriverObject,
sizeof(myfs_mount_object_t),
// '\Device\Myfs{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
&fsDeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
deviceCharacteristics,
FALSE,
&SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R,
NULL,
&fsDeviceObject);
myfs_mount_object_t *zmo_vcb = fsDeviceObject->DeviceExtension;
dprintf("WinDeviceObject : %p\n", WIN_DriverObject);
dprintf("diskDeviceObject: %p\n", diskDeviceObject);
dprintf("fsDeviceObject : %p\n", fsDeviceObject);
// '\Device\Myfs{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
AsciiStringToUnicodeString(buf, &zmo_vcb->device_name);
// '\DosDevices\Global\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
AsciiStringToUnicodeString(buf, &zmo_vcb->symlink_name);
fsDeviceObject->Flags |= DO_DIRECT_IO;
diskDeviceObject->Vpb->DeviceObject = fsDeviceObject;
diskDeviceObject->Vpb->RealDevice = fsDeviceObject;
diskDeviceObject->Vpb->Flags |= VPB_MOUNTED;
diskDeviceObject->Vpb->VolumeLabelLength = 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 symlink for userland
// '\DosDevices\Global\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
// '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
status = IoCreateSymbolicLink(&symbolicLinkTarget, &diskDeviceName);
// Mark devices as initialized
diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
fsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
// Send IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION on the
// diskDeviceObject to MountMgr
// '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
SendVolumeArrivalNotification(&diskDeviceName);
// register objects
status = IoReportDetectedDevice(
WIN_DriverObject,
InterfaceTypeUndefined,
0, 0, NULL, NULL, FALSE,
&pnpDeviceObject);
IoAttachDeviceToDeviceStack(pnpDeviceObject, diskDeviceObject);
IoRegisterDeviceInterface(
pnpDeviceObject,
&GUID_DEVINTERFACE_DISK,
NULL,
// out "\??\ROOT#MYFS#0000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"
&diskDeviceName);
IoSetDeviceInterfaceState(&diskDeviceName, TRUE);
IoRegisterDeviceInterface(
pnpDeviceObject,
&MOUNTDEV_MOUNTED_DEVICE_GUID,
NULL,
// out "\??\ROOT#MYFS#0000#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}"
&fsDeviceName);
status = IoSetDeviceInterfaceState(&Dcb->fs_name, TRUE);
// Lets call IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
status = mountmgr_add_drive_letter(mountmgrDeviceObject, &fsDeviceName);
dprintf("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
// Lets call IOCTL_MOUNTMGR_QUERY_POINTS
status = mountmgr_get_drive_letter(mountmgrDeviceObject, &diskDeviceName);
dprintf(" point %d: '%.*S' '%.*S'\n", Index,
ipoint->DeviceNameLength/sizeof(WCHAR), DeviceName,
ipoint->SymbolicLinkNameLength/sizeof(WCHAR), SymbolicLinkName);
輸出:
** Run code:
WinDeviceObject : FFFFAA81D83CC060
diskDeviceObject: FFFFAA81D260A080
fsDeviceObject : FFFFAA81D301EC40
=> SendVolumeArrivalNotification
# First requests come in, I don't really know what to do in CREATE/CLEANUP
# and CLOSE, so they mostly just return STATUS_SUCCESS
dispatcher: enter: major 0: minor 0: IRP_MJ_CREATE diskDeviceObject
IRP_MJ_CREATE: FileObject FFFFAA81D6AE8CC0 related 0000000000000000 name '(null)' flags 0x0
Setting FileObject->Vpb to FFFFAA81D559B590
dispatcher: exit: 0x0
dispatcher: enter: major 18: minor 0: IRP_MJ_CLEANUP diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 2: minor 0: IRP_MJ_CLOSE diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 0: minor 0: IRP_MJ_CREATE diskDeviceObject
IRP_MJ_CREATE: FileObject FFFFAA81D6AE8CC0 related 0000000000000000 name '(null)' flags 0x0
Setting FileObject->Vpb to FFFFAA81D559B590
dispatcher: exit: 0x0
dispatcher: enter: major 18: minor 0: IRP_MJ_CLEANUP deviceObject FFFFAA81D260A080
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
dispatcher: exit: STATUS_BUFFER_OVERFLOW
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
replying with '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
dispatcher: exit: STATUS_BUFFER_OVERFLOW
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
replying with '\DosDevices\Global\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_STABLE_GUID
dispatcher: exit: STATUS_NOT_IMPLEMENTED
# Doesn't sound like I want/need to use stable_guid, so skipping it
dispatcher: enter: major 2: minor 0: IRP_MJ_CLOSE diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 0: minor 0: IRP_MJ_CREATE diskDeviceObject
IRP_MJ_CREATE: FileObject FFFFAA81D6AE8CC0 related 0000000000000000 name '(null)' flags 0x0
Setting FileObject->Vpb to FFFFAA81D559B590
dispatcher: exit: 0x0
dispatcher: enter: major 18: minor 0: IRP_MJ_CLEANUP diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
dispatcher: exit: STATUS_NOT_IMPLEMENTED
# Similarly here, should be ok to go without, right?
dispatcher: enter: major 2: minor 0: IRP_MJ_CLOSE diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 0: minor 0: IRP_MJ_CREATE diskDeviceObject
IRP_MJ_CREATE: FileObject FFFFAA81D6AE8CC0 related 0000000000000000 name '(null)' flags 0x0
Setting FileObject->Vpb to FFFFAA81D559B590
dispatcher: exit: 0x0
dispatcher: enter: major 18: minor 0: IRP_MJ_CLEANUP diskDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_VOLUME_ONLINE
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL diskDeviceObject
IOCTL_VOLUME_POST_ONLINE
dispatcher: exit: 0x0
dispatcher: enter: major 2: minor 0: IRP_MJ_CLOSE diskDeviceObject
dispatcher: exit: 0x0
<= SendVolumeArrivalNotification
IoReportDetectedDevice success
IoAttachDeviceToDeviceStack success
# Reply to GUID_DEVINTERFACE_DISK
IoRegisterDeviceInterface success: \??\ROOT#MYFS#0000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
IoSetDeviceInterfaceState success
# Reply to MOUNTDEV_MOUNTED_DEVICE_GUID
IoRegisterDeviceInterface success: \??\ROOT#MYFS#0000#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
IoSetDeviceInterfaceState success
# IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER work
mmdlt = \Device\Myfs{0b1bb601-af0b-32e8-a1d2-54c167af6277}
dispatcher: enter: major 0: minor 0: IRP_MJ_CREATE fsDeviceObject
IRP_MJ_CREATE: FileObject FFFFAA81D2958390 related 0000000000000000 name '(null)' flags 0x0
Setting FileObject->Vpb to FFFFAA81D559B590
dispatcher: exit: 0x0
dispatcher: enter: major 18: minor 0: IRP_MJ_CLEANUP fsDeviceObject
dispatcher: exit: 0x0
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL fsDeviceObject
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
dispatcher: exit: STATUS_BUFFER_OVERFLOW
dispatcher: enter: major 14: minor 0: IRP_MJ_DEVICE_CONTROL fsDeviceObject
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
replying with '\Device\Myfs{0b1bb601-af0b-32e8-a1d2-54c167af6277}'
dispatcher: exit: 0x0
dispatcher: enter: major 2: minor 0: IRP_MJ_CLOSE fsDeviceObject
dispatcher: exit: 0x0
DriveLetterWasAssigned = 0, CurrentDriveLetter = D
# Oh, claims it has a drive letter?
IOCTL_MOUNTMGR_QUERY_POINTS return 0
point 0: '\Device\HarddiskVolume1' '\??\Volume{168821f0-0000-0000-0000-100000000000}'
point 1: '\Device\HarddiskVolume2' '\DosDevices\C:'
point 2: '\Device\HarddiskVolume2' '\??\Volume{168821f0-0000-0000-0000-501f00000000}'
point 3: '\Device\Floppy0' '\DosDevices\A:'
point 4: '\Device\Floppy0' '\??\Volume{ffc72bda-0526-11e7-ba78-806e6f6e6963}'
point 5: '' '\??\Volume{5d761629-339b-11e7-baa7-ab3bc3128e46}'
point 6: '' '\DosDevices\D:'
沒有我的代碼,我只會有0,1,2,3和4。因此,它似乎 我已創建5 6.我不知道5是什麼,Volume GUID確實 與代碼或輸出中的任何內容不匹配。 6有「D:」像上面雖然...
「D:」出現是令人鼓舞的,但應該左側 (DeviceName)真的是空的?那接下來我應該看看嗎?
或者它是對IRP_MJ_CREATE的調用嗎?我幾乎沒有任何迴應,但回覆 STATUS_SUCCESS。我沒有將Vpb分配給FileObject,但沒有任何區別。
什麼是設備5?是我的問題,是一個生成的名稱,因爲我 不正確地回答某處?
或者我錯過了一個基本的命令?
希望我的Windows開發者...