]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Vlnk/src/main_windows.c
Fixed to select the 1st menu item when switching between upper and lower sub-menus.
[Ventoy.git] / Vlnk / src / main_windows.c
1 #include <Windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <time.h>
7 #include <resource.h>
8 #include <vlnk.h>
9
10 static WCHAR g_CurDirW[MAX_PATH];
11 static CHAR g_CurDirA[MAX_PATH];
12 static CHAR g_LogFile[MAX_PATH];
13 static HWND g_create_button;
14 static HWND g_parse_button;
15
16 typedef enum MSGID
17 {
18 MSGID_ERROR = 0,
19 MSGID_INFO,
20 MSGID_BTN_CREATE,
21 MSGID_BTN_PARSE,
22 MSGID_SRC_UNSUPPORTED,
23 MSGID_FS_UNSUPPORTED,
24 MSGID_SUFFIX_UNSUPPORTED,
25 MSGID_DISK_INFO_ERR,
26 MSGID_VLNK_SUCCESS,
27 MSGID_RUNNING_TIP,
28 MSGID_CREATE_FILE_ERR,
29 MSGID_ALREADY_VLNK,
30 MSGID_INVALID_VLNK,
31 MSGID_VLNK_POINT_TO,
32 MSGID_VLNK_NO_DST,
33 MSGID_FILE_NAME_TOO_LONG,
34
35 MSGID_BUTT
36 }MSGID;
37
38
39 const WCHAR *g_msg_cn[MSGID_BUTT] =
40 {
41 L"´íÎó",
42 L"ÌáÐÑ",
43 L"´´½¨",
44 L"½âÎö",
45 L"²»Ö§³ÖΪ´ËÎļþ´´½¨vlnk",
46 L"²»Ö§³ÖµÄÎļþϵͳ",
47 L"²»Ö§³ÖµÄÎļþºó׺Ãû",
48 L"»ñÈ¡´ÅÅÌÐÅϢʱ·¢Éú´íÎó",
49 L"Vlnk Îļþ´´½¨³É¹¦¡£",
50 L"ÇëÏȹرÕÕýÔÚÔËÐÐµÄ VentoyVlnk ³ÌÐò£¡",
51 L"´´½¨Îļþʧ°Ü",
52 L"´ËÎļþÒѾ­ÊÇÒ»¸övlnkÎļþÁË£¡",
53 L"·Ç·¨µÄvlnkÎļþ!",
54 L"´Ë vlnk ÎļþÖ¸Ïò ",
55 L"´Ë vlnk Ö¸ÏòµÄÎļþ²»´æÔÚ£¡",
56 L"Îļþ·¾¶Ì«³¤£¡",
57 };
58 const WCHAR *g_msg_en[MSGID_BUTT] =
59 {
60 L"Error",
61 L"Info",
62 L"Create",
63 L"Parse",
64 L"This file is not supported for vlnk",
65 L"Unsupported file system!",
66 L"Unsupported file suffix!",
67 L"Error when getting disk info",
68 L"Vlnk file successfully created!",
69 L"Please close another running VentoyVlnk instance!",
70 L"Failed to create file!",
71 L"This file is already a vlnk file!",
72 L"Invalid vlnk file!",
73 L"The vlnk file point to ",
74 L"The file pointed by the vlnk does NOT exist!",
75 L"The file full path is too long!",
76 };
77
78 const WCHAR **g_msg_lang = NULL;
79
80 HINSTANCE g_hInst;
81
82 static void Log2File(const char *log)
83 {
84 time_t stamp;
85 struct tm ttm;
86 FILE *fp;
87
88 time(&stamp);
89 localtime_s(&ttm, &stamp);
90
91 fopen_s(&fp, g_LogFile, "a+");
92 if (fp)
93 {
94 fprintf_s(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
95 ttm.tm_year + 1900, ttm.tm_mon + 1, ttm.tm_mday,
96 ttm.tm_hour, ttm.tm_min, ttm.tm_sec, log);
97 fclose(fp);
98 }
99 }
100
101 void LogW(const WCHAR *Fmt, ...)
102 {
103 WCHAR log[512];
104 CHAR alog[2048];
105 va_list arg;
106
107 if (g_LogFile[0] == 0)
108 {
109 return;
110 }
111
112 va_start(arg, Fmt);
113 vswprintf_s(log, 512, Fmt, arg);
114 va_end(arg);
115
116 WideCharToMultiByte(CP_UTF8, 0, log, -1, alog, 2048, 0, 0);
117
118 Log2File(alog);
119 }
120
121
122 void LogA(const CHAR *Fmt, ...)
123 {
124 CHAR log[512];
125 va_list arg;
126
127 if (g_LogFile[0] == 0)
128 {
129 return;
130 }
131
132 va_start(arg, Fmt);
133 vsprintf_s(log, 512, Fmt, arg);
134 va_end(arg);
135
136 Log2File(log);
137 }
138
139 static int Utf8ToUtf16(const char* src, WCHAR * dst)
140 {
141 int size = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, 0);
142 return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size + 1);
143 }
144
145 static BOOL OnDestroyDialog()
146 {
147 return TRUE;
148 }
149
150
151 static BOOL InitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
152 {
153 HICON hIcon;
154
155 g_create_button = GetDlgItem(hWnd, IDC_BUTTON1);
156 g_parse_button = GetDlgItem(hWnd, IDC_BUTTON2);
157
158 hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1));
159 SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
160 SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
161
162 SetWindowTextW(g_create_button, g_msg_lang[MSGID_BTN_CREATE]);
163 SetWindowTextW(g_parse_button, g_msg_lang[MSGID_BTN_PARSE]);
164
165 return TRUE;
166 }
167
168 static int GetPhyDiskInfo(const char LogicalDrive, UINT32 *DiskSig, DISK_EXTENT *DiskExtent)
169 {
170 BOOL Ret;
171 DWORD dwSize;
172 HANDLE Handle;
173 VOLUME_DISK_EXTENTS DiskExtents;
174 CHAR PhyPath[128];
175 UINT8 SectorBuf[512];
176
177 LogA("GetPhyDiskInfo %C\n", LogicalDrive);
178
179 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
180 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
181 if (Handle == INVALID_HANDLE_VALUE)
182 {
183 LogA("Could not open the disk %C: error:%u\n", LogicalDrive, GetLastError());
184 return 1;
185 }
186
187 Ret = DeviceIoControl(Handle,
188 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
189 NULL,
190 0,
191 &DiskExtents,
192 (DWORD)(sizeof(DiskExtents)),
193 (LPDWORD)&dwSize,
194 NULL);
195 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
196 {
197 LogA("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u\n", GetLastError());
198 CloseHandle(Handle);
199 return 1;
200 }
201 CloseHandle(Handle);
202
203 memcpy(DiskExtent, DiskExtents.Extents, sizeof(DISK_EXTENT));
204 LogA("%C: is in PhysicalDrive%d Offset:%llu\n", LogicalDrive, DiskExtents.Extents[0].DiskNumber,
205 (ULONGLONG)(DiskExtents.Extents[0].StartingOffset.QuadPart));
206
207 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
208 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
209 if (Handle == INVALID_HANDLE_VALUE)
210 {
211 LogA("Could not open the disk<PhysicalDrive%d>, error:%u\n", DiskExtents.Extents[0].DiskNumber, GetLastError());
212 return 1;
213 }
214
215 if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
216 {
217 LogA("ReadFile failed, dwSize:%u error:%u\n", dwSize, GetLastError());
218 CloseHandle(Handle);
219 return 1;
220 }
221
222 memcpy(DiskSig, SectorBuf + 0x1B8, 4);
223
224 CloseHandle(Handle);
225 return 0;
226 }
227
228
229 static int SaveBuffer2File(const WCHAR *Fullpath, void *Buffer, DWORD Length)
230 {
231 int rc = 1;
232 DWORD dwSize;
233 HANDLE Handle;
234
235 LogW(L"SaveBuffer2File <%ls> len:%u\n", Fullpath, Length);
236
237 Handle = CreateFileW(Fullpath, GENERIC_READ | GENERIC_WRITE,
238 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
239 if (Handle == INVALID_HANDLE_VALUE)
240 {
241 LogA("Could not create new file, error:%u\n", GetLastError());
242 goto End;
243 }
244
245 WriteFile(Handle, Buffer, Length, &dwSize, NULL);
246
247 rc = 0;
248
249 End:
250
251 if (Handle != INVALID_HANDLE_VALUE)
252 {
253 CloseHandle(Handle);
254 }
255
256
257 return rc;
258 }
259
260 static int DefaultVlnkDstFullPath(WCHAR *Src, WCHAR *Dir, WCHAR *Dst)
261 {
262 int i, j;
263 int len;
264 int wrlen;
265 WCHAR C;
266
267 len = (int)lstrlen(Src);
268 for (i = len - 1; i >= 0; i--)
269 {
270 if (Src[i] == '.')
271 {
272 C = Src[i];
273 Src[i] = 0;
274 wrlen = swprintf_s(Dst, MAX_PATH, L"%ls\\%ls.vlnk.%ls", Dir, Src, Src + i + 1);
275 Src[i] = C;
276
277 for (j = wrlen - (len - i); j < wrlen; j++)
278 {
279 if (Dst[j] >= 'A' && Dst[j] <= 'Z')
280 {
281 Dst[j] = 'a' + (Dst[j] - 'A');
282 }
283 }
284
285 break;
286 }
287 }
288
289 return 0;
290 }
291
292 static BOOL IsVlnkFile(WCHAR *path, ventoy_vlnk *outvlnk)
293 {
294 BOOL bRet;
295 BOOL bVlnk = FALSE;
296 DWORD dwSize;
297 LARGE_INTEGER FileSize;
298 HANDLE Handle;
299 ventoy_vlnk vlnk;
300
301 Handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
302 if (Handle == INVALID_HANDLE_VALUE)
303 {
304 LogA("Could not open this file, error:%u\n", GetLastError());
305 return FALSE;
306 }
307
308 if (!GetFileSizeEx(Handle, &FileSize))
309 {
310 LogA("Failed to get vlnk file size\n");
311 goto End;
312 }
313
314 if (FileSize.QuadPart != VLNK_FILE_LEN)
315 {
316 LogA("Invalid vlnk file length %llu\n", (unsigned long long)FileSize.QuadPart);
317 goto End;
318 }
319
320 memset(&vlnk, 0, sizeof(vlnk));
321 bRet = ReadFile(Handle, &vlnk, sizeof(vlnk), &dwSize, NULL);
322 if (bRet && CheckVlnkData(&vlnk))
323 {
324 if (outvlnk)
325 {
326 memcpy(outvlnk, &vlnk, sizeof(vlnk));
327 }
328
329 bVlnk = TRUE;
330 }
331
332 End:
333
334 if (Handle != INVALID_HANDLE_VALUE)
335 {
336 CloseHandle(Handle);
337 }
338
339 return bVlnk;
340 }
341
342
343 static int CreateVlnk(HWND hWnd, WCHAR *Dir)
344 {
345 int i;
346 int end;
347 int len;
348 UINT32 DiskSig;
349 DISK_EXTENT DiskExtend;
350 OPENFILENAME ofn = { 0 };
351 CHAR UTF8Path[MAX_PATH];
352 WCHAR DstFullPath[MAX_PATH];
353 WCHAR szFile[MAX_PATH] = { 0 };
354 CHAR suffix[8] = { 0 };
355 CHAR Drive[8] = { 0 };
356 CHAR FsName[64] = { 0 };
357 CHAR *Buf = NULL;
358 WCHAR *Pos = NULL;
359 ventoy_vlnk *vlnk = NULL;
360
361 ofn.lStructSize = sizeof(ofn);
362 ofn.hwndOwner = hWnd;
363 ofn.lpstrFile = szFile;
364 ofn.nMaxFile = sizeof(szFile);
365 ofn.lpstrFilter = L"Vlnk Source File\0*.iso;*.img;*.wim;*.vhd;*.vhdx;*.vtoy;*.efi;*.dat\0";
366 ofn.nFilterIndex = 1;
367 ofn.lpstrFileTitle = NULL;
368 ofn.nMaxFileTitle = 0;
369 ofn.lpstrInitialDir = NULL;
370 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
371
372 if (GetOpenFileName(&ofn) != TRUE)
373 {
374 return 1;
375 }
376
377 LogW(L"Create vlnk for <%ls>\n", szFile);
378
379 len = lstrlen(szFile);
380
381 if (len < 5 || szFile[0] == '.' || szFile[1] != ':')
382 {
383 MessageBox(hWnd, g_msg_lang[MSGID_SRC_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
384 return 1;
385 }
386
387 Drive[0] = (CHAR)szFile[0];
388 Drive[1] = ':';
389 Drive[2] = '\\';
390 if (0 == GetVolumeInformationA(Drive, NULL, 0, NULL, NULL, NULL, FsName, sizeof(FsName) - 1))
391 {
392 LogA("GetVolumeInformationA failed %u\n", GetLastError());
393 return 1;
394 }
395
396 LogA("Partition filesystem of <%s> is <%s>\n", Drive, FsName);
397 if (_stricmp(FsName, "NTFS") == 0 ||
398 _stricmp(FsName, "exFAT") == 0 ||
399 _stricmp(FsName, "FAT") == 0 ||
400 _stricmp(FsName, "FAT32") == 0 ||
401 _stricmp(FsName, "FAT16") == 0 ||
402 _stricmp(FsName, "FAT12") == 0 ||
403 _stricmp(FsName, "UDF") == 0)
404 {
405 LogA("FS Check OK\n");
406 }
407 else
408 {
409 MessageBox(hWnd, g_msg_lang[MSGID_FS_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
410 return 1;
411 }
412
413
414 end = (szFile[len - 5] == '.') ? 5 : 4;
415 for (i = 0; i < end; i++)
416 {
417 suffix[i] = (CHAR)szFile[len - (end - i)];
418 }
419
420 if (!IsSupportedImgSuffix(suffix))
421 {
422 MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
423 return 1;
424 }
425
426 if (IsVlnkFile(szFile, NULL))
427 {
428 MessageBox(hWnd, g_msg_lang[MSGID_ALREADY_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
429 return 1;
430 }
431
432 for (i = 0; i < MAX_PATH && szFile[i]; i++)
433 {
434 if (szFile[i] == '\\' || szFile[i] == '/')
435 {
436 Pos = szFile + i;
437 }
438 }
439
440 if (!Pos)
441 {
442 LogA("name part not found\n");
443 return 1;
444 }
445 LogW(L"File Name is <%ls>\n", Pos + 1);
446
447 memset(UTF8Path, 0, sizeof(UTF8Path));
448 WideCharToMultiByte(CP_UTF8, 0, szFile + 2, -1, UTF8Path, MAX_PATH, NULL, 0);
449
450 for (i = 0; i < MAX_PATH && UTF8Path[i]; i++)
451 {
452 if (UTF8Path[i] == '\\')
453 {
454 UTF8Path[i] = '/';
455 }
456 }
457
458 len = (int)strlen(UTF8Path);
459 if (len >= VLNK_NAME_MAX)
460 {
461 LogA("File name length %d overflow\n", len);
462 MessageBox(hWnd, g_msg_lang[MSGID_FILE_NAME_TOO_LONG], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
463 return 1;
464 }
465
466 DiskExtend.StartingOffset.QuadPart = 0;
467 if (GetPhyDiskInfo((char)szFile[0], &DiskSig, &DiskExtend))
468 {
469 MessageBox(hWnd, g_msg_lang[MSGID_DISK_INFO_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
470 return 1;
471 }
472
473 Buf = malloc(VLNK_FILE_LEN);
474 if (Buf)
475 {
476 memset(Buf, 0, VLNK_FILE_LEN);
477 vlnk = (ventoy_vlnk *)Buf;
478 ventoy_create_vlnk(DiskSig, (uint64_t)DiskExtend.StartingOffset.QuadPart, UTF8Path, vlnk);
479
480 DefaultVlnkDstFullPath(Pos + 1, Dir, DstFullPath);
481 LogW(L"vlnk output file path is <%ls>\n", DstFullPath);
482
483 if (SaveBuffer2File(DstFullPath, Buf, VLNK_FILE_LEN) == 0)
484 {
485 WCHAR Msg[1024];
486
487 swprintf_s(Msg, 1024, L"%ls\r\n\r\n%ls", g_msg_lang[MSGID_VLNK_SUCCESS], DstFullPath + lstrlen(Dir) + 1);
488
489 LogW(L"Vlnk file create success <%ls>\n", DstFullPath);
490 MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);
491 }
492 else
493 {
494 LogA("Vlnk file save failed\n");
495 MessageBox(hWnd, g_msg_lang[MSGID_CREATE_FILE_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
496 }
497
498 free(Buf);
499 }
500
501 return 0;
502 }
503
504 static CHAR GetDriveLetter(UINT32 disksig, UINT64 PartOffset)
505 {
506 CHAR Letter;
507 DWORD Drives;
508 UINT32 Sig;
509 DISK_EXTENT DiskExtent;
510
511 Letter = 'A';
512 Drives = GetLogicalDrives();
513 LogA("Logic Drives: 0x%x", Drives);
514
515 while (Drives)
516 {
517 if (Drives & 0x01)
518 {
519 Sig = 0;
520 DiskExtent.StartingOffset.QuadPart = 0;
521 if (GetPhyDiskInfo(Letter, &Sig, &DiskExtent) == 0)
522 {
523 if (Sig == disksig && DiskExtent.StartingOffset.QuadPart == PartOffset)
524 {
525 return Letter;
526 }
527 }
528 }
529
530 Drives >>= 1;
531 Letter++;
532 }
533
534 return 0;
535 }
536
537
538 static int ParseVlnk(HWND hWnd)
539 {
540 int i;
541 CHAR Letter;
542 ventoy_vlnk vlnk;
543 OPENFILENAME ofn = { 0 };
544 WCHAR szFile[MAX_PATH] = { 0 };
545 WCHAR szDst[MAX_PATH + 2] = { 0 };
546 WCHAR Msg[1024];
547 CHAR *suffix = NULL;
548 HANDLE hFile;
549
550 ofn.lStructSize = sizeof(ofn);
551 ofn.hwndOwner = hWnd;
552 ofn.lpstrFile = szFile;
553 ofn.nMaxFile = sizeof(szFile);
554 ofn.lpstrFilter = L"Vlnk File\0*.vlnk.iso;*.vlnk.img;*.vlnk.wim;*.vlnk.efi;*.vlnk.vhd;*.vlnk.vhdx;*.vlnk.vtoy;*.vlnk.dat\0";
555 ofn.nFilterIndex = 1;
556 ofn.lpstrFileTitle = NULL;
557 ofn.nMaxFileTitle = 0;
558 ofn.lpstrInitialDir = NULL;
559 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
560
561 if (GetOpenFileName(&ofn) != TRUE)
562 {
563 return 1;
564 }
565
566 LogW(L"Parse vlnk for <%ls>\n", szFile);
567
568 if (!IsVlnkFile(szFile, &vlnk))
569 {
570 MessageBox(hWnd, g_msg_lang[MSGID_INVALID_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
571 return 1;
572 }
573
574 for (i = 0; i < sizeof(vlnk.filepath) && vlnk.filepath[i]; i++)
575 {
576 if (vlnk.filepath[i] == '.')
577 {
578 suffix = vlnk.filepath + i;
579 }
580 }
581
582 if (!IsSupportedImgSuffix(suffix))
583 {
584 MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
585 return 1;
586 }
587
588 Utf8ToUtf16(vlnk.filepath, szDst + 2);
589 for (i = 2; i < MAX_PATH && szDst[i]; i++)
590 {
591 if (szDst[i] == '/')
592 {
593 szDst[i] = '\\';
594 }
595 }
596
597
598 Letter = GetDriveLetter(vlnk.disk_signature, vlnk.part_offset);
599 if (Letter == 0)
600 {
601 MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
602 return 1;
603 }
604
605 szDst[0] = toupper(Letter);
606 szDst[1] = ':';
607 LogW(L"vlnk dst is %ls\n", szDst);
608
609 hFile = CreateFileW(szDst, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
610 if (INVALID_HANDLE_VALUE == hFile)
611 {
612 MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
613 return 1;
614 }
615 CloseHandle(hFile);
616
617 swprintf_s(Msg, 1024, L"%ls %ls", g_msg_lang[MSGID_VLNK_POINT_TO], szDst);
618 MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);
619
620 return 0;
621 }
622
623 INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
624 {
625 WORD NotifyCode;
626 WORD CtrlID;
627
628 switch (Message)
629 {
630 case WM_COMMAND:
631 {
632 NotifyCode = HIWORD(wParam);
633 CtrlID = LOWORD(wParam);
634
635 if (NotifyCode == BN_CLICKED)
636 {
637 if (CtrlID == IDC_BUTTON1)
638 {
639 EnableWindow(g_create_button, FALSE);
640 CreateVlnk(hWnd, g_CurDirW);
641 EnableWindow(g_create_button, TRUE);
642 }
643 else if (CtrlID == IDC_BUTTON2)
644 {
645 EnableWindow(g_parse_button, FALSE);
646 ParseVlnk(hWnd);
647 EnableWindow(g_parse_button, TRUE);
648 }
649 }
650 break;
651 }
652 case WM_INITDIALOG:
653 {
654 InitDialog(hWnd, wParam, lParam);
655 break;
656 }
657 case WM_CLOSE:
658 {
659 OnDestroyDialog();
660 EndDialog(hWnd, 0);
661 }
662 }
663
664 return 0;
665 }
666
667 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
668 {
669 int i;
670 HANDLE hMutex;
671
672 UNREFERENCED_PARAMETER(hPrevInstance);
673
674 if (GetUserDefaultUILanguage() == 0x0804)
675 {
676 g_msg_lang = g_msg_cn;
677 }
678 else
679 {
680 g_msg_lang = g_msg_en;
681 }
682
683 hMutex = CreateMutexA(NULL, TRUE, "VtoyVlnkMUTEX");
684 if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
685 {
686 MessageBoxW(NULL, g_msg_lang[MSGID_RUNNING_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
687 return 1;
688 }
689
690 GetCurrentDirectoryA(MAX_PATH, g_CurDirA);
691 GetCurrentDirectoryW(MAX_PATH, g_CurDirW);
692 sprintf_s(g_LogFile, sizeof(g_LogFile), "%s\\VentoyVlnk.log", g_CurDirA);
693
694 for (i = 0; i < __argc; i++)
695 {
696 if (strncmp(__argv[i], "-Q", 2) == 0 ||
697 strncmp(__argv[i], "-q", 2) == 0)
698 {
699 g_LogFile[0] = 0;
700 break;
701 }
702 }
703
704
705 LogA("========= VentoyVlnk =========\n");
706
707 g_hInst = hInstance;
708 DialogBoxA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG1), NULL, DialogProc);
709
710 return 0;
711 }