7 #include <ventoy_define.h>
8 #include <ventoy_util.h>
9 #include <ventoy_json.h>
10 #include <ventoy_disk.h>
11 #include <ventoy_http.h>
13 char g_ventoy_dir
[MAX_PATH
];
15 static BOOL g_ChromeFirst
= TRUE
;
16 static BOOL g_running
= FALSE
;
17 static HWND g_refresh_button
;
18 static HWND g_start_button
;
19 static HWND g_openlink_button
;
20 static HWND g_exit_button
;
21 static HWND g_ComboxHwnd
;
46 const WCHAR
*g_msg_cn
[MSGID_BUTT
] =
50 L
"请在 Ventoy 盘根目录下运行本程序!(存放ISO文件的位置)",
51 L
"创建 ventoy 目录失败,无法继续!",
52 L
"ventoy 目录存在,但是大小写不匹配,请先将其重命名!",
60 L
"停止运行后浏览器页面将会关闭,是否继续?",
62 L
"请先关闭正在运行的 VentoyPlugson 程序!",
63 L
"ventoy\\plugson.tar.xz 文件不存在,请在正确的目录下运行!",
65 const WCHAR
*g_msg_en
[MSGID_BUTT
] =
69 L
"Please run me at the root of Ventoy partition.",
70 L
"Failed to create ventoy directory!",
71 L
"ventoy directory case mismatch, please rename it first!",
72 L
"Internal error, the program will exit!",
79 L
"The browser page will close after stop, continue?",
80 L
"Service is running, continue?",
81 L
"Please close another running VentoyPlugson instance!",
82 L
"ventoy\\plugson.tar.xz does not exist, please run under the correct directory!",
85 const WCHAR
**g_msg_lang
= NULL
;
89 char g_log_file
[MAX_PATH
];
90 char g_cur_dir
[MAX_PATH
];
92 int ventoy_log_init(void);
93 void ventoy_log_exit(void);
95 static BOOL
OnDestroyDialog()
107 static void OpenURL(void)
111 const static char * Browsers
[] =
113 "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
114 "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
115 "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe",
116 "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
120 sprintf_s(url
, sizeof(url
), "http://%s:%s/index.html", g_sysinfo
.ip
, g_sysinfo
.port
);
124 for (i
= 0; Browsers
[i
] != NULL
; i
++)
126 if (ventoy_is_file_exist("%s", Browsers
[i
]))
128 ShellExecuteA(NULL
, "open", Browsers
[i
], url
, NULL
, SW_SHOW
);
134 ShellExecuteA(NULL
, "open", url
, NULL
, NULL
, SW_SHOW
);
138 static void FillCombox(HWND hWnd
)
142 const ventoy_disk
*list
= NULL
;
143 CHAR DeviceName
[256];
146 SendMessage(g_ComboxHwnd
, CB_RESETCONTENT
, 0, 0);
148 list
= ventoy_get_disk_list(&num
);
149 if (NULL
== list
|| num
<= 0)
154 for (i
= 0; i
< num
; i
++)
156 sprintf_s(DeviceName
, sizeof(DeviceName
),
159 list
[i
].cur_capacity
,
161 SendMessageA(g_ComboxHwnd
, CB_ADDSTRING
, 0, (LPARAM
)DeviceName
);
163 SendMessage(g_ComboxHwnd
, CB_SETCURSEL
, 0, 0);
167 static BOOL
InitDialog(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
171 g_ComboxHwnd
= GetDlgItem(hWnd
, IDC_COMBO1
);
172 g_refresh_button
= GetDlgItem(hWnd
, IDC_BUTTON1
);
173 g_start_button
= GetDlgItem(hWnd
, IDC_BUTTON2
);
174 g_openlink_button
= GetDlgItem(hWnd
, IDC_BUTTON3
);
175 g_exit_button
= GetDlgItem(hWnd
, IDC_BUTTON4
);
177 hIcon
= LoadIcon(g_hInst
, MAKEINTRESOURCE(IDI_ICON1
));
178 SendMessage(hWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
179 SendMessage(hWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
181 SetWindowTextW(g_refresh_button
, g_msg_lang
[MSGID_BTN_REFRESH
]);
182 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_START
]);
183 SetWindowTextW(g_openlink_button
, g_msg_lang
[MSGID_BTN_LINK
]);
184 SetWindowTextW(g_exit_button
, g_msg_lang
[MSGID_BTN_EXIT
]);
186 EnableWindow(g_openlink_button
, FALSE
);
193 static void VentoyStopService()
198 static int VentoyStartService(int sel
)
203 char CurDir
[MAX_PATH
];
204 const ventoy_disk
*disk
= NULL
;
206 vlog("VentoyStartService ...\n");
208 disk
= ventoy_get_disk_node(sel
);
214 vlog("Start service at %C: %s %s ...\n", disk
->devname
[0], disk
->cur_model
, disk
->cur_ventoy_ver
);
216 g_cur_dir
[0] = disk
->devname
[0];
221 g_sysinfo
.pathcase
= disk
->pathcase
;
222 g_sysinfo
.cur_secureboot
= disk
->cur_secureboot
;
223 g_sysinfo
.cur_part_style
= disk
->cur_part_style
;
224 strlcpy(g_sysinfo
.cur_fsname
, disk
->cur_fsname
);
225 strlcpy(g_sysinfo
.cur_capacity
, disk
->cur_capacity
);
226 strlcpy(g_sysinfo
.cur_model
, disk
->cur_model
);
227 strlcpy(g_sysinfo
.cur_ventoy_ver
, disk
->cur_ventoy_ver
);
229 bRet
= SetCurrentDirectoryA(g_cur_dir
);
230 vlog("SetCurrentDirectoryA %u <%s>\n", bRet
, g_cur_dir
);
233 GetCurrentDirectoryA(sizeof(CurDir
), CurDir
);
234 vlog("CurDir=<%s>\n", CurDir
);
236 if (strcmp(g_cur_dir
, CurDir
))
238 vlog("Failed to change current directory.");
243 if (ventoy_is_directory_exist("ventoy"))
245 if (g_sysinfo
.pathcase
)
247 vlog("ventoy directory already exist, check case sensitive.\n");
248 strlcpy(Path
, "ventoy");
250 rc
= ventoy_path_case(Path
, 0);
251 vlog("ventoy_path_case actual path is <%s> <count:%d>\n", Path
, rc
);
255 vlog("ventoy directory case mismatch, rename<%s>--><%s>\n", Path
, "ventoy");
256 if (MoveFileA(Path
, "ventoy"))
258 vlog("Rename <%s>--><%s> success\n", Path
, "ventoy");
262 vlog("Rename <%s>--><%s> failed %u\n", Path
, "ventoy", LASTERR
);
263 MessageBoxW(NULL
, g_msg_lang
[MSGID_RENAME_VENTOY
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
270 vlog("ventoy directory already exist, no need to check case sensitive.\n");
275 if (CreateDirectoryA("ventoy", NULL
))
277 vlog("Create ventoy directory success.\n");
281 vlog("Create ventoy directory failed %u.\n", LASTERR
);
282 MessageBoxW(NULL
, g_msg_lang
[MSGID_NEW_DIR_FAIL
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
287 return ventoy_http_start(g_sysinfo
.ip
, g_sysinfo
.port
);
290 INT_PTR CALLBACK
DialogProc(HWND hWnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
306 code
= ((LPNMHDR
)lParam
)->code
;
307 idFrom
= ((LPNMHDR
)lParam
)->idFrom
;
310 if (idFrom
== IDC_SYSLINK1
&& (NM_CLICK
== code
|| NM_RETURN
== code
))
318 NotifyCode
= HIWORD(wParam
);
319 CtrlID
= LOWORD(wParam
);
321 if (NotifyCode
== BN_CLICKED
)
323 if (CtrlID
== IDC_BUTTON1
)
333 else if (CtrlID
== IDC_BUTTON2
)
337 if (IDYES
== MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_STOP_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
342 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_START
]);
343 EnableWindow(g_ComboxHwnd
, TRUE
);
344 EnableWindow(g_refresh_button
, TRUE
);
345 EnableWindow(g_openlink_button
, FALSE
);
350 nCurSel
= (int)SendMessage(g_ComboxHwnd
, CB_GETCURSEL
, 0, 0);
351 if (CB_ERR
!= nCurSel
)
353 rc
= VentoyStartService(nCurSel
);
356 vlog("Ventoy failed to start http server, check %s for detail\n", g_log_file
);
357 MessageBoxW(NULL
, g_msg_lang
[MSGID_INTERNAL_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
362 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_STOP
]);
364 EnableWindow(g_ComboxHwnd
, FALSE
);
365 EnableWindow(g_refresh_button
, FALSE
);
366 EnableWindow(g_openlink_button
, TRUE
);
373 else if (CtrlID
== IDC_BUTTON3
)
380 else if (CtrlID
== IDC_BUTTON4
)
384 if (IDYES
!= MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_EXIT_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
400 InitDialog(hWnd
, wParam
, lParam
);
407 if (IDYES
!= MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_EXIT_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
423 static int ParseCmdLine(LPSTR lpCmdLine
, char *ip
, char *port
)
435 pos
= strstr(lpCmdLine
, "-H");
438 pos
= strstr(lpCmdLine
, "-h");
444 while (*pos
== ' ' || *pos
== '\t')
449 while (isdigit(*pos
) || *pos
== '.')
456 pos
= strstr(lpCmdLine
, "-P");
459 pos
= strstr(lpCmdLine
, "-p");
464 portnum
= (int)strtol(pos
+ 3, NULL
, 10);
465 sprintf_s(port
, 16, "%d", portnum
);
475 //Copyright © 2011-2021 Pete Batard <pete@akeo.ie>
477 #include <delayimp.h>
478 // For delay-loaded DLLs, use LOAD_LIBRARY_SEARCH_SYSTEM32 to avoid DLL search order hijacking.
479 FARPROC WINAPI
dllDelayLoadHook(unsigned dliNotify
, PDelayLoadInfo pdli
)
481 if (dliNotify
== dliNotePreLoadLibrary
) {
482 // Windows 7 without KB2533623 does not support the LOAD_LIBRARY_SEARCH_SYSTEM32 flag.
483 // That is is OK, because the delay load handler will interrupt the NULL return value
484 // to mean that it should perform a normal LoadLibrary.
485 return (FARPROC
)LoadLibraryExA(pdli
->szDll
, NULL
, LOAD_LIBRARY_SEARCH_SYSTEM32
);
490 #if defined(_MSC_VER)
491 // By default the Windows SDK headers have a `const` while MinGW does not.
494 PfnDliHook __pfnDliNotifyHook2
= dllDelayLoadHook
;
496 typedef BOOL(WINAPI
* SetDefaultDllDirectories_t
)(DWORD
);
497 static void DllProtect(void)
499 SetDefaultDllDirectories_t pfSetDefaultDllDirectories
= NULL
;
501 // Disable loading system DLLs from the current directory (sideloading mitigation)
502 // PS: You know that official MSDN documentation for SetDllDirectory() that explicitly
503 // indicates that "If the parameter is an empty string (""), the call removes the current
504 // directory from the default DLL search order"? Yeah, that doesn't work. At all.
505 // Still, we invoke it, for platforms where the following call might actually work...
506 SetDllDirectoryA("");
508 // For libraries on the KnownDLLs list, the system will always load them from System32.
509 // For other DLLs we link directly to, we can delay load the DLL and use a delay load
510 // hook to load them from System32. Note that, for this to work, something like:
511 // 'somelib.dll;%(DelayLoadDLLs)' must be added to the 'Delay Loaded Dlls' option of
512 // the linker properties in Visual Studio (which means this won't work with MinGW).
513 // For all other DLLs, use SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32).
514 // Finally, we need to perform the whole gymkhana below, where we can't call on
515 // SetDefaultDllDirectories() directly, because Windows 7 doesn't have the API exposed.
516 // Also, no, Coverity, we never need to care about freeing kernel32 as a library.
517 // coverity[leaked_storage]
519 pfSetDefaultDllDirectories
= (SetDefaultDllDirectories_t
)
520 GetProcAddress(LoadLibraryW(L
"kernel32.dll"), "SetDefaultDllDirectories");
521 if (pfSetDefaultDllDirectories
!= NULL
)
522 pfSetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32
);
526 int APIENTRY
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, INT nCmdShow
)
531 WCHAR CurDir
[MAX_PATH
];
533 UNREFERENCED_PARAMETER(hPrevInstance
);
535 for (i
= 0; i
< __argc
; i
++)
537 if (__argv
[i
] && _stricmp(__argv
[i
], "/F") == 0)
539 g_ChromeFirst
= FALSE
;
546 if (GetUserDefaultUILanguage() == 0x0804)
548 g_sysinfo
.language
= LANGUAGE_CN
;
549 g_msg_lang
= g_msg_cn
;
553 g_sysinfo
.language
= LANGUAGE_EN
;
554 g_msg_lang
= g_msg_en
;
557 hMutex
= CreateMutexA(NULL
, TRUE
, "PlugsonMUTEX");
558 if ((hMutex
!= NULL
) && (GetLastError() == ERROR_ALREADY_EXISTS
))
560 MessageBoxW(NULL
, g_msg_lang
[MSGID_RUNNING_TIP
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
564 GetCurrentDirectoryW(MAX_PATH
, CurDir
);
565 WideCharToMultiByte(CP_UTF8
, 0, CurDir
, -1, g_cur_dir
, MAX_PATH
, NULL
, 0);
567 sprintf_s(g_ventoy_dir
, sizeof(g_ventoy_dir
), "%s", g_cur_dir
);
568 sprintf_s(g_log_file
, sizeof(g_log_file
), "%s\\%s", g_cur_dir
, LOG_FILE
);
571 if (!ventoy_is_file_exist("%s\\ventoy\\%s", g_ventoy_dir
, PLUGSON_TXZ
))
573 MessageBoxW(NULL
, g_msg_lang
[MSGID_NO_TARXZ_TIP
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
577 ParseCmdLine(lpCmdLine
, g_sysinfo
.ip
, g_sysinfo
.port
);
578 if (g_sysinfo
.ip
[0] == 0)
580 strlcpy(g_sysinfo
.ip
, "127.0.0.1");
582 if (g_sysinfo
.port
[0] == 0)
584 strlcpy(g_sysinfo
.port
, "24681");
587 vlog("===============================================\n");
588 vlog("===== Ventoy Plugson %s:%s =====\n", g_sysinfo
.ip
, g_sysinfo
.port
);
589 vlog("===============================================\n");
594 rc
= ventoy_www_init();
597 vlog("Failed to init www\n");
598 MessageBoxW(NULL
, g_msg_lang
[MSGID_INTERNAL_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
608 DialogBoxA(hInstance
, MAKEINTRESOURCE(IDD_DIALOG1
), NULL
, DialogProc
);