1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 #include "Ventoy2Disk.h"
30 BOOL g_SecureBoot
= FALSE
;
33 HWND g_StaticLocalVerHwnd
;
34 HWND g_StaticDiskVerHwnd
;
35 HWND g_BtnInstallHwnd
;
37 HWND g_StaticLocalHwnd
;
38 HWND g_StaticDiskHwnd
;
40 HWND g_ProgressBarHwnd
;
41 HWND g_StaticStatusHwnd
;
42 CHAR g_CurVersion
[64];
43 HANDLE g_ThreadHandle
= NULL
;
45 int g_language_count
= 0;
46 int g_cur_lang_id
= 0;
47 VENTOY_LANGUAGE
*g_language_data
= NULL
;
48 VENTOY_LANGUAGE
*g_cur_lang_data
= NULL
;
50 static int LoadCfgIni(void)
54 value
= GetPrivateProfileInt(TEXT("Ventoy"), TEXT("SecureBoot"), 0, VENTOY_CFG_INI
);
64 static int WriteCfgIni(void)
68 swprintf_s(TmpBuf
, 128, TEXT("%d"), g_cur_lang_id
);
69 WritePrivateProfileString(TEXT("Ventoy"), TEXT("Language"), TmpBuf
, VENTOY_CFG_INI
);
71 swprintf_s(TmpBuf
, 128, TEXT("%d"), g_SecureBoot
);
72 WritePrivateProfileString(TEXT("Ventoy"), TEXT("SecureBoot"), TmpBuf
, VENTOY_CFG_INI
);
78 void GetExeVersionInfo(const char *FilePath
)
83 VS_FIXEDFILEINFO
*verInfo
= NULL
;
85 verBufferSize
= GetFileVersionInfoSizeA(FilePath
, NULL
);
87 if (verBufferSize
> 0 && verBufferSize
<= sizeof(verBuffer
))
89 if (GetFileVersionInfoA(FilePath
, 0, verBufferSize
, (LPVOID
)verBuffer
))
91 VerQueryValueA(verBuffer
, "\\", &verInfo
, &length
);
93 safe_sprintf(g_CurVersion
, "%u.%u.%u.%u",
94 HIWORD(verInfo
->dwProductVersionMS
),
95 LOWORD(verInfo
->dwProductVersionMS
),
96 HIWORD(verInfo
->dwProductVersionLS
),
97 LOWORD(verInfo
->dwProductVersionLS
));
102 void SetProgressBarPos(int Pos
)
106 if (Pos
>= PT_FINISH
)
111 SendMessage(g_ProgressBarHwnd
, PBM_SETPOS
, Pos
, 0);
113 safe_sprintf(Ratio
, "Status - %.0lf%%", Pos
* 100.0 / PT_FINISH
);
114 SetWindowTextA(g_StaticStatusHwnd
, Ratio
);
117 static void OnComboxSelChange(HWND hCombox
)
120 PHY_DRIVE_INFO
*CurDrive
= NULL
;
122 SetWindowTextA(g_StaticLocalVerHwnd
, GetLocalVentoyVersion());
123 EnableWindow(g_BtnInstallHwnd
, FALSE
);
124 EnableWindow(g_BtnUpdateHwnd
, FALSE
);
126 nCurSelected
= SendMessage(hCombox
, CB_GETCURSEL
, 0, 0);
127 if (CB_ERR
== nCurSelected
)
132 CurDrive
= GetPhyDriveInfoById(nCurSelected
);
138 SetWindowTextA(g_StaticDiskVerHwnd
, CurDrive
->VentoyVersion
);
140 if (g_ForceOperation
== 0)
142 if (CurDrive
->VentoyVersion
[0])
145 EnableWindow(g_BtnInstallHwnd
, FALSE
);
146 EnableWindow(g_BtnUpdateHwnd
, TRUE
);
151 EnableWindow(g_BtnInstallHwnd
, TRUE
);
152 EnableWindow(g_BtnUpdateHwnd
, FALSE
);
157 EnableWindow(g_BtnInstallHwnd
, TRUE
);
158 EnableWindow(g_BtnUpdateHwnd
, TRUE
);
161 InvalidateRect(g_DialogHwnd
, NULL
, TRUE
);
162 UpdateWindow(g_DialogHwnd
);
165 static void UpdateItemString(int defaultLangId
)
170 HMENU hMenu
= GetMenu(g_DialogHwnd
);
172 g_cur_lang_id
= defaultLangId
;
173 g_cur_lang_data
= g_language_data
+ defaultLangId
;
177 hLangFont
= CreateFont(g_language_data
[defaultLangId
].FontSize
, 0, 0, 0, 400, FALSE
, FALSE
, 0,
178 DEFAULT_CHARSET
, OUT_DEFAULT_PRECIS
,
179 CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
,
180 DEFAULT_PITCH
, g_language_data
[defaultLangId
].FontFamily
);
182 SendMessage(g_BtnInstallHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
183 SendMessage(g_BtnUpdateHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
184 SendMessage(g_StaticStatusHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
185 SendMessage(g_StaticLocalHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
186 SendMessage(g_StaticDiskHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
187 SendMessage(g_StaticDevHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
188 SendMessage(g_DialogHwnd
, WM_SETFONT
, (WPARAM
)hLangFont
, TRUE
);
190 ModifyMenu(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, 0, _G(STR_MENU_OPTION
));
192 SetWindowText(GetDlgItem(g_DialogHwnd
, IDC_STATIC_DEV
), _G(STR_DEVICE
));
193 SetWindowText(GetDlgItem(g_DialogHwnd
, IDC_STATIC_LOCAL
), _G(STR_LOCAL_VER
));
194 SetWindowText(GetDlgItem(g_DialogHwnd
, IDC_STATIC_DISK
), _G(STR_DISK_VER
));
195 SetWindowText(g_StaticStatusHwnd
, _G(STR_STATUS
));
197 SetWindowText(g_BtnInstallHwnd
, _G(STR_INSTALL
));
198 SetWindowText(g_BtnUpdateHwnd
, _G(STR_UPDATE
));
200 SubMenu
= GetSubMenu(hMenu
, 0);
203 ModifyMenu(SubMenu
, 0, MF_BYPOSITION
| MF_STRING
| MF_CHECKED
, 0, _G(STR_MENU_SECURE_BOOT
));
207 ModifyMenu(SubMenu
, 0, MF_BYPOSITION
| MF_STRING
| MF_UNCHECKED
, 0, _G(STR_MENU_SECURE_BOOT
));
210 ShowWindow(g_DialogHwnd
, SW_HIDE
);
211 ShowWindow(g_DialogHwnd
, SW_NORMAL
);
214 for (i
= 0; i
< g_language_count
; i
++)
216 CheckMenuItem(hMenu
, VTOY_MENU_LANGUAGE_BEGIN
| i
, MF_BYCOMMAND
| MF_STRING
| MF_UNCHECKED
);
218 CheckMenuItem(hMenu
, VTOY_MENU_LANGUAGE_BEGIN
| defaultLangId
, MF_BYCOMMAND
| MF_STRING
| MF_CHECKED
);
221 static void LanguageInit(void)
227 LANGID LangId
= GetSystemDefaultUILanguage();
229 HMENU hMenu
= GetMenu(g_DialogHwnd
);
231 SubMenu
= GetSubMenu(hMenu
, 1);
232 DeleteMenu(SubMenu
, 0, MF_BYPOSITION
);
234 g_language_data
= (VENTOY_LANGUAGE
*)malloc(sizeof(VENTOY_LANGUAGE
)* VENTOY_MAX_LANGUAGE
);
235 memset(g_language_data
, 0, sizeof(VENTOY_LANGUAGE
)* VENTOY_MAX_LANGUAGE
);
237 swprintf_s(Language
, 64, L
"StringDefine");
238 for (i
= 0; i
< STR_ID_MAX
; i
++)
240 swprintf_s(TmpBuf
, 256, L
"%d", i
);
241 GET_INI_STRING(TmpBuf
, g_language_data
[0].StrId
[i
]);
244 for (i
= 0; i
< VENTOY_MAX_LANGUAGE
; i
++)
246 swprintf_s(Language
, 64, L
"Language%d", i
);
247 GET_INI_STRING(TEXT("name"), g_language_data
[i
].Name
);
249 if (g_language_data
[i
].Name
[0] == '#')
255 Log("Find Language%d ...", i
);
257 AppendMenu(SubMenu
, MF_STRING
| MF_BYCOMMAND
, VTOY_MENU_LANGUAGE_BEGIN
| i
, g_language_data
[i
].Name
);
259 GET_INI_STRING(TEXT("FontFamily"), g_language_data
[i
].FontFamily
);
260 g_language_data
[i
].FontSize
= GetPrivateProfileInt(Language
, TEXT("FontSize"), 10, VENTOY_LANGUAGE_INI
);
262 for (j
= 0; j
< STR_ID_MAX
; j
++)
264 GET_INI_STRING(g_language_data
[0].StrId
[j
], g_language_data
[i
].MsgString
[j
]);
266 for (k
= 0; g_language_data
[i
].MsgString
[j
][k
] && g_language_data
[i
].MsgString
[j
][k
+ 1]; k
++)
268 if (g_language_data
[i
].MsgString
[j
][k
] == '#' && g_language_data
[i
].MsgString
[j
][k
+ 1] == '@')
270 g_language_data
[i
].MsgString
[j
][k
] = '\r';
271 g_language_data
[i
].MsgString
[j
][k
+ 1] = '\n';
277 DefaultId
= (MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_SIMPLIFIED
) == LangId
) ? 0 : 1;
278 id
= GetPrivateProfileInt(TEXT("Ventoy"), TEXT("Language"), DefaultId
, VENTOY_CFG_INI
);
284 UpdateItemString(id
);
287 static BOOL
InitDialog(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
293 CHAR DeviceName
[256];
297 g_ComboxHwnd
= GetDlgItem(hWnd
, IDC_COMBO1
);
298 g_StaticLocalVerHwnd
= GetDlgItem(hWnd
, IDC_STATIC_LOCAL_VER
);
299 g_StaticDiskVerHwnd
= GetDlgItem(hWnd
, IDC_STATIC_DISK_VER
);
300 g_BtnInstallHwnd
= GetDlgItem(hWnd
, IDC_BUTTON4
);
303 g_StaticDevHwnd
= GetDlgItem(hWnd
, IDC_STATIC_DEV
);
304 g_StaticLocalHwnd
= GetDlgItem(hWnd
, IDC_STATIC_LOCAL
);
305 g_StaticDiskHwnd
= GetDlgItem(hWnd
, IDC_STATIC_DISK
);
308 g_BtnUpdateHwnd
= GetDlgItem(hWnd
, IDC_BUTTON3
);
309 g_ProgressBarHwnd
= GetDlgItem(hWnd
, IDC_PROGRESS1
);
310 g_StaticStatusHwnd
= GetDlgItem(hWnd
, IDC_STATIC_STATUS
);
312 hIcon
= LoadIcon(g_hInst
, MAKEINTRESOURCE(IDI_ICON1
));
313 SendMessage(hWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
314 SendMessage(hWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
316 SendMessage(g_ProgressBarHwnd
, PBM_SETRANGE
, (WPARAM
)0, (LPARAM
)(MAKELPARAM(0, PT_FINISH
)));
317 PROGRESS_BAR_SET_POS(PT_START
);
319 SetMenu(hWnd
, LoadMenu(g_hInst
, MAKEINTRESOURCE(IDR_MENU1
)));
325 // Fill device combox
326 hCombox
= GetDlgItem(hWnd
, IDC_COMBO1
);
327 for (i
= 0; i
< g_PhyDriveCount
; i
++)
329 if (g_PhyDriveList
[i
].Id
< 0)
334 if (g_PhyDriveList
[i
].FirstDriveLetter
>= 0)
336 safe_sprintf(Letter
, "%C: ", g_PhyDriveList
[i
].FirstDriveLetter
);
343 safe_sprintf(DeviceName
, "%s[%dGB] %s %s",
345 GetHumanReadableGBSize(g_PhyDriveList
[i
].SizeInBytes
),
346 g_PhyDriveList
[i
].VendorId
,
347 g_PhyDriveList
[i
].ProductId
349 SendMessageA(hCombox
, CB_ADDSTRING
, 0, (LPARAM
)DeviceName
);
352 SendMessage(hCombox
, CB_SETCURSEL
, 0, 0);
354 // Set static text & font
355 hStaticFont
= CreateFont(26, 0, 0, 0, FW_BOLD
, FALSE
, FALSE
, 0,
356 ANSI_CHARSET
, OUT_DEFAULT_PRECIS
,
357 CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
,
358 DEFAULT_PITCH
&FF_SWISS
, TEXT("Courier New"));
360 SendMessage(g_StaticLocalVerHwnd
, WM_SETFONT
, (WPARAM
)hStaticFont
, TRUE
);
361 SendMessage(g_StaticDiskVerHwnd
, WM_SETFONT
, (WPARAM
)hStaticFont
, TRUE
);
363 OnComboxSelChange(g_ComboxHwnd
);
365 SetFocus(g_ProgressBarHwnd
);
370 static DWORD WINAPI
InstallVentoyThread(void* Param
)
373 PHY_DRIVE_INFO
*pPhyDrive
= (PHY_DRIVE_INFO
*)Param
;
375 rc
= InstallVentoy2PhyDrive(pPhyDrive
);
378 Log("This time install failed, now wait and retry...");
381 Log("Now retry to install...");
383 rc
= InstallVentoy2PhyDrive(pPhyDrive
);
388 PROGRESS_BAR_SET_POS(PT_FINISH
);
389 MessageBox(g_DialogHwnd
, _G(STR_INSTALL_SUCCESS
), _G(STR_INFO
), MB_OK
| MB_ICONINFORMATION
);
390 safe_strcpy(pPhyDrive
->VentoyVersion
, GetLocalVentoyVersion());
394 PROGRESS_BAR_SET_POS(PT_FINISH
);
395 MessageBox(g_DialogHwnd
, _G(STR_INSTALL_FAILED
), _G(STR_ERROR
), MB_OK
| MB_ICONERROR
);
398 PROGRESS_BAR_SET_POS(PT_START
);
399 g_ThreadHandle
= NULL
;
400 SetWindowText(g_StaticStatusHwnd
, _G(STR_STATUS
));
401 OnComboxSelChange(g_ComboxHwnd
);
406 static DWORD WINAPI
UpdateVentoyThread(void* Param
)
409 PHY_DRIVE_INFO
*pPhyDrive
= (PHY_DRIVE_INFO
*)Param
;
411 rc
= UpdateVentoy2PhyDrive(pPhyDrive
);
414 Log("This time update failed, now wait and retry...");
417 Log("Now retry to update...");
419 rc
= UpdateVentoy2PhyDrive(pPhyDrive
);
424 PROGRESS_BAR_SET_POS(PT_FINISH
);
425 MessageBox(g_DialogHwnd
, _G(STR_UPDATE_SUCCESS
), _G(STR_INFO
), MB_OK
| MB_ICONINFORMATION
);
426 safe_strcpy(pPhyDrive
->VentoyVersion
, GetLocalVentoyVersion());
430 PROGRESS_BAR_SET_POS(PT_FINISH
);
431 MessageBox(g_DialogHwnd
, _G(STR_UPDATE_FAILED
), _G(STR_ERROR
), MB_OK
| MB_ICONERROR
);
434 PROGRESS_BAR_SET_POS(PT_START
);
435 g_ThreadHandle
= NULL
;
436 SetWindowText(g_StaticStatusHwnd
, _G(STR_STATUS
));
437 OnComboxSelChange(g_ComboxHwnd
);
444 static void OnInstallBtnClick(void)
447 PHY_DRIVE_INFO
*pPhyDrive
= NULL
;
449 if (MessageBox(g_DialogHwnd
, _G(STR_INSTALL_TIP
), _G(STR_WARNING
), MB_YESNO
| MB_ICONWARNING
) != IDYES
)
454 if (MessageBox(g_DialogHwnd
, _G(STR_INSTALL_TIP2
), _G(STR_WARNING
), MB_YESNO
| MB_ICONWARNING
) != IDYES
)
461 Log("Another thread is runing");
465 nCurSel
= SendMessage(g_ComboxHwnd
, CB_GETCURSEL
, 0, 0);
466 if (CB_ERR
== nCurSel
)
468 Log("Failed to get combox sel");
472 pPhyDrive
= GetPhyDriveInfoById(nCurSel
);
478 EnableWindow(g_BtnInstallHwnd
, FALSE
);
479 EnableWindow(g_BtnUpdateHwnd
, FALSE
);
481 g_ThreadHandle
= CreateThread(NULL
, 0, InstallVentoyThread
, (LPVOID
)pPhyDrive
, 0, NULL
);
486 static void OnUpdateBtnClick(void)
489 PHY_DRIVE_INFO
*pPhyDrive
= NULL
;
491 if (MessageBox(g_DialogHwnd
, _G(STR_UPDATE_TIP
), _G(STR_INFO
), MB_YESNO
| MB_ICONQUESTION
) != IDYES
)
498 Log("Another thread is runing");
502 nCurSel
= SendMessage(g_ComboxHwnd
, CB_GETCURSEL
, 0, 0);
503 if (CB_ERR
== nCurSel
)
505 Log("Failed to get combox sel");
509 pPhyDrive
= GetPhyDriveInfoById(nCurSel
);
515 EnableWindow(g_BtnInstallHwnd
, FALSE
);
516 EnableWindow(g_BtnUpdateHwnd
, FALSE
);
518 g_ThreadHandle
= CreateThread(NULL
, 0, UpdateVentoyThread
, (LPVOID
)pPhyDrive
, 0, NULL
);
521 static void MenuProc(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
524 HMENU hMenu
= GetMenu(hWnd
);
526 CtrlID
= LOWORD(wParam
);
530 g_SecureBoot
= !g_SecureBoot
;
534 CheckMenuItem(hMenu
, 0, MF_BYCOMMAND
| MF_STRING
| MF_CHECKED
);
538 CheckMenuItem(hMenu
, 0, MF_BYCOMMAND
| MF_STRING
| MF_UNCHECKED
);
541 else if (CtrlID
>= VTOY_MENU_LANGUAGE_BEGIN
&& CtrlID
< VTOY_MENU_LANGUAGE_BEGIN
+ g_language_count
)
543 UpdateItemString(CtrlID
- VTOY_MENU_LANGUAGE_BEGIN
);
547 INT_PTR CALLBACK
DialogProc(HWND hWnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
556 NotifyCode
= HIWORD(wParam
);
557 CtrlID
= LOWORD(wParam
);
559 if (CtrlID
== IDC_COMBO1
&& NotifyCode
== CBN_SELCHANGE
)
561 OnComboxSelChange((HWND
)lParam
);
564 if (CtrlID
== IDC_BUTTON4
&& NotifyCode
== BN_CLICKED
)
568 else if (CtrlID
== IDC_BUTTON3
&& NotifyCode
== BN_CLICKED
)
573 if (lParam
== 0 && NotifyCode
== 0)
575 MenuProc(hWnd
, wParam
, lParam
);
582 InitDialog(hWnd
, wParam
, lParam
);
585 case WM_CTLCOLORSTATIC
:
587 if (GetDlgItem(hWnd
, IDC_STATIC_LOCAL_VER
) == (HANDLE
)lParam
||
588 GetDlgItem(hWnd
, IDC_STATIC_DISK_VER
) == (HANDLE
)lParam
)
590 SetBkMode((HDC
)wParam
, TRANSPARENT
);
591 SetTextColor((HDC
)wParam
, RGB(255, 0, 0));
592 return (LRESULT
)(HBRUSH
)(GetStockObject(HOLLOW_BRUSH
));
603 MessageBox(g_DialogHwnd
, _G(STR_WAIT_PROCESS
), _G(STR_INFO
), MB_OK
| MB_ICONINFORMATION
);
617 int APIENTRY
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, INT nCmdShow
)
619 UNREFERENCED_PARAMETER(hPrevInstance
);
621 if (!IsFileExist(VENTOY_FILE_VERSION
))
623 if (IsDirExist("grub"))
625 MessageBox(NULL
, _G(STR_INCORRECT_DIR
), _G(STR_ERROR
), MB_OK
| MB_ICONERROR
);
629 MessageBox(NULL
, _G(STR_INCORRECT_DIR
), _G(STR_ERROR
), MB_OK
| MB_ICONERROR
);
631 return ERROR_NOT_FOUND
;
634 GetExeVersionInfo(__argv
[0]);
636 Log("\n################################ Ventoy2Disk %s ################################", g_CurVersion
);
638 ParseCmdLineOption(lpCmdLine
);
640 DumpWindowsVersion();
647 DialogBox(hInstance
, MAKEINTRESOURCE(IDD_DIALOG1
), NULL
, DialogProc
);
649 Ventoy2DiskDestroy();