benners Posted December 12, 2021 Share Posted December 12, 2021 (edited) Sorted. The issue was with the list styles. By default it is sorted. Just needed the styles changing expandcollapse popup#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 December 12, 2021 by benners bobomb 1 Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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. expandcollapse popupFunc 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 bobomb 1 Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) 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 December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) 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. expandcollapse popup#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 December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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 bobomb 1 Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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. expandcollapse popup#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 bobomb 1 Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) @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 December 12, 2021 by bobomb benners 1 Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) @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 December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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. Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) can u post initboot.dat's and initdata.dat contents here? Edited December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 (edited) initboot Sel Dis 1 cre par pri format quick fs=fat32 label="BOOTFILES" assign letter=H Active Exit initdata Sel Dis 1 cre par pri shrink minimum=200 format quick fs=ntfs label="WinPE Data" assign letter=I Exit Edited December 12, 2021 by benners typo Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) 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 EDIT* This is what it looks like for me Edited December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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 More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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? bobomb 1 Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) 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 Edited December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 Looks like DriveGetDrive sorts them alphabetically. As it's not a udf function, we wont be able to change it. There will have to be another loop that that gets the disk numbers and sorts them as you say, then creates an array to process. Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) @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.. expandcollapse popup#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 Edited December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 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 bobomb 1 Link to comment Share on other sites More sharing options...
bobomb Posted December 12, 2021 Author Share Posted December 12, 2021 (edited) @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... Edited December 12, 2021 by bobomb Link to comment Share on other sites More sharing options...
benners Posted December 12, 2021 Share Posted December 12, 2021 (edited) Forgot to sort the array. Gimme a minute Edited December 12, 2021 by benners bobomb 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now