Dougiefresh Posted November 18, 2007 Author Posted November 18, 2007 (edited) I was looking at MadBoy's code and figured that it would take a long time to query a large number of drives. So I've modified MadBoy's code so that the PNP Device ID for all drives are returned in an array. Array returned is dimensioned as 3 slots (Drive Letter, PNP Device ID, Interface Type) per number of drives returned. Here's the code:expandcollapse popup#include <Array.au3> #include <String.au3> $test = _DriveGetDeviceIDList() _ArrayDisplay( $Test ) Func _DriveGetDeviceIDList( $strComputer = "." ) local $Arr[27][3], $i = 1, $colItems, $j, $Antecedent, $Dependent const $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20 ; Get the disk/partition number for the logical drives attached to machine: $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDiskToPartition", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $Antecedent = _StringBetween($objItem.Antecedent, '"', '"') $Dependent = _StringBetween($objItem.Dependent, '"', '"') $Arr[$i][0] = $Dependent[0] $Arr[$i][1] = $Antecedent[0] $i = $i + 1 Next ReDim $Arr[$i][3] $Arr[0][0] = $i - 1 ; Associate physical drive with disk/partition number in array: $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $Antecedent = _StringBetween($objItem.Antecedent, '"', '"') $Dependent = _StringBetween($objItem.Dependent, '"', '"') $drive_physical = StringTrimLeft($Antecedent[0], StringInStr($Antecedent[0], "\", 1, -1)) for $j = 1 to $i - 1 If $Dependent[0] = $Arr[$j][1] then $Arr[$j][1] = $drive_physical next Next ; Associate PNP device ID with physical drives in array: $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $DeviceID = StringTrimLeft($objItem.DeviceID, StringInStr($objItem.DeviceID, "\", 1, -1)) for $j = 1 to $i - 1 if $DeviceID = $Arr[$j][1] then $Arr[$j][1] = $objItem.PNPDeviceID $Arr[$j][2] = $objItem.InterfaceType endif next Next return $Arr EndFunc;==> _DriveGetDeviceIDListThe device differentation that I am doing can take place that the $Arr[$j][2] assignment statement. Edited November 18, 2007 by Dougiefresh
Dougiefresh Posted November 18, 2007 Author Posted November 18, 2007 (edited) Ok, I was fiddling with the code, trying to get rid of the floppy drive grind everytime that the script is run. I replaced the first 5 (or so) lines of the above post with the following code: Func _DriveGetDeviceIDList( $strComputer = "." ) local $Arr[27][3], $i = 1, $colItems, $j, $Antecedent, $Dependent, $Filter = "" const $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20 const $DL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; Let's filter out the floppy drives first: for $j = 1 to 26 $Drv = StringMid( $DL, $j, 1 ) & ":" if DriveGetType( $Drv ) <> "REMOVABLE" then ContinueLoop $usbdev = RegRead( "HKLM\SYSTEM\MountedDevices", "\DosDevices\" & $Drv ) $usbdev = _HexToString( StringReplace( $usbdev, "00", "" ) ) if StringInStr( $usbdev, "STORAGE#RemovableMedia" ) = 0 then _ $Filter = $Filter & _IIf( $Filter = "", " WHERE ", " and " ) & "DeviceID <> '" & $Drv & "'" next ; Get the disk/partition number for the logical drives attached to machine: $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDiskToPartition" & $Filter, _ "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)If I insert that code, nothing is returned in the array. I know that the non-USB floppy drive I have is properly detected as drive A: (haven't tested a USB drive). What am I doing wrong here? Edited November 18, 2007 by Dougiefresh
Dougiefresh Posted November 18, 2007 Author Posted November 18, 2007 (edited) Fiddled with the code some more and found a way to kill the second floppy grind. Here's the code:expandcollapse popupFunc _DriveGetDeviceIDList() ; Find floppy drives for the script: ;==================================================================================== local $UsbDev, $Filt1 = "", $Filt2 = "", $Floppy = "" local $Drv = DriveGetDrive( "REMOVABLE" ) if @error = 0 then for $j = 1 to $Drv[0] $usbdev = RegRead( $MOUNT, "\DosDevices\" & $Drv[ $j ] ) $usbdev = _HexToString( StringReplace( $usbdev, "00", "" ) ) if StringInStr( $usbdev, "STORAGE#RemovableMedia" ) = 0 then $Floppy = $Floppy & "|" & $Drv[ $j ] next if $Floppy <> "" Then ;Draft the $Filt1 variable here.... $Filt2 = "WHERE " & StringReplace( $Floppy, "|", "' And DeviceID <> '" ) $Filt2 = StringReplace( $Filt2, "WHERE ' And", "WHERE" ) & "'" Endif endif ; Get PNP Device IDs for all drives: ;==================================================================================== global $PNP[27][3] local $i = 1, $colItems, $j, $Antecedent, $Dependent const $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20, $strComputer = "." ; Get the disk/partition number for the logical drives attached to machine: $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDiskToPartition" & $Filt1, _ "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $Antecedent = _StringBetween($objItem.Antecedent, '"', '"') $Dependent = _StringBetween($objItem.Dependent, '"', '"') $PNP[$i][0] = $Dependent[0] $PNP[$i][1] = $Antecedent[0] $i = $i + 1 Next ReDim $PNP[$i][3] $PNP[0][0] = $i - 1 ; Associate physical drive with disk/partition number in array: $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $Antecedent = _StringBetween($objItem.Antecedent, '"', '"') $Dependent = _StringBetween($objItem.Dependent, '"', '"') $drive_physical = StringTrimLeft($Antecedent[0], StringInStr($Antecedent[0], "\", 1, -1)) for $j = 1 to $i - 1 if $Dependent[0] = $PNP[$j][1] then $PNP[$j][1] = $drive_physical next Next ; Associate PNP device ID with physical drives in array: $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive " & $Filt2, "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) For $objItem In $colItems $DeviceID = StringTrimLeft($objItem.DeviceID, StringInStr($objItem.DeviceID, "\", 1, -1)) for $j = 1 to $i - 1 if $DeviceID = $PNP[$j][1] then $PNP[$j][1] = $objItem.PNPDeviceID $PNP[$j][2] = $objItem.InterfaceType endif next Next return $PNP EndFuncI can't figure out how to draft the $FILT1 variable to get rid of 1st floppy grind.EDIT: Oh, yeah. Here's how I can pull the PNP Device ID or Interface type for any drive from the array easily:Func _GetPNP( $Drv, $Element = 1 ) for $i = 1 to $PNP[0][0] if $Drv = $PNP[ $i ][0] then return $PNP[ $i ][ $Element ] Next return "" EndFuncBy default, it returns the PNP Device ID. By specifying 2 for the element, it will return the interface type. If the drive doesn't exist in the array, it returns an empty string. Edited November 20, 2007 by Dougiefresh
Dougiefresh Posted November 19, 2007 Author Posted November 19, 2007 (edited) Got rid of first floppy grind. Here's the original code:if $Floppy <> "" Then ;Draft the $Filt1 variable here.... $Filt2 = "WHERE " & StringReplace( $Floppy, "|", "' And DeviceID <> '" ) $Filt2 = StringReplace( $Filt2, "WHERE ' And", "WHERE" ) & "'" Endif endifand here's what to replace it with:if $Floppy <> "" Then $Filt1 = """' and Dependent='\\\\.\\root\\cimv2:Win32_LogicalDisk.DeviceID<>""" $Filt1 = "WHERE " & StringReplace( $Floppy, "|", $Filt1 ) & """'" $Filt1 = StringReplace( $Filt1, "WHERE ""' And", "WHERE" ) $Filt2 = "WHERE " & StringReplace( $Floppy, "|", "' And DeviceID <> '" ) $Filt2 = StringReplace( $Filt2, "WHERE ' And", "WHERE" ) & "'" Endif This solves my last problem with this. Edited November 20, 2007 by Dougiefresh
Dougiefresh Posted November 20, 2007 Author Posted November 20, 2007 No, above code replacement results in PNP device detection not functioning.... Sorry, I'll keep looking!
GEOSoft Posted November 20, 2007 Posted November 20, 2007 @dougiefresh There is probably something in here that you can use. AFAIK it won't even look at the floppies. expandcollapse popup$wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" $Output="" $Output &= "Computer: " & $strComputer & @CRLF $Output &= "==========================================" & @CRLF $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) then For $objItem In $colItems $Output &= "Availability: " & $objItem.Availability & @CRLF $Output &= "BytesPerSector: " & $objItem.BytesPerSector & @CRLF $strCapabilities = $objItem.Capabilities(0) $Output &= "Capabilities: " & $strCapabilities & @CRLF $strCapabilityDescriptions = $objItem.CapabilityDescriptions(0) $Output &= "CapabilityDescriptions: " & $strCapabilityDescriptions & @CRLF $Output &= "Caption: " & $objItem.Caption & @CRLF $Output &= "CompressionMethod: " & $objItem.CompressionMethod & @CRLF $Output &= "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF $Output &= "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF $Output &= "CreationClassName: " & $objItem.CreationClassName & @CRLF $Output &= "DefaultBlockSize: " & $objItem.DefaultBlockSize & @CRLF $Output &= "Description: " & $objItem.Description & @CRLF $Output &= "DeviceID: " & $objItem.DeviceID & @CRLF $Output &= "ErrorCleared: " & $objItem.ErrorCleared & @CRLF $Output &= "ErrorDescription: " & $objItem.ErrorDescription & @CRLF $Output &= "ErrorMethodology: " & $objItem.ErrorMethodology & @CRLF $Output &= "Index: " & $objItem.Index & @CRLF $Output &= "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF $Output &= "InterfaceType: " & $objItem.InterfaceType & @CRLF $Output &= "LastErrorCode: " & $objItem.LastErrorCode & @CRLF $Output &= "Manufacturer: " & $objItem.Manufacturer & @CRLF $Output &= "MaxBlockSize: " & $objItem.MaxBlockSize & @CRLF $Output &= "MaxMediaSize: " & $objItem.MaxMediaSize & @CRLF $Output &= "MediaLoaded: " & $objItem.MediaLoaded & @CRLF $Output &= "MediaType: " & $objItem.MediaType & @CRLF $Output &= "MinBlockSize: " & $objItem.MinBlockSize & @CRLF $Output &= "Model: " & $objItem.Model & @CRLF $Output &= "Name: " & $objItem.Name & @CRLF $Output &= "NeedsCleaning: " & $objItem.NeedsCleaning & @CRLF $Output &= "NumberOfMediaSupported: " & $objItem.NumberOfMediaSupported & @CRLF $Output &= "Partitions: " & $objItem.Partitions & @CRLF $Output &= "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0) $Output &= "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF $Output &= "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF $Output &= "SCSIBus: " & $objItem.SCSIBus & @CRLF $Output &= "SCSILogicalUnit: " & $objItem.SCSILogicalUnit & @CRLF $Output &= "SCSIPort: " & $objItem.SCSIPort & @CRLF $Output &= "SCSITargetId: " & $objItem.SCSITargetId & @CRLF $Output &= "SectorsPerTrack: " & $objItem.SectorsPerTrack & @CRLF $Output &= "Signature: " & $objItem.Signature & @CRLF $Output &= "Size: " & $objItem.Size & @CRLF $Output &= "Status: " & $objItem.Status & @CRLF $Output &= "StatusInfo: " & $objItem.StatusInfo & @CRLF $Output &= "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF $Output &= "SystemName: " & $objItem.SystemName & @CRLF $Output &= "TotalCylinders: " & $objItem.TotalCylinders & @CRLF $Output &= "TotalHeads: " & $objItem.TotalHeads & @CRLF $Output &= "TotalSectors: " & $objItem.TotalSectors & @CRLF $Output &= "TotalTracks: " & $objItem.TotalTracks & @CRLF $Output &= "TracksPerCylinder: " & $objItem.TracksPerCylinder & @CRLF if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop $Output="" Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_DiskDrive" ) Endif Func WMIDateStringToDate($dtmDate) Return (StringMid($dtmDate, 5, 2) & "/" & _ StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _ & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2)) EndFunc George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Dougiefresh Posted November 21, 2007 Author Posted November 21, 2007 (edited) Actually, for the "SELECT * FROM Win32_DiskDrive" section of code, I've already got the code not to look at the floppy. That's where the "$Filt2" variable comes in. It's actually built earlier in the function, so that all detected floppy drives are covered in the list of drives not to look at.The problem I'm having is with the "SELECT * FROM Win32_LogicalDiskToPartition" section of code. I can't seem to find any way to prevent the code from causing the floppy drive to activate (or grind). I was hoping to use something similar to the "SELECT * FROM Win32_DiskDrive" code, but everything I've tried to exclude the floppy drives in the search has met without success. If you could look at 2 posts ago (and 3 or 4 posts with full code for function) and solve this problem, it would be most appreciated! I'll continue looking for a solution...EDIT: Edited post because "$FILT1" is used for first search (Win32_LogicalDiskToPartition), "$FILT2" for the second search (Win32_DiskDrive). Sorry about that! Edited November 21, 2007 by Dougiefresh
GEOSoft Posted November 21, 2007 Posted November 21, 2007 Interesting because the code I gave you causes no drive activity on my floppy drive at all. George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
MadBoy Posted November 21, 2007 Posted November 21, 2007 Interesting because the code I gave you causes no drive activity on my floppy drive at all.GEOSoft the problem is that your code as itself isn't enought to get PnpDeviceID from drive letter. I had to use a lot of others wmi calls to get this right. My little company: Evotec (PL version: Evotec)
Dougiefresh Posted November 21, 2007 Author Posted November 21, 2007 GEOSoft, the code you provided doesn't cause a floppy drive access either. I looked at my code and yours, and I don't see any difference between the two (mine without the filter). Mine causes floppy drive access, yours doesn't. No clue why... Madboy is right, though. Your code doesn't return PNP device IDs. Madboy, any ideas on how to solve this little issue?
GEOSoft Posted November 21, 2007 Posted November 21, 2007 GEOSoft, the code you provided doesn't cause a floppy drive access either. I looked at my code and yours, and I don't see any difference between the two (mine without the filter). Mine causes floppy drive access, yours doesn't. No clue why... Madboy is right, though. Your code doesn't return PNP device IDs.Madboy, any ideas on how to solve this little issue?It returns PNPDeviceID but you can't call it by Drive letter.$Output &= "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Dougiefresh Posted November 21, 2007 Author Posted November 21, 2007 It returns PNPDeviceID but you can't call it by Drive letter.You're right. I missed the PNPDeviceID line in your code. I need to associate a drive letter with a PNP device ID. The modified MadDog post found here does using 3 WMI queries, but it grinds the floppy drive. The second WMI query doesn't (probably by design). The third WMI query gets the PNP Device ID from WMI, like your code does GEOSoft. I've already got a filter for that (Win32_DiskDrive) WMI query.The first WMI query uses Win32_LogicalDriveToPartition. How do I modify this so that the query doesn't check the floppy drive?
Dougiefresh Posted December 9, 2007 Author Posted December 9, 2007 Can anyone help me? I'd be appreciated! Thanks!
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