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

Sorted. The issue was with the list styles. By default it is sorted. Just needed the styles changing

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

Global $DiskList, $Selection, $IsoFile, $MountedDrive = ""
Global $finalfiles, $finaldirs, $wimSize, $bootDrive, $dataDrive

ProperUse()
MountIso()
GetISODriveLetter()
BootWim_Check()
Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

Func MainMenu()
    GUICreate('Burn Tool (XPE/SE) v2.0', 300, 298)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")
    GUISetIcon(@WorkingDir & '\USBTool.ico', 1)
    GUISetBkColor(0x797979)
    GUICtrlCreateLabel('1: Select a disk to use...', 20, 10, 280)
    $DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT))
    GUICtrlSetData(-1, GetDiskList())
    $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)
    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)
    $Burn = GUICtrlCreateButton('Burn', 90, 232, 120, 40)
    GUICtrlSetOnEvent(-1, "BurnPressed")
    GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30)
    GUISetState()
    ; Just idle around
    While 1
        Sleep(10)
    WEnd
EndFunc   ;==>MainMenu

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

Func BurnPressed()
    If GUICtrlRead($DiskList) = '' Or StringInStr(GUICtrlRead($DiskList), 'partition') Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "Please select a disk number")
    Else
        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("Applying ISO...", "Creating Bootable Media... ", "0%")
                PrepFormat($s_DiskNumber)
                ProgressSet(5 & "%", "Formatting Disk " & $s_DiskNumber)
                Format()
                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()
                UnmountIso()
                MsgBox($MB_ICONINFORMATION, "", " Enjoy! ")
                Exit
            EndIf
        EndIf
    EndIf
EndFunc   ;==>BurnPressed

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            UnmountIso()
            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 ProperUse()
    If Not ($CmdLine[0]) = 0 Then ;Something was dropped on the EXE file or CLI was used with a flag(s)
        $IsoFile = ($CmdLine[1]) ;Sets $IsoFile var to the full path of whatever was dropped onto the EXE file or the 1st CLI flag that was used
    Else
        MsgBox($MB_ICONERROR, "Notice: ", "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto" & @CRLF & "the program to begin...")
        Exit
    EndIf
EndFunc   ;==>ProperUse


Func BootWim_Check() ; check for the boot wim file
    If Not FileExists($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.")
        UnmountIso()
        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($MountedDrive & ':\sources\boot.wim') + 209715200) / 1048576)
EndFunc   ;==>BootWim_GetSize

Func MountIso()
    RunWait('cmd /c powershell.exe ' & '"Mount-DiskImage "' & '"' & $IsoFile & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>MountIso

Func UnmountIso()
    RunWait('cmd /c powershell.exe ' & '"Dismount-DiskImage "' & '"' & $IsoFile & '"' & '"' & '"' & ' >nul', @WorkingDir, @SW_HIDE)
EndFunc   ;==>UnmountIso

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

Func GetISODriveLetter()
    Local $findiso = StringSplit("CDEFGHIJKLMNOPQRSTUVWXYZ", "", 1)
    For $i = 1 To $findiso[0] Step +1
        $isoExists = FileExists($findiso[$i] & ":\CdUsb.Y")
        If $isoExists Then
            If PathIsWritable($findiso[$i] & ":\") = False Then
                $MountedDrive = ($findiso[$i])
            EndIf
        EndIf
    Next
    If $MountedDrive = "" Then
        MsgBox($MB_ICONERROR, "Notice: ", "CdUsb.Y NOT DETECTED!!!" & @CRLF & "This tool is designed for SE" & @CRLF & "and XPE projects only.")
        Exit
    EndIf
EndFunc   ;==>GetISODriveLetter

Func PathIsWritable($sFile)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', _
            'wstr', $sFile, _
            'dword', 2, _
            'dword', 7, _
            'struct*', 0, _
            'dword', 3, _
            'dword', 0x02000000, _
            'handle', 0)
    If @error Or $aRet[0] = Ptr(-1) Or $aRet[0] = 0 Then Return False
    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $aRet[0])
    Return True
EndFunc   ;==>PathIsWritable

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 $sDrivesInfo, $s_Drives

    For $i = 0 To UBound($aDrives) - 1
        If IsNumber($aDrives[$i][1]) Then
            If $aDrives[$i][1] <> $iLastDevNumber Then
                $sDrivesInfo &= "Disk " & $aDrives[$i][1] & " [" & _GetDiskNameByNumber($aDrives[$i][1]) & "]" & "|" & @CRLF
                $iLastDevNumber = $aDrives[$i][1]
            EndIf

            $sDrivesInfo &= " - Partition #" & $aDrives[$i][2] & "  " & DriveGetLabel($aDrives[$i][0]) & " - " & StringUpper($aDrives[$i][0]) & "|" & @CRLF
        EndIf
    Next


Return $sDrivesInfo
EndFunc   ;==>GetDiskList

Func _GetDiskNameByNumber($iDiskNumber)
    Local $iCount = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", "Count")
    Local $sDiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($iDiskNumber))
    If @error Then Return SetError(1, 0, 0)

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

    Return $sDiskName
EndFunc   ;==>_GetDiskNameByNumber

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

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

Func CopyBootFiles()
    RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOT ' & $bootDrive & ':\BOOT /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(27 & "%", "Copying Boot Partition ")
    RunWait('cmd /c xcopy ' & $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 ' & $MountedDrive & ':\sources ' & $bootDrive & ':\sources /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(50 & "%", "Copying Boot Files ")
    If FileExists($MountedDrive & ":\BOOTMGR.") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOTMGR. ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.efi") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.efi ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.exe") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.exe ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\menu.lst") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\menu.lst ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CopyBootFiles

Func CopyDataFilesF()
    Local $GoFiles = (GetCachePath() & $finalfiles), $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 ' & $MountedDrive & ':\' & $aArray[$i] & ' ' & $dataDrive & ':\' & ' /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
        $StartProgAt = ($StartProgAt + 1)
    Next
EndFunc   ;==>CopyDataFilesF

Func CopyDataFilesD()
    Local $GoFiles = (GetCachePath() & $finaldirs), $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 ' & $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 ' & $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 createDiskPartScriptFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc   ;==>createDiskPartScriptFile

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()
        UnmountIso()
        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
EndFunc   ;==>GetDriveLetters

Func CleanDirList()
    Local $rawlist = 'isod.dat'
    $finaldirs = 'isodirs.dat'
    RunWait('cmd /c DIR /B /A:D ' & $MountedDrive & ':\>' & '"' & GetCachePath() & $rawlist & '"', @WorkingDir, @SW_HIDE)
    RunWait('cmd /c FINDSTR /v /i /c:' & '"' & 'efi' & '"' & ' /c:' & '"' & 'boot' & '"' & ' /c:' & '"' & 'sources' & '"' & ' "' & GetCachePath() & $rawlist & '"' & '>>' & '"' & GetCachePath() & $finaldirs & '"', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CleanDirList

Func CleanFileList()
    Local $rawlist = 'isof.dat'
    $finalfiles = 'isofiles.dat'
    RunWait('cmd /c DIR /B /A-D ' & $MountedDrive & ':\>' & '"' & GetCachePath() & $rawlist & '"', @WorkingDir, @SW_HIDE)
    RunWait('cmd /c FINDSTR /v /i /c:' & '"' & 'bootmgr' & '"' & ' /c:' & '"' & 'menu' & '"' & ' "' & GetCachePath() & $rawlist & '"' & '>>' & '"' & GetCachePath() & $finalfiles & '"', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CleanFileList

Func Format()
    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])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

EndFunc   ;==>Format

 

Edited by benners
Link to comment
Share on other sites

I tidied some more functions up. I have tested them as much as I can so you'll have to check them on your end. There is an issue in the other posts in format where one file is called scrub.dat when it should be scrubber.dat.

I'm on Windows 7 so no Mount-Image cmdlet for me. Editied post above as well.

Func CleanDirList() ; setting GetCachePath() as the working directory so need dir path needed for the files
    $finaldirs = 'isodirs.dat'

    RunWait(@ComSpec & ' /c DIR /B /A:D ' & $MountedDrive & ':\ > isod.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"efi" /C:"boot" /C:"sources" isod.dat > ' & $finaldirs, GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanDirList

Func CleanFileList() ; setting GetCachePath() as the working directory so need dir path needed for the files
    $finalfiles = 'isofiles.dat'
    Local $MountedDrive = 'E'

    RunWait(@ComSpec & ' /c DIR /B /A-D ' & $MountedDrive & ':\ > isof.dat', GetCachePath(), @SW_HIDE)
    RunWait(@ComSpec & ' /c FINDSTR /V /I /C:"bootmgr" /C:"menu" isof.dat > ' & $finalfiles, GetCachePath(), @SW_HIDE)
EndFunc   ;==>CleanFileList

Func Format() ; using notepad to test the files open. Will need you to check on your end for the diskpart
    Local $as_Process[7][2] = [ _
            [6, 0], _
            ["Cleaning Drive", 'clean.dat'], _
            ["Formatting Drive", 'scrubber.dat'], _
            ["Resetting Disk Attributes", 'attrib.dat'], _
            ["Converting Layout to MBR", 'convert.dat'], _
            ["Creating Data Partition", 'initdata.dat'], _
            ["Creating Boot Partition", 'initboot.dat'] _
            ]

    For $i = 1 To $as_Process[0][0]
        ConsoleWrite('Process: ' & $as_Process[$i][0] & @CRLF)
        RunWait('notepad.exe ' & $as_Process[$i][1], GetCachePath())
;~      RunWait(@ComSpec & ' /c diskpart /s ' & $as_Process[$i][1], GetCachePath(), @SW_HIDE)
    Next
EndFunc   ;==>Format

Func ProperUse() ; needs $IsoFile replacing with $CmdLine[1]
    If $CmdLine[0] = 0 Then ; no file was dropped or passed via the command line
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto the program to begin...")

        Exit
    EndIf
EndFunc   ;==>ProperUse

 

Link to comment
Share on other sites

Thank you so much I dont understand how you noticed that or how it

BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT)

works.. 

You are great, I am not worthy 😜  .. I am adjusting now

Update:

After looking into your changes I found the following; To combine styles with the default style use BitOR($GUI_SS_DEFAULT_LIST, newstyle, ... )  and https://www.autoitscript.com/autoit3/docs/appendix/GUIStyles.htm#ListBox) The styles list seems important :) lol, you set it to sort alphabetically with $LBS_SORT. 

Edited by bobomb
Link to comment
Share on other sites

3 hours ago, benners said:

I'm on Windows 7 so no Mount-Image cmdlet for me. expan

No need, as long as an ISO is mounted with a CDUSB.Y empty marker file on the root while the program tries to run it should still work. You can mount with a 3rd party tool and drop a random garbage file on the program to open it and it should find the ISO anyway.

Ok so finished all those changes.. added an error for picking a partition instead of a disk :) The disk list looks so much better, the fact that I was not previously producing a decent disk list is a bad issue for a tool like this, with these changes you made it is a lot safer for the end user to use this without making a mistake and formatting the wrong disk.. that is a huge help i was waiting to do something with WMIC later on after I worked on certain other bits first.. I thought it was going to be a huge ordeal, you just made that look so easy and I cant thank you enough... This one really made my day.

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

Global $DiskList, $Selection, $MountedDrive = ""
Global $finalfiles, $finaldirs, $wimSize, $bootDrive, $dataDrive

ProperUse()
MountIso()
GetISODriveLetter()
BootWim_Check()
Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

Func MainMenu()
    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())
    $Refresh = GUICtrlCreateButton('Refresh List', 110, 187, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)
    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)
    $Burn = GUICtrlCreateButton('Burn', 90, 232, 120, 40)
    GUICtrlSetOnEvent(-1, "BurnPressed")
    GUISetState()
    ; Just idle around
    While 1
        Sleep(10)
    WEnd
EndFunc   ;==>MainMenu

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

Func BurnPressed()
    If GUICtrlRead($DiskList) = '' Or StringInStr(GUICtrlRead($DiskList), "   └ ") Then
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "Please select a disk number")
    Else
        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%")
                PrepFormat($s_DiskNumber)
                ProgressSet(5 & "%", "Formatting Disk " & $s_DiskNumber)
                Format()
                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()
                UnmountIso()
                MsgBox($MB_ICONINFORMATION, "", " Enjoy! ")
                Exit
            EndIf
        EndIf
    EndIf
EndFunc   ;==>BurnPressed

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            UnmountIso()
            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 ProperUse()
    If $CmdLine[0] = 0 Then ; no file was dropped or passed via the command line
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto the program to begin...")
        Exit
    EndIf
EndFunc   ;==>ProperUse


Func BootWim_Check() ; check for the boot wim file
    If Not FileExists($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.")
        UnmountIso()
        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($MountedDrive & ':\sources\boot.wim') + 209715200) / 1048576)
EndFunc   ;==>BootWim_GetSize

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

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

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

Func GetISODriveLetter()
    Local $findiso = StringSplit("CDEFGHIJKLMNOPQRSTUVWXYZ", "", 1)
    For $i = 1 To $findiso[0] Step +1
        $isoExists = FileExists($findiso[$i] & ":\CdUsb.Y")
        If $isoExists Then
            If PathIsWritable($findiso[$i] & ":\") = False Then
                $MountedDrive = ($findiso[$i])
            EndIf
        EndIf
    Next
    If $MountedDrive = "" Then
        MsgBox($MB_ICONERROR, "Notice: ", "CdUsb.Y NOT DETECTED!!!" & @CRLF & "This tool is designed for SE" & @CRLF & "and XPE projects only.")
        Exit
    EndIf
EndFunc   ;==>GetISODriveLetter

Func PathIsWritable($sFile)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', _
            'wstr', $sFile, _
            'dword', 2, _
            'dword', 7, _
            'struct*', 0, _
            'dword', 3, _
            'dword', 0x02000000, _
            'handle', 0)
    If @error Or $aRet[0] = Ptr(-1) Or $aRet[0] = 0 Then Return False
    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $aRet[0])
    Return True
EndFunc   ;==>PathIsWritable

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 $sDrivesInfo, $s_Drives

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

Func _GetDiskNameByNumber($iDiskNumber)
    Local $iCount = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", "Count")
    Local $sDiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($iDiskNumber))
    If @error Then Return SetError(1, 0, 0)

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

    Return $sDiskName
EndFunc   ;==>_GetDiskNameByNumber

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

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

Func CopyBootFiles()
    RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOT ' & $bootDrive & ':\BOOT /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(27 & "%", "Copying Boot Partition ")
    RunWait('cmd /c xcopy ' & $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 ' & $MountedDrive & ':\sources ' & $bootDrive & ':\sources /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(50 & "%", "Copying Boot Files ")
    If FileExists($MountedDrive & ":\BOOTMGR.") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOTMGR. ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.efi") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.efi ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.exe") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.exe ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\menu.lst") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\menu.lst ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CopyBootFiles

Func CopyDataFilesF()
    Local $GoFiles = (GetCachePath() & $finalfiles), $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 ' & $MountedDrive & ':\' & $aArray[$i] & ' ' & $dataDrive & ':\' & ' /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
        $StartProgAt = ($StartProgAt + 1)
    Next
EndFunc   ;==>CopyDataFilesF

Func CopyDataFilesD()
    Local $GoFiles = (GetCachePath() & $finaldirs), $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 ' & $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 ' & $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 createDiskPartScriptFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc   ;==>createDiskPartScriptFile

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()
        UnmountIso()
        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
EndFunc   ;==>GetDriveLetters

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

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

Func Format()
    Local $aArray[7][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrubber.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])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

EndFunc   ;==>Format

It appears the disks are coming back in the correct ascending order but the partitions are reversed still(But importantly they ARE under their correct disks)... I feel like any changes I make to the array creation are being overridden.. by the style settings?

Edited by bobomb
Link to comment
Share on other sites

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

I can mount the iso and remove the check for the marker file or comment out function, as I have been doing but if I am altering your code, I like to test it as much as possible before I post it and run it as it was intended. I also have to remember to remove the comments on the code. Some folks who know what they are talking about can write code that is untested and it works first time, I have been helped this way before, but I tend to overthink things 😁. With the mount and unmount functions I couldn't test them.

I would make a few more changes to the code but it feels like I am taking over, I don't want to impose the way I like to do things on you, as its better if you develop your own style as it's part of the process.

If you don't specify styles then AutoIt will use whatever has been set as the default style. As you have found, the help file has loads of info on the different styles and each has it's own constant value. You could just add them up or subtract one style from another like this.

$GUI_SS_DEFAULT_LIST - $LBS_SORT

The correct\better? way is to perform a bitwise operation on the values. Basically if I want to add numbers or styles I use BitOR, and BitXOR to subtract them.

The list isn't sorting them now. In the GetDiskList function, there is a line that sorts the array. If it's not needed, either comment it out or delete it.The partitions will be displayed correctly.

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

As you mentioned, because of the nature of the program, it would be quite easy to hose a partition and lose whatever was on it. When it is working correctly, you will want to start adding error checking for values returned from functions or actions performed by the functions. I only have 1 drive split into two partitions. I have plugged a in a usb drive to test this but if I lose focus and run the program on the main drive I will be up shit creek :)

Link to comment
Share on other sites

I have cleaned it up a bit more. Trimmed the function that loads the list, it now loads the control from the function. Added a function for when the list is clicked that enables or disables the Burn button.. Renamed some functions to more descriptive names.

I'm still not sure about the formatting and file copying though. The current setup doesn't copy any files when I run it as the drive letter changes with the diskpart calls. The drive is cleaned, then formatted and labelled "scrubber", then cleaned again, then formatted again and a primary partition is created and assigned a new drive letter. Then  a primary partition is created again, assigned a drive letter and set to active. I'm struggling to undersatnd the process after the burn button is clicked.  I am hard of thinking though😆

Have you successfully create the usb with this AutoIt program? I know you have said the bat file works correctly.

#NoTrayIcon
#RequireAdmin

;~ #Tidy_Parameters=/sf

#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 $c_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($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
            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 DiskList_Load() ; load the list control with enumerated drives
    Local $as_Fixed = DriveGetDrive('FIXED')
    Local $as_Removable = DriveGetDrive('REMOVABLE')

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

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

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

    For $i = 1 To $as_Fixed[0] ; loop through the fixed drives
        ; get info on the fixed drive
        $aDriveInfo = _WinAPI_GetDriveNumber($as_Fixed[$i])
        $i_DeviceNumber = $aDriveInfo[1]

        ; get the drive number and device name
        If $i_DeviceNumber <> $i_LastDeviceNumber Then ; add the device name to the list
            GUICtrlSetData($c_DiskList, 'Disk ' & $i_DeviceNumber & ' [' & Disk_GetName($i_DeviceNumber) & ']')
            $i_LastDeviceNumber = $i_DeviceNumber
        EndIf

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

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($c_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, _
                "Notice: ", _
                "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, _
                "Notice: ", _
                $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)
    $c_DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT))
    DiskList_Load()
    GUICtrlSetOnEvent(-1, "DiskList_Selected")
    GUICtrlCreateButton('Refresh List', 110, 187, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)
    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)
    $c_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()
    DiskList_Load()
    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

 

Link to comment
Share on other sites

@benners it is perfectly working, every copy that has been posted in this thread works.. :) I wish there was an easy way to send you a test ISO

Here is where a builder is to make a PE disk.. but that is a project in itself.. https://github.com/ChrisRfr/Win10XPE

The reason the drive is cleaned then "scrubbed" then cleaned again is that there is a bug in windows explorer, that if this step is not done you may (small chance) see an extra drive + letter in windows explorer that is inaccessible.. Like a phantom disk with a letter that you cannot eject and will remain if the drive is unplugged.. When this step is performed the issue is overcome. It is a very annoying bug and im happy to run clean twice to avoid it lol.. its actually not the clean part that fixes it, its the format "scrub" partition the entire disk into one partition then clean that.. it may have to do with the dual partition breakdown diskpart does during the initial clean... you generally do not partition usb sticks, and when cleaning one that is already split into partitions weird things happen lol (The phantom drive goes away if the USB is reinserted and "scrubbed")

For bootable media, on Windows 7, if you have more than 1 partition on a usb, only the first partition will be seen. So for this format process we create the data partition first, it is NTFS so files larger than 4gb can be used, then shrink the drive the size we need for the boot partition (this was checked +200mb added), the boot partition is created containing the boot files as fat32 and set as active. So when the system starts it boots off the boot partition, where the boot.wim is located, and the system automaps Y: (with cdusb.y marker) to the Data partition during boot, where all the programs in the windows pe start menu live(depending on how you created your build)...

Some builds have everything loaded to ram so all program are located in the boot.wim and nothing is on the data drive... But using this tool with the split partition still benefits those users because it will allow their boot wim to be loaded on the FAT32 (Mac compatible) partition, and still have the remaining space on their USB set as NTFS so they can deal with whatever file sizes they need to... The boot partition doesnt need to be accessed after the rescue pe is loaded because it contains nothing other than the files already loaded into ram.. (as I alluded earlier, boot.wim loads into ram during boot)

 

Edited by bobomb
Link to comment
Share on other sites

@benners using BOOTMGR as a markerfile for burning is genius! I am so stuck on the fact that Y is our marker as builders to reference our program drives that I did not notice it is completely irrelevant to the burn process.. the Y marker gets places correctly with your method if present and this allows ISO's without the marker to be burned as well.. very smooth move..

The sorting in your new example on the disk list looks like this

Disk 1
  Partition a
Disk 0
  Drive letter b
  Drive letter a
Disk 2

The OP for that disk checking function was here: https://www.autoitscript.com/forum/topic/184895-get-diskname-without-diskpart-wmi-wmic/page/3/?tab=comments#comment-1329548 , He was helping someone with it.. And i had the same issue as the person he was helping... for the disks still being in the correct order but the drive letters being backwards.. so he posted this fix to correct the sort order: https://www.autoitscript.com/forum/topic/184895-get-diskname-without-diskpart-wmi-wmic/page/3/?tab=comments#comment-1332763 .  We were already using the prior code and I could not get his changes to work in what you adjusted for me i tried for a while last night and I would either lose the list or 0 difference... I'm ok with the partitions letters being reversed as long as the disks are in order.. idk why the list sort isnt displaying correctly.. (It is clearly not listed alphabetical, but is set to be)

 

Edited by bobomb
Link to comment
Share on other sites

It might be genius, but it was a fluke 🤣 I made that as I don't have the CdUsb.Y file on my iso. I'm just using a Windows 10 iso. I forgot to comment it out. If it's better, and won't cause any other issues, then yay! I'm a genius 😅

The list selection is in order for me. Attached a pic, there is no array sorting wth the new code, the arrays come as they are returned from the func calls. You could add some array display calls and see if the arrays order change. The two arrays are joined together so there's only one loop to get all the data.

I manually ran the diskpart commands from the files in the cache from a dos prompt. All worked for me except the from the initboot.dat when I tried to create another primary partition. It moaned there was no free space. Looked on diskmgmt.msc and it shows the 200mb unallocated so it seems there is.

bobomb.png

Link to comment
Share on other sites

Those are both correct.

Probably doesnt create the second pri par for the same reason it only sees the first partition on a correctly created usb in a Win7 system now that I think about it..  

We need to get you updated to 10 @benners :P

EDIT* 

This is what it looks like for me

Screenshot 2021-12-12 135328.png

Edited by bobomb
Link to comment
Share on other sites

Never mind Windows 10, what type of snakeoil are you peddling with software that doesn't work 🤣. I have installed a WIn 10 on a VM, god it's slow. That has issues with the list as it doesn't return an array with removable drives. The Mount-DiskImage works great. I have seen code on the net and found that you can get the drive letter of the mounted iso from the cmdlet here

Link to comment
Share on other sites

8 minutes ago, benners said:

Whats does $as_Fixed array look like if you display it (_ArrayDisplay). What order are the drives?. Wonder if the DriveGetDrive function returns them dependent on which is the system drive?

Attached.. So it looks like the whole list is getting sorted by the drive letters... It ideally would be sorted by disk numbers 0-9, and then inside the disk numbers sorted by the letters..a-z -- That other function, sorted by disk number but then the drive letters were always sorted z-a under each disk, troubleshooting whats going on in an array is such a waste of time without displaying it and taking a look, thank for asking to kick me in the butt to look lol

Screenshot 2021-12-12 142958.png

Edited by bobomb
Link to comment
Share on other sites

@benners I got it to work in the old script i was using before you made these new latest set of updates to the disk listing function (just now got it), here it is, using a delimeter for the second sort loop of ";" and adding that onto the front of the drive letter lines allowed it to work.  I dont understand the new stuff fully yet we are going a little fast.. but I will soon...  here is what i have as a working example to help with the updates you are trying to show me..

#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=burntool.ico
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Comment=Drag an XPE or SE related Project ISO onto the tool to begin.
#AutoIt3Wrapper_Res_Description=BurnTool
#AutoIt3Wrapper_Res_Fileversion=2.0.0.0
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <StringConstants.au3>
; *** End added by AutoIt3Wrapper ***
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <GUIConstantsEx.au3>
#include <ListBoxConstants.au3>
#include <MsgBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $DiskList, $Selection, $MountedDrive = ""
Global $finalfiles, $finaldirs, $wimSize, $bootDrive, $dataDrive

ProperUse()
MountIso()
GetISODriveLetter()
BootWim_Check()
Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

Func MainMenu()
    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 & '\BurnTool.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())
    $Refresh = GUICtrlCreateButton('Refresh List', 110, 187, 80, 25)
    GUICtrlSetOnEvent(-1, "RefreshPressed")
    GUICtrlSetState(-1, $GUI_FOCUS)
    GUICtrlCreateLabel('________________________________________', 30, 210, 280, 30)
    $Burn = GUICtrlCreateButton('Burn', 90, 233, 120, 40)
    GUICtrlSetOnEvent(-1, "BurnPressed")
    GUISetState()
    ; Just idle around
    While 1
        Sleep(10)
    WEnd
EndFunc   ;==>MainMenu

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

Func BurnPressed()
    If GUICtrlRead($DiskList) = '' Or StringInStr(GUICtrlRead($DiskList), "    └ ") Then
        MsgBox( _
                $MB_ICONERROR, _
                "Attention: ", _
                "Please select a disk number")
    Else
        Local $s_DiskNumber = StringRegExp(GUICtrlRead($DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0]

        If @error Then
            MsgBox( _
                    $MB_ICONERROR, _
                    "Attention: ", _
                    "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%")
                PrepFormat($s_DiskNumber)
                ProgressSet(5 & "%", "Formatting Disk " & $s_DiskNumber)
                Format()
                ProgressSet(25 & "%", "Analyzing ISO Structure ")
                Sleep(250)
                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()
                UnmountIso()
                MsgBox($MB_ICONINFORMATION, "", " Enjoy! ")
                Exit
            EndIf
        EndIf
    EndIf
EndFunc   ;==>BurnPressed

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ; Code below for actions on Close
            Cleanup()
            UnmountIso()
            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 ProperUse()
    If $CmdLine[0] = 0 Then ; no file was dropped or passed via the command line
        MsgBox( _
                $MB_ICONERROR, _
                "Notice: ", _
                "This program cannot be run directly!" & @CRLF & "Please drag an ISO onto the program to begin...")
        Exit
    EndIf
EndFunc   ;==>ProperUse


Func BootWim_Check() ; check for the boot wim file
    If Not FileExists($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.")
        UnmountIso()
        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($MountedDrive & ':\sources\boot.wim') + 209715200) / 1048576)
EndFunc   ;==>BootWim_GetSize

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

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

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

Func GetISODriveLetter()
    Local $findiso = StringSplit("CDEFGHIJKLMNOPQRSTUVWXYZ", "", 1)
    For $i = 1 To $findiso[0] Step +1
        $isoExists = FileExists($findiso[$i] & ":\CdUsb.Y")
        If $isoExists Then
            If PathIsWritable($findiso[$i] & ":\") = False Then
                $MountedDrive = ($findiso[$i])
            EndIf
        EndIf
    Next
    If $MountedDrive = "" Then
        MsgBox($MB_ICONERROR, "Notice: ", "CdUsb.Y NOT DETECTED!!!" & @CRLF & "This tool is designed for XPE" & @CRLF & "and SE projects only.")
        Exit
    EndIf
EndFunc   ;==>GetISODriveLetter

Func PathIsWritable($sFile)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', _
            'wstr', $sFile, _
            'dword', 2, _
            'dword', 7, _
            'struct*', 0, _
            'dword', 3, _
            'dword', 0x02000000, _
            'handle', 0)
    If @error Or $aRet[0] = Ptr(-1) Or $aRet[0] = 0 Then Return False
    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $aRet[0])
    Return True
EndFunc   ;==>PathIsWritable

Func GetDiskList2()
    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 $sDrivesInfo, $s_Drives

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

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 $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] & " [" & _GetDiskNameByNumber($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

Func _GetDiskNameByNumber($iDiskNumber)
    Local $iCount = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", "Count")
    Local $sDiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($iDiskNumber))
    If @error Then Return SetError(1, 0, 0)

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

    Return $sDiskName
EndFunc   ;==>_GetDiskNameByNumber

Func GetCachePath()
    Local Static $s_CachePath = IniRead(@WorkingDir & '\BurnTool.ini', "Settings", "CachePath", @WorkingDir & '\cache') & '\'
    Return $s_CachePath
EndFunc   ;==>GetCachePath

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

Func CopyBootFiles()
    RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOT ' & $bootDrive & ':\BOOT /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(27 & "%", "Copying Boot Partition ")
    RunWait('cmd /c xcopy ' & $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 ' & $MountedDrive & ':\sources ' & $bootDrive & ':\sources /i /s /e /h /r /v /y', @WorkingDir, @SW_HIDE)
    ProgressSet(50 & "%", "Copying Boot Files ")
    If FileExists($MountedDrive & ":\BOOTMGR.") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\BOOTMGR. ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.efi") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.efi ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\bootmgr.exe") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\bootmgr.exe ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
    If FileExists($MountedDrive & ":\menu.lst") Then RunWait('cmd /c xcopy ' & $MountedDrive & ':\menu.lst ' & $bootDrive & ':\ /h /r /v /y', @WorkingDir, @SW_HIDE)
EndFunc   ;==>CopyBootFiles

Func CopyDataFilesF()
    Local $GoFiles = (GetCachePath() & $finalfiles), $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 ' & $MountedDrive & ':\' & $aArray[$i] & ' ' & $dataDrive & ':\' & ' /h /r /v /y', @WorkingDir, @SW_HIDE, 2)
        $StartProgAt = ($StartProgAt + 1)
    Next
EndFunc   ;==>CopyDataFilesF

Func CopyDataFilesD()
    Local $GoFiles = (GetCachePath() & $finaldirs), $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 ' & $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 ' & $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 createDiskPartScriptFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc   ;==>createDiskPartScriptFile

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()
        UnmountIso()
        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
EndFunc   ;==>GetDriveLetters

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

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

Func Format()
    Local $aArray[7][3] = [ _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _
            ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrubber.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])
        ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data
        RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(750)
    Next

EndFunc   ;==>Format

 

Screenshot 2021-12-12 150113.png

Edited by bobomb
Link to comment
Share on other sites

Try this

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

        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

 

Link to comment
Share on other sites

@benners No that lists the disks incorrectly as well it appears to prioritize drive letters too.. (image attached)

The code i posted above yours is working for the sort im not sure if you saw that yet i think you were working on this when i posted it...

 

Screenshot 2021-12-12 151609.png

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)

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...