脚本:Grub4DOS Toolbox for Windows
优质
小牛编辑
131浏览
2023-12-01
引用Grub4DOS Toolbox for Windows.nsi:
#------------------------------------------------------------------------------------------# # Project settings SetCompressor /SOLID /FINAL lzma Name "Grub4DOS Toolbox for Windows" !define PROJECT "Grub4DOS Toolbox for Windows" !define VERSION "0.1" OutFile "${PROJECT}-${VERSION}.exe" Caption "${PROJECT} ${VERSION}" BrandingText "${PROJECT} by farter" RequestExecutionLevel user !define MULTIUSER_EXECUTIONLEVEL Standard !define MUI_CUSTOMFUNCTION_ABORT CleanUp !include MultiUser.nsh !include FileFunc.nsh !include WordFunc.nsh !include MUI2.nsh !include x64.nsh !insertmacro GetDrives !insertmacro GetSize !define mdb "!insertmacro debugcb" !macro debugcb Parameter MessageBox MB_OK "${Parameter}" !macroend #------------------------------------------------------------------------------------------# # Used constants and variables !define Sectors 49152 Var /GLOBAL WinVer Var /GLOBAL msg Var /GLOBAL LogFile Var /GLOBAL TempFolder Var /GLOBAL PriPtNumber Var /GLOBAL ExtPtNumber Var /GLOBAL TaskListBox Var /GLOBAL TaskNumber Var /GLOBAL TextBox Var /GLOBAL TargetFile Var /GLOBAL FileToPatch Var /GLOBAL PatchedFile Var /GLOBAL MenuFile Var /GLOBAL TargetFile2 Var /GLOBAL TargetFile3 Var /GLOBAL DoButton Var /GLOBAL FileUI1 Var /GLOBAL FilePath1 Var /GLOBAL FileBrowseButton1 Var /GLOBAL FileUI2 Var /GLOBAL FilePath2 Var /GLOBAL FileBrowseButton2 Var /GLOBAL FileUI3 Var /GLOBAL FilePath3 Var /GLOBAL FileBrowseButton3 Var /GLOBAL CheckBox1 Var /GLOBAL DropList1 Var /GLOBAL Label1 Var /GLOBAL Label2 Var /GLOBAL Label3 Var /GLOBAL Label4 #------------------------------------------------------------------------------------------# # UI setting #!define MUI_ICON icon.ico !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH #!define MUI_HEADERIMAGE_BITMAP "logo.bmp" #------------------------------------------------------------------------------------------# # win32 API defines !define MAX_DISKS 24 !define FILE_DEVICE_MASS_STORAGE 0x2D !define FILE_DEVICE_DISK 0x00000007 !define GENERIC_READ 0x80000000 !define GENERIC_WRITE 0x40000000 !define GENERIC_ALL 0x10000000 !define FILE_ANY_ACCESS 0 !define FILE_READ_ACCESS 1 !define FILE_SHARE_READ 1 !define FILE_SHARE_WRITE 2 !define CREATE_ALWAYS 2 !define OPEN_ALWAYS 4 !define OPEN_EXISTING 3 !define FSCTL_GET_NTFS_VOLUME_DATA 0x00090064 !define FILE_ATTRIBUTE_NORMAL 0x80 !define NTFS_VOLUME_DATA_SIZE 96 !define METHOD_BUFFERED 0 !define METHOD_IN_DIRECT 1 !define METHOD_NEITHER 3 !define FILE_FLAG_WRITE_THROUGH 0x80000000 !define FILE_FLAG_NO_BUFFERING 0x20000000 #define CTL_CODE(DeviceType, Function, Method, Access) ( ((DeviceType) << 16) |\ ((Access) << 14) | ((Function) << 2) | (Method) ) !define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE !define IOCTL_DISK_BASE FILE_DEVICE_DISK #define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) !define IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400 #define IOCTL_DISK_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_DISK_BASE, 0x0000, METHOD_BUFFERED, FILE_ANY_ACCESS) !define IOCTL_DISK_GET_DRIVE_GEOMETRY 0x00070000 #define IOCTL_DISK_GET_DRIVE_LAYOUT CTL_CODE(IOCTL_DISK_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS) !define IOCTL_DISK_GET_DRIVE_LAYOUT 0x0007400C !define PropertyStandardQuery 0 !define StorageDeviceProperty 0 !define ERROR_HANDLE_EOF 38 #------------------------------------------------------------------------------------------# # Pages PageEx custom PageCallbacks Main PageExEnd #!insertmacro MUI_PAGE_INSTFILES #------------------------------------------------------------------------------------------# # Sections Section Dummy DummyFlag SectionEnd #------------------------------------------------------------------------------------------# # Functions #--------------------------------------------# # Installer init Function .onInit # Check user previledge !insertmacro MULTIUSER_INIT ${If} $MultiUser.Privileges != "Admin" MessageBox MB_YesNo|MB_ICONEXCLAMATION "你不是以管理员身份运行本软件。$\n\ 某些功能将不能正确运行!$\n$\n\ 你是否仍然继续?" IDYES +2 IDNO 0 Quit Nop ${EndIf} # Check multiple instances System::Call /NOUNLOAD 'kernel32::CreateMutexA(i 0, i 0, t "myMutex") i .r1 ?e' Pop $R0 ${If} $R0 != 0 MessageBox MB_OK|MB_ICONEXCLAMATION "本软件的另一实例已经运行!$\n$\n\ 点击 '确定' 退出." Quit ${Endif} # Check Grub4DOS files IfFileExists $EXEDIR\grldr +3 0 MessageBox MB_OK|MB_ICONEXCLAMATION "本软件必须运行于\ 已解包的 Grub4DOS 文件夹内!$\n$\n\ (即包含grldr,grldr.mbr,bootlace.com的文件夹)$\n$\n\ 点击 '确定' 退出。" Quit IfFileExists $EXEDIR\grldr.mbr 0 -2 IfFileExists $EXEDIR\bootlace.com 0 -3 # Get Windows version ClearErrors ReadRegStr $WinVer HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion IfErrors 0 +3 MessageBox MB_YesNo|MB_ICONEXCLAMATION "你的 Windows 版本太低 。$\n$\n\ 本软件很多功能不能正确执行!$\n$\n\ 你是否仍然继续?" IDYES +3 IDNO 0 Quit IntCmpU $WinVer 5 0 -2 0 ${If} ${RunningX64} ${DisableX64FSRedirection} ${EndIf} Strcpy $TempFolder "$TEMP\G4Dtemp" CreateDirectory $TempFolder SetOutpath $TempFolder SectionSetFlags ${DummyFlag} 0 StrCpy $LogFile "$EXEDIR\${PROJECT}.log" FunctionEnd #--------------------------------------------# # Handles main dropdown list and action button Function Main !insertmacro MUI_HEADER_TEXT "从 列表中选择一个任务" \ "点击 按钮,执行这个任务。" # Disable and hide 'Install' button, rename 'Cancel' to 'Exit' GetDlgItem $0 $HWNDPARENT 1 ShowWindow $0 ${SW_HIDE} EnableWindow $0 0 GetDlgItem $0 $HWNDPARENT 2 ${NSD_SetText} $0 "退出" # Create dropdown task list and action button nsDialogs::Create /NOUNLOAD 1018 Pop $0 ${If} $0 == error Call CleanUp Quit ${EndIf} ${NSD_CreateLabel} 18u 2u 30u 13u "任务:" Pop $0 ${NSD_CreateDroplist} 52u 0 190u 13u "" Pop $TaskListBox ${NSD_SetFocus} $TaskListBox ${NSD_OnChange} $TaskListBox TaskChange ${NSD_CreateButton} 250u 0 40u 13u "" Pop $DoButton ${NSD_SetText} $DoButton "执行" ${NSD_OnClick} $DoButton DoCallBack SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:安装 Grub4DOS 到磁盘或分区 (通过 bootlace.com) " SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:恢复磁盘或分区的引导扇区 (通过已备份的镜像文件)" SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:将Grub4Dost添加到bootmgr启动项中(Vista/2008以上)" SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:修改 grldr.mbr (修改grldr.mbr内建的引导文件名)" SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:修改 grldr(修改菜单中或grldr中内建的引导文件名)" SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:显示已挂载的 Windows 分区的 UUID " SendMessage $TaskListBox ${CB_ADDSTRING} 0 "STR:查看版本信息" Call TaskChange nsDialogs::Show FunctionEnd #--------------------------------------------# # Handels action button click Function DoCallBack SendMessage $TaskListBox ${CB_GETCURSEL} 0 0 $TaskNumber ${If} $TaskNumber == -1 Return ${EndIf} # Display UUID and release info ${If} $TaskNumber > 4 ${If} $TaskNumber == 5 Call DisplayUUID ${Else} Call DisplayInfo ${EndIf} Return ${EndIf} # Handles conditional bootmgr task first ${If} $TaskNumber == 2 ${If} $WinVer >= 6 Call Bootmgr Return ${Else} # Shouldn't get here, but just in case Call TaskChange Return ${EndIf} ${EndIf} # Check target file name in $R0 ${If} $TaskNumber == 0 ${NSD_GetText} $FilePath3 $R0 StrCpy $R2 $FilePath3 ${ElseIf} $TaskNumber > 2 ${NSD_GetText} $FilePath1 $R0 StrCpy $R2 $FilePath1 ${EndIf} # Restore task has no target file ${If} $TaskNumber != 1 Call CheckFileName ${If} $R0 == "" MessageBox MB_OK|MB_ICONEXCLAMATION "你必须选择一个有效的目标文件名!" ${NSD_SetFocus} $R2 Return ${EndIf} # Enfore 8.3 format ${WordFind} $R0 "." "*" $R1 ${If} $R1 > 0 ${If} $R1 > 1 lbldo83check: MessageBox MB_OK|MB_ICONEXCLAMATION "目标文件必须是 8.3 文件名格式!" ${NSD_SetFocus} $R2 Return ${Else} ${WordFind} $R0 "." "+02" $R1 StrLen $R1 $R1 ${If} $R1 > 3 Goto lbldo83check ${EndIf} ${EndIf} ${Else} StrLen $R1 $R0 ${If} $R1 > 8 Goto lbldo83check ${EndIf} ${EndIf} StrLen $R1 $R0 ${If} $R1 > 12 Goto lbldo83check ${EndIf} StrCpy $TargetFile $R0 ${EndIf} ${If} $TaskNumber 4096 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$R2 大于 4096 字节,在修改时它可以被截短 $\n$\n\ 你是否继续?" IDYES +2 IDNO 0 Return ${EndIf} StrCpy $MenuFile $R2 ${EndIf} ${EndIf} Call Patch FunctionEnd #--------------------------------------------# # Handles patch tasks Function Patch ${If} $TaskNumber == 3 StrCpy $FileToPatch "$EXEDIR\grldr.mbr" ${Else} StrCpy $FileToPatch "$EXEDIR\grldr" ${EndIf} StrCpy $R0 $PatchedFile StrCpy $PatchedFile $TempFolder\patched.bin Call PatchFileName Pop $0 ${If} $0 == "error" Return ${EndIf} ${If} $TaskNumber != 3 ${AndIf} $MenuFile != "" Call PatchMenu ${EndIf} Pop $0 ${If} $0 == "error" Return ${EndIf} CopyFiles /SILENT $PatchedFile $R0 MessageBox MB_OK "$R0 已被保存." Return FunctionEnd #--------------------------------------------# # Patch menu.lst of $PatchedFile with $MenuFile Function PatchMenu System::Store "S" IntOp $R0 512 << 6 # Read source file StrCpy $R1 $PatchedFile System::Call "kernel32::CreateFile(t R1, i ${GENERIC_ALL}, \ i ${FILE_SHARE_READ} | ${FILE_SHARE_WRITE}, i 0, \ i ${OPEN_EXISTING}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R1" ${If} $R1 $R2 MessageBox MB_OK|MB_ICONEXCLAMATION "$FileToPatch 文件不是一个有效的Grub4DOS文件" lblpatchmenu1: System::Call "kernel32::CloseHandle(i R1)" Goto lblpatchmenu ${EndIf} System::Alloc 512 Pop $R3 ${For} $R9 0 63 System::Call "kernel32::ReadFile(i R1, i R3 , i 512, *i .R4, i ..)" ${If} $R4 != 512 MessageBox MB_OK|MB_ICONEXCLAMATION "临时文件读取错误" lblpatchmenu2: System::Free $R3 Goto lblpatchmenu1 ${EndIf} System::Call "*$R3(i .R4)" IntFmt $R4 "0x%08X" $R4 ${If} $R4 == 0x008270EA ${ExitFor} ${EndIf} ${Next} ${If} $R4 != 0x008270EA lblpatchmenu3: MessageBox MB_OK|MB_ICONEXCLAMATION "$FileToPatch 文件不是一个有效的Grub4DOS文件" Goto lblpatchmenu2 ${EndIf} System::Call "*$R3(&i108 .., i .R4)" IntOp $R4 $R4 - 0x83F0 ${If} $R4 < 0 Goto lblpatchmenu3 ${EndIf} System::Free $R3 System::Call "kernel32::SetFilePointer(i R1, i R4, i 0, i 1) i .R5" ${If} $R5 < 0 Goto lblpatchmenu3 ${EndIf} FileOpen $0 $MenuFile r ${If} $0 == "" MessageBox MB_OK|MB_ICONEXCLAMATION "$MenuFile 打开错误" Goto lblpatchmenu4 ${EndIf} lblpatchmenuloop: ClearErrors FileRead $0 $1 IfErrors lblpatchmenuloopend StrCpy $2 $1 1 ${If} $2 == "#" ${OrIf} $2 == "$\n" ${OrIf} $2 == "$\r" Goto lblpatchmenuloop ${EndIf} FileWrite $R1 $1 Goto lblpatchmenuloop lblpatchmenuloopend: FileClose $0 lblpatchmenu4: System::Call "kernel32::SetEndOfFile(i R1)" System::Call "kernel32::CloseHandle(i R1)" System::Store "L" Push "success" Return FunctionEnd #--------------------------------------------# # Setup appropriate UI for selected task Function TaskChange # Clear UI SendMessage $TextBox ${WM_CLOSE} 0 0 SendMessage $FileUI1 ${WM_CLOSE} 0 0 SendMessage $FilePath1 ${WM_CLOSE} 0 0 SendMessage $FileBrowseButton1 ${WM_CLOSE} 0 0 SendMessage $FileUI2 ${WM_CLOSE} 0 0 SendMessage $FilePath2 ${WM_CLOSE} 0 0 SendMessage $FileBrowseButton2 ${WM_CLOSE} 0 0 SendMessage $FileUI3 ${WM_CLOSE} 0 0 SendMessage $FilePath3 ${WM_CLOSE} 0 0 SendMessage $FileBrowseButton3 ${WM_CLOSE} 0 0 SendMessage $CheckBox1 ${WM_CLOSE} 0 0 SendMessage $DropList1 ${WM_CLOSE} 0 0 SendMessage $Label1 ${WM_CLOSE} 0 0 SendMessage $Label2 ${WM_CLOSE} 0 0 SendMessage $Label3 ${WM_CLOSE} 0 0 SendMessage $Label4 ${WM_CLOSE} 0 0 SendMessage $TaskListBox ${CB_GETCURSEL} 0 0 $TaskNumber ${If} $TaskNumber == -1 EnableWindow $DoButton 0 Return ${EndIf} # Handles conditional bootmgr task first ${If} $TaskNumber == 2 ${AndIf} $WinVer 4 nsDialogs::CreateControl /NOUNLOAD ${__NSD_Text_CLASS} \ ${DEFAULT_STYLES}|${WS_TABSTOP}|${ES_MULTILINE}|${ES_READONLY}|${WS_VSCROLL} \ ${__NSD_Text_EXSTYLE} 0 43 100% 70% "" Pop $TextBox Call DoCallBack Return ${EndIf} # Bootmgr task ${If} $TaskNumber == 2 ${NSD_CreateGroupBox} 7u 20u -13u 35u "选择将使用的 bootmgr 文件 (留空将使用 Windows 默认的):" Pop $FileUI1 ${NSD_CreateDropList} 20u 34u -95u 13u "" Pop $FilePath1 ${NSD_CreateBrowseButton} -70u 34u 50u 13u "刷新" Pop $FileBrowseButton1 ${NSD_OnClick} $FileBrowseButton1 GetBootmgr ${NSD_CreateGroupBox} 7u 60u -13u 35u "输入将使用的 Grub4DOS 的 mbr 文件名:" Pop $FileUI2 ${NSD_CreateDirRequest} 20u 74u -95u 13u "" Pop $FilePath2 ${NSD_SetText} $FilePath2 "grldr.mbr" ${NSD_CreateGroupBox} 7u 100u -13u 35u "为在 bootmgr 中的 GRUB4DOS 启动项指定选项:" Pop $FileUI3 ${NSD_CreateLabel} 20u 116u 20u 13u "Title:" Pop $Label1 ${NSD_CreateDirRequest} 40u 114u 70u 13u "Grub4DOS" Pop $FilePath3 ${NSD_CreateCheckBox} 125u 114u 65u 13u "Boot by default" Pop $CheckBox1 ${NSD_CreateLabel} 195u 116u 65u 13u "Timeout (seconds)" Pop $Label2 ${NSD_CreateDroplist} 262u 114u 25u 13u "" Pop $DropList1 SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:5" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:15" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:30" Call GetBootmgr Return ${EndIf} # bootlace.com and restore tasks ${If} $TaskNumber < 2 ${If} $TaskNumber < 1 ${NSD_CreateGroupBox} 7u 20u -13u 50u "选择 GRUB4DOS 安装到的目标设备:" ${Else} ${NSD_CreateGroupBox} 7u 20u -13u 50u "选择恢复到的目标设备:" ${EndIf} Pop $FileUI1 ${NSD_CreateLabel} 20u 34u 30u 13u "磁盘: " Pop $Label1 ${NSD_CreateDroplist} 55u 33u 180u 13u "" Pop $FilePath1 ${NSD_OnChange} $FilePath1 EnumParts ${NSD_CreateButton} 245u 33u 40u 13u "刷新" Pop $FileBrowseButton1 ${NSD_OnClick} $FileBrowseButton1 EnumDisks ${NSD_CreateLabel} 20u 50u 30u 13u "分区: " Pop $Label2 ${NSD_CreateDroplist} 55u 49u 180u 13u "" Pop $FilePath2 ${NSD_OnChange} $FilePath2 AutoSetOptions ${NSD_CreateButton} 245u 49u 40u 13u "刷新" Pop $FileBrowseButton2 ${NSD_OnClick} $FileBrowseButton2 EnumParts ${If} $TaskNumber < 1 ${NSD_CreateGroupBox} 7u 75u -13u 65u "设置bootlace.com安装选项:" Pop $FileUI2 ${NSD_CreateLabel} 15u 90u 40u 13u "引导文件:" Pop $Label3 ${NSD_CreateDirRequest} 55u 89u 50u 13u "" Pop $FilePath3 ${NSD_SetText} $FilePath3 "grldr" ${NSD_CreateLabel} 110u 90u 30u 13u "选项:" Pop $Label4 ${NSD_CreateDroplist} 142u 89u 145u 13u "" Pop $DropList1 SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--read-only" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--mbr-no-bpb" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--no-backup-mbr" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--force-backup-mbr" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--mbr-enable-floppy" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--mbr-disable-floppy" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--mbr-enable-osbr" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--mbr-disable-osbr" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--duce" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--chs-no-tune" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--boot-prevmbr-first" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--boot-prevmbr-last" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--preferred-drive=0" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--preferred-partition=0" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--serial-number=1" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--time-out=5" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--hot-key=0x3920" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--floppy" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--floppy=0" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--sectors-per-track=63" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--heads=255" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--start-sector=1" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--total-sectors=0" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--lba" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--chs" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--fat12" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--fat16" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--fat32" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--vfat" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--ntfs" SendMessage $DropList1 ${CB_ADDSTRING} 0 "STR:--ext2" ${NSD_OnChange} $DropList1 SetOptions nsDialogs::CreateControl /NOUNLOAD ${__NSD_Text_CLASS} \ ${DEFAULT_STYLES}|${WS_TABSTOP}|${ES_MULTILINE}|${WS_VSCROLL} \ ${__NSD_Text_EXSTYLE} 20 75% -35 20% "" Pop $TextBox # Restore task ${Else} ${NSD_CreateGroupBox} 7u 100u -13u 35u "选择已备份的镜像文件:" Pop $FileUI3 ${NSD_CreateDirRequest} 20u 114u -95u 13u "" Pop $FilePath3 ${NSD_CreateBrowseButton} -70u 114u 50u 13u "浏览" Pop $FileBrowseButton3 StrCpy $TargetFile3 "*.bin" ${NSD_OnClick} $FileBrowseButton3 BrowseFile3 ${EndIf} Call EnumDisks Return ${EndIf} # Patch file tasks ${NSD_CreateGroupBox} 7u 20u -13u 35u "指定目标文件名:" Pop $FileUI1 ${NSD_CreateDirRequest} 20u 34u -95u 13u "" Pop $FilePath1 ${NSD_SetText} $FilePath1 "mygrldr" ${If} $TaskNumber == 4 ${NSD_CreateGroupBox} 7u 60u -13u 35u "选择被使用的 menu.lst 文件:" Pop $FileUI2 ${NSD_CreateDirRequest} 20u 74u -95u 13u "" Pop $FilePath2 ${NSD_SetText} $FilePath2 $EXEDIR\menu.lst ${NSD_CreateBrowseButton} -70u 74u 50u 13u "浏览" Pop $FileBrowseButton2 StrCpy $TargetFile2 "*.lst" ${NSD_OnClick} $FileBrowseButton2 BrowseFile2 ${EndIf} ${NSD_CreateGroupBox} 7u 100u -13u 35u "指定输出文件:" Pop $FileUI3 ${NSD_CreateDirRequest} 20u 114u -95u 13u "" Pop $FilePath3 ${NSD_CreateBrowseButton} -70u 114u 50u 13u "浏览" Pop $FileBrowseButton3 ${If} $TaskNumber == 4 ${NSD_SetText} $FilePath3 "$EXEDIR\mygrldr" ${EndIf} StrCpy $TargetFile3 "*.*" ${NSD_OnClick} $FileBrowseButton3 BrowseFile3 FunctionEnd #--------------------------------------------# # Install using bootlace.com Function Install # Get file handle $R4 StrCpy $R4 0 System::Call "kernel32::CreateFile(t R3, i ${GENERIC_READ}, i ${FILE_SHARE_WRITE}, \ i 0, i ${OPEN_EXISTING}, i 0, i 0) i .R4" ${If} $R4 = 0 System::Alloc 4096 Pop $1 System::Call "kernel32::DeviceIoControl(i R4, i ${IOCTL_DISK_GET_DRIVE_LAYOUT}, i 0, \ i 0, i r1, i 4096, *i .R5, i 0) i .r2" ${If} $2 == 0 MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" Goto lblinstallret ${EndIf} System::Call "*$1(i .r2)" ${If} $2 < 1 MessageBox MB_OK|MB_ICONEXCLAMATION "获取分区信息错误" System::Free $1 lblinstallret: System::Call "kernel32::CloseHandle(i R4)" ${NSD_SetFocus} $FilePath1 Call EnumDisks Return ${EndIf} StrCpy $PriPtNumber 0 StrCpy $ExtPtNumber 4 IntOp $0 $1 + 8 ${For} $3 1 $2 System::Call "*$0(l .R5)" ${If} $R5 != 0 System::Call "*$0(&i20 .., i .r7)" ${If} $7 == 0 ${If} $3 <= 4 # Extended partition IntOp $PriPtNumber $PriPtNumber + 1 ${EndIf} GoTo lblinstallloop ${EndIf} ${If} $3 = 0 System::Call "kernel32::SetFilePointerEx(i R4, l R5, *l .R6, 0)" System::Int64Op $R5 = $R6 Pop $R6 ${If} $R6 != 1 MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" Goto lblinstallret ${EndIf} ${EndIf} # Read sectors System::Alloc ${Sectors} Pop $R6 System::Call "kernel32::ReadFile(i R4, i R6 , i ${Sectors}, *i .R7, i ..)" ${If} $R7 != ${Sectors} MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" lblinstallret1: System::Free $R6 GoTo lblinstallret ${EndIf} System::Call "kernel32::CloseHandle(i R4)" # Save sector file StrCpy $R4 $TempFolder\image.bin System::Call "kernel32::CreateFile(t R4, i ${GENERIC_READ}|${GENERIC_WRITE}, i 0, i 0, \ i ${CREATE_ALWAYS}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R4" ${If} $R4 <= 0 MessageBox MB_OK|MB_ICONEXCLAMATION "建立镜像文件错误" GoTo lblinstallret1 ${EndIf} System::Call "kernel32::WriteFile(i R4, i R6 , i ${Sectors}, *i .R7, i ..)" ${If} $R7 != ${Sectors} MessageBox MB_OK|MB_ICONEXCLAMATION "写入镜像文件错误" GoTo lblinstallret1 ${EndIf} System::Call "kernel32::CloseHandle(i R4)" CopyFiles /SILENT $TempFolder\image.bin $TempFolder\image.bak # Patch and call bootlace.com StrCpy $FileToPatch $EXEDIR\bootlace.com StrCpy $PatchedFile $TempFolder\bootlace.com Call PatchFileName Pop $0 ${If} $0 == "error" Return ${EndIf} # Get bootlace.com options $R8 ${NSD_GetText} $TextBox $R8 ${WordReplace} $R8 "$\n" "" "+" $R8 ${WordReplace} $R8 "$\r" "" "+" $R8 ${WordReplace} $R8 "$\t" " " "+" $R8 nsExec::ExecToStack '"bootlace.com" $R8 image.bin' Pop $0 Pop $1 ${WordReplace} $1 "Invalid keyboard code specified$\r" " " "+" $1 ${If} $0 != 0 ${WordFind3X} $1 "$\r" "Error" "$\r" "+1" $1 StrCpy $1 "Bootlace.com 返回以下错误信息:$\r$\n\ --------------------------------------------------------------$\r$\r\ $1$\r$\r\ --------------------------------------------------------------" MessageBox MB_OK "$1" System::Free $R6 Return ${EndIf} # Wirte sectors if not 'read-only' StrCpy $1 "Bootlace.com 返回以下成功信息:$\r\ --------------------------------------------------------------$\r$1\ --------------------------------------------------------------" ${WordReplace} $R8 "--read-only" "" "+" $R9 ${If} $R8 != $R9 MessageBox MB_OK "$1" System::Free $R6 Return ${EndIf} StrCpy $1 "$1$\r是否正式写入目标设备" MessageBox MB_YESNO "$1" IDYES +3 IDNO 0 System::Free $R6 Return # Read sector file StrCpy $R4 $TempFolder\image.bin System::Call "kernel32::CreateFile(t R4, i ${GENERIC_READ}|${GENERIC_WRITE}, i 0, i 0, \ i ${OPEN_EXISTING}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R4" ${If} $R4 <= 0 MessageBox MB_OK|MB_ICONEXCLAMATION "Error opening image file!" GoTo lblinstallret1 ${EndIf} System::Call "kernel32::ReadFile(i R4, i R6 , i ${Sectors}, *i .R7, i ..)" ${If} $R7 != ${Sectors} MessageBox MB_OK|MB_ICONEXCLAMATION "镜像文件读取错误" GoTo lblinstallret1 ${EndIf} System::Call "kernel32::CloseHandle(i R4)" # Get file handle $R4 StrCpy $R4 0 System::Call "kernel32::CreateFile(t R3, i ${GENERIC_WRITE}, i ${FILE_SHARE_WRITE}, \ i 0, i ${OPEN_EXISTING}, \ i ${FILE_FLAG_NO_BUFFERING} | ${FILE_FLAG_WRITE_THROUGH}, i 0) i .R4" ${If} $R4 = 0 System::Call "kernel32::SetFilePointerEx(i R4, l R5, *l .R7, i 0)" System::Int64Op $R5 = $R7 Pop $R7 ${If} $R7 != 1 MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" Goto lblinstallret1 ${EndIf} ${EndIf} # Write sectors System::Call "kernel32::WriteFile(i R4, i R6 , i ${Sectors}, *i .R7, i ..)" ${If} $R7 != ${Sectors} MessageBox MB_OK|MB_ICONEXCLAMATION "设备写入错误" GoTo lblinstallret1 ${EndIf} System::Call "kernel32::CloseHandle(i R4)" System::Free $R6 # Save backup ${GetTime} "" L $0 $1 $2 $3 $4 $5 $6 StrCpy $R5 "$EXEDIR\$2-$1-$0-$4-$5-$6.bin" CopyFiles /SILENT $TempFolder\image.bak $R5 # Write log ${NSD_GetText} $FilePath1 $R1 ${NSD_GetText} $FilePath2 $R2 ${NSD_GetText} $FilePath3 $R3 ${NSD_GetText} $TextBox $R4 StrCpy $R0 "Grub4DOS 已安装到设备.$\r$\n\ $\r$\n\ 目标设备: $R1$\r$\n\ 目标分区: $R2$\r$\n\ 目标文件: $R3$\r$\n\ Bootlace.com 选项: $R4$\r$\n\ 备份文件: $R5$\r$\n\ $\r$\n" Call WriteLog MessageBox MB_OK "Grub4DOS 已成功安装!" FunctionEnd #--------------------------------------------# # Set bootlace.com commandline options Function SetOptions ${NSD_GetText} $DropList1 $R1 ${If} $R1 == "" Return ${EndIf} ${NSD_GetText} $TextBox $R0 ${WordReplace} $R0 "$\n" "" "+" $R0 ${WordReplace} $R0 "$\r" "" "+" $R0 ${WordReplace} $R0 "$\t" " " "+" $R0 StrCpy $R0 "$R0$R1 " ${NSD_SetText} $TextBox $R0 FunctionEnd #--------------------------------------------# # Set bootlace.com commandline options according to selected disk/partition Function AutoSetOptions StrCpy $R0 "" ${NSD_GetText} $FilePath1 $R1 ${NSD_GetText} $FilePath2 $R2 SendMessage $FilePath2 ${CB_GETCOUNT} 0 0 $R3 ${If} $R1 != "" ${If} $R2 != "" # Get partition number ${WordFind} $R2 " " "+1" $R2 StrCpy $R0 "--floppy=$R2 " ${ElseIf} $R3 < 1 StrCpy $R0 "--floppy " ${EndIf} ${EndIf} ${NSD_SetText} $TextBox $R0 FunctionEnd #--------------------------------------------# # Restore using bootlace.com and backup image Function Restore # Image file name in $R0 ${NSD_GetText} $FilePath3 $R0 IfFileExists $R0 0 +3 IfFileExists $R0\*.* +2 +4 StrCmp $R0 "" 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "你必须指定一个有效的镜像文件" Return # Get image file handle in $R0 ${NSD_GetText} $FilePath3 $R0 System::Call "kernel32::CreateFile(t R0, i ${GENERIC_READ}, i 0, i 0, \ i ${OPEN_EXISTING}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R0" ${If} $R0 <= 0 MessageBox MB_OK|MB_ICONEXCLAMATION "镜像文件打开错误" Return ${EndIf} # Get imgae file size in $R2 IntOp $R4 $R2 + 0 System::Alloc 8 POp $2 IntOp $R9 0 + 0 System::Call "kernel32::GetFileSizeEx(i R0, i r2) i .R9" ${If} $R9 == 0 MessageBox MB_OK|MB_ICONEXCLAMATION "镜像文件读取错误" System::Free $2 Goto lblrestore ${EndIf} System::Call "*$2(l .R2)" System::Free $2 System::Int64Op $R2 = ${Sectors} Pop $R9 ${If} $R9 != 1 ${NSD_GetText} $FilePath3 $R9 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$R9 不是本程序建立的备份镜像 $\n$\n\ 是否继续?" IDYES 0 IDNO lblrestore ${EndIf} # Get target file handle in $R1 # partition number is in $R4, device file name is in $R3 System::Call "kernel32::CreateFile(t R3, i ${GENERIC_READ}, i 0, \ i 0, i ${OPEN_EXISTING}, i 0, i 0) i .R1" ${If} $R1 = 0 System::Alloc 4096 Pop $1 System::Call "kernel32::DeviceIoControl(i R1, i ${IOCTL_DISK_GET_DRIVE_LAYOUT}, i 0, \ i 0, i r1, i 4096, *i .R5, i 0) i .r2" ${If} $2 == 0 MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" Goto lblrestore ${EndIf} System::Call "*$1(i .r2)" ${If} $2 < 1 MessageBox MB_OK|MB_ICONEXCLAMATION "获取分区信息错误" System::Free $1 ${NSD_SetFocus} $FilePath1 Call EnumDisks Goto lblrestore1 ${EndIf} StrCpy $PriPtNumber 0 StrCpy $ExtPtNumber 4 IntOp $0 $1 + 8 ${For} $3 1 $2 System::Call "*$0(l .R5, l .R6)" ${If} $R5 != 0 System::Call "*$0(&i20 .., i .r7)" ${If} $7 == 0 ${If} $3 <= 4 # Extended partition IntOp $PriPtNumber $PriPtNumber + 1 ${EndIf} GoTo lblrestoreloop ${EndIf} ${If} $3 <= 4 StrCpy $7 $PriPtNumber IntOp $PriPtNumber $PriPtNumber + 1 ${Else} StrCpy $7 $ExtPtNumber IntOp $ExtPtNumber $ExtPtNumber + 1 ${EndIf} ${If} $7 == $R4 ${ExitFor} ${EndIf} ${EndIf} lblrestoreloop: IntOp $0 $0 + 32 ${Next} System::Free $1 ${EndIf} # Set file pointer System::Call "kernel32::CloseHandle(i R1)" System::Call "kernel32::CreateFile(t R3, i ${GENERIC_WRITE}, i 0, \ i 0, i ${OPEN_EXISTING}, \ i ${FILE_FLAG_NO_BUFFERING} | ${FILE_FLAG_WRITE_THROUGH}, i 0) i .R1" ${If} $R1 = 0 System::Call "kernel32::SetFilePointerEx(i R1, l R5, *l .R9, i 0)" System::Int64Op $R5 = $R9 Pop $R9 ${If} $R9 != 1 MessageBox MB_OK|MB_ICONEXCLAMATION "设备读取错误" Goto lblrestore1 ${EndIf} ${EndIf} # Get buffer in $R7 System::Alloc ${Sectors} Pop $R7 # Read/Write loop # Determine $0 bytes to copy IntOp $0 ${Sectors} + 0 # if image size $R2 is not SECTORS, use image size System::Int64Op $0 = $R2 Pop $1 ${If} $1 != 1 IntOp $0 $R2 + 0 # if target is partition and size $R6 is smaller than image size, use target size ${If} $R4 >= 0 System::Int64Op $0 > $R6 Pop $1 ${If} $1 == 1 System::Int64Op $R6 + 0 Pop $0 ${EndIf} ${EndIf} Pop $1 ${EndIf} # actual loop. stores bytes to read per loop in $1 IntOp $1 ${Sectors} + 0 lblrestorecopyloop: System::Int64Op $1 > $0 Pop $2 ${If} $2 == 1 System::Int64Op $0 + 0 Pop $1 ${EndIf} System::Call "kernel32::ReadFile(i R0, i R7 , i r1, *i .R8, i ..)" ${If} $R8 != $1 MessageBox MB_OK|MB_ICONEXCLAMATION "镜像文件读取错误" Goto lblrestore2 ${EndIf} System::Call "kernel32::WriteFile(i R1, i R7 , i r1, *i .R8, i ..)" ${If} $R8 != $1 System::Call "kernel32::GetLastError() i .R9" ${If} $R9 != ${ERROR_HANDLE_EOF} MessageBox MB_OK|MB_ICONEXCLAMATION "设备写入错误 $R9" ${EndIf} Goto lblrestore2 ${EndIf} System::Int64Op $0 - $1 Pop $0 ${If} $0 > 0 Goto lblrestorecopyloop ${EndIf} lblrestore2: System::Free $R7 lblrestore1: System::Call "kernel32::CloseHandle(i R1)" lblrestore: System::Call "kernel32::CloseHandle(i R0)" # Write log ${NSD_GetText} $FilePath1 $R1 ${NSD_GetText} $FilePath2 $R2 ${NSD_GetText} $FilePath3 $R3 ${NSD_GetText} $TextBox $R4 StrCpy $R0 "Restored image file to device.$\r$\n\ $\r$\n\ Source file: $R3$\r$\n\ Target disk: $R1$\r$\n\ Target partition: $R2$\r$\n\ $\r$\n" Call WriteLog MessageBox MB_OK "镜像文件成功写入设备" FunctionEnd #--------------------------------------------# # Locate drives with bootmgr in the root folder Function GetBootmgr SendMessage $FilePath1 ${CB_RESETCONTENT} 0 0 $0 ${GetDrives} "FDD+HDD+NET" "CheckBootmgr" FunctionEnd Function CheckBootmgr IfFileExists $9bootmgr 0 lblgetbootmgr # $9 is driveletter; Stores partition type in $7 System::Call /NOUNLOAD 'kernel32::GetVolumeInformation(t r9, t .r8, i 1024, \ *i .r1, i .., i .., t .r7, i 1024 ) i ..' ${If} $7 == "NTFS" SendMessage $FilePath1 ${CB_ADDSTRING} 0 "STR:$9bootmgr" ${EndIf} lblgetbootmgr: Push "Keep Searching" FunctionEnd #--------------------------------------------# # Opens file selection dialog Function BrowseFile1 nsDialogs::SelectFileDialog /NOUNLOAD open "" "$TargetFile1|$TargetFile1" Pop $R0 ${NSD_SetText} $FilePath1 $R0 FunctionEnd Function BrowseFile2 nsDialogs::SelectFileDialog /NOUNLOAD open "" "$TargetFile2|$TargetFile2" Pop $R0 ${NSD_SetText} $FilePath2 $R0 FunctionEnd Function BrowseFile3 nsDialogs::SelectFileDialog /NOUNLOAD open "" "$TargetFile3|$TargetFile3" Pop $R0 ${NSD_SetText} $FilePath3 $R0 FunctionEnd #--------------------------------------------# # Enumerate connected disks Function EnumDisks SendMessage $FilePath1 ${CB_RESETCONTENT} 0 0 $0 EnableWindow $FilePath1 1 SendMessage $FilePath2 ${CB_RESETCONTENT} 0 0 $0 EnableWindow $FilePath2 1 StrCpy $R0 "\\.\A:" Call CheckDisk ${If} $R1 != "" SendMessage $FilePath1 ${CB_ADDSTRING} 0 "STR:fd0:$R1" ${EndIf} StrCpy $R0 "\\.\B:" Call CheckDisk ${If} $R1 != "" SendMessage $FilePath1 ${CB_ADDSTRING} 0 "STR:fd1:$R1" ${EndIf} ${For} $1 0 ${MAX_DISKS} StrCpy $R0 "\\.\PhysicalDrive$1" Call CheckDisk ${If} $R1 != "" SendMessage $FilePath1 ${CB_ADDSTRING} 0 "STR:hd$1:$R1" ${EndIf} ${Next} Call AutoSetOptions FunctionEnd #--------------------------------------------# # Check whether $R0 exists and stores disk info in $R1 Function CheckDisk StrCpy $R1 "" System::Call "kernel32::CreateFile(t R0, i 0, i ${FILE_SHARE_READ}|${FILE_SHARE_WRITE}, \ i 0, i ${OPEN_EXISTING}, i 0, i 0) i .R2" ${If} $R2 > 0 System::Alloc 24 Pop $R3 System::Call "kernel32::DeviceIoControl(i R2, i ${IOCTL_DISK_GET_DRIVE_GEOMETRY}, i 0, \ i 0, i R3, i 24, *i .R5, i 0) i .R4" ${If} $R4 == 0 Return ${EndIf} System::Call "*$R3(&i8 .R4, i .R5, i .R6, i .R7, i .R8)" System::Free $R3 IntOp $R6 $R6 * $R7 IntOp $R6 $R6 * $R8 System::Int64Op $R4 * $R6 Pop $R4 Call GetDiskSize StrCpy $R8 $R4 System::Call "*(i ${StorageDeviceProperty}, i ${PropertyStandardQuery}, i 0) i .s" Pop $R3 System::Alloc 1024 Pop $R4 System::Call "kernel32::DeviceIoControl(i R2, i ${IOCTL_STORAGE_QUERY_PROPERTY}, \ i R3, i 12, i R4, i 1024, *i .R5, i 0) i .." ${If} $R5 > 0 # Get BusType IntOp $R5 $R4 + 28 System::Call "*$R5(i .R6)" ${Select} $R6 ${Case} "1" StrCpy $R6 "SCSI" ${Case} "3" StrCpy $R6 "ATA" ${Case} "4" StrCpy $R6 "1394" ${Case} "5" StrCpy $R6 "SSA" ${Case} "6" StrCpy $R6 "FIBRE" ${Case} "7" StrCpy $R6 "USB" ${Case} "8" StrCpy $R6 "RAID" ${Case} "9" StrCpy $R6 "iSCSI" ${Case} "10" StrCpy $R6 "SAS" ${Case} "11" StrCpy $R6 "SATA" ${Case} "12" StrCpy $R6 "SD" ${Case} "13" StrCpy $R6 "MMC" ${CaseElse} StrCpy $R6 "" ${EndSelect} ${If} $R6 != "" StrCpy $R1 "$R6:" ${EndIf} # Get VendorID IntOp $R5 $R4 + 12 System::Call "*$R5(i .R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024 .R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R7 != "" Strcpy $R1 $R1$R7- ${EndIf} ${EndIf} # Get ProductID IntOp $R5 $R4 + 16 System::Call "*$R5(i .R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024 .R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R1 != "" ${AndIf} $R7 != "" Strcpy $R1 "$R1$R7" ${EndIf} ${EndIf} # Get ProductRevision IntOp $R5 $R4 + 20 System::Call "*$R5(i .R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024 .R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R7 != "" Strcpy $R1 "$R1($R7)" ${EndIf} ${EndIf} ${EndIf} StrCpy $R1 "$R1 ($R8)" System::Free $R3 System::Free $R4 System::Call "kernel32::CloseHandle(i R2)" ${EndIf} FunctionEnd #--------------------------------------------# # Enumerate partitions of selected disk Function EnumParts SendMessage $FilePath2 ${CB_RESETCONTENT} 0 0 $R1 ${NSD_GetText} $FilePath1 $R1 StrCpy $R2 $R1 1 4 ${If} $R2 != ":" StrCpy $R2 $R1 3 ${Else} StrCpy $R2 $R1 4 ${EndIf} StrCpy $PriPtNumber 0 StrCpy $ExtPtNumber 4 ${If} $R2 == "fd0" ${OrIf} $R2 == "fd1" Return ${EndIf} StrCpy $R2 $R2 "" 2 StrCpy $R0 "\\.\PhysicalDrive$R2" System::Call "kernel32::CreateFile(t R0, i ${GENERIC_READ}, i ${FILE_SHARE_WRITE}, i 0, \ i ${OPEN_EXISTING}, i 0, i 0) i .R2" ${If} $R2 > 0 System::Alloc 4096 Pop $R1 System::Call "kernel32::DeviceIoControl(i R2, i ${IOCTL_DISK_GET_DRIVE_LAYOUT}, i 0, \ i 0, i R1, i 4096, *i .R5, i 0) i .R4" ${If} $R4 == 0 Goto lblenumptret ${EndIf} # typedef struct _DRIVE_LAYOUT_INFORMATION { # DWORD PartitionCount; # DWORD Signature; # PARTITION_INFORMATION PartitionEntry[1]; # } DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION; # Get number of partitions System::Call "*$R1(i .R5)" ${If} $R5 < 1 Goto lblenumptret ${EndIf} IntOp $R0 $R1 + 8 # typedef struct _PARTITION_INFORMATION { # LARGE_INTEGER StartingOffset; # LARGE_INTEGER PartitionLength; # DWORD HiddenSectors; # DWORD PartitionNumber; # BYTE PartitionType; # BOOLEAN BootIndicator; # BOOLEAN RecognizedPartition; # BOOLEAN RewritePartition; # } PARTITION_INFORMATION, *PPARTITION_INFORMATION; ${For} $R3 1 $R5 System::Call "*$R0(l .R6)" ${If} $R6 != 0 System::Call "*$R0(l .., l .R4)" Call GetDiskSize System::Call "*$R0(&i20 .., i .R7, &i1 .R8, &i1 .R9 )" ${If} $R7 == 0 ${If} $R3 <= 4 # Extended partition IntOp $PriPtNumber $PriPtNumber + 1 ${EndIf} GoTo lblenumptloop ${EndIf} ${If} $R3 5000 System::Int64Op $R4 / 1000 Pop $R4 ${If} $R4 > 5000 IntOp $R4 $R4 / 1000 ${If} $R4 > 5000 IntOp $R4 $R4 / 1000 ${If} $R4 > 5000 IntOp $R4 $R4 / 1000 StrCpy $R4 "$R4T" ${EndIf} ${Else} StrCpy $R4 "$R4G" ${EndIf} ${Else} StrCpy $R4 "$R4M" ${EndIf} ${Else} StrCpy $R4 "$R4K" ${EndIf} FunctionEnd #--------------------------------------------# # Get human-readable file system type from $R8 to $R8 Function GetFSType IntFmt $R8 "%02X" $R8 ${Select} $R8 ${Case} "01" StrCpy $R8 "FAT12" ${Case3} "04" "06" "0E" StrCpy $R8 "FAT16" ${Case} "07" StrCpy $R8 "NTFS/exFAT" ${Case2} "0B" "0C" StrCpy $R8 "FAT32" ${Case} "11" StrCpy $R8 "hidden FAT12" ${Case3} "14" "16" "1E" StrCpy $R8 "hidden FAT16" ${Case} "17" StrCpy $R8 "hidden NTFS/exFAT" ${Case2} "1B" "1C" StrCpy $R8 "hidden FAT32" ${Case} "27" StrCpy $R8 "hidden NTFS (RE)" ${Case} "35" StrCpy $R8 "JFS" ${Case2} "80" "81" StrCpy $R8 "MINIX" ${Case} "82" StrCpy $R8 "LINUX SWAP" ${Case} "83" StrCpy $R8 "LINUX" ${CaseElse} StrCpy $R8 "UNSUPPORTED" ${EndSelect} FunctionEnd #--------------------------------------------# # Patch $FileToPatch using $TargetFile as $PatchedFile Function PatchFileName System::Store "S" # determine signature offset ${GetFileName} $FileToPatch $R0 ${If} $R0 == "bootlace.com" IntOp $R0 0 + 0x8FFC ${ElseIf} $R0 == "grldr.mbr" IntOp $R0 0 + 0x23FC ${Else} IntOp $R0 0 + 0x1FFC ${EndIf} # Read source file StrCpy $R1 $FileToPatch System::Call "kernel32::CreateFile(t R1, i ${GENERIC_READ}, i ${FILE_SHARE_READ}, i 0, \ i ${OPEN_EXISTING}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R1" ${If} $R1 $R2 MessageBox MB_OK|MB_ICONEXCLAMATION "$FileToPatch 文件不是一个有效的 Grub4DOS 文件" System::Call "kernel32::CloseHandle(i R1)" Goto lblpatchfilename1 ${EndIf} System::Alloc $R2 Pop $R3 System::Call "kernel32::ReadFile(i R1, i R3 , i R2, *i .R4, i ..)" System::Call "kernel32::CloseHandle(i R1)" ${If} $R2 != $R4 MessageBox MB_OK|MB_ICONEXCLAMATION "$FileToPatch 读取错误!" lblpatchfilename: System::Free $R3 lblpatchfilename1: System::Store "L" Push "error" Return ${EndIf} IntOp $R4 $R3 + $R0 System::Call "*$R4(i .R5)" IntFmt $R5 "0x%08X" $R5 ${If} $R5 != "0xAA555247" MessageBox MB_OK|MB_ICONEXCLAMATION "$FileToPatch 文件不是一个有效的Grub4DOS文件" Goto lblpatchfilename1 ${EndIf} ${GetFileName} $FileToPatch $R0 ${If} $R0 == "bootlace.com" IntOp $R0 0 + 0x7000 ${Else} IntOp $R0 0 + 0x400 ${EndIf} # FAT32 IntOp $R4 $R0 + 0x1EC IntOp $R4 $R3 + $R4 System::Call "*$R4(&i2 .R5)" IntOp $R5 $R5 & 0x7FF IntOp $R4 $R0 + $R5 IntOp $R4 $R3 + $R4 StrCpy $R5 $TargetFile ${WordReplace} $R5 "." "" "+" $R5 ${StrFilter} $R5 "+" "" "" $R5 StrLen $R6 $R5 System::Call "*(&t12 R5) i .R7" System::Copy /$R6 $R4 $R7 # FAT12/16 IntOp $R0 $R0 + 0x200 IntOp $R4 $R0 + 0x1EC IntOp $R4 $R3 + $R4 System::Call "*$R4(&i2 .R5)" IntOp $R5 $R5 & 0x7FF IntOp $R4 $R0 + $R5 IntOp $R4 $R3 + $R4 System::Copy /$R6 $R4 $R7 System::Free $R7 # EXT2 IntOp $R0 $R0 + 0x200 IntOp $R4 $R0 + 0x1EE IntOp $R4 $R3 + $R4 System::Call "*$R4(&i2 .R5)" IntOp $R5 $R5 & 0x7FF IntOp $R4 $R0 + $R5 IntOp $R4 $R3 + $R4 StrCpy $R5 $TargetFile ${StrFilter} $R5 "-" "" "" $R5 StrLen $R6 $R5 System::Call "*(&t12 R5) i .R7" System::Copy /$R6 $R4 $R7 # NTFS IntOp $R0 $R0 + 0x200 IntOp $R4 $R0 + 0x1EC IntOp $R4 $R3 + $R4 System::Call "*$R4(&i2 .R5)" IntOp $R5 $R5 & 0x7FF IntOp $R4 $R0 + $R5 IntOp $R4 $R3 + $R4 System::Copy /$R6 $R4 $R7 System::Free $R7 # Write output file StrCpy $R1 $PatchedFile System::Call "kernel32::CreateFile(t R1, i ${GENERIC_WRITE}, i 0, i 0, i ${CREATE_ALWAYS}, \ i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R1" ${If} $R1 0 System::Call "kernel32::ReadFile(i R5, i R6 , i R7, *i .R4, i ..)" System::Call "kernel32::CloseHandle(i R5)" System::Call /NOUNLOAD 'user32::SendMessage(i $TextBox, i ${WM_SETTEXT}, i 0, i R6)' ${EndIf} System::Free $R6 FunctionEnd #--------------------------------------------# # Check file name ($R0) validity by creating a file in TempFolder; Set $R0 to null if error Function CheckFileName Push $R2 Push $R1 ${If} $R0 != "" StrCpy $R1 $TempFolder\$R0 System::Call "kernel32::CreateFile(t R1, i ${GENERIC_READ}|${GENERIC_WRITE}, i 0, i 0, \ i ${CREATE_ALWAYS}, i ${FILE_ATTRIBUTE_NORMAL}, i 0) i .R2" ${If} $R2 > 0 System::Call "kernel32::CloseHandle(i R2)" Delete $R1 Goto lblcheckfilename ${EndIf} ${EndIf} StrCpy $R0 "" MessageBox MB_OK|MB_ICONEXCLAMATION "你必须提供一个有效的文件名" lblcheckfilename: Pop $R1 Pop $R2 FunctionEnd #--------------------------------------------# # Write log messages from $R0 Function WriteLog ${GetTime} "" L $0 $1 $2 $3 $4 $5 $6 StrCpy $msg "--------------------------------$\r$\n$2-$1-$0 $4:$5:$6" IfFileExists $LogFile +3 0 FileOpen $0 $LogFile w GoTo +2 FileOpen $0 $LogFile a FileSeek $0 0 END FileWrite $0 "$msg$\r$\n$R0$\r$\n" FileClose $0 FunctionEnd #--------------------------------------------# Function CleanUp RMDir /r /REBOOTOK $TempFolder FunctionEnd #--------------------------------------------# !insertmacro MUI_LANGUAGE "English"