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_running
= FALSE
;
16 static HWND g_refresh_button
;
17 static HWND g_start_button
;
18 static HWND g_openlink_button
;
19 static HWND g_exit_button
;
20 static HWND g_ComboxHwnd
;
45 const WCHAR
*g_msg_cn
[MSGID_BUTT
] =
49 L
"请在 Ventoy 盘根目录下运行本程序!(存放ISO文件的位置)",
50 L
"创建 ventoy 目录失败,无法继续!",
51 L
"ventoy 目录存在,但是大小写不匹配,请先将其重命名!",
59 L
"停止运行后浏览器页面将会关闭,是否继续?",
61 L
"请先关闭正在运行的 VentoyPlugson 程序!",
62 L
"ventoy\\plugson.tar.xz 文件不存在,请在正确的目录下运行!",
64 const WCHAR
*g_msg_en
[MSGID_BUTT
] =
68 L
"Please run me at the root of Ventoy partition.",
69 L
"Failed to create ventoy directory!",
70 L
"ventoy directory case mismatch, please rename it first!",
71 L
"Internal error, the program will exit!",
78 L
"The browser page will close after stop, continue?",
79 L
"Service is running, continue?",
80 L
"Please close another running VentoyPlugson instance!",
81 L
"ventoy\\plugson.tar.xz does not exist, please run under the correct directory!",
84 const WCHAR
**g_msg_lang
= NULL
;
88 char g_log_file
[MAX_PATH
];
89 char g_cur_dir
[MAX_PATH
];
91 int ventoy_log_init(void);
92 void ventoy_log_exit(void);
94 static BOOL
OnDestroyDialog()
106 static void OpenURL(void)
110 const static char * Browsers
[] =
112 "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
113 "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
114 "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe",
115 "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
119 sprintf_s(url
, sizeof(url
), "http://%s:%s/index.html", g_sysinfo
.ip
, g_sysinfo
.port
);
121 for (i
= 0; Browsers
[i
] != NULL
; i
++)
123 if (ventoy_is_file_exist("%s", Browsers
[i
]))
125 ShellExecuteA(NULL
, "open", Browsers
[i
], url
, NULL
, SW_SHOW
);
130 ShellExecuteA(NULL
, "open", url
, NULL
, NULL
, SW_SHOW
);
134 static void FillCombox(HWND hWnd
)
138 const ventoy_disk
*list
= NULL
;
139 CHAR DeviceName
[256];
142 SendMessage(g_ComboxHwnd
, CB_RESETCONTENT
, 0, 0);
144 list
= ventoy_get_disk_list(&num
);
145 if (NULL
== list
|| num
<= 0)
150 for (i
= 0; i
< num
; i
++)
152 sprintf_s(DeviceName
, sizeof(DeviceName
),
155 list
[i
].cur_capacity
,
157 SendMessageA(g_ComboxHwnd
, CB_ADDSTRING
, 0, (LPARAM
)DeviceName
);
159 SendMessage(g_ComboxHwnd
, CB_SETCURSEL
, 0, 0);
163 static BOOL
InitDialog(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
167 g_ComboxHwnd
= GetDlgItem(hWnd
, IDC_COMBO1
);
168 g_refresh_button
= GetDlgItem(hWnd
, IDC_BUTTON1
);
169 g_start_button
= GetDlgItem(hWnd
, IDC_BUTTON2
);
170 g_openlink_button
= GetDlgItem(hWnd
, IDC_BUTTON3
);
171 g_exit_button
= GetDlgItem(hWnd
, IDC_BUTTON4
);
173 hIcon
= LoadIcon(g_hInst
, MAKEINTRESOURCE(IDI_ICON1
));
174 SendMessage(hWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
175 SendMessage(hWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
177 SetWindowTextW(g_refresh_button
, g_msg_lang
[MSGID_BTN_REFRESH
]);
178 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_START
]);
179 SetWindowTextW(g_openlink_button
, g_msg_lang
[MSGID_BTN_LINK
]);
180 SetWindowTextW(g_exit_button
, g_msg_lang
[MSGID_BTN_EXIT
]);
182 EnableWindow(g_openlink_button
, FALSE
);
189 static void VentoyStopService()
194 static int VentoyStartService(int sel
)
199 char CurDir
[MAX_PATH
];
200 const ventoy_disk
*disk
= NULL
;
202 vlog("VentoyStartService ...\n");
204 disk
= ventoy_get_disk_node(sel
);
210 vlog("Start service at %C: %s %s ...\n", disk
->devname
[0], disk
->cur_model
, disk
->cur_ventoy_ver
);
212 g_cur_dir
[0] = disk
->devname
[0];
217 g_sysinfo
.pathcase
= disk
->pathcase
;
218 g_sysinfo
.cur_secureboot
= disk
->cur_secureboot
;
219 g_sysinfo
.cur_part_style
= disk
->cur_part_style
;
220 strlcpy(g_sysinfo
.cur_fsname
, disk
->cur_fsname
);
221 strlcpy(g_sysinfo
.cur_capacity
, disk
->cur_capacity
);
222 strlcpy(g_sysinfo
.cur_model
, disk
->cur_model
);
223 strlcpy(g_sysinfo
.cur_ventoy_ver
, disk
->cur_ventoy_ver
);
225 bRet
= SetCurrentDirectoryA(g_cur_dir
);
226 vlog("SetCurrentDirectoryA %u <%s>\n", bRet
, g_cur_dir
);
229 GetCurrentDirectoryA(sizeof(CurDir
), CurDir
);
230 vlog("CurDir=<%s>\n", CurDir
);
232 if (strcmp(g_cur_dir
, CurDir
))
234 vlog("Failed to change current directory.");
239 if (ventoy_is_directory_exist("ventoy"))
241 if (g_sysinfo
.pathcase
)
243 vlog("ventoy directory already exist, check case sensitive.\n");
244 strlcpy(Path
, "ventoy");
246 rc
= ventoy_path_case(Path
, 0);
247 vlog("ventoy_path_case actual path is <%s> <count:%d>\n", Path
, rc
);
251 vlog("ventoy directory case mismatch, rename<%s>--><%s>\n", Path
, "ventoy");
252 if (MoveFileA(Path
, "ventoy"))
254 vlog("Rename <%s>--><%s> success\n", Path
, "ventoy");
258 vlog("Rename <%s>--><%s> failed %u\n", Path
, "ventoy", LASTERR
);
259 MessageBoxW(NULL
, g_msg_lang
[MSGID_RENAME_VENTOY
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
266 vlog("ventoy directory already exist, no need to check case sensitive.\n");
271 if (CreateDirectoryA("ventoy", NULL
))
273 vlog("Create ventoy directory success.\n");
277 vlog("Create ventoy directory failed %u.\n", LASTERR
);
278 MessageBoxW(NULL
, g_msg_lang
[MSGID_NEW_DIR_FAIL
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
283 return ventoy_http_start(g_sysinfo
.ip
, g_sysinfo
.port
);
286 INT_PTR CALLBACK
DialogProc(HWND hWnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
302 code
= ((LPNMHDR
)lParam
)->code
;
303 idFrom
= ((LPNMHDR
)lParam
)->idFrom
;
306 if (idFrom
== IDC_SYSLINK1
&& (NM_CLICK
== code
|| NM_RETURN
== code
))
314 NotifyCode
= HIWORD(wParam
);
315 CtrlID
= LOWORD(wParam
);
317 if (NotifyCode
== BN_CLICKED
)
319 if (CtrlID
== IDC_BUTTON1
)
329 else if (CtrlID
== IDC_BUTTON2
)
333 if (IDYES
== MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_STOP_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
338 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_START
]);
339 EnableWindow(g_ComboxHwnd
, TRUE
);
340 EnableWindow(g_refresh_button
, TRUE
);
341 EnableWindow(g_openlink_button
, FALSE
);
346 nCurSel
= (int)SendMessage(g_ComboxHwnd
, CB_GETCURSEL
, 0, 0);
347 if (CB_ERR
!= nCurSel
)
349 rc
= VentoyStartService(nCurSel
);
352 vlog("Ventoy failed to start http server, check %s for detail\n", g_log_file
);
353 MessageBoxW(NULL
, g_msg_lang
[MSGID_INTERNAL_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
358 SetWindowTextW(g_start_button
, g_msg_lang
[MSGID_BTN_STOP
]);
360 EnableWindow(g_ComboxHwnd
, FALSE
);
361 EnableWindow(g_refresh_button
, FALSE
);
362 EnableWindow(g_openlink_button
, TRUE
);
369 else if (CtrlID
== IDC_BUTTON3
)
376 else if (CtrlID
== IDC_BUTTON4
)
380 if (IDYES
!= MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_EXIT_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
396 InitDialog(hWnd
, wParam
, lParam
);
403 if (IDYES
!= MessageBoxW(NULL
, g_msg_lang
[MSGID_BTN_EXIT_TIP
], g_msg_lang
[MSGID_INFO
], MB_YESNO
| MB_ICONINFORMATION
))
419 static int ParseCmdLine(LPSTR lpCmdLine
, char *ip
, char *port
)
431 pos
= strstr(lpCmdLine
, "-H");
434 pos
= strstr(lpCmdLine
, "-h");
440 while (*pos
== ' ' || *pos
== '\t')
445 while (isdigit(*pos
) || *pos
== '.')
452 pos
= strstr(lpCmdLine
, "-P");
455 pos
= strstr(lpCmdLine
, "-p");
460 portnum
= (int)strtol(pos
+ 3, NULL
, 10);
461 sprintf_s(port
, 16, "%d", portnum
);
471 //Copyright © 2011-2021 Pete Batard <pete@akeo.ie>
473 #include <delayimp.h>
474 // For delay-loaded DLLs, use LOAD_LIBRARY_SEARCH_SYSTEM32 to avoid DLL search order hijacking.
475 FARPROC WINAPI
dllDelayLoadHook(unsigned dliNotify
, PDelayLoadInfo pdli
)
477 if (dliNotify
== dliNotePreLoadLibrary
) {
478 // Windows 7 without KB2533623 does not support the LOAD_LIBRARY_SEARCH_SYSTEM32 flag.
479 // That is is OK, because the delay load handler will interrupt the NULL return value
480 // to mean that it should perform a normal LoadLibrary.
481 return (FARPROC
)LoadLibraryExA(pdli
->szDll
, NULL
, LOAD_LIBRARY_SEARCH_SYSTEM32
);
486 #if defined(_MSC_VER)
487 // By default the Windows SDK headers have a `const` while MinGW does not.
490 PfnDliHook __pfnDliNotifyHook2
= dllDelayLoadHook
;
492 typedef BOOL(WINAPI
* SetDefaultDllDirectories_t
)(DWORD
);
493 static void DllProtect(void)
495 SetDefaultDllDirectories_t pfSetDefaultDllDirectories
= NULL
;
497 // Disable loading system DLLs from the current directory (sideloading mitigation)
498 // PS: You know that official MSDN documentation for SetDllDirectory() that explicitly
499 // indicates that "If the parameter is an empty string (""), the call removes the current
500 // directory from the default DLL search order"? Yeah, that doesn't work. At all.
501 // Still, we invoke it, for platforms where the following call might actually work...
502 SetDllDirectoryA("");
504 // For libraries on the KnownDLLs list, the system will always load them from System32.
505 // For other DLLs we link directly to, we can delay load the DLL and use a delay load
506 // hook to load them from System32. Note that, for this to work, something like:
507 // 'somelib.dll;%(DelayLoadDLLs)' must be added to the 'Delay Loaded Dlls' option of
508 // the linker properties in Visual Studio (which means this won't work with MinGW).
509 // For all other DLLs, use SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32).
510 // Finally, we need to perform the whole gymkhana below, where we can't call on
511 // SetDefaultDllDirectories() directly, because Windows 7 doesn't have the API exposed.
512 // Also, no, Coverity, we never need to care about freeing kernel32 as a library.
513 // coverity[leaked_storage]
515 pfSetDefaultDllDirectories
= (SetDefaultDllDirectories_t
)
516 GetProcAddress(LoadLibraryW(L
"kernel32.dll"), "SetDefaultDllDirectories");
517 if (pfSetDefaultDllDirectories
!= NULL
)
518 pfSetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32
);
522 int APIENTRY
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, INT nCmdShow
)
526 WCHAR CurDir
[MAX_PATH
];
528 UNREFERENCED_PARAMETER(hPrevInstance
);
532 if (GetUserDefaultUILanguage() == 0x0804)
534 g_sysinfo
.language
= LANGUAGE_CN
;
535 g_msg_lang
= g_msg_cn
;
539 g_sysinfo
.language
= LANGUAGE_EN
;
540 g_msg_lang
= g_msg_en
;
543 hMutex
= CreateMutexA(NULL
, TRUE
, "PlugsonMUTEX");
544 if ((hMutex
!= NULL
) && (GetLastError() == ERROR_ALREADY_EXISTS
))
546 MessageBoxW(NULL
, g_msg_lang
[MSGID_RUNNING_TIP
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
550 GetCurrentDirectoryW(MAX_PATH
, CurDir
);
551 WideCharToMultiByte(CP_UTF8
, 0, CurDir
, -1, g_cur_dir
, MAX_PATH
, NULL
, 0);
553 sprintf_s(g_ventoy_dir
, sizeof(g_ventoy_dir
), "%s", g_cur_dir
);
554 sprintf_s(g_log_file
, sizeof(g_log_file
), "%s\\%s", g_cur_dir
, LOG_FILE
);
557 if (!ventoy_is_file_exist("%s\\ventoy\\%s", g_ventoy_dir
, PLUGSON_TXZ
))
559 MessageBoxW(NULL
, g_msg_lang
[MSGID_NO_TARXZ_TIP
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
563 ParseCmdLine(lpCmdLine
, g_sysinfo
.ip
, g_sysinfo
.port
);
564 if (g_sysinfo
.ip
[0] == 0)
566 strlcpy(g_sysinfo
.ip
, "127.0.0.1");
568 if (g_sysinfo
.port
[0] == 0)
570 strlcpy(g_sysinfo
.port
, "24681");
573 vlog("===============================================\n");
574 vlog("===== Ventoy Plugson %s:%s =====\n", g_sysinfo
.ip
, g_sysinfo
.port
);
575 vlog("===============================================\n");
580 rc
= ventoy_www_init();
583 vlog("Failed to init www\n");
584 MessageBoxW(NULL
, g_msg_lang
[MSGID_INTERNAL_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
594 DialogBoxA(hInstance
, MAKEINTRESOURCE(IDD_DIALOG1
), NULL
, DialogProc
);