Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpnweb/vpnwebdlg.c')
-rw-r--r--src/vpnweb/vpnwebdlg.c1581
1 files changed, 1581 insertions, 0 deletions
diff --git a/src/vpnweb/vpnwebdlg.c b/src/vpnweb/vpnwebdlg.c
new file mode 100644
index 00000000..5bb2b7fc
--- /dev/null
+++ b/src/vpnweb/vpnwebdlg.c
@@ -0,0 +1,1581 @@
+// SoftEther VPN Source Code
+// Cedar Communication Module
+//
+// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
+//
+// Copyright (c) 2012-2014 Daiyuu Nobori.
+// Copyright (c) 2012-2014 SoftEther VPN Project, University of Tsukuba, Japan.
+// Copyright (c) 2012-2014 SoftEther Corporation.
+//
+// All Rights Reserved.
+//
+// http://www.softether.org/
+//
+// Author: Daiyuu Nobori
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+// vpnwebdlg.c
+// VPN Client Web Installer
+
+#include <GlobalConst.h>
+
+#define VPNWEBDLG_C
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <winsock2.h>
+#include <windows.h>
+#include <Wintrust.h>
+#include <Softpub.h>
+#include <wincrypt.h>
+#include <wininet.h>
+#include <shlobj.h>
+#include <commctrl.h>
+#include <Dbghelp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <process.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <locale.h>
+#include <Msi.h>
+#include <Msiquery.h>
+#include "vpnwebdlg.h"
+#include "vpnwebdlg_inner.h"
+#include "resource.h"
+
+#pragma comment(lib, "wininet.lib")
+
+static VPNWEBDLG_INIT data;
+static bool inited = false;
+static VW_TASK task;
+static bool clicked_flag = false;
+
+// Check the signature of the EXE file, and displays a warning if dangerous
+bool VwCheckExeSign(HWND hWnd, char *exe)
+{
+ wchar_t tmp[2048];
+ bool danger = true;
+ wchar_t *warningMessage = msgWarning;
+ wchar_t *warningMessageTitle = msgWarningTitle;
+ // Validate arguments
+ if (hWnd == NULL || exe == NULL)
+ {
+ return false;
+ }
+
+ if (VwCheckFileDigitalSignature(hWnd, exe, &danger))
+ {
+ if (danger == false)
+ {
+ // Safe
+ return true;
+ }
+ else
+ {
+ // Show the message because there is potentially dangerous
+ swprintf(tmp, sizeof(tmp) / 2, warningMessage,
+ VwUrlToFileName(exe), VwUrlToFileName(exe), VwUrlToFileName(exe));
+
+ if (MessageBoxW(hWnd, tmp, warningMessageTitle,
+ MB_OKCANCEL | MB_DEFBUTTON2 | MB_ICONEXCLAMATION) == IDOK)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ // Danger
+ return false;
+ }
+}
+
+// Check the digital signature of the file
+bool VwCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger)
+{
+ HRESULT ret = S_OK;
+ wchar_t tmp[MAX_PATH];
+ LONG (WINAPI *_WinVerifyTrust)(HWND, GUID *, LPVOID) = NULL;
+ HINSTANCE hDll;
+ // Validate arguments
+ if (name == NULL)
+ {
+ return false;
+ }
+
+ if (danger != NULL)
+ {
+ *danger = false;
+ }
+
+ swprintf(tmp, sizeof(tmp), L"%S", name);
+
+ hDll = LoadLibrary("Wintrust.dll");
+ if (hDll == NULL)
+ {
+ return false;
+ }
+
+ _WinVerifyTrust =
+ (LONG (__stdcall *)(HWND,GUID *,LPVOID))
+ GetProcAddress(hDll, "WinVerifyTrust");
+ if (_WinVerifyTrust == NULL)
+ {
+ FreeLibrary(hDll);
+ return false;
+ }
+ else
+ {
+ GUID action_id = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ WINTRUST_FILE_INFO file;
+ WINTRUST_DATA data;
+
+ Zero(&file, sizeof(file));
+ file.cbStruct = sizeof(file);
+ file.pcwszFilePath = tmp;
+
+ Zero(&data, sizeof(data));
+ data.cbStruct = sizeof(data);
+ data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
+ data.dwUIChoice = (hWnd != NULL ? WTD_UI_NOGOOD : WTD_UI_NONE);
+ data.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN;
+ data.dwUnionChoice = WTD_CHOICE_FILE;
+ data.pFile = &file;
+
+ ret = _WinVerifyTrust(hWnd, &action_id, &data);
+
+ if (ret == ERROR_SUCCESS && danger != NULL)
+ {
+ if (hWnd != NULL)
+ {
+ if (VwCheckFileDigitalSignature(NULL, name, NULL) == false)
+ {
+ // It's a dangerous file, but the user selected the [OK]
+ *danger = true;
+ }
+ }
+ }
+ }
+
+ FreeLibrary(hDll);
+
+ if (ret != ERROR_SUCCESS)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// Task execution thread
+DWORD CALLBACK VwTaskThread(void *param)
+{
+ HWND hWnd = data.hWnd;
+ VW_FILE *f;
+
+ // Download the Inf file
+ f = VwOpenFile(data.InstallerInfUrl);
+
+ if (f == NULL)
+ {
+ wchar_t tmp[MAX_SIZE];
+ swprintf(tmp, sizeof(tmp) / 2, msgInfDownloadFailed, VwUrlToFileName(data.InstallerInfUrl));
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+ else
+ {
+ UINT size = 0;
+ UINT bufsize = 0;
+ UINT readsize = 1024;
+ UINT build = 0;
+ char *buf;
+
+ // Read all the contents of the file
+ buf = ZeroMalloc(size);
+
+ while (true)
+ {
+ UINT ret;
+
+ bufsize = size + readsize;
+ buf = ReAlloc(buf, bufsize);
+ ret = VwReadFile(f, buf + size, readsize);
+
+ if (ret == INFINITE || size >= 65536 || task.Halt)
+ {
+ wchar_t tmp[MAX_SIZE];
+ // Download Failed
+ Free(buf);
+ VwCloseFile(f);
+ swprintf(tmp, sizeof(tmp) / 2, msgInfDownloadFailed, VwUrlToFileName(data.InstallerInfUrl));
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+ else if (ret == 0)
+ {
+ // Download Complete
+ break;
+ }
+ else
+ {
+ size += ret;
+ }
+ }
+
+ VwCloseFile(f);
+
+ bufsize = size + 1;
+ buf = ReAlloc(buf, bufsize);
+ buf[size] = 0;
+
+ build = VwGetBuildFromVpnInstallInf(buf);
+ if (build == 0)
+ {
+ wchar_t tmp[MAX_SIZE];
+ // Build number incorrect
+ Free(buf);
+ swprintf(tmp, sizeof(tmp) / 2, msgBadInfFile, VwUrlToFileName(data.InstallerInfUrl));
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+ else
+ {
+ char tmpdir[MAX_SIZE];
+ char wintmp[MAX_SIZE];
+ char temp_vpninstaller_exe[MAX_SIZE];
+ char temp_vpninstaller_exe_tmp[MAX_SIZE];
+ char temp_vpninstaller_inf[MAX_SIZE];
+ HANDLE h;
+
+ GetTempPath(sizeof(wintmp), wintmp);
+
+ if (lstrlen(wintmp) >= 1)
+ {
+ if (wintmp[lstrlen(wintmp) - 1] == '\\')
+ {
+ wintmp[lstrlen(wintmp) - 1] = 0;
+ }
+ }
+
+ // Generate a temporary directory name
+ _snprintf(tmpdir, sizeof(tmpdir), "%s\\vpninstall_%u", wintmp, build);
+
+ // Generate a temporary file name
+ _snprintf(temp_vpninstaller_exe, sizeof(temp_vpninstaller_exe),
+ "%s\\%s", tmpdir, VPNINSTALL_EXE_FILENAME);
+ _snprintf(temp_vpninstaller_exe_tmp, sizeof(temp_vpninstaller_exe_tmp),
+ "%s\\%s", tmpdir, VPNINSTALL_EXE_FILENAME_TMP);
+ _snprintf(temp_vpninstaller_inf, sizeof(temp_vpninstaller_inf),
+ "%s\\%s", tmpdir, VPNINSTALL_INF_FILENAME);
+
+ // Create a directory
+ MakeDir(tmpdir);
+
+ // Save the inf file
+ h = FileCreate(temp_vpninstaller_inf);
+ if (h == NULL)
+ {
+ wchar_t tmp[MAX_SIZE];
+ // File creation failure
+ Free(buf);
+ swprintf(tmp, sizeof(tmp) / 2, msgWriteFailed, VPNINSTALL_INF_FILENAME);
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+
+ FileWrite(h, buf, lstrlen(buf));
+ FileClose(h);
+
+ Free(buf);
+
+ // Download the vpninstall.exe
+ h = FileOpen(temp_vpninstaller_exe, false);
+ if (h == NULL)
+ {
+ UCHAR *buffer;
+ UINT buffer_size = 65536;
+ UINT total_size, current_size;
+
+ // Perform the download so download unfinished
+ VwPrint(hWnd, msgDownloading);
+ Show(hWnd, P_PROGRESS);
+ SetPos(hWnd, P_PROGRESS, 0);
+
+ f = VwOpenFile(data.InstallerExeUrl);
+ if (f == NULL)
+ {
+ // Download Failed
+ wchar_t tmp[MAX_SIZE];
+
+ swprintf(tmp, sizeof(tmp) / 2, msgInfDownloadFailed, VwUrlToFileName(data.InstallerExeUrl));
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+
+ total_size = VwGetFileSize(f);
+ if (total_size == 0)
+ {
+ total_size = 2 * 1024 * 1024;
+ }
+ current_size = 0;
+
+ h = FileCreate(temp_vpninstaller_exe_tmp);
+ if (h == NULL)
+ {
+ wchar_t tmp[MAX_SIZE];
+ // File creation failure
+ swprintf(tmp, sizeof(tmp) / 2, msgWriteFailed, VPNINSTALL_EXE_FILENAME);
+ VwPrint(hWnd, tmp);
+ VwCloseFile(f);
+ return 0;
+ }
+
+ buffer = ZeroMalloc(buffer_size);
+
+ while (true)
+ {
+ UINT ret;
+
+ ret = VwReadFile(f, buffer, buffer_size);
+
+ if (ret == INFINITE || task.Halt || current_size >= (8 * 1024 * 1024))
+ {
+ // Download Failed
+ wchar_t tmp[MAX_SIZE];
+
+DOWNLOAD_FAILED:
+ swprintf(tmp, sizeof(tmp) / 2, msgInfDownloadFailed, VwUrlToFileName(data.InstallerExeUrl));
+ VwPrint(hWnd, tmp);
+ Free(buffer);
+ FileClose(h);
+ VwCloseFile(f);
+ return 0;
+ }
+ else if (ret == 0)
+ {
+ // Download Complete
+ break;
+ }
+ else
+ {
+ UINT pos = 0;
+ current_size += ret;
+
+ pos = (UINT)((float)current_size * 100.0f / (float)total_size);
+ SetPos(hWnd, P_PROGRESS, pos);
+
+ if (FileWrite(h, buffer, ret) == false)
+ {
+ goto DOWNLOAD_FAILED;
+ }
+ }
+ }
+
+ Free(buffer);
+ FileClose(h);
+ VwCloseFile(f);
+
+ Hide(hWnd, P_PROGRESS);
+
+ // Rename the file
+ if (MoveFile(temp_vpninstaller_exe_tmp, temp_vpninstaller_exe) == false)
+ {
+ // Download Failed
+ wchar_t tmp[MAX_SIZE];
+ swprintf(tmp, sizeof(tmp) / 2, msgInfDownloadFailed, VwUrlToFileName(data.InstallerExeUrl));
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+ }
+ else
+ {
+ // Download has already been completed
+ FileClose(h);
+ }
+
+ VwPrint(hWnd, msgProcessCreating);
+
+ if (VwCheckExeSign(hWnd, temp_vpninstaller_exe))
+ {
+ // Starting the vpninstall.exe
+ STARTUPINFO info;
+ PROCESS_INFORMATION ret;
+ char cmdline[MAX_SIZE];
+
+ Zero(&info, sizeof(info));
+ Zero(&ret, sizeof(ret));
+ info.cb = sizeof(info);
+ info.dwFlags = STARTF_USESHOWWINDOW;
+ info.wShowWindow = SW_SHOWDEFAULT;
+
+ if (data.VpnServerManagerMode == FALSE)
+ {
+ if (lstrlen(data.SettingUrl) == 0)
+ {
+ _snprintf(cmdline, sizeof(cmdline) - 1,
+ "\"%s\" /web", temp_vpninstaller_exe);
+ }
+ else
+ {
+ _snprintf(cmdline, sizeof(cmdline) - 1,
+ "\"%s\" /web \"%s\"", temp_vpninstaller_exe, data.SettingUrl);
+ }
+ }
+ else
+ {
+ char args[MAX_SIZE];
+
+ _snprintf(args, sizeof(args) - 1,
+ "\"\"%s\"\" /HUB:\"\"%s\"\" /PASSWORD:\"\"%s\"\" /HWND:%I64u",
+ data.VpnServerHostname,
+ data.VpnServerHubName,
+ data.VpnServerPassword,
+ (UINT64)/*data.hControlWnd*/0ULL);
+
+ _snprintf(cmdline, sizeof(cmdline) - 1,
+ "\"%s\" /web \"%s\"", temp_vpninstaller_exe, args);
+ }
+
+ if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE,
+ NORMAL_PRIORITY_CLASS, NULL, NULL, &info, &ret) == false)
+ {
+ // Process startup failure
+ wchar_t tmp[MAX_SIZE];
+ swprintf(tmp, sizeof(tmp) / 2, msgProcessFailed, VPNINSTALL_EXE_FILENAME);
+ VwPrint(hWnd, tmp);
+ return 0;
+ }
+
+ if (data.VpnServerManagerMode == FALSE)
+ {
+ VwPrint(hWnd, msgProcessCreated);
+ }
+ else
+ {
+ VwPrint(hWnd, msgProcessCreatedForVpnServer);
+ }
+ }
+ else
+ {
+ VwPrint(hWnd, msgUserCancal);
+ }
+ }
+ }
+
+ return 0;
+}
+
+// Get the build number from file vpninstall.inf
+UINT VwGetBuildFromVpnInstallInf(char *buf)
+{
+ UINT i, len;
+ char tmp[MAX_SIZE];
+ UINT wp;
+ char seps[] = " \t";
+
+ len = lstrlen(buf);
+
+ wp = 0;
+ for (i = 0;i < len;i++)
+ {
+ char c = buf[i];
+
+ if (c == 13 || c == 10)
+ {
+ tmp[wp] = 0;
+ wp = 0;
+
+ if (lstrlen(tmp) >= 1)
+ {
+ char *token = strtok(tmp, seps);
+ if (token != NULL && lstrcmpi(token, VPNINSTALL_INF_BUILDTAG) == 0)
+ {
+ token = strtok(NULL, seps);
+ if (token != NULL)
+ {
+ return (UINT)strtod(token, NULL);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((wp + 2) < sizeof(tmp))
+ {
+ tmp[wp++] = c;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// Convert the URL to the file name
+char *VwUrlToFileName(char *url)
+{
+ UINT i, len;
+ char *ret = url;
+ bool b = true;
+ len = lstrlen(url);
+
+ for (i = 0;i < len;i++)
+ {
+ char c = url[i];
+
+ if (c == '?' || c == '#')
+ {
+ b = false;
+ }
+
+ if (b)
+ {
+ if (c == '/' || c == '\\')
+ {
+ if (lstrlen(url + i + 1) > 1)
+ {
+ ret = url + i + 1;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+// Initialization
+void VwOnInit(HWND hWnd)
+{
+ inited = false;
+ if (IsSupportedOs() == false)
+ {
+ // The OS is unsupported
+ Hide(hWnd, P_PROGRESS);
+ SetDlgItemTextA(hWnd, S_INFO, msgNotSupported);
+ return;
+ }
+
+ if(data.VpnServerManagerMode == FALSE)
+ {
+ SetText(hWnd, S_INFO2, msgStartTextForVpnClient);
+ SetText(hWnd, B_START, msgButtonForVpnClient);
+ }
+ else
+ {
+ SetText(hWnd, S_INFO2, msgStartTextForVpnServer);
+ SetText(hWnd, B_START, msgButtonForVpnServer);
+ }
+
+ if (lstrlen(data.InstallerExeUrl) == 0 || lstrlen(data.InstallerInfUrl) == 0)
+ {
+ // Parameter is not specified
+ Hide(hWnd, P_PROGRESS);
+ SetDlgItemTextA(hWnd, S_INFO, msgNoParam);
+ return;
+ }
+
+ if (data.VpnServerManagerMode == FALSE)
+ {
+ Show(hWnd, S_ICON_VPN);
+ Hide(hWnd, S_ICON_SERVER);
+ }
+ else
+ {
+ Show(hWnd, S_ICON_SERVER);
+ Hide(hWnd, S_ICON_VPN);
+
+
+ }
+
+ Hide(hWnd, P_PROGRESS);
+ Hide(hWnd, S_INFO);
+ Show(hWnd, S_INFO2);
+ Show(hWnd, B_START);
+ clicked_flag = false;
+
+ Zero(&task, sizeof(task));
+}
+
+// Release
+void VwOnFree(HWND hWnd)
+{
+ if (inited == false)
+ {
+ return;
+ }
+
+ task.Halt = true;
+
+ if (task.Thread != NULL)
+ {
+ while (true)
+ {
+ if (WaitForSingleObject(task.Thread, 30) != WAIT_TIMEOUT)
+ {
+ break;
+ }
+ DoEvents(hWnd);
+ }
+ CloseHandle(task.Thread);
+ task.Thread = NULL;
+ }
+}
+
+// Show the string
+void VwPrint(HWND hWnd, wchar_t *str)
+{
+ // Validate arguments
+ if (hWnd == NULL || str == NULL)
+ {
+ return;
+ }
+
+ SetText(hWnd, S_INFO, str);
+}
+
+// Dialog procedure
+INT_PTR CALLBACK VpnWebDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ VwOnInit(hWnd);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case B_START:
+ if (clicked_flag == false)
+ {
+ clicked_flag = true;
+ SetTimer(hWnd, 1, 1, NULL);
+ }
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ VwOnFree(hWnd);
+ break;
+
+ case WM_CLOSE:
+ return 1;
+
+ case WM_TIMER:
+ switch (wParam)
+ {
+ case 1:
+ KillTimer(hWnd, 1);
+ inited = true;
+ Hide(hWnd, B_START);
+ Hide(hWnd, S_INFO2);
+ Show(hWnd, S_INFO);
+ VwPrint(hWnd, msgInfDownloag);
+ task.Thread = VwNewThread(VwTaskThread, NULL);
+ break;
+
+ case 2:
+ KillTimer(hWnd, 2);
+ SendMessage(hWnd, WM_COMMAND, B_START, 0);
+ break;
+ }
+ break;
+
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORMSGBOX:
+ case WM_CTLCOLORSCROLLBAR:
+ case WM_CTLCOLORSTATIC:
+ return (UINT)GetStockObject(WHITE_BRUSH);
+ }
+
+ return 0;
+}
+
+// Set the string to window
+void SetText(HWND hWnd, UINT id, wchar_t *str)
+{
+ wchar_t tmp[512];
+ // Validate arguments
+ if (hWnd == NULL || str == NULL)
+ {
+ return;
+ }
+
+ Zero(tmp, sizeof(tmp));
+ GetWindowTextW(DlgItem(hWnd, id), tmp, sizeof(tmp) - 1);
+
+ if (lstrcmpW(tmp, str) == 0)
+ {
+ return;
+ }
+
+ SetWindowTextW(DlgItem(hWnd, id), str);
+}
+
+// Check whether the OS is supported
+bool IsSupportedOs()
+{
+ OSVERSIONINFO ver;
+
+ Zero(&ver, sizeof(ver));
+
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ if (GetVersionExA(&ver) == false)
+ {
+ return false;
+ }
+
+ if (ver.dwMajorVersion <= 4)
+ {
+ return false;
+ }
+
+ if (ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS || ver.dwPlatformId == VER_PLATFORM_WIN32s)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// Show a message box
+UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg)
+{
+ // Validate arguments
+ if (msg == NULL)
+ {
+ msg = L"MessageBox";
+ }
+
+ return MessageBoxW(hWnd, msg, msgAppTitle, flag);
+}
+
+// Create a directory
+bool MakeDir(char *name)
+{
+ // Validate arguments
+ if (name == NULL)
+ {
+ return false;
+ }
+
+ return CreateDirectory(name, NULL);
+}
+
+// Create a file
+HANDLE FileCreate(char *name)
+{
+ HANDLE h;
+ // Validate arguments
+ if (name == NULL)
+ {
+ return NULL;
+ }
+
+ h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == NULL || h == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ return h;
+}
+
+// Open the file
+HANDLE FileOpen(char *name, bool write_mode)
+{
+ HANDLE h;
+ DWORD lock_mode;
+ // Validate arguments
+ if (name == NULL)
+ {
+ return NULL;
+ }
+
+ if (write_mode)
+ {
+ lock_mode = FILE_SHARE_READ;
+ }
+ else
+ {
+ lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ }
+
+ h = CreateFile(name,
+ (write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),
+ lock_mode,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ return h;
+}
+
+// Close the file
+void FileClose(HANDLE h)
+{
+ // Validate arguments
+ if (h == NULL)
+ {
+ return;
+ }
+
+ FlushFileBuffers(h);
+
+ CloseHandle(h);
+}
+
+// Read from the file
+bool FileRead(HANDLE h, void *buf, UINT size)
+{
+ UINT read_size;
+ // Validate arguments
+ if (h == NULL || buf == NULL || size == 0)
+ {
+ return false;
+ }
+
+ if (ReadFile(h, buf, size, &read_size, NULL) == false)
+ {
+ return false;
+ }
+
+ if (read_size != size)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// Write to the file
+bool FileWrite(HANDLE h, void *buf, UINT size)
+{
+ DWORD write_size;
+ // Validate arguments
+ if (h == NULL || buf == NULL || size == 0)
+ {
+ return false;
+ }
+
+ if (WriteFile(h, buf, size, &write_size, NULL) == false)
+ {
+ return false;
+ }
+
+ if (write_size != size)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// Get the file size
+UINT64 FileSize(HANDLE h)
+{
+ UINT64 ret;
+ DWORD tmp;
+ // Validate arguments
+ if (h == NULL)
+ {
+ return 0;
+ }
+
+ tmp = 0;
+ ret = GetFileSize(h, &tmp);
+ if (ret == (DWORD)-1)
+ {
+ return 0;
+ }
+
+ if (tmp != 0)
+ {
+ ret += (UINT64)tmp * 4294967296ULL;
+ }
+
+ return ret;
+}
+
+// Open the Internet file
+VW_FILE *VwOpenFile(char *path)
+{
+ VW_FILE *f;
+ HINTERNET hHttpFile;
+ HINTERNET hInternet = InternetOpenA(
+ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)",
+ INTERNET_OPEN_TYPE_PRECONFIG,
+ NULL, NULL, 0);
+ UINT size;
+ UINT sizesize;
+ char tmp[8];
+ // Validate arguments
+ if (path == NULL)
+ {
+ return NULL;
+ }
+
+ if (hInternet == NULL)
+ {
+ return NULL;
+ }
+
+ hHttpFile = InternetOpenUrlA(hInternet, path, NULL, 0,
+ INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, 0);
+
+ if (hHttpFile == NULL)
+ {
+ InternetCloseHandle(hInternet);
+ return NULL;
+ }
+
+ size = 0;
+ sizesize = sizeof(size);
+
+ ZeroMemory(tmp, sizeof(tmp));
+
+ if (strlen(path) >= 6)
+ {
+ CopyMemory(tmp, path, 6);
+ }
+
+ if (lstrcmpi(tmp, "ftp://") == 0)
+ {
+ // ftp
+ DWORD high = 0;
+
+ size = FtpGetFileSize(hHttpFile, &high);
+ }
+ else
+ {
+ UINT errorcode = 0;
+ UINT errorcode_size = sizeof(errorcode);
+
+ // http
+ if (HttpQueryInfo(hHttpFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
+ &size, &sizesize, NULL) == false)
+ {
+ size = 0;
+ }
+
+ if (HttpQueryInfo(hHttpFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
+ &errorcode, &errorcode_size, NULL) == false ||
+ (errorcode / 100) != 2)
+ {
+ // HTTP getting error
+ InternetCloseHandle(hInternet);
+ InternetCloseHandle(hHttpFile);
+ return NULL;
+ }
+ }
+
+ f = ZeroMalloc(sizeof(VW_FILE));
+ f->hInternet = hInternet;
+ f->hHttpFile = hHttpFile;
+ f->FileSize = size;
+
+ return f;
+}
+
+// Get the Internet file size
+UINT VwGetFileSize(VW_FILE *f)
+{
+ // Validate arguments
+ if (f == NULL)
+ {
+ return 0;
+ }
+
+ return f->FileSize;
+}
+
+// Read from the Internet file
+UINT VwReadFile(VW_FILE *f, void *buf, UINT size)
+{
+ UINT readsize = 0;
+ // Validate arguments
+ if (f == NULL || buf == NULL)
+ {
+ return INFINITE;
+ }
+
+ if (InternetReadFile(f->hHttpFile, buf, size, &readsize) == false)
+ {
+ return INFINITE;
+ }
+
+ return readsize;
+}
+
+// Close the Internet file
+void VwCloseFile(VW_FILE *f)
+{
+ // Validate arguments
+ if (f == NULL)
+ {
+ return;
+ }
+
+ InternetCloseHandle(f->hHttpFile);
+ InternetCloseHandle(f->hInternet);
+
+ Free(f);
+}
+
+// Memory reallocation
+void *ReAlloc(void *p, UINT size)
+{
+ void *ret;
+ if (size == 0)
+ {
+ size = 1;
+ }
+
+ ret = realloc(p, size);
+ if (ret == NULL)
+ {
+ _exit(0);
+ }
+
+ return ret;
+}
+
+// Memory allocation
+void *ZeroMalloc(UINT size)
+{
+ void *p;
+ if (size == 0)
+ {
+ size = 1;
+ }
+
+ p = malloc(size);
+ if (p == NULL)
+ {
+ _exit(0);
+ }
+
+ Zero(p, size);
+
+ return p;
+}
+
+// Memory clear
+void Zero(void *p, UINT size)
+{
+ if (p != NULL)
+ {
+ ZeroMemory(p, size);
+ }
+}
+
+// Memory release
+void Free(void *p)
+{
+ if (p != NULL)
+ {
+ free(p);
+ }
+}
+
+// Thread creation
+HANDLE VwNewThread(LPTHREAD_START_ROUTINE start, void *param)
+{
+ HANDLE h;
+ DWORD id;
+ // Validate arguments
+ if (start == NULL)
+ {
+ return NULL;
+ }
+
+ h = (HANDLE)_beginthreadex(NULL, 0, start, param, 0, &id);
+
+ return h;
+}
+
+// Thread release
+void VwFreeThread(HANDLE h)
+{
+ // Validate arguments
+ if (h == NULL)
+ {
+ return;
+ }
+
+ CloseHandle(h);
+}
+
+// Dialog procedure that does not do anything
+INT_PTR CALLBACK VpnWebDummyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+// Initialization of the dialog
+HWND InitVpnWebDlg(VPNWEBDLG_INIT *init)
+{
+ HWND hWnd;
+ // Validate arguments
+ if (init == NULL)
+ {
+ return NULL;
+ }
+
+ _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
+ setlocale(LC_ALL, "");
+
+ ZeroMemory(&data, sizeof(data));
+ CopyMemory(&data, init, sizeof(data));
+
+ LoadTables(data.LanguageId);
+
+ hWnd = CreateDialog(hDllInstance, MAKEINTRESOURCE(IDD_VPNWEBDLG),
+ data.hControlWnd, VpnWebDlgProc);
+
+ data.hWnd = hWnd;
+
+ ShowWindow(hWnd, SW_SHOW);
+
+ return hWnd;
+}
+
+// Exit the dialog
+void FreeVpnWebDlg()
+{
+ DestroyWindow(data.hWnd);
+}
+
+// Get the size of the dialog
+void GetVpnWebDlgSize(SIZE *size)
+{
+ HWND hWnd;
+ RECT rect;
+ // Validate arguments
+ if (size == NULL)
+ {
+ return;
+ }
+
+ hWnd = CreateDialog(hDllInstance, MAKEINTRESOURCE(IDD_VPNWEBDLG),
+ GetDesktopWindow(), VpnWebDummyDlgProc);
+
+ ZeroMemory(&rect, sizeof(rect));
+ GetWindowRect(hWnd, &rect);
+
+ DestroyWindow(hWnd);
+
+ size->cx = rect.right - rect.left;
+ size->cy = rect.bottom - rect.top;
+}
+
+
+// Get the item in the dialog
+HWND DlgItem(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return NULL;
+ }
+
+ if (id == 0)
+ {
+ return hWnd;
+ }
+ else
+ {
+ return GetDlgItem(hWnd, id);
+ }
+}
+
+// Hide the window
+void Hide(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ if (IsShow(hWnd, id))
+ {
+ ShowWindow(DlgItem(hWnd, id), SW_HIDE);
+ }
+}
+
+// Display the window
+void Show(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ if (IsHide(hWnd, id))
+ {
+ ShowWindow(DlgItem(hWnd, id), SW_SHOW);
+ }
+}
+
+// Changing the visibility setting
+void SetShow(HWND hWnd, UINT id, bool b)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ if (b)
+ {
+ Show(hWnd, id);
+ }
+ else
+ {
+ Hide(hWnd, id);
+ }
+}
+
+// Get whether the window is shown
+bool IsShow(HWND hWnd, UINT id)
+{
+ return IsHide(hWnd, id) ? false : true;
+}
+
+// Get whether the window is hidden
+bool IsHide(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return true;
+ }
+
+ if (GetStyle(hWnd, id) & WS_VISIBLE)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+// Remove the window style
+void RemoveExStyle(HWND hWnd, UINT id, UINT style)
+{
+ UINT old;
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ old = GetExStyle(hWnd, id);
+ if ((old & style) == 0)
+ {
+ return;
+ }
+
+ SetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE, old & ~style);
+ Refresh(DlgItem(hWnd, id));
+}
+
+// Set the window style
+void SetExStyle(HWND hWnd, UINT id, UINT style)
+{
+ UINT old;
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ old = GetExStyle(hWnd, id);
+ if (old & style)
+ {
+ return;
+ }
+
+ SetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE, old | style);
+ Refresh(DlgItem(hWnd, id));
+}
+
+// Get the window style
+UINT GetExStyle(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return 0;
+ }
+
+ return GetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE);
+}
+
+// Remove the window style
+void RemoveStyle(HWND hWnd, UINT id, UINT style)
+{
+ UINT old;
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ old = GetStyle(hWnd, id);
+ if ((old & style) == 0)
+ {
+ return;
+ }
+
+ SetWindowLong(DlgItem(hWnd, id), GWL_STYLE, old & ~style);
+ Refresh(DlgItem(hWnd, id));
+}
+
+// Set the window style
+void SetStyle(HWND hWnd, UINT id, UINT style)
+{
+ UINT old;
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ old = GetStyle(hWnd, id);
+ if (old & style)
+ {
+ return;
+ }
+
+ SetWindowLong(DlgItem(hWnd, id), GWL_STYLE, old | style);
+ Refresh(DlgItem(hWnd, id));
+}
+
+// Get the window style
+UINT GetStyle(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return 0;
+ }
+
+ return GetWindowLong(DlgItem(hWnd, id), GWL_STYLE);
+}
+
+// Update the window
+void Refresh(HWND hWnd)
+{
+ HWND parent;
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ DoEvents(hWnd);
+ UpdateWindow(hWnd);
+ DoEvents(hWnd);
+
+ parent = GetParent(hWnd);
+ if (parent != NULL)
+ {
+ Refresh(parent);
+ }
+}
+
+// Handle the event
+void DoEvents(HWND hWnd)
+{
+ MSG msg;
+
+ if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ UpdateWindow(hWnd);
+
+ if (hWnd)
+ {
+ DoEvents(NULL);
+ }
+}
+
+// Disable the window
+void Disable(HWND hWnd, UINT id)
+{
+ SetEnable(hWnd, id, false);
+}
+
+// Enable the window
+void Enable(HWND hWnd, UINT id)
+{
+ SetEnable(hWnd, id, true);
+}
+
+// Set the enabled state of the window
+void SetEnable(HWND hWnd, UINT id, bool b)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ if (b == false)
+ {
+ if (IsEnable(hWnd, id))
+ {
+ EnableWindow(DlgItem(hWnd, id), false);
+ Refresh(DlgItem(hWnd, id));
+ }
+ }
+ else
+ {
+ if (IsDisable(hWnd, id))
+ {
+ EnableWindow(DlgItem(hWnd, id), true);
+ Refresh(DlgItem(hWnd, id));
+ }
+ }
+}
+
+// Examine whether the Window is disabled
+bool IsDisable(HWND hWnd, UINT id)
+{
+ return IsEnable(hWnd, id) ? false : true;
+}
+
+// Examine whether the window is enabled
+bool IsEnable(HWND hWnd, UINT id)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return false;
+ }
+
+ return IsWindowEnabled(DlgItem(hWnd, id));
+}
+
+// Set the position of the progress bar
+void SetPos(HWND hWnd, UINT id, UINT pos)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ SendMsg(hWnd, id, PBM_SETPOS, pos, 0);
+}
+
+// Set the range of the progress bar
+void SetRange(HWND hWnd, UINT id, UINT start, UINT end)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return;
+ }
+
+ SendMsg(hWnd, id, PBM_SETRANGE32, start, end);
+}
+
+// Transmit a message to the control
+UINT SendMsg(HWND hWnd, UINT id, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ // Validate arguments
+ if (hWnd == NULL)
+ {
+ return 0;
+ }
+
+ return (UINT)SendMessageA(DlgItem(hWnd, id), msg, wParam, lParam);
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/