2017-05-08 4 views
0

Je suis coincé avec un problème depuis 3 semaines maintenant, et je voudrais vraiment passer au travail de "portage réel" de remplir le code du système de fichiers. Je suis essayant de simuler une demande de montage dynamique, émise depuis l'utilisateur vers le pilote du noyau . Il s'agit donc du code du noyau.Pilote Windows, créer/monter un périphérique disque à partir du noyau

J'ai lu les sources à Dokan, et win-btrfs et un tas d'autres, qui fait des choses similaires. À savoir, créer un nouveau dispositif de disque faux, et en quelque sorte obtenir d'avoir un « volume » qui obtient attribué une lettre de lecteur et les demandes de système de fichiers se déverse dans ...

Je voudrais croire (hah) que Je suis proche ... J'ai simplifié les sources autant que possible, pour aider à la lecture, et de même a nettoyé le journal, en remplaçant les adresses hexadécimales avec des noms de variables.

Je génère l'uuid basé sur le nom, et je mets le nom utilisé dans le commentaire avant l'appel.

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); 

et sortie généré par le programme:

** 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:' 

Sans mon code, je n'aurais 0, 1, 2, 3 et 4. Il semblerait j'ai créé 5 et 6. Je ne sais pas ce que 5 est, le volume GUID ne correspond à rien dans le code ou la sortie. 6 a "D:" comme ci-dessus si ...

Que "D:" apparaît est encourageant, mais le côté gauche (DeviceName) doit-il être vide? Est-ce que c'est ce que je devrais regarder ensuite?

Ou est-ce les appels à IRP_MJ_CREATE? Je ne fais pratiquement rien mais je réponds STATUS_SUCCESS. J'ai assigné Vpb à FileObject, mais cela n'a fait aucune différence.

Qu'est-ce que le périphérique 5? Est-ce mon problème, est-ce un généré un nom, parce que je a répondu incorrectement quelque part?

Ou est-ce que je manque une commande fondamentale?

moi l'espoir développeurs Windows ...

Répondre

0

En fin de compte, il devrait fonctionner, il doit être quelque chose que je l'ai fait. Ce qui est à peu près ce qu'il se passe. J'avais ramassé ces lignes quelque part; Ce qui signifiait que je supprimais l'entier de retour "size needed" pour les requêtes sondant la longueur du nom. Ce qui n'aurait pas pu être répondu par n'importe qui juste en voyant le code ici. Maintenant, je reçois une plus belle:

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

et un tas de nouvelles requêtes, y compris IRP_MJ_DIRECTORY_CONTROL, donc je peux au moins continuer. Désolé pour le bruit.