Sign in to follow this  
Followers 0
ilko

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

3 posts in this topic

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")
            Quit()
        Else
            Logging("WMI repair web page refused, closing program")
            Quit()
        EndIf
    EndIf
    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
                ExitLoop
            EndIf
        Next
        For $objPartition In $colPartitions
            If $objPartition.PrimaryPartition = -1 Then
                $HasPrimPart = 1
                ExitLoop
            EndIf
        Next        
        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
                Next            
            Next
        EndIf
    Next

    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.

http://msdn.microsoft.com/en-us/library/aa394084(VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa394135%28VS.85%29.aspx

http://msdn.microsoft.com/en-us/library/aa394132%28VS.85%29.aspx

Share this post


Link to post
Share on other sites



Does this help at all?

$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_DiskPartition", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

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

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

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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  
Followers 0