]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Plugson/src/main_windows.c
1.0.70 release
[Ventoy.git] / Plugson / src / main_windows.c
1 #include <Windows.h>
2 #include <Shlobj.h>
3 #include <tlhelp32.h>
4 #include <Psapi.h>
5 #include <commctrl.h>
6 #include <resource.h>
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>
12
13 char g_ventoy_dir[MAX_PATH];
14
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;
21
22 typedef enum MSGID
23 {
24 MSGID_ERROR = 0,
25 MSGID_INFO,
26 MSGID_INVALID_DIR,
27 MSGID_NEW_DIR_FAIL,
28 MSGID_RENAME_VENTOY,
29 MSGID_INTERNAL_ERR,
30 MSGID_BTN_REFRESH,
31 MSGID_BTN_START,
32 MSGID_BTN_STOP,
33 MSGID_BTN_LINK,
34 MSGID_BTN_EXIT,
35
36 MSGID_BTN_STOP_TIP,
37 MSGID_BTN_EXIT_TIP,
38 MSGID_RUNNING_TIP,
39 MSGID_NO_TARXZ_TIP,
40
41 MSGID_BUTT
42 }MSGID;
43
44
45 const WCHAR *g_msg_cn[MSGID_BUTT] =
46 {
47 L"´íÎó",
48 L"ÌáÐÑ",
49 L"ÇëÔÚ Ventoy Å̸ùĿ¼ÏÂÔËÐб¾³ÌÐò£¡£¨´æ·ÅISOÎļþµÄλÖã©",
50 L"´´½¨ ventoy Ŀ¼ʧ°Ü£¬ÎÞ·¨¼ÌÐø£¡",
51 L"ventoy Ŀ¼´æÔÚ£¬µ«ÊÇ´óСд²»Æ¥Å䣬ÇëÏȽ«ÆäÖØÃüÃû£¡",
52 L"ÄÚ²¿´íÎ󣬳ÌÐò¼´½«Í˳ö£¡",
53 L"Ë¢ÐÂ",
54 L"Æô¶¯",
55 L"ֹͣ",
56 L"Á´½Ó",
57 L"Í˳ö",
58
59 L"Í£Ö¹ÔËÐкóä¯ÀÀÆ÷Ò³Ãæ½«»á¹Ø±Õ£¬ÊÇ·ñ¼ÌÐø£¿",
60 L"µ±Ç°·þÎñÕýÔÚÔËÐУ¬ÊÇ·ñÍ˳ö£¿",
61 L"ÇëÏȹرÕÕýÔÚÔËÐÐµÄ VentoyPlugson ³ÌÐò£¡",
62 L"ventoy\\plugson.tar.xz Îļþ²»´æÔÚ£¬ÇëÔÚÕýÈ·µÄĿ¼ÏÂÔËÐУ¡",
63 };
64 const WCHAR *g_msg_en[MSGID_BUTT] =
65 {
66 L"Error",
67 L"Info",
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!",
72 L"Refresh",
73 L"Start",
74 L"Stop",
75 L"Link",
76 L"Exit",
77
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!",
82 };
83
84 const WCHAR **g_msg_lang = NULL;
85
86 HINSTANCE g_hInst;
87
88 char g_log_file[MAX_PATH];
89 char g_cur_dir[MAX_PATH];
90
91 int ventoy_log_init(void);
92 void ventoy_log_exit(void);
93
94 static BOOL OnDestroyDialog()
95 {
96 ventoy_http_exit();
97 ventoy_disk_exit();
98 #ifndef VENTOY_SIM
99 ventoy_www_exit();
100 #endif
101 ventoy_log_exit();
102 return TRUE;
103 }
104
105
106 static void OpenURL(void)
107 {
108 int i;
109 char url[128];
110 const static char * Browsers[] =
111 {
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",
116 NULL
117 };
118
119 sprintf_s(url, sizeof(url), "http://%s:%s/index.html", g_sysinfo.ip, g_sysinfo.port);
120
121 for (i = 0; Browsers[i] != NULL; i++)
122 {
123 if (ventoy_is_file_exist("%s", Browsers[i]))
124 {
125 ShellExecuteA(NULL, "open", Browsers[i], url, NULL, SW_SHOW);
126 return;
127 }
128 }
129
130 ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOW);
131 }
132
133
134 static void FillCombox(HWND hWnd)
135 {
136 int i = 0;
137 int num = 0;
138 const ventoy_disk *list = NULL;
139 CHAR DeviceName[256];
140
141 // delete all items
142 SendMessage(g_ComboxHwnd, CB_RESETCONTENT, 0, 0);
143
144 list = ventoy_get_disk_list(&num);
145 if (NULL == list || num <= 0)
146 {
147 return;
148 }
149
150 for (i = 0; i < num; i++)
151 {
152 sprintf_s(DeviceName, sizeof(DeviceName),
153 "%C: [%s] %s",
154 list[i].devname[0],
155 list[i].cur_capacity,
156 list[i].cur_model);
157 SendMessageA(g_ComboxHwnd, CB_ADDSTRING, 0, (LPARAM)DeviceName);
158 }
159 SendMessage(g_ComboxHwnd, CB_SETCURSEL, 0, 0);
160 }
161
162
163 static BOOL InitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
164 {
165 HICON hIcon;
166
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);
172
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);
176
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]);
181
182 EnableWindow(g_openlink_button, FALSE);
183
184 FillCombox(hWnd);
185
186 return TRUE;
187 }
188
189 static void VentoyStopService()
190 {
191 ventoy_http_stop();
192 }
193
194 static int VentoyStartService(int sel)
195 {
196 int rc;
197 BOOL bRet;
198 char Path[128];
199 char CurDir[MAX_PATH];
200 const ventoy_disk *disk = NULL;
201
202 vlog("VentoyStartService ...\n");
203
204 disk = ventoy_get_disk_node(sel);
205 if (disk == NULL)
206 {
207 return 1;
208 }
209
210 vlog("Start service at %C: %s %s ...\n", disk->devname[0], disk->cur_model, disk->cur_ventoy_ver);
211
212 g_cur_dir[0] = disk->devname[0];
213 g_cur_dir[1] = ':';
214 g_cur_dir[2] = '\\';
215 g_cur_dir[3] = 0;
216
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);
224
225 bRet = SetCurrentDirectoryA(g_cur_dir);
226 vlog("SetCurrentDirectoryA %u <%s>\n", bRet, g_cur_dir);
227
228 CurDir[0] = 0;
229 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
230 vlog("CurDir=<%s>\n", CurDir);
231
232 if (strcmp(g_cur_dir, CurDir))
233 {
234 vlog("Failed to change current directory.");
235 }
236
237 g_cur_dir[2] = 0;
238
239 if (ventoy_is_directory_exist("ventoy"))
240 {
241 if (g_sysinfo.pathcase)
242 {
243 vlog("ventoy directory already exist, check case sensitive.\n");
244 strlcpy(Path, "ventoy");
245
246 rc = ventoy_path_case(Path, 0);
247 vlog("ventoy_path_case actual path is <%s> <count:%d>\n", Path, rc);
248
249 if (rc)
250 {
251 vlog("ventoy directory case mismatch, rename<%s>--><%s>\n", Path, "ventoy");
252 if (MoveFileA(Path, "ventoy"))
253 {
254 vlog("Rename <%s>--><%s> success\n", Path, "ventoy");
255 }
256 else
257 {
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);
260 return 1;
261 }
262 }
263 }
264 else
265 {
266 vlog("ventoy directory already exist, no need to check case sensitive.\n");
267 }
268 }
269 else
270 {
271 if (CreateDirectoryA("ventoy", NULL))
272 {
273 vlog("Create ventoy directory success.\n");
274 }
275 else
276 {
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);
279 return 1;
280 }
281 }
282
283 return ventoy_http_start(g_sysinfo.ip, g_sysinfo.port);
284 }
285
286 INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
287 {
288 int rc;
289 int nCurSel;
290 WORD NotifyCode;
291 WORD CtrlID;
292
293 switch (Message)
294 {
295 case WM_NOTIFY:
296 {
297 UINT code = 0;
298 UINT_PTR idFrom = 0;
299
300 if (lParam)
301 {
302 code = ((LPNMHDR)lParam)->code;
303 idFrom = ((LPNMHDR)lParam)->idFrom;
304 }
305
306 if (idFrom == IDC_SYSLINK1 && (NM_CLICK == code || NM_RETURN == code))
307 {
308 OpenURL();
309 }
310 break;
311 }
312 case WM_COMMAND:
313 {
314 NotifyCode = HIWORD(wParam);
315 CtrlID = LOWORD(wParam);
316
317 if (NotifyCode == BN_CLICKED)
318 {
319 if (CtrlID == IDC_BUTTON1)
320 {
321 if (!g_running)
322 {
323 //refresh
324 ventoy_disk_exit();
325 ventoy_disk_init();
326 FillCombox(hWnd);
327 }
328 }
329 else if (CtrlID == IDC_BUTTON2)
330 {
331 if (g_running)
332 {
333 if (IDYES == MessageBoxW(NULL, g_msg_lang[MSGID_BTN_STOP_TIP], g_msg_lang[MSGID_INFO], MB_YESNO | MB_ICONINFORMATION))
334 {
335 VentoyStopService();
336
337 g_running = FALSE;
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);
342 }
343 }
344 else
345 {
346 nCurSel = (int)SendMessage(g_ComboxHwnd, CB_GETCURSEL, 0, 0);
347 if (CB_ERR != nCurSel)
348 {
349 rc = VentoyStartService(nCurSel);
350 if (rc)
351 {
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);
354 }
355 else
356 {
357 g_running = TRUE;
358 SetWindowTextW(g_start_button, g_msg_lang[MSGID_BTN_STOP]);
359
360 EnableWindow(g_ComboxHwnd, FALSE);
361 EnableWindow(g_refresh_button, FALSE);
362 EnableWindow(g_openlink_button, TRUE);
363
364 OpenURL();
365 }
366 }
367 }
368 }
369 else if (CtrlID == IDC_BUTTON3)
370 {
371 if (g_running)
372 {
373 OpenURL();
374 }
375 }
376 else if (CtrlID == IDC_BUTTON4)
377 {
378 if (g_running)
379 {
380 if (IDYES != MessageBoxW(NULL, g_msg_lang[MSGID_BTN_EXIT_TIP], g_msg_lang[MSGID_INFO], MB_YESNO | MB_ICONINFORMATION))
381 {
382 return 0;
383 }
384
385 ventoy_http_stop();
386 }
387
388 OnDestroyDialog();
389 EndDialog(hWnd, 0);
390 }
391 }
392 break;
393 }
394 case WM_INITDIALOG:
395 {
396 InitDialog(hWnd, wParam, lParam);
397 break;
398 }
399 case WM_CLOSE:
400 {
401 if (g_running)
402 {
403 if (IDYES != MessageBoxW(NULL, g_msg_lang[MSGID_BTN_EXIT_TIP], g_msg_lang[MSGID_INFO], MB_YESNO | MB_ICONINFORMATION))
404 {
405 return 0;
406 }
407
408 VentoyStopService();
409 }
410
411 OnDestroyDialog();
412 EndDialog(hWnd, 0);
413 }
414 }
415
416 return 0;
417 }
418
419 static int ParseCmdLine(LPSTR lpCmdLine, char *ip, char *port)
420 {
421 int portnum;
422 char *ipstart = ip;
423 char *pos;
424
425
426 if (!lpCmdLine)
427 {
428 return 0;
429 }
430
431 pos = strstr(lpCmdLine, "-H");
432 if (!pos)
433 {
434 pos = strstr(lpCmdLine, "-h");
435 }
436
437 if (pos)
438 {
439 pos += 2;
440 while (*pos == ' ' || *pos == '\t')
441 {
442 pos++;
443 }
444
445 while (isdigit(*pos) || *pos == '.')
446 {
447 *ipstart++ = *pos++;
448 }
449 }
450
451
452 pos = strstr(lpCmdLine, "-P");
453 if (!pos)
454 {
455 pos = strstr(lpCmdLine, "-p");
456 }
457
458 if (pos)
459 {
460 portnum = (int)strtol(pos + 3, NULL, 10);
461 sprintf_s(port, 16, "%d", portnum);
462 }
463
464 return 0;
465 }
466
467 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
468 {
469 int rc;
470 HANDLE hMutex;
471 WCHAR CurDir[MAX_PATH];
472
473 UNREFERENCED_PARAMETER(hPrevInstance);
474
475 if (GetUserDefaultUILanguage() == 0x0804)
476 {
477 g_sysinfo.language = LANGUAGE_CN;
478 g_msg_lang = g_msg_cn;
479 }
480 else
481 {
482 g_sysinfo.language = LANGUAGE_EN;
483 g_msg_lang = g_msg_en;
484 }
485
486 hMutex = CreateMutexA(NULL, TRUE, "PlugsonMUTEX");
487 if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
488 {
489 MessageBoxW(NULL, g_msg_lang[MSGID_RUNNING_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
490 return 1;
491 }
492
493 GetCurrentDirectoryW(MAX_PATH, CurDir);
494 WideCharToMultiByte(CP_UTF8, 0, CurDir, -1, g_cur_dir, MAX_PATH, NULL, 0);
495
496 sprintf_s(g_ventoy_dir, sizeof(g_ventoy_dir), "%s", g_cur_dir);
497 sprintf_s(g_log_file, sizeof(g_log_file), "%s\\%s", g_cur_dir, LOG_FILE);
498 ventoy_log_init();
499
500 if (!ventoy_is_file_exist("%s\\ventoy\\%s", g_ventoy_dir, PLUGSON_TXZ))
501 {
502 MessageBoxW(NULL, g_msg_lang[MSGID_NO_TARXZ_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
503 return 1;
504 }
505
506 ParseCmdLine(lpCmdLine, g_sysinfo.ip, g_sysinfo.port);
507 if (g_sysinfo.ip[0] == 0)
508 {
509 strlcpy(g_sysinfo.ip, "127.0.0.1");
510 }
511 if (g_sysinfo.port[0] == 0)
512 {
513 strlcpy(g_sysinfo.port, "24681");
514 }
515
516 vlog("===============================================\n");
517 vlog("===== Ventoy Plugson %s:%s =====\n", g_sysinfo.ip, g_sysinfo.port);
518 vlog("===============================================\n");
519
520
521 ventoy_disk_init();
522 #ifndef VENTOY_SIM
523 rc = ventoy_www_init();
524 if (rc)
525 {
526 vlog("Failed to init www\n");
527 MessageBoxW(NULL, g_msg_lang[MSGID_INTERNAL_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
528
529 ventoy_disk_exit();
530 ventoy_log_exit();
531 return 1;
532 }
533 #endif
534 ventoy_http_init();
535
536 g_hInst = hInstance;
537 DialogBoxA(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
538
539 return 0;
540 }
541