]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - Vlnk/src/main_windows.c
keep up with 1.0.67 (#1464)
[Ventoy.git] / Vlnk / src / main_windows.c
index 6596c29bec158f9692b0e5d008985265048f77b5..089512026cd9d8ac9da8bae36db974fe059369d4 100644 (file)
@@ -13,12 +13,18 @@ static CHAR g_LogFile[MAX_PATH];
 static HWND g_create_button;\r
 static HWND g_parse_button;\r
 \r
+static BOOL g_ShowHelp = FALSE;\r
+static BOOL g_SaveAs = FALSE;\r
+static WCHAR g_CmdInFile[MAX_PATH];\r
+static WCHAR g_CmdOutFile[MAX_PATH];\r
+\r
 typedef enum MSGID\r
 {\r
     MSGID_ERROR = 0,\r
        MSGID_INFO,\r
        MSGID_BTN_CREATE,\r
        MSGID_BTN_PARSE,\r
+    MSGID_SRC_NONEXIST,\r
     MSGID_SRC_UNSUPPORTED,\r
     MSGID_FS_UNSUPPORTED,\r
     MSGID_SUFFIX_UNSUPPORTED,\r
@@ -31,6 +37,7 @@ typedef enum MSGID
     MSGID_VLNK_POINT_TO,\r
     MSGID_VLNK_NO_DST,\r
     MSGID_FILE_NAME_TOO_LONG,\r
+    MSGID_INVALID_SUFFIX,\r
 \r
     MSGID_BUTT\r
 }MSGID;\r
@@ -42,6 +49,7 @@ const WCHAR *g_msg_cn[MSGID_BUTT] =
        L"ÌáÐÑ",\r
        L"´´½¨",\r
        L"½âÎö",        \r
+    L"Ö¸¶¨µÄÎļþ²»´æÔÚ", \r
     L"²»Ö§³ÖΪ´ËÎļþ´´½¨vlnk",\r
     L"²»Ö§³ÖµÄÎļþϵͳ",\r
     L"²»Ö§³ÖµÄÎļþºó׺Ãû",\r
@@ -54,6 +62,7 @@ const WCHAR *g_msg_cn[MSGID_BUTT] =
     L"´Ë vlnk ÎļþÖ¸Ïò ",\r
     L"´Ë vlnk Ö¸ÏòµÄÎļþ²»´æÔÚ£¡",\r
     L"Îļþ·¾¶Ì«³¤£¡",\r
+    L"·Ç·¨µÄvlnkÎļþºó׺Ãû!",\r
 };\r
 const WCHAR *g_msg_en[MSGID_BUTT] =\r
 {\r
@@ -61,6 +70,7 @@ const WCHAR *g_msg_en[MSGID_BUTT] =
        L"Info",   \r
        L"Create",\r
        L"Parse",\r
+    L"The specified file is not exist!",\r
     L"This file is not supported for vlnk",\r
     L"Unsupported file system!", \r
     L"Unsupported file suffix!",\r
@@ -73,11 +83,28 @@ const WCHAR *g_msg_en[MSGID_BUTT] =
     L"The vlnk file point to ",\r
     L"The file pointed by the vlnk does NOT exist!",\r
     L"The file full path is too long!",\r
+    L"Invalid vlnk file suffix!",\r
 };\r
 \r
 const WCHAR **g_msg_lang = NULL;\r
 \r
 HINSTANCE g_hInst;\r
+\r
+static int VtoyMessageBox\r
+(\r
+    _In_opt_ HWND hWnd,\r
+    _In_opt_ LPCWSTR lpText,\r
+    _In_opt_ LPCWSTR lpCaption,\r
+    _In_ UINT uType\r
+)\r
+{\r
+    if (g_CmdInFile[0] && g_CmdOutFile[0])\r
+    {\r
+        return 0;\r
+    }\r
+\r
+    return MessageBox(hWnd, lpText, lpCaption, uType);\r
+}\r
 
 static void Log2File(const char *log)
 {
@@ -340,11 +367,62 @@ End:
 }\r
 \r
 \r
-static int CreateVlnk(HWND hWnd, WCHAR *Dir)\r
+static BOOL VentoyGetSaveFileName(HWND hWnd, WCHAR *szFile)\r
+{\r
+    OPENFILENAME ofn = { 0 };\r
+\r
+    ofn.lStructSize = sizeof(ofn);\r
+    ofn.hwndOwner = hWnd;\r
+    ofn.lpstrFilter = L"Vlnk File\0*.vlnk.iso;*.vlnk.img;*.vlnk.wim;*.vlnk.efi;*.vlnk.vhd;*.vlnk.vhdx;*.vlnk.vtoy;*.vlnk.dat\0";\r
+    ofn.nFilterIndex = 1;\r
+    ofn.lpstrFile = szFile;\r
+    ofn.nMaxFile = MAX_PATH;\r
+    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;\r
+    ofn.lpstrFileTitle = NULL;\r
+    ofn.nMaxFileTitle = 0;\r
+    ofn.lpstrInitialDir = NULL;\r
+\r
+    return GetSaveFileName(&ofn);\r
+}\r
+\r
+static BOOL IsSupportedVlnkSuffix(WCHAR *FileName)\r
+{\r
+    int len;\r
+\r
+    len = lstrlen(FileName);\r
+\r
+    if (len > 9)\r
+    {\r
+        if (lstrcmp(FileName + len - 9, L".vlnk.iso") == 0 ||\r
+            lstrcmp(FileName + len - 9, L".vlnk.img") == 0 ||\r
+            lstrcmp(FileName + len - 9, L".vlnk.wim") == 0 ||\r
+            lstrcmp(FileName + len - 9, L".vlnk.vhd") == 0 ||\r
+            lstrcmp(FileName + len - 9, L".vlnk.efi") == 0 ||\r
+            lstrcmp(FileName + len - 9, L".vlnk.dat") == 0)\r
+        {\r
+            return TRUE;\r
+        }\r
+    }\r
+\r
+\r
+    if (len > 10)\r
+    {\r
+        if (lstrcmp(FileName + len - 10, L".vlnk.vhdx") == 0 ||\r
+            lstrcmp(FileName + len - 10, L".vlnk.vtoy") == 0)\r
+        {\r
+            return TRUE;\r
+        }\r
+    }\r
+\r
+    return FALSE;\r
+}\r
+\r
+static int CreateVlnk(HWND hWnd, WCHAR *Dir, WCHAR *InFile, WCHAR *OutFile)\r
 {\r
     int i;\r
     int end;\r
     int len;\r
+    BOOL SetOutFile = FALSE;\r
     UINT32 DiskSig;\r
     DISK_EXTENT DiskExtend;\r
     OPENFILENAME ofn = { 0 };\r
@@ -358,20 +436,27 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
     WCHAR *Pos = NULL;\r
     ventoy_vlnk *vlnk = NULL;\r
 \r
-    ofn.lStructSize = sizeof(ofn);\r
-    ofn.hwndOwner = hWnd;\r
-    ofn.lpstrFile = szFile;\r
-    ofn.nMaxFile = sizeof(szFile);\r
-    ofn.lpstrFilter = L"Vlnk Source File\0*.iso;*.img;*.wim;*.vhd;*.vhdx;*.vtoy;*.efi;*.dat\0";\r
-    ofn.nFilterIndex = 1;\r
-    ofn.lpstrFileTitle = NULL;\r
-    ofn.nMaxFileTitle = 0;\r
-    ofn.lpstrInitialDir = NULL;\r
-    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;\r
-\r
-    if (GetOpenFileName(&ofn) != TRUE)\r
+    if (InFile)\r
     {\r
-        return 1;\r
+        wcscpy_s(szFile, MAX_PATH, InFile);\r
+    }\r
+    else\r
+    {\r
+        ofn.lStructSize = sizeof(ofn);\r
+        ofn.hwndOwner = hWnd;\r
+        ofn.lpstrFile = szFile;\r
+        ofn.nMaxFile = sizeof(szFile);\r
+        ofn.lpstrFilter = L"Vlnk Source File\0*.iso;*.img;*.wim;*.vhd;*.vhdx;*.vtoy;*.efi;*.dat\0";\r
+        ofn.nFilterIndex = 1;\r
+        ofn.lpstrFileTitle = NULL;\r
+        ofn.nMaxFileTitle = 0;\r
+        ofn.lpstrInitialDir = NULL;\r
+        ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;\r
+\r
+        if (GetOpenFileName(&ofn) != TRUE)\r
+        {\r
+            return 1;\r
+        }\r
     }\r
 \r
     LogW(L"Create vlnk for <%ls>\n", szFile);\r
@@ -380,7 +465,7 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
 \r
     if (len < 5 || szFile[0] == '.' || szFile[1] != ':')\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_SRC_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_SRC_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
     \r
@@ -406,7 +491,7 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
     }\r
     else\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_FS_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_FS_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
@@ -419,13 +504,13 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
 \r
     if (!IsSupportedImgSuffix(suffix))\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
     if (IsVlnkFile(szFile, NULL))\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_ALREADY_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_ALREADY_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
@@ -459,17 +544,18 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
     if (len >= VLNK_NAME_MAX)\r
     {\r
         LogA("File name length %d overflow\n", len);\r
-        MessageBox(hWnd, g_msg_lang[MSGID_FILE_NAME_TOO_LONG], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_FILE_NAME_TOO_LONG], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
     DiskExtend.StartingOffset.QuadPart = 0;\r
     if (GetPhyDiskInfo((char)szFile[0], &DiskSig, &DiskExtend))\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_DISK_INFO_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_DISK_INFO_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
+\r
     Buf = malloc(VLNK_FILE_LEN);\r
     if (Buf)\r
     {\r
@@ -477,24 +563,65 @@ static int CreateVlnk(HWND hWnd, WCHAR *Dir)
         vlnk = (ventoy_vlnk *)Buf;\r
         ventoy_create_vlnk(DiskSig, (uint64_t)DiskExtend.StartingOffset.QuadPart, UTF8Path, vlnk);\r
 \r
-        DefaultVlnkDstFullPath(Pos + 1, Dir, DstFullPath);\r
+        if (OutFile)\r
+        {\r
+            wcscpy_s(DstFullPath, MAX_PATH, OutFile);\r
+            SetOutFile = TRUE;\r
+        }\r
+        else\r
+        {\r
+            DefaultVlnkDstFullPath(Pos + 1, Dir, DstFullPath);\r
+\r
+            if (g_SaveAs)\r
+            {\r
+                wcscpy_s(szFile, MAX_PATH, DstFullPath);\r
+                if (VentoyGetSaveFileName(hWnd, szFile))\r
+                {\r
+                    if (IsSupportedVlnkSuffix(szFile))\r
+                    {\r
+                        wcscpy_s(DstFullPath, MAX_PATH, szFile);\r
+                        SetOutFile = TRUE;\r
+                    }\r
+                    else\r
+                    {\r
+                        VtoyMessageBox(hWnd, g_msg_lang[MSGID_INVALID_SUFFIX], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+                        LogA("Invalid vlnk suffix\n");\r
+                        goto end;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    LogA("User cancel the save as diaglog, use default name\n");\r
+                }\r
+            }\r
+        }\r
+\r
         LogW(L"vlnk output file path is <%ls>\n", DstFullPath);\r
 \r
         if (SaveBuffer2File(DstFullPath, Buf, VLNK_FILE_LEN) == 0)\r
         {\r
             WCHAR Msg[1024];\r
 \r
-            swprintf_s(Msg, 1024, L"%ls\r\n\r\n%ls", g_msg_lang[MSGID_VLNK_SUCCESS], DstFullPath + lstrlen(Dir) + 1);\r
-\r
             LogW(L"Vlnk file create success <%ls>\n", DstFullPath);\r
-            MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);\r
+\r
+            if (SetOutFile)\r
+            {\r
+                swprintf_s(Msg, 1024, L"%ls\r\n\r\n%ls", g_msg_lang[MSGID_VLNK_SUCCESS], DstFullPath);\r
+                VtoyMessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);\r
+            }\r
+            else\r
+            {\r
+                swprintf_s(Msg, 1024, L"%ls\r\n\r\n%ls", g_msg_lang[MSGID_VLNK_SUCCESS], DstFullPath + lstrlen(Dir) + 1);\r
+                VtoyMessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);\r
+            }\r
         }\r
         else\r
         {\r
             LogA("Vlnk file save failed\n");\r
-            MessageBox(hWnd, g_msg_lang[MSGID_CREATE_FILE_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+            VtoyMessageBox(hWnd, g_msg_lang[MSGID_CREATE_FILE_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         }\r
 \r
+        end:\r
         free(Buf);\r
     }\r
 \r
@@ -534,7 +661,6 @@ static CHAR GetDriveLetter(UINT32 disksig, UINT64 PartOffset)
     return 0;\r
 }\r
 \r
-\r
 static int ParseVlnk(HWND hWnd)\r
 {\r
     int i;\r
@@ -567,7 +693,7 @@ static int ParseVlnk(HWND hWnd)
 \r
     if (!IsVlnkFile(szFile, &vlnk))\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_INVALID_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_INVALID_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
@@ -581,7 +707,7 @@ static int ParseVlnk(HWND hWnd)
 \r
     if (!IsSupportedImgSuffix(suffix))\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
@@ -598,7 +724,7 @@ static int ParseVlnk(HWND hWnd)
     Letter = GetDriveLetter(vlnk.disk_signature, vlnk.part_offset);\r
     if (Letter == 0)\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
 \r
@@ -609,13 +735,13 @@ static int ParseVlnk(HWND hWnd)
     hFile = CreateFileW(szDst, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);\r
     if (INVALID_HANDLE_VALUE == hFile)\r
     {\r
-        MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        VtoyMessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
         return 1;\r
     }\r
     CloseHandle(hFile);\r
 \r
     swprintf_s(Msg, 1024, L"%ls %ls", g_msg_lang[MSGID_VLNK_POINT_TO], szDst);\r
-    MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);\r
+    VtoyMessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);\r
 \r
     return 0;\r
 }\r
@@ -637,7 +763,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lPara
                                if (CtrlID == IDC_BUTTON1)\r
                                {\r
                     EnableWindow(g_create_button, FALSE);\r
-                    CreateVlnk(hWnd, g_CurDirW);\r
+                    CreateVlnk(hWnd, g_CurDirW, NULL, NULL);\r
                     EnableWindow(g_create_button, TRUE);\r
                                }\r
                                else if (CtrlID == IDC_BUTTON2)\r
@@ -664,9 +790,50 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lPara
     return 0;\r
 }\r
 \r
-int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)\r
+static int ParseCmdLine(LPSTR lpCmdLine)\r
 {\r
     int i;\r
+    int argc = 0;\r
+    LPWSTR *lpszArgv = NULL;\r
+    \r
+    lpszArgv = CommandLineToArgvW(GetCommandLineW(), &argc);\r
+\r
+    for (i = 0; i < argc; i++)\r
+    {\r
+        if (lstrcmp(lpszArgv[i], L"-q") == 0 || lstrcmp(lpszArgv[i], L"-Q") == 0)\r
+        {\r
+            g_LogFile[0] = 0;\r
+        }\r
+        else if (lstrcmp(lpszArgv[i], L"-h") == 0 || lstrcmp(lpszArgv[i], L"-H") == 0)\r
+        {\r
+            g_ShowHelp = TRUE;\r
+        }\r
+        else if (lstrcmp(lpszArgv[i], L"-s") == 0 || lstrcmp(lpszArgv[i], L"-S") == 0)\r
+        {\r
+            g_SaveAs = TRUE;\r
+        }\r
+        else if (lstrcmp(lpszArgv[i], L"-i") == 0 || lstrcmp(lpszArgv[i], L"-I") == 0)\r
+        {\r
+            if (i + 1 < argc)\r
+            {\r
+                wcscpy_s(g_CmdInFile, MAX_PATH, lpszArgv[i + 1]);\r
+            }\r
+        }\r
+        else if (lstrcmp(lpszArgv[i], L"-o") == 0 || lstrcmp(lpszArgv[i], L"-O") == 0)\r
+        {\r
+            if (i + 1 < argc)\r
+            {\r
+                wcscpy_s(g_CmdOutFile, MAX_PATH, lpszArgv[i + 1]);\r
+            }\r
+        }\r
+    }\r
+\r
+    return argc;\r
+}\r
+\r
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)\r
+{\r
+    DWORD dwAttrib;\r
        HANDLE hMutex;\r
 \r
     UNREFERENCED_PARAMETER(hPrevInstance);\r
@@ -680,32 +847,52 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
         g_msg_lang = g_msg_en;\r
     }\r
 \r
-       hMutex = CreateMutexA(NULL, TRUE, "VtoyVlnkMUTEX");\r
-       if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))\r
-       {\r
-               MessageBoxW(NULL, g_msg_lang[MSGID_RUNNING_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
-               return 1;\r
-       }\r
+    hMutex = CreateMutexA(NULL, TRUE, "VtoyVlnkMUTEX");\r
+    if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))\r
+    {\r
+        MessageBoxW(NULL, g_msg_lang[MSGID_RUNNING_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+        return 1;\r
+    }\r
 \r
     GetCurrentDirectoryA(MAX_PATH, g_CurDirA);\r
     GetCurrentDirectoryW(MAX_PATH, g_CurDirW);\r
     sprintf_s(g_LogFile, sizeof(g_LogFile), "%s\\VentoyVlnk.log", g_CurDirA);\r
 \r
-    for (i = 0; i < __argc; i++)\r
+    ParseCmdLine(lpCmdLine);\r
+    \r
+    g_hInst = hInstance;\r
+\r
+    if (g_ShowHelp)\r
     {\r
-        if (strncmp(__argv[i], "-Q", 2) == 0 ||\r
-            strncmp(__argv[i], "-q", 2) == 0)\r
+        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);\r
+        return 0;\r
+    }\r
+    else if (g_CmdInFile[0] && g_CmdOutFile[0])\r
+    {\r
+        LogA("========= VentoyVlnk Cmdline Mode =========\n");\r
+\r
+        dwAttrib = GetFileAttributesW(g_CmdInFile);\r
+        if (dwAttrib == INVALID_FILE_ATTRIBUTES || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY))\r
         {\r
-            g_LogFile[0] = 0;\r
-            break;\r
+            LogW(L"File <<%ls>> does not exist!\n", g_CmdInFile);\r
+            VtoyMessageBox(NULL, g_msg_lang[MSGID_SRC_NONEXIST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+            return 1;\r
         }\r
-    }\r
-    \r
 \r
-    LogA("========= VentoyVlnk =========\n");\r
+        if (!IsSupportedVlnkSuffix(g_CmdOutFile))\r
+        {\r
+            LogW(L"File <<%ls>> contains invalid vlnk suffix!\n", g_CmdOutFile);\r
+            VtoyMessageBox(NULL, g_msg_lang[MSGID_INVALID_SUFFIX], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);\r
+            return 1;\r
+        }\r
 \r
-    g_hInst = hInstance;\r
-    DialogBoxA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG1), NULL, DialogProc);\r
+        return CreateVlnk(NULL, g_CurDirW, g_CmdInFile, g_CmdOutFile);\r
+    }\r
+    else\r
+    {\r
+        LogA("========= VentoyVlnk GUI Mode =========\n");\r
 \r
-    return 0;\r
+        DialogBoxA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG1), NULL, DialogProc);\r
+        return 0;\r
+    }\r
 }\r