Jump to content











Photo
- - - - -

Retrieving device/drive information


  • Please log in to reply
100 replies to this topic

#26 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 12 May 2015 - 05:15 PM

Seems like nice.

I will have to test it in a few different scenarios.

If I may two things, this:

 

/S:[{0 | 1 | 2 | 3 | 4 | 5}] Size units to show (optional - only one allowed):
0 auto select (set by default)
1 sizes as Bytes
2 sizes as Kilobytes
3 sizes as Megabytes
4 sizes as Gigabytes
5 sizes as Terabytes

 

makes little sense, it would be much easier to have:

 

/S:[{ B | K | M | G | T}] Size units to show (optional - only one allowed):
B sizes as Bytes
K sizes as Kilobytes
M sizes as Megabytes
G sizes as Gigabytes
T sizes as Terabytes

If the /S: is omitted or none of the allowed units is specified the program will attempt to use automatically the most suited unit.

 

Can you specify here (or somewhere else):

 

/T:[{2 | 3 | 4 | 5 | 6}] DriveType arguments (optional - only one allowed):
2 show Removable drives only
3 show fixed drives only
4 show remote (network) drives only
5 show CD/DVD-Rom drives only
6 show ramdisk drives only

 

the EXACT string that is written in DevMediaType?

Right now (quick test, using the /test swithc, nice, thank you) I have:

 

[cd0]DevModel =[ASUS DRW-2014S1T ATAPI Device]
[cd0]DevSizeTotal =0,00 KB
[cd0]DevMediaType =Not Ready
[cd0]DevPhysDisk =
[cd0]DevPath =\Device\CdRom0
[cd0]DevPartInfo =\\.\Device\CDRom0
[cd0]VolGuid =\\?\Volume{80cf88c2-8a34-11dd-813c-806d6172696f}\
[cd0]VolDrvType =CD/DVD-ROM
[cd0]VolMP =I:\

[cd1]DevModel =[KernSafe DVD-RAM MOUNTER SCSI Device]
[cd1]DevSizeTotal =
[cd1]DevMediaType =Removable (other than Floppy)
[cd1]DevPhysDisk =
[cd1]DevPath =\Device\CdRom1
[cd1]DevPartInfo =\\.\Device\CDRom1
[cd1]VolGuid =\\?\Volume{c930f56b-520e-11e4-b08b-001fc6bb76ce}\
[cd1]VolDrvType =CD/DVD-ROM
[cd1]VolMP =F:\

 

which doesn't "sound" like "right".

 

:duff:

Wonko



#27 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 12 May 2015 - 05:24 PM

Indeed, for the DiskSize I use the IOCTL_DISK_GET_DRIVE_GEOMETRY control code for DeviceIOControl.

 

Structure:

 Private Type DISK_GEOMETRY
    Cylinders         As LARGE_INTEGER
    'Cylinders         As Currency  'LARGE_INTEGER (8 bytes)
    MediaType         As Long
    TracksPerCylinder As Long
    SectorsPerTrack   As Long
    BytesPerSector    As Long
  End Type

 

whereas Cylinders refer to the LARGE_INTEGER structure

Private Type LARGE_INTEGER
    lowpart As Long
    highpart As Long
End Type
 

The Volume Disk spaces are retrieved by the GetDiskFreeSpaceEx-API that also uses the LARGE_INTEGER structure to get sizes in byte.

 

I cross-checked all results on my systems - the exactly showed the same sizes as in the disk management console. That's all I could do so far. Maybe I should try to use currency declarations.? Will have a look at that - thanks for input.

 

What screen are you looking at in the disk management console?

I can only see a size in Mbytes which is not accurate enough.

 

The issue is not with the variables but the api's you use I believe.



#28 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 12 May 2015 - 05:44 PM

erwan.l,

maybe I'm using wrong terms?

I meant compmgmt.msc - disk management snap-in.

I see sizes in TB / GB  or MB for volumes or the whole drive. Same goes by right clicking a drive in explorer and chosing the properties. Sizes shown here are exactly the same as in my program (if using the same unit).

Edit: My experience tells me that the issue may not the API in main, but the formatting functions you use when dealing with 32bit or 64bit variable values.

 

Wonko,

Will change switch and help - thanks.

Regarding the /TEST switch. Yes, something went wrong :-).

Will correct this.

 

DrvType uses the GetDriveType API.

Well documented here: https://msdn.microso...9(v=vs.85).aspx

Enumeration:

  Public Enum DRIVE_TYPES
    DRIVE_UNKNOWN = 0         ' The drive type cannot be determined.
    DRIVE_NO_ROOT_DIR = 1     ' The root directory does not exist. E.g. there is no volume mounted at the specified path.
    DRIVE_REMOVABLE = 2 ' The disk can be removed from the drive. E.g. a floppy drive, thumb drive, or flash card reader.
    DRIVE_FIXED = 3             ' The disk cannot be removed from the drive. E.g. a hard disk drive or SSD drive.
    DRIVE_REMOTE = 4        ' The drive is a remote (network) drive.
    DRIVE_CDROM = 5          ' The drive is a CD-ROM drive.
    DRIVE_RAMDISK = 6        ' The drive is a RAM disk.
  End Enum
 

String-Output in zDInfo:

  Private Const DRIVE_TYPES_TEXT = _
    "Unknown|RootDir does not exist|Removable|Fixed|Remote (network)|CD/DVD-ROM|Ramdrive"

 

DevMediaType is part of an enum needed for DeviceIOControl.

Public Enum DISK_GEOMETRY_MEDIA_TYPES
    Unknown = 0
    F5_1Pt2_512 = 1
    F3_1Pt44_512 = 2
    F3_2Pt88_512 = 3
    F3_20Pt8_512 = 4
    F3_720_512 = 5
    F5_360_512 = 6
    F5_320_512 = 7
    F5_320_1024 = 8
    F5_180_512 = 9
    F5_160_512 = 10
    Removable = 11
    FixedMedia = 12
    F3_120M_512 = 13
    F3_640_512 = 14
    F5_640_512 = 15
    F5_720_512 = 16
    F3_1Pt2_512 = 17
    F3_1Pt23_1024 = 18
    F5_1Pt23_1024 = 19
    F3_128Mb_512 = 20
    F3_230Mb_512 = 21
    F8_256_128 = 22
    F3_200Mb_512 = 23
    F3_240M_512 = 24
    F3_32M_512 = 25
    DeviceNotReady = 26 ' added by me
  End Enum

 

Strings used in ZDInfo:

 Private Const DISK_GEOMETRY_MEDIA_TYPES_TXT = "Unknown Format" & _
    "|5.25 Floppy, 1.2MB, 512 bytes/sector|3.5 Floppy, 1.44MB, 512 bytes/sector|3.5 Floppy, 2.88MB, 512 bytes/sector" & _
    "|3.5 Floppy, 20.8MB, 512 bytes/sector|3.5 Floppy, 720KB, 512 bytes/sector|5.25 Floppy, 360KB, 512 bytes/sector" & _
    "|5.25 Floppy, 320KB, 512 bytes/sector|5.25 Floppy, 320KB, 1024 bytes/sector|5.25 Floppy, 180KB, 512 bytes/sector" & _
    "|5.25 Floppy, 160KB, 512 bytes/sector|Removable (other than Floppy)|Fixed (Hard Disk)" & _
    "|3.5 Floppy, 120MB, 512 bytes/sector|3.5 Floppy, 640KB, 512 bytes/sector|5.25 Floppy, 640KB, 512 bytes/sector" & _
    "|5.25 Floppy, 720KB, 512 bytes/sector|3.5 Floppy, 1.2MB, 512 bytes/sector|3.5 Floppy, 1.23MB, 1024 bytes/sector" & _
    "|5.25 Floppy, 1.23MB, 1024 bytes/sector|3.5 Floppy, 128MB, 512 bytes/sector|3.5 Floppy, 230MB, 512 bytes/sector" & _
    "|8 Floppy, 256KB, 128 bytes/sector|3.5 Floppy, 200MB, 512 bytes/sector (HiFD)|3.5 Floppy, 240MB, 512 bytes/sector (HiFD)" & _
    "|3.5 Floppy, 32MB, 512 bytes/sector|Not Ready"
 



#29 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 12 May 2015 - 06:05 PM

erwan.l,

maybe I'm using wrong terms?

I meant compmgmt.msc - disk management snap-in.

I see sizes in TB / GB  or MB for volumes or the whole drive. Same goes by right clicking a drive in explorer and chosing the properties. Sizes shown here are exactly the same as in my program (if using the same unit).

Edit: My experience tells me that the issue may not the API in main, but the formatting functions you use when dealing with 32bit or 64bit variable values.

 

 

 

32/64 bits wont change the value here : you are off a few mbytes, not maxing to 2 147 483 647 bytes.

IOCTL_DISK_GET_DRIVE_GEOMETRY is giving you erroneous results.

Same goes with getdiskfreespace.

 

Compare it to other tools out there and you'll see.

 

Example : compare the partition size you have in the MBR to the size you get with getdiskfreespace or even the totalsec field in the bootsector.

And you'll see that getdiskfreespace is incorrect.

 

Same goes with your disk size.

If you were to use that size to clone your disk for instance, you would get an incomplete disk image.



#30 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 12 May 2015 - 06:19 PM

Okay, you're one of the dev experts here.

Certainly I believe in what you said.

I don't have the knowledge (cause dealing with disk layouts and geometries is not my "favourite" buseness) to critically appraise your statements.

Therefore, what do you suggest?

Which API usable in VB6 is in your mind?

BTW, what about the view in explorer and diskmanagement snap-in?

Are the results here are same for you as for me?



#31 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 12 May 2015 - 06:23 PM

Okay, you're one of the dev experts here.

Certainly I believe in what you said.

I don't have the knowledge (cause dealing with disk layouts and geometries is not my "favourite" buseness) to critically appraise your statements.

Therefore, what do you suggest?

Which API usable in VB6 is in your mind?

BTW, what about the view in explorer and diskmanagement snap-in?

Are the results here are same for you as for me?

 

Did not mean to make my statement as criticism : sorry about that :)

We are all experts over here!

 

Drop IOCTL_DISK_GET_LENGTH_INFO/getdiskfreespace and go for IOCTL_DISK_GET_LENGTH_INFO/IOCTL_DISK_GET_PARTITION_INFO.

 

Then you'll get the "true" partition/disk size.

 

As you stated already, explorer/disk management gives you a "view".



#32 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 12 May 2015 - 06:40 PM

Hm, did I imply of beeing criticised? If so I've to say sorry. Everything is well here.

Anyway there's nothing with. I like expedient and constructive-minded critics.

 

Thanks for your suggestions, that helps much. Will hunt these API's.

BTW: I am not an expert in these terms and will never be.

My intent was to retrieve reliable device information only,

strictly following the features and limitations of windows API's.



#33 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 13 May 2015 - 12:04 PM

Only to confirm the size issue and providing a possible explanation :unsure:, which API is to be used to find the exact size is another thing, but a similar behaviour can be observed in Tiny Hexer as well.:

 

USB stick (partitioned but "Removable")

In ZDinfo.exe /test /S:1
[hd2,1]DevModel =[TDK LoR TF10 USB Device]
[hd2,1]DevSizeTotal =7739988480 Bytes
[hd2,1]DevMediaType =Removable (other than Floppy)
[hd2,1]DevPhysDisk =\\.\PHYSICALDRIVE2
[hd2,1]DevPath =\Device\Harddisk2\DP(1)0-0+23
[hd2,1]DevPartInfo =\\.\Device\Harddisk2\Partition1
[hd2,1]VolGuid =\\?\Volume{4ae75ea9-cbde-11e4-b099-001fc6bb76ce}\
[hd2,1]VolDrvType =Removable
[hd2,1]VolMP =E:\


In Tiny Hexer:
PhysicalDrive2 0xE6C000 Sectors
PhysicalDrive2 (partition1) 0xFFFF Sectors
\\.\E: 0xE6AB6D Sectors

The partition is manually created with offset 63 sectors and size 65535 (0xFFFF) sectors.

The (wrong) size of 7739988480/512=15117165 sectors (0xE6AB6D) seems like an "artifact" of the OS, as 0xE6C000-0xE6AB6D=0x1493=5267
What probably happens is that it is somehow used the nx255x63 geometry and somehow, since the device is removable, the volume seems like extending beyond the actual partition entry :unsure:.
941x255x63=15117165
0xE6C000=15122432/255/63=941,32785...

 

On a hard disk:

 

In ZDinfo.exe /test /S:1

[hd1,1]DevModel =[MAXTOR STM3320820AS ATA Device]
[hd1,1]DevSizeTotal =320070320640 Bytes
[hd1,1]DevMediaType =Fixed (Hard Disk)
[hd1,1]DevPhysDisk =\\.\PHYSICALDRIVE1
[hd1,1]DevPath =\Device\HarddiskVolume2
[hd1,1]DevPartInfo =\\.\Device\Harddisk1\Partition1
[hd1,1]VolGuid =\\?\Volume{b0b284c4-8a33-11dd-8781-806d6172696f}\
[hd1,1]VolDrvType =Fixed
[hd1,1]VolMP =D:\

 

 

In Tiny Hexer:
PhysicalDrive1 0x2542EAB0 Sectors
\\.\D: (PhysicalDrive1partition1) 0x2542971C Sectors

0x2542EAB0=625142448x512=320072933376

0x2542971C=625121052x512=320061978624

The partition has 63 sectors before and extends for 625121217, it respects cylinder/head boundary 63+625121217=625121280=38912*255*63

When you open the object \\.\D: (PhysicalDrive1partition1) it actually opens correctly on sector 0/625121217, so the 625121052 is a "false"  value, though in this case I seem to not being able to find a connection with HS geometry. :dubbio:. while the "false" size from zdinfo is related to it:

320070320640/512=625137345=38913*255*63

 

:duff:

Wonko



#34 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 13 May 2015 - 12:16 PM

For partition side, zdinfo uses getdiskfreespace (lpSectorsPerCluster * lpBytesPerSector * lpTotalNumberOfClusters to get the partition size).

 

For disk size, zdinfo uses IOCTL_DISK_GET_DRIVE_GEOMETRY (C*H*S*size of sectors to get the disk size).



#35 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 13 May 2015 - 12:17 PM

For partition size, zdinfo uses getdiskfreespace (lpSectorsPerCluster * lpBytesPerSector * lpTotalNumberOfClusters to get the partition size).

 

For disk size, zdinfo uses IOCTL_DISK_GET_DRIVE_GEOMETRY (C*H*S*size of sectors to get the disk size).

 

Both proved to report wrong values to me in the past when implementing these in CloneDisk.

You can not trust these values when cloning partitions/disks.



#36 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 13 May 2015 - 01:36 PM

Good :), so now it is clear why this happens, and needs to be changed, because besides the "rounding" (to either CHS or cluster number) there would likely be an issue with the (admittedly "rare") case in which a partitioned device has an actual valid partition table but it has been not formatted (or maybe formatted with an unknown filesystem) and - possibly - some similar issue with extended partitions and logical volumes :unsure:

 

@zharif

These (or very similar) issues were talked about here as a "side topic", JFYI:

http://reboot.pro/to...ated-with-dsfo/

http://www.911cd.net...ic=24353&st=240

 

:duff:

Wonko



#37 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 13 May 2015 - 03:27 PM

erwan.l,

 

I got DISK_GET_LENGTH_INFO working.

But the most annoying thing is, that it seems to need elevated rights cause of GENERIC_READ access in CreateFile.

All the other listing I had so far doesn't need this cause I could set this value to "0&".

If I implement this function (which seems really to be important - shown by you and Wonko), I MUST elevate the command prompt window just at the beginning. And this just for showing size units correctly.

Maybe the regular output should stay as it is (without displaying sizes).

If the user decides to use a "Size"-Switch my proggy would elevate itself.???

Any suggestions?

 

Edit:

What do you think about this approach;

https://harryjohnsto...n-floppy-disks/ ?

Scroll down to the end to read his comments.

He suggests using the IOCTL control code above in cases when DiskGetDriveGeometry outputs HardDisk

drives or removable drives other than floppies.

As far as I understood, you do not second this?



#38 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 13 May 2015 - 03:59 PM

Well, running XP, the issue shouldn't bother me, it sounds "strange" that even for having the size of a device one needs to be elevated, but again a lot of things in Windows, particularly on latish versions and with UAC are "strange".

We could use the current "as is" limiting it to Gb and Mb (the difference wouldn't be that much noticeable and there is enough mish-mash between real Megabytes and Gigabytes (Mib and Gib) and stupid decimal Megabytes and Gigabytes (Mb and Gb) that noone will ever notice, while this approximated size could be useful to quickly distinguish a large device (say a hard disk) from a small one (say a USB stick).

This exact value is otherwise not really-really needed for anything else but cloning/imaging disks/partitions (or similar) which is not the "main scope" of the tool, and if someone needs/wants an "exact" size in Bytes (I personally don't think Kb will ever be of use to anyone :unsure: ) and in this case the tool could ask for elevation.

You could have just the default "automatic" (without any switch) that auto-toggles between Gb and Mb (the Tb doesn't really make much sense, what is the most you can have now, 5 Tb?) and make the /S switch become (say) /SE or /SB providing the Size Exactly (in Bytes), while another unit of measure that might IMHO be of use is "number of sectors" (but this would need an additional line of info "sector size" :ph34r: since nowadays a number of disks come in 4 Kb sized sectors).

I would be more preoccupied :unsure: by the issue with partitioned Removable devices where instead of the size of the partition/volume, the size of the whole device is shown.

:duff:
Wonko

#39 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 13 May 2015 - 05:51 PM

erwan.l,

 

I got DISK_GET_LENGTH_INFO working.

But the most annoying thing is, that it seems to need elevated rights cause of GENERIC_READ access in CreateFile.

All the other listing I had so far doesn't need this cause I could set this value to "0&".

If I implement this function (which seems really to be important - shown by you and Wonko), I MUST elevate the command prompt window just at the beginning. And this just for showing size units correctly.

Maybe the regular output should stay as it is (without displaying sizes).

If the user decides to use a "Size"-Switch my proggy would elevate itself.???

Any suggestions?

 

 

 

About the admin rights, I dont recall having this issue.

I'll look into my code.

 

I vaguely recall that there are several possible syntax around "physicaldriveX" which can be the trick.

 

One extra detail to stay away from getdiskfreespace as much as possible : this is userland.

If your system has quotas or specific NTFS permissions, getdiskfreespace will be impacted by this and again you will return an incorrect partition size.

 

EDIT : below my createfile parameters.

EDIT2 : it actually makes sense from a security p.o.v tha one cannot access (even in read mode) the physicaldrive as otherwise one could bypass the file system security...

//src='\\.\PhysicalDriveX'
hDevice_src := CreateFile(pchar(src ), GENERIC_READ ,file_share_read or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);


#40 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 13 May 2015 - 07:41 PM

Thanks for posting your syntax. This is the one I successfully tried to avoid.

hDevice = CreateFileW(StrPtr(sDev), 0&, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&)

EDIT: This syntax works for DiskFreeSpaceEx, the StorageDeviceDescriptor, GetDriveGeometry and the StorageGetDeviceNumber IOCTL to bypass admin privilges in a commandline window - but not for the DiskGetLengthInfo. But I will investigate further.

Thanks so far.



#41 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 14 May 2015 - 08:10 AM

EDIT2 : it actually makes sense from a security p.o.v tha one cannot access the physicaldrive as otherwise one could bypass the file system security...

Actually it makes not much sense to remove READ ONLY access (querying the size of the device or of structures in it should not be a "write" operation) to the PhysicalDrive.

 

I am still convinced however that there must be a way to access these info without elevation.

The issue with UAC (lack of ) efficiency as an increased security solution is IMHO that it is triggered by "too many things", once you have been prompted to elevate n times, the nth+1 time you will click OK even when you really shouldn't :ph34r: or get fed up with it and disable it altogether.

Not completely unlike triggering on purpose a burglar alarm several times will induce the owner to believe that it has an issue and that in order to sleep the only thing to do is to switch it off ;).

 

:duff:

Wonko



#42 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 14 May 2015 - 08:20 AM

I absolutely second your opinion Wonko.

Will try to hunt/discover other API's before posting a new version.



#43 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 14 May 2015 - 11:41 AM

I absolutely second your opinion Wonko.

Will try to hunt/discover other API's before posting a new version.

 

While looking for other api's, keep in mind that imdisk drives dont show up in zdinfo.

Not sure if you want to support these, but if so, it might influence your choice while choosing windows api's.

 

My R: drive below does not show up in zdinfo (i mean it does but with empty values).

Note that this partition does not have a device number nor a volume GUID which probably confuses zdinfo.

 

cq9Fgot.png

DevModel       =[Unknown Device]
DevSizeTotal   =0,00 KB
DevMediaType   =Unknown Format
DevPhysDisk    =
DevPath        =\Device\ImDisk0
DevPartInfo    =
VolGuid        =
VolDrvType     =Fixed
VolMP          =R:\


#44 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13748 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 15 May 2015 - 10:05 AM

 

While looking for other api's, keep in mind that imdisk drives dont show up in zdinfo.

 

 

Well, this is IMHO "normal", as IMDISK "bypasses" (or "is transparent") to the NT mount manager, i.e. the volume is not seen in MountVol nor in disk management:

http://reboot.pro/to...win-2k/?p=28992

so I find it already a very good thing that zdinfo can see it (with only partial or "default" data).

 

:duff:

Wonko



#45 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 15 May 2015 - 10:35 AM

Well, this is IMHO "normal", as IMDISK "bypasses" (or "is transparent") to the NT mount manager, i.e. the volume is not seen in MountVol nor in disk management:

http://reboot.pro/to...win-2k/?p=28992

so I find it already a very good thing that zdinfo can see it (with only partial or "default" data).

 

:duff:

Wonko

 

Yes indeed this was my point : there are several way to enumerate "drives" (generic terms).

By listing volumes, listing (dos)devices, (ab)using the createfile against physicaldriveX (increasing x) or logical drive (increasing) letter, etc.

Some methods will miss some drives.

 

Then, when you "detect" a drive, there again several ways to retrieve details (size, etc).

 

What makes it even more complex (as spot by Zharif), one is also limited by the admin rights.

 

Not quiet easy but zdinfo is definitely doing a nice job : I very much enjoy the console output and ability to use in a script.

 

One extra suggestion : if you use iotcl_disk_get_drive_layout, you could also retrieve some extra informations such as RAW/MBR/GPT and number of disk partitions.

I dont know if this one requires admin rights thus : depends on MS interpretation of security.



#46 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 16 May 2015 - 05:57 PM

Erwan.l,

you're right. ZDInfo was indeed "confused" because it translates any drive letter to a GUID.

If translation led to an empty value (no GUID), it retrieves partial or no info. I didn't thought about virtual drives without Guid or PhysDrv entry. Must change the validation routine.

 

Some research results:

GetDriveLayout and PartitionInfo both support DrvLetters, GUIDs or PhysDrive pathes.

GetDriveLayout and PartitionInfo both need GENERIC_READ access for CreateFile.

GetDriveLayout and PartitionInfo both say "Goodby" if input is a non-MBR drive (this is per API-design - error: invalid function).

GetDriveLayout and PartitionInfo both are able to check all partitions through PartitionEntriesArray, but unmounted/hidden partitions are not discovered.

BTW erwan.l, I couln't see how GetDriveLayout could retrieve the extra info you stated.

What does e.g. clonedisk show, if a device with a gpt partition table was selected?

 

After "endless" hours I got GetDriveLayoutEx, PartitionInfoEx and DriveGeometryEx working.

These do not need GENERIC_READ access for CreateFile!

GetDriveLayoutEx, PartitionInfoEx work on GPT drives too and recieve the additional info MBR/GPT/RAW PartitionStyle etc.

But these functions are not well documented and a really, really difficult to implement as code (through unioned structure builds). Additionally I had to change the syntax of the DeviceIOControl API. Partially I still get some glibberish or simply unusable output. However the main interesting values are working so far.

As said before, handle setting as well as IOCTL-calls depend on the input value.

At least somebody has to try DrvLetters, Guids, PhysDrv and sometimes DevPathes.

Kind of Output and/or failure depends on these input pathes.



#47 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 16 May 2015 - 06:27 PM

What does e.g. clonedisk show, if a device with a gpt partition table was selected?

 

 

Actually you answered the question already : I use IOCTL_DISK_GEt_DRIVE_LAYOUT_EX.

 

With this, I can handle it all (mbr, gpt, raw).

 

Actually over the years  I had to adapt CloneDisk to finally end up with this IOCLT which gives me the best result.

But indeed, the structure used is not easy to start with when you are not using plain C (I use delphi, you use VB).

 

With this IOCTL (get/set), I was able to put a simple partition editor.

1LDhg3Q.png

 

Your feedback this is very instructive :

-I did not know one could do wtihout the generic_read flag (i have to try it in CloneDisk)

-I did not know one could input different syntax (other than physicaldriveX)

 

Thanks for sharing !



#48 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 16 May 2015 - 06:44 PM

EDIT: Thanks, I hope I will get DiskGetDriveLayoutEx fully working.

I think you should keep in mind, that if looping though all PhysDrive numbers DiskGetDriveLayoutEx will not show unmounted/hidden volumes (this goes for my preliminary tests).

But If you know the GUID of the unmounted/hidden volume - pass it to DiskGetDriveLayoutEx (or better to DiskPartitionInfoEx) and you could add it to your partition editor.



#49 erwan.l

erwan.l

    Gold Member

  • Developer
  • 1986 posts
  • Location:Nantes - France
  •  
    France

Posted 16 May 2015 - 07:15 PM

EDIT: Thanks, I hope I will get DiskGetDriveLayoutEx fully working.

I think you should keep in mind, that if looping though all PhysDrive numbers DiskGetDriveLayoutEx will not show unmounted/hidden volumes (this goes for my preliminary tests).

But If you know the GUID of the unmounted/hidden volume - pass it to DiskGetDriveLayoutEx (or better to DiskPartitionInfoEx) and you could add it to your partition editor.

 

I did not experience that (miss hidden/unmounted volumes) while looping thru physicadrives.

But I am using generic_read and run as admin : that could be explain why.

 

my disk_layout_ex structure (it may help you)



    type
    TDriveLayoutInformation_Ex2 = record
    PartitionStyle: DWORD;
    PartitionCount: DWORD;
    Union: record
      case Integer of
        0: (Mbr: DRIVE_LAYOUT_INFORMATION_MBR);
        1: (Gpt: DRIVE_LAYOUT_INFORMATION_GPT);
    end;
    PartitionEntry: array [0..31] of PARTITION_INFORMATION_EX;
    end;


#50 Zharif

Zharif

    Frequent Member

  • .script developer
  • 152 posts
  • Location:Germany
  •  
    Germany

Posted 16 May 2015 - 07:31 PM

Thank you,

mine is looking similar, like this:

  Private Enum PARTITION_STYLE
    PARTITION_STYLE_MBR = 0
    PARTITION_STYLE_GPT = 1
    PARTITION_STYLE_RAW = 2
  End Enum

 Private Type DRIVE_LAYOUT_INFORMATION_MBR
    Signature As Long
  End Type

  Private Type DRIVE_LAYOUT_INFORMATION_GPT
    DiskId                As Long
    StartingUsableOffset  As LARGE_INTEGER
    UsableLength          As LARGE_INTEGER
    MaxPartitionCount     As Long
  End Type
 
  Private Type PARTITION_INFORMATION_MBR
    PartitionType       As DISK_PARTITION_TYPES 
    BootIndicator       As Boolean              
    RecognizedPartition As Boolean        
    HiddenSectors       As Long           
  End Type
 
  Private Type PARTITION_INFORMATION_GPT
    PartitionType   As DISK_PARTITION_TYPES
    PartitionId     As Long
    ATTRIBUTES      As LARGE_INTEGER ' DWORD64
    Name            As String * 36
  End Type

  Private Type PARTITION_INFORMATION_EX
    PartitionStyle    As PARTITION_STYLE
    StartingOffset    As LARGE_INTEGER
    PartitionLength   As LARGE_INTEGER
    PartitionNumber   As Long
    RewritePartition  As Boolean
    MbrFix            As PARTITION_INFORMATION_MBR
    GptFix            As PARTITION_INFORMATION_GPT
'    Mbr               As DRIVE_LAYOUT_INFORMATION_MBR
'    Gpt               As DRIVE_LAYOUT_INFORMATION_GPT
  End Type
    
  Private Type DRIVE_LAYOUT_INFORMATION_EX
    PartitionStyle      As PARTITION_STYLE
    PartitionCount      As Long
    Mbr                 As DRIVE_LAYOUT_INFORMATION_MBR
    Gpt                 As DRIVE_LAYOUT_INFORMATION_GPT
'    Mbr                 As PARTITION_INFORMATION_MBR
'    Gpt                 As PARTITION_INFORMATION_GPT
    PartitionEntry(31)  As PARTITION_INFORMATION_EX
  End Type

I do have problems for the PARTITION_INFORMATION_GPT-Type.

Don't know how to acces these types documented here: https://msdn.microso...9(v=vs.85).aspx

Setting them as e.g. constants does not work because of HexValues that can't be read in VB6.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users