twbradio Posted March 20, 2009 Share Posted March 20, 2009 I have an external program that requires the disk number (0, 1, 2 ... ) and I am looking to wrap it with an AutoIt script. Is there a way to get the disk number from the drive letter of a partition? Tom Brown Anyone have a TRS 80 Model III for sale? Link to comment Share on other sites More sharing options...
trancexx Posted March 20, 2009 Share Posted March 20, 2009 Maybe this: $sDriveLetter = "c" $iDriveNumber = Asc(StringUpper($sDriveLetter)) - 65 ConsoleWrite($iDriveNumber & @CRLF) ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 20, 2009 Share Posted March 20, 2009 (edited) I have an external program that requires the disk number (0, 1, 2 ... ) and I am looking to wrap it with an AutoIt script. Is there a way to get the disk number from the drive letter of a partition?Tom BrownToo vague: Logical disk? Physical disk? Partition number on the physical disk? Include mount points? What about mapped network drives? Removable drives? Removable media?What, in your context, is a "disk number"? I like trancexx's idea! Edited March 20, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
twbradio Posted March 20, 2009 Author Share Posted March 20, 2009 Because physical disks can have more than one partiton, this doesn't always equate properly. Thanks you for the reply. Tom Maybe this: $sDriveLetter = "c" $iDriveNumber = Asc(StringUpper($sDriveLetter)) - 65 ConsoleWrite($iDriveNumber & @CRLF) Anyone have a TRS 80 Model III for sale? Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 20, 2009 Share Posted March 20, 2009 Because physical disks can have more than one partiton, this doesn't always equate properly. Thanks you for the reply.Tom...ermm... ...tracexx was just kidding with you. That just shows the ASCII code of the drive letter. You need to provide more info on what you want, as I posted earlier. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
twbradio Posted March 20, 2009 Author Share Posted March 20, 2009 Too vague: Logical disk? Physical disk? Partition number on the physical disk? Include mount points? What about mapped network drives? Removable drives? Removable media?What, in your context, is a "disk number"? I like trancexx's idea! Thanks for the catch on this ... I am looking for the windows physical disk number (similar to what is seen in Disk Management) with the Logical partition name (c:, d: ... ) as the input ... I don't need the partition number or any other data.Tom Brown Anyone have a TRS 80 Model III for sale? Link to comment Share on other sites More sharing options...
martin Posted March 20, 2009 Share Posted March 20, 2009 (edited) ...ermm... ...tracexx was just kidding with you. That just shows the ASCII code of the drive letter. You need to provide more info on what you want, as I posted earlier. It's not obvious to me trancexx was kidding. His script doesn't return the ascii code it returns the drive number doesn't it?What difference does it make if the drive is mounted in whatever way? Isn't the drive number still given by tracexx' code?EDIT. No, I see that I am wrong. (Not about the ascii code) The disc number for C: and D: is given as 0 on my laptop. I am obviously confusing this with some other number. When I used to write C programs the drives really were referred to as Ascii(DriveLetter) - Ascii('A') so Drive J: was 9. I'm out of touch again!Here is a link which has some useful information.It is not possible to detrmine the disc number from the drive letter alone because it is determined by the bios and simply changing drives or adding a drive can change numbers around without changing the drive letters.In Drive manager on my pc there is nothing shown for virtual drives or network drives. So I suppose the question to twbradio is, what do you mean by the disk number because I can't see that it is very useful to many applications? Edited March 20, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 20, 2009 Share Posted March 20, 2009 You can work your way around to it, but it's not trivial (to me, anyway): $oWMISvc = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2") $colDiskDrives = $oWMISvc.ExecQuery("SELECT * FROM Win32_DiskDrive") For $oDiskDrive In $colDiskDrives ConsoleWrite("DiskDrive = " & $oDiskDrive.DeviceId & " Caption = " & $oDiskDrive.Caption & @LF) $sQuery = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $oDiskDrive.DeviceId & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition" $colPartitions = $oWMISvc.ExecQuery($sQuery) For $oPartition In $colPartitions ConsoleWrite(@TAB & "Partition = " & $oPartition.DeviceId & @LF) $sQuery = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $oPartition.DeviceId & "'} WHERE AssocClass = Win32_LogicalDiskToPartition" $colLogicalDisks = $oWMISvc.ExecQuery($sQuery) For $oLogicalDisk In $colLogicalDisks ConsoleWrite(@TAB & @TAB & "LogicalDisk = " & $oLogicalDisk.DeviceId & @LF) Next Next Next DirkM 1 Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
trancexx Posted March 22, 2009 Share Posted March 22, 2009 (edited) That's cool.Going to my special folder of special folders of... special things.edit:I did some thinking ( ) and I'm confused by the return values of the duck's code. For me it returns something like this:DiskDrive = \\.\PHYSICALDRIVE0 Caption = WDC WD1200JS-00MVB1 Partition = Disk #0, Partition #0 LogicalDisk = C: Partition = Disk #0, Partition #1 LogicalDisk = F: Partition = Disk #0, Partition #2 LogicalDisk = G: LogicalDisk = H: Partition = Disk #0, Partition #3 LogicalDisk = E:What confuses me is that I never heard of partition #0 and that code returned drive C to be partition #0. I did some searching too and thing is that there shouldn't be partition 0 with windows (better say, partition(0) refers to the entire disk <- link, this too).Further more, my mum (what?) told me that I should try to do something with DeviceIoControl function found in kernel32.dll.I got this:expandcollapse popupLocal $aCall = DllCall("kernel32.dll", "dword", "GetLogicalDrives") Local $iMask = $aCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $hDevice Local $a_hCall, $a_iCall For $i = 0 To 25; alphabet (A = 0) If BitAND(BitShift($iMask, $i), 1) Then; drive exists $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & Chr(65 + $i) & ":", _; want handle to the logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) $hDevice = $a_hCall[0] $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ConsoleWrite("Drive " & Chr(65 + $i) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) EndIf NextData returned by that is in some degree different than using PsaltyDS's code. In case that code is correct something like this could be written:expandcollapse popup$sDDriveLetter = "C" $iDiskNumber = _GetDiskNimberForDrive($sDDriveLetter) If @error Then MsgBox(48, "Error", "Error Number " & @error & @CRLF) Else MsgBox(64, "_GetDiskNimberForDrive", "Drive " & StringUpper($sDDriveLetter) & " is on disk #" & $iDiskNumber) EndIf Func _GetDiskNimberForDrive($sDriveLetter) Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & $sDriveLetter & ":", _; logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) If @error Then Return SetError(1, 0, -1); your system is very old. Do something. EndIf If $a_hCall[0] = -1 Then Return SetError(2, 0, -1); non-existing drive EndIf Local $hDevice = $a_hCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) If @error Or Not $a_hCall[0] Then DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) Return SetError(3, 0, -1); DeviceIoControl failed for some reason EndIf DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ; will write some data ConsoleWrite("Drive " & StringUpper($sDriveLetter) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) ; end writing If DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") = 7 Then; FILE_DEVICE_DISK Return SetError(0, 0, DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber")) EndIf Return SetError(4, 0, -1); not a disk partition EndFunc ;==>_GetDiskNimberForDriveI only have one disk, so I cannot test it. Edited March 23, 2009 by trancexx meoit and AZJIO 2 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 23, 2009 Share Posted March 23, 2009 That's cool. Going to my special folder of special folders of... special things. edit: I did some thinking ( ) and I'm confused by the return values of the duck's code. For me it returns something like this: DiskDrive = \\.\PHYSICALDRIVE0 Caption = WDC WD1200JS-00MVB1 Partition = Disk #0, Partition #0 LogicalDisk = C: Partition = Disk #0, Partition #1 LogicalDisk = F: Partition = Disk #0, Partition #2 LogicalDisk = G: LogicalDisk = H: Partition = Disk #0, Partition #3 LogicalDisk = E: What confuses me is that I never heard of partition #0 and that code returned drive C to be partition #0. I did some searching too and thing is that there shouldn't be partition 0 with windows (better say, partition(0) refers to the entire disk <- link, this too). Further more, my mum (what?) told me that I should try to do something with DeviceIoControl function found in kernel32.dll. I got this: CODELocal $aCall = DllCall("kernel32.dll", "dword", "GetLogicalDrives") Local $iMask = $aCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $hDevice Local $a_hCall, $a_iCall For $i = 0 To 25; alphabet (A = 0) If BitAND(BitShift($iMask, $i), 1) Then; drive exists $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & Chr(65 + $i) & ":", _; want handle to the logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) $hDevice = $a_hCall[0] $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ConsoleWrite("Drive " & Chr(65 + $i) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) EndIf NextData returned by that is in some degree different than using PsaltyDS's code. In case that code is correct something like this could be written: CODE$sDDriveLetter = "C" $iDiskNumber = _GetDiskNimberForDrive($sDDriveLetter) If @error Then MsgBox(48, "Error", "Error Number " & @error & @CRLF) Else MsgBox(64, "_GetDiskNimberForDrive", "Drive " & StringUpper($sDDriveLetter) & " is on disk #" & $iDiskNumber) EndIf Func _GetDiskNimberForDrive($sDriveLetter) Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & $sDriveLetter & ":", _; logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) If @error Then Return SetError(1, 0, -1); your system is very old. Do something. EndIf If $a_hCall[0] = -1 Then Return SetError(2, 0, -1); non-existing drive EndIf Local $hDevice = $a_hCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) If @error Or Not $a_hCall[0] Then DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) Return SetError(3, 0, -1); DeviceIoControl failed for some reason EndIf DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ; will write some data ConsoleWrite("Drive " & StringUpper($sDriveLetter) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) ; end writing If DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") = 7 Then; FILE_DEVICE_DISK Return SetError(0, 0, DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber")) EndIf Return SetError(4, 0, -1); not a disk partition EndFunc ;==>_GetDiskNimberForDriveI only have one disk, so I cannot test it. Well, in the case of extended vice primary partitions, there could be... wait-a-minute... "the duck's code"? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
twbradio Posted March 26, 2009 Author Share Posted March 26, 2009 Huge thank you to everyone, I first tried the WMI call which worked on my local system, but did not work when I attempted to run it from my BartPE environment ... Moving to the DLL example, I was able to get exactly the result I wanted. Thank you all so much for pitching in. Thomas Brown Anyone have a TRS 80 Model III for sale? Link to comment Share on other sites More sharing options...
trancexx Posted March 27, 2009 Share Posted March 27, 2009 Well, in the case of extended vice primary partitions, there could be... wait-a-minute... "the duck's code"? <- click it ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Pretend2Script Posted July 29, 2010 Share Posted July 29, 2010 I just want to add a thanks here too. Just goes to show if you search long enough you'll some brilliant posts (as shown above). I had all the WMI component working just didn't have the association piece! Thanks PsaltyDs for the code and everyone else who added to it and the thread and to twbradio for the original question! The difference between Genius and Stupidity is that Genius has its limits....Einstein Link to comment Share on other sites More sharing options...
dexto Posted April 15, 2012 Share Posted April 15, 2012 Further more, my mum (what?) told me that I should try to do something with DeviceIoControl function found in kernel32.dll.Your mom is so cool... Link to comment Share on other sites More sharing options...
olmanRvr Posted September 24, 2016 Share Posted September 24, 2016 (edited) Hi there!! The following snippet gets the HDD serial number through a bat file.The bat file writes to a text file from which the sr. num. is retrieved by the Autoit script.In every run the HDD sr. num. is written successfully to comp_id.txt.But .au3 script acts inconsistently.It fail frequently (though succeeds occasionally) to retrieve the sr.no.. Can any one please help remove this inconsistent behavior ? here is the code: #include <constants.au3> #include <WinAPIFiles.au3> #include <MsgBoxConstants.au3> Func getHDDNum() Run("gtSrNumHDD.bat") While FileExists("comp_id.txt")==False Sleep(100) WEnd Sleep(100) Local $hddNum=FileReadLine("comp_id.txt",2) ConsoleWrite ("sr no is: "&$hddNum&@CRLF) MsgBox(0,"",$hddNum); ConsoleWrite ("sr no is: "&$hddNum&@CRLF) EndFunc getHDDNum() FileDelete("comp_id.txt") the .bat file code: @ECHO OFF::writes to file comp_id.txt wmic diskdrive get serialnumber > comp_id.txt I will greatly appreciate any help olmar Edited September 24, 2016 by olmanRvr Link to comment Share on other sites More sharing options...
pluto41 Posted September 26, 2016 Share Posted September 26, 2016 Func getHDDNum() RunWait("gtSrNumHDD.bat") Sleep(100) Local $hddNum=FileReadLine("comp_id.txt",2) ConsoleWrite ("sr no is: "&$hddNum&@CRLF) MsgBox(0,"",$hddNum); ConsoleWrite ("sr no is: "&$hddNum&@CRLF) EndFunc getHDDNum() FileDelete("comp_id.txt") @ECHO Off vol c: > comp_id.txt Local $strDiskDrive = "C:" Local $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") ;Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk Where DeviceID = 'C:'") Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk Where DeviceID = '" & $strDiskDrive & "'" ) For $objItem In $colItems Local $strSerial = $objItem.VolumeSerialNumber ConsoleWrite ( "Serial Number of Drive " & $strDiskDrive & $strSerial & @CRLF ) Next @olmanRvr I changed Run to RunWait() in your'e function And In your'e batch file i changed the wmic command to: "Vol C: > comp_id.txt" After these changes the code seems to run ok. Also i added a third piece of code on how to do almost the same with WMI. Hope this helps Link to comment Share on other sites More sharing options...
olmanRvr Posted October 17, 2016 Share Posted October 17, 2016 Hi pluto41, Many thanks for your reply.I tried your revised version.But there are errors. @ECHO OFF ->"undefined macro" and for vol c: > comp_id.txt ->"Statement cannot be just an expression".Attaching snap shot(not showing the includes).Any idea why the errors? cheers olmar Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now