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
;
16 static BOOL g_ShowHelp
= FALSE
;
17 static BOOL g_SaveAs
= FALSE
;
18 static WCHAR g_CmdInFile
[MAX_PATH
];
19 static WCHAR g_CmdOutFile
[MAX_PATH
];
28 MSGID_SRC_UNSUPPORTED
,
30 MSGID_SUFFIX_UNSUPPORTED
,
34 MSGID_CREATE_FILE_ERR
,
39 MSGID_FILE_NAME_TOO_LONG
,
45 const WCHAR
*g_msg_cn
[MSGID_BUTT
] =
52 L
"²»Ö§³ÖΪ´ËÎļþ´´½¨vlnk",
54 L
"²»Ö§³ÖµÄÎļþºó׺Ãû",
55 L
"»ñÈ¡´ÅÅÌÐÅϢʱ·¢Éú´íÎó",
56 L
"Vlnk Îļþ´´½¨³É¹¦¡£",
57 L
"ÇëÏȹرÕÕýÔÚÔËÐÐµÄ VentoyVlnk ³ÌÐò£¡",
59 L
"´ËÎļþÒѾÊÇÒ»¸övlnkÎļþÁË£¡",
62 L
"´Ë vlnk Ö¸ÏòµÄÎļþ²»´æÔÚ£¡",
65 const WCHAR
*g_msg_en
[MSGID_BUTT
] =
71 L
"The specified file is not exist!",
72 L
"This file is not supported for vlnk",
73 L
"Unsupported file system!",
74 L
"Unsupported file suffix!",
75 L
"Error when getting disk info",
76 L
"Vlnk file successfully created!",
77 L
"Please close another running VentoyVlnk instance!",
78 L
"Failed to create file!",
79 L
"This file is already a vlnk file!",
80 L
"Invalid vlnk file!",
81 L
"The vlnk file point to ",
82 L
"The file pointed by the vlnk does NOT exist!",
83 L
"The file full path is too long!",
86 const WCHAR
**g_msg_lang
= NULL
;
90 static int VtoyMessageBox
93 _In_opt_ LPCWSTR lpText
,
94 _In_opt_ LPCWSTR lpCaption
,
98 if (g_CmdInFile
[0] && g_CmdOutFile
[0])
103 return MessageBox(hWnd
, lpText
, lpCaption
, uType
);
106 static void Log2File(const char *log
)
113 localtime_s(&ttm
, &stamp
);
115 fopen_s(&fp
, g_LogFile
, "a+");
118 fprintf_s(fp
, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
119 ttm
.tm_year
+ 1900, ttm
.tm_mon
+ 1, ttm
.tm_mday
,
120 ttm
.tm_hour
, ttm
.tm_min
, ttm
.tm_sec
, log
);
125 void LogW(const WCHAR
*Fmt
, ...)
131 if (g_LogFile
[0] == 0)
137 vswprintf_s(log
, 512, Fmt
, arg
);
140 WideCharToMultiByte(CP_UTF8
, 0, log
, -1, alog
, 2048, 0, 0);
146 void LogA(const CHAR
*Fmt
, ...)
151 if (g_LogFile
[0] == 0)
157 vsprintf_s(log
, 512, Fmt
, arg
);
163 static int Utf8ToUtf16(const char* src
, WCHAR
* dst
)
165 int size
= MultiByteToWideChar(CP_UTF8
, 0, src
, -1, dst
, 0);
166 return MultiByteToWideChar(CP_UTF8
, 0, src
, -1, dst
, size
+ 1);
169 static BOOL
OnDestroyDialog()
175 static BOOL
InitDialog(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
179 g_create_button
= GetDlgItem(hWnd
, IDC_BUTTON1
);
180 g_parse_button
= GetDlgItem(hWnd
, IDC_BUTTON2
);
182 hIcon
= LoadIcon(g_hInst
, MAKEINTRESOURCE(IDI_ICON1
));
183 SendMessage(hWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
184 SendMessage(hWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
186 SetWindowTextW(g_create_button
, g_msg_lang
[MSGID_BTN_CREATE
]);
187 SetWindowTextW(g_parse_button
, g_msg_lang
[MSGID_BTN_PARSE
]);
192 static int GetPhyDiskInfo(const char LogicalDrive
, UINT32
*DiskSig
, DISK_EXTENT
*DiskExtent
)
197 VOLUME_DISK_EXTENTS DiskExtents
;
199 UINT8 SectorBuf
[512];
201 LogA("GetPhyDiskInfo %C\n", LogicalDrive
);
203 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\%C:", LogicalDrive
);
204 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
205 if (Handle
== INVALID_HANDLE_VALUE
)
207 LogA("Could not open the disk %C: error:%u\n", LogicalDrive
, GetLastError());
211 Ret
= DeviceIoControl(Handle
,
212 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
,
216 (DWORD
)(sizeof(DiskExtents
)),
219 if (!Ret
|| DiskExtents
.NumberOfDiskExtents
== 0)
221 LogA("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u\n", GetLastError());
227 memcpy(DiskExtent
, DiskExtents
.Extents
, sizeof(DISK_EXTENT
));
228 LogA("%C: is in PhysicalDrive%d Offset:%llu\n", LogicalDrive
, DiskExtents
.Extents
[0].DiskNumber
,
229 (ULONGLONG
)(DiskExtents
.Extents
[0].StartingOffset
.QuadPart
));
231 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\PhysicalDrive%d", DiskExtents
.Extents
[0].DiskNumber
);
232 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
233 if (Handle
== INVALID_HANDLE_VALUE
)
235 LogA("Could not open the disk<PhysicalDrive%d>, error:%u\n", DiskExtents
.Extents
[0].DiskNumber
, GetLastError());
239 if (!ReadFile(Handle
, SectorBuf
, sizeof(SectorBuf
), &dwSize
, NULL
))
241 LogA("ReadFile failed, dwSize:%u error:%u\n", dwSize
, GetLastError());
246 memcpy(DiskSig
, SectorBuf
+ 0x1B8, 4);
253 static int SaveBuffer2File(const WCHAR
*Fullpath
, void *Buffer
, DWORD Length
)
259 LogW(L
"SaveBuffer2File <%ls> len:%u\n", Fullpath
, Length
);
261 Handle
= CreateFileW(Fullpath
, GENERIC_READ
| GENERIC_WRITE
,
262 FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, CREATE_ALWAYS
, 0, 0);
263 if (Handle
== INVALID_HANDLE_VALUE
)
265 LogA("Could not create new file, error:%u\n", GetLastError());
269 WriteFile(Handle
, Buffer
, Length
, &dwSize
, NULL
);
275 if (Handle
!= INVALID_HANDLE_VALUE
)
284 static int DefaultVlnkDstFullPath(WCHAR
*Src
, WCHAR
*Dir
, WCHAR
*Dst
)
291 len
= (int)lstrlen(Src
);
292 for (i
= len
- 1; i
>= 0; i
--)
298 wrlen
= swprintf_s(Dst
, MAX_PATH
, L
"%ls\\%ls.vlnk.%ls", Dir
, Src
, Src
+ i
+ 1);
301 for (j
= wrlen
- (len
- i
); j
< wrlen
; j
++)
303 if (Dst
[j
] >= 'A' && Dst
[j
] <= 'Z')
305 Dst
[j
] = 'a' + (Dst
[j
] - 'A');
316 static BOOL
IsVlnkFile(WCHAR
*path
, ventoy_vlnk
*outvlnk
)
321 LARGE_INTEGER FileSize
;
325 Handle
= CreateFileW(path
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
326 if (Handle
== INVALID_HANDLE_VALUE
)
328 LogA("Could not open this file, error:%u\n", GetLastError());
332 if (!GetFileSizeEx(Handle
, &FileSize
))
334 LogA("Failed to get vlnk file size\n");
338 if (FileSize
.QuadPart
!= VLNK_FILE_LEN
)
340 LogA("Invalid vlnk file length %llu\n", (unsigned long long)FileSize
.QuadPart
);
344 memset(&vlnk
, 0, sizeof(vlnk
));
345 bRet
= ReadFile(Handle
, &vlnk
, sizeof(vlnk
), &dwSize
, NULL
);
346 if (bRet
&& CheckVlnkData(&vlnk
))
350 memcpy(outvlnk
, &vlnk
, sizeof(vlnk
));
358 if (Handle
!= INVALID_HANDLE_VALUE
)
367 static BOOL
VentoyGetSaveFileName(HWND hWnd
, WCHAR
*szFile
)
369 OPENFILENAME ofn
= { 0 };
371 ofn
.lStructSize
= sizeof(ofn
);
372 ofn
.hwndOwner
= hWnd
;
373 ofn
.lpstrFilter
= L
"Vlnk File\0*.vlnk.iso;*.vlnk.img;*.vlnk.wim;*.vlnk.efi;*.vlnk.vhd;*.vlnk.vhdx;*.vlnk.vtoy;*.vlnk.dat\0";
374 ofn
.nFilterIndex
= 1;
375 ofn
.lpstrFile
= szFile
;
376 ofn
.nMaxFile
= MAX_PATH
;
377 ofn
.Flags
= OFN_EXPLORER
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
378 ofn
.lpstrFileTitle
= NULL
;
379 ofn
.nMaxFileTitle
= 0;
380 ofn
.lpstrInitialDir
= NULL
;
382 return GetSaveFileName(&ofn
);
385 static int CreateVlnk(HWND hWnd
, WCHAR
*Dir
, WCHAR
*InFile
, WCHAR
*OutFile
)
390 BOOL SetOutFile
= FALSE
;
392 DISK_EXTENT DiskExtend
;
393 OPENFILENAME ofn
= { 0 };
394 CHAR UTF8Path
[MAX_PATH
];
395 WCHAR DstFullPath
[MAX_PATH
];
396 WCHAR szFile
[MAX_PATH
] = { 0 };
397 CHAR suffix
[8] = { 0 };
398 CHAR Drive
[8] = { 0 };
399 CHAR FsName
[64] = { 0 };
402 ventoy_vlnk
*vlnk
= NULL
;
406 wcscpy_s(szFile
, MAX_PATH
, InFile
);
410 ofn
.lStructSize
= sizeof(ofn
);
411 ofn
.hwndOwner
= hWnd
;
412 ofn
.lpstrFile
= szFile
;
413 ofn
.nMaxFile
= sizeof(szFile
);
414 ofn
.lpstrFilter
= L
"Vlnk Source File\0*.iso;*.img;*.wim;*.vhd;*.vhdx;*.vtoy;*.efi;*.dat\0";
415 ofn
.nFilterIndex
= 1;
416 ofn
.lpstrFileTitle
= NULL
;
417 ofn
.nMaxFileTitle
= 0;
418 ofn
.lpstrInitialDir
= NULL
;
419 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
421 if (GetOpenFileName(&ofn
) != TRUE
)
427 LogW(L
"Create vlnk for <%ls>\n", szFile
);
429 len
= lstrlen(szFile
);
431 if (len
< 5 || szFile
[0] == '.' || szFile
[1] != ':')
433 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_SRC_UNSUPPORTED
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
437 Drive
[0] = (CHAR
)szFile
[0];
440 if (0 == GetVolumeInformationA(Drive
, NULL
, 0, NULL
, NULL
, NULL
, FsName
, sizeof(FsName
) - 1))
442 LogA("GetVolumeInformationA failed %u\n", GetLastError());
446 LogA("Partition filesystem of <%s> is <%s>\n", Drive
, FsName
);
447 if (_stricmp(FsName
, "NTFS") == 0 ||
448 _stricmp(FsName
, "exFAT") == 0 ||
449 _stricmp(FsName
, "FAT") == 0 ||
450 _stricmp(FsName
, "FAT32") == 0 ||
451 _stricmp(FsName
, "FAT16") == 0 ||
452 _stricmp(FsName
, "FAT12") == 0 ||
453 _stricmp(FsName
, "UDF") == 0)
455 LogA("FS Check OK\n");
459 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_FS_UNSUPPORTED
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
464 end
= (szFile
[len
- 5] == '.') ? 5 : 4;
465 for (i
= 0; i
< end
; i
++)
467 suffix
[i
] = (CHAR
)szFile
[len
- (end
- i
)];
470 if (!IsSupportedImgSuffix(suffix
))
472 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_SUFFIX_UNSUPPORTED
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
476 if (IsVlnkFile(szFile
, NULL
))
478 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_ALREADY_VLNK
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
482 for (i
= 0; i
< MAX_PATH
&& szFile
[i
]; i
++)
484 if (szFile
[i
] == '\\' || szFile
[i
] == '/')
492 LogA("name part not found\n");
495 LogW(L
"File Name is <%ls>\n", Pos
+ 1);
497 memset(UTF8Path
, 0, sizeof(UTF8Path
));
498 WideCharToMultiByte(CP_UTF8
, 0, szFile
+ 2, -1, UTF8Path
, MAX_PATH
, NULL
, 0);
500 for (i
= 0; i
< MAX_PATH
&& UTF8Path
[i
]; i
++)
502 if (UTF8Path
[i
] == '\\')
508 len
= (int)strlen(UTF8Path
);
509 if (len
>= VLNK_NAME_MAX
)
511 LogA("File name length %d overflow\n", len
);
512 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_FILE_NAME_TOO_LONG
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
516 DiskExtend
.StartingOffset
.QuadPart
= 0;
517 if (GetPhyDiskInfo((char)szFile
[0], &DiskSig
, &DiskExtend
))
519 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_DISK_INFO_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
524 Buf
= malloc(VLNK_FILE_LEN
);
527 memset(Buf
, 0, VLNK_FILE_LEN
);
528 vlnk
= (ventoy_vlnk
*)Buf
;
529 ventoy_create_vlnk(DiskSig
, (uint64_t)DiskExtend
.StartingOffset
.QuadPart
, UTF8Path
, vlnk
);
533 wcscpy_s(DstFullPath
, MAX_PATH
, OutFile
);
538 DefaultVlnkDstFullPath(Pos
+ 1, Dir
, DstFullPath
);
542 wcscpy_s(szFile
, MAX_PATH
, DstFullPath
);
543 if (VentoyGetSaveFileName(hWnd
, szFile
))
545 wcscpy_s(DstFullPath
, MAX_PATH
, szFile
);
550 LogA("User cancel the save as diaglog, use default name\n");
555 LogW(L
"vlnk output file path is <%ls>\n", DstFullPath
);
557 if (SaveBuffer2File(DstFullPath
, Buf
, VLNK_FILE_LEN
) == 0)
561 LogW(L
"Vlnk file create success <%ls>\n", DstFullPath
);
565 swprintf_s(Msg
, 1024, L
"%ls\r\n\r\n%ls", g_msg_lang
[MSGID_VLNK_SUCCESS
], DstFullPath
);
566 VtoyMessageBox(hWnd
, Msg
, g_msg_lang
[MSGID_INFO
], MB_OK
| MB_ICONINFORMATION
);
570 swprintf_s(Msg
, 1024, L
"%ls\r\n\r\n%ls", g_msg_lang
[MSGID_VLNK_SUCCESS
], DstFullPath
+ lstrlen(Dir
) + 1);
571 VtoyMessageBox(hWnd
, Msg
, g_msg_lang
[MSGID_INFO
], MB_OK
| MB_ICONINFORMATION
);
576 LogA("Vlnk file save failed\n");
577 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_CREATE_FILE_ERR
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
586 static CHAR
GetDriveLetter(UINT32 disksig
, UINT64 PartOffset
)
591 DISK_EXTENT DiskExtent
;
594 Drives
= GetLogicalDrives();
595 LogA("Logic Drives: 0x%x", Drives
);
602 DiskExtent
.StartingOffset
.QuadPart
= 0;
603 if (GetPhyDiskInfo(Letter
, &Sig
, &DiskExtent
) == 0)
605 if (Sig
== disksig
&& DiskExtent
.StartingOffset
.QuadPart
== PartOffset
)
619 static int ParseVlnk(HWND hWnd
)
624 OPENFILENAME ofn
= { 0 };
625 WCHAR szFile
[MAX_PATH
] = { 0 };
626 WCHAR szDst
[MAX_PATH
+ 2] = { 0 };
631 ofn
.lStructSize
= sizeof(ofn
);
632 ofn
.hwndOwner
= hWnd
;
633 ofn
.lpstrFile
= szFile
;
634 ofn
.nMaxFile
= sizeof(szFile
);
635 ofn
.lpstrFilter
= L
"Vlnk File\0*.vlnk.iso;*.vlnk.img;*.vlnk.wim;*.vlnk.efi;*.vlnk.vhd;*.vlnk.vhdx;*.vlnk.vtoy;*.vlnk.dat\0";
636 ofn
.nFilterIndex
= 1;
637 ofn
.lpstrFileTitle
= NULL
;
638 ofn
.nMaxFileTitle
= 0;
639 ofn
.lpstrInitialDir
= NULL
;
640 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
642 if (GetOpenFileName(&ofn
) != TRUE
)
647 LogW(L
"Parse vlnk for <%ls>\n", szFile
);
649 if (!IsVlnkFile(szFile
, &vlnk
))
651 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_INVALID_VLNK
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
655 for (i
= 0; i
< sizeof(vlnk
.filepath
) && vlnk
.filepath
[i
]; i
++)
657 if (vlnk
.filepath
[i
] == '.')
659 suffix
= vlnk
.filepath
+ i
;
663 if (!IsSupportedImgSuffix(suffix
))
665 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_SUFFIX_UNSUPPORTED
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
669 Utf8ToUtf16(vlnk
.filepath
, szDst
+ 2);
670 for (i
= 2; i
< MAX_PATH
&& szDst
[i
]; i
++)
679 Letter
= GetDriveLetter(vlnk
.disk_signature
, vlnk
.part_offset
);
682 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_VLNK_NO_DST
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
686 szDst
[0] = toupper(Letter
);
688 LogW(L
"vlnk dst is %ls\n", szDst
);
690 hFile
= CreateFileW(szDst
, FILE_READ_EA
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
691 if (INVALID_HANDLE_VALUE
== hFile
)
693 VtoyMessageBox(hWnd
, g_msg_lang
[MSGID_VLNK_NO_DST
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
698 swprintf_s(Msg
, 1024, L
"%ls %ls", g_msg_lang
[MSGID_VLNK_POINT_TO
], szDst
);
699 VtoyMessageBox(hWnd
, Msg
, g_msg_lang
[MSGID_INFO
], MB_OK
| MB_ICONINFORMATION
);
704 INT_PTR CALLBACK
DialogProc(HWND hWnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
713 NotifyCode
= HIWORD(wParam
);
714 CtrlID
= LOWORD(wParam
);
716 if (NotifyCode
== BN_CLICKED
)
718 if (CtrlID
== IDC_BUTTON1
)
720 EnableWindow(g_create_button
, FALSE
);
721 CreateVlnk(hWnd
, g_CurDirW
, NULL
, NULL
);
722 EnableWindow(g_create_button
, TRUE
);
724 else if (CtrlID
== IDC_BUTTON2
)
726 EnableWindow(g_parse_button
, FALSE
);
728 EnableWindow(g_parse_button
, TRUE
);
735 InitDialog(hWnd
, wParam
, lParam
);
748 static int ParseCmdLine(LPSTR lpCmdLine
)
752 LPWSTR
*lpszArgv
= NULL
;
754 lpszArgv
= CommandLineToArgvW(GetCommandLineW(), &argc
);
756 for (i
= 0; i
< argc
; i
++)
758 if (lstrcmp(lpszArgv
[i
], L
"-q") == 0 || lstrcmp(lpszArgv
[i
], L
"-Q") == 0)
762 else if (lstrcmp(lpszArgv
[i
], L
"-h") == 0 || lstrcmp(lpszArgv
[i
], L
"-H") == 0)
766 else if (lstrcmp(lpszArgv
[i
], L
"-s") == 0 || lstrcmp(lpszArgv
[i
], L
"-S") == 0)
770 else if (lstrcmp(lpszArgv
[i
], L
"-i") == 0 || lstrcmp(lpszArgv
[i
], L
"-I") == 0)
774 wcscpy_s(g_CmdInFile
, MAX_PATH
, lpszArgv
[i
+ 1]);
777 else if (lstrcmp(lpszArgv
[i
], L
"-o") == 0 || lstrcmp(lpszArgv
[i
], L
"-O") == 0)
781 wcscpy_s(g_CmdOutFile
, MAX_PATH
, lpszArgv
[i
+ 1]);
789 int APIENTRY
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, INT nCmdShow
)
794 UNREFERENCED_PARAMETER(hPrevInstance
);
796 if (GetUserDefaultUILanguage() == 0x0804)
798 g_msg_lang
= g_msg_cn
;
802 g_msg_lang
= g_msg_en
;
805 hMutex
= CreateMutexA(NULL
, TRUE
, "VtoyVlnkMUTEX");
806 if ((hMutex
!= NULL
) && (GetLastError() == ERROR_ALREADY_EXISTS
))
808 MessageBoxW(NULL
, g_msg_lang
[MSGID_RUNNING_TIP
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
812 GetCurrentDirectoryA(MAX_PATH
, g_CurDirA
);
813 GetCurrentDirectoryW(MAX_PATH
, g_CurDirW
);
814 sprintf_s(g_LogFile
, sizeof(g_LogFile
), "%s\\VentoyVlnk.log", g_CurDirA
);
816 ParseCmdLine(lpCmdLine
);
822 VtoyMessageBox(NULL
, L
"VentoyVlnk.exe CMD\r\n -i Input file path\r\n -o Output vlnk file path\r\n -q Quite mode (no log)", L
"Tip", MB_OK
);
825 else if (g_CmdInFile
[0] && g_CmdOutFile
[0])
827 LogA("========= VentoyVlnk Cmdline Mode =========\n");
829 dwAttrib
= GetFileAttributesW(g_CmdInFile
);
830 if (dwAttrib
== INVALID_FILE_ATTRIBUTES
|| (dwAttrib
& FILE_ATTRIBUTE_DIRECTORY
))
832 LogW(L
"File <<%ls>> does not exist!\n", g_CmdInFile
);
833 VtoyMessageBox(NULL
, g_msg_lang
[MSGID_SRC_NONEXIST
], g_msg_lang
[MSGID_ERROR
], MB_OK
| MB_ICONERROR
);
837 return CreateVlnk(NULL
, g_CurDirW
, g_CmdInFile
, g_CmdOutFile
);
841 LogA("========= VentoyVlnk GUI Mode =========\n");
843 DialogBoxA(hInstance
, MAKEINTRESOURCEA(IDD_DIALOG1
), NULL
, DialogProc
);