Jump to content

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


Go to solution Solved by mikell,

Recommended Posts

Posted (edited)

@benners and this is the final working script using your method, you were 100% correct that drive letters were being skipped and needed to be moved.  THANK you.. I even removed some global variables and made them local ;)

#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=PrepareDiskNT.ico
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep)
#AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5
#AutoIt3Wrapper_Res_Fileversion=1.3
#AutoIt3Wrapper_Add_Constants=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive

_Cleanup()

DirCreate(@WorkingDir & '\cache')
$listFile = FileOpen(@WorkingDir & '\cache\list.ini', 2)
FileWrite($listFile, 'lis dis')
FileClose($listFile)

GUICreate('Prep/Format Disk v1.3', 300, 298)
GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1)
GUISetBkColor (0x797979)
GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
$DiskList = GUICtrlCreateList('', 20, 30, 260, 150)
GUICtrlSetData(-1, _GetInfo())
$Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
$MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40)
$GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40)
GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30)
GUISetState()

Do
    $Selection = GUIGetMsg()
    If $Selection = $MBR Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatMBR($DiskN[6])
                _IniWriteMBR()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
                Run("cmd /c ..\WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
                EndSelect
        EndIf
    EndIf
    If $Selection = $GPT Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatGPT($DiskN[6])
                _IniWriteGPT()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
                Run("cmd /c ..\WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
        EndSelect
        EndIf
    EndIf
    If $Selection = $Refresh Then
        GUICtrlSetData($DiskList, "")
        GUICtrlSetData($DiskList, _GetInfo())
    EndIf
Until $Selection = $GUI_EVENT_CLOSE
_Cleanup()

Func _GetInfo()
    RunWait("cmd /c diskpart /s cache\list.ini>cache\list.txt", @WorkingDir, @SW_HIDE) ; Only works when compiled if x64
    Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead(@WorkingDir & '\cache\list.txt'), @LF)
    For $RawList = 0 To UBound($Array) - 1
        If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|'
    Next
    $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') ;Removal of spaces, returns, line breaks, and pipes from end of the string
    Return $Filtered
EndFunc   ;==>_GetInfo

Func _FormatMBR($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2)
    FileWrite($cleandatFile, 'Sel Dis ' & $Drive)
    FileWrite($cleandatFile, @CRLF & 'clean')
    FileClose($cleandatFile)
    $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2)
    FileWrite($attribdatFile, 'Sel Dis ' & $Drive)
    FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly')
    FileClose($attribdatFile)
    $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2)
    FileWrite($scrubdatFile, 'Sel Dis ' & $Drive)
    FileWrite($scrubdatFile, @CRLF & 'cre par pri')
    FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber')
    FileClose($scrubdatFile)
    $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2)
    FileWrite($convertFile, 'Sel Dis ' & $Drive)
    FileWrite($convertFile, @CRLF & 'convert mbr')
    FileClose($convertFile)
    $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2)
    FileWrite($mainFile, 'Sel Dis ' & $Drive)
    FileWrite($mainFile, @CRLF & 'cre par pri')
    FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows')
    FileWrite($mainFile, @CRLF & 'Active')
    FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive)
    FileClose($mainFile)
    ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>_FormatMBR

Func _FormatGPT($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2)
    FileWrite($cleandatFile, 'Sel Dis ' & $Drive)
    FileWrite($cleandatFile, @CRLF & 'clean')
    FileClose($cleandatFile)
    $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2)
    FileWrite($scrubdatFile, 'Sel Dis ' & $Drive)
    FileWrite($scrubdatFile, @CRLF & 'cre par pri')
    FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=GPTscrubber')
    FileClose($scrubdatFile)
    $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2)
    FileWrite($attribdatFile, 'Sel Dis ' & $Drive)
    FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly')
    FileClose($attribdatFile)
    $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2)
    FileWrite($convertFile, 'Sel Dis ' & $Drive)
    FileWrite($convertFile, @CRLF & 'convert gpt')
    FileClose($convertFile)
    $fsFile = FileOpen(@WorkingDir & '\cache\formatsystem.dat', 2)
    FileWrite($fsFile, 'Sel Dis ' & $Drive)
    FileWrite($fsFile, @CRLF & 'cre par efi size=100')
    FileWrite($fsFile, @CRLF & 'format quick fs=fat32 label=System')
    FileWrite($fsFile, @CRLF & 'assign letter=' & $bootDrive)
    FileClose($fsFile)
    $msrFile = FileOpen(@WorkingDir & '\cache\createmsr.dat', 2)
    FileWrite($msrFile, 'Sel Dis ' & $Drive)
    FileWrite($msrFile, @CRLF & 'cre par msr size=16')
    FileClose($msrFile)
    $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2)
    FileWrite($mainFile, 'Sel Dis ' & $Drive)
    FileWrite($mainFile, @CRLF & 'cre par pri')
    FileWrite($mainFile, @CRLF & 'shrink minimum=450')
    FileWrite($mainFile, @CRLF & 'format quick fs=ntfs label=Windows')
    FileWrite($mainFile, @CRLF & 'assign letter=' & $mainDrive)
    FileClose($mainFile)
    $reFile = FileOpen(@WorkingDir & '\cache\formatwinre.dat', 2)
    FileWrite($reFile, 'Sel Dis ' & $Drive)
    FileWrite($reFile, @CRLF & 'cre par pri')
    FileWrite($reFile, @CRLF & 'format quick fs=ntfs label=WinRE')
    FileWrite($reFile, @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac')
    FileClose($reFile)
    ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%")
    ProgressSet(10 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(15 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(30 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(40 & "%", "Converting Disk to GPT")
    RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(50 & "%", "Formatting System Partition")
    RunWait("cmd /c diskpart /s cache\formatsystem.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(70 & "%", "Creating MSR")
    RunWait("cmd /c diskpart /s cache\createmsr.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(90 & "%", "Formatting WinRE Partition")
    RunWait("cmd /c diskpart /s cache\formatwinre.dat", @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>_FormatGPT

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

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

Func _Cleanup()
    Local Const $WDcachePath = @WorkingDir & "\cache"
    If FileExists($WDcachePath) Then
        DirRemove($WDcachePath, $DIR_REMOVE)
    EndIf
EndFunc   ;==>_Cleanup

Func _GetDriveLetters()
    Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1)
    For $bd = 1 to $driveletter[0] step +1
        $bdStat = DriveStatus($driveletter[$bd] & ":")
        If $bdStat = "INVALID" Then
            $bootDrive=($driveletter[$bd])
            For $md = 1 to $driveletter[0] step +1
                $mdStat = DriveStatus($driveletter[$md] & ":")
                If Not ($bootDrive=($driveletter[$md])) Then
                    If $mdStat = "INVALID" Then
                        $mainDrive=($driveletter[$md])
                    EndIf
                EndIf
            Next
        EndIf
    Next
EndFunc   ;==>_GetDriveLetters

very cool... and very much cleaned up from the OP

Edited by bobomb
Posted (edited)

@benners i actually moved the _GetDriveLetters() call to the format functions.  That way if someone opens the program the list is sitting open and someone plugs in a new disk this will wait until the format begins to check for available letters.. updated the post above to reflect this. Just some extra cleaning to ensure reliability.

Edited by bobomb
Posted

AutoIt is a pretty lenient language compared to others, not that I have much experience with others but just from what I have read from other posts. In the future, you may want to learn another langauge so trying to incorporate best practice now could help later on.

If a variable is modified from various points in the script, there isn't an issue with making it global but as was the case with $FIltered, does it need to be. Could it be local scope or passed ByRef. I have seen posts where people are having issues with code and they are expecting one value from a global variable but it is being changed elsewhere in a function as they have reused the variable name.

When you create a variable it assigns a bit of memory to hold the value and though it's probably not an issue with todays ram sizes, but hogs memory if the variable isn't immediately required or may not be required when running the code.

When your code gets more complex and too big for one file, you might start making UDFs of your own and keeping good structure and following naming conventions will make it easier when you come to troubleshoot issues. Have a peek inside the AutoIt UDFs and see how big things can get.

When you declare variables outside of functions, AutoIt gives them a global scope. and some things benefit from this, liike a filepath. If you declare them inside functions using Local, the variable is destroyed when the function ends and the memory returned to the pool. If you had a massive array as global and this was only used in one function, it's a waste.

I am sure others will add there knowledge about variables but a lot of times it's down to the individual and sometimes the size of the script whether its worth it. I try to give them scope and descriptive names as well as defining what value I am expecting on return.  A read of the wiki will explain more  in depth than I have.

Posted

I'm glad you're tweaking it, It's addictive after a while. I have wasted loads of time overthinking code rather than coding first then tweaking.

With loops, a variable is created automatically with the local scope so you don't need to declare it. In your instance $RawList doesn't need to be declared. I normaly use $i for a count variable so,

For $i = 1 To 5
    ' code here
Next

In previous code it was declared as a global variable. I see now you have move it to the GetInfo function 👍. Once the code is working as you want, it would be a good idea to add some error checking. An example would be checking an array is an array before performing actions on it., or checking file read\close operations, if they are essential.

More tweaks for later would be to change the do loop to a while loop, use a switch or select case instead of the if..then parts, and move the code currently inside the if..then into their own functions 😀

Posted (edited)
  • Using global variables you learned already by hitting a defect with the list.
    Think twice when you introduce globals its fine when you have small scripts. But a rule of thumb "Do I understand next month still what I have written" or "Does someone else understand it by reading it 1 time"

This 

Func _FormatMBR($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2)
    FileWrite($cleandatFile, 'Sel Dis ' & $Drive)
    FileWrite($cleandatFile, @CRLF & 'clean')
    FileClose($cleandatFile)
    $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2)
    FileWrite($attribdatFile, 'Sel Dis ' & $Drive)
    FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly')
    FileClose($attribdatFile)
    $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2)
    FileWrite($scrubdatFile, 'Sel Dis ' & $Drive)
    FileWrite($scrubdatFile, @CRLF & 'cre par pri')
    FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber')
    FileClose($scrubdatFile)
    $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2)
    FileWrite($convertFile, 'Sel Dis ' & $Drive)
    FileWrite($convertFile, @CRLF & 'convert mbr')
    FileClose($convertFile)
    $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2)
    FileWrite($mainFile, 'Sel Dis ' & $Drive)
    FileWrite($mainFile, @CRLF & 'cre par pri')
    FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows')
    FileWrite($mainFile, @CRLF & 'Active')
    FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive)
    FileClose($mainFile)
    ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc   ;==>_FormatMBR

you could rewrite for "Clean coding" like below

func _writeInfoToFile($fileName, $message)
    $cleandatFile = FileOpen($fileName, 2)
    FileWrite($cleandatFile, $message)
    FileClose($cleandatFile)
end func
func _cleanDrive()
    ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
end func

func cleanDrive2()\
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
end func

func _scrubDrive()
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
end func
func _resetDrive()
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
end func
func _convertDrive()
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE)
    SLEEP(1000)
end func
func formatWindowsPartition()
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
end func

Func _FormatMBR($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    _writeInfoToFile(@WorkingDir & '\cache\clean.dat',   'Sel Dis ' & $Drive & @CRLF & 'clean')
    _writeInfoToFile(@WorkingDir & '\cache\scrub.dat',   'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & 'format quick fs=NTFS label=MBRscrubber' )
    _writeInfoToFile(@WorkingDir & '\cache\convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr')
    _writeInfoToFile(@WorkingDir & '\cache\formatmain.dat',   'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' @CRLF & 'Active' @CRLF & 'Assign letter=' & $bootDrive)

    _cleanDrive1()
    _scrubDrive()
    _cleanDrive2()
    _resetDrive()
    _convertDrive()
    _formatWindowsPartition()

    ProgressOff()
    GUISetState()
EndFunc   ;==>_FormatMBR

 

Edited by junkew
Posted (edited)

@junkew literally was just cleaning that

#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=PrepareDiskNT.ico
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep)
#AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5
#AutoIt3Wrapper_Res_Fileversion=1.3
#AutoIt3Wrapper_Add_Constants=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $WinNTSetupPath = (@WorkingDir & "\..\") ;To run in the same folder as WinNTSetup5 instead of subfolder just use "\" instead of "\..\"
Global $CachePath = (@WorkingDir & "\cache\")
Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive

_Cleanup()

DirCreate($CachePath)
$listFile = FileOpen($CachePath & 'list.ini', 2)
FileWrite($listFile, 'lis dis')
FileClose($listFile)

GUICreate('Prep/Format Disk v1.3', 300, 298)
GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1)
GUISetBkColor (0x797979)
GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
$DiskList = GUICtrlCreateList('', 20, 30, 260, 150)
GUICtrlSetData(-1, _DiskList())
$Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
$MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40)
$GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40)
GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30)
GUISetState()

Do
    $Selection = GUIGetMsg()
    If $Selection = $MBR Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatMBR($DiskN[6])
                _IniWriteMBR()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
                Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
                EndSelect
        EndIf
    EndIf
    If $Selection = $GPT Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatGPT($DiskN[6])
                _IniWriteGPT()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
                Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
        EndSelect
        EndIf
    EndIf
    If $Selection = $Refresh Then
        GUICtrlSetData($DiskList, "")
        GUICtrlSetData($DiskList, _DiskList())
    EndIf
Until $Selection = $GUI_EVENT_CLOSE
_Cleanup()

Func _DiskList()
    RunWait("cmd /c diskpart /s " & $CachePath & "list.ini>" & $CachePath & "list.txt", @WorkingDir, @SW_HIDE)
    Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF)
    For $RawList = 0 To UBound($Array) - 1
        If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|'
    Next
    $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '')
    Return $Filtered
EndFunc ;==>_DiskList

Func _FormatMBR($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    $cleandatFile = FileOpen($CachePath & 'clean.dat', 2)
    FileWrite($cleandatFile, 'Sel Dis ' & $Drive)
    FileWrite($cleandatFile, @CRLF & 'clean')
    FileClose($cleandatFile)
    $scrubdatFile = FileOpen($CachePath & 'scrub.dat', 2)
    FileWrite($scrubdatFile, 'Sel Dis ' & $Drive)
    FileWrite($scrubdatFile, @CRLF & 'cre par pri')
    FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber')
    FileClose($scrubdatFile)
    $attribdatFile = FileOpen($CachePath & 'attrib.dat', 2)
    FileWrite($attribdatFile, 'Sel Dis ' & $Drive)
    FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly')
    FileClose($attribdatFile)
    $convertFile = FileOpen($CachePath & 'convert.dat', 2)
    FileWrite($convertFile, 'Sel Dis ' & $Drive)
    FileWrite($convertFile, @CRLF & 'convert mbr')
    FileClose($convertFile)
    $mainFile = FileOpen($CachePath & 'formatmain.dat', 2)
    FileWrite($mainFile, 'Sel Dis ' & $Drive)
    FileWrite($mainFile, @CRLF & 'cre par pri')
    FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows')
    FileWrite($mainFile, @CRLF & 'Active')
    FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive)
    FileClose($mainFile)
    ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc ;==>_FormatMBR

Func _FormatGPT($Drive)
    _GetDriveLetters()
    GUISetState(@SW_HIDE)
    $cleandatFile = FileOpen($CachePath & 'clean.dat', 2)
    FileWrite($cleandatFile, 'Sel Dis ' & $Drive)
    FileWrite($cleandatFile, @CRLF & 'clean')
    FileClose($cleandatFile)
    $scrubdatFile = FileOpen($CachePath & 'scrub.dat', 2)
    FileWrite($scrubdatFile, 'Sel Dis ' & $Drive)
    FileWrite($scrubdatFile, @CRLF & 'cre par pri')
    FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=GPTscrubber')
    FileClose($scrubdatFile)
    $attribdatFile = FileOpen($CachePath & 'attrib.dat', 2)
    FileWrite($attribdatFile, 'Sel Dis ' & $Drive)
    FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly')
    FileClose($attribdatFile)
    $convertFile = FileOpen($CachePath & 'convert.dat', 2)
    FileWrite($convertFile, 'Sel Dis ' & $Drive)
    FileWrite($convertFile, @CRLF & 'convert gpt')
    FileClose($convertFile)
    $fsFile = FileOpen($CachePath & 'formatsystem.dat', 2)
    FileWrite($fsFile, 'Sel Dis ' & $Drive)
    FileWrite($fsFile, @CRLF & 'cre par efi size=100')
    FileWrite($fsFile, @CRLF & 'format quick fs=fat32 label=System')
    FileWrite($fsFile, @CRLF & 'assign letter=' & $bootDrive)
    FileClose($fsFile)
    $msrFile = FileOpen($CachePath & 'createmsr.dat', 2)
    FileWrite($msrFile, 'Sel Dis ' & $Drive)
    FileWrite($msrFile, @CRLF & 'cre par msr size=16')
    FileClose($msrFile)
    $mainFile = FileOpen($CachePath & 'formatmain.dat', 2)
    FileWrite($mainFile, 'Sel Dis ' & $Drive)
    FileWrite($mainFile, @CRLF & 'cre par pri')
    FileWrite($mainFile, @CRLF & 'shrink minimum=450')
    FileWrite($mainFile, @CRLF & 'format quick fs=ntfs label=Windows')
    FileWrite($mainFile, @CRLF & 'assign letter=' & $mainDrive)
    FileClose($mainFile)
    $reFile = FileOpen($CachePath & 'formatwinre.dat', 2)
    FileWrite($reFile, 'Sel Dis ' & $Drive)
    FileWrite($reFile, @CRLF & 'cre par pri')
    FileWrite($reFile, @CRLF & 'format quick fs=ntfs label=WinRE')
    FileWrite($reFile, @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac')
    FileClose($reFile)
    ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%")
    ProgressSet(10 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(15 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE)
    SLEEP(1000)
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(30 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(40 & "%", "Converting Disk to GPT")
    RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(50 & "%", "Formatting System Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatsystem.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(70 & "%", "Creating MSR")
    RunWait("cmd /c diskpart /s " & $CachePath & 'createmsr.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(90 & "%", "Formatting WinRE Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatwinre.dat', @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc ;==>_FormatGPT

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

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

Func _Cleanup()
    If FileExists($CachePath) Then
        DirRemove($CachePath, $DIR_REMOVE)
    EndIf
EndFunc ;==>_Cleanup

Func _GetDriveLetters()
    Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1)
    For $bd = 1 to $driveletter[0] step +1
        $bdStat = DriveStatus($driveletter[$bd] & ":")
        If $bdStat = "INVALID" Then
            $bootDrive=($driveletter[$bd])
            For $md = 1 to $driveletter[0] step +1
                $mdStat = DriveStatus($driveletter[$md] & ":")
                If Not ($bootDrive=($driveletter[$md])) Then
                    If $mdStat = "INVALID" Then
                        $mainDrive=($driveletter[$md])
                    EndIf
                EndIf
            Next
        EndIf
    Next
EndFunc ;==>_GetDriveLetters

But I still have a ways to go..

Edited by bobomb
Posted

I know I am trying to use less globals, they are temporary Im proly gonna have it read from a settings ini in its own folder for these paths later.

Posted

I just was editing my post with some rewritten code, see my previous post for some refactored code.

"general rule of thumb" functions should not have more then 10-20 lines of code but split frequently and give your function a meaningfull name describing your intent. The more you do that the less comments you will need in your coding.

Posted

Study this one 

https://www.autoitscript.com/autoit3/docs/functions/GUICtrlSetOnEvent.htm

You can put your gui in function a and by setting the events you can give each event a different function. This split will make your life easier in maintenance and shows clearly the intent of each action you want to do by splitting GUI from the actual functionality away.

And if you really want to learn more there are offcourse many references on the internet but this is a nice list of some good practices

https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29#file-clean_code-md

 

Posted (edited)

Halfway there, not sure how i want to break down the format functions yet..

#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=PrepareDiskNT.ico
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep)
#AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5
#AutoIt3Wrapper_Res_Fileversion=1.3
#AutoIt3Wrapper_Add_Constants=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $WinNTSetupPath = (@WorkingDir & "\") ;To run in the same folder as WinNTSetup5 instead of subfolder just use "\" instead of "\..\"
Global $CachePath = (@WorkingDir & "\cache\")
Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive

_Cleanup()

DirCreate($CachePath)
$listFile = FileOpen($CachePath & 'list.ini', 2)
FileWrite($listFile, 'lis dis')
FileClose($listFile)

GUICreate('Prep/Format Disk v1.3', 300, 298)
GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1)
GUISetBkColor (0x797979)
GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
$DiskList = GUICtrlCreateList('', 20, 30, 260, 150)
GUICtrlSetData(-1, _DiskList())
$Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
$MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40)
$GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40)
GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30)
GUISetState()

Do
    $Selection = GUIGetMsg()
    If $Selection = $MBR Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatMBR($DiskN[6])
                _IniWriteMBR()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
                Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
                EndSelect
        EndIf
    EndIf
    If $Selection = $GPT Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
        $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $iMsgBoxAnswer = 6 ;Yes
                _FormatGPT($DiskN[6])
                _IniWriteGPT()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
                Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE)
                _Cleanup()
                Exit
            Case $iMsgBoxAnswer = 7 ;No
        EndSelect
        EndIf
    EndIf
    If $Selection = $Refresh Then
        GUICtrlSetData($DiskList, "")
        GUICtrlSetData($DiskList, _DiskList())
    EndIf
Until $Selection = $GUI_EVENT_CLOSE
_Cleanup()

Func _DiskList()
    RunWait("cmd /c diskpart /s " & $CachePath & "list.ini>" & $CachePath & "list.txt", @WorkingDir, @SW_HIDE)
    Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF)
    For $RawList = 0 To UBound($Array) - 1
        If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|'
    Next
    $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '')
    Return $Filtered
EndFunc ;==>_DiskList

Func _FormatMBR($Drive)
    _GetDriveLetters()
    _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean')
    _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber')
    _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly')
    _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr')
    _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive)
    GUISetState(@SW_HIDE)
    ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc ;==>_FormatMBR

Func _FormatGPT($Drive)
    _GetDriveLetters()
    _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean')
    _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber')
    _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly')
    _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt')
    _writeInfoToFile($CachePath & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive)
    _writeInfoToFile($CachePath & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16')
    _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive)
    _writeInfoToFile($CachePath & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac')
    GUISetState(@SW_HIDE)
    ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%")
    ProgressSet(10 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(15 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(30 & "%", "Resetting Disk Attributes")
    RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(40 & "%", "Converting Disk to GPT")
    RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(50 & "%", "Formatting System Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatsystem.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(70 & "%", "Creating MSR")
    RunWait("cmd /c diskpart /s " & $CachePath & 'createmsr.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE)
    Sleep(1000)
    ProgressSet(90 & "%", "Formatting WinRE Partition")
    RunWait("cmd /c diskpart /s " & $CachePath & 'formatwinre.dat', @WorkingDir, @SW_HIDE)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc ;==>_FormatGPT

Func _writeInfoToFile($fileName, $message)
    $CacheFile = ''
    $CacheFile = FileOpen($fileName, 2)
    FileWrite($CacheFile, $message)
    FileClose($CacheFile)
EndFunc

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

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

Func _Cleanup()
    If FileExists($CachePath) Then
        DirRemove($CachePath, $DIR_REMOVE)
    EndIf
EndFunc ;==>_Cleanup

Func _GetDriveLetters()
    Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1)
    For $bd = 1 to $driveletter[0] step +1
        $bdStat = DriveStatus($driveletter[$bd] & ":")
        If $bdStat = "INVALID" Then
            $bootDrive=($driveletter[$bd])
            For $md = 1 to $driveletter[0] step +1
                $mdStat = DriveStatus($driveletter[$md] & ":")
                If Not ($bootDrive=($driveletter[$md])) Then
                    If $mdStat = "INVALID" Then
                        $mainDrive=($driveletter[$md])
                    EndIf
                EndIf
            Next
        EndIf
    Next
EndFunc ;==>_GetDriveLetters

 

Edited by bobomb
Posted (edited)

The variable paths I added introduced issues with paths with spaces, but I corrected it below, I also reduced the sleep times as they arent even needed (verified through testing) but it freaks me out when i jam that many commands at diskpart, even though it works i still dont trust it without letting it breathe a little.. officially you are supposed to wait 15 seconds between each diskpart script 😜

 

#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=PrepareDiskNT.ico
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep)
#AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5
#AutoIt3Wrapper_Res_Fileversion=1.3.0.0
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ListBoxConstants.au3>
#include <Constants.au3>
#include <File.au3>
#include <Array.au3>
#include <String.au3>

Global $WinNTSetupPath = (@WorkingDir & '\..\') ;To run in the same folder as WinNTSetup5 use "\" for subfolder use "\..\"
Global $CachePath = (@WorkingDir & '\cache\')
Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive

_Cleanup()

DirCreate($CachePath)
$listFile = FileOpen($CachePath & 'list.ini', 2)
FileWrite($listFile, 'lis dis')
FileClose($listFile)

GUICreate('Prep/Format Disk v1.3', 300, 298)
GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1)
GUISetBkColor(0x797979)
GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280)
$DiskList = GUICtrlCreateList('', 20, 30, 260, 150)
GUICtrlSetData(-1, _DiskList())
$Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
$MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 232, 120, 40)
$GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40)
GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30)
GUISetState()

Do
    $Selection = GUIGetMsg()
    If $Selection = $MBR Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
            $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
            Select
                Case $iMsgBoxAnswer = 6 ;Yes
                    _PrepMBR($DiskN[6])
                    _FormatMBR()
                    _IniWriteMBR()
                    MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
                    _LaunchWinNTSetup()
                    _Cleanup()
                    Exit
                Case $iMsgBoxAnswer = 7 ;No
            EndSelect
        EndIf
    EndIf
    If $Selection = $GPT Then
        Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
        Local $DiskN = StringSplit($Disk, "")
        Local $iMsgBoxAnswer
        If $Disk = "" Then
            MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
        Else
            $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
            Select
                Case $iMsgBoxAnswer = 6 ;Yes
                    _PrepGPT($DiskN[6])
                    _FormatGPT()
                    _IniWriteGPT()
                    MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
                    _LaunchWinNTSetup()
                    _Cleanup()
                    Exit
                Case $iMsgBoxAnswer = 7 ;No
            EndSelect
        EndIf
    EndIf
    If $Selection = $Refresh Then
        GUICtrlSetData($DiskList, "")
        GUICtrlSetData($DiskList, _DiskList())
    EndIf
Until $Selection = $GUI_EVENT_CLOSE
_Cleanup()

Func _DiskList()
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'list.ini' & '"' & '>' & '"' & $CachePath & 'list.txt' & '"', @WorkingDir, @SW_HIDE)
    Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF)
    For $RawList = 0 To UBound($Array) - 1
        If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|'
    Next
    $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '')
    Return $Filtered
EndFunc ;==>_DiskList

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

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

Func _GetDriveLetters()
    Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C", ",", 1)
    For $bd = 1 To $driveletter[0] Step +1
        $bdStat = DriveStatus($driveletter[$bd] & ":")
        If $bdStat = "INVALID" Then
            $bootDrive = ($driveletter[$bd])
            For $md = 1 To $driveletter[0] Step +1
                $mdStat = DriveStatus($driveletter[$md] & ":")
                If Not ($bootDrive = ($driveletter[$md])) Then
                    If $mdStat = "INVALID" Then
                        $mainDrive = ($driveletter[$md])
                    EndIf
                EndIf
            Next
        EndIf
    Next
EndFunc ;==>_GetDriveLetters

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

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

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

Func _LaunchWinNTSetup()
    Run('cmd /c ' & '"' & $WinNTSetupPath & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE)
EndFunc

Func _Cleanup()
    If FileExists($CachePath) Then
        DirRemove($CachePath, $DIR_REMOVE)
    EndIf
EndFunc ;==>_Cleanup

Func _FormatMBR()
    GUISetState(@SW_HIDE)
    ProgressOn("Getting BIOS (MBR) Ready...", "Preparing Disk: ", "0%")
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(30 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(40 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(50 & "%", "Resetting Disk Attributes")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(60 & "%", "Converting Disk Layout to MBR")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc

Func _FormatGPT()
    GUISetState(@SW_HIDE)
    ProgressOn("Getting UEFI (GPT) Ready...", "Preparing Disk: ", "0%")
    ProgressSet(10 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(15 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(20 & "%", "Cleaning Drive")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(30 & "%", "Resetting Disk Attributes")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(40 & "%", "Converting Disk to GPT")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(50 & "%", "Formatting System Partition")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatsystem.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(70 & "%", "Creating MSR")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'createmsr.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(80 & "%", "Formatting Windows Partition")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(90 & "%", "Formatting WinRE Partition")
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatwinre.dat' & '"', @WorkingDir, @SW_HIDE)
    Sleep(500)
    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc ;==>_FormatGPT

 

Edited by bobomb
Posted
  • Now I understand a little more from your script 
    rename _writeInfoToFile to _createDiskPartScriptFile as thats what you are actually doing
  • Some example of more refactoring with multidimensional array
    you have to uncomment the runwait command and the percentage calculation you can improve by (%i/ubound($aarray) * 100)
    The  more you split and refactor the easier it becomes for debugging and testing besides the benefit of readability and maintainability
_formatGPT()

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

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

    for $i=0 to ubound($aArray)-1
         consolewrite($aArray[$i][1] & @CRLF)
         ProgressSet($i*10 & "%", $aArray[$i][0])
         ; RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE)
        Sleep(500)
    Next

    ProgressSet(100, "Finished", "Format Completed")
    Sleep(1500)
    ProgressOff()
    GUISetState()
EndFunc
Posted (edited)

@junkew Here is the updated script with your recommendations added.

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

Global $WinNTSetupPath, $CachePath, $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive

_GetCachePath()
_GetWinNTSetupPath()
_Cleanup()

DirCreate($CachePath)
$listFile = FileOpen($CachePath & 'list.ini', 2)
FileWrite($listFile, 'lis dis')
FileClose($listFile)

Opt("GUIOnEventMode", 1)
_MainMenu()

_Cleanup()
Exit

Func _MainMenu()
   GUICreate('Prep/Format Disk v1.3', 300, 298)
   GUISetOnEvent($GUI_EVENT_CLOSE, "_SpecialEvents")
   GUISetOnEvent($GUI_EVENT_MINIMIZE, "_SpecialEvents")
   GUISetOnEvent($GUI_EVENT_RESTORE, "_SpecialEvents")

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

   GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30)
   $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 232, 120, 40)
   GUICtrlSetOnEvent(-1, "_MBRPressed")
   $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40)
   GUICtrlSetOnEvent(-1, "_GPTPressed")
   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, _DiskList())
EndFunc ;==>_RefreshPressed

Func _MBRPressed()
    Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
    Local $DiskN = StringSplit($Disk, "")
    Local $AreYouSure
    If $Disk = "" Then
        MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
    Else
        $AreYouSure = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $AreYouSure = 6 ;Yes
                _PrepMBR($DiskN[6])
                _FormatMBR()
                _IniWriteMBR()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive)
                _LaunchWinNTSetup()
                _Cleanup()
                Exit
            Case $AreYouSure = 7 ;No
        EndSelect
    EndIf
EndFunc ;==>MBRPressed

Func _GPTPressed()
    Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1')
    Local $DiskN = StringSplit($Disk, "")
    Local $AreYouSure
    If $Disk = "" Then
        MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected")
    Else
        $AreYouSure = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?')
        Select
            Case $AreYouSure = 6 ;Yes
                _PrepGPT($DiskN[6])
                _FormatGPT()
                _IniWriteGPT()
                MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive)
                _LaunchWinNTSetup()
                _Cleanup()
                Exit
            Case $AreYouSure = 7 ;No
        EndSelect
    EndIf
EndFunc ;==>_GPTPressed

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

Func _DiskList()
    RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'list.ini' & '"' & '>' & '"' & $CachePath & 'list.txt' & '"', @WorkingDir, @SW_HIDE)
    Local $Filtered = '', $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF)
    For $RawList = 0 To UBound($Array) - 1
        If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|'
    Next
    $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '')
    Return $Filtered
EndFunc ;==>_DiskList

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

Func _GetWinNTSetupPath()
    $WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\')
EndFunc

Func _GetCachePath()
    $CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache')
    $CachePath = ($CachePath & '\')
EndFunc

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

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

Func _LaunchWinNTSetup()
    Run('cmd /c ' & '"' & $WinNTSetupPath & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE)
EndFunc

Func _Cleanup()
    If FileExists($CachePath) Then
        DirRemove($CachePath, $DIR_REMOVE)
    EndIf
EndFunc ;==>_Cleanup

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

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

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

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

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

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

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

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

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

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

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

Also it checks for an INI for the program path..

PrepareDiskNT.ini

[Settings]
WinNTSetupPath=(Relative-OR-FullPathToExe)

No ini file

But all in all converting the sections is a great way to see how this stuff works. It was already working as messy code, and I was able to understand how each section should be behaving beforehand.. Very cool... 

Edited by bobomb
Posted

Code should read like a book 😉 if it doesn't most likely a few weeks later you will not understand your own code.

Some minor observations (but the last script I would consider final and readable)

  • The underscore is not needed and depends on coding style but in general I would use that more in UDF functions
  • Prep most likely means prepare I would write that _prepareMBR  (so the first time you read this you do not spend any second on interpreting what it means)
  • _MBRPressed I probably would only put in calls to 2 functions (basically rule of thumb split GUI related functions from the actual algorithm functions)
    and then your 2nd functionname is only executing the algorithm so you can easily replace your gui with a different one if needed or make your tool a cmdline version of it
    • validateGUI    --> There I would validate all things user did in the GUI to be correct
    • Instead of switch I would just use: if $areYouSure=$IDYES then <functionname>
  • read this page https://www.autoitscript.com/autoit3/docs/functions/MsgBox.htm
    • $IDYES (6)

 

Posted (edited)

@benners i tried to adapt what you taught me on the ISO burning tool and integrate it here, strangely, it is working fine in Windows but when I use it in WinPE Rescue environment I get Subscript used on non-accessible variable error (It did throw an error on regular windows too but it went away? which makes this really hard to troubleshoot) it seemed to be coming from the disk list array. However the burn tool we worked on does work properly in PE, I am so I was wondering if you see anything wrong with what I did here.  

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

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

Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

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

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

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

    ; Just idle around
    While 1
        Sleep(10)
    WEnd

EndFunc   ;==>MainMenu

Func RefreshPressed()
    DiskList_Load()
    DiskList_Selected()
EndFunc   ;==>RefreshPressed

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

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

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

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

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

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

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

    Return $s_DiskName
EndFunc   ;==>Disk_GetName

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

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

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

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

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

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

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

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

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

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

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

Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0, $iStart = 0)
    If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array
    If UBound($aSort, 2) = 0 Then Return SetError(4, 0, 0) ;array is 1D only
    If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array
    Local $1st, $2nd, $x, $j, $k, $l = 0
    For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense
        If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric
    Next
    $iStart = Int($iStart) < 0 ? 0 : Int($iStart) > 1 ? 1 : Int($iStart)
    If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) ;check if only one index is given
    _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0])
    Do
        $1st = $aIndices[$l]
        $2nd = $aIndices[$l + 1]
        $j = 0
        $k = 1
        While $k < UBound($aSort)
            If $aSort[$j][$1st] <> $aSort[$k][$1st] Then
                If $k - $j > 1 Then
                    _ArraySort($aSort, $iDir, $j, $k - 1, $2nd)
                    $j = $k
                Else
                    $j = $k
                EndIf
            EndIf
            $k += 1
        WEnd
        If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd)
        $l += 1
    Until $l = UBound($aIndices) - 1
    Return 1
EndFunc   ;==>_ArraySort_MultiColumn

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

Edited by bobomb
  • bobomb changed the title to Is it possible to move the GUI out of this function easily? (WinNTSetup format helper tool)
Posted

I can't see anything obvious with the code. If you think it is the disklist then you can add msgboxes to check the values. Put them in each loop before the other code and use the title to identify which loop it is, and in the text of the message box put the loop count and total count for the array.

MsgBox(0,'$as_Fixed', '$i: ' & $i & @CRLF & '$as_Fixed: ' & $as_Fixed[0])

MsgBox(0,'$as_DriveInfo', '$i: ' & $i & @CRLF & '$as_DriveInfo: ' & $as_DriveInfo[0][0])

There are basic checks to test the arrays are valid and the error points to trying to access the array element that doesn't exist.

Unless you can run the script itself in PE, not the exe, then check the output window

Posted (edited)

@benners I put those lines in the front of the loops and got the below return.. also this is happening on the burn tool as well, they run fine on my Win11 system but its hit or miss on Win10 systems that I tested on.. same error.. It was happening on my host Win11 machine last night for a few minutes but a reboot corrected it and I thought it was a fluke..

 

Capture.PNG

Capture2.PNG

From memory the bug that was reproduced (that i cannot reproduce now) was in this section, one of the [ ] variables...

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

Again this isnt just inside WinPE this happened almost all machines I tested this on today.. 

Edited by bobomb
Posted (edited)

I cannot get it to produce an error code or window in PE other than the one posted above referencing line 6732. The program must be compiled to run in PE as autoit resources are unavailable there.. As a side note I did get it to work with the original function I was using before @benners refined version... (working version posted below)

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

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

Cleanup()

DirCreate(GetCachePath())

Opt("GUIOnEventMode", 1)
MainMenu()

Cleanup()
Exit

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

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

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

    ; Just idle around
    While 1
        Sleep(10)
    WEnd

EndFunc   ;==>MainMenu

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

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

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

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

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

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

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

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

    Return $s_DiskName
EndFunc   ;==>Disk_GetName

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

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

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

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

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

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


Return $sOutput
EndFunc

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

I guess if it works like this its ok to leave it, Benners put a bit of effort out for the other method so would have liked to use it. Its good if we cant see anything obvious that there is already a working alternative though.

Edited by bobomb

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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