2017-05-08 330 views
0

我一直被問題困擾了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開發者...

回答

0

最後,它應該工作,那一定是我做的事。這幾乎是它的結果。我在某處找到了這些線條;

if (Status != STATUS_SUCCESS) 
     Irp->IoStatus.Information = 0; 

這意味着我吹掉了查詢探測名稱長度的「需要的大小」返回整數。只有在這裏看到代碼的人才能回答這個問題。現在,我能得到一個更好:

point 4: '\Device\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}' 
     '\DosDevices\D:' 

和一堆新的查詢,包括IRP_MJ_DIRECTORY_CONTROL,所以我至少可以繼續。對不起,噪音。

相關問題