Jump to content

USB Burning tool for PE projects - (Progress Bar options, and disk list)


bobomb
 Share

Go to solution Solved by benners,

Recommended Posts

No, the disks display correctly like that but then we are back to the drive letters being reversed for the partitions lol.  Can you adapt the code I posted easily?  I was trying to get it to sort in every way i could possibly think of and the code i posted with my last codebox is the only way i have seen it display correctly so far...

Link to comment
Share on other sites

Ok, this must be it. I have left the arraydisplay in so you can uncomment and see if it's sorted. I'll have a look at the other code if you're not happy with this. There's another function to sort on two columns as well

Func DiskList_Load() ; load the list control with enumerated drives
    Local $as_Fixed = DriveGetDrive('FIXED')

    If IsArray($as_Fixed) Then
        Local $as_Removable = DriveGetDrive('REMOVABLE')

        ; join the two array to just make one loop through for the drives
        If IsArray($as_Removable) Then $as_Fixed[0] = _ArrayConcatenate($as_Fixed, $as_Removable, 1) - 1

        GUICtrlSetData($c_DiskList, "") ; clear previous list info

        Local _
                $i_DeviceNumber = 0, _
                $i_LastDeviceNumber = -1

        ; create a new 2D array for the device numbers
        Local $as_DriveInfo[$as_Fixed[0] + 1][2] = [[$as_Fixed[0], 0]]

        ; loop through the drive letter array, add the letter and the device number to the new array
        For $i = 1 To $as_Fixed[0]
            $as_DriveInfo[$i][0] = $as_Fixed[$i]
            $as_DriveInfo[$i][1] = _WinAPI_GetDriveNumber($as_Fixed[$i])[1]
        Next

        Local $ai_Columns[2] = [1,0]

        ; sort the array by device number and then drive letter
        _ArraySort_MultiColumn($as_DriveInfo, $ai_Columns, 0, 0, 1)
;~      _ArrayDisplay($as_DriveInfo)

        For $i = 1 To $as_DriveInfo[0][0] ; loop through the fixed drives
            ; get the drive number and device name
            If $as_DriveInfo[$i][1] <> $i_LastDeviceNumber Then ; add the device name to the list
                GUICtrlSetData($c_DiskList, 'Disk ' & $as_DriveInfo[$i][1] & ' [' & Disk_GetName($as_DriveInfo[$i][1]) & ']')
                $i_LastDeviceNumber = $as_DriveInfo[$i][1]
            EndIf

            ; add the partition info to the list
            GUICtrlSetData($c_DiskList, "   └ " & DriveGetLabel($as_DriveInfo[$i][0]) & " - " & "(" & StringUpper($as_DriveInfo[$i][0]) & "\ )")
        Next
    EndIf
EndFunc   ;==>DiskList_Load

; #FUNCTION# =============================================================================
; Name.............:    _ArraySort_MultiColumn
; Description ...:      sorts an array at given colums (multi colum sort)
; Syntax...........:    _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices)
; Parameters ...:       $aSort - array to sort
;                       $aIndices - array with colum indices which should be sorted in specified order - zero based
;                       $oDir/$iDir - sort direction - if set to 1, sort descending else ascending. $oDir is for the 1st row,
;                                                     $iDir for the remaining rows
;                       $iStart - where to start to sort - 0 = 0 based array, 1 = 1 based array
; Author .........:     UEZ
; Version ........:     v0.80 build 2019-01-26 Beta
; Link............:     https://www.autoitscript.com/forum/topic/197521-sort-arrays-on-multiple-columns/
; =========================================================================================
Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0, $iStart = 0)
    If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array
    If UBound($aSort, 2) = 0 Then Return SetError(4, 0, 0) ;array is 1D only
    If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array
    Local $1st, $2nd, $x, $j, $k, $l = 0
    For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense
        If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric
    Next
    $iStart = Int($iStart) < 0 ? 0 : Int($iStart) > 1 ? 1 : Int($iStart)
    If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) ;check if only one index is given
    _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0])
    Do
        $1st = $aIndices[$l]
        $2nd = $aIndices[$l + 1]
        $j = 0
        $k = 1
        While $k < UBound($aSort)
            If $aSort[$j][$1st] <> $aSort[$k][$1st] Then
                If $k - $j > 1 Then
                    _ArraySort($aSort, $iDir, $j, $k - 1, $2nd)
                    $j = $k
                Else
                    $j = $k
                EndIf
            EndIf
            $k += 1
        WEnd
        If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd)
        $l += 1
    Until $l = UBound($aIndices) - 1
    Return 1
EndFunc   ;==>_ArraySort_MultiColumn

 

Link to comment
Share on other sites

Aaaaaannnd WORKS PERFECT! 

The only downside to this way is that I have no idea what is happening here can you explain this to me please?

You joined the (drive numbers) and (partition names/drive letters) to the same 3d array and the new function sorts both columns alphabetically independent of eachother?

 

Screenshot 2021-12-12 155131.png

Edited by bobomb
Link to comment
Share on other sites

  • Solution

.....And that's what the functions does. I have probably been talking to myself for 20 minutes 😅 so here is the function with lots of comments. I think a treeview would be better than a list but it's a simple gui and maybe overkill for the amount of drives there will most likely be.

Func DiskList_Load() ; load the list control with enumerated drives
    ; here we get the list of fixed drive on the system. It returns an array if OK
    Local $as_Fixed = DriveGetDrive('FIXED')

    ; here we check if $as_Fixed is an array before actioning it
    If IsArray($as_Fixed) Then
        ; here we get a list of removable drive
        Local $as_Removable = DriveGetDrive('REMOVABLE')

        ; here we check if $as_Removable is an array. On my VM machine it returns an error as
        ; there are no removable drives so we need to check before we join the two arrays.
        ; This is important because we use the return from _ArrayConcatenate to update the element count
        ; in the as_Fixed array
        If IsArray($as_Removable) Then $as_Fixed[0] = _ArrayConcatenate($as_Fixed, $as_Removable, 1) - 1

        GUICtrlSetData($c_DiskList, "") ; clear previous list info

        ; declare and initialise our variables
        Local _
                $i_DeviceNumber = 0, _ ; set the device number to 0 as it is most theres a 0 disk
                $i_LastDeviceNumber = -1 ; set the value to -1 so it doesn't conflict with any disk numbers

        ; create a new 2D array for the device numbers. This has columns for the drive letter [0]
        ; and the device number [1], with enough elements for all the drives in the $as_Fixed array
        ; we add an extra row for the array count, I prefer this over using ubound if I am creating the arrays
        Local $as_DriveInfo[$as_Fixed[0] + 1][2] = [[$as_Fixed[0], 0]]

        ; here we loop through the drive letter array, add the letter to column 0
        ; and the device number to column 1 of the array. We only need the device number
        ; so when we call _WinAPI_GetDriveNumber, we can add the array element we want onto the end
        ; and it will return that. Fuck knows how that works, but it does, and it's useful
        For $i = 1 To $as_Fixed[0]
            $as_DriveInfo[$i][0] = $as_Fixed[$i]
            $as_DriveInfo[$i][1] = _WinAPI_GetDriveNumber($as_Fixed[$i])[1]
        Next

        ; here we create a new array and add the numbers of the columns we want to sort the
        ; array on. We use UEZ's brilliant function and this requires an array
        ; we want to sort first by the device number, then by drive letter so we add 1 and 0
        Local $ai_Columns[2] = [1, 0]

        ; sort the array by device number and then drive letter and sort both columns ascending
        ; let the function know we are using a 1 based array
        _ArraySort_MultiColumn($as_DriveInfo, $ai_Columns, 0, 0, 1)

        ; here we loop through the full 2D array containing the fixed drives and device numbers
        For $i = 1 To $as_DriveInfo[0][0]
            ; here we check if we are working on a different device number
            ; this is because there could be multiple volumes on a single disk
            ; we set the start number as -1 so it will always be different on first run
            ; if the device number is the same, this part is skipped
            If $as_DriveInfo[$i][1] <> $i_LastDeviceNumber Then
                ; here we are updating the list with the disk number and friendly name
                GUICtrlSetData($c_DiskList, 'Disk ' & $as_DriveInfo[$i][1] & ' [' & Disk_GetName($as_DriveInfo[$i][1]) & ']')
                ; here we set the current device number we are working on
                $i_LastDeviceNumber = $as_DriveInfo[$i][1]
            EndIf

            ; here we add the volume info, this is the label and the letter changed to upper case
            GUICtrlSetData($c_DiskList, "   └ " & DriveGetLabel($as_DriveInfo[$i][0]) & " - " & "(" & StringUpper($as_DriveInfo[$i][0]) & "\ )")
            ; here we then continue the loop and look at the next row in the array
        Next
    EndIf
EndFunc   ;==>DiskList_Load

 

Edited by benners
Link to comment
Share on other sites

No problem. There are still a few improvements you could make like in Format_Run where text is repeated that could be changed, and the whole copy files thing with progress and label updating.

Instead of individual files, can the diskpart bit not be done in one file, or does it mong out. Think you've mentioned it before which is why the sleep in the format loop.

Link to comment
Share on other sites

Yea it sometimes errors on certain disks when combined into a single diskpart script, depending on the scenario and unfortunately the process i am using is required, although not recommended (15 seconds between scripts is the rule) it works flawlessly (so far)...

EDIT: The above script was found to have bugs in the disk list section, trying to figure out whats wrong, here is a working version in the meantime

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

Global $DiskList = 0
Global $BurnBtn = 0
Global $bootDrive = ""
Global $dataDrive = ""

Opt("GUIOnEventMode", 1)

ISO_CheckWasDropped()
ISO_Mount()
Global $s_MountedDrive = ISO_GetDriveLetter()
BootWim_Check()
Cleanup()

DirCreate(GetCachePath())

MainMenu()

Func BootWim_Check() ; check for the boot wim file
    If Not FileExists($s_MountedDrive & 'sources\boot.wim') Then
        MsgBox($MB_ICONERROR, "Notice: ", "BOOT.WIM NOT DETECTED!!!" & @CRLF & "This tool is designed for SE" & @CRLF & "and XPE projects only.")
        ISO_Unmount()
        Exit
    EndIf
EndFunc   ;==>BootWim_Check

Func BootWim_GetSize() ; get the boot wim size and add 200 megabytes for headroom on boot partition
    Return Round((FileGetSize($s_MountedDrive & 'sources\boot.wim') + 209715200) / 1048576)
EndFunc   ;==>BootWim_GetSize

Func BurnPressed()
    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
            GUISetState(@SW_HIDE)
            ProgressOn("BurnTool (XPE/SE) v2.0", "Creating Bootable Media...", "0%")
            Format_Prepare($s_DiskNumber)
            ProgressSet(5 & "%", "Formatting Disk " & $s_DiskNumber)
            Format_Run()
            ProgressSet(25 & "%", "Analyzing ISO Structure ")
            CleanDirList()
            CleanFileList()
            ProgressSet(26 & "%", "Copying Boot Partition ")
            CopyBootFiles()
            ;Progress in function; start at 55%
            CopyDataFilesF()
            ;Progress in function; start at 65%
            CopyDataFilesD()
            ProgressSet(100, "Finished", "ISO Applied!!")
            Sleep(2750)
            ProgressOff()
            Cleanup()
            ISO_Unmount()
            MsgBox($MB_ICONINFORMATION, "", " Enjoy! ")
            Exit
        EndIf
    EndIf
EndFunc   ;==>BurnPressed

Func CleanDirList() ; setting GetCachePath() as the working directory so dir path needed for the files
    RunWait(@ComSpec & ' /c DIR /B /A:D ' & $s_MountedDrive & ' > isod.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"efi" /C:"boot" /C:"sources" isod.dat > ' & FinalDirs_GetName(), GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanDirList

Func CleanFileList() ; setting GetCachePath() as the working directory so need dir path needed for the files
    RunWait(@ComSpec & ' /c DIR /B /A-D ' & $s_MountedDrive & ' > isof.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"bootmgr" /C:"menu" isof.dat > ' & FinalFiles_GetName(), GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanFileList

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

Func CopyBootFiles()
    ProgressSet(27 & "%", "Copying Boot Partition ")
    RunWait(@ComSpec & ' /c xcopy ' & $s_MountedDrive & 'BOOT ' & $bootDrive & ':\BOOT /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)

    RunWait('cmd /c xcopy ' & $s_MountedDrive & 'EFI ' & $bootDrive & ':\EFI /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(40 & "%", "Copying Boot.wim, this may take a while... ")

    RunWait('cmd /c xcopy ' & $s_MountedDrive & 'sources ' & $bootDrive & ':\sources /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(50 & "%", "Copying Boot Files ")

    If FileExists($s_MountedDrive & "BOOTMGR.") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'BOOTMGR. ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "bootmgr.efi") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'bootmgr.efi ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "bootmgr.exe") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'bootmgr.exe ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "menu.lst") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'menu.lst ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CopyBootFiles

Func CopyDataFilesD()
    Local $GoFiles = (GetCachePath() & FinalDirs_GetName()), $StartProgAt, $xcopycmd, $line = ""
    FileOpen($GoFiles, 0)
    Local $aArray[1000]
    ReDim $aArray[_FileCountLines($GoFiles) + 1]
    For $i = 1 To _FileCountLines($GoFiles)
        $newline = FileReadLine($GoFiles, $i)
        $aArray[$i] = $newline
    Next

    _ArraySort($aArray)
    $StartProgAt = 65

    For $i = 1 To UBound($aArray) - 1
        If $aArray[$i] = "Programs" Then
            ProgressSet($StartProgAt & "%", "Copying Programs Folder, this may take a while...")
            RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & $aArray[$i] & ' /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
            $StartProgAt = ($StartProgAt + 15)
        Else
            ProgressSet($StartProgAt & "%", "Copying " & $aArray[$i] & " Folder")
            RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & $aArray[$i] & ' /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
            $StartProgAt = ($StartProgAt + 1)
        EndIf
    Next
EndFunc   ;==>CopyDataFilesD

Func CopyDataFilesF()
    Local $GoFiles = (GetCachePath() & FinalFiles_GetName()), $StartProgAt, $xcopycmd, $line = ""
    FileOpen($GoFiles, 0)
    Local $aArray[1000]
    ReDim $aArray[_FileCountLines($GoFiles) + 1]
    For $i = 1 To _FileCountLines($GoFiles)
        $newline = FileReadLine($GoFiles, $i)
        $aArray[$i] = $newline
    Next

    _ArraySort($aArray)
    $StartProgAt = 55
    For $i = 1 To UBound($aArray) - 1
        ProgressSet($StartProgAt & "%", "Copying " & $aArray[$i])
        RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & ' /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
        $StartProgAt = ($StartProgAt + 1)
    Next
EndFunc   ;==>CopyDataFilesF

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
    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($BurnBtn, $i_State)
EndFunc   ;==>DiskList_Selected

Func Diskpart_CreateScriptFile($s_File, $s_Data)
    Local $CacheFile = FileOpen(GetCachePath() & $s_File, 2)
    FileWrite($CacheFile, $s_Data)
    FileClose($CacheFile)
EndFunc   ;==>Diskpart_CreateScriptFile

Func FinalDirs_GetName() ; get the name for the final dirs to copy
    Return 'isodirs.dat'
EndFunc   ;==>FinalDirs_GetName

Func FinalFiles_GetName() ; get the names of the final files to copy
    Return 'isofiles.dat'
EndFunc   ;==>FinalFiles_GetName

Func Format_Prepare($s_Drive)
    GetDriveLetters()
    Diskpart_CreateScriptFile('clean.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('attrib.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('scrubber.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=scrubber' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('convert.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('initdata.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=' & BootWim_GetSize() & @CRLF & 'format quick fs=ntfs label="WinPE Data"' & @CRLF & 'assign letter=' & $dataDrive & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('initboot.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=fat32 label="BOOTFILES"' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Active' & @CRLF & 'Exit')
EndFunc   ;==>Format_Prepare

Func Format_Run()
    Local $aArray[7][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 Data Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'initdata.dat' & '"'], _
            ["Creating Boot Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'initboot.dat' & '"'] _
            ]

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 2 & "%", $aArray[$i][0])
;~         ConsoleWrite('cmd: ' & $aArray[$i][1] & @CRLF)
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next
EndFunc   ;==>Format_Run

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

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()
        ISO_Unmount()
        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
    $dataDrive = $AvailDriveLetters[2] ; Get second available letter
;~  ConsoleWrite('boot drive: ' & $bootDrive & @CRLF)
;~  ConsoleWrite('data drive: ' & $dataDrive & @CRLF)
EndFunc   ;==>GetDriveLetters

Func ISO_CheckWasDropped() ; check that an iso was dropped on to the exe
    If $CmdLine[0] = 0 Then ; no file was dropped or passed via the command line
        MsgBox( _
                $MB_ICONERROR, _
                "Attention: ", _
                "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto the program to begin...")
        Exit
    EndIf
EndFunc   ;==>ISO_CheckWasDropped

Func ISO_GetDriveLetter() ; get the drive letter of the mounted iso
;~  Local $s_MarkerFile = 'CdUsb.Y'
    Local $s_MarkerFile = 'BOOTMGR'
    Local $s_IsoDrive = ''

    Local $as_CDROM = DriveGetDrive($DT_CDROM)

    For $i = 1 To $as_CDROM[0]
        If FileExists($as_CDROM[$i] & '\' & $s_MarkerFile) Then
            If Not _WinAPI_IsWritable($as_CDROM[$i]) Then $s_IsoDrive = $as_CDROM[$i] & '\'
        EndIf
    Next

    If $s_IsoDrive = "" Then
        MsgBox( _
                $MB_ICONERROR, _
                "Attention: ", _
                $s_MarkerFile & " NOT DETECTED!!!" & @CRLF & "This tool is designed for SE" & @CRLF & "and XPE projects only.")

        Exit
    EndIf

    Return $s_IsoDrive
EndFunc   ;==>ISO_GetDriveLetter

Func ISO_Mount() ; mount the droppped iso
    RunWait('cmd /c powershell.exe ' & '"Mount-DiskImage "' & '"' & $CmdLine[1] & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>ISO_Mount

Func ISO_Unmount() ; unmount the dropped iso
    RunWait('cmd /c powershell.exe ' & '"Dismount-DiskImage "' & '"' & $CmdLine[1] & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>ISO_Unmount

Func MainMenu() ; draw the gui
    GUICreate('BurnTool (XPE/SE) v2.0', 300, 287)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")
    GUISetIcon(@WorkingDir & '\USBTool.ico', 1)
    GUISetBkColor(0x797979)
    GUICtrlCreateLabel('Select a disk to use...', 20, 10, 280)
    $DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT))
    GUICtrlSetData(-1, GetDiskList())
    GUICtrlSetOnEvent(-1, "DiskList_Selected")
    GUICtrlCreateButton('Refresh List', 110, 187, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)
    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)
    $BurnBtn = GUICtrlCreateButton('Burn', 90, 232, 120, 40)
    GUICtrlSetOnEvent(-1, "BurnPressed")
    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 SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            ISO_Unmount()
            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

 

Edited by bobomb
Link to comment
Share on other sites

  • bobomb changed the title to USB Burning tool for PE projects - (Progress Bar options, and disk list)

Thank you to @benners, for making this awesome DiskList_GetDrives function for GUICtrlCreateTreeView, that is almost as awesome as she is lol..🤩 and sharing it with all of us.. Excellent work my friend.

Below is the updated BurnTool

This has been put through thorough testing over the last few days in as many scenarios as I could dream up. It seems extremely solid. I hope this source helps others learn as I have. 

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

Global $c_DiskList = 0
Global $BurnBtn = 0
Global $bootDrive = ""
Global $dataDrive = ""

Opt("GUIOnEventMode", 1)

ISO_CheckWasDropped()
ISO_Mount()
Global $s_MountedDrive = ISO_GetDriveLetter()
BootWim_Check()
Cleanup(False)

DirCreate(GetCachePath())

MainMenu()

Func BootWim_Check() ; check for the boot wim file
    If Not FileExists($s_MountedDrive & 'sources\boot.wim') Then
        MsgBox($MB_ICONERROR, "Notice: ", "BOOT.WIM NOT DETECTED!!!" & @CRLF & "This tool is designed for SE" & @CRLF & "and XPE projects only.")
        ISO_Unmount()
        Exit
    EndIf
EndFunc   ;==>BootWim_Check

Func BootWim_GetSize() ; get the boot wim size and add 200 megabytes for headroom on boot partition
    Return Round((FileGetSize($s_MountedDrive & 'sources\boot.wim') + 209715200) / 1048576)
EndFunc   ;==>BootWim_GetSize

Func BurnPressed()
    Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList, $GUI_READ_EXTENDED), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)
    If $s_DiskNumber = "" Then
        MsgBox( _
                $MB_ICONERROR, _ ; it is possible to bug the GUI and make the buttons appear by pressing + or - on tree then refresh
                "Attention: ", _
                "No disk is selected!")
        Buttons_Disable()
    Else

        Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList, $GUI_READ_EXTENDED), '(?<=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
                GUISetState(@SW_HIDE)
                ProgressOn("BurnTool (XPE/SE) v2.0", "Creating Bootable Media...", "0%")
                Format_Prepare($s_DiskNumber)
                ProgressSet(5 & "%", "Formatting Disk " & $s_DiskNumber)
                Format_Run()
                ProgressSet(25 & "%", "Analyzing ISO Structure ")
                CleanDirList()
                CleanFileList()
                ProgressSet(26 & "%", "Copying Boot Partition ")
                CopyBootFiles()
                ;Progress in function; start at 55%
                CopyDataFilesF()
                ;Progress in function; start at 65%
                CopyDataFilesD()
                ProgressSet(100, "Finished", "ISO Applied!!")
                Sleep(2750)
                ProgressOff()
                ISO_Unmount()
                Cleanup(False)
                MsgBox($MB_ICONINFORMATION, "", " Enjoy! ")
                Exit
            EndIf
        EndIf
    EndIf
EndFunc   ;==>BurnPressed

Func Buttons_Disable()
    GUICtrlSetState($BurnBtn, $GUI_DISABLE)
EndFunc   ;==>Buttons_Disable

Func Buttons_Enable()
    GUICtrlSetState($BurnBtn, $GUI_ENABLE)
EndFunc   ;==>Buttons_Enable

Func CleanDirList() ; setting GetCachePath() as the working directory so dir path needed for the files
    RunWait(@ComSpec & ' /c DIR /B /A:D ' & $s_MountedDrive & ' > isod.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"efi" /C:"boot" /C:"sources" isod.dat > ' & FinalDirs_GetName(), GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanDirList

Func CleanFileList() ; setting GetCachePath() as the working directory so need dir path needed for the files
    RunWait(@ComSpec & ' /c DIR /B /A-D ' & $s_MountedDrive & ' > isof.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"bootmgr" /C:"menu" isof.dat > ' & FinalFiles_GetName(), GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanFileList

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

Func CopyBootFiles()
    ProgressSet(27 & "%", "Copying Boot Partition ")
    RunWait(@ComSpec & ' /c xcopy ' & $s_MountedDrive & 'BOOT ' & $bootDrive & ':\BOOT /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)

    RunWait('cmd /c xcopy ' & $s_MountedDrive & 'EFI ' & $bootDrive & ':\EFI /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(40 & "%", "Copying Boot.wim, this may take a while... ")

    RunWait('cmd /c xcopy ' & $s_MountedDrive & 'sources ' & $bootDrive & ':\sources /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(50 & "%", "Copying Boot Files ")

    If FileExists($s_MountedDrive & "BOOTMGR.") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'BOOTMGR. ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "bootmgr.efi") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'bootmgr.efi ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "bootmgr.exe") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'bootmgr.exe ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($s_MountedDrive & "menu.lst") Then RunWait('cmd /c xcopy ' & $s_MountedDrive & 'menu.lst ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CopyBootFiles

Func CopyDataFilesD()
    Local $GoFiles = (GetCachePath() & FinalDirs_GetName()), $StartProgAt, $xcopycmd, $line = ""
    FileOpen($GoFiles, 0)
    Local $aArray[1000]
    ReDim $aArray[_FileCountLines($GoFiles) + 1]
    For $i = 1 To _FileCountLines($GoFiles)
        $newline = FileReadLine($GoFiles, $i)
        $aArray[$i] = $newline
    Next

    _ArraySort($aArray)
    $StartProgAt = 65

    For $i = 1 To UBound($aArray) - 1
        If $aArray[$i] = "Programs" Then
            ProgressSet($StartProgAt & "%", "Copying Programs Folder, this may take a while...")
            RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & $aArray[$i] & ' /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
            $StartProgAt = ($StartProgAt + 15)
        Else
            ProgressSet($StartProgAt & "%", "Copying " & $aArray[$i] & " Folder")
            RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & $aArray[$i] & ' /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
            $StartProgAt = ($StartProgAt + 1)
        EndIf
    Next
EndFunc   ;==>CopyDataFilesD

Func CopyDataFilesF()
    Local $GoFiles = (GetCachePath() & FinalFiles_GetName()), $StartProgAt, $xcopycmd, $line = ""
    FileOpen($GoFiles, 0)
    Local $aArray[1000]
    ReDim $aArray[_FileCountLines($GoFiles) + 1]
    For $i = 1 To _FileCountLines($GoFiles)
        $newline = FileReadLine($GoFiles, $i)
        $aArray[$i] = $newline
    Next

    _ArraySort($aArray)
    $StartProgAt = 55
    For $i = 1 To UBound($aArray) - 1
        ProgressSet($StartProgAt & "%", "Copying " & $aArray[$i])
        RunWait('cmd /c xcopy ' & $s_MountedDrive & $aArray[$i] & ' ' & $dataDrive & ':\' & ' /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
        $StartProgAt = ($StartProgAt + 1)
    Next
EndFunc   ;==>CopyDataFilesF

Func Diskpart_CreateScriptFile($s_File, $s_Data)
    Local $CacheFile = FileOpen(GetCachePath() & $s_File, 2)
    FileWrite($CacheFile, $s_Data)
    FileClose($CacheFile)
EndFunc   ;==>Diskpart_CreateScriptFile

Func FinalDirs_GetName() ; get the name for the final dirs to copy
    Return 'isodirs.dat'
EndFunc   ;==>FinalDirs_GetName

Func FinalFiles_GetName() ; get the names of the final files to copy
    Return 'isofiles.dat'
EndFunc   ;==>FinalFiles_GetName

Func Format_Prepare($s_Drive)
    GetDriveLetters()
    Diskpart_CreateScriptFile('clean.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'clean' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('attrib.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('scrubber.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=scrubber' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('convert.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('initdata.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=' & BootWim_GetSize() & @CRLF & 'format quick fs=ntfs label="WinPE Data"' & @CRLF & 'assign letter=' & $dataDrive & @CRLF & 'Exit')
    Diskpart_CreateScriptFile('initboot.dat', 'Sel Dis ' & $s_Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=fat32 label="BOOTFILES"' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Active' & @CRLF & 'Exit')
EndFunc   ;==>Format_Prepare

Func Format_Run()
    Local $aArray[7][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 Data Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'initdata.dat' & '"'], _
            ["Creating Boot Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'initboot.dat' & '"'] _
            ]

    For $i = 0 To UBound($aArray) - 1
        ProgressSet($i * 2 & "%", $aArray[$i][0])
;~         ConsoleWrite('cmd: ' & $aArray[$i][1] & @CRLF)
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next
EndFunc   ;==>Format_Run

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

; #### this is excellent. who did this?
Func DiskList_GetDrives()
    Local Const $WBEMFLAGRETURNIMMEDIATELY = 0x10

    Local Enum _
            $Unknown, _
            $NoRootDirectory, _
            $RemovableDisk, _
            $LocalDisk, _
            $NetworkDrive, _
            $CompactDisk, _
            $RAMDisk

    Local $o_WMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")

    If IsObj($o_WMIService) Then
        Local $s_Query = "SELECT * FROM Win32_DiskDrive"
        Local $o_DiskDrives = $o_WMIService.ExecQuery($s_Query, "WQL", $WBEMFLAGRETURNIMMEDIATELY)

        If IsObj($o_DiskDrives) Then
            Local $o_Partitions = 0
            Local $o_LogicalDisks = 0

            For $o_DiskDrive In $o_DiskDrives
                $h_Parent = GUICtrlCreateTreeViewItem("Disk " & $o_DiskDrive.Index & " [" & $o_DiskDrive.Model & "]", $c_DiskList)
                GUICtrlSetOnEvent(-1, 'Buttons_Enable')
                _GUICtrlTreeView_SetIcon($c_DiskList, $h_Parent, "shell32.dll", 15)

                $s_Query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $o_DiskDrive.DeviceId & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"
                $o_Partitions = $o_WMIService.ExecQuery($s_Query)

                If IsObj($o_Partitions) Then
                    For $o_Partition In $o_Partitions
                        $s_Query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $o_Partition.DeviceId & "'} WHERE AssocClass = Win32_LogicalDiskToPartition"
                        $o_LogicalDisks = $o_WMIService.ExecQuery($s_Query)

                        For $o_LogicalDisk In $o_LogicalDisks
                            If $o_LogicalDisk.drivetype = $RemovableDisk Or $o_LogicalDisk.drivetype = $LocalDisk Then
                                GUICtrlCreateTreeViewItem('(' & $o_LogicalDisk.DeviceId & '\) ' & $o_LogicalDisk.Volumename, $h_Parent)
                                GUICtrlSetOnEvent(-1, 'Buttons_Disable')
                                _GUICtrlTreeView_SetIcon($c_DiskList, -1, "shell32.dll", 7)
                            EndIf
                        Next
                    Next
                Else
                    ; add error info here
                EndIf
            Next
        Else
            ; add error info here
        EndIf
    Else
        ; add error info here
    EndIf
EndFunc   ;==>DiskList_GetDrives

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...")
        ISO_Unmount()
        Cleanup()
    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
    $dataDrive = $AvailDriveLetters[2] ; Get second available letter
;~  ConsoleWrite('boot drive: ' & $bootDrive & @CRLF)
;~  ConsoleWrite('data drive: ' & $dataDrive & @CRLF)
EndFunc   ;==>GetDriveLetters

Func ISO_CheckWasDropped() ; check that an iso was dropped on to the exe
    If $CmdLine[0] = 0 Then ; no file was dropped or passed via the command line
        MsgBox( _
                $MB_ICONERROR, _
                "Attention: ", _
                "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto the program to begin...")
        Exit
    EndIf
EndFunc   ;==>ISO_CheckWasDropped

Func ISO_GetDriveLetter() ; get the drive letter of the mounted iso
;~  Local $s_MarkerFile = 'CdUsb.Y'
    Local $s_MarkerFile = 'BOOTMGR'
    Local $s_IsoDrive = ''

    Local $as_CDROM = DriveGetDrive($DT_CDROM)

    For $i = 1 To $as_CDROM[0]
        If FileExists($as_CDROM[$i] & '\' & $s_MarkerFile) Then
            If Not _WinAPI_IsWritable($as_CDROM[$i]) Then $s_IsoDrive = $as_CDROM[$i] & '\'
        EndIf
    Next

    If $s_IsoDrive = "" Then
        MsgBox( _
                $MB_ICONERROR, _
                "Attention: ", _
                $s_MarkerFile & " NOT DETECTED!!!" & @CRLF & "This tool is designed for XPE" & @CRLF & "and SE projects only.")

        Exit
    EndIf

    Return $s_IsoDrive
EndFunc   ;==>ISO_GetDriveLetter

Func ISO_Mount() ; mount the droppped iso
    RunWait('cmd /c powershell.exe ' & '"Mount-DiskImage "' & '"' & $CmdLine[1] & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>ISO_Mount

Func ISO_Unmount() ; unmount the dropped iso
    RunWait('cmd /c powershell.exe ' & '"Dismount-DiskImage "' & '"' & $CmdLine[1] & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>ISO_Unmount

Func MainMenu() ; draw the gui
    GUICreate('BurnTool (XPE/SE) v2.0', 300, 287)
    GUISetOnEvent($GUI_EVENT_CLOSE, "GUI_Close")

    GUISetIcon(@WorkingDir & '\USBTool.ico', 1)
    GUISetBkColor(0x797979)
    GUICtrlCreateLabel('Select a disk to use...', 20, 10, 280)

    $c_DiskList = GUICtrlCreateTreeView(10, 30, 280, 150)
    DiskList_Load()

    GUICtrlCreateButton('Refresh List', 110, 187, 80, 25)
    GUICtrlSetOnEvent(-1, "DiskList_Load")
    GUICtrlSetState(-1, $GUI_FOCUS)

    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)

    $BurnBtn = GUICtrlCreateButton('Burn', 90, 232, 120, 40)
    GUICtrlSetOnEvent(-1, "BurnPressed")
    GUICtrlSetState(-1, $GUI_DISABLE)

    GUISetState()

    ; Just idle around
    While 1
        Sleep(10)
    WEnd
EndFunc   ;==>MainMenu

Func DiskList_Load()
    _GUICtrlTreeView_BeginUpdate($c_DiskList)
    _GUICtrlTreeView_DeleteAll($c_DiskList)
    DiskList_GetDrives()
    If _GUICtrlTreeView_GetCount($c_DiskList) > 2 Then _GUICtrlTreeView_Sort($c_DiskList)
    _GUICtrlTreeView_Expand($c_DiskList)
    _GUICtrlTreeView_EndUpdate($c_DiskList)
    Buttons_Disable()
EndFunc   ;==>DiskList_Load

Func GUI_Close()
    ISO_Unmount()
    Cleanup()
EndFunc   ;==>GUI_Close

 

Screenshot 2021-12-17 232833.png

Edited by bobomb
Link to comment
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
 Share

  • Recently Browsing   0 members

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