Converting a drive letter to a Partition ID / Disk ID - windows

Given a drive letter, how do I get the OSImage InstallTo Partition ID and Disk ID without using the registry?

The WMI class Win32_DiskPartition is what I need. Now to figure out how to use WMI to get this information from a drive letter.
Win32_LogicalDisk is also useful, MSDN Example, and this stackoverflow answer.
Update: Hmm, this doesn't work! Not in the Windows Installer anyway (WMI is missing from Windows PE!!) so I am using the other answer QueryDosDevice (e.g. \\.\PhysicalDisk1\Partition0) and hacking it together. This sucks Microsoft, accept a damn path in your installer.
Answer: IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS works to get the Disk ID. And DeviceIoControl IOCTL_DISK_GET_PARTITION_INFO_EX (thanks TLama) gets me the Partition ID.

Have you tried simply calling QueryDosDevice?

Related

How to map a UNC name to an external drive when the drive letter is variable? [duplicate]

This question already has an answer here:
How do i map network drive with User Credentials [closed]
(1 answer)
Closed 2 months ago.
This post was edited and submitted for review 2 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I have an external drive. When I plug it in, sometimes it comes up as d: and sometimes as e:. I presume depending on whether I've plugged anything else in lately, like a USB drive, but whatever. I would like to have a fixed name to files on this drive. Can I map a UNC name to the drive, so that whether it's D: or E:, it will always be \foo or \mycomputer\foo or whatever?
I see someone referred me to a question about how to map network drives to UNC names. Thanks, but that's not what I'm looking for. I know how to map a specific drive letter to a UNC name. But in this case, the drive letter can change each time I plug the drive in. What I want to know is, is there a way to map a device name to a UNC name? Like, I've named the drive "pergamum". (Because it's my library and there was a great ancient library in Pergamum, get it? My network drive I call Alexandria.) So what I'm looking for is a way that whenever I plug it in, it becomes \\pergamum (or whatever, the exact name doesn't matter), regardless of whether it's on D: or E:
I see I've gotten the same suggested "does this answer your question" a second time. Please read my second paragraph in which I attempt to explain why that doesn't answer my question. I'm not asking how to map a UNC name to a drive LETTER. I'm asking how to map a UNC name to a drive NAME. Or some other identifier of the drive that would remain constant even if the drive letter changes.
Sigh. I have already edited the question twice to explain why " How do i map network drive with User Credentials" does not answer my question. I'll state it a third time: I'm looking for a way to map a removable external drive to a UNC name, where the drive letter might change every time the drive is connected. I AM NOT ASKING HOW TO MAP A FIXED DRIVE LETTER TO A UNC NAME!!! Does anyone actually read the question before voting to close? I understand that the first time this was suggested, perhaps my question was not clearly enough worded. But I've now spelled out, I think quite clearly, why that does not answer my question. If the answer is, "There is no out-of-the-box way to do this", okay, fine. But don't tell me there's a way and then point me to an answer that does not, in fact, answer my question.
Any solution must be able to identify your specific drive based on some unique piece of information that sets it apart from other drives that could've been plugged in. I don't think there is an out-of-the-box automatic solution. One solution can be to create a scheduled script (use Windows Task Scheduler) that hooks on device attach event and performs some checks that you have defined. E.g., put a file with a unique hash in the root folder of your drive and let the scheduled script read it upon drive attach. Once the drive is verified, the script can create a static alias that you define for it, like this: https://superuser.com/questions/528836/map-network-drive-and-provide-an-alias.

How do I map the device details such as \Device\Harddisk1\DR1 in the event log to a drive letter such as C:?

Using the event viewer, I can see that the event log has entries such as "The driver detected a controller error on \Device\Harddisk1\DR1." and "The driver detected a controller error on \Device\Harddisk1\DR7.".
Using VC++ code, I want to translate this device path (e.g. \Device\Harddisk1\DR1) to a drive letter such as C: wherever applicable (I understand that not all the devices will map to a drive letter).
Using FindFirstVolume and FindNextVolume I am able to loop through all the volumes and for each, I am using QueryDosDevice to get the device name and GetVolumePathNamesForVolumeName to get the drive letter.
The problem I am having is that when I use the above method to get the device names, I end up with device names such as "\Device\HarddiskVolume3", "\Device\HarddiskVolume2", etc.
I do get these mapped to the drive letters. However, I am not sure how these map to the device name format I see in the event log entry.
So, in summary, my question is:
How do I map the device name format "\Device\HarddiskVolume%d" to the format "\Device\Harddisk%d\DR%d" where each %d is a number.
This isn't C++ code, but two applications written in C++ show this information, at least to check your results. I don't believe the source of either application is readily available.
NirSoft's DriveLetterView matches drive letter to \Device\HarddiskVolume%d in the Drive Letter and Device Path columns.
SysInternals' WinObj matches drive letter to \Device\HarddiskVolume%d and \Device\Harddisk%d\DR%d to PhysicalDrive%d.
Updating #Dan-H's answer:
DriveLetterView
NirSoft DriveLetterView doesn't show the DRnumber, as in \Device\Harddisk1\DR1
But it does show the \Device\HarddiskVolumeN and the \PhysicalDriveN and the X:\ drive letter
The \Device\HarddiskN number and the \PhysicalDriveN number are the same.
So knowing that, you can take the \Device\HarddiskN number from \Device\HarddiskN\DRx and look at the corresponding \PhysicalDriveN in DriveLetterView and then look at the corresponding X:\ drive letter.
WinOjb
WinObj has had some improvements since 2014. It's now up to v3.10 as of 07/20/2021.
Note, have to run as administrator, otherwise it doesn't show as much info.
Also note, sorting the columns is incredibly helpful in finding information. As is the new search.
GLOBAL?? is the most useful in the left nav pane.
Sorting GLOBAL?? by column Symbolic Link Target you can map
\Device\HarddiskN\DRx
to \PhysicalDriveN
to Harddisk1Partition1
to \Device\HarddiskVolumeN
to X:\ drive letter
You can also use WinObj search to find these mappings.
The volume numbers do not match command line tool diskpart; that has its own volume numbering scheme. But the \PhysicalDriveN and HarddiskN appear to match diskpart numbering (but I'd confirm before relying on it).

VBScript to get DC SYSVOL information (path, size, free space)

I am obtaining information about my DCs and need to pull in the path to sysvol, total size, and free space remaining.
Cant his be done in VBScript and if so how?
Thanks
Have a look at this Microsoft support page - the registry entries are in this document of where the SYSVOL and other NTDS directories are stored.
You might find that you can also get this information through Active Directory however I'm not sure - I will check ADSIEdit shorly.
You can do it through the WMI. See an example here: http://www.computerperformance.co.uk/vbscript/wmi_disks.htm

Find which drive corresponds to which USB mass storage device in WinXP

I have several USB drives connected to a WinXP SP3 computer, and I need to tell them apart programatically - I need to find which drive letter corresponds to which device (in this case, one device ~ one volume). I can get their Volume IDs and drive letters using mountvol, looking something like this:
C:\WINDOWS\> mountvol
\\?\Volume{bdb681b2-1ddf-11dd-bf71-806d6172696f}\
C:\
\\?\Volume{6a8784f8-7406-11dd-a8c3-001e8c829b67}\
A:\
Also, using devcon or the Device Manager, I can see the device IDs:
C:\WINDOWS\> devcon resources *STOR*
STORAGE\REMOVABLEMEDIA\7&190C24E5&0&RM
Name: Generic volume
STORAGE\VOLUME\1&30A96598&0&SIGNATURED84ED84EOFFSET7E00LENGTH2543150400
Name: Generic volume
USBSTOR\DISK&VEN_KINGSTON&PROD_DATATRAVELER2.0&REV_1.00\0803240752536&0
Name: Kingston DataTraveler2.0 USB Device
However, I haven't found a way to link the device ID and the volume ID/letter, like the "Safely remove hardware" dialog does (therefore I assume it's possible):
(source: piskvor.org)
As you may see, these are the same devices that I see in devcon and the same volume that mountvol sees; but so far I haven't found the link between them.
I've found some related questions, but those seem to use the approach "whatever you find first is your USB device", which is not very useful in my case, since there will be several similar devices (same vendor, often same product type) connected.
Edit:
#MSalters' answer looks promising: On XP, HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices has REG_BINARY values \DosDevices\x: (where x is [A-Z]); the comment is (UTF-16) name of the correct device (e.g.
\DosDevices\A: = "\??\STORAGE#RemovableMedia#7&190c24e5&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}\", which corresponds to
STORAGE\REMOVABLEMEDIA\7&190C24E5&0&RM seen above in the device list).
Will see if that's the way to go.
It's a non-trivial question. There is no official API for it, as far as I can tell. So, you need an undocumented API: the registry. HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices contains entries for both drive letters and volume IDs. If you look at the actual data, you'll find that it identifies the drive. Look at the binary data as a Unicode string. It will point you to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ENUM\. However, XP and Vista differ in exactly what subkeys are referenced there, and how. (Vista is easier, so try that first).
There is an official API to do this. See this sample:
http://www.codeproject.com/KB/system/RemoveDriveByLetter.aspx
The principle is that each storage volume on Windows is assigned a global number. First, you ask your drive for its number (by opening "\X:" and sending a IOCTL_STORAGE_GET_DEVICE_NUMBER request). Second, you go over all disk devices and ask each one for its number (by opening it, through a different path, so you can't just string-compare).
Once you find a disk device carrying the same number as you queried your drive, you know you have a winner.

Network Drive label

I'm trying to get the label of some network resources mapped as drives. When I use DriveInfo.GetDrives(), local volumes have the VolumeLabel filled parameter as expected, but in network drives it is an empty string. How can I get those labels?
You can use WMI for this - not sure of the exact query (it's been a while), but here's an example of how to get network drive free space:
http://en.csharp-online.net/Network_Drive_Free_Space
I think replacing 'name' with 'VolumeName' in that example will give you what you need.
WMI reference here just in case:
http://msdn.microsoft.com/en-us/library/aa394173(VS.85).aspx
Never use WMI
Use net apis.

Resources