Jump to content

WinNTSetup format helper tool (Is it possible to move the GUI out of this function easily? )


Go to solution Solved by mikell,

Recommended Posts

Posted (edited)

Screenshot 2021-12-13 192821.png

I think this is off, I may be wrong, but this happened uncompiled last night and I rebooted and it went away and the error I saw was ~ Lines 6739-6740 if we use this as a reference..not the compile high line # 6k+, i mean the real autoit script error window that showed the ^, again in my previous post the alternate disklist code is working.. 

Edited by bobomb
Posted

I'm at work now so can't do much. If the old code works flawlessly,  then use that. Personally I want to know what is wrong with mine. Seems weird that it's intermittent on different machines.

With the errors, did the error occur after the pictured message box?  If so then use array display to show what as_DriveInfo looks like. The error shows the fixed array has 6 elements.

I mentioned in other posts about about adding error checks and maybe log writes, this is when it helps 😁.

There is a portable version of AutoIt around. Find that and see if you can add it to the PE disk and run the script.

Posted (edited)

I get the attached values right before it errors out using the below code

For $i = 1 To $as_Fixed[0]


    Local $aArray = DriveGetDrive('Removable')
    $as_DriveInfo[$i][0] = $as_Fixed[$i]
    MsgBox(0,'$as_DriveInfo', '$i: ' & $i & @CRLF & '$as_DriveInfo: ' & $as_DriveInfo[0][0])
    $as_DriveInfo[$i][1] = _WinAPI_GetDriveNumber($as_Fixed[$i])[1]

Next

*EDIT - Here are some pics of the array.. b: is a virtual disk it has no real disk #

Capture.PNG

Capture1.PNG

Capture2.PNG

Edited by bobomb
Posted (edited)

You don't need the drivegetdrive function in there  and variables shouldn't be declared Inside loops, this isn't the problem though.

Seen the new pics after a refresh. They seem OK.

It could be the getdrivenumber call.

Edited by benners
Posted

The reason is due to ramdisks or drives with no letter. _WinAPI_GetDriveNumber is returning an error. If we allow for that by skipping, we have a blank in the array. When the array is sorted on multi-columns, the blanks would mess up the line up. To get around this, we would need to use _ArrayDelete, this uses ReDim and thats what I wanted to get away from with the other code. It would redim after every delete which is worse than the working code.

The code you posted that is working would be the better choice, and ditch mine for the DiskList_Load function. We can look at loading the list from the function or leave it returning the string and using GuiCtrlSetData.

#NoTrayIcon
#RequireAdmin
#include <StringConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $c_DiskList = 0
Global $MBR = 0
Global $GPT = 0
Global $bootDrive = ""
Global $mainDrive = ""

Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

Func MainMenu()
    GUICreate('Prep/Format Disk v2.0', 300, 289)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")

    GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1)
    GUISetBkColor(0x797979)
    GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
    $c_DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT))
    GUICtrlSetData(-1, GetDiskList())
    GUICtrlSetOnEvent(-1, "DiskList_Selected")
    $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)

    GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
    $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 234, 120, 40)
    GUICtrlSetOnEvent(-1, "MBRPressed")
    GUICtrlSetState(-1, $GUI_DISABLE)
    $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 234, 120, 40)
    GUICtrlSetOnEvent(-1, "GPTPressed")
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

    ; Just idle around
    While 1
        Sleep(10)
    WEnd

EndFunc   ;==>MainMenu

Func RefreshPressed()
    GUICtrlSetData($c_DiskList, "")
    GUICtrlSetData($c_DiskList, GetDiskList())
    DiskList_Selected()
EndFunc   ;==>RefreshPressed

Func MBRPressed()
    Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0]

    If @error Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "An error occured retrieving the disk number")
    Else
        If MsgBox( _
                BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _
                'This will FORMAT Disk ' & $s_DiskNumber, _
                'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then
            PrepMBR($s_DiskNumber)
            FormatMBR()
            IniWriteMBR()
            MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
            LaunchWinNTSetup()
            Cleanup()
            Exit
        EndIf
    EndIf
EndFunc   ;==>MBRPressed

Func GPTPressed()
    Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0]

    If @error Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "An error occured retrieving the disk number")
    Else
        If MsgBox( _
                BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _
                'This will FORMAT Disk ' & $s_DiskNumber, _
                'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then
            PrepGPT($s_DiskNumber)
            FormatGPT()
            IniWriteGPT()
            MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
            LaunchWinNTSetup()
            Cleanup()
            Exit
        EndIf
    EndIf
EndFunc   ;==>GPTPressed

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            Exit
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ; Code below for actions on Minimize
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ; Code below for actions on Restore
    EndSelect
EndFunc   ;==>SpecialEvents

Func Disk_GetName($i_DiskNumber)
    Local $s_DiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($i_DiskNumber))
    If @error Then Return SetError(1, 0, 0)

    Local $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "FriendlyName")
    If $s_DiskName = "" Then $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "DeviceDesc")

    Return $s_DiskName
EndFunc   ;==>Disk_GetName

Func GetDiskList()
    Local $aDriveInfo, $iLastDevNumber = -1
    Local $aFixed = DriveGetDrive('FIXED'), $aRemovable = DriveGetDrive('REMOVABLE')
    Local $aDrives[(IsArray($aFixed) ? $aFixed[0] : 0) + (IsArray($aRemovable) ? $aRemovable[0] : 0)][3]

    Local $iDrive = 0
    GUICtrlSetData($c_DiskList, "") ; clear previous list info

    For $i = 1 To UBound($aFixed) - 1
        $aDrives[$iDrive][0] = $aFixed[$i]
        $aDriveInfo = _WinAPI_GetDriveNumber($aFixed[$i])

        If Not @error Then
            $aDrives[$iDrive][1] = $aDriveInfo[1]
            $aDrives[$iDrive][2] = $aDriveInfo[2]
        EndIf

        $iDrive += 1
    Next

    For $i = 1 To UBound($aRemovable) - 1
        $aDrives[$iDrive][0] = $aRemovable[$i]
        $aDriveInfo = _WinAPI_GetDriveNumber($aRemovable[$i])

        If Not @error Then
            $aDrives[$iDrive][1] = $aDriveInfo[1]
            $aDrives[$iDrive][2] = $aDriveInfo[2]
        EndIf

        $iDrive += 1
    Next

    _ArraySort($aDrives, 0, 0, 0, 1)

    Local $aDisks[UBound($aDrives)][2]
    Local $sOutput = ""

    For $i = 0 To UBound($aDrives) - 1
        If IsNumber($aDrives[$i][1]) Then
            If $aDrives[$i][1] <> $iLastDevNumber Then
                $iLastDevNumber = $aDrives[$i][1]
                $aDisks[$iLastDevNumber][0] = " Disk " & $aDrives[$i][1] & " [" & Disk_GetName($aDrives[$i][1]) & "]" & "|" & @CRLF
            EndIf
            $aDisks[$iLastDevNumber][1] &= ";   └ " & DriveGetLabel($aDrives[$i][0]) & " - " & "(" & StringUpper($aDrives[$i][0]) & "\ )" & "|"
        EndIf
    Next

    ReDim $aDisks[$iLastDevNumber + 1][2]

    For $i = 0 To UBound($aDisks) - 1
        $sOutput &= $aDisks[$i][0]

        $aSplit = StringRegExp($aDisks[$i][1], "[^;]+", 3)
        _ArraySort($aSplit)

        For $j = 0 To UBound($aSplit) - 1
            $sOutput &= $aSplit[$j]
        Next
        ;$sOutput &= @CRLF
    Next

    Return $sOutput
EndFunc   ;==>GetDiskList

Func DiskList_Selected() ; action when a list item is selected
    Local $i_State = $GUI_ENABLE

    If GUICtrlRead($c_DiskList) = '' Or StringInStr(GUICtrlRead($c_DiskList), "   └ ") Then $i_State = $GUI_DISABLE
    GUICtrlSetState($MBR, $i_State)
    GUICtrlSetState($GPT, $i_State)
EndFunc   ;==>DiskList_Selected

Func GetDriveLetters()
    Local $allDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ", $AvailDriveLetters
    Local $aArray = DriveGetDrive($DT_ALL)
    If @error Then
        ; An error occurred when retrieving the drives.
        MsgBox($MB_SYSTEMMODAL, "", "An Error Occurred! Unable to retrieve " & @CRLF & "available drive letters! Exiting Program...")
        Cleanup()
        Exit
    Else
        For $i = 1 To $aArray[0]
            $driveLetter = StringLeft(StringUpper($aArray[$i]), 1)
            $allDriveLetters = StringReplace($allDriveLetters, $driveLetter, "")
        Next
    EndIf
    $AvailDriveLetters = StringSplit($allDriveLetters, "")
    $bootDrive = $AvailDriveLetters[1] ;Get first available letter
    $mainDrive = $AvailDriveLetters[2] ;Get second available letter
EndFunc   ;==>GetDriveLetters

Func GetWinNTSetupPath()
    Local Static $s_WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\')
    Return $s_WinNTSetupPath
EndFunc   ;==>GetWinNTSetupPath

Func GetCachePath() ; get the path to the cache folder
    Local Static $s_CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache') & '\'
    Return $s_CachePath
EndFunc   ;==>GetCachePath

Func IniWriteMBR()
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":")
EndFunc   ;==>IniWriteMBR

Func IniWriteGPT()
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":")
EndFunc   ;==>IniWriteGPT

Func LaunchWinNTSetup()
    Run('cmd /c ' & '"' & GetWinNTSetupPath() & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE)
EndFunc   ;==>LaunchWinNTSetup

Func Cleanup()
    If FileExists(GetCachePath()) Then
        DirRemove(GetCachePath(), $DIR_REMOVE)
    EndIf
EndFunc   ;==>Cleanup

Func PrepMBR($Drive)
    GetDriveLetters()
    createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive & @CRLF & 'Exit')
EndFunc   ;==>PrepMBR

Func PrepGPT($Drive)
    GetDriveLetters()
    createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac' & @CRLF & 'Exit')
EndFunc   ;==>PrepGPT

Func createDiskPartScriptFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc   ;==>createDiskPartScriptFile

Func FormatMBR()
    GUISetState(@SW_HIDE)
    Local $aArray[6][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _
            ["Converting Layout to MBR", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _
            ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'] _
            ]

    ProgressOn("Formatting Legacy (MBR)...", "Preparing Disk: ", "0%")

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 17 & "%", $aArray[$i][0])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>FormatMBR

Func FormatGPT()
    GUISetState(@SW_HIDE)
    Local $aArray[9][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _
            ["Converting Layout to GPT", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _
            ["Creating System Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatsystem.dat' & '"'], _
            ["Creating MSR Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'createmsr.dat' & '"'], _
            ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'], _
            ["Creating WinRE Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatwinre.dat' & '"'] _
            ]

    ProgressOn("Formatting UEFI (GPT)...", "Preparing Disk: ", "0%")

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 11 & "%", $aArray[$i][0])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>FormatGPT

 

Posted (edited)

Can we add a letter, double letter (or other unique value) as a substitute for the empty space if nothing is found? and then do a replace after?

The reason I ask is, this "working" method that I found isnt actually working 😕

Idk whats going on here but I brought this somewhere to test it today and the disk names are wrong/reversed, this was from before your update i havent tried that yet.. it will be a few hours before I can, in this picture Disk 0 should be PNY and disk 2 should be samsung flash.... 

Capture.PNG

Edited by bobomb
Posted

Alternative way for your getdisklist

  • Iterate once all drives
  • No merging of array
  • No redimming of array
  • Probably no sorting needed
  • Hopefully better understandable and readable as code is shortened
  • You still have to split to make it an array
  • And you have to build your layout of the string to your needs

 

#NoTrayIcon
#requireadmin
#include <StringConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>
 ;  GUICtrlSetData($c_DiskList, "") ; clear previous list info
MsgBox($MB_SYSTEMMODAL, "",getdisklist2())
func getDiskList2()
   Local $aArray = DriveGetDrive($DT_ALL)
   local $strLine

   If @error Then
       ; An error occurred when retrieving the drives.
       MsgBox($MB_SYSTEMMODAL, "", "It appears an error occurred.")
   Else
      For $i = 1 To $aArray[0]
           ; Show all the drives found and convert the drive letter to uppercase.
           $sInfo = DriveGetType($aArray[$i], $DT_DRIVETYPE)  ;"Unknown", "Removable", "Fixed", "Network", "CDROM", "RAMDisk"
           if (stringinstr(stringupper("Removable,Fixed"),stringupper($sInfo))>0) Then
              $strLine=StringUpper($aArray[$i])  & ";"
              $strLine&=$sInfo & ";"

              $aDriveInfo = _WinAPI_GetDriveNumber($aArray[$i])
              If Not @error Then
                  $strLine&=$aDriveInfo[0]&";"       ;[0] - The type of device ($FILE_DEVICE_*). see apifileconstants
                  $strLine&="Disk " & $aDriveInfo[1] &";"          ;[1] - The device number.
                  $strLine&=$aDriveInfo[2] &";"       ;            [2] - The partition number, or (-1) if device cannot be partitioned.
                  $strLine&=Disk_GetName($aDriveInfo[1])& ";"
                  $strLine&=DriveGetLabel($aArray[$i])& ";" & @CRLF
               Else
                  $strLine&="Error" & ";"
                  $strLine&="Error" & ";"
                  $strLine&="Error" & ";"
                  $strLine&="Error" & ";" & @CRLF
               EndIf
            endif
      Next
   EndIf
   return $strLine
EndFunc

Func Disk_GetName($i_DiskNumber)
    Local $s_DiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($i_DiskNumber))
    If @error Then Return SetError(1, 0, 0)

    Local $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "FriendlyName")
    If $s_DiskName = "" Then $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "DeviceDesc")

    Return $s_DiskName
EndFunc   ;==>Disk_GetName
Posted (edited)

With this I get the following arraydisplay and msg window, but it only displays the I: usb I have plugged in... and the loop ends...

I am looking at a WMIC to sort the correct disk label, since that is the only issue, it may be easier to focus on that...

wmic diskdrive get index,model

==> returns ==>

Index  Model
2      Samsung Flash Drive USB Device
0      Samsung SSD 860 EVO 1TB
1      Samsung SSD 970 PRO 512GB

 

Screenshot 2021-12-14 181813.png

Screenshot 2021-12-14 181752.png

Edited by bobomb
Posted (edited)

How would I go about converting the output of this into an array?

#NoTrayIcon
#RequireAdmin
#include <AutoItConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

$wmicdata = Run('cmd /c wmic diskdrive get index,model', @WorkingDir, @SW_HIDE, 2)
ProcessWaitClose($wmicdata)
$line = StdoutRead($wmicdata)
MsgBox($MB_SYSTEMMODAL, "", $line)

Any line that starts with a number contains a disk, on those lines the 1st char is always the disk# (or 1st AND  2nd 10 or more disks) the 8th char is always the start of the label even if there is a 2 digit disk #.. I can manually make an array by hardcoding it but idk how to parse stdout output into one...

Screenshot 2021-12-14 190851.png

 

EDIT* -->  I made this function to get the friendly name based on the disk number through WMIC and I dont need to create a temp file because I can use the STDout i was shown ;)

#NoTrayIcon
#RequireAdmin
#include <AutoItConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

$ForThisDiskNumber = 0

MsgBox($MB_SYSTEMMODAL, "", Disk_GetName($ForThisDiskNumber))

Func Disk_GetName($Disk)
    Local $pre_name = ""
    $wmicdata = Run('cmd /c wmic diskdrive ' & $Disk & ' get model', @WorkingDir, @SW_HIDE, 2)
    ProcessWaitClose($wmicdata)
    $pre_name = _StringExplode(StdoutRead($wmicdata), @LF)
    $d_name = StringStripWS($pre_name[1], $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
    Return $d_name
EndFunc   ;==>Disk_GetName

You send it the disk # and it sends you back the name of the disk.. 😜 awesome.. 

Edited by bobomb
Posted (edited)

Tested the new function and it is getting the name correctly, even for the dual dock, no more mixups. @junkew I will look at the direct call tonight when I get some time that seems easier once understood.

All below are displaying correctly and an example of what a 2 drive dock would look like in the list with both disk slots used. Ill edit this and update the full code when I get back to that workstation...

Capture.PNG

Capture2.PNG

#NoTrayIcon
#RequireAdmin
#include <StringConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $DiskList = 0
Global $MBR = 0
Global $GPT = 0
Global $bootDrive = ""
Global $mainDrive = ""

Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

Func MainMenu()
    GUICreate('Prep/Format Disk v2.0', 300, 289)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")

    GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1)
    GUISetBkColor(0x797979)
    GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
    $DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT))
    GUICtrlSetData(-1, GetDiskList())
    GUICtrlSetOnEvent(-1, "DiskList_Selected")
    $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)

    GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
    $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 234, 120, 40)
    GUICtrlSetOnEvent(-1, "MBRPressed")
    GUICtrlSetState(-1, $GUI_DISABLE)
    $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 234, 120, 40)
    GUICtrlSetOnEvent(-1, "GPTPressed")
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

    ; Just idle around
    While 1
        Sleep(10)
    WEnd

EndFunc   ;==>MainMenu

Func RefreshPressed()
    GUICtrlSetData($DiskList, "")
    GUICtrlSetData($DiskList, GetDiskList())
    DiskList_Selected()
EndFunc   ;==>RefreshPressed

Func MBRPressed()
    Local $s_DiskNumber = StringRegExp(GUICtrlRead($DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0]

    If @error Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "An error occured retrieving the disk number")
    Else
        If MsgBox( _
                BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _
                'This will FORMAT Disk ' & $s_DiskNumber, _
                'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then
            PrepMBR($s_DiskNumber)
            FormatMBR()
            IniWriteMBR()
            MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
            LaunchWinNTSetup()
            Cleanup()
            Exit
        EndIf
    EndIf
EndFunc   ;==>MBRPressed

Func GPTPressed()
    Local $s_DiskNumber = StringRegExp(GUICtrlRead($DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0]

    If @error Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "An error occured retrieving the disk number")
    Else
        If MsgBox( _
                BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _
                'This will FORMAT Disk ' & $s_DiskNumber, _
                'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then
            PrepGPT($s_DiskNumber)
            FormatGPT()
            IniWriteGPT()
            MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
            LaunchWinNTSetup()
            Cleanup()
            Exit
        EndIf
    EndIf
EndFunc   ;==>GPTPressed

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            Exit
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ; Code below for actions on Minimize
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ; Code below for actions on Restore
    EndSelect
EndFunc   ;==>SpecialEvents

Func Disk_GetName($Disk)
    Local $pre_name = ""
    $wmicdata = Run('cmd /c wmic diskdrive ' & $Disk & ' get model', @WorkingDir, @SW_HIDE, 2)
    ProcessWaitClose($wmicdata)
    $pre_name = _StringExplode(StdoutRead($wmicdata), @LF)
    $d_name = StringStripWS($pre_name[1], $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
    Return $d_name
EndFunc   ;==>Disk_GetName

Func GetDiskList()
    Local $aDriveInfo, $iLastDevNumber = -1
    Local $aFixed = DriveGetDrive('FIXED'), $aRemovable = DriveGetDrive('REMOVABLE')
    Local $aDrives[(IsArray($aFixed) ? $aFixed[0] : 0) + (IsArray($aRemovable) ? $aRemovable[0] : 0)][3]

    Local $iDrive = 0
    GUICtrlSetData($DiskList, "") ; clear previous list info
    For $i = 1 To UBound($aFixed) - 1
        $aDrives[$iDrive][0] = $aFixed[$i]
        $aDriveInfo = _WinAPI_GetDriveNumber($aFixed[$i])
        If Not @error Then
            $aDrives[$iDrive][1] = $aDriveInfo[1]
            $aDrives[$iDrive][2] = $aDriveInfo[2]
        EndIf
        $iDrive += 1
    Next
    For $i = 1 To UBound($aRemovable) - 1
        $aDrives[$iDrive][0] = $aRemovable[$i]
        $aDriveInfo = _WinAPI_GetDriveNumber($aRemovable[$i])
        If Not @error Then
            $aDrives[$iDrive][1] = $aDriveInfo[1]
            $aDrives[$iDrive][2] = $aDriveInfo[2]
        EndIf
        $iDrive += 1
    Next

    _ArraySort($aDrives, 0, 0, 0, 1)
    Local $aDisks[UBound($aDrives)][2]
    Local $DiskListOutput = ""

    For $i = 0 To UBound($aDrives) - 1
        If IsNumber($aDrives[$i][1]) Then
            If $aDrives[$i][1] <> $iLastDevNumber Then
                $iLastDevNumber = $aDrives[$i][1]
                $aDisks[$iLastDevNumber][0] = " Disk " & $aDrives[$i][1] & " [" & Disk_GetName($aDrives[$i][1]) & "]" & "|" & @CRLF
            EndIf
            $aDisks[$iLastDevNumber][1] &= ";   └ " & DriveGetLabel($aDrives[$i][0]) & " - " & "(" & StringUpper($aDrives[$i][0]) & "\ )" & "|"
        EndIf
    Next
    ReDim $aDisks[$iLastDevNumber + 1][2]

    For $i = 0 To UBound($aDisks) - 1
        $DiskListOutput &= $aDisks[$i][0]

        $aSplit = StringRegExp($aDisks[$i][1], "[^;]+", 3)
        _ArraySort($aSplit)
        For $j = 0 To UBound($aSplit) - 1
            $DiskListOutput &= $aSplit[$j]
        Next
    Next


    Return $DiskListOutput
EndFunc   ;==>GetDiskList

Func DiskList_Selected() ; action when a list item is selected
    Local $i_State = $GUI_ENABLE

    If GUICtrlRead($DiskList) = '' Or StringInStr(GUICtrlRead($DiskList), "   └ ") Then $i_State = $GUI_DISABLE
    GUICtrlSetState($MBR, $i_State)
    GUICtrlSetState($GPT, $i_State)
EndFunc   ;==>DiskList_Selected

Func GetDriveLetters()
    Local $allDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ", $AvailDriveLetters
    Local $aArray = DriveGetDrive($DT_ALL)
    If @error Then
        ; An error occurred when retrieving the drives.
        MsgBox($MB_SYSTEMMODAL, "", "An Error Occurred! Unable to retrieve " & @CRLF & "available drive letters! Exiting Program...")
        Cleanup()
        Exit
    Else
        For $i = 1 To $aArray[0]
            $driveLetter = StringLeft(StringUpper($aArray[$i]), 1)
            $allDriveLetters = StringReplace($allDriveLetters, $driveLetter, "")
        Next
    EndIf
    $AvailDriveLetters = StringSplit($allDriveLetters, "")
    $bootDrive = $AvailDriveLetters[1] ;Get first available letter
    $mainDrive = $AvailDriveLetters[2] ;Get second available letter
EndFunc   ;==>GetDriveLetters

Func GetWinNTSetupPath()
    Local Static $s_WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\')
    Return $s_WinNTSetupPath
EndFunc   ;==>GetWinNTSetupPath

Func GetCachePath() ; get the path to the cache folder
    Local Static $s_CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache') & '\'
    Return $s_CachePath
EndFunc   ;==>GetCachePath

Func IniWriteMBR()
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":")
EndFunc   ;==>IniWriteMBR

Func IniWriteGPT()
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":")
    IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":")
EndFunc   ;==>IniWriteGPT

Func LaunchWinNTSetup()
    Run('cmd /c ' & '"' & GetWinNTSetupPath() & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE)
EndFunc   ;==>LaunchWinNTSetup

Func Cleanup()
    If FileExists(GetCachePath()) Then
        DirRemove(GetCachePath(), $DIR_REMOVE)
    EndIf
EndFunc   ;==>Cleanup

Func PrepMBR($Drive)
    GetDriveLetters()
    createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive & @CRLF & 'Exit')
EndFunc   ;==>PrepMBR

Func PrepGPT($Drive)
    GetDriveLetters()
    createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16' & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive & @CRLF & 'Exit')
    createDiskPartScriptFile(GetCachePath() & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac' & @CRLF & 'Exit')
EndFunc   ;==>PrepGPT

Func createDiskPartScriptFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc   ;==>createDiskPartScriptFile

Func FormatMBR()
    GUISetState(@SW_HIDE)
    Local $aArray[6][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _
            ["Converting Layout to MBR", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _
            ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'] _
            ]

    ProgressOn("Formatting Legacy (MBR)...", "Preparing Disk: ", "0%")

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 17 & "%", $aArray[$i][0])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>FormatMBR

Func FormatGPT()
    GUISetState(@SW_HIDE)
    Local $aArray[9][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _
            ["Converting Layout to GPT", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _
            ["Creating System Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatsystem.dat' & '"'], _
            ["Creating MSR Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'createmsr.dat' & '"'], _
            ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'], _
            ["Creating WinRE Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatwinre.dat' & '"'] _
            ]

    ProgressOn("Formatting UEFI (GPT)...", "Preparing Disk: ", "0%")

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 11 & "%", $aArray[$i][0])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>FormatGPT

 

Edited by bobomb
added fully working code shown in pics
Posted (edited)

Ok so fortunately/unfortunately I found another bug in this script, i think it will be my last hurdle other than cleaning up/error checking and GUI...

When a disk is not initialized I cannot see it in the list (e.g. if you use diskpart "clean" on a disk it will be uninitialized afterwards until you create partitions/format it OR if a disk is brand new out of the box)

Diskpart sees all connected disks regardless of their state..

Has anyone used the method from the previous post and was able to see uninitialized disks before? (DriveGetDrive) Or with WMIC? I dont see a way other than to generate a diskpart array..

Edited by bobomb
Posted (edited)

I know this looks horrible but im just testing output..

should something like this work to clean and rebuild an array scraped from STdout? 

Disk_GetIndexList()

Func Disk_GetIndexList() ; Get Clean Disk List Index Array
    Local $aArray = ""
    $wmicdata = Run('cmd /c wmic diskdrive get index', @WorkingDir, @SW_HIDE, 2)
    ProcessWaitClose($wmicdata)
    $pre_name = _StringExplode(StdoutRead($wmicdata), @LF)
    For $i = 0 To UBound($pre_name) - 1 ; $i is automatically created and is set to zero, UBound($aArray) returns the no. of elements in the $aArray.
        If Not $pre_name[$i] = "" Or $pre_name[$i] = "Index" Then $aArray &= $pre_name[$i]
    Next
    _ArrayDisplay($aArray)
EndFunc   ;==>Disk_GetIndex

I am trying to clean up this output

C:\Users\Bob.Omb>wmic diskdrive get index
Index
0
1
2

And this is what is produced in the "$pre_name" var

 

Screenshot 2021-12-15 200812.png

Edited by bobomb
Posted

Try this

#include <array.au3>
#include <Constants.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>

Local $as_Indexes = Disk_GetIndexList()

If IsArray($as_Indexes) Then
    _ArrayDisplay($as_Indexes)
Else
    MsgBox($MB_ICONERROR, 'Error', $as_Indexes)
EndIf

Func Disk_GetIndexList() ; Get Clean Disk List Index Array
    Local $i_Pid = Run('cmd /c wmic diskdrive get index', @WorkingDir, @SW_HIDE, $STDERR_MERGED)
    ProcessWaitClose($i_Pid)

    Local $as_Indexes = StringSplit(StringStripWS(StdoutRead($i_Pid), $STR_STRIPTRAILING), @LF)

    If IsArray($as_Indexes) Then
        If StringInStr($as_Indexes[1], 'Index', $STR_NOCASESENSE) Then
            Return $as_Indexes
        Else ; assumes errors occured
            Return SetError(1, @extended, $as_Indexes[3])
        EndIf
    Else ; an error occured reading the stdout
        Return SetError(2, @extended, 'Unable to read wmic output stream')
    EndIf
EndFunc   ;==>Disk_GetIndexList

 

Posted (edited)

I want that array without the string "Index", i was going to use a loop to clean it unless there is a better way?

It will be used as a clean array to pass through the current list assignment loop in place of the existing DiskGetDisk.. on the disk numbers where it retrieves no information like uninitialized or new disks, it will only show the disk number and the disk model, the other disks will also show partitions, but the ones this loop gets that the others miss will not.. but at least they will show up... in the end the only thing that matters is the disk number and the user being able to identify that disk 0 is their PNY ssd or that disk 1 is their samsung etc.. if they have several identical disks plugged in ill leave that to them to check closer.. i think thats a fair midpoint... this whole thing is probably gonna save someone 5mins time ;) 

Edited by bobomb
Posted

Changed a bit

Func Disk_GetIndexList() ; Get Clean Disk List Index Array
    Local $i_Pid = Run('cmd /c wmic diskdrive get index', @WorkingDir, @SW_HIDE, $STDERR_MERGED)
    ProcessWaitClose($i_Pid)

    Local $as_Indexes = StringSplit(StringStripWS(StringReplace(StdoutRead($i_Pid), 'Index', '', 0, $STR_NOCASESENSE), BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING)), @LF)

    If IsArray($as_Indexes) Then
        If $as_Indexes[0] = 3 And StringInStr($as_Indexes[2], 'ERROR', $STR_NOCASESENSE) Then Return SetError(1, @extended, $as_Indexes[3]) ; assume there's been an error
        Return $as_Indexes
    Else ; an error occured reading the stdout
        Return SetError(2, @extended, 'Unable to read wmic output stream')
    EndIf
EndFunc   ;==>Disk_GetIndexList

 

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...