Bootloader installer 2.0 (C++ port)
This commit is contained in:
commit
c538f115f1
15 files changed
+1569
No files matched your search
@@ -0,0 +1,393 @@
|
||||
#include <GUIConstantsEx.au3>
|
||||
#include <WindowsConstants.au3>
|
||||
#include <MsgBoxConstants.au3>
|
||||
#include <StaticConstants.au3>
|
||||
#include <FileConstants.au3>
|
||||
#NoTrayIcon
|
||||
#RequireAdmin
|
||||
#pragma compile(Stripper, True)
|
||||
#pragma compile(ProductVersion, 3.2.0)
|
||||
#pragma compile(ProductName, "Change bootLoader")
|
||||
#pragma compile(FileDescription, CBL)
|
||||
#pragma compile(LegalCopyright, paravis.ru@2024)
|
||||
#pragma compile(CompanyName, paravis.ru@2024)
|
||||
|
||||
Opt("ExpandEnvStrings", 1)
|
||||
Opt("GUIOnEventMode", 0)
|
||||
Opt("MustDeclareVars", 1)
|
||||
|
||||
; --- оформление (как у установщика)
|
||||
Global Const $CLR_BG = 0xF1F4F9
|
||||
Global Const $CLR_HEAD = 0x1E2A44
|
||||
Global Const $CLR_DIM = 0x6B7280
|
||||
Global Const $CLR_BORDER = 0xBFC9D6
|
||||
Global Const $CLR_BTN = 0xFFFFFF
|
||||
Global Const $CLR_HOVER = 0xE4EEFF
|
||||
Global Const $CLR_PRESS = 0xCFE0FF
|
||||
Global Const $CLR_TEXT = 0x14202E
|
||||
|
||||
Global $sDisk = StringLeft(@ScriptDir, 2)
|
||||
Global $boot = ($sDisk & "\efi\Paravis\Boot")
|
||||
Global $bootice = ($boot & "\bootice.exe")
|
||||
|
||||
; защита: не даём случайно записать MBR в диск, где нет сборки Paravis
|
||||
If Not FileExists($bootice) Or Not FileExists($boot & "\NOT.DEL") Then
|
||||
MsgBox(BitOR($MB_ICONERROR, $MB_OK), "Change BootLoader", "Этот диск не является сборкой Paravis (нет bootice.exe или NOT.DEL):" & @CRLF & $sDisk)
|
||||
Exit
|
||||
EndIf
|
||||
|
||||
Global $hMain, $hMin, $hClose, $hTitle, $hSub
|
||||
Global $aFrame[7], $aBtn[7], $aBg[7], $aName[7]
|
||||
Global $gDown = -1, $gBusy = False, $gDrag = False, $gDragX = 0, $gDragY = 0
|
||||
Global $gMinBg = -1, $gCloseBg = -1
|
||||
|
||||
; --- окно
|
||||
$hMain = GUICreate("Change BootLoader", 376, 208, -1, -1, $WS_POPUP, $WS_EX_APPWINDOW)
|
||||
GUISetBkColor($CLR_BG, $hMain)
|
||||
GUISetFont(9, 400, 0, "Tahoma", $hMain)
|
||||
|
||||
; шапка
|
||||
Global $hHead = GUICtrlCreateLabel("", 0, 0, 376, 48)
|
||||
GUICtrlSetBkColor($hHead, $CLR_HEAD)
|
||||
|
||||
$hTitle = GUICtrlCreateLabel("Paravis Flash", 16, 2, 300, 24)
|
||||
GUICtrlSetFont($hTitle, 15, 700, 0, "Tahoma")
|
||||
GUICtrlSetColor($hTitle, 0xFFFFFF)
|
||||
GUICtrlSetBkColor($hTitle, $CLR_HEAD)
|
||||
|
||||
$hSub = GUICtrlCreateLabel("Смена загрузчика", 18, 27, 300, 14)
|
||||
GUICtrlSetColor($hSub, 0xC7D0E0)
|
||||
GUICtrlSetBkColor($hSub, $CLR_HEAD)
|
||||
|
||||
$hMin = GUICtrlCreateLabel("—", 306, 2, 30, 18, BitOR($SS_CENTER, $SS_CENTERIMAGE, $SS_NOTIFY))
|
||||
GUICtrlSetFont($hMin, 10, 400, 0, "Tahoma")
|
||||
GUICtrlSetColor($hMin, 0xC7D0E0)
|
||||
GUICtrlSetBkColor($hMin, $CLR_HEAD)
|
||||
|
||||
$hClose = GUICtrlCreateLabel("✕", 338, 2, 30, 18, BitOR($SS_CENTER, $SS_CENTERIMAGE, $SS_NOTIFY))
|
||||
GUICtrlSetFont($hClose, 9, 400, 0, "Tahoma")
|
||||
GUICtrlSetColor($hClose, 0xC7D0E0)
|
||||
GUICtrlSetBkColor($hClose, $CLR_HEAD)
|
||||
|
||||
; --- подписи секций
|
||||
Local $hSecL = GUICtrlCreateLabel("LEGACY BIOS", 15, 56, 200, 14)
|
||||
GUICtrlSetFont($hSecL, 8, 700, 0, "Tahoma")
|
||||
GUICtrlSetColor($hSecL, $CLR_DIM)
|
||||
GUICtrlSetBkColor($hSecL, $CLR_BG)
|
||||
|
||||
Local $hSecU = GUICtrlCreateLabel("UEFI", 15, 152, 200, 14)
|
||||
GUICtrlSetFont($hSecU, 8, 700, 0, "Tahoma")
|
||||
GUICtrlSetColor($hSecU, $CLR_DIM)
|
||||
GUICtrlSetBkColor($hSecU, $CLR_BG)
|
||||
|
||||
; --- кнопки: рамка 1 px + надпись
|
||||
$aName[0] = "XorBoot"
|
||||
$aName[1] = "Bootmgr"
|
||||
$aName[2] = "Grub4Dos"
|
||||
$aName[3] = "Grub2"
|
||||
$aName[4] = "Bootmgr"
|
||||
$aName[5] = "Grub2"
|
||||
$aName[6] = "Xorboot"
|
||||
|
||||
Local $aPos[7][4] = [ _
|
||||
[14, 72, 170, 32], _
|
||||
[192, 72, 170, 32], _
|
||||
[14, 110, 170, 32], _
|
||||
[192, 110, 170, 32], _
|
||||
[14, 168, 110, 32], _
|
||||
[132, 168, 110, 32], _
|
||||
[250, 168, 110, 32] ]
|
||||
|
||||
Local $i
|
||||
For $i = 0 To 6
|
||||
$aFrame[$i] = GUICtrlCreateLabel("", $aPos[$i][0] - 1, $aPos[$i][1] - 1, $aPos[$i][2] + 2, $aPos[$i][3] + 2)
|
||||
GUICtrlSetBkColor($aFrame[$i], $CLR_BORDER)
|
||||
$aBtn[$i] = GUICtrlCreateLabel($aName[$i], $aPos[$i][0], $aPos[$i][1], $aPos[$i][2], $aPos[$i][3], BitOR($SS_CENTER, $SS_CENTERIMAGE, $SS_NOTIFY))
|
||||
GUICtrlSetFont($aBtn[$i], 10, 400, 0, "Segoe UI Semibold")
|
||||
GUICtrlSetColor($aBtn[$i], $CLR_TEXT)
|
||||
GUICtrlSetBkColor($aBtn[$i], $CLR_BTN)
|
||||
$aBg[$i] = $CLR_BTN
|
||||
Next
|
||||
|
||||
GUISetState(@SW_SHOW, $hMain)
|
||||
AdlibRegister("_Poll", 40)
|
||||
|
||||
While 1
|
||||
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
|
||||
Sleep(30)
|
||||
WEnd
|
||||
|
||||
; ================= действия =================
|
||||
|
||||
Func _Run($idx)
|
||||
If $gBusy Then Return
|
||||
|
||||
; перед любым действием подтверждаем целевой диск
|
||||
If Not FileExists($boot & "\NOT.DEL") Or _DiskNumber($sDisk) < 0 Then
|
||||
_Msg("Целевой диск не подтверждён:" & @CRLF & $sDisk & @CRLF & _
|
||||
"нет \efi\Paravis\Boot\NOT.DEL или не найден PhysicalDrive.")
|
||||
Return
|
||||
EndIf
|
||||
|
||||
$gBusy = True
|
||||
Switch $idx
|
||||
Case 0
|
||||
_LegacyXor()
|
||||
Case 1
|
||||
_LegacyMgr()
|
||||
Case 2
|
||||
_LegacyG4d()
|
||||
Case 3
|
||||
_LegacyGrub2()
|
||||
Case 4
|
||||
_UefiMgr()
|
||||
Case 5
|
||||
_UefiGrub2()
|
||||
Case 6
|
||||
_UefiXor()
|
||||
EndSwitch
|
||||
$gBusy = False
|
||||
EndFunc
|
||||
|
||||
Func _LegacyXor()
|
||||
FileDelete($sDisk & "\bootmgr")
|
||||
FileDelete($sDisk & "\grldr")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /mbr /restore /file=" & $boot & "\xor\xmbr.bin /keep_dpt /quiet")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /pbr /restore /file=" & $boot & "\xor\xpbr.bin /keep_bpb /quiet")
|
||||
_Done("XorBoot")
|
||||
EndFunc
|
||||
|
||||
Func _LegacyMgr()
|
||||
FileDelete($sDisk & "\bootmgr")
|
||||
FileDelete($sDisk & "\grldr")
|
||||
FileCopy($boot & "\mgr\bootmgr", $sDisk & "\bootmgr")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /mbr /install /type=nt60 /quiet")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /pbr /install /type=bootmgr /quiet")
|
||||
_Done("Bootmgr")
|
||||
EndFunc
|
||||
|
||||
Func _LegacyG4d()
|
||||
FileDelete($sDisk & "\bootmgr")
|
||||
FileDelete($sDisk & "\grldr")
|
||||
FileCopy($boot & "\g4d\grldr", $sDisk & "\grldr")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /mbr /install /type=GRUB4DOS /quiet")
|
||||
RunWait($bootice & " /DEVICE=" & $sDisk & " /pbr /install /type=GRUB4DOS /quiet")
|
||||
_Done("Grub4Dos")
|
||||
EndFunc
|
||||
|
||||
Func _LegacyGrub2()
|
||||
Local $src = $boot & "\loaders\grub2-bios"
|
||||
Local $dst = $boot & "\grub2\bios"
|
||||
If Not FileExists($src & "\boot.img") Or Not FileExists($src & "\core.img") Then
|
||||
_Msg("Файлы GRUB2 для Legacy BIOS не найдены:" & @CRLF & $src)
|
||||
Return
|
||||
EndIf
|
||||
If Not FileExists($dst & "\grub.cfg") Then
|
||||
_Msg("Не найден основной grub.cfg:" & @CRLF & $dst & "\grub.cfg")
|
||||
Return
|
||||
EndIf
|
||||
|
||||
Local $disk = _DiskNumber($sDisk)
|
||||
If $disk < 0 Then
|
||||
_Msg("Не удалось определить номер физического диска для " & $sDisk)
|
||||
Return
|
||||
EndIf
|
||||
|
||||
; убрать файлы других Legacy-загрузчиков из корня
|
||||
FileDelete($sDisk & "\bootmgr")
|
||||
FileDelete($sDisk & "\grldr")
|
||||
|
||||
; дерево для core.img: модули и меню должны лежать по префиксу /efi/Paravis/Boot/grub2/bios
|
||||
DirCreate($dst)
|
||||
DirCreate($dst & "\i386-pc")
|
||||
FileCopy($src & "\boot.img", $dst & "\boot.img", 9)
|
||||
FileCopy($src & "\core.img", $dst & "\core.img", 9)
|
||||
FileCopy($src & "\make-paravis-mbr.ps1", $dst & "\make-paravis-mbr.ps1", 9)
|
||||
; grub.cfg НЕ копируем: в loaders лежит тестовое меню, рабочее уже в $dst
|
||||
RunWait(@ComSpec & ' /c xcopy /E /I /Y /Q "' & $src & '\i386-pc" "' & $dst & '\i386-pc" > nul 2>&1', "", @SW_HIDE)
|
||||
|
||||
; MBR-образ: наш boot.img (0..439) + текущая таблица разделов (440..511)
|
||||
Local $rc1 = RunWait('powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' & $dst & '\make-paravis-mbr.ps1" -Disk ' & $disk & ' -Boot "' & $dst & '\boot.img" -Out "' & $dst & '\paravis-mbr-table.img"', "", @SW_HIDE)
|
||||
If $rc1 <> 0 Then
|
||||
_Msg("Не удалось сформировать MBR-образ (код " & $rc1 & ").")
|
||||
Return
|
||||
EndIf
|
||||
|
||||
; Bootice /sectors: MBR (сектор 0) и core.img (с сектора 1); таблица разделов сохраняется
|
||||
Local $rc2 = RunWait('"' & $bootice & '" /DEVICE=' & $sDisk & ' /sectors /restore /file="' & $dst & '\paravis-mbr-table.img" /lba=0 /sectors=1 /quiet', "", @SW_HIDE)
|
||||
If $rc2 <> 0 Then
|
||||
_Msg("Ошибка записи MBR (код " & $rc2 & ").")
|
||||
Return
|
||||
EndIf
|
||||
Local $rc3 = RunWait('"' & $bootice & '" /DEVICE=' & $sDisk & ' /sectors /restore /file="' & $dst & '\core.img" /lba=1 /sectors=591 /quiet', "", @SW_HIDE)
|
||||
If $rc3 <> 0 Then
|
||||
_Msg("Ошибка записи core.img (код " & $rc3 & ").")
|
||||
Return
|
||||
EndIf
|
||||
_Done("Grub2 (Legacy)")
|
||||
EndFunc
|
||||
|
||||
Func _UefiMgr()
|
||||
_UefiClean()
|
||||
FileCopy($boot & "\mgr\UEFI\bootx64.efi", $sDisk & "\efi\boot\bootx64.efi")
|
||||
FileCopy($boot & "\mgr\UEFI\bootia32.efi", $sDisk & "\efi\boot\bootia32.efi")
|
||||
_Done("UEFI Bootmgr")
|
||||
EndFunc
|
||||
|
||||
Func _UefiGrub2()
|
||||
; bootia32 не трогаем: на ia32 остаётся XorBoot
|
||||
FileDelete($sDisk & "\efi\boot\bootx64.efi")
|
||||
FileDelete($sDisk & "\efi\boot\fbx64.efi")
|
||||
FileDelete($sDisk & "\efi\boot\mmx64.efi")
|
||||
FileCopy($boot & "\loaders\grub2\bootx64.efi", $sDisk & "\efi\boot\bootx64.efi")
|
||||
FileCopy($boot & "\loaders\grub2\fbx64.efi", $sDisk & "\efi\boot\fbx64.efi")
|
||||
FileCopy($boot & "\loaders\grub2\mmx64.efi", $sDisk & "\efi\boot\mmx64.efi")
|
||||
_Done("UEFI GRUB2")
|
||||
EndFunc
|
||||
|
||||
Func _UefiXor()
|
||||
_UefiClean()
|
||||
FileCopy($boot & "\xor\UEFI\bootx64.efi", $sDisk & "\efi\boot\bootx64.efi")
|
||||
FileCopy($boot & "\xor\UEFI\bootia32.efi", $sDisk & "\efi\boot\bootia32.efi")
|
||||
_Done("UEFI Xorboot")
|
||||
EndFunc
|
||||
|
||||
Func _UefiClean()
|
||||
FileDelete($sDisk & "\efi\boot\bootx64.efi")
|
||||
FileDelete($sDisk & "\efi\boot\bootia32.efi")
|
||||
FileDelete($sDisk & "\efi\boot\fbx64.efi")
|
||||
FileDelete($sDisk & "\efi\boot\mmx64.efi")
|
||||
EndFunc
|
||||
|
||||
; ================= служба =================
|
||||
|
||||
Func _Done($name)
|
||||
_Msg("Загрузчик изменён: " & $name)
|
||||
EndFunc
|
||||
|
||||
Func _Msg($text)
|
||||
Local $prev = $gBusy
|
||||
$gBusy = True
|
||||
MsgBox(BitOR($MB_ICONINFORMATION, $MB_OK), "Change BootLoader", $text)
|
||||
$gBusy = $prev
|
||||
EndFunc
|
||||
|
||||
Func _DiskNumber($letter)
|
||||
Local $oWMI = ObjGet("winmgmts:\\.\root\cimv2")
|
||||
If Not IsObj($oWMI) Then Return -1
|
||||
Local $col = $oWMI.ExecQuery("SELECT * FROM Win32_DiskDrive")
|
||||
If Not IsObj($col) Then Return -1
|
||||
For $d In $col
|
||||
Local $parts = $oWMI.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $d.DeviceID & "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition")
|
||||
If IsObj($parts) Then
|
||||
For $p In $parts
|
||||
Local $lds = $oWMI.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $p.DeviceID & "'} WHERE AssocClass=Win32_LogicalDiskToPartition")
|
||||
If IsObj($lds) Then
|
||||
For $l In $lds
|
||||
If StringUpper(String($l.DeviceID)) = StringUpper($letter) Then
|
||||
Return Number(StringRegExpReplace($d.DeviceID, ".*PHYSICALDRIVE(\d+).*", "$1"))
|
||||
EndIf
|
||||
Next
|
||||
EndIf
|
||||
Next
|
||||
EndIf
|
||||
Next
|
||||
Return -1
|
||||
EndFunc
|
||||
|
||||
Func _Poll()
|
||||
Local $ci = GUIGetCursorInfo($hMain)
|
||||
If Not IsArray($ci) Then Return
|
||||
|
||||
; кнопки шапки
|
||||
Local $minBg = $CLR_HEAD, $closeBg = $CLR_HEAD
|
||||
If $ci[4] = $hMin Then
|
||||
If $ci[2] = 1 Then
|
||||
$minBg = 0x3A4A6B
|
||||
Else
|
||||
$minBg = 0x2C3A57
|
||||
EndIf
|
||||
EndIf
|
||||
If $ci[4] = $hClose Then
|
||||
If $ci[2] = 1 Then
|
||||
$closeBg = 0xC0392B
|
||||
Else
|
||||
$closeBg = 0xE04B3F
|
||||
EndIf
|
||||
EndIf
|
||||
If $minBg <> $gMinBg Then
|
||||
GUICtrlSetBkColor($hMin, $minBg)
|
||||
$gMinBg = $minBg
|
||||
EndIf
|
||||
If $closeBg <> $gCloseBg Then
|
||||
GUICtrlSetBkColor($hClose, $closeBg)
|
||||
$gCloseBg = $closeBg
|
||||
EndIf
|
||||
|
||||
; нажатия в шапке
|
||||
Static $minDown = False, $closeDown = False
|
||||
If $ci[4] = $hMin And $ci[2] = 1 Then
|
||||
$minDown = True
|
||||
ElseIf $minDown Then
|
||||
$minDown = False
|
||||
If $ci[4] = $hMin And $ci[2] = 0 Then GUISetState(@SW_MINIMIZE, $hMain)
|
||||
EndIf
|
||||
If $ci[4] = $hClose And $ci[2] = 1 Then
|
||||
$closeDown = True
|
||||
ElseIf $closeDown Then
|
||||
$closeDown = False
|
||||
If $ci[4] = $hClose And $ci[2] = 0 Then Exit
|
||||
EndIf
|
||||
|
||||
; перетаскивание за шапку
|
||||
If ($ci[4] = $hHead Or $ci[4] = $hTitle Or $ci[4] = $hSub) And $ci[2] = 1 And Not $gDrag Then
|
||||
Local $m = MouseGetPos()
|
||||
Local $w = WinGetPos($hMain)
|
||||
If IsArray($m) And IsArray($w) Then
|
||||
$gDrag = True
|
||||
$gDragX = $m[0] - $w[0]
|
||||
$gDragY = $m[1] - $w[1]
|
||||
EndIf
|
||||
EndIf
|
||||
If $gDrag Then
|
||||
If $ci[2] = 0 Then
|
||||
$gDrag = False
|
||||
Else
|
||||
Local $m2 = MouseGetPos()
|
||||
If IsArray($m2) Then WinMove($hMain, "", $m2[0] - $gDragX, $m2[1] - $gDragY)
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
; подсветка кнопок
|
||||
Local $i
|
||||
For $i = 0 To 6
|
||||
Local $bg = $CLR_BTN
|
||||
If $ci[4] = $aBtn[$i] Or $ci[4] = $aFrame[$i] Then
|
||||
If $ci[2] = 1 Then
|
||||
$bg = $CLR_PRESS
|
||||
Else
|
||||
$bg = $CLR_HOVER
|
||||
EndIf
|
||||
EndIf
|
||||
If $aBg[$i] <> $bg Then
|
||||
GUICtrlSetBkColor($aBtn[$i], $bg)
|
||||
$aBg[$i] = $bg
|
||||
EndIf
|
||||
Next
|
||||
|
||||
; клик по кнопке
|
||||
If $gBusy Then Return
|
||||
If $ci[2] = 1 Then
|
||||
For $i = 0 To 6
|
||||
If $ci[4] = $aBtn[$i] Or $ci[4] = $aFrame[$i] Then
|
||||
$gDown = $i
|
||||
Return
|
||||
EndIf
|
||||
Next
|
||||
$gDown = -1
|
||||
ElseIf $gDown >= 0 Then
|
||||
Local $idx = $gDown
|
||||
$gDown = -1
|
||||
If $ci[4] = $aBtn[$idx] Or $ci[4] = $aFrame[$idx] Then _Run($idx)
|
||||
EndIf
|
||||
EndFunc
|
||||
Reference in new issue
Block a user