Jump to content
Sign in to follow this  

How to use WMI to find presence of MBR on USB disk?

Recommended Posts


I am using this function to find all attached USB disks:

Func _GetUSBDrivesInfo()
    Local $USBDlettersInfo[1][10], $NrOfFoundUSB = 0, $dp, $HasPrimPart, $IsBootable
    Local $strComputer = ".", $objDrive, $strDeviceID, $colPartitions, $objPartition, $colLogicalDisks, $objLogicalDisk
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
    If Not IsObj($objWMIService) Then
        Logging("WMI appears to be broken")
        $msg = MsgBox(4 + 48, "Warning !", "WMI (Windows Management Instrumentation) seems to be not working. It's needed to obtain USB disk properties." _
                 & @CRLF & "Press YES to visit a web page, describing how to repair it, or NO to exit the program")
        If $msg = 6 Then
            Run(@ComSpec & " /c " & 'start http://windowsxp.mvps.org/repairwmi.htm', "", @SW_HIDE)
            Logging("WMI repair web page opened, closing program")
            Logging("WMI repair web page refused, closing program")
    Local $colDiskDrives = $objWMIService.ExecQuery("Select * from Win32_DiskDrive Where (InterfaceType like " & Chr(34) & "%USB%" & Chr(34) & " And MediaLoaded=1" & ")")
    For $objDrive In $colDiskDrives
        $HasPrimPart = 0
        $IsBootable = 0
        Logging($objDrive.Caption )
        Logging("       DeviceID: " & $objDrive.DeviceID)
        Logging("       PNPDeviceID: " & $objDrive.PNPDeviceID)
        Logging("       Partitions count: " & $objDrive.Partitions)
        $strDeviceID = StringReplace($objDrive.DeviceID, "\", "\\")
        Local $colPartitions = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & $strDeviceID & """}" _
                 & "WHERE AssocClass = Win32_DiskDriveToDiskPartition")
        ;check if this disk has bootable partitions
        For $objPartition In $colPartitions
            If $objPartition.Bootable = -1 Then
                $IsBootable = 1
        For $objPartition In $colPartitions
            If $objPartition.PrimaryPartition = -1 Then
                $HasPrimPart = 1
        If $IsBootable = 1 And $HasPrimPart = 1 Then
            For $objPartition In $colPartitions
                Logging("           Disk--Partition: " & $objPartition.DeviceID)
                $colLogicalDisks = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & $objPartition.DeviceID & """}" _
                        & "WHERE  AssocClass = Win32_LogicalDiskToPartition")
                For $objLogicalDisk In $colLogicalDisks
                    Logging("               Logical Disk: " & $objLogicalDisk.DeviceID & "  File system: " & $objLogicalDisk.FileSystem _
                            & " Primary: " & $objPartition.PrimaryPartition)
                    $NrOfFoundUSB += 1
                    $USBDlettersInfo[0][0] = $NrOfFoundUSB
                    ReDim $USBDlettersInfo[$NrOfFoundUSB + 1][10]
                    $USBDlettersInfo[$NrOfFoundUSB][0] = $objLogicalDisk.DeviceID
                    $USBDlettersInfo[$NrOfFoundUSB][1] = StringReplace($objDrive.Model, "USB device", "")
                    $dp = StringSplit($objPartition.DeviceID, ",")
                    $USBDlettersInfo[$NrOfFoundUSB][2] = StringRegExpReplace($dp[1], "[^0-9]", "")
                    $USBDlettersInfo[$NrOfFoundUSB][3] = StringRegExpReplace($dp[2], "[^0-9]", "")
                    $USBDlettersInfo[$NrOfFoundUSB][4] = Round(DriveSpaceTotal($objLogicalDisk.DeviceID), 0)
                    $USBDlettersInfo[$NrOfFoundUSB][5] = Round(DriveSpaceFree($objLogicalDisk.DeviceID), 0)
                    $USBDlettersInfo[$NrOfFoundUSB][6] = DriveGetType($objLogicalDisk.DeviceID)
                    $USBDlettersInfo[$NrOfFoundUSB][7] = $objLogicalDisk.FileSystem
                    $USBDlettersInfo[$NrOfFoundUSB][8] = $objPartition.PrimaryPartition 
                    $USBDlettersInfo[$NrOfFoundUSB][9] = $objDrive.PNPDeviceID 
                    ;$USBDlettersInfo[$NrOfFoundUSB][8] = $objPartition.Bootable
                    ;$USBDlettersInfo[$NrOfFoundUSB][8] = $objPartition.Bootable
                    ;array is in format--> DriveLetter | Name | Disk# | Part# | TotalSpace | FreeSpace | DriveType | FileSystem | Primary(-1) or Not (0)| PNPId

    Return $USBDlettersInfo
EndFunc   ;==>_GetUSBDrivesInfo

What I need to do is to exclude disks, which do not have a MBR.

I've been looking at Win32 classes, but can't spot anything suitable there.

Any ideas how to do it using WMI? I'd try first with WMI since it's already in the loop, rather that extracting first sector and looking at its code, or using 3rd party tools for the purpose.




Share this post

Link to post
Share on other sites

Does this help at all?

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output &= "Computer: " & $strComputer  & @CRLF
$Output &= "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskPartition", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      If NOT $objItem.BootPartition  Then MsgBox(0, "Result", "Not Bootable")
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_DiskPartition" )


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: - 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!"

Share this post

Link to post
Share on other sites

Not really. This would return true if there is an active partition, supposedly MBR too.

The case which bothers me is MBR and no active partition set. In this case Win32_DiskPartition.Bootable and Win32_DiskPartition.BootPartition would NOT return -1, but the disk is still valid for my needs, as I will be installing Grub4Dos MBR on it, which doesn't care if there is active partition or not, as it seeks and executes grldr file from any of the available partitions.

Win32_DiskPartition.PrimaryPartition is also not a good indication- it returns that the only partition is primary, even if there is no MBR and partition table, but a boot sector on the first sector, floppy-like partitioning without MBR, which is default in Windows after 2000. Talking about USB sticks, not USB hard disks.

Edited by ilko

Share this post

Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this