mirror of https://github.com/OpenVPN/openvpn-gui
				
				
				
			Reformat source code with uncrustify
Closes: #445 Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com>pull/643/head
							parent
							
								
									f2aad3a879
								
							
						
					
					
						commit
						2cb3c6e417
					
				
							
								
								
									
										82
									
								
								access.c
								
								
								
								
							
							
						
						
									
										82
									
								
								access.c
								
								
								
								
							|  | @ -44,7 +44,9 @@ extern options_t o; | |||
| #define MAX_UNAME_LEN (UNLEN + DNLEN + 2) /* UNLEN, DNLEN from lmcons.h +2 for '\' and NULL */ | ||||
| 
 | ||||
| static BOOL GetOwnerSID(PSID sid, DWORD sid_size); | ||||
| 
 | ||||
| static BOOL IsUserInGroup(PSID sid, PTOKEN_GROUPS token_groups, const WCHAR *group_name); | ||||
| 
 | ||||
| static PTOKEN_GROUPS GetProcessTokenGroups(void); | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -52,7 +54,7 @@ static PTOKEN_GROUPS GetProcessTokenGroups(void); | |||
|  * Get the local name of the group using the SID. | ||||
|  */ | ||||
| static BOOL | ||||
| GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) | ||||
| GetBuiltinAdminGroupName(WCHAR *name, DWORD nlen) | ||||
| { | ||||
|     BOOL b = FALSE; | ||||
|     PSID admin_sid = NULL; | ||||
|  | @ -64,19 +66,21 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) | |||
| 
 | ||||
|     admin_sid = malloc(sid_size); | ||||
|     if (!admin_sid) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     b = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, | ||||
|                             &sid_size); | ||||
|     if(b) | ||||
|                            &sid_size); | ||||
|     if (b) | ||||
|     { | ||||
|         b = LookupAccountSidW(NULL, admin_sid, name, &nlen, domain, &dlen, &su); | ||||
|     } | ||||
| #ifdef DEBUG | ||||
|         PrintDebug (L"builtin admin group name = %ls", name); | ||||
|     PrintDebug(L"builtin admin group name = %ls", name); | ||||
| #endif | ||||
| 
 | ||||
|     free (admin_sid); | ||||
|     free(admin_sid); | ||||
| 
 | ||||
|     return b; | ||||
| } | ||||
|  | @ -86,7 +90,7 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) | |||
|  * Reject if the group name contains certain illegal characters. | ||||
|  */ | ||||
| static BOOL | ||||
| AddUserToGroup (const WCHAR *group) | ||||
| AddUserToGroup(const WCHAR *group) | ||||
| { | ||||
|     WCHAR username[MAX_UNAME_LEN]; | ||||
|     WCHAR cmd[MAX_PATH] = L"C:\\windows\\system32\\cmd.exe"; | ||||
|  | @ -109,17 +113,19 @@ AddUserToGroup (const WCHAR *group) | |||
|     if (wcspbrk(group, reject) != NULL) | ||||
|     { | ||||
| #ifdef DEBUG | ||||
|         PrintDebug (L"AddUSerToGroup: illegal characters in group name: '%ls'.", group); | ||||
|         PrintDebug(L"AddUSerToGroup: illegal characters in group name: '%ls'.", group); | ||||
| #endif | ||||
|         return retval; | ||||
|     } | ||||
| 
 | ||||
|     size = _countof(username); | ||||
|     if (!GetUserNameExW (NameSamCompatible, username, &size)) | ||||
|     if (!GetUserNameExW(NameSamCompatible, username, &size)) | ||||
|     { | ||||
|         return retval; | ||||
|     } | ||||
| 
 | ||||
|     size = _countof(syspath); | ||||
|     if (GetSystemDirectory (syspath, size)) | ||||
|     if (GetSystemDirectory(syspath, size)) | ||||
|     { | ||||
|         syspath[size-1] = L'\0'; | ||||
|         size = _countof(cmd); | ||||
|  | @ -130,26 +136,34 @@ AddUserToGroup (const WCHAR *group) | |||
|         netcmd[size-1] = L'\0'; | ||||
|     } | ||||
|     size = (wcslen(fmt) + wcslen(username) + 2*wcslen(group) + 2*wcslen(netcmd)+ 1); | ||||
|     if ((params = malloc (size*sizeof(WCHAR))) == NULL) | ||||
|     if ((params = malloc(size*sizeof(WCHAR))) == NULL) | ||||
|     { | ||||
|         return retval; | ||||
|     } | ||||
| 
 | ||||
|     _snwprintf(params, size, fmt, netcmd, group, netcmd, group, username); | ||||
|     params[size-1] = L'\0'; | ||||
| 
 | ||||
|     status = RunAsAdmin (cmd, params); | ||||
|     status = RunAsAdmin(cmd, params); | ||||
|     if (status == 0) | ||||
|     { | ||||
|         retval = TRUE; | ||||
|     } | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
|     if (status == (DWORD) -1) | ||||
|     { | ||||
|         PrintDebug(L"RunAsAdmin: failed to execute the command [%ls %ls] : error = 0x%x", | ||||
|                     cmd, params, GetLastError()); | ||||
|                    cmd, params, GetLastError()); | ||||
|     } | ||||
|     else if (status) | ||||
|     { | ||||
|         PrintDebug(L"RunAsAdmin: command [%ls %ls] returned exit_code = %lu", | ||||
|                     cmd, params, status); | ||||
|                    cmd, params, status); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     free (params); | ||||
|     free(params); | ||||
|     return retval; | ||||
| } | ||||
| 
 | ||||
|  | @ -158,18 +172,22 @@ AddUserToGroup (const WCHAR *group) | |||
|  * interactive service. | ||||
|  */ | ||||
| static BOOL | ||||
| CheckConfigPath (const WCHAR *config_dir) | ||||
| CheckConfigPath(const WCHAR *config_dir) | ||||
| { | ||||
|     BOOL ret = FALSE; | ||||
|     int size = wcslen(o.global_config_dir); | ||||
| 
 | ||||
|     /* if interactive service is not running, no access control: return TRUE */ | ||||
|     if (!CheckIServiceStatus(FALSE)) | ||||
|     { | ||||
|         ret = TRUE; | ||||
|     } | ||||
|     /* if config is from the global location allow it */ | ||||
|     else if (wcsncmp(config_dir, o.global_config_dir, size) == 0 | ||||
|              && wcsstr(config_dir + size, L"..") == NULL) | ||||
|     { | ||||
|         ret = TRUE; | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
|  | @ -192,19 +210,27 @@ AuthorizeConfig(const connection_t *c) | |||
|     PTOKEN_GROUPS groups = NULL; | ||||
| 
 | ||||
|     if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group))) | ||||
|     { | ||||
|         admin_group = sysadmin_group; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         admin_group = L"Administrators"; | ||||
|     } | ||||
| 
 | ||||
|     PrintDebug(L"Authorized groups: '%ls', '%ls'", admin_group, o.ovpn_admin_group); | ||||
| 
 | ||||
|     if (CheckConfigPath(c->config_dir)) | ||||
|     { | ||||
|         return TRUE; | ||||
|     } | ||||
| 
 | ||||
|     if (!GetOwnerSID(sid, sid_size)) | ||||
|     { | ||||
|         if (!o.silent_connection) | ||||
|         { | ||||
|             MessageBoxW(NULL, L"Failed to determine process owner SID", L""PACKAGE_NAME, MB_OK); | ||||
|         } | ||||
|         return FALSE; | ||||
|     } | ||||
|     groups = GetProcessTokenGroups(); | ||||
|  | @ -225,7 +251,7 @@ AuthorizeConfig(const connection_t *c) | |||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     if (WaitForSingleObject (o.netcmd_semaphore, 0) != WAIT_OBJECT_0) | ||||
|     if (WaitForSingleObject(o.netcmd_semaphore, 0) != WAIT_OBJECT_0) | ||||
|     { | ||||
|         /* Could not lock semaphore -- auth dialog already running? */ | ||||
|         ShowLocalizedMsg(IDS_NFO_CONFIG_AUTH_PENDING, c->config_name, o.ovpn_admin_group); | ||||
|  | @ -237,17 +263,21 @@ AuthorizeConfig(const connection_t *c) | |||
|                              o.ovpn_admin_group); | ||||
|     if (res == IDYES) | ||||
|     { | ||||
|         AddUserToGroup (o.ovpn_admin_group); | ||||
|         AddUserToGroup(o.ovpn_admin_group); | ||||
|         /*
 | ||||
|          * Check the success of above by testing the group membership again | ||||
|          */ | ||||
|         if (IsUserInGroup(sid, NULL, o.ovpn_admin_group)) | ||||
|         { | ||||
|             retval = TRUE; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             ShowLocalizedMsg(IDS_ERR_ADD_USER_TO_ADMIN_GROUP, o.ovpn_admin_group); | ||||
|         SetForegroundWindow (o.hWnd); | ||||
|         } | ||||
|         SetForegroundWindow(o.hWnd); | ||||
|     } | ||||
|     ReleaseSemaphore (o.netcmd_semaphore, 1, NULL); | ||||
|     ReleaseSemaphore(o.netcmd_semaphore, 1, NULL); | ||||
| 
 | ||||
|     return retval; | ||||
| } | ||||
|  | @ -287,7 +317,9 @@ GetProcessTokenGroups(void) | |||
|     DWORD buf_size = 0; | ||||
| 
 | ||||
|     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
|     if (!GetTokenInformation(token, TokenGroups, NULL, 0, &buf_size) | ||||
|         && GetLastError() == ERROR_INSUFFICIENT_BUFFER) | ||||
|     { | ||||
|  | @ -301,7 +333,7 @@ GetProcessTokenGroups(void) | |||
|     if (!GetTokenInformation(token, TokenGroups, groups, buf_size, &buf_size)) | ||||
|     { | ||||
|         PrintDebug(L"Failed to get Token Group Information: error = %lu", GetLastError); | ||||
|         free (groups); | ||||
|         free(groups); | ||||
|         groups = NULL; | ||||
|     } | ||||
| 
 | ||||
|  | @ -345,7 +377,9 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam | |||
|     } | ||||
| 
 | ||||
|     if (!sid) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     do | ||||
|     { | ||||
|  | @ -354,7 +388,9 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam | |||
|         err = NetLocalGroupGetMembers(NULL, group_name, 0, (LPBYTE *) &members, | ||||
|                                       MAX_PREFERRED_LENGTH, &nread, &nmax, &resume); | ||||
|         if (err != NERR_Success && err != ERROR_MORE_DATA) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         /* If a match is already found, ret = TRUE, the loop is skipped */ | ||||
|         for (DWORD i = 0; i < nread && !ret; ++i) | ||||
|  | @ -362,13 +398,17 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam | |||
|             ret = EqualSid(members[i].lgrmi0_sid, sid); | ||||
|         } | ||||
|         NetApiBufferFree(members); | ||||
|     /* MSDN says the lookup should always iterate until err != ERROR_MORE_DATA */ | ||||
|         /* MSDN says the lookup should always iterate until err != ERROR_MORE_DATA */ | ||||
|     } while (err == ERROR_MORE_DATA && nloop++ < 100); | ||||
| 
 | ||||
|     if (err != NERR_Success && err != NERR_GroupNotFound) | ||||
|     { | ||||
|         PrintDebug(L"NetLocalGroupGetMembers for group '%ls' failed: error = %lu", group_name, err); | ||||
|     } | ||||
|     if (ret) | ||||
|     { | ||||
|         PrintDebug(L"User is in group '%ls'", group_name); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								access.h
								
								
								
								
							
							
						
						
									
										2
									
								
								access.h
								
								
								
								
							|  | @ -24,6 +24,6 @@ | |||
| 
 | ||||
| #include "options.h" | ||||
| 
 | ||||
| BOOL AuthorizeConfig (const connection_t *c); | ||||
| BOOL AuthorizeConfig(const connection_t *c); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										399
									
								
								as.c
								
								
								
								
							
							
						
						
									
										399
									
								
								as.c
								
								
								
								
							|  | @ -44,7 +44,8 @@ void | |||
| SanitizeFilename(wchar_t *fname) | ||||
| { | ||||
|     const wchar_t *reserved = L"<>:\"/\\|?*;"; /* remap these and ascii 1 to 31 */ | ||||
|     while (*fname) { | ||||
|     while (*fname) | ||||
|     { | ||||
|         wchar_t c = *fname; | ||||
|         if (c < 32 || wcschr(reserved, c)) | ||||
|         { | ||||
|  | @ -80,12 +81,15 @@ ExtractProfileName(const WCHAR *profile, const WCHAR *default_name, WCHAR *out_n | |||
|     WCHAR *ctx = NULL; | ||||
|     pch = wcstok_s(buf, L"\r\n", &ctx); | ||||
| 
 | ||||
|     while (pch != NULL) { | ||||
|         if (wcsbegins(pch, PROFILE_NAME_TOKEN)) { | ||||
|     while (pch != NULL) | ||||
|     { | ||||
|         if (wcsbegins(pch, PROFILE_NAME_TOKEN)) | ||||
|         { | ||||
|             wcsncpy(profile_name, pch + wcslen(PROFILE_NAME_TOKEN), PROFILE_NAME_LEN - 1); | ||||
|             profile_name[PROFILE_NAME_LEN - 1] = L'\0'; | ||||
|         } | ||||
|         else if (wcsbegins(pch, FRIENDLY_NAME_TOKEN)) { | ||||
|         else if (wcsbegins(pch, FRIENDLY_NAME_TOKEN)) | ||||
|         { | ||||
|             wcsncpy(friendly_name, pch + wcslen(FRIENDLY_NAME_TOKEN), PROFILE_NAME_LEN - 1); | ||||
|             friendly_name[PROFILE_NAME_LEN - 1] = L'\0'; | ||||
|         } | ||||
|  | @ -96,11 +100,17 @@ ExtractProfileName(const WCHAR *profile, const WCHAR *default_name, WCHAR *out_n | |||
|     /* we use .ovpn here, but extension could be customized */ | ||||
|     /* actual extension will be applied during import */ | ||||
|     if (wcslen(friendly_name) > 0) | ||||
|     { | ||||
|         swprintf(out_name, out_name_length, L"%ls.ovpn", friendly_name); | ||||
|     } | ||||
|     else if (wcslen(profile_name) > 0) | ||||
|     { | ||||
|         swprintf(out_name, out_name_length, L"%ls.ovpn", profile_name); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         swprintf(out_name, out_name_length, L"%ls.ovpn", default_name); | ||||
|     } | ||||
| 
 | ||||
|     out_name[out_name_length - 1] = L'\0'; | ||||
| 
 | ||||
|  | @ -114,7 +124,7 @@ ShowWinInetError(HANDLE hWnd) | |||
| { | ||||
|     WCHAR err[256] = { 0 }; | ||||
|     FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM, GetModuleHandleW(L"wininet.dll"), | ||||
|         GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, _countof(err), NULL); | ||||
|                    GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, _countof(err), NULL); | ||||
|     ShowLocalizedMsgEx(MB_OK, hWnd, _T(PACKAGE_NAME), IDS_ERR_URL_IMPORT_PROFILE, GetLastError(), err); | ||||
| } | ||||
| 
 | ||||
|  | @ -128,26 +138,30 @@ struct UrlComponents | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
| * Extracts protocol, port and hostname from URL | ||||
| * | ||||
| * @param url URL to parse, length must be less than URL_MAX | ||||
| */ | ||||
|  * Extracts protocol, port and hostname from URL | ||||
|  * | ||||
|  * @param url URL to parse, length must be less than URL_MAX | ||||
|  */ | ||||
| void | ||||
| ParseUrl(const WCHAR *url, struct UrlComponents* comps) | ||||
| ParseUrl(const WCHAR *url, struct UrlComponents *comps) | ||||
| { | ||||
|     ZeroMemory(comps, sizeof(struct UrlComponents)); | ||||
| 
 | ||||
|     comps->port = 443; | ||||
|     comps->https = true; | ||||
|     if (wcsbegins(url, L"http://")) { | ||||
|     if (wcsbegins(url, L"http://")) | ||||
|     { | ||||
|         url += 7; | ||||
|     } else if (wcsbegins(url, L"https://")) { | ||||
|         url +=8; | ||||
|     } | ||||
|     else if (wcsbegins(url, L"https://")) | ||||
|     { | ||||
|         url += 8; | ||||
|     } | ||||
| 
 | ||||
|     WCHAR *strport = wcsstr(url, L":"); | ||||
|     WCHAR *pathptr = wcsstr(url, L"/"); | ||||
|     if (strport) { | ||||
|     if (strport) | ||||
|     { | ||||
|         wcsncpy_s(comps->host, URL_LEN, url, strport - url); | ||||
|         comps->port = wcstol(strport + 1, NULL, 10); | ||||
|     } | ||||
|  | @ -175,35 +189,41 @@ ParseUrl(const WCHAR *url, struct UrlComponents* comps) | |||
|  * @param psize pointer to a profile size, assigned by this function | ||||
|  */ | ||||
| BOOL | ||||
| DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char** pbuf, size_t* psize) | ||||
| DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char **pbuf, size_t *psize) | ||||
| { | ||||
|     size_t pos = 0; | ||||
|     size_t size = READ_CHUNK_LEN; | ||||
| 
 | ||||
|     *pbuf = calloc(1, size + 1); | ||||
|     char* buf = *pbuf; | ||||
|     if (buf == NULL) { | ||||
|     char *buf = *pbuf; | ||||
|     if (buf == NULL) | ||||
|     { | ||||
|         MessageBoxW(hWnd, L"Out of memory", _T(PACKAGE_NAME), MB_OK); | ||||
|         return FALSE; | ||||
|     } | ||||
|     while (true) { | ||||
|     while (true) | ||||
|     { | ||||
|         DWORD bytesRead = 0; | ||||
|         if (!InternetReadFile(hRequest, buf + pos, READ_CHUNK_LEN, &bytesRead)) { | ||||
|         if (!InternetReadFile(hRequest, buf + pos, READ_CHUNK_LEN, &bytesRead)) | ||||
|         { | ||||
|             ShowWinInetError(hWnd); | ||||
|             return FALSE; | ||||
|         } | ||||
| 
 | ||||
|         buf[pos + bytesRead] = '\0'; | ||||
| 
 | ||||
|         if (bytesRead == 0) { | ||||
|         if (bytesRead == 0) | ||||
|         { | ||||
|             size = pos; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         if (pos + bytesRead >= size) { | ||||
|         if (pos + bytesRead >= size) | ||||
|         { | ||||
|             size += READ_CHUNK_LEN; | ||||
|             *pbuf = realloc(*pbuf, size + 1); | ||||
|             if (!*pbuf) { | ||||
|             if (!*pbuf) | ||||
|             { | ||||
|                 free(buf); | ||||
|                 MessageBoxW(hWnd, L"Out of memory", _T(PACKAGE_NAME), MB_OK); | ||||
|                 return FALSE; | ||||
|  | @ -225,15 +245,17 @@ DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char** pbuf, size_t* psi | |||
| INT_PTR CALLBACK | ||||
| CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) | ||||
| { | ||||
|     auth_param_t * param = NULL; | ||||
|     auth_param_t *param = NULL; | ||||
| 
 | ||||
|     switch (msg) { | ||||
|     switch (msg) | ||||
|     { | ||||
|         case WM_INITDIALOG: | ||||
|             param = (auth_param_t*)lParam; | ||||
|             param = (auth_param_t *)lParam; | ||||
|             TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)param); | ||||
| 
 | ||||
|             WCHAR *wstr = Widen(param->str); | ||||
|             if (!wstr) { | ||||
|             if (!wstr) | ||||
|             { | ||||
|                 EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|                 break; | ||||
|             } | ||||
|  | @ -242,7 +264,9 @@ CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 
 | ||||
|             /* Set password echo on if needed */ | ||||
|             if (param->flags & FLAG_CR_ECHO) | ||||
|             { | ||||
|                 SendMessage(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), EM_SETPASSWORDCHAR, 0, 0); | ||||
|             } | ||||
| 
 | ||||
|             SetForegroundWindow(hwndDlg); | ||||
| 
 | ||||
|  | @ -253,28 +277,30 @@ CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) | |||
|             break; | ||||
| 
 | ||||
|         case WM_COMMAND: | ||||
|             param = (auth_param_t*)GetProp(hwndDlg, cfgProp); | ||||
|             param = (auth_param_t *)GetProp(hwndDlg, cfgProp); | ||||
| 
 | ||||
|             switch (LOWORD(wParam)) { | ||||
|             case ID_EDT_RESPONSE: | ||||
|                 if (!(param->flags & FLAG_CR_ECHO)) | ||||
|                 { | ||||
|                     ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), | ||||
|                                         GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
|                 } | ||||
|                 if (HIWORD(wParam) == EN_UPDATE) { | ||||
|                     /* enable OK if response is non-empty */ | ||||
|                     BOOL enableOK = GetWindowTextLength((HWND)lParam); | ||||
|                     EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); | ||||
|                 } | ||||
|                 break; | ||||
|             switch (LOWORD(wParam)) | ||||
|             { | ||||
|                 case ID_EDT_RESPONSE: | ||||
|                     if (!(param->flags & FLAG_CR_ECHO)) | ||||
|                     { | ||||
|                         ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), | ||||
|                                             GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
|                     } | ||||
|                     if (HIWORD(wParam) == EN_UPDATE) | ||||
|                     { | ||||
|                         /* enable OK if response is non-empty */ | ||||
|                         BOOL enableOK = GetWindowTextLength((HWND)lParam); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case IDOK: { | ||||
|                     int len = 0; | ||||
|                     GetDlgItemTextUtf8(hwndDlg, ID_EDT_RESPONSE, ¶m->cr_response, &len); | ||||
|                     EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|                 } | ||||
|                 return TRUE; | ||||
|                     return TRUE; | ||||
| 
 | ||||
|                 case IDCANCEL: | ||||
|                     EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|  | @ -408,7 +434,7 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user | |||
|     HANDLE hConnect = NULL; | ||||
|     HANDLE hRequest = NULL; | ||||
|     BOOL result = FALSE; | ||||
|     char* buf = NULL; | ||||
|     char *buf = NULL; | ||||
| 
 | ||||
|     /* need to make copy of password to use it for dynamic response */ | ||||
|     char password[USER_PASS_LEN] = { 0 }; | ||||
|  | @ -421,7 +447,8 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user | |||
|     } | ||||
| 
 | ||||
|     hInternet = InternetOpenW(L"openvpn-gui/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); | ||||
|     if (!hInternet) { | ||||
|     if (!hInternet) | ||||
|     { | ||||
|         ShowWinInetError(hWnd); | ||||
|         goto done; | ||||
|     } | ||||
|  | @ -435,7 +462,8 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user | |||
|     SetCursor(LoadCursorW(0, IDC_WAIT)); | ||||
| 
 | ||||
|     hConnect = InternetConnectW(hInternet, comps->host, comps->port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); | ||||
|     if (!hConnect) { | ||||
|     if (!hConnect) | ||||
|     { | ||||
|         ShowWinInetError(hWnd); | ||||
|         goto done; | ||||
|     } | ||||
|  | @ -443,13 +471,15 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user | |||
|     DWORD req_flags = INTERNET_FLAG_RELOAD; /* load from server, do not use cached data */ | ||||
|     req_flags |= comps->https ? INTERNET_FLAG_SECURE : 0; | ||||
|     hRequest = HttpOpenRequestW(hConnect, NULL, comps->path, NULL, NULL, NULL, req_flags, 0); | ||||
|     if (!hRequest) { | ||||
|     if (!hRequest) | ||||
|     { | ||||
|         ShowWinInetError(hWnd); | ||||
|         goto done; | ||||
|     } | ||||
| 
 | ||||
| again: | ||||
|     if (buf) { | ||||
|     if (buf) | ||||
|     { | ||||
|         free(buf); | ||||
|         buf = NULL; | ||||
|     } | ||||
|  | @ -462,26 +492,30 @@ again: | |||
| 
 | ||||
|     /* handle cert errors */ | ||||
|     /* https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/182888 */ | ||||
|     if (!HttpSendRequestW(hRequest, NULL, 0, NULL, 0)) { | ||||
|     if (!HttpSendRequestW(hRequest, NULL, 0, NULL, 0)) | ||||
|     { | ||||
| #ifdef DEBUG | ||||
|         DWORD err = GetLastError(); | ||||
|         if ((err == ERROR_INTERNET_INVALID_CA) || | ||||
|             (err == ERROR_INTERNET_SEC_CERT_CN_INVALID) || | ||||
|             (err == ERROR_INTERNET_SEC_CERT_DATE_INVALID) || | ||||
|             (err == ERROR_INTERNET_SEC_CERT_REV_FAILED)) { | ||||
|         if ((err == ERROR_INTERNET_INVALID_CA) | ||||
|             || (err == ERROR_INTERNET_SEC_CERT_CN_INVALID) | ||||
|             || (err == ERROR_INTERNET_SEC_CERT_DATE_INVALID) | ||||
|             || (err == ERROR_INTERNET_SEC_CERT_REV_FAILED)) | ||||
|         { | ||||
| 
 | ||||
|             /* ask user what to do and modify options if needed */ | ||||
|             DWORD dlg_result = InternetErrorDlg(hWnd, hRequest, | ||||
|                 err, | ||||
|                 FLAGS_ERROR_UI_FILTER_FOR_ERRORS | | ||||
|                 FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | | ||||
|                 FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, | ||||
|                 NULL); | ||||
|                                                 err, | ||||
|                                                 FLAGS_ERROR_UI_FILTER_FOR_ERRORS | ||||
|                                                 |FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | ||||
|                                                 |FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, | ||||
|                                                 NULL); | ||||
| 
 | ||||
|             if (dlg_result == ERROR_SUCCESS) { | ||||
|             if (dlg_result == ERROR_SUCCESS) | ||||
|             { | ||||
|                 /* for unknown reasons InternetErrorDlg() doesn't change options for ERROR_INTERNET_SEC_CERT_REV_FAILED,
 | ||||
|                  * despite user is willing to continue, so we have to do it manually */ | ||||
|                 if (err == ERROR_INTERNET_SEC_CERT_REV_FAILED) { | ||||
|                 if (err == ERROR_INTERNET_SEC_CERT_REV_FAILED) | ||||
|                 { | ||||
|                     DWORD flags; | ||||
|                     DWORD len = sizeof(flags); | ||||
|                     InternetQueryOptionW(hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, &len); | ||||
|  | @ -495,9 +529,11 @@ again: | |||
|                 goto again; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 goto done; | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
| #endif /* ifdef DEBUG */ | ||||
|         ShowWinInetError(hWnd); | ||||
|         goto done; | ||||
|     } | ||||
|  | @ -510,36 +546,49 @@ again: | |||
|     size_t size = 0; | ||||
| 
 | ||||
|     /* download profile content */ | ||||
|     if ((status_code == 200) || (status_code == 401)) { | ||||
|     if ((status_code == 200) || (status_code == 401)) | ||||
|     { | ||||
|         if (!DownloadProfileContent(hWnd, hRequest, &buf, &size)) | ||||
|         { | ||||
|             goto done; | ||||
|         } | ||||
| 
 | ||||
|         char* msg_begin = strstr(buf, "<Message>CRV1:"); | ||||
|         char* msg_end = strstr(buf, "</Message>"); | ||||
|         if ((status_code == 401) && msg_begin && msg_end) { | ||||
|         char *msg_begin = strstr(buf, "<Message>CRV1:"); | ||||
|         char *msg_end = strstr(buf, "</Message>"); | ||||
|         if ((status_code == 401) && msg_begin && msg_end) | ||||
|         { | ||||
|             *msg_end = '\0'; | ||||
|             auth_param_t* param = (auth_param_t*)calloc(1, sizeof(auth_param_t)); | ||||
|             auth_param_t *param = (auth_param_t *)calloc(1, sizeof(auth_param_t)); | ||||
|             if (!param) | ||||
|             { | ||||
|                 goto done; | ||||
|             } | ||||
| 
 | ||||
|             if (parse_dynamic_cr(msg_begin + 14, param)) { | ||||
|             if (parse_dynamic_cr(msg_begin + 14, param)) | ||||
|             { | ||||
|                 /* prompt user for dynamic challenge */ | ||||
|                 INT_PTR res = LocalizedDialogBoxParam(ID_DLG_CHALLENGE_RESPONSE, CRDialogFunc, (LPARAM)param); | ||||
|                 if (res == IDOK) | ||||
|                 { | ||||
|                     _snprintf_0(password, "CRV1::%s::%s", param->id, param->cr_response); | ||||
|                 } | ||||
| 
 | ||||
|                 free_auth_param(param); | ||||
| 
 | ||||
|                 if (res == IDOK) | ||||
|                 { | ||||
|                     goto again; | ||||
|                 } | ||||
|             } | ||||
|             else { | ||||
|             else | ||||
|             { | ||||
|                 free_auth_param(param); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (status_code != 200) { | ||||
|     if (status_code != 200) | ||||
|     { | ||||
|         ShowLocalizedMsgEx(MB_OK, hWnd, _T(PACKAGE_NAME), IDS_ERR_URL_IMPORT_PROFILE, status_code, L"HTTP error"); | ||||
|         goto done; | ||||
|     } | ||||
|  | @ -563,8 +612,9 @@ again: | |||
|     if (strlen(comps->content_type) == 0 /* AS profile */ | ||||
|         || !ExtractFilenameFromHeader(hRequest, name, MAX_PATH)) | ||||
|     { | ||||
|         WCHAR* wbuf = Widen(buf); | ||||
|         if (!wbuf) { | ||||
|         WCHAR *wbuf = Widen(buf); | ||||
|         if (!wbuf) | ||||
|         { | ||||
|             MessageBoxW(hWnd, L"Failed to convert profile content to wchar", _T(PACKAGE_NAME), MB_OK); | ||||
|             goto done; | ||||
|         } | ||||
|  | @ -574,14 +624,16 @@ again: | |||
| 
 | ||||
|     /* save profile content into tmp file */ | ||||
|     DWORD res = GetTempPathW((DWORD)out_path_size, out_path); | ||||
|     if (res == 0 || res > out_path_size) { | ||||
|     if (res == 0 || res > out_path_size) | ||||
|     { | ||||
|         MessageBoxW(hWnd, L"Failed to get TMP path", _T(PACKAGE_NAME), MB_OK); | ||||
|         goto done; | ||||
|     } | ||||
|     swprintf(out_path, out_path_size, L"%ls%ls", out_path, name); | ||||
|     out_path[out_path_size - 1] = '\0'; | ||||
|     FILE* f = _wfopen(out_path, L"w"); | ||||
|     if (f == NULL) { | ||||
|     FILE *f = _wfopen(out_path, L"w"); | ||||
|     if (f == NULL) | ||||
|     { | ||||
|         MessageBoxW(hWnd, L"Unable to save downloaded profile", _T(PACKAGE_NAME), MB_OK); | ||||
|         goto done; | ||||
|     } | ||||
|  | @ -592,26 +644,34 @@ again: | |||
| 
 | ||||
| done: | ||||
|     if (buf) | ||||
|     { | ||||
|         free(buf); | ||||
|     } | ||||
| 
 | ||||
|     /* wipe the password */ | ||||
|     SecureZeroMemory(password, sizeof(password)); | ||||
| 
 | ||||
|     if (hRequest) | ||||
|     { | ||||
|         InternetCloseHandle(hRequest); | ||||
|     } | ||||
| 
 | ||||
|     if (hConnect) | ||||
|     { | ||||
|         InternetCloseHandle(hConnect); | ||||
|     } | ||||
| 
 | ||||
|     if (hInternet) | ||||
|     { | ||||
|         InternetCloseHandle(hInternet); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| typedef enum { | ||||
|    server_as = 1, | ||||
|    server_generic = 2 | ||||
|     server_as = 1, | ||||
|     server_generic = 2 | ||||
| } server_type_t; | ||||
| 
 | ||||
| INT_PTR CALLBACK | ||||
|  | @ -623,116 +683,123 @@ ImportProfileFromURLDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa | |||
| 
 | ||||
|     switch (msg) | ||||
|     { | ||||
|     case WM_INITDIALOG: | ||||
|         type = (server_type_t) lParam; | ||||
|         TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)lParam); | ||||
|         SetStatusWinIcon(hwndDlg, ID_ICO_APP); | ||||
|         case WM_INITDIALOG: | ||||
|             type = (server_type_t) lParam; | ||||
|             TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)lParam); | ||||
|             SetStatusWinIcon(hwndDlg, ID_ICO_APP); | ||||
| 
 | ||||
|         if (type == server_generic) | ||||
|         { | ||||
|             /* Change window title and hide autologin checkbox */ | ||||
|             SetWindowTextW(hwndDlg, LoadLocalizedString(IDS_MENU_IMPORT_URL)); | ||||
|             ShowWindow(GetDlgItem(hwndDlg, ID_CHK_AUTOLOGIN), SW_HIDE); | ||||
|         } | ||||
|         /* disable OK button until required data is filled in */ | ||||
|         EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); | ||||
|         ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), | ||||
|                             GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); | ||||
|         break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         type = (server_type_t) GetProp(hwndDlg, cfgProp); | ||||
|         switch (LOWORD(wParam)) | ||||
|         { | ||||
|         case ID_EDT_AUTH_PASS: | ||||
|             if (type == server_generic) | ||||
|             { | ||||
|                 /* Change window title and hide autologin checkbox */ | ||||
|                 SetWindowTextW(hwndDlg, LoadLocalizedString(IDS_MENU_IMPORT_URL)); | ||||
|                 ShowWindow(GetDlgItem(hwndDlg, ID_CHK_AUTOLOGIN), SW_HIDE); | ||||
|             } | ||||
|             /* disable OK button until required data is filled in */ | ||||
|             EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); | ||||
|             ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), | ||||
|                                 GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
|             /* fall through */ | ||||
|         case ID_EDT_AUTH_USER: | ||||
|         case ID_EDT_URL: | ||||
|             if (HIWORD(wParam) == EN_UPDATE) { | ||||
|                 /* enable OK button only if url and username are filled */ | ||||
|                 BOOL enableOK = GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_URL)) | ||||
|                     && GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); | ||||
|                                 GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); | ||||
|             break; | ||||
| 
 | ||||
|         case WM_COMMAND: | ||||
|             type = (server_type_t) GetProp(hwndDlg, cfgProp); | ||||
|             switch (LOWORD(wParam)) | ||||
|             { | ||||
|                 case ID_EDT_AUTH_PASS: | ||||
|                     ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), | ||||
|                                         GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
| 
 | ||||
|                 /* fall through */ | ||||
|                 case ID_EDT_AUTH_USER: | ||||
|                 case ID_EDT_URL: | ||||
|                     if (HIWORD(wParam) == EN_UPDATE) | ||||
|                     { | ||||
|                         /* enable OK button only if url and username are filled */ | ||||
|                         BOOL enableOK = GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_URL)) | ||||
|                                         && GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case IDOK: | ||||
| 
 | ||||
|                     GetDlgItemTextW(hwndDlg, ID_EDT_URL, url, _countof(url)); | ||||
| 
 | ||||
|                     int username_len = 0; | ||||
|                     char *username = NULL; | ||||
|                     GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_USER, &username, &username_len); | ||||
| 
 | ||||
|                     int password_len = 0; | ||||
|                     char *password = NULL; | ||||
|                     GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_PASS, &password, &password_len); | ||||
| 
 | ||||
|                     WCHAR path[MAX_PATH + 1] = { 0 }; | ||||
|                     struct UrlComponents comps = {0}; | ||||
|                     if (type == server_as) | ||||
|                     { | ||||
| 
 | ||||
|                         autologin = IsDlgButtonChecked(hwndDlg, ID_CHK_AUTOLOGIN) == BST_CHECKED; | ||||
|                         GetASUrl(url, autologin, &comps); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         ParseUrl(url, &comps); | ||||
|                         strncpy_s(comps.content_type, _countof(comps.content_type), | ||||
|                                   "application/x-openvpn-profile", _TRUNCATE); | ||||
|                     } | ||||
|                     BOOL downloaded = DownloadProfile(hwndDlg, &comps, username, password, path, _countof(path)); | ||||
| 
 | ||||
|                     if (username_len > 0) | ||||
|                     { | ||||
|                         free(username); | ||||
|                     } | ||||
| 
 | ||||
|                     if (password_len > 0) | ||||
|                     { | ||||
|                         SecureZeroMemory(password, strlen(password)); | ||||
|                         free(password); | ||||
|                     } | ||||
| 
 | ||||
|                     if (downloaded) | ||||
|                     { | ||||
|                         EndDialog(hwndDlg, LOWORD(wParam)); | ||||
| 
 | ||||
|                         ImportConfigFile(path, false); /* do not prompt user */ | ||||
|                         _wunlink(path); | ||||
|                     } | ||||
|                     return TRUE; | ||||
| 
 | ||||
|                 case IDCANCEL: | ||||
|                     EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|                     return TRUE; | ||||
| 
 | ||||
|                 case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ | ||||
|                     ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), | ||||
|                                              GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
|                     return TRUE; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case IDOK: | ||||
| 
 | ||||
|             GetDlgItemTextW(hwndDlg, ID_EDT_URL, url, _countof(url)); | ||||
| 
 | ||||
|             int username_len = 0; | ||||
|             char *username = NULL; | ||||
|             GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_USER, &username, &username_len); | ||||
| 
 | ||||
|             int password_len = 0; | ||||
|             char *password = NULL; | ||||
|             GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_PASS, &password, &password_len); | ||||
| 
 | ||||
|             WCHAR path[MAX_PATH + 1] = { 0 }; | ||||
|             struct UrlComponents comps = {0}; | ||||
|             if (type == server_as) | ||||
|             { | ||||
| 
 | ||||
|                 autologin = IsDlgButtonChecked(hwndDlg, ID_CHK_AUTOLOGIN) == BST_CHECKED; | ||||
|                 GetASUrl(url, autologin, &comps); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ParseUrl(url, &comps); | ||||
|                 strncpy_s(comps.content_type, _countof(comps.content_type), | ||||
|                           "application/x-openvpn-profile", _TRUNCATE); | ||||
|             } | ||||
|             BOOL downloaded = DownloadProfile(hwndDlg, &comps, username, password, path, _countof(path)); | ||||
| 
 | ||||
|             if (username_len > 0) | ||||
|                 free(username); | ||||
| 
 | ||||
|             if (password_len > 0) | ||||
|             { | ||||
|                 SecureZeroMemory(password, strlen(password)); | ||||
|                 free(password); | ||||
|             } | ||||
| 
 | ||||
|             if (downloaded) { | ||||
|                 EndDialog(hwndDlg, LOWORD(wParam)); | ||||
| 
 | ||||
|                 ImportConfigFile(path, false); /* do not prompt user */ | ||||
|                 _wunlink(path); | ||||
|             } | ||||
|             return TRUE; | ||||
| 
 | ||||
|         case IDCANCEL: | ||||
|         case WM_CLOSE: | ||||
|             EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|             return TRUE; | ||||
| 
 | ||||
|         case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ | ||||
|             ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), | ||||
|                                      GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); | ||||
|             return TRUE; | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
| 
 | ||||
|     case WM_CLOSE: | ||||
|         EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|         return TRUE; | ||||
| 
 | ||||
|     case WM_NCDESTROY: | ||||
|         RemoveProp(hwndDlg, cfgProp); | ||||
|         break; | ||||
|         case WM_NCDESTROY: | ||||
|             RemoveProp(hwndDlg, cfgProp); | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     return FALSE; | ||||
| } | ||||
| 
 | ||||
| void ImportConfigFromAS() | ||||
| void | ||||
| ImportConfigFromAS() | ||||
| { | ||||
|     LocalizedDialogBoxParam(ID_DLG_URL_PROFILE_IMPORT, ImportProfileFromURLDialogFunc, (LPARAM) server_as); | ||||
| } | ||||
| 
 | ||||
| void ImportConfigFromURL() | ||||
| void | ||||
| ImportConfigFromURL() | ||||
| { | ||||
|     LocalizedDialogBoxParam(ID_DLG_URL_PROFILE_IMPORT, ImportProfileFromURLDialogFunc, (LPARAM) server_generic); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										513
									
								
								chartable.h
								
								
								
								
							
							
						
						
									
										513
									
								
								chartable.h
								
								
								
								
							|  | @ -20,261 +20,260 @@ | |||
|  */ | ||||
| 
 | ||||
| WCHAR unicode_to_ascii[256] = { | ||||
| 0x0000, | ||||
| 0x0001, | ||||
| 0x0002, | ||||
| 0x0003, | ||||
| 0x0004, | ||||
| 0x0005, | ||||
| 0x0006, | ||||
| 0x0007, | ||||
| 0x0008, | ||||
| 0x0009, | ||||
| 0x000a, | ||||
| 0x000b, | ||||
| 0x000c, | ||||
| 0x000d, | ||||
| 0x000e, | ||||
| 0x000f, | ||||
| 0x0010, | ||||
| 0x0011, | ||||
| 0x0012, | ||||
| 0x0013, | ||||
| 0x0014, | ||||
| 0x0015, | ||||
| 0x0016, | ||||
| 0x0017, | ||||
| 0x0018, | ||||
| 0x0019, | ||||
| 0x001a, | ||||
| 0x001b, | ||||
| 0x001c, | ||||
| 0x001d, | ||||
| 0x001e, | ||||
| 0x001f, | ||||
| 0x0020, | ||||
| 0x0021, | ||||
| 0x0022, | ||||
| 0x0023, | ||||
| 0x0024, | ||||
| 0x0025, | ||||
| 0x0026, | ||||
| 0x0027, | ||||
| 0x0028, | ||||
| 0x0029, | ||||
| 0x002a, | ||||
| 0x002b, | ||||
| 0x002c, | ||||
| 0x002d, | ||||
| 0x002e, | ||||
| 0x002f, | ||||
| 0x0030, | ||||
| 0x0031, | ||||
| 0x0032, | ||||
| 0x0033, | ||||
| 0x0034, | ||||
| 0x0035, | ||||
| 0x0036, | ||||
| 0x0037, | ||||
| 0x0038, | ||||
| 0x0039, | ||||
| 0x003a, | ||||
| 0x003b, | ||||
| 0x003c, | ||||
| 0x003d, | ||||
| 0x003e, | ||||
| 0x003f, | ||||
| 0x0040, | ||||
| 0x0041, | ||||
| 0x0042, | ||||
| 0x0043, | ||||
| 0x0044, | ||||
| 0x0045, | ||||
| 0x0046, | ||||
| 0x0047, | ||||
| 0x0048, | ||||
| 0x0049, | ||||
| 0x004a, | ||||
| 0x004b, | ||||
| 0x004c, | ||||
| 0x004d, | ||||
| 0x004e, | ||||
| 0x004f, | ||||
| 0x0050, | ||||
| 0x0051, | ||||
| 0x0052, | ||||
| 0x0053, | ||||
| 0x0054, | ||||
| 0x0055, | ||||
| 0x0056, | ||||
| 0x0057, | ||||
| 0x0058, | ||||
| 0x0059, | ||||
| 0x005a, | ||||
| 0x005b, | ||||
| 0x005c, | ||||
| 0x005d, | ||||
| 0x005e, | ||||
| 0x005f, | ||||
| 0x0060, | ||||
| 0x0061, | ||||
| 0x0062, | ||||
| 0x0063, | ||||
| 0x0064, | ||||
| 0x0065, | ||||
| 0x0066, | ||||
| 0x0067, | ||||
| 0x0068, | ||||
| 0x0069, | ||||
| 0x006a, | ||||
| 0x006b, | ||||
| 0x006c, | ||||
| 0x006d, | ||||
| 0x006e, | ||||
| 0x006f, | ||||
| 0x0070, | ||||
| 0x0071, | ||||
| 0x0072, | ||||
| 0x0073, | ||||
| 0x0074, | ||||
| 0x0075, | ||||
| 0x0076, | ||||
| 0x0077, | ||||
| 0x0078, | ||||
| 0x0079, | ||||
| 0x007a, | ||||
| 0x007b, | ||||
| 0x007c, | ||||
| 0x007d, | ||||
| 0x007e, | ||||
| 0x007f, | ||||
| 0x00c7, | ||||
| 0x00fc, | ||||
| 0x00e9, | ||||
| 0x00e2, | ||||
| 0x00e4, | ||||
| 0x00e0, | ||||
| 0x00e5, | ||||
| 0x00e7, | ||||
| 0x00ea, | ||||
| 0x00eb, | ||||
| 0x00e8, | ||||
| 0x00ef, | ||||
| 0x00ee, | ||||
| 0x00ec, | ||||
| 0x00c4, | ||||
| 0x00c5, | ||||
| 0x00c9, | ||||
| 0x00e6, | ||||
| 0x00c6, | ||||
| 0x00f4, | ||||
| 0x00f6, | ||||
| 0x00f2, | ||||
| 0x00fb, | ||||
| 0x00f9, | ||||
| 0x00ff, | ||||
| 0x00d6, | ||||
| 0x00dc, | ||||
| 0x00f8, | ||||
| 0x00a3, | ||||
| 0x00d8, | ||||
| 0x00d7, | ||||
| 0x0192, | ||||
| 0x00e1, | ||||
| 0x00ed, | ||||
| 0x00f3, | ||||
| 0x00fa, | ||||
| 0x00f1, | ||||
| 0x00d1, | ||||
| 0x00aa, | ||||
| 0x00ba, | ||||
| 0x00bf, | ||||
| 0x00ae, | ||||
| 0x00ac, | ||||
| 0x00bd, | ||||
| 0x00bc, | ||||
| 0x00a1, | ||||
| 0x00ab, | ||||
| 0x00bb, | ||||
| 0x2591, | ||||
| 0x2592, | ||||
| 0x2593, | ||||
| 0x2502, | ||||
| 0x2524, | ||||
| 0x00c1, | ||||
| 0x00c2, | ||||
| 0x00c0, | ||||
| 0x00a9, | ||||
| 0x2563, | ||||
| 0x2551, | ||||
| 0x2557, | ||||
| 0x255d, | ||||
| 0x00a2, | ||||
| 0x00a5, | ||||
| 0x2510, | ||||
| 0x2514, | ||||
| 0x2534, | ||||
| 0x252c, | ||||
| 0x251c, | ||||
| 0x2500, | ||||
| 0x253c, | ||||
| 0x00e3, | ||||
| 0x00c3, | ||||
| 0x255a, | ||||
| 0x2554, | ||||
| 0x2569, | ||||
| 0x2566, | ||||
| 0x2560, | ||||
| 0x2550, | ||||
| 0x256c, | ||||
| 0x00a4, | ||||
| 0x00f0, | ||||
| 0x00d0, | ||||
| 0x00ca, | ||||
| 0x00cb, | ||||
| 0x00c8, | ||||
| 0x0131, | ||||
| 0x00cd, | ||||
| 0x00ce, | ||||
| 0x00cf, | ||||
| 0x2518, | ||||
| 0x250c, | ||||
| 0x2588, | ||||
| 0x2584, | ||||
| 0x00a6, | ||||
| 0x00cc, | ||||
| 0x2580, | ||||
| 0x00d3, | ||||
| 0x00df, | ||||
| 0x00d4, | ||||
| 0x00d2, | ||||
| 0x00f5, | ||||
| 0x00d5, | ||||
| 0x00b5, | ||||
| 0x00fe, | ||||
| 0x00de, | ||||
| 0x00da, | ||||
| 0x00db, | ||||
| 0x00d9, | ||||
| 0x00fd, | ||||
| 0x00dd, | ||||
| 0x00af, | ||||
| 0x00b4, | ||||
| 0x00ad, | ||||
| 0x00b1, | ||||
| 0x2017, | ||||
| 0x00be, | ||||
| 0x00b6, | ||||
| 0x00a7, | ||||
| 0x00f7, | ||||
| 0x00b8, | ||||
| 0x00b0, | ||||
| 0x00a8, | ||||
| 0x00b7, | ||||
| 0x00b9, | ||||
| 0x00b3, | ||||
| 0x00b2, | ||||
| 0x25a0, | ||||
| 0x00a0 | ||||
|     0x0000, | ||||
|     0x0001, | ||||
|     0x0002, | ||||
|     0x0003, | ||||
|     0x0004, | ||||
|     0x0005, | ||||
|     0x0006, | ||||
|     0x0007, | ||||
|     0x0008, | ||||
|     0x0009, | ||||
|     0x000a, | ||||
|     0x000b, | ||||
|     0x000c, | ||||
|     0x000d, | ||||
|     0x000e, | ||||
|     0x000f, | ||||
|     0x0010, | ||||
|     0x0011, | ||||
|     0x0012, | ||||
|     0x0013, | ||||
|     0x0014, | ||||
|     0x0015, | ||||
|     0x0016, | ||||
|     0x0017, | ||||
|     0x0018, | ||||
|     0x0019, | ||||
|     0x001a, | ||||
|     0x001b, | ||||
|     0x001c, | ||||
|     0x001d, | ||||
|     0x001e, | ||||
|     0x001f, | ||||
|     0x0020, | ||||
|     0x0021, | ||||
|     0x0022, | ||||
|     0x0023, | ||||
|     0x0024, | ||||
|     0x0025, | ||||
|     0x0026, | ||||
|     0x0027, | ||||
|     0x0028, | ||||
|     0x0029, | ||||
|     0x002a, | ||||
|     0x002b, | ||||
|     0x002c, | ||||
|     0x002d, | ||||
|     0x002e, | ||||
|     0x002f, | ||||
|     0x0030, | ||||
|     0x0031, | ||||
|     0x0032, | ||||
|     0x0033, | ||||
|     0x0034, | ||||
|     0x0035, | ||||
|     0x0036, | ||||
|     0x0037, | ||||
|     0x0038, | ||||
|     0x0039, | ||||
|     0x003a, | ||||
|     0x003b, | ||||
|     0x003c, | ||||
|     0x003d, | ||||
|     0x003e, | ||||
|     0x003f, | ||||
|     0x0040, | ||||
|     0x0041, | ||||
|     0x0042, | ||||
|     0x0043, | ||||
|     0x0044, | ||||
|     0x0045, | ||||
|     0x0046, | ||||
|     0x0047, | ||||
|     0x0048, | ||||
|     0x0049, | ||||
|     0x004a, | ||||
|     0x004b, | ||||
|     0x004c, | ||||
|     0x004d, | ||||
|     0x004e, | ||||
|     0x004f, | ||||
|     0x0050, | ||||
|     0x0051, | ||||
|     0x0052, | ||||
|     0x0053, | ||||
|     0x0054, | ||||
|     0x0055, | ||||
|     0x0056, | ||||
|     0x0057, | ||||
|     0x0058, | ||||
|     0x0059, | ||||
|     0x005a, | ||||
|     0x005b, | ||||
|     0x005c, | ||||
|     0x005d, | ||||
|     0x005e, | ||||
|     0x005f, | ||||
|     0x0060, | ||||
|     0x0061, | ||||
|     0x0062, | ||||
|     0x0063, | ||||
|     0x0064, | ||||
|     0x0065, | ||||
|     0x0066, | ||||
|     0x0067, | ||||
|     0x0068, | ||||
|     0x0069, | ||||
|     0x006a, | ||||
|     0x006b, | ||||
|     0x006c, | ||||
|     0x006d, | ||||
|     0x006e, | ||||
|     0x006f, | ||||
|     0x0070, | ||||
|     0x0071, | ||||
|     0x0072, | ||||
|     0x0073, | ||||
|     0x0074, | ||||
|     0x0075, | ||||
|     0x0076, | ||||
|     0x0077, | ||||
|     0x0078, | ||||
|     0x0079, | ||||
|     0x007a, | ||||
|     0x007b, | ||||
|     0x007c, | ||||
|     0x007d, | ||||
|     0x007e, | ||||
|     0x007f, | ||||
|     0x00c7, | ||||
|     0x00fc, | ||||
|     0x00e9, | ||||
|     0x00e2, | ||||
|     0x00e4, | ||||
|     0x00e0, | ||||
|     0x00e5, | ||||
|     0x00e7, | ||||
|     0x00ea, | ||||
|     0x00eb, | ||||
|     0x00e8, | ||||
|     0x00ef, | ||||
|     0x00ee, | ||||
|     0x00ec, | ||||
|     0x00c4, | ||||
|     0x00c5, | ||||
|     0x00c9, | ||||
|     0x00e6, | ||||
|     0x00c6, | ||||
|     0x00f4, | ||||
|     0x00f6, | ||||
|     0x00f2, | ||||
|     0x00fb, | ||||
|     0x00f9, | ||||
|     0x00ff, | ||||
|     0x00d6, | ||||
|     0x00dc, | ||||
|     0x00f8, | ||||
|     0x00a3, | ||||
|     0x00d8, | ||||
|     0x00d7, | ||||
|     0x0192, | ||||
|     0x00e1, | ||||
|     0x00ed, | ||||
|     0x00f3, | ||||
|     0x00fa, | ||||
|     0x00f1, | ||||
|     0x00d1, | ||||
|     0x00aa, | ||||
|     0x00ba, | ||||
|     0x00bf, | ||||
|     0x00ae, | ||||
|     0x00ac, | ||||
|     0x00bd, | ||||
|     0x00bc, | ||||
|     0x00a1, | ||||
|     0x00ab, | ||||
|     0x00bb, | ||||
|     0x2591, | ||||
|     0x2592, | ||||
|     0x2593, | ||||
|     0x2502, | ||||
|     0x2524, | ||||
|     0x00c1, | ||||
|     0x00c2, | ||||
|     0x00c0, | ||||
|     0x00a9, | ||||
|     0x2563, | ||||
|     0x2551, | ||||
|     0x2557, | ||||
|     0x255d, | ||||
|     0x00a2, | ||||
|     0x00a5, | ||||
|     0x2510, | ||||
|     0x2514, | ||||
|     0x2534, | ||||
|     0x252c, | ||||
|     0x251c, | ||||
|     0x2500, | ||||
|     0x253c, | ||||
|     0x00e3, | ||||
|     0x00c3, | ||||
|     0x255a, | ||||
|     0x2554, | ||||
|     0x2569, | ||||
|     0x2566, | ||||
|     0x2560, | ||||
|     0x2550, | ||||
|     0x256c, | ||||
|     0x00a4, | ||||
|     0x00f0, | ||||
|     0x00d0, | ||||
|     0x00ca, | ||||
|     0x00cb, | ||||
|     0x00c8, | ||||
|     0x0131, | ||||
|     0x00cd, | ||||
|     0x00ce, | ||||
|     0x00cf, | ||||
|     0x2518, | ||||
|     0x250c, | ||||
|     0x2588, | ||||
|     0x2584, | ||||
|     0x00a6, | ||||
|     0x00cc, | ||||
|     0x2580, | ||||
|     0x00d3, | ||||
|     0x00df, | ||||
|     0x00d4, | ||||
|     0x00d2, | ||||
|     0x00f5, | ||||
|     0x00d5, | ||||
|     0x00b5, | ||||
|     0x00fe, | ||||
|     0x00de, | ||||
|     0x00da, | ||||
|     0x00db, | ||||
|     0x00d9, | ||||
|     0x00fd, | ||||
|     0x00dd, | ||||
|     0x00af, | ||||
|     0x00b4, | ||||
|     0x00ad, | ||||
|     0x00b1, | ||||
|     0x2017, | ||||
|     0x00be, | ||||
|     0x00b6, | ||||
|     0x00a7, | ||||
|     0x00f7, | ||||
|     0x00b8, | ||||
|     0x00b0, | ||||
|     0x00a8, | ||||
|     0x00b7, | ||||
|     0x00b9, | ||||
|     0x00b3, | ||||
|     0x00b2, | ||||
|     0x25a0, | ||||
|     0x00a0 | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ | |||
| #define PACKAGE_VERSION "11" | ||||
| 
 | ||||
| /* Version in windows resource format */ | ||||
| #define PACKAGE_VERSION_RESOURCE @GUI_VERSION_MAJOR@,@GUI_VERSION_MINOR@,0,0 | ||||
| #define PACKAGE_VERSION_RESOURCE @GUI_VERSION_MAJOR@, @GUI_VERSION_MINOR@, 0, 0 | ||||
| 
 | ||||
| /* Version as a string */ | ||||
| #define PACKAGE_VERSION_RESOURCE_STR "@GUI_VERSION_MAJOR@.@GUI_VERSION_MINOR@.0.0" | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ is_comment(wchar_t *s) | |||
| } | ||||
| 
 | ||||
| static int | ||||
| copy_token(wchar_t **dest, wchar_t **src, wchar_t* delim) | ||||
| copy_token(wchar_t **dest, wchar_t **src, wchar_t *delim) | ||||
| { | ||||
|     wchar_t *p = *src; | ||||
|     wchar_t *s = *dest; | ||||
|  | @ -61,7 +61,9 @@ copy_token(wchar_t **dest, wchar_t **src, wchar_t* delim) | |||
|             return -1; /* parse error -- illegal backslash in input */ | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             *s = *p; | ||||
|         } | ||||
|     } | ||||
|     /* at this point p is one of the delimiters or null */ | ||||
|     *s = L'\0'; | ||||
|  | @ -79,9 +81,12 @@ tokenize(config_entry_t *ce) | |||
|     unsigned int i = 0; | ||||
|     int status = 0; | ||||
| 
 | ||||
|     for ( ; *p != L'\0';  p++, s++) | ||||
|     for ( ; *p != L'\0'; p++, s++) | ||||
|     { | ||||
|         if (*p == L' ' || *p == L'\t') continue; | ||||
|         if (*p == L' ' || *p == L'\t') | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (_countof(ce->tokens) <= i) | ||||
|         { | ||||
|  | @ -89,7 +94,7 @@ tokenize(config_entry_t *ce) | |||
|         } | ||||
|         ce->tokens[i++] = s; | ||||
| 
 | ||||
|         if (*p == L'\'' ) | ||||
|         if (*p == L'\'') | ||||
|         { | ||||
|             int len = wcscspn(++p, L"\'"); | ||||
|             wcsncpy(s, p, len); | ||||
|  | @ -119,7 +124,10 @@ tokenize(config_entry_t *ce) | |||
|             return status; | ||||
|         } | ||||
| 
 | ||||
|         if (*p == L'\0') break; | ||||
|         if (*p == L'\0') | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     ce->ntokens = i; | ||||
|     return 0; | ||||
|  | @ -145,8 +153,8 @@ config_readline(FILE *fd, int first) | |||
|     config_entry_t *ce = calloc(sizeof(*ce), 1); | ||||
|     if (!ce) | ||||
|     { | ||||
|        MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory in config_readline"); | ||||
|        return NULL; | ||||
|         MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory in config_readline"); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     mbstowcs(ce->line, &tmp[offset], _countof(ce->line)-1); | ||||
|  |  | |||
|  | @ -52,4 +52,4 @@ config_entry_t *config_parse(wchar_t *fname); | |||
|  */ | ||||
| void config_list_free(config_entry_t *head); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef CONFIG_PARSER_H */ | ||||
|  |  | |||
							
								
								
									
										185
									
								
								echo.c
								
								
								
								
							
							
						
						
									
										185
									
								
								echo.c
								
								
								
								
							|  | @ -80,9 +80,11 @@ echo_msg_add_fp(struct echo_msg *msg, time_t timestamp) | |||
| 
 | ||||
|     msg->fp.timestamp = timestamp; | ||||
|     if (md_init(&ctx, CALG_SHA1) != 0) | ||||
|     { | ||||
|         return; | ||||
|     md_update(&ctx, (BYTE*) msg->text, msg->txtlen*sizeof(msg->text[0])); | ||||
|     md_update(&ctx, (BYTE*) msg->title, wcslen(msg->title)*sizeof(msg->title[0])); | ||||
|     } | ||||
|     md_update(&ctx, (BYTE *) msg->text, msg->txtlen*sizeof(msg->text[0])); | ||||
|     md_update(&ctx, (BYTE *) msg->title, wcslen(msg->title)*sizeof(msg->title[0])); | ||||
|     md_final(&ctx, msg->fp.digest); | ||||
|     return; | ||||
| } | ||||
|  | @ -91,15 +93,18 @@ echo_msg_add_fp(struct echo_msg *msg, time_t timestamp) | |||
| static struct echo_msg_history * | ||||
| echo_msg_recall(const BYTE *digest, struct echo_msg_history *hist) | ||||
| { | ||||
|     for( ; hist; hist = hist->next) | ||||
|     for (; hist; hist = hist->next) | ||||
|     { | ||||
|         if (memcmp(hist->fp.digest, digest, HASHLEN) == 0) break; | ||||
|         if (memcmp(hist->fp.digest, digest, HASHLEN) == 0) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     return hist; | ||||
| } | ||||
| 
 | ||||
| /* Add an item to message history and return the head of the list */ | ||||
| static struct echo_msg_history* | ||||
| static struct echo_msg_history * | ||||
| echo_msg_history_add(struct echo_msg_history *head, const struct echo_msg_fp *fp) | ||||
| { | ||||
|     struct echo_msg_history *hist = malloc(sizeof(struct echo_msg_history)); | ||||
|  | @ -137,10 +142,15 @@ echo_msg_persist(connection_t *c) | |||
|     for (hist = c->echo_msg.history; hist; hist = hist->next) | ||||
|     { | ||||
|         len++; | ||||
|         if (len > 99) break; /* max 100 history items persisted */ | ||||
|         if (len > 99) | ||||
|         { | ||||
|             break;           /* max 100 history items persisted */ | ||||
|         } | ||||
|     } | ||||
|     if (len == 0) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     size_t size = len*sizeof(struct echo_msg_fp); | ||||
|     struct echo_msg_fp *data = malloc(size); | ||||
|  | @ -156,7 +166,9 @@ echo_msg_persist(connection_t *c) | |||
|         data[i++] = hist->fp; | ||||
|     } | ||||
|     if (!SetConfigRegistryValueBinary(c->config_name, L"echo_msg_history", (BYTE *) data, size)) | ||||
|     { | ||||
|         WriteStatusLog(c, L"GUI> ", L"Failed to persist echo msg history: error writing to registry", false); | ||||
|     } | ||||
| 
 | ||||
|     free(data); | ||||
|     return; | ||||
|  | @ -171,7 +183,9 @@ echo_msg_load(connection_t *c) | |||
| 
 | ||||
|     size_t size = GetConfigRegistryValue(c->config_name, L"echo_msg_history", NULL, 0); | ||||
|     if (size == 0) | ||||
|     { | ||||
|         return; /* no history in registry */ | ||||
|     } | ||||
|     else if (size%item_len != 0) | ||||
|     { | ||||
|         WriteStatusLog(c, L"GUI> ", L"echo msg history in registry has invalid size", false); | ||||
|  | @ -179,11 +193,13 @@ echo_msg_load(connection_t *c) | |||
|     } | ||||
| 
 | ||||
|     data = malloc(size); | ||||
|     if (!data || !GetConfigRegistryValue(c->config_name, L"echo_msg_history", (BYTE*) data, size)) | ||||
|     if (!data || !GetConfigRegistryValue(c->config_name, L"echo_msg_history", (BYTE *) data, size)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     size_t len = size/item_len; | ||||
|     for(size_t i = 0; i < len; i++) | ||||
|     for (size_t i = 0; i < len; i++) | ||||
|     { | ||||
|         c->echo_msg.history = echo_msg_history_add(c->echo_msg.history, &data[i]); | ||||
|     } | ||||
|  | @ -255,7 +271,7 @@ echo_msg_display(connection_t *c, time_t timestamp, const char *title, int type) | |||
|     } | ||||
|     echo_msg_add_fp(&c->echo_msg, timestamp); /* add fingerprint: digest+timestamp */ | ||||
| 
 | ||||
|      /* Check whether the message is muted */ | ||||
|     /* Check whether the message is muted */ | ||||
|     if (c->flags & FLAG_DISABLE_ECHO_MSG || echo_msg_repeated(&c->echo_msg)) | ||||
|     { | ||||
|         return; | ||||
|  | @ -356,7 +372,9 @@ static wchar_t * | |||
| get_text_in_range(HWND h, CHARRANGE chrg) | ||||
| { | ||||
|     if (chrg.cpMax <= chrg.cpMin) | ||||
| 	return NULL; | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     size_t len = chrg.cpMax - chrg.cpMin; | ||||
|     wchar_t *txt = malloc((len + 1)*sizeof(wchar_t)); | ||||
|  | @ -365,9 +383,13 @@ get_text_in_range(HWND h, CHARRANGE chrg) | |||
|     { | ||||
|         TEXTRANGEW txtrg = {chrg, txt}; | ||||
|         if (SendMessage(h, EM_GETTEXTRANGE, 0, (LPARAM)&txtrg) <= 0) | ||||
|         { | ||||
|             txt[0] = '\0'; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             txt[len] = '\0'; /* safety */ | ||||
|         } | ||||
|     } | ||||
|     return txt; | ||||
| } | ||||
|  | @ -392,7 +414,9 @@ OnEnLinkNotify(HWND UNUSED hwnd, ENLINK *el) | |||
|         /* get the link text */ | ||||
|         wchar_t *url = get_text_in_range(el->nmhdr.hwndFrom, el->chrg); | ||||
|         if (url) | ||||
|         { | ||||
|             open_url(url); | ||||
|         } | ||||
|         free(url); | ||||
|         return 1; | ||||
|     } | ||||
|  | @ -431,7 +455,7 @@ AddMessageBoxText(HWND hwnd, const wchar_t *text, const wchar_t *title, const wc | |||
|         cfm.dwEffects |= CFE_ITALIC; | ||||
| 
 | ||||
|         SendMessage(hmsg, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfm); | ||||
|        /* Align to right */ | ||||
|         /* Align to right */ | ||||
|         pf.wAlignment = align[1]; | ||||
|         SendMessage(hmsg, EM_SETPARAFORMAT, 0, (LPARAM) &pf); | ||||
|         SendMessage(hmsg, EM_REPLACESEL, FALSE, (LPARAM) from); | ||||
|  | @ -500,69 +524,70 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) | |||
| 
 | ||||
|     switch (msg) | ||||
|     { | ||||
|     case WM_INITDIALOG: | ||||
|         hIcon = LoadLocalizedIcon(ID_ICO_APP); | ||||
|         if (hIcon) { | ||||
|             SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); | ||||
|             SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); | ||||
|         } | ||||
|         hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); | ||||
|         SetWindowText(hwnd, L"OpenVPN Messages"); | ||||
|         SendMessage(hmsg, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, | ||||
|                          MAKELPARAM(side_margin, side_margin)); | ||||
|         if (LangFlowDirection() == 1) | ||||
|         { | ||||
|             LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); | ||||
|             SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | WS_EX_RTLREADING | WS_EX_LAYOUTRTL); | ||||
|             exstyle = GetWindowLong(hmsg, GWL_EXSTYLE); | ||||
|             SetWindowLong(hmsg, GWL_EXSTYLE, exstyle | WS_EX_LEFTSCROLLBAR); | ||||
| 	} | ||||
| 
 | ||||
|         enable_url_detection(hmsg); | ||||
| 
 | ||||
|         /* Position the window close to top right corner of the screen */ | ||||
|         RECT rc; | ||||
|         GetWindowRect(hwnd, &rc); | ||||
|         OffsetRect(&rc, -rc.left, -rc.top); | ||||
|         int ox = GetSystemMetrics(SM_CXSCREEN); /* screen size along x */ | ||||
|         ox -= rc.right + DPI_SCALE(rand()%50 + 25); | ||||
|         int oy = DPI_SCALE(rand()%50 + 25); | ||||
|         SetWindowPos(hwnd, HWND_TOP, ox > 0 ? ox:0, oy, 0, 0, SWP_NOSIZE); | ||||
| 
 | ||||
|         return TRUE; | ||||
| 
 | ||||
|     case WM_SIZE: | ||||
|         hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); | ||||
|         /* leave some space as top margin */ | ||||
|         SetWindowPos(hmsg, NULL, 0, top_margin, LOWORD(lParam), HIWORD(lParam)-top_margin, 0); | ||||
|         InvalidateRect(hwnd, NULL, TRUE); | ||||
|         break; | ||||
| 
 | ||||
|     /* set the whole client area background to white */ | ||||
|     case WM_CTLCOLORDLG: | ||||
|     case WM_CTLCOLORSTATIC: | ||||
|         return (INT_PTR) GetStockObject(WHITE_BRUSH); | ||||
|         break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         if (LOWORD(wParam) == ID_TXT_MESSAGE) | ||||
|         { | ||||
|             /* The caret is distracting in a readonly msg box: hide it when we get focus */ | ||||
|             if (HIWORD(wParam) == EN_SETFOCUS) | ||||
|         case WM_INITDIALOG: | ||||
|             hIcon = LoadLocalizedIcon(ID_ICO_APP); | ||||
|             if (hIcon) | ||||
|             { | ||||
|                 HideCaret((HWND)lParam); | ||||
|                 SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); | ||||
|                 SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); | ||||
|             } | ||||
|             else if (HIWORD(wParam) == EN_KILLFOCUS) | ||||
|             hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); | ||||
|             SetWindowText(hwnd, L"OpenVPN Messages"); | ||||
|             SendMessage(hmsg, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, | ||||
|                         MAKELPARAM(side_margin, side_margin)); | ||||
|             if (LangFlowDirection() == 1) | ||||
|             { | ||||
|                 ShowCaret((HWND)lParam); | ||||
|                 LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); | ||||
|                 SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | WS_EX_RTLREADING | WS_EX_LAYOUTRTL); | ||||
|                 exstyle = GetWindowLong(hmsg, GWL_EXSTYLE); | ||||
|                 SetWindowLong(hmsg, GWL_EXSTYLE, exstyle | WS_EX_LEFTSCROLLBAR); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     /* Must be sent with lParam = connection pointer
 | ||||
|      * Adds the current echo message and shows the window. | ||||
|      */ | ||||
|     case WM_OVPN_ECHOMSG: | ||||
|             enable_url_detection(hmsg); | ||||
| 
 | ||||
|             /* Position the window close to top right corner of the screen */ | ||||
|             RECT rc; | ||||
|             GetWindowRect(hwnd, &rc); | ||||
|             OffsetRect(&rc, -rc.left, -rc.top); | ||||
|             int ox = GetSystemMetrics(SM_CXSCREEN); /* screen size along x */ | ||||
|             ox -= rc.right + DPI_SCALE(rand()%50 + 25); | ||||
|             int oy = DPI_SCALE(rand()%50 + 25); | ||||
|             SetWindowPos(hwnd, HWND_TOP, ox > 0 ? ox : 0, oy, 0, 0, SWP_NOSIZE); | ||||
| 
 | ||||
|             return TRUE; | ||||
| 
 | ||||
|         case WM_SIZE: | ||||
|             hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); | ||||
|             /* leave some space as top margin */ | ||||
|             SetWindowPos(hmsg, NULL, 0, top_margin, LOWORD(lParam), HIWORD(lParam)-top_margin, 0); | ||||
|             InvalidateRect(hwnd, NULL, TRUE); | ||||
|             break; | ||||
| 
 | ||||
|         /* set the whole client area background to white */ | ||||
|         case WM_CTLCOLORDLG: | ||||
|         case WM_CTLCOLORSTATIC: | ||||
|             return (INT_PTR) GetStockObject(WHITE_BRUSH); | ||||
|             break; | ||||
| 
 | ||||
|         case WM_COMMAND: | ||||
|             if (LOWORD(wParam) == ID_TXT_MESSAGE) | ||||
|             { | ||||
|                 /* The caret is distracting in a readonly msg box: hide it when we get focus */ | ||||
|                 if (HIWORD(wParam) == EN_SETFOCUS) | ||||
|                 { | ||||
|                     HideCaret((HWND)lParam); | ||||
|                 } | ||||
|                 else if (HIWORD(wParam) == EN_KILLFOCUS) | ||||
|                 { | ||||
|                     ShowCaret((HWND)lParam); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         /* Must be sent with lParam = connection pointer
 | ||||
|          * Adds the current echo message and shows the window. | ||||
|          */ | ||||
|         case WM_OVPN_ECHOMSG: | ||||
|         { | ||||
|             connection_t *c = (connection_t *) lParam; | ||||
|             wchar_t from[256]; | ||||
|  | @ -570,7 +595,9 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) | |||
| 
 | ||||
|             /* strip \n added by _wctime */ | ||||
|             if (wcslen(from) > 0) | ||||
|             { | ||||
|                 from[wcslen(from)-1] = L'\0'; | ||||
|             } | ||||
| 
 | ||||
|             AddMessageBoxText(hwnd, c->echo_msg.text, c->echo_msg.title, from); | ||||
|             SetForegroundWindow(hwnd); | ||||
|  | @ -578,16 +605,18 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) | |||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case WM_NOTIFY: | ||||
|         nmh = (NMHDR*) lParam; | ||||
|         /* We handle only EN_LINK messages */ | ||||
|         if (nmh->idFrom == ID_TXT_MESSAGE && nmh->code == EN_LINK) | ||||
|             return OnEnLinkNotify(hwnd, (ENLINK*)lParam); | ||||
|         break; | ||||
|         case WM_NOTIFY: | ||||
|             nmh = (NMHDR *) lParam; | ||||
|             /* We handle only EN_LINK messages */ | ||||
|             if (nmh->idFrom == ID_TXT_MESSAGE && nmh->code == EN_LINK) | ||||
|             { | ||||
|                 return OnEnLinkNotify(hwnd, (ENLINK *)lParam); | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|     case WM_CLOSE: | ||||
|         ShowWindow(hwnd, SW_HIDE); | ||||
|         return TRUE; | ||||
|         case WM_CLOSE: | ||||
|             ShowWindow(hwnd, SW_HIDE); | ||||
|             return TRUE; | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
|  |  | |||
							
								
								
									
										2
									
								
								echo.h
								
								
								
								
							
							
						
						
									
										2
									
								
								echo.h
								
								
								
								
							|  | @ -54,4 +54,4 @@ void echo_msg_clear(connection_t *c, BOOL clear_history); | |||
| /* Load echo msg history from the registry */ | ||||
| void echo_msg_load(connection_t *c); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef ECHO_H */ | ||||
|  |  | |||
							
								
								
									
										26
									
								
								env_set.c
								
								
								
								
							
							
						
						
									
										26
									
								
								env_set.c
								
								
								
								
							|  | @ -94,7 +94,10 @@ env_item_del(struct env_item *head, const wchar_t *name) | |||
| { | ||||
|     struct env_item *item, *prev = NULL; | ||||
| 
 | ||||
|     if (!name) return head; | ||||
|     if (!name) | ||||
|     { | ||||
|         return head; | ||||
|     } | ||||
| 
 | ||||
|     for (item = head; item; item = item->next) | ||||
|     { | ||||
|  | @ -102,9 +105,13 @@ env_item_del(struct env_item *head, const wchar_t *name) | |||
|         { | ||||
|             /* matching item found */ | ||||
|             if (prev) | ||||
|             { | ||||
|                 prev->next = item->next; | ||||
|             } | ||||
|             else /* head is going to be deleted */ | ||||
|             { | ||||
|                 head = item->next; | ||||
|             } | ||||
|             env_item_free(item); | ||||
|             break; | ||||
|         } | ||||
|  | @ -132,7 +139,7 @@ env_item_insert(struct env_item *head, struct env_item *item) | |||
|         cmp = env_name_compare(item->nameval, tmp->nameval); | ||||
|         if (cmp <= 0) /* found the position to add */ | ||||
|         { | ||||
|              break; | ||||
|             break; | ||||
|         } | ||||
|         prev = tmp; | ||||
|         continue; | ||||
|  | @ -148,9 +155,13 @@ env_item_insert(struct env_item *head, struct env_item *item) | |||
|     } | ||||
| 
 | ||||
|     if (prev) | ||||
|     { | ||||
|         prev->next = item; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         head = item; | ||||
|     } | ||||
| 
 | ||||
|     return head; | ||||
| } | ||||
|  | @ -194,13 +205,15 @@ env_item_new_utf8(const char *nameval) | |||
| /* Insert an env item to the set given nameval: name=val.
 | ||||
|  * Returns new head of the list. | ||||
|  */ | ||||
| static struct env_item* | ||||
| static struct env_item * | ||||
| env_item_insert_utf8(struct env_item *head, const char *nameval) | ||||
| { | ||||
|     struct env_item *item = env_item_new_utf8(nameval); | ||||
| 
 | ||||
|     if (!item) | ||||
|     { | ||||
|         return head; | ||||
|     } | ||||
| 
 | ||||
|     return env_item_insert(head, item); | ||||
| } | ||||
|  | @ -247,11 +260,10 @@ merge_env_block(const struct env_item *es) | |||
| 
 | ||||
|     for (pe = e; *pe; pe += wcslen(pe)+1) | ||||
|     { | ||||
|        ; | ||||
|     } | ||||
|     len = (pe + 1 - e); /* including the extra '\0' at the end */ | ||||
| 
 | ||||
|     for(item = es; item; item = item->next) | ||||
|     for (item = es; item; item = item->next) | ||||
|     { | ||||
|         len += wcslen(item->nameval) + 1; | ||||
|     } | ||||
|  | @ -291,7 +303,9 @@ merge_env_block(const struct env_item *es) | |||
|         { | ||||
|             pe += len; | ||||
|             if (*pe) /* update len */ | ||||
|             { | ||||
|                 len = wcslen(pe) + 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /* Add any remaining entries -- either item or *pe is NULL at this point.
 | ||||
|  | @ -326,7 +340,9 @@ process_setenv(connection_t *c, UNUSED time_t timestamp, const char *msg) | |||
|     char *nameval; | ||||
| 
 | ||||
|     if (!strbegins(msg, "setenv ")) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     msg += strlen("setenv ");    /* character following "setenv" */ | ||||
|     msg += strspn(msg, " \t");   /* skip leading space */ | ||||
|  |  | |||
|  | @ -41,6 +41,6 @@ void process_setenv(connection_t *c, time_t timestamp, const char *msg); | |||
|  * as the env block or NULL on error. The caller must free the returned | ||||
|  * pointer. | ||||
|  */ | ||||
| wchar_t * merge_env_block(const struct env_item *es); | ||||
| wchar_t *merge_env_block(const struct env_item *es); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										337
									
								
								localization.c
								
								
								
								
							
							
						
						
									
										337
									
								
								localization.c
								
								
								
								
							|  | @ -52,18 +52,24 @@ FindResourceLang(PTSTR resType, PTSTR resId, LANGID langId) | |||
|     /* try to find the resource in requested language */ | ||||
|     res = FindResourceEx(o.hInstance, resType, resId, langId); | ||||
|     if (res) | ||||
|     { | ||||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     /* try to find the resource in the default sublanguage */ | ||||
|     LANGID defLangId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_DEFAULT); | ||||
|     res = FindResourceEx(o.hInstance, resType, resId, defLangId); | ||||
|     if (res) | ||||
|     { | ||||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     /* try to find the resource in the default language */ | ||||
|     res = FindResourceEx(o.hInstance, resType, resId, fallbackLangId); | ||||
|     if (res) | ||||
|     { | ||||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     /* try to find the resource in any language */ | ||||
|     return FindResource(o.hInstance, resId, resType); | ||||
|  | @ -90,7 +96,9 @@ LANGID | |||
| GetGUILanguage(void) | ||||
| { | ||||
|     if (gui_language != 0) | ||||
|     { | ||||
|         return gui_language; | ||||
|     } | ||||
| 
 | ||||
|     HKEY regkey; | ||||
|     DWORD value = 0; | ||||
|  | @ -113,8 +121,10 @@ SetGUILanguage(LANGID langId) | |||
| { | ||||
|     HKEY regkey; | ||||
|     if (RegCreateKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, NULL, 0, | ||||
|         KEY_WRITE, NULL, ®key, NULL) != ERROR_SUCCESS ) | ||||
|                        KEY_WRITE, NULL, ®key, NULL) != ERROR_SUCCESS) | ||||
|     { | ||||
|         ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); | ||||
|     } | ||||
| 
 | ||||
|     SetRegistryValueNumeric(regkey, _T("ui_language"), langId); | ||||
|     InitMUILanguage(langId); | ||||
|  | @ -197,12 +207,16 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li | |||
|     /* find resource block for string */ | ||||
|     HRSRC res = FindResourceLang(RT_STRING, resBlockId, langId); | ||||
|     if (res == NULL) | ||||
|     { | ||||
|         goto err; | ||||
|     } | ||||
| 
 | ||||
|     /* get pointer to first entry in resource block */ | ||||
|     entry = (PWCH) LoadResource(o.hInstance, res); | ||||
|     if (entry == NULL) | ||||
|     { | ||||
|         goto err; | ||||
|     } | ||||
| 
 | ||||
|     /* search for string in block */ | ||||
|     for (int i = 0; i < 16; i++) | ||||
|  | @ -216,12 +230,16 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li | |||
| 
 | ||||
|         /* string does not exist */ | ||||
|         if (i == resIndex && *entry == 0) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         /* string found, copy it */ | ||||
|         PTSTR formatStr = (PTSTR) malloc((*entry + 1) * sizeof(TCHAR)); | ||||
|         if (formatStr == NULL) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|         formatStr[*entry] = 0; | ||||
| 
 | ||||
|         wcsncpy(formatStr, entry + 1, *entry); | ||||
|  | @ -234,7 +252,9 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li | |||
| err: | ||||
|     /* not found, try again with the default language */ | ||||
|     if (langId != fallbackLangId) | ||||
|     { | ||||
|         return LoadStringLang(stringId, fallbackLangId, buffer, bufferSize, args); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
|  | @ -276,7 +296,7 @@ static int | |||
| __ShowLocalizedMsgEx(const UINT type, HANDLE parent, LPCTSTR caption, const UINT stringId, va_list args) | ||||
| { | ||||
|     return MessageBoxEx(parent, __LoadLocalizedString(stringId, args), caption, | ||||
|         type | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); | ||||
|                         type | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -305,12 +325,16 @@ LoadLocalizedIconEx(const UINT iconId, int cxDesired, int cyDesired) | |||
|     LANGID langId = GetGUILanguage(); | ||||
| 
 | ||||
|     HICON hIcon = | ||||
|             (HICON) LoadImage (o.hInstance, MAKEINTRESOURCE(iconId), | ||||
|                     IMAGE_ICON, cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); | ||||
|         (HICON) LoadImage(o.hInstance, MAKEINTRESOURCE(iconId), | ||||
|                           IMAGE_ICON, cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); | ||||
|     if (hIcon) | ||||
|     { | ||||
|         return hIcon; | ||||
|     } | ||||
|     else | ||||
|         PrintDebug (L"Loading icon using LoadImage failed."); | ||||
|     { | ||||
|         PrintDebug(L"Loading icon using LoadImage failed."); | ||||
|     } | ||||
| 
 | ||||
|     /* Fallback to CreateIconFromResource which always scales
 | ||||
|      * from the first image in the resource | ||||
|  | @ -318,51 +342,63 @@ LoadLocalizedIconEx(const UINT iconId, int cxDesired, int cyDesired) | |||
|     /* find group icon resource */ | ||||
|     HRSRC res = FindResourceLang(RT_GROUP_ICON, MAKEINTRESOURCE(iconId), langId); | ||||
|     if (res == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     HGLOBAL resInfo = LoadResource(o.hInstance, res); | ||||
|     if (resInfo == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     int id = LookupIconIdFromDirectory(resInfo, TRUE); | ||||
|     if (id == 0) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     /* find the actual icon */ | ||||
|     res = FindResourceLang(RT_ICON, MAKEINTRESOURCE(id), langId); | ||||
|     if (res == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     resInfo = LoadResource(o.hInstance, res); | ||||
|     if (resInfo == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     DWORD resSize = SizeofResource(o.hInstance, res); | ||||
|     if (resSize == 0) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     /* Note: this uses the first icon in the resource and scales it */ | ||||
|     hIcon = CreateIconFromResourceEx(resInfo, resSize, TRUE, 0x30000, | ||||
|             cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); | ||||
|                                      cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); | ||||
|     return hIcon; | ||||
| } | ||||
| 
 | ||||
| HICON | ||||
| LoadLocalizedIcon(const UINT iconId) | ||||
| { | ||||
|    /* get the required normal icon size (e.g., taskbar icon) */ | ||||
|    int cx = GetSystemMetrics(SM_CXICON); | ||||
|    int cy = GetSystemMetrics(SM_CYICON); | ||||
|    return LoadLocalizedIconEx(iconId, cx, cy); | ||||
|     /* get the required normal icon size (e.g., taskbar icon) */ | ||||
|     int cx = GetSystemMetrics(SM_CXICON); | ||||
|     int cy = GetSystemMetrics(SM_CYICON); | ||||
|     return LoadLocalizedIconEx(iconId, cx, cy); | ||||
| } | ||||
| 
 | ||||
| HICON | ||||
| LoadLocalizedSmallIcon(const UINT iconId) | ||||
| { | ||||
|    /* get the required small icon size (e.g., tray icon) */ | ||||
|    int cx = GetSystemMetrics(SM_CXSMICON); | ||||
|    int cy = GetSystemMetrics(SM_CYSMICON); | ||||
|    return LoadLocalizedIconEx(iconId, cx, cy); | ||||
|     /* get the required small icon size (e.g., tray icon) */ | ||||
|     int cx = GetSystemMetrics(SM_CXSMICON); | ||||
|     int cy = GetSystemMetrics(SM_CYSMICON); | ||||
|     return LoadLocalizedIconEx(iconId, cx, cy); | ||||
| } | ||||
| 
 | ||||
| LPCDLGTEMPLATE | ||||
|  | @ -371,7 +407,9 @@ LocalizedDialogResource(const UINT dialogId) | |||
|     /* find dialog resource */ | ||||
|     HRSRC res = FindResourceLang(RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); | ||||
|     if (res == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     return LoadResource(o.hInstance, res); | ||||
| } | ||||
|  | @ -388,7 +426,9 @@ LocalizedDialogBoxParamEx(const UINT dialogId, HWND owner, DLGPROC dialogFunc, c | |||
| { | ||||
|     LPCDLGTEMPLATE resInfo = LocalizedDialogResource(dialogId); | ||||
|     if (resInfo == NULL) | ||||
|     { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     return DialogBoxIndirectParam(o.hInstance, resInfo, owner, dialogFunc, param); | ||||
| } | ||||
|  | @ -399,11 +439,15 @@ CreateLocalizedDialogParam(const UINT dialogId, DLGPROC dialogFunc, const LPARAM | |||
|     /* find dialog resource */ | ||||
|     HRSRC res = FindResourceLang(RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); | ||||
|     if (res == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     HGLOBAL resInfo = LoadResource(o.hInstance, res); | ||||
|     if (resInfo == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     return CreateDialogIndirectParam(o.hInstance, resInfo, o.hWnd, dialogFunc, param); | ||||
| } | ||||
|  | @ -438,59 +482,71 @@ typedef struct { | |||
| static BOOL | ||||
| FillLangListProc(UNUSED HANDLE module, UNUSED PTSTR type, UNUSED PTSTR stringId, WORD langId, LONG_PTR lParam) | ||||
| { | ||||
|     langProcData *data = (langProcData*) lParam; | ||||
|     langProcData *data = (langProcData *) lParam; | ||||
| 
 | ||||
|     int index = ComboBox_AddString(data->languages, LangListEntry(IDS_LANGUAGE_NAME, langId)); | ||||
|     ComboBox_SetItemData(data->languages, index, langId); | ||||
| 
 | ||||
|     /* Select this item if it is the currently displayed language */ | ||||
|     if (langId == data->language | ||||
|     ||  (PRIMARYLANGID(langId) == PRIMARYLANGID(data->language) | ||||
|      && ComboBox_GetCurSel(data->languages) == CB_ERR) ) | ||||
|         ||  (PRIMARYLANGID(langId) == PRIMARYLANGID(data->language) | ||||
|              && ComboBox_GetCurSel(data->languages) == CB_ERR) ) | ||||
|     { | ||||
|         ComboBox_SetCurSel(data->languages, index); | ||||
|     } | ||||
| 
 | ||||
|     return TRUE; | ||||
| } | ||||
| 
 | ||||
| static BOOL  | ||||
| static BOOL | ||||
| GetLaunchOnStartup() | ||||
| { | ||||
| 	 | ||||
|     WCHAR regPath[MAX_PATH], exePath[MAX_PATH];	 | ||||
| 
 | ||||
|     WCHAR regPath[MAX_PATH], exePath[MAX_PATH]; | ||||
|     BOOL result = FALSE; | ||||
|     HKEY regkey; | ||||
| 
 | ||||
|     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, ®key) == ERROR_SUCCESS) { | ||||
|     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, ®key) == ERROR_SUCCESS) | ||||
|     { | ||||
| 
 | ||||
|         if (GetRegistryValue(regkey, L"OpenVPN-GUI", regPath, MAX_PATH) && | ||||
|             GetModuleFileNameW(NULL, exePath, MAX_PATH)) { | ||||
|         if (GetRegistryValue(regkey, L"OpenVPN-GUI", regPath, MAX_PATH) | ||||
|             && GetModuleFileNameW(NULL, exePath, MAX_PATH)) | ||||
|         { | ||||
|             if (_wcsicmp(regPath, exePath) == 0) | ||||
|             { | ||||
|                 result = TRUE; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         RegCloseKey(regkey); | ||||
| 
 | ||||
|     } | ||||
| 	 | ||||
| 
 | ||||
|     return result; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| SetLaunchOnStartup(BOOL value)  | ||||
| SetLaunchOnStartup(BOOL value) | ||||
| { | ||||
| 
 | ||||
|     WCHAR exePath[MAX_PATH]; | ||||
|     HKEY regkey; | ||||
| 
 | ||||
|     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, ®key) == ERROR_SUCCESS) { | ||||
|     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, ®key) == ERROR_SUCCESS) | ||||
|     { | ||||
| 
 | ||||
|         if (value) { | ||||
|             if (GetModuleFileNameW(NULL, exePath, MAX_PATH))  | ||||
|         if (value) | ||||
|         { | ||||
|             if (GetModuleFileNameW(NULL, exePath, MAX_PATH)) | ||||
|             { | ||||
|                 SetRegistryValue(regkey, L"OpenVPN-GUI", exePath); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             RegDeleteValue(regkey, L"OpenVPN-GUI"); | ||||
|         } | ||||
|         else  | ||||
|             RegDeleteValue(regkey, L"OpenVPN-GUI");             | ||||
| 
 | ||||
|         RegCloseKey(regkey); | ||||
| 
 | ||||
|  | @ -507,108 +563,155 @@ GeneralSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lPar | |||
|         .language = GetGUILanguage() | ||||
|     }; | ||||
| 
 | ||||
|     switch(msg) { | ||||
|     switch (msg) | ||||
|     { | ||||
| 
 | ||||
|     case WM_INITDIALOG: | ||||
|         /* Populate UI language selection combo box */ | ||||
|         EnumResourceLanguages( NULL, RT_STRING, MAKEINTRESOURCE(IDS_LANGUAGE_NAME / 16 + 1), | ||||
|             (ENUMRESLANGPROC) FillLangListProc, (LONG_PTR) &langData ); | ||||
|         case WM_INITDIALOG: | ||||
|             /* Populate UI language selection combo box */ | ||||
|             EnumResourceLanguages( NULL, RT_STRING, MAKEINTRESOURCE(IDS_LANGUAGE_NAME / 16 + 1), | ||||
|                                    (ENUMRESLANGPROC) FillLangListProc, (LONG_PTR) &langData ); | ||||
| 
 | ||||
|         /* If none of the available languages matched, select the fallback */ | ||||
|         if (ComboBox_GetCurSel(langData.languages) == CB_ERR) | ||||
|             ComboBox_SelectString(langData.languages, -1, | ||||
|                 LangListEntry(IDS_LANGUAGE_NAME, fallbackLangId)); | ||||
|             /* If none of the available languages matched, select the fallback */ | ||||
|             if (ComboBox_GetCurSel(langData.languages) == CB_ERR) | ||||
|             { | ||||
|                 ComboBox_SelectString(langData.languages, -1, | ||||
|                                       LangListEntry(IDS_LANGUAGE_NAME, fallbackLangId)); | ||||
|             } | ||||
| 
 | ||||
|         /* Clear language id data for the selected item */ | ||||
|         ComboBox_SetItemData(langData.languages, ComboBox_GetCurSel(langData.languages), 0); | ||||
|             /* Clear language id data for the selected item */ | ||||
|             ComboBox_SetItemData(langData.languages, ComboBox_GetCurSel(langData.languages), 0); | ||||
| 
 | ||||
|         if (GetLaunchOnStartup()) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP), BST_CHECKED); | ||||
|             if (GetLaunchOnStartup()) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP), BST_CHECKED); | ||||
|             } | ||||
| 
 | ||||
|         if (o.log_append) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND), BST_CHECKED); | ||||
|         if (o.silent_connection) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT), BST_CHECKED); | ||||
|         if (o.iservice_admin) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE), BST_CHECKED); | ||||
|         if (o.show_balloon == 0) | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); | ||||
|         else if (o.show_balloon == 1) | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); | ||||
|         else if (o.show_balloon == 2) | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); | ||||
|         if (o.show_script_window) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN), BST_CHECKED); | ||||
|         if (o.enable_persistent == 0) /* Never */ | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON5); | ||||
|         else if (o.enable_persistent == 1) /* Enabled, but no auto-attach */ | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON4); | ||||
|         else if (o.enable_persistent == 2) /* Enabled and auto-attach */ | ||||
|             CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON3); | ||||
|             if (o.log_append) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND), BST_CHECKED); | ||||
|             } | ||||
|             if (o.silent_connection) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT), BST_CHECKED); | ||||
|             } | ||||
|             if (o.iservice_admin) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE), BST_CHECKED); | ||||
|             } | ||||
|             if (o.show_balloon == 0) | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); | ||||
|             } | ||||
|             else if (o.show_balloon == 1) | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); | ||||
|             } | ||||
|             else if (o.show_balloon == 2) | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); | ||||
|             } | ||||
|             if (o.show_script_window) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN), BST_CHECKED); | ||||
|             } | ||||
|             if (o.enable_persistent == 0) /* Never */ | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON5); | ||||
|             } | ||||
|             else if (o.enable_persistent == 1) /* Enabled, but no auto-attach */ | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON4); | ||||
|             } | ||||
|             else if (o.enable_persistent == 2) /* Enabled and auto-attach */ | ||||
|             { | ||||
|                 CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON3); | ||||
|             } | ||||
| 
 | ||||
|         int plap_status = GetPLAPRegistrationStatus(); | ||||
|         if (plap_status == -1) /* PLAP not supported in this version */ | ||||
|             ShowWindow(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), SW_HIDE); | ||||
|         else if (plap_status != 0) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), BST_CHECKED); | ||||
|         if (o.enable_auto_restart) | ||||
|             Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART), BST_CHECKED); | ||||
|             int plap_status = GetPLAPRegistrationStatus(); | ||||
|             if (plap_status == -1) /* PLAP not supported in this version */ | ||||
|             { | ||||
|                 ShowWindow(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), SW_HIDE); | ||||
|             } | ||||
|             else if (plap_status != 0) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), BST_CHECKED); | ||||
|             } | ||||
|             if (o.enable_auto_restart) | ||||
|             { | ||||
|                 Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART), BST_CHECKED); | ||||
|             } | ||||
| 
 | ||||
|         break; | ||||
|             break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         if (LOWORD(wParam) == ID_CHK_PLAP_REG && HIWORD(wParam) == BN_CLICKED) | ||||
|         { | ||||
|             /* change PLAPRegistration state */ | ||||
|             HWND h = GetDlgItem(hwndDlg, ID_CHK_PLAP_REG); | ||||
|             BOOL newstate = Button_GetCheck(h) == BST_CHECKED ?  TRUE : FALSE; | ||||
|             if (SetPLAPRegistration(newstate) != 0) /* failed or user cancelled -- reset checkmark */ | ||||
|                 Button_SetCheck(h, newstate  ? BST_UNCHECKED : BST_CHECKED); | ||||
|         } | ||||
|         break; | ||||
|         case WM_COMMAND: | ||||
|             if (LOWORD(wParam) == ID_CHK_PLAP_REG && HIWORD(wParam) == BN_CLICKED) | ||||
|             { | ||||
|                 /* change PLAPRegistration state */ | ||||
|                 HWND h = GetDlgItem(hwndDlg, ID_CHK_PLAP_REG); | ||||
|                 BOOL newstate = Button_GetCheck(h) == BST_CHECKED ?  TRUE : FALSE; | ||||
|                 if (SetPLAPRegistration(newstate) != 0) /* failed or user cancelled -- reset checkmark */ | ||||
|                 { | ||||
|                     Button_SetCheck(h, newstate  ? BST_UNCHECKED : BST_CHECKED); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|     case WM_NOTIFY: | ||||
|         psn = (LPPSHNOTIFY) lParam; | ||||
|         if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|         { | ||||
|             LANGID langId = (LANGID) ComboBox_GetItemData(langData.languages, | ||||
|                 ComboBox_GetCurSel(langData.languages)); | ||||
|         case WM_NOTIFY: | ||||
|             psn = (LPPSHNOTIFY) lParam; | ||||
|             if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|             { | ||||
|                 LANGID langId = (LANGID) ComboBox_GetItemData(langData.languages, | ||||
|                                                               ComboBox_GetCurSel(langData.languages)); | ||||
| 
 | ||||
|             if (langId != 0) | ||||
|                 SetGUILanguage(langId); | ||||
|                 if (langId != 0) | ||||
|                 { | ||||
|                     SetGUILanguage(langId); | ||||
|                 } | ||||
| 
 | ||||
|             SetLaunchOnStartup(Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP)) == BST_CHECKED); | ||||
|                 SetLaunchOnStartup(Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP)) == BST_CHECKED); | ||||
| 
 | ||||
|             o.log_append = | ||||
|                 (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND)) == BST_CHECKED); | ||||
|             o.silent_connection = | ||||
|                 (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT)) == BST_CHECKED); | ||||
|             o.iservice_admin = | ||||
|                 (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE)) == BST_CHECKED); | ||||
|             if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) | ||||
|                 o.show_balloon = 0; | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) | ||||
|                 o.show_balloon = 2; | ||||
|             else | ||||
|                 o.show_balloon = 1; | ||||
|             if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) | ||||
|                 o.enable_persistent = 2; | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) | ||||
|                 o.enable_persistent = 1; | ||||
|             else | ||||
|                 o.enable_persistent = 0; | ||||
|             o.show_script_window = | ||||
|                 (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN)) == BST_CHECKED); | ||||
|             o.enable_auto_restart = | ||||
|                 (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART)) == BST_CHECKED); | ||||
|                 o.log_append = | ||||
|                     (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND)) == BST_CHECKED); | ||||
|                 o.silent_connection = | ||||
|                     (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT)) == BST_CHECKED); | ||||
|                 o.iservice_admin = | ||||
|                     (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE)) == BST_CHECKED); | ||||
|                 if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) | ||||
|                 { | ||||
|                     o.show_balloon = 0; | ||||
|                 } | ||||
|                 else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) | ||||
|                 { | ||||
|                     o.show_balloon = 2; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     o.show_balloon = 1; | ||||
|                 } | ||||
|                 if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) | ||||
|                 { | ||||
|                     o.enable_persistent = 2; | ||||
|                 } | ||||
|                 else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) | ||||
|                 { | ||||
|                     o.enable_persistent = 1; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     o.enable_persistent = 0; | ||||
|                 } | ||||
|                 o.show_script_window = | ||||
|                     (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN)) == BST_CHECKED); | ||||
|                 o.enable_auto_restart = | ||||
|                     (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART)) == BST_CHECKED); | ||||
| 
 | ||||
| 
 | ||||
|             SaveRegistryKeys(); | ||||
|                 SaveRegistryKeys(); | ||||
| 
 | ||||
|             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); | ||||
|             return TRUE; | ||||
|         } | ||||
|         break; | ||||
|                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); | ||||
|                 return TRUE; | ||||
|             } | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     return FALSE; | ||||
|  |  | |||
|  | @ -23,26 +23,43 @@ | |||
| #define LOCALIZATION_H | ||||
| 
 | ||||
| int LocalizedTime(const time_t, LPTSTR, size_t); | ||||
| 
 | ||||
| wchar_t *LocalizedFileTime(const FILETIME *ft); | ||||
| 
 | ||||
| PTSTR LoadLocalizedString(const UINT, ...); | ||||
| 
 | ||||
| int LoadLocalizedStringBuf(PTSTR, const int, const UINT, ...); | ||||
| 
 | ||||
| void ShowLocalizedMsg(const UINT, ...); | ||||
| 
 | ||||
| int ShowLocalizedMsgEx(const UINT, HANDLE, LPCTSTR, const UINT, ...); | ||||
| 
 | ||||
| HICON LoadLocalizedIconEx(const UINT, int cx, int cy); | ||||
| 
 | ||||
| HICON LoadLocalizedIcon(const UINT); | ||||
| 
 | ||||
| HICON LoadLocalizedSmallIcon(const UINT); | ||||
| 
 | ||||
| LPCDLGTEMPLATE LocalizedDialogResource(const UINT); | ||||
| 
 | ||||
| INT_PTR LocalizedDialogBoxParam(const UINT, DLGPROC, const LPARAM); | ||||
| 
 | ||||
| INT_PTR LocalizedDialogBoxParamEx(const UINT, HWND parent, DLGPROC, const LPARAM); | ||||
| 
 | ||||
| HWND CreateLocalizedDialogParam(const UINT, DLGPROC, const LPARAM); | ||||
| 
 | ||||
| HWND CreateLocalizedDialog(const UINT, DLGPROC); | ||||
| 
 | ||||
| INT_PTR CALLBACK GeneralSettingsDlgProc(HWND, UINT, WPARAM, LPARAM); | ||||
| 
 | ||||
| LANGID GetGUILanguage(void); | ||||
| 
 | ||||
| /*
 | ||||
|  * Detect whether the selected UI language is LTR or RTL. | ||||
|  * Returns 0 for LTR, 1 for RTL, 2 or 3 for vertical | ||||
|  */ | ||||
| int LangFlowDirection(void); | ||||
| 
 | ||||
| #define MBOX_RTL_FLAGS ((LangFlowDirection() == 1) ? MB_RIGHT|MB_RTLREADING : 0) | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef LOCALIZATION_H */ | ||||
|  |  | |||
							
								
								
									
										45
									
								
								main.h
								
								
								
								
							
							
						
						
									
										45
									
								
								main.h
								
								
								
								
							|  | @ -28,16 +28,16 @@ | |||
| #include <tchar.h> | ||||
| 
 | ||||
| /* Define this to enable DEBUG build */ | ||||
| //#define DEBUG
 | ||||
| #define DEBUG_FILE	L"C:\\windows\\temp\\openvpngui_debug.txt" | ||||
| /*#define DEBUG */ | ||||
| #define DEBUG_FILE      L"C:\\windows\\temp\\openvpngui_debug.txt" | ||||
| 
 | ||||
| /* Registry key for User Settings */ | ||||
| #define GUI_REGKEY_HKCU	_T("Software\\OpenVPN-GUI") | ||||
| #define GUI_REGKEY_HKCU _T("Software\\OpenVPN-GUI") | ||||
| 
 | ||||
| #define MAX_LOG_LENGTH      1024/* Max number of characters per log line */ | ||||
| #define MAX_LOG_LINES		500	/* Max number of lines in LogWindow */ | ||||
| #define DEL_LOG_LINES		10	/* Number of lines to delete from LogWindow */ | ||||
| #define USAGE_BUF_SIZE		3000	/* Size of buffer used to display usage message */ | ||||
| #define MAX_LOG_LINES           500     /* Max number of lines in LogWindow */ | ||||
| #define DEL_LOG_LINES           10      /* Number of lines to delete from LogWindow */ | ||||
| #define USAGE_BUF_SIZE          3000    /* Size of buffer used to display usage message */ | ||||
| 
 | ||||
| /* Authorized group who can use any options and config locations */ | ||||
| #define OVPN_ADMIN_GROUP TEXT("OpenVPN Administrators") /* May be reset in registry */ | ||||
|  | @ -78,11 +78,11 @@ | |||
| #define NORETURN __attribute__ ((noreturn)) | ||||
| #endif | ||||
| 
 | ||||
| #define PACKVERSION(major,minor) MAKELONG(minor,major) | ||||
| #define PACKVERSION(major, minor) MAKELONG(minor, major) | ||||
| struct security_attributes | ||||
| { | ||||
|   SECURITY_ATTRIBUTES sa; | ||||
|   SECURITY_DESCRIPTOR sd; | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     SECURITY_DESCRIPTOR sd; | ||||
| }; | ||||
| 
 | ||||
| /* clear an object */ | ||||
|  | @ -90,9 +90,9 @@ struct security_attributes | |||
| 
 | ||||
| /* _sntprintf with guaranteed \0 termination */ | ||||
| #define _sntprintf_0(buf, ...) \ | ||||
|   do { \ | ||||
|     __sntprintf_0(buf, _countof(buf), __VA_ARGS__); \ | ||||
|   } while(0); | ||||
|     do { \ | ||||
|         __sntprintf_0(buf, _countof(buf), __VA_ARGS__); \ | ||||
|     } while(0); | ||||
| 
 | ||||
| static inline int | ||||
| __sntprintf_0(TCHAR *buf, size_t size, TCHAR *format, ...) | ||||
|  | @ -108,9 +108,9 @@ __sntprintf_0(TCHAR *buf, size_t size, TCHAR *format, ...) | |||
| 
 | ||||
| /* _snprintf with guaranteed \0 termination */ | ||||
| #define _snprintf_0(buf, ...) \ | ||||
|   do { \ | ||||
|     __snprintf_0(buf, sizeof(buf), __VA_ARGS__); \ | ||||
|   } while(0); | ||||
|     do { \ | ||||
|         __snprintf_0(buf, sizeof(buf), __VA_ARGS__); \ | ||||
|     } while(0); | ||||
| static inline int | ||||
| __snprintf_0(char *buf, size_t size, char *format, ...) | ||||
| { | ||||
|  | @ -126,14 +126,15 @@ __snprintf_0(char *buf, size_t size, char *format, ...) | |||
| #ifdef DEBUG | ||||
| /* Print Debug Message */ | ||||
| #define PrintDebug(...) \ | ||||
|         do { \ | ||||
|            TCHAR x_msg[256]; \ | ||||
|            _sntprintf_0(x_msg, __VA_ARGS__); \ | ||||
|            PrintDebugMsg(x_msg); \ | ||||
|         } while(0) | ||||
|     do { \ | ||||
|         TCHAR x_msg[256]; \ | ||||
|         _sntprintf_0(x_msg, __VA_ARGS__); \ | ||||
|         PrintDebugMsg(x_msg); \ | ||||
|     } while(0) | ||||
| 
 | ||||
| void PrintDebugMsg(TCHAR *msg); | ||||
| #else | ||||
| 
 | ||||
| #else  /* ifdef DEBUG */ | ||||
| #define PrintDebug(...) do { } while(0) | ||||
| #endif | ||||
| 
 | ||||
|  | @ -141,4 +142,4 @@ DWORD GetDllVersion(LPCTSTR lpszDllName); | |||
| 
 | ||||
| void ErrorExit(int exit_code, const wchar_t *msg); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef MAIN_H */ | ||||
|  |  | |||
							
								
								
									
										445
									
								
								manage.c
								
								
								
								
							
							
						
						
									
										445
									
								
								manage.c
								
								
								
								
							|  | @ -63,18 +63,22 @@ OpenManagement(connection_t *c) | |||
| { | ||||
|     WSADATA wsaData; | ||||
|     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     c->manage.connected = 0; | ||||
|     c->manage.sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||||
|     if (c->manage.sk == INVALID_SOCKET) | ||||
|     { | ||||
|         WSACleanup (); | ||||
|         WSACleanup(); | ||||
|         return FALSE; | ||||
|     } | ||||
|     if (WSAAsyncSelect(c->manage.sk, c->hwndStatus, WM_MANAGEMENT, | ||||
|         FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0) | ||||
|                        FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); | ||||
|     c->manage.timeout = time(NULL) + max_connect_time; | ||||
|  | @ -92,14 +96,20 @@ SendCommand(connection_t *c) | |||
|     int res; | ||||
|     mgmt_cmd_t *cmd = c->manage.cmd_queue; | ||||
|     if (cmd == NULL || cmd->size == 0) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     res = send(c->manage.sk, cmd->command, cmd->size, 0); | ||||
|     if (res < 1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (res != cmd->size) | ||||
|     { | ||||
|         memmove(cmd->command, cmd->command + res, cmd->size - res); | ||||
|     } | ||||
| 
 | ||||
|     cmd->size -= res; | ||||
| } | ||||
|  | @ -113,7 +123,9 @@ ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cm | |||
| { | ||||
|     mgmt_cmd_t *cmd = calloc(1, sizeof(*cmd)); | ||||
|     if (cmd == NULL) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     cmd->size = strlen(command) + 1; | ||||
|     cmd->command = malloc(cmd->size); | ||||
|  | @ -141,7 +153,9 @@ ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cm | |||
|     } | ||||
| 
 | ||||
|     if (c->manage.cmd_queue == cmd) | ||||
|     { | ||||
|         SendCommand(c); | ||||
|     } | ||||
| 
 | ||||
|     return TRUE; | ||||
| } | ||||
|  | @ -155,7 +169,9 @@ UnqueueCommand(connection_t *c) | |||
| { | ||||
|     mgmt_cmd_t *cmd = c->manage.cmd_queue; | ||||
|     if (!cmd) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     /* Wipe command as it may contain passwords */ | ||||
|     memset(cmd->command, 'x', cmd->size); | ||||
|  | @ -197,241 +213,281 @@ OnManagement(SOCKET sk, LPARAM lParam) | |||
| 
 | ||||
|     connection_t *c = GetConnByManagement(sk); | ||||
|     if (c == NULL) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     switch (WSAGETSELECTEVENT(lParam)) | ||||
|     { | ||||
|     case FD_CONNECT: | ||||
|         if (WSAGETSELECTERROR(lParam)) | ||||
|         { | ||||
|             /* keep trying for connections with persistent daemons */ | ||||
|             if (c->flags & FLAG_DAEMON_PERSISTENT | ||||
|                 || time(NULL) < c->manage.timeout) | ||||
|         case FD_CONNECT: | ||||
|             if (WSAGETSELECTERROR(lParam)) | ||||
|             { | ||||
|                 /* show a message on status window */ | ||||
|                 if (rtmsg_handler[log_] && (c->flags & FLAG_DAEMON_PERSISTENT)) | ||||
|                 /* keep trying for connections with persistent daemons */ | ||||
|                 if (c->flags & FLAG_DAEMON_PERSISTENT | ||||
|                     || time(NULL) < c->manage.timeout) | ||||
|                 { | ||||
|                     char buf[256]; | ||||
|                     _snprintf_0(buf, "%lld,W,Waiting for the management interface to come up", | ||||
|                                 (long long)time(NULL)) | ||||
|                     rtmsg_handler[log_](c, buf); | ||||
|                 } | ||||
|                     /* show a message on status window */ | ||||
|                     if (rtmsg_handler[log_] && (c->flags & FLAG_DAEMON_PERSISTENT)) | ||||
|                     { | ||||
|                         char buf[256]; | ||||
|                         _snprintf_0(buf, "%lld,W,Waiting for the management interface to come up", | ||||
|                                     (long long)time(NULL)) | ||||
|                         rtmsg_handler[log_](c, buf); | ||||
|                     } | ||||
| 
 | ||||
|                 connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); | ||||
|                     connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     /* Connection to MI timed out. */ | ||||
|                     CloseManagement(c); | ||||
|                     if (c->state != disconnected) | ||||
|                     { | ||||
|                         rtmsg_handler[timeout_](c, ""); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 /* Connection to MI timed out. */ | ||||
|                 CloseManagement (c); | ||||
|                 if (c->state != disconnected) | ||||
|                     rtmsg_handler[timeout_](c, ""); | ||||
|                 c->manage.connected = 1; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|             c->manage.connected = 1; | ||||
|         break; | ||||
|             break; | ||||
| 
 | ||||
|     case FD_READ: | ||||
|         if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0 | ||||
|         ||  data_size == 0) | ||||
|             return; | ||||
| 
 | ||||
|         data = malloc(c->manage.saved_size + data_size); | ||||
|         if (data == NULL) | ||||
|             return; | ||||
| 
 | ||||
|         res = recv(c->manage.sk, data + c->manage.saved_size, data_size, 0); | ||||
|         if (res != (int) data_size) | ||||
|         { | ||||
|             free(data); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         /* Copy previously saved management data */ | ||||
|         if (c->manage.saved_size) | ||||
|         { | ||||
|             memcpy(data, c->manage.saved_data, c->manage.saved_size); | ||||
|             data_size += c->manage.saved_size; | ||||
|             free(c->manage.saved_data); | ||||
|             c->manage.saved_data = NULL; | ||||
|             c->manage.saved_size = 0; | ||||
|         } | ||||
| 
 | ||||
|         offset = 0; | ||||
|         while (offset < data_size) | ||||
|         { | ||||
|             char *pos; | ||||
|             char *line = data + offset; | ||||
|             size_t line_size = data_size - offset; | ||||
|             BOOL passwd_request = false; | ||||
|             const char *passwd_prompt = "ENTER PASSWORD:"; | ||||
| 
 | ||||
|             if (line_size >= strlen(passwd_prompt) | ||||
|                 && memcmp(line, passwd_prompt, strlen(passwd_prompt)) == 0) | ||||
|         case FD_READ: | ||||
|             if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0 | ||||
|                 ||  data_size == 0) | ||||
|             { | ||||
|                 pos = memchr(line, ':', line_size); | ||||
|                 passwd_request = true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 pos = memchr(line, '\n', line_size); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (pos == NULL) | ||||
|             data = malloc(c->manage.saved_size + data_size); | ||||
|             if (data == NULL) | ||||
|             { | ||||
|                 c->manage.saved_data = malloc(line_size); | ||||
|                 if (c->manage.saved_data) | ||||
|                 { | ||||
|                     c->manage.saved_size = line_size; | ||||
|                     memcpy(c->manage.saved_data, line, c->manage.saved_size); | ||||
|                 } | ||||
|                 break; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             offset += (pos - line) + 1; | ||||
| 
 | ||||
|             /* Reply to a management password request */ | ||||
|             if (*c->manage.password && passwd_request) | ||||
|             res = recv(c->manage.sk, data + c->manage.saved_size, data_size, 0); | ||||
|             if (res != (int) data_size) | ||||
|             { | ||||
|                 ManagementCommand(c, c->manage.password, NULL, regular); | ||||
|                 SecureZeroMemory(c->manage.password, sizeof(c->manage.password)); | ||||
| 
 | ||||
|                 continue; | ||||
|                 free(data); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (!*c->manage.password && passwd_request) | ||||
|             /* Copy previously saved management data */ | ||||
|             if (c->manage.saved_size) | ||||
|             { | ||||
|                 /* either we don't have a password or we used it and didn't match */ | ||||
|                 MsgToEventLog(EVENTLOG_WARNING_TYPE, L"%ls: management password mismatch", | ||||
|                               c->config_name); | ||||
|                 c->state = disconnecting; | ||||
|                 CloseManagement (c); | ||||
|                 rtmsg_handler[stop_](c, ""); | ||||
| 
 | ||||
|                 continue; | ||||
|                 memcpy(data, c->manage.saved_data, c->manage.saved_size); | ||||
|                 data_size += c->manage.saved_size; | ||||
|                 free(c->manage.saved_data); | ||||
|                 c->manage.saved_data = NULL; | ||||
|                 c->manage.saved_size = 0; | ||||
|             } | ||||
| 
 | ||||
|             /* Handle regular management interface output */ | ||||
|             line[pos - line - 1] = '\0'; | ||||
|             if (line[0] == '>') | ||||
|             offset = 0; | ||||
|             while (offset < data_size) | ||||
|             { | ||||
|                 /* Real time notifications */ | ||||
|                 pos = line + 1; | ||||
|                 if (strncmp(pos, "LOG:", 4) == 0) | ||||
|                 char *pos; | ||||
|                 char *line = data + offset; | ||||
|                 size_t line_size = data_size - offset; | ||||
|                 BOOL passwd_request = false; | ||||
|                 const char *passwd_prompt = "ENTER PASSWORD:"; | ||||
| 
 | ||||
|                 if (line_size >= strlen(passwd_prompt) | ||||
|                     && memcmp(line, passwd_prompt, strlen(passwd_prompt)) == 0) | ||||
|                 { | ||||
|                     if (rtmsg_handler[log_]) | ||||
|                         rtmsg_handler[log_](c, pos + 4); | ||||
|                     pos = memchr(line, ':', line_size); | ||||
|                     passwd_request = true; | ||||
|                 } | ||||
|                 else if (strncmp(pos, "STATE:", 6) == 0) | ||||
|                 else | ||||
|                 { | ||||
|                     if (rtmsg_handler[state_]) | ||||
|                         rtmsg_handler[state_](c, pos + 6); | ||||
|                     pos = memchr(line, '\n', line_size); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "HOLD:", 5) == 0) | ||||
| 
 | ||||
|                 if (pos == NULL) | ||||
|                 { | ||||
|                     if (rtmsg_handler[hold_]) | ||||
|                         rtmsg_handler[hold_](c, pos + 5); | ||||
|                     c->manage.saved_data = malloc(line_size); | ||||
|                     if (c->manage.saved_data) | ||||
|                     { | ||||
|                         c->manage.saved_size = line_size; | ||||
|                         memcpy(c->manage.saved_data, line, c->manage.saved_size); | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 else if (strncmp(pos, "PASSWORD:", 9) == 0) | ||||
| 
 | ||||
|                 offset += (pos - line) + 1; | ||||
| 
 | ||||
|                 /* Reply to a management password request */ | ||||
|                 if (*c->manage.password && passwd_request) | ||||
|                 { | ||||
|                     if (rtmsg_handler[password_]) | ||||
|                         rtmsg_handler[password_](c, pos + 9); | ||||
|                     ManagementCommand(c, c->manage.password, NULL, regular); | ||||
|                     SecureZeroMemory(c->manage.password, sizeof(c->manage.password)); | ||||
| 
 | ||||
|                     continue; | ||||
|                 } | ||||
|                 else if (strncmp(pos, "PROXY:", 6) == 0) | ||||
| 
 | ||||
|                 if (!*c->manage.password && passwd_request) | ||||
|                 { | ||||
|                     if (rtmsg_handler[proxy_]) | ||||
|                         rtmsg_handler[proxy_](c, pos + 6); | ||||
|                     /* either we don't have a password or we used it and didn't match */ | ||||
|                     MsgToEventLog(EVENTLOG_WARNING_TYPE, L"%ls: management password mismatch", | ||||
|                                   c->config_name); | ||||
|                     c->state = disconnecting; | ||||
|                     CloseManagement(c); | ||||
|                     rtmsg_handler[stop_](c, ""); | ||||
| 
 | ||||
|                     continue; | ||||
|                 } | ||||
|                 else if (strncmp(pos, "INFO:", 5) == 0) | ||||
| 
 | ||||
|                 /* Handle regular management interface output */ | ||||
|                 line[pos - line - 1] = '\0'; | ||||
|                 if (line[0] == '>') | ||||
|                 { | ||||
|                     /* delay until management interface accepts input */ | ||||
|                     /* use real sleep here, since WM_MANAGEMENT might arrive before management is ready */ | ||||
|                     Sleep(100); | ||||
|                     c->manage.connected = 2; | ||||
|                     if (rtmsg_handler[ready_]) | ||||
|                         rtmsg_handler[ready_](c, pos + 5); | ||||
|                     /* Real time notifications */ | ||||
|                     pos = line + 1; | ||||
|                     if (strncmp(pos, "LOG:", 4) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[log_]) | ||||
|                         { | ||||
|                             rtmsg_handler[log_](c, pos + 4); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "STATE:", 6) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[state_]) | ||||
|                         { | ||||
|                             rtmsg_handler[state_](c, pos + 6); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "HOLD:", 5) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[hold_]) | ||||
|                         { | ||||
|                             rtmsg_handler[hold_](c, pos + 5); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "PASSWORD:", 9) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[password_]) | ||||
|                         { | ||||
|                             rtmsg_handler[password_](c, pos + 9); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "PROXY:", 6) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[proxy_]) | ||||
|                         { | ||||
|                             rtmsg_handler[proxy_](c, pos + 6); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "INFO:", 5) == 0) | ||||
|                     { | ||||
|                         /* delay until management interface accepts input */ | ||||
|                         /* use real sleep here, since WM_MANAGEMENT might arrive before management is ready */ | ||||
|                         Sleep(100); | ||||
|                         c->manage.connected = 2; | ||||
|                         if (rtmsg_handler[ready_]) | ||||
|                         { | ||||
|                             rtmsg_handler[ready_](c, pos + 5); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "NEED-OK:", 8) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[needok_]) | ||||
|                         { | ||||
|                             rtmsg_handler[needok_](c, pos + 8); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "NEED-STR:", 9) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[needstr_]) | ||||
|                         { | ||||
|                             rtmsg_handler[needstr_](c, pos + 9); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "ECHO:", 5) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[echo_]) | ||||
|                         { | ||||
|                             rtmsg_handler[echo_](c, pos + 5); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "BYTECOUNT:", 10) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[bytecount_]) | ||||
|                         { | ||||
|                             rtmsg_handler[bytecount_](c, pos + 10); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "INFOMSG:", 8) == 0) | ||||
|                     { | ||||
|                         if (rtmsg_handler[infomsg_]) | ||||
|                         { | ||||
|                             rtmsg_handler[infomsg_](c, pos + 8); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (strncmp(pos, "PKCS11ID", 8) == 0 | ||||
|                              && c->manage.cmd_queue) | ||||
|                     { | ||||
|                         /* This is not a real-time message, but unfortunately implemented
 | ||||
|                          * in the core as one. Work around by handling the response here. | ||||
|                          */ | ||||
|                         mgmt_cmd_t *cmd = c->manage.cmd_queue; | ||||
|                         if (cmd->handler) | ||||
|                         { | ||||
|                             cmd->handler(c, line); | ||||
|                         } | ||||
|                         UnqueueCommand(c); | ||||
|                     } | ||||
|                 } | ||||
|                 else if (strncmp(pos, "NEED-OK:", 8) == 0) | ||||
|                 else if (c->manage.cmd_queue) | ||||
|                 { | ||||
|                     if (rtmsg_handler[needok_]) | ||||
|                         rtmsg_handler[needok_](c, pos + 8); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "NEED-STR:", 9) == 0) | ||||
|                 { | ||||
|                     if (rtmsg_handler[needstr_]) | ||||
|                         rtmsg_handler[needstr_](c, pos + 9); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "ECHO:", 5) == 0) | ||||
|                 { | ||||
|                     if (rtmsg_handler[echo_]) | ||||
|                         rtmsg_handler[echo_](c, pos + 5); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "BYTECOUNT:", 10) == 0) | ||||
|                 { | ||||
|                     if (rtmsg_handler[bytecount_]) | ||||
|                         rtmsg_handler[bytecount_](c, pos + 10); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "INFOMSG:", 8) == 0) | ||||
|                 { | ||||
|                     if (rtmsg_handler[infomsg_]) | ||||
|                         rtmsg_handler[infomsg_](c, pos + 8); | ||||
|                 } | ||||
|                 else if (strncmp(pos, "PKCS11ID", 8) == 0 | ||||
|                          && c->manage.cmd_queue) | ||||
|                 { | ||||
|                     /* This is not a real-time message, but unfortunately implemented
 | ||||
|                      * in the core as one. Work around by handling the response here. | ||||
|                      */ | ||||
|                     /* Response to commands */ | ||||
|                     mgmt_cmd_t *cmd = c->manage.cmd_queue; | ||||
|                     if (cmd->handler) | ||||
|                     if (strncmp(line, "SUCCESS:", 8) == 0) | ||||
|                     { | ||||
|                         if (cmd->handler) | ||||
|                         { | ||||
|                             cmd->handler(c, line + 9); | ||||
|                         } | ||||
|                         UnqueueCommand(c); | ||||
|                     } | ||||
|                     else if (strncmp(line, "ERROR:", 6) == 0) | ||||
|                     { | ||||
|                         /* Response sent to management is not processed. Log an error in status window  */ | ||||
|                         char buf[256]; | ||||
|                         _snprintf_0(buf, "%lld,N,Previous command sent to management failed: %s", | ||||
|                                     (long long)time(NULL), line) | ||||
|                         rtmsg_handler[log_](c, buf); | ||||
| 
 | ||||
|                         if (cmd->handler) | ||||
|                         { | ||||
|                             cmd->handler(c, NULL); | ||||
|                         } | ||||
|                         UnqueueCommand(c); | ||||
|                     } | ||||
|                     else if (strcmp(line, "END") == 0) | ||||
|                     { | ||||
|                         UnqueueCommand(c); | ||||
|                     } | ||||
|                     else if (cmd->handler) | ||||
|                     { | ||||
|                         cmd->handler(c, line); | ||||
|                     UnqueueCommand(c); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else if (c->manage.cmd_queue) | ||||
|             free(data); | ||||
|             break; | ||||
| 
 | ||||
|         case FD_WRITE: | ||||
|             SendCommand(c); | ||||
|             break; | ||||
| 
 | ||||
|         case FD_CLOSE: | ||||
|             CloseManagement(c); | ||||
|             if (rtmsg_handler[stop_]) | ||||
|             { | ||||
|                 /* Response to commands */ | ||||
|                 mgmt_cmd_t *cmd = c->manage.cmd_queue; | ||||
|                 if (strncmp(line, "SUCCESS:", 8) == 0) | ||||
|                 { | ||||
|                     if (cmd->handler) | ||||
|                         cmd->handler(c, line + 9); | ||||
|                     UnqueueCommand(c); | ||||
|                 } | ||||
|                 else if (strncmp(line, "ERROR:", 6) == 0) | ||||
|                 { | ||||
|                     /* Response sent to management is not processed. Log an error in status window  */ | ||||
|                     char buf[256]; | ||||
|                     _snprintf_0(buf, "%lld,N,Previous command sent to management failed: %s", | ||||
|                                 (long long)time(NULL), line) | ||||
|                     rtmsg_handler[log_](c, buf); | ||||
| 
 | ||||
|                     if (cmd->handler) | ||||
|                         cmd->handler(c, NULL); | ||||
|                     UnqueueCommand(c); | ||||
|                 } | ||||
|                 else if (strcmp(line, "END") == 0) | ||||
|                 { | ||||
|                     UnqueueCommand(c); | ||||
|                 } | ||||
|                 else if (cmd->handler) | ||||
|                 { | ||||
|                     cmd->handler(c, line); | ||||
|                 } | ||||
|                 rtmsg_handler[stop_](c, ""); | ||||
|             } | ||||
|         } | ||||
|         free(data); | ||||
|         break; | ||||
| 
 | ||||
|     case FD_WRITE: | ||||
|         SendCommand(c); | ||||
|         break; | ||||
| 
 | ||||
|     case FD_CLOSE: | ||||
|         CloseManagement (c); | ||||
|         if (rtmsg_handler[stop_]) | ||||
|             rtmsg_handler[stop_](c, ""); | ||||
|         break; | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -450,7 +506,8 @@ CloseManagement(connection_t *c) | |||
|         c->manage.sk = INVALID_SOCKET; | ||||
|         c->manage.connected = 0; | ||||
|         while (UnqueueCommand(c)) | ||||
|             ; | ||||
|         { | ||||
|         } | ||||
|         WSACleanup(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										5
									
								
								manage.h
								
								
								
								
							
							
						
						
									
										5
									
								
								manage.h
								
								
								
								
							|  | @ -64,10 +64,13 @@ typedef struct mgmt_cmd { | |||
| 
 | ||||
| 
 | ||||
| void InitManagement(const mgmt_rtmsg_handler *handler); | ||||
| 
 | ||||
| BOOL OpenManagement(connection_t *); | ||||
| 
 | ||||
| BOOL ManagementCommand(connection_t *, char *, mgmt_msg_func, mgmt_cmd_type); | ||||
| 
 | ||||
| void OnManagement(SOCKET, LPARAM); | ||||
| 
 | ||||
| void CloseManagement(connection_t *); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef MANAGE_H */ | ||||
|  |  | |||
							
								
								
									
										159
									
								
								misc.c
								
								
								
								
							
							
						
						
									
										159
									
								
								misc.c
								
								
								
								
							|  | @ -57,27 +57,29 @@ Base64Encode(const char *input, int input_len, char **output) | |||
|     if (input_len == 0) | ||||
|     { | ||||
|         /* set output to empty string  -- matches the behavior in openvpn */ | ||||
|         *output = calloc (1, sizeof(char)); | ||||
|         *output = calloc(1, sizeof(char)); | ||||
|         return TRUE; | ||||
|     } | ||||
|     if (!CryptBinaryToStringA((const BYTE *) input, (DWORD) input_len, | ||||
|         flags, NULL, &output_len) || output_len == 0) | ||||
|                               flags, NULL, &output_len) || output_len == 0) | ||||
|     { | ||||
| #ifdef DEBUG | ||||
|         PrintDebug (L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); | ||||
|         PrintDebug(L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); | ||||
| #endif | ||||
|         *output = NULL; | ||||
|         return FALSE; | ||||
|     } | ||||
|     *output = (char *)malloc(output_len); | ||||
|     if (*output == NULL) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     if (!CryptBinaryToStringA((const BYTE *) input, (DWORD) input_len, | ||||
|         flags, *output, &output_len)) | ||||
|                               flags, *output, &output_len)) | ||||
|     { | ||||
| #ifdef DEBUG | ||||
|         PrintDebug (L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); | ||||
|         PrintDebug(L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); | ||||
| #endif | ||||
|         free(*output); | ||||
|         *output = NULL; | ||||
|  | @ -100,7 +102,7 @@ Base64Decode(const char *input, char **output) | |||
| { | ||||
|     DWORD len; | ||||
| 
 | ||||
|     PrintDebug (L"decoding %hs", input); | ||||
|     PrintDebug(L"decoding %hs", input); | ||||
|     if (!CryptStringToBinaryA(input, 0, CRYPT_STRING_BASE64_ANY, | ||||
|                               NULL, &len, NULL, NULL) || len == 0) | ||||
|     { | ||||
|  | @ -110,10 +112,12 @@ Base64Decode(const char *input, char **output) | |||
| 
 | ||||
|     *output = malloc(len + 1); | ||||
|     if (*output == NULL) | ||||
|     { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     if (!CryptStringToBinaryA(input, 0, | ||||
|         CRYPT_STRING_BASE64, (BYTE *) *output, &len, NULL, NULL)) | ||||
|                               CRYPT_STRING_BASE64, (BYTE *) *output, &len, NULL, NULL)) | ||||
|     { | ||||
|         free(*output); | ||||
|         *output = NULL; | ||||
|  | @ -122,7 +126,7 @@ Base64Decode(const char *input, char **output) | |||
| 
 | ||||
|     /* NUL terminate output */ | ||||
|     (*output)[len] = '\0'; | ||||
|     PrintDebug (L"Decoded output %hs", *output); | ||||
|     PrintDebug(L"Decoded output %hs", *output); | ||||
| 
 | ||||
|     return len; | ||||
| } | ||||
|  | @ -140,19 +144,27 @@ GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR *str, int *len) | |||
| 
 | ||||
|     ucs2_len = GetWindowTextLength(GetDlgItem(hDlg, id)) + 1; | ||||
|     if (ucs2_len == 1) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     ucs2_str = malloc(ucs2_len * sizeof(*ucs2_str)); | ||||
|     if (ucs2_str == NULL) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     if (GetDlgItemText(hDlg, id, ucs2_str, ucs2_len) == 0) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     utf8_len = WideCharToMultiByte(CP_UTF8, 0, ucs2_str, -1, NULL, 0, NULL, NULL); | ||||
|     utf8_str = malloc(utf8_len); | ||||
|     if (utf8_str == NULL) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     WideCharToMultiByte(CP_UTF8, 0, ucs2_str, -1, utf8_str, utf8_len, NULL, NULL); | ||||
| 
 | ||||
|  | @ -255,7 +267,7 @@ out: | |||
|  * Generate a management command from double user inputs and send it | ||||
|  */ | ||||
| BOOL | ||||
| ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int id, int id2) | ||||
| ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg, int id, int id2) | ||||
| { | ||||
|     BOOL retval = FALSE; | ||||
|     LPSTR input, input2, input_b64, input2_b64, cmd; | ||||
|  | @ -268,9 +280,13 @@ ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int | |||
|     GetDlgItemTextUtf8(hDlg, id2, &input2, &input2_len); | ||||
| 
 | ||||
|     if (!Base64Encode(input, input_len, &input_b64)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
|     if (!Base64Encode(input2, input2_len, &input2_b64)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     cmd_len = strlen(input_b64) + strlen(input2_b64) + strlen(fmt); | ||||
|     cmd = malloc(cmd_len); | ||||
|  | @ -284,9 +300,13 @@ ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int | |||
| out: | ||||
|     /* Clear buffers with potentially secret content */ | ||||
|     if (input_b64) | ||||
|     { | ||||
|         memset(input_b64, 0, strlen(input_b64)); | ||||
|     } | ||||
|     if (input2_b64) | ||||
|     { | ||||
|         memset(input2_b64, 0, strlen(input2_b64)); | ||||
|     } | ||||
|     free(input_b64); | ||||
|     free(input2_b64); | ||||
| 
 | ||||
|  | @ -310,7 +330,7 @@ out: | |||
|  * Generate a management command from base64-encoded user inputs and send it | ||||
|  */ | ||||
| BOOL | ||||
| ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) | ||||
| ManagementCommandFromInputBase64(connection_t *c, LPCSTR fmt, HWND hDlg, int id) | ||||
| { | ||||
|     BOOL retval = FALSE; | ||||
|     LPSTR input, input_b64, cmd; | ||||
|  | @ -321,7 +341,9 @@ ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) | |||
|     GetDlgItemTextUtf8(hDlg, id, &input, &input_len); | ||||
| 
 | ||||
|     if (!Base64Encode(input, input_len, &input_b64)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     cmd_len = strlen(input_b64) + strlen(fmt); | ||||
|     cmd = malloc(cmd_len); | ||||
|  | @ -335,7 +357,9 @@ ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) | |||
| out: | ||||
|     /* Clear buffers with potentially secret content */ | ||||
|     if (input_b64) | ||||
|     { | ||||
|         memset(input_b64, 0, strlen(input_b64)); | ||||
|     } | ||||
|     free(input_b64); | ||||
| 
 | ||||
|     if (input_len) | ||||
|  | @ -365,20 +389,26 @@ EnsureDirExists(LPTSTR dir) | |||
|         { | ||||
|             LPTSTR pos = _tcsrchr(dir, '\\'); | ||||
|             if (pos == NULL) | ||||
|             { | ||||
|                 return FALSE; | ||||
|             } | ||||
| 
 | ||||
|             *pos = '\0'; | ||||
|             BOOL ret = EnsureDirExists(dir); | ||||
|             *pos = '\\'; | ||||
|             if (ret == FALSE) | ||||
|             { | ||||
|                 return FALSE; | ||||
|             } | ||||
|         } | ||||
|         else if (error != ERROR_FILE_NOT_FOUND) | ||||
|         { | ||||
|             return FALSE; | ||||
|         } | ||||
| 
 | ||||
|         /* No error if directory already exists */ | ||||
|         return (CreateDirectory(dir, NULL) == TRUE | ||||
|             ||  GetLastError() == ERROR_ALREADY_EXISTS); | ||||
|                 ||  GetLastError() == ERROR_ALREADY_EXISTS); | ||||
|     } | ||||
| 
 | ||||
|     return (attr & FILE_ATTRIBUTE_DIRECTORY ? TRUE : FALSE); | ||||
|  | @ -425,13 +455,17 @@ ForceForegroundWindow(HWND hWnd) | |||
|  * Set scale factor of windows in pixels. Scale = 100% for dpi = 96 | ||||
|  */ | ||||
| void | ||||
| DpiSetScale(options_t* options, UINT dpix) | ||||
| DpiSetScale(options_t *options, UINT dpix) | ||||
| { | ||||
|     /* scale factor in percentage compared to the reference dpi of 96 */ | ||||
|     if (dpix != 0) | ||||
|     { | ||||
|         options->dpi_scale = MulDiv(dpix, 100, 96); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         options->dpi_scale = 100; | ||||
|     } | ||||
|     PrintDebug(L"DPI scale set to %u", options->dpi_scale); | ||||
| } | ||||
| 
 | ||||
|  | @ -442,19 +476,22 @@ DpiSetScale(options_t* options, UINT dpix) | |||
|  * in its SID.  Assumes the caller is not impersonating and has access to open its own | ||||
|  * process token. | ||||
|  */ | ||||
| BOOL IsUserAdmin(VOID) | ||||
| BOOL | ||||
| IsUserAdmin(VOID) | ||||
| { | ||||
|     BOOL b; | ||||
|     SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; | ||||
|     PSID AdministratorsGroup; | ||||
| 
 | ||||
|     b = AllocateAndInitializeSid (&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, | ||||
|                                   DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, | ||||
|                                   &AdministratorsGroup); | ||||
|     if(b) | ||||
|     b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, | ||||
|                                  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, | ||||
|                                  &AdministratorsGroup); | ||||
|     if (b) | ||||
|     { | ||||
|         if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) | ||||
|         { | ||||
|             b = FALSE; | ||||
|         } | ||||
|         FreeSid(AdministratorsGroup); | ||||
|     } | ||||
| 
 | ||||
|  | @ -462,15 +499,15 @@ BOOL IsUserAdmin(VOID) | |||
| } | ||||
| 
 | ||||
| HANDLE | ||||
| InitSemaphore (WCHAR *name) | ||||
| InitSemaphore(WCHAR *name) | ||||
| { | ||||
|     HANDLE semaphore = NULL; | ||||
|     semaphore = CreateSemaphore (NULL, 1, 1, name); | ||||
|     semaphore = CreateSemaphore(NULL, 1, 1, name); | ||||
|     if (!semaphore) | ||||
|     { | ||||
|         MessageBoxW (NULL, L"Error creating semaphore", TEXT(PACKAGE_NAME), MB_OK); | ||||
|         MessageBoxW(NULL, L"Error creating semaphore", TEXT(PACKAGE_NAME), MB_OK); | ||||
| #ifdef DEBUG | ||||
|         PrintDebug (L"InitSemaphore: CreateSemaphore failed [error = %lu]", GetLastError()); | ||||
|         PrintDebug(L"InitSemaphore: CreateSemaphore failed [error = %lu]", GetLastError()); | ||||
| #endif | ||||
|     } | ||||
|     return semaphore; | ||||
|  | @ -488,17 +525,17 @@ CloseSemaphore(HANDLE sem) | |||
| 
 | ||||
| /* Check access rights on an existing file */ | ||||
| BOOL | ||||
| CheckFileAccess (const TCHAR *path, int access) | ||||
| CheckFileAccess(const TCHAR *path, int access) | ||||
| { | ||||
|     HANDLE h; | ||||
|     bool ret = FALSE; | ||||
| 
 | ||||
|     h = CreateFile (path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, | ||||
|     h = CreateFile(path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, | ||||
|                    FILE_ATTRIBUTE_NORMAL, NULL); | ||||
|     if ( h != INVALID_HANDLE_VALUE ) | ||||
|     if (h != INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         ret = TRUE; | ||||
|         CloseHandle (h); | ||||
|         CloseHandle(h); | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
|  | @ -514,17 +551,23 @@ WidenEx(UINT codepage, const char *str) | |||
| { | ||||
|     WCHAR *wstr = NULL; | ||||
|     if (!str) | ||||
|     { | ||||
|         return wstr; | ||||
|     } | ||||
| 
 | ||||
|     int nch = MultiByteToWideChar(codepage, 0, str, -1, NULL, 0); | ||||
|     if (nch > 0) | ||||
|     { | ||||
|         wstr = malloc(sizeof(WCHAR) * nch); | ||||
|     } | ||||
|     if (wstr) | ||||
|     { | ||||
|         nch =  MultiByteToWideChar(codepage, 0, str, -1, wstr, nch); | ||||
|     } | ||||
| 
 | ||||
|     if (nch == 0 && wstr) | ||||
|     { | ||||
|         free (wstr); | ||||
|         free(wstr); | ||||
|         wstr = NULL; | ||||
|     } | ||||
| 
 | ||||
|  | @ -545,7 +588,9 @@ BOOL | |||
| validate_input(const WCHAR *input, const WCHAR *exclude) | ||||
| { | ||||
|     if (!exclude) | ||||
|     { | ||||
|         exclude = L"\n"; | ||||
|     } | ||||
|     return (wcspbrk(input, exclude) == NULL); | ||||
| } | ||||
| 
 | ||||
|  | @ -556,17 +601,27 @@ wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WC | |||
|     int n = 0; | ||||
| 
 | ||||
|     if (!dest || len == 0) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (src1 && src2 && src1[0] && src2[0]) | ||||
|     { | ||||
|         n = swprintf(dest, len, L"%ls%ls%ls", src1, sep, src2); | ||||
|     } | ||||
|     else if (src1 && src1[0]) | ||||
|     { | ||||
|         n = swprintf(dest, len, L"%ls", src1); | ||||
|     } | ||||
|     else if (src2 && src2[0]) | ||||
|     { | ||||
|         n = swprintf(dest, len, L"%ls", src2); | ||||
|     } | ||||
| 
 | ||||
|     if (n < 0 || n >= len) /*swprintf failed */ | ||||
|     { | ||||
|         n = 0; | ||||
|     } | ||||
|     dest[n] = L'\0'; | ||||
| } | ||||
| 
 | ||||
|  | @ -594,7 +649,9 @@ url_decode(const char *src) | |||
|     char *o; | ||||
| 
 | ||||
|     if (!out) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     for (o = out; *s; o++) | ||||
|     { | ||||
|  | @ -618,7 +675,9 @@ md_init(md_ctx *ctx, ALG_ID hash_type) | |||
|     DWORD status = 0; | ||||
| 
 | ||||
|     if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) | ||||
|     { | ||||
|         goto err; | ||||
|     } | ||||
|     if (!CryptCreateHash(ctx->prov, hash_type, 0, 0, &ctx->hash)) | ||||
|     { | ||||
|         CryptReleaseContext(ctx->prov, 0); | ||||
|  | @ -684,7 +743,7 @@ open_url(const wchar_t *url) | |||
| extern options_t o; | ||||
| 
 | ||||
| void | ||||
| ImportConfigFile(const TCHAR* source, bool prompt_user) | ||||
| ImportConfigFile(const TCHAR *source, bool prompt_user) | ||||
| { | ||||
|     TCHAR fileName[MAX_PATH] = _T(""); | ||||
|     TCHAR ext[MAX_PATH] = _T(""); | ||||
|  | @ -723,7 +782,7 @@ ImportConfigFile(const TCHAR* source, bool prompt_user) | |||
|     { | ||||
|         if (prompt_user | ||||
|             && ShowLocalizedMsgEx(MB_YESNO|MB_TOPMOST, o.hWnd, TEXT(PACKAGE_NAME), | ||||
|                               IDS_NFO_IMPORT_SOURCE, fileName) == IDNO) | ||||
|                                   IDS_NFO_IMPORT_SOURCE, fileName) == IDNO) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|  | @ -741,10 +800,10 @@ ImportConfigFile(const TCHAR* source, bool prompt_user) | |||
| 
 | ||||
|     if (!CopyFile(source, destination, no_overwrite)) | ||||
|     { | ||||
|        MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Copy file <%ls> to <%ls> failed (error = %lu)", | ||||
|                      source, destination, GetLastError()); | ||||
|        ShowLocalizedMsg(IDS_ERR_IMPORT_FAILED, destination); | ||||
|        return; | ||||
|         MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Copy file <%ls> to <%ls> failed (error = %lu)", | ||||
|                       source, destination, GetLastError()); | ||||
|         ShowLocalizedMsg(IDS_ERR_IMPORT_FAILED, destination); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ShowTrayBalloon(LoadLocalizedString(IDS_NFO_IMPORT_SUCCESS), fileName); | ||||
|  | @ -900,7 +959,9 @@ MsgToEventLog(WORD type, wchar_t *format, ...) | |||
|     { | ||||
|         o.event_log = RegisterEventSource(NULL, TEXT(PACKAGE_NAME)); | ||||
|         if (!o.event_log) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     va_list args; | ||||
|  | @ -908,7 +969,10 @@ MsgToEventLog(WORD type, wchar_t *format, ...) | |||
|     int nchar = vswprintf(buf, size-1, format, args); | ||||
|     va_end(args); | ||||
| 
 | ||||
|     if (nchar == -1) return; | ||||
|     if (nchar == -1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     buf[size - 1] = '\0'; | ||||
| 
 | ||||
|  | @ -954,11 +1018,13 @@ GetPLAPRegistrationStatus(void) | |||
|     wchar_t dllPath[MAX_PATH]; | ||||
| 
 | ||||
|     _sntprintf_0(dllPath, L"%ls%ls", o.install_path, L"bin\\libopenvpn_plap.dll"); | ||||
|     if (!CheckFileAccess(dllPath, GENERIC_READ)) { | ||||
|     if (!CheckFileAccess(dllPath, GENERIC_READ)) | ||||
|     { | ||||
|         res = -1; | ||||
|     } | ||||
|     else if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID\\"PLAP_CLASSID, 0, KEY_READ, ®key) | ||||
|               == ERROR_SUCCESS) { | ||||
|              == ERROR_SUCCESS) | ||||
|     { | ||||
|         res = 1; | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
|  | @ -975,19 +1041,24 @@ SetPLAPRegistration(BOOL value) | |||
| 
 | ||||
|     /* Run only if the state has changed */ | ||||
|     int plap_status = GetPLAPRegistrationStatus(); | ||||
|     if (plap_status > 0 && (BOOL) plap_status == value)  return 0; | ||||
|     if (plap_status > 0 && (BOOL) plap_status == value) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     if (value) { | ||||
|     if (value) | ||||
|     { | ||||
|         _sntprintf_0( params, L"import \"%ls%ls\"", o.install_path, L"bin\\openvpn-plap-install.reg"); | ||||
|     } | ||||
|     else { | ||||
|     else | ||||
|     { | ||||
|         _sntprintf_0( params, L"import \"%ls%ls\"", o.install_path, L"bin\\openvpn-plap-uninstall.reg"); | ||||
|     } | ||||
| 
 | ||||
|     res = RunAsAdmin(cmd, params); | ||||
|     if (res != 0) | ||||
|     { | ||||
|         ShowLocalizedMsg(value? IDS_ERR_PLAP_REG  : IDS_ERR_PLAP_UNREG, res); | ||||
|         ShowLocalizedMsg(value ? IDS_ERR_PLAP_REG  : IDS_ERR_PLAP_UNREG, res); | ||||
|     } | ||||
|     return res; | ||||
| } | ||||
|  | @ -1003,7 +1074,7 @@ RunAsAdmin(const WCHAR *cmd, const WCHAR *params) | |||
|     SHELLEXECUTEINFO shinfo; | ||||
|     DWORD status = -1; | ||||
| 
 | ||||
|     CLEAR (shinfo); | ||||
|     CLEAR(shinfo); | ||||
|     shinfo.cbSize = sizeof(shinfo); | ||||
|     shinfo.fMask = SEE_MASK_NOCLOSEPROCESS; | ||||
|     shinfo.hwnd = NULL; | ||||
|  | @ -1038,7 +1109,7 @@ OVPNMsgWait(DWORD timeout, HWND hdlg) | |||
|         if (MsgWaitForMultipleObjectsEx(0, NULL, end - now, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_OBJECT_0) | ||||
|         { | ||||
|             MSG msg; | ||||
|             while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) | ||||
|             while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) | ||||
|             { | ||||
|                 if (msg.message == WM_QUIT) | ||||
|                 { | ||||
|  | @ -1069,14 +1140,20 @@ GetRandomPassword(char *buf, size_t len) | |||
|     unsigned i; | ||||
| 
 | ||||
|     if (!CryptAcquireContext(&cp, NULL, NULL, PROV_DSS, CRYPT_VERIFYCONTEXT)) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     if (!CryptGenRandom(cp, len, (PBYTE) buf)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     /* Make sure all values are between 0x21 '!' and 0x7e '~' */ | ||||
|     for (i = 0; i < len; ++i) | ||||
|     { | ||||
|         buf[i] = (buf[i] & 0x5d) + 0x21; | ||||
|     } | ||||
| 
 | ||||
|     retval = TRUE; | ||||
| out: | ||||
|  |  | |||
							
								
								
									
										35
									
								
								misc.h
								
								
								
								
							
							
						
						
									
										35
									
								
								misc.h
								
								
								
								
							|  | @ -27,30 +27,44 @@ | |||
| #include "options.h" | ||||
| 
 | ||||
| BOOL ManagementCommandFromInput(connection_t *, LPCSTR, HWND, int); | ||||
| BOOL ManagementCommandFromTwoInputsBase64(connection_t*, LPCSTR, HWND, int, int); | ||||
| 
 | ||||
| BOOL ManagementCommandFromTwoInputsBase64(connection_t *, LPCSTR, HWND, int, int); | ||||
| 
 | ||||
| BOOL ManagementCommandFromInputBase64(connection_t *, LPCSTR, HWND, int); | ||||
| 
 | ||||
| BOOL EnsureDirExists(LPTSTR); | ||||
| 
 | ||||
| BOOL streq(LPCSTR, LPCSTR); | ||||
| 
 | ||||
| BOOL strbegins(const char *str, const char *begin); | ||||
| 
 | ||||
| BOOL wcsbegins(LPCWSTR, LPCWSTR); | ||||
| 
 | ||||
| BOOL ForceForegroundWindow(HWND); | ||||
| void DpiSetScale(options_t*, UINT dpix); | ||||
| 
 | ||||
| void DpiSetScale(options_t *, UINT dpix); | ||||
| 
 | ||||
| BOOL IsUserAdmin(VOID); | ||||
| HANDLE InitSemaphore (WCHAR *); | ||||
| BOOL CheckFileAccess (const TCHAR *path, int access); | ||||
| 
 | ||||
| HANDLE InitSemaphore(WCHAR *); | ||||
| 
 | ||||
| BOOL CheckFileAccess(const TCHAR *path, int access); | ||||
| 
 | ||||
| BOOL Base64Encode(const char *input, int input_len, char **output); | ||||
| 
 | ||||
| int Base64Decode(const char *input, char **output); | ||||
| 
 | ||||
| WCHAR *Widen(const char *utf8); | ||||
| 
 | ||||
| WCHAR *WidenEx(UINT codepage, const char *utf8); | ||||
| 
 | ||||
| BOOL validate_input(const WCHAR *input, const WCHAR *exclude); | ||||
| 
 | ||||
| /* Concatenate two wide strings with a separator */ | ||||
| void wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WCHAR *sep); | ||||
| 
 | ||||
| void CloseSemaphore(HANDLE sem); | ||||
| 
 | ||||
| /* Close a handle if not null or invalid */ | ||||
| void CloseHandleEx(LPHANDLE h); | ||||
| 
 | ||||
|  | @ -61,25 +75,27 @@ char *url_decode(const char *src); | |||
| 
 | ||||
| /* digest functions */ | ||||
| typedef struct md_ctx { | ||||
|      HCRYPTPROV prov; | ||||
|      HCRYPTHASH hash; | ||||
|     HCRYPTPROV prov; | ||||
|     HCRYPTHASH hash; | ||||
| } md_ctx; | ||||
| 
 | ||||
| DWORD md_init(md_ctx *ctx, ALG_ID hash_type); | ||||
| 
 | ||||
| DWORD md_update(md_ctx *ctx, const BYTE *data, size_t size); | ||||
| 
 | ||||
| DWORD md_final(md_ctx *ctx, BYTE *md); | ||||
| 
 | ||||
| /* Open specified http/https URL using ShellExecute. */ | ||||
| BOOL open_url(const wchar_t *url); | ||||
| 
 | ||||
| void ImportConfigFile(const TCHAR* path, bool prompt_user); | ||||
| void ImportConfigFile(const TCHAR *path, bool prompt_user); | ||||
| 
 | ||||
| /*
 | ||||
|  * Helper function to convert UCS-2 text from a dialog item to UTF-8. | ||||
|  * Caller must free *str if *len != 0. | ||||
|  */ | ||||
| BOOL | ||||
| GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR* str, int* len); | ||||
| GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR *str, int *len); | ||||
| 
 | ||||
| /* Return escaped copy of a string */ | ||||
| char *escape_string(const char *str); | ||||
|  | @ -157,6 +173,7 @@ bool OVPNMsgWait(DWORD timeout, HWND hdlg); | |||
| bool GetRandomPassword(char *buf, size_t len); | ||||
| 
 | ||||
| void ResetPasswordReveal(HWND edit, HWND btn, WPARAM wParam); | ||||
| 
 | ||||
| void ChangePasswordVisibility(HWND edit, HWND btn, WPARAM wParam); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef MISC_H */ | ||||
|  |  | |||
|  | @ -409,4 +409,4 @@ | |||
| /* Timer IDs */ | ||||
| #define IDT_STOP_TIMER                  2500  /* Timer used to trigger force termination */ | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef OPENVPN_GUI_RES_H */ | ||||
|  |  | |||
							
								
								
									
										50
									
								
								openvpn.h
								
								
								
								
							
							
						
						
									
										50
									
								
								openvpn.h
								
								
								
								
							|  | @ -26,33 +26,51 @@ | |||
| #include "options.h" | ||||
| 
 | ||||
| #define TRY_SETPROP(hwnd, name, p)                                                   \ | ||||
|             do { if (SetPropW(hwnd, name, p)) break;                                 \ | ||||
|                  MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d GetProp returned null", \ | ||||
|                                __func__, __LINE__);                                  \ | ||||
|                  EndDialog(hwnd, IDABORT);                                           \ | ||||
|                  return false;                                                       \ | ||||
|                } while(0) | ||||
|     do { if (SetPropW(hwnd, name, p)) break;                                 \ | ||||
|          MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d GetProp returned null", \ | ||||
|                        __func__, __LINE__);                                  \ | ||||
|          EndDialog(hwnd, IDABORT);                                           \ | ||||
|          return false;                                                       \ | ||||
|     } while(0) | ||||
| 
 | ||||
| BOOL StartOpenVPN(connection_t *); | ||||
| 
 | ||||
| void StopOpenVPN(connection_t *); | ||||
| 
 | ||||
| void DetachOpenVPN(connection_t *); | ||||
| 
 | ||||
| void SuspendOpenVPN(int config); | ||||
| 
 | ||||
| void RestartOpenVPN(connection_t *); | ||||
| 
 | ||||
| void ReleaseOpenVPN(connection_t *); | ||||
| 
 | ||||
| BOOL CheckVersion(); | ||||
| 
 | ||||
| void SetStatusWinIcon(HWND hwndDlg, int IconID); | ||||
| 
 | ||||
| void OnReady(connection_t *, char *); | ||||
| 
 | ||||
| void OnHold(connection_t *, char *); | ||||
| 
 | ||||
| void OnLogLine(connection_t *, char *); | ||||
| 
 | ||||
| void OnStateChange(connection_t *, char *); | ||||
| 
 | ||||
| void OnPassword(connection_t *, char *); | ||||
| 
 | ||||
| void OnStop(connection_t *, char *); | ||||
| 
 | ||||
| void OnNeedOk(connection_t *, char *); | ||||
| 
 | ||||
| void OnNeedStr(connection_t *, char *); | ||||
| 
 | ||||
| void OnEcho(connection_t *, char *); | ||||
| 
 | ||||
| void OnByteCount(connection_t *, char *); | ||||
| void OnInfoMsg(connection_t*, char*); | ||||
| 
 | ||||
| void OnInfoMsg(connection_t *, char *); | ||||
| 
 | ||||
| void OnTimeout(connection_t *, char *); | ||||
| 
 | ||||
| void ResetSavePasswords(connection_t *); | ||||
|  | @ -66,7 +84,7 @@ extern const TCHAR *cfgProp; | |||
| #define ERROR_MESSAGE_TYPE 0x20000003 | ||||
| 
 | ||||
| /* Write a line to status window and optionally to the log file */ | ||||
| void WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio); | ||||
| void WriteStatusLog(connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio); | ||||
| 
 | ||||
| #define FLAG_CR_TYPE_SCRV1  0x1    /* static challenege */ | ||||
| #define FLAG_CR_TYPE_CRV1   0x2    /* dynamic challenege */ | ||||
|  | @ -78,12 +96,12 @@ void WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BO | |||
| #define FLAG_CR_TYPE_CRTEXT 0x80   /* crtext */ | ||||
| 
 | ||||
| typedef struct { | ||||
|     connection_t* c; | ||||
|     connection_t *c; | ||||
|     unsigned int flags; | ||||
|     char* str; | ||||
|     char* id; | ||||
|     char* user; | ||||
|     char* cr_response; | ||||
|     char *str; | ||||
|     char *id; | ||||
|     char *user; | ||||
|     char *cr_response; | ||||
| } auth_param_t; | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -92,10 +110,10 @@ typedef struct { | |||
|  * even on error. | ||||
|  */ | ||||
| BOOL | ||||
| parse_dynamic_cr(const char* str, auth_param_t* param); | ||||
| parse_dynamic_cr(const char *str, auth_param_t *param); | ||||
| 
 | ||||
| void | ||||
| free_auth_param(auth_param_t* param); | ||||
| free_auth_param(auth_param_t *param); | ||||
| 
 | ||||
| /*
 | ||||
|  * Given an OpenVPN state as reported by the management interface | ||||
|  | @ -103,4 +121,4 @@ free_auth_param(auth_param_t* param); | |||
|  */ | ||||
| int daemon_state_resid(const char *name); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef OPENVPN_H */ | ||||
|  |  | |||
|  | @ -50,28 +50,34 @@ match(const WIN32_FIND_DATA *find, const TCHAR *ext) | |||
|     int i; | ||||
| 
 | ||||
|     if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | ||||
|     { | ||||
|         return match_dir; | ||||
|     } | ||||
| 
 | ||||
|     if (ext_len == 0) | ||||
|     { | ||||
|         return match_file; | ||||
|     } | ||||
| 
 | ||||
|     i = _tcslen(find->cFileName) - ext_len - 1; | ||||
| 
 | ||||
|     if (i > 0 && find->cFileName[i] == '.' | ||||
|     && _tcsicmp(find->cFileName + i + 1, ext) == 0) | ||||
|         && _tcsicmp(find->cFileName + i + 1, ext) == 0) | ||||
|     { | ||||
|         return match_file; | ||||
|     } | ||||
| 
 | ||||
|     return match_false; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| CheckReadAccess (const TCHAR *dir, const TCHAR *file) | ||||
| CheckReadAccess(const TCHAR *dir, const TCHAR *file) | ||||
| { | ||||
|     TCHAR path[MAX_PATH]; | ||||
| 
 | ||||
|     _sntprintf_0 (path, _T("%ls\\%ls"), dir, file); | ||||
|     _sntprintf_0(path, _T("%ls\\%ls"), dir, file); | ||||
| 
 | ||||
|     return CheckFileAccess (path, GENERIC_READ); | ||||
|     return CheckFileAccess(path, GENERIC_READ); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | @ -80,7 +86,9 @@ ConfigAlreadyExists(TCHAR *newconfig) | |||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (_tcsicmp(c->config_file, newconfig) == 0) | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | @ -148,9 +156,13 @@ AddConfigFileToList(int group, const TCHAR *filename, const TCHAR *config_dir) | |||
|     else | ||||
|     { | ||||
|         if (IsAuthPassSaved(c->config_name)) | ||||
|         { | ||||
|             c->flags |= FLAG_SAVE_AUTH_PASS; | ||||
|         } | ||||
|         if (IsKeyPassSaved(c->config_name)) | ||||
|         { | ||||
|             c->flags |= FLAG_SAVE_KEY_PASS; | ||||
|         } | ||||
|     } | ||||
|     if (o.disable_popup_messages) | ||||
|     { | ||||
|  | @ -214,7 +226,9 @@ ActivateConfigGroups(void) | |||
| 
 | ||||
|     /* children is a counter re-used for activation, menu indexing etc. -- reset before use */ | ||||
|     for (int i = 0; i < o.num_groups; i++) | ||||
|     { | ||||
|         o.groups[i].children = 0; | ||||
|     } | ||||
| 
 | ||||
|     /* count children of each group -- this includes groups
 | ||||
|      * and configs which have it as parent | ||||
|  | @ -229,7 +243,9 @@ ActivateConfigGroups(void) | |||
|         config_group_t *this = &o.groups[i]; | ||||
|         config_group_t *parent = PARENT_GROUP(this); | ||||
|         if (parent) /* should be true as i = 0 is omitted */ | ||||
|         { | ||||
|             parent->children++; | ||||
|         } | ||||
| 
 | ||||
|         /* unless activated below the group stays inactive */ | ||||
|         this->active = false; | ||||
|  | @ -290,7 +306,9 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) | |||
|     _sntprintf_0(find_string, _T("%ls\\*"), config_dir); | ||||
|     find_handle = FindFirstFile(find_string, &find_obj); | ||||
|     if (find_handle == INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     /* Loop over each config file in config dir */ | ||||
|     do | ||||
|  | @ -301,11 +319,13 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) | |||
|             if (ConfigAlreadyExists(find_obj.cFileName)) | ||||
|             { | ||||
|                 if (flags & FLAG_WARN_DUPLICATES) | ||||
|                 { | ||||
|                     ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName); | ||||
|                 } | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (CheckReadAccess (config_dir, find_obj.cFileName)) | ||||
|             if (CheckReadAccess(config_dir, find_obj.cFileName)) | ||||
|             { | ||||
|                 AddConfigFileToList(group, find_obj.cFileName, config_dir); | ||||
|             } | ||||
|  | @ -316,11 +336,15 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) | |||
| 
 | ||||
|     /* optionally loop over each subdir */ | ||||
|     if (recurse_depth < 1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     find_handle = FindFirstFile (find_string, &find_obj); | ||||
|     find_handle = FindFirstFile(find_string, &find_obj); | ||||
|     if (find_handle == INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     do | ||||
|     { | ||||
|  | @ -389,13 +413,16 @@ IsSamePath(const wchar_t *path1, const wchar_t *path2) | |||
|     BOOL ret = false; | ||||
|     BY_HANDLE_FILE_INFORMATION info1, info2; | ||||
| 
 | ||||
|     if (_wcsicmp(path1, path2) == 0) return true; | ||||
|     if (_wcsicmp(path1, path2) == 0) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     if (GetFileInfo(path1, &info1) && GetFileInfo(path2, &info2)) | ||||
|     { | ||||
|         ret = (info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber | ||||
|                 && info1.nFileIndexLow == info2.nFileIndexLow | ||||
|                 && info1.nFileIndexHigh == info2.nFileIndexHigh); | ||||
|                && info1.nFileIndexLow == info2.nFileIndexLow | ||||
|                && info1.nFileIndexHigh == info2.nFileIndexHigh); | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
|  | @ -410,7 +437,9 @@ BuildFileList() | |||
|     static int root_gp, system_gp, persistent_gp; | ||||
| 
 | ||||
|     if (o.silent_connection) | ||||
|     { | ||||
|         issue_warnings = false; | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|      * If first time or no entries in the connection list reset groups and rescan | ||||
|  | @ -438,11 +467,11 @@ BuildFileList() | |||
|         flags |= FLAG_WARN_DUPLICATES | FLAG_WARN_MAX_CONFIGS; | ||||
|     } | ||||
| 
 | ||||
|     BuildFileList0 (o.config_dir, recurse_depth, root_gp, flags); | ||||
|     BuildFileList0(o.config_dir, recurse_depth, root_gp, flags); | ||||
| 
 | ||||
|     if (!IsSamePath(o.global_config_dir, o.config_dir)) | ||||
|     { | ||||
|         BuildFileList0 (o.global_config_dir, recurse_depth, system_gp, flags); | ||||
|         BuildFileList0(o.global_config_dir, recurse_depth, system_gp, flags); | ||||
|     } | ||||
| 
 | ||||
|     if (o.service_state == service_connected | ||||
|  | @ -450,12 +479,14 @@ BuildFileList() | |||
|     { | ||||
|         if (!IsSamePath(o.config_auto_dir, o.config_dir)) | ||||
|         { | ||||
|             BuildFileList0 (o.config_auto_dir, recurse_depth, persistent_gp, flags); | ||||
|             BuildFileList0(o.config_auto_dir, recurse_depth, persistent_gp, flags); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (o.num_configs == 0 && issue_warnings) | ||||
|     { | ||||
|         ShowLocalizedMsg(IDS_NFO_NO_CONFIGS, o.config_dir, o.global_config_dir); | ||||
|     } | ||||
| 
 | ||||
|     ActivateConfigGroups(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,7 +25,9 @@ | |||
| #include "main.h" | ||||
| 
 | ||||
| void BuildFileList(void); | ||||
| 
 | ||||
| bool ConfigFileOptionExist(int, const char *); | ||||
| 
 | ||||
| void FreeConfigList(options_t *o); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										401
									
								
								options.c
								
								
								
								
							
							
						
						
									
										401
									
								
								options.c
								
								
								
								
							|  | @ -50,37 +50,37 @@ | |||
| extern options_t o; | ||||
| 
 | ||||
| static version_t | ||||
| MakeVersion (short ma, short mi, short b, short r) | ||||
| MakeVersion(short ma, short mi, short b, short r) | ||||
| { | ||||
|     version_t v = {ma, mi, b, r}; | ||||
|     return v; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| ExpandString (WCHAR *str, int max_len) | ||||
| ExpandString(WCHAR *str, int max_len) | ||||
| { | ||||
|   WCHAR expanded_string[MAX_PATH]; | ||||
|   int len = ExpandEnvironmentStringsW (str, expanded_string, _countof(expanded_string)); | ||||
|     WCHAR expanded_string[MAX_PATH]; | ||||
|     int len = ExpandEnvironmentStringsW(str, expanded_string, _countof(expanded_string)); | ||||
| 
 | ||||
|   if (len > max_len || len > (int) _countof(expanded_string)) | ||||
|   { | ||||
|       PrintDebug (L"Failed to expanded env vars in '%ls'. String too long", str); | ||||
|       return; | ||||
|   } | ||||
|   wcsncpy (str, expanded_string, max_len); | ||||
|     if (len > max_len || len > (int) _countof(expanded_string)) | ||||
|     { | ||||
|         PrintDebug(L"Failed to expanded env vars in '%ls'. String too long", str); | ||||
|         return; | ||||
|     } | ||||
|     wcsncpy(str, expanded_string, max_len); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ExpandOptions (void) | ||||
| ExpandOptions(void) | ||||
| { | ||||
|     ExpandString (o.exe_path, _countof(o.exe_path)); | ||||
|     ExpandString (o.config_dir, _countof(o.config_dir)); | ||||
|     ExpandString (o.global_config_dir, _countof(o.global_config_dir)); | ||||
|     ExpandString (o.config_auto_dir, _countof(o.config_auto_dir)); | ||||
|     ExpandString (o.log_dir, _countof(o.log_dir)); | ||||
|     ExpandString (o.editor, _countof(o.editor)); | ||||
|     ExpandString (o.log_viewer, _countof(o.log_viewer)); | ||||
|     ExpandString (o.install_path, _countof(o.install_path)); | ||||
|     ExpandString(o.exe_path, _countof(o.exe_path)); | ||||
|     ExpandString(o.config_dir, _countof(o.config_dir)); | ||||
|     ExpandString(o.global_config_dir, _countof(o.global_config_dir)); | ||||
|     ExpandString(o.config_auto_dir, _countof(o.config_auto_dir)); | ||||
|     ExpandString(o.log_dir, _countof(o.log_dir)); | ||||
|     ExpandString(o.editor, _countof(o.editor)); | ||||
|     ExpandString(o.log_viewer, _countof(o.log_viewer)); | ||||
|     ExpandString(o.install_path, _countof(o.install_path)); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | @ -157,8 +157,8 @@ add_option(options_t *options, int i, TCHAR **p) | |||
|         ++i; | ||||
|         _tcsncpy(options->priority_string, p[1], _countof(options->priority_string) - 1); | ||||
|     } | ||||
|     else if ( (streq(p[0], _T("append_string")) || | ||||
|              streq(p[0], _T("log_append"))) && p[1] ) | ||||
|     else if ( (streq(p[0], _T("append_string")) | ||||
|                || streq(p[0], _T("log_append"))) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         options->log_append = _ttoi(p[1]) ? 1 : 0; | ||||
|  | @ -181,22 +181,22 @@ add_option(options_t *options, int i, TCHAR **p) | |||
|     else if (streq(p[0], _T("allow_edit")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("allow_service")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("allow_password")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("allow_proxy")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("show_balloon")) && p[1]) | ||||
|     { | ||||
|  | @ -206,7 +206,7 @@ add_option(options_t *options, int i, TCHAR **p) | |||
|     else if (streq(p[0], _T("service_only")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("show_script_window")) && p[1]) | ||||
|     { | ||||
|  | @ -221,7 +221,7 @@ add_option(options_t *options, int i, TCHAR **p) | |||
|     else if (streq(p[0], _T("passphrase_attempts")) && p[1]) | ||||
|     { | ||||
|         ++i; | ||||
|         PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|         PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); | ||||
|     } | ||||
|     else if (streq(p[0], _T("connectscript_timeout")) && p[1]) | ||||
|     { | ||||
|  | @ -362,7 +362,9 @@ parse_argv(options_t *options, int argc, TCHAR **argv) | |||
|             { | ||||
|                 TCHAR *arg = argv[i + j]; | ||||
|                 if (_tcsncmp(arg, _T("--"), 2) == 0) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|                 p[j] = arg; | ||||
|             } | ||||
|         } | ||||
|  | @ -375,8 +377,8 @@ void | |||
| InitOptions(options_t *opt) | ||||
| { | ||||
|     CLEAR(*opt); | ||||
|     opt->netcmd_semaphore = InitSemaphore (NULL); | ||||
|     opt->version = MakeVersion (PACKAGE_VERSION_RESOURCE); | ||||
|     opt->netcmd_semaphore = InitSemaphore(NULL); | ||||
|     opt->version = MakeVersion(PACKAGE_VERSION_RESOURCE); | ||||
|     opt->clr_warning = RGB(0xff, 0, 0); | ||||
|     opt->clr_error = RGB(0xff, 0, 0); | ||||
| } | ||||
|  | @ -393,49 +395,67 @@ ProcessCommandLine(options_t *options, TCHAR *command_line) | |||
|     do | ||||
|     { | ||||
|         while (*pos == _T(' ')) | ||||
|         { | ||||
|             ++pos; | ||||
|         } | ||||
| 
 | ||||
|         if (*pos == _T('\0')) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         ++argc; | ||||
| 
 | ||||
|         while (*pos != _T('\0') && *pos != _T(' ')) | ||||
|            ++pos; | ||||
|         { | ||||
|             ++pos; | ||||
|         } | ||||
|     } | ||||
|     while (*pos != _T('\0')); | ||||
| 
 | ||||
|     if (argc == 0) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     /* Tokenize the arguments */ | ||||
|     argv = (TCHAR**) malloc(argc * sizeof(TCHAR*)); | ||||
|     argv = (TCHAR **) malloc(argc * sizeof(TCHAR *)); | ||||
|     pos = command_line; | ||||
|     argc = 0; | ||||
| 
 | ||||
|     do | ||||
|     { | ||||
|         while (*pos == _T(' ')) | ||||
|         { | ||||
|             pos++; | ||||
|         } | ||||
| 
 | ||||
|         if (*pos == _T('\0')) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         if (*pos == _T('\"')) | ||||
|         { | ||||
|             argv[argc++] = ++pos; | ||||
|             while (*pos != _T('\0') && *pos != _T('\"')) | ||||
|             { | ||||
|                 ++pos; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             argv[argc++] = pos; | ||||
|             while (*pos != _T('\0') && *pos != _T(' ')) | ||||
|             { | ||||
|                 ++pos; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (*pos == _T('\0')) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         *pos++ = _T('\0'); | ||||
|     } | ||||
|  | @ -445,7 +465,7 @@ ProcessCommandLine(options_t *options, TCHAR *command_line) | |||
| 
 | ||||
|     free(argv); | ||||
| 
 | ||||
|     ExpandOptions (); | ||||
|     ExpandOptions(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -458,52 +478,58 @@ CountConnState(conn_state_t check) | |||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (c->state == check) | ||||
|         { | ||||
|             ++count; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return count; | ||||
| } | ||||
| 
 | ||||
| connection_t* | ||||
| connection_t * | ||||
| GetConnByManagement(SOCKET sk) | ||||
| { | ||||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (c->manage.sk == sk) | ||||
|         { | ||||
|             return c; | ||||
|         } | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| connection_t* | ||||
| connection_t * | ||||
| GetConnByName(const WCHAR *name) | ||||
| { | ||||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (wcsicmp (c->config_file, name) == 0 | ||||
|         if (wcsicmp(c->config_file, name) == 0 | ||||
|             || wcsicmp(c->config_name, name) == 0) | ||||
|         { | ||||
|             return c; | ||||
|         } | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static BOOL | ||||
| BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_path_size) | ||||
| BrowseFolder(const WCHAR *initial_path, WCHAR *selected_path, size_t selected_path_size) | ||||
| { | ||||
|     IFileOpenDialog* pfd; | ||||
|     IFileOpenDialog *pfd; | ||||
|     HRESULT initResult, result, dialogResult = E_FAIL; | ||||
| 
 | ||||
|     // Create dialog
 | ||||
|     /* Create dialog */ | ||||
|     initResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); | ||||
|     if (FAILED(initResult)) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     result = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&pfd); | ||||
|     result = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void **)&pfd); | ||||
|     if (SUCCEEDED(result)) | ||||
|     { | ||||
|         // Select folders, not files
 | ||||
|         /* Select folders, not files */ | ||||
|         DWORD dwOptions; | ||||
|         result = pfd->lpVtbl->GetOptions(pfd, &dwOptions); | ||||
|         if (SUCCEEDED(result)) | ||||
|  | @ -512,24 +538,24 @@ BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_p | |||
|             result = pfd->lpVtbl->SetOptions(pfd, dwOptions); | ||||
|         } | ||||
| 
 | ||||
|         // Set initial path
 | ||||
|         IShellItem* psi; | ||||
|         result = SHCreateItemFromParsingName(initial_path, NULL, &IID_IShellItem, (void**)&psi); | ||||
|         /* Set initial path */ | ||||
|         IShellItem *psi; | ||||
|         result = SHCreateItemFromParsingName(initial_path, NULL, &IID_IShellItem, (void **)&psi); | ||||
|         if (SUCCEEDED(result)) | ||||
|         { | ||||
|             pfd->lpVtbl->SetFolder(pfd, psi); | ||||
|             psi->lpVtbl->Release(psi); | ||||
|         } | ||||
| 
 | ||||
|         // Show dialog and copy the selected file path if the user didn't cancel
 | ||||
|         /* Show dialog and copy the selected file path if the user didn't cancel */ | ||||
|         dialogResult = pfd->lpVtbl->Show(pfd, NULL); | ||||
|         if (SUCCEEDED(dialogResult)) | ||||
|         { | ||||
|             IShellItem* psi; | ||||
|             IShellItem *psi; | ||||
|             LPOLESTR path = NULL; | ||||
| 
 | ||||
|             result = pfd->lpVtbl->GetResult(pfd, &psi); | ||||
|             if(SUCCEEDED(result)) | ||||
|             if (SUCCEEDED(result)) | ||||
|             { | ||||
|                 result = psi->lpVtbl->GetDisplayName(psi, SIGDN_FILESYSPATH, &path); | ||||
|             } | ||||
|  | @ -548,65 +574,71 @@ BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_p | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Cleanup
 | ||||
|         /* Cleanup */ | ||||
|         pfd->lpVtbl->Release(pfd); | ||||
|     } | ||||
| 
 | ||||
|     if (initResult != RPC_E_CHANGED_MODE && SUCCEEDED(initResult)) | ||||
|     { | ||||
|         CoUninitialize(); //All successful CoInitializeEx calls must be balanced by a corresponding CoUninitialize
 | ||||
|         CoUninitialize(); /*All successful CoInitializeEx calls must be balanced by a corresponding CoUninitialize */ | ||||
|     } | ||||
| 
 | ||||
|     return SUCCEEDED(dialogResult); | ||||
| } | ||||
| 
 | ||||
| static BOOL | ||||
| CheckAdvancedDlgParams (HWND hdlg) | ||||
| CheckAdvancedDlgParams(HWND hdlg) | ||||
| { | ||||
|     WCHAR tmp_path[MAX_PATH]; | ||||
| 
 | ||||
|     /* replace empty entries by current values */ | ||||
|     if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_CONFIG_DIR)) == 0) | ||||
|         SetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir); | ||||
|     if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_LOG_DIR)) == 0) | ||||
|         SetDlgItemText (hdlg, ID_EDT_LOG_DIR, o.log_dir); | ||||
|     if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_CONFIG_EXT)) == 0) | ||||
|         SetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string); | ||||
|     if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_CONFIG_DIR)) == 0) | ||||
|     { | ||||
|         SetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir); | ||||
|     } | ||||
|     if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_LOG_DIR)) == 0) | ||||
|     { | ||||
|         SetDlgItemText(hdlg, ID_EDT_LOG_DIR, o.log_dir); | ||||
|     } | ||||
|     if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_CONFIG_EXT)) == 0) | ||||
|     { | ||||
|         SetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string); | ||||
|     } | ||||
| 
 | ||||
|     /* ensure paths are absolute */ | ||||
|     GetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     ExpandString (tmp_path, _countof(tmp_path)); | ||||
|     if (PathIsRelativeW (tmp_path)) | ||||
|     GetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     ExpandString(tmp_path, _countof(tmp_path)); | ||||
|     if (PathIsRelativeW(tmp_path)) | ||||
|     { | ||||
|         MessageBox (hdlg, L"Specified config directory is not an absolute path", | ||||
|                     L"Option error", MB_OK); | ||||
|         MessageBox(hdlg, L"Specified config directory is not an absolute path", | ||||
|                    L"Option error", MB_OK); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     GetDlgItemText (hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     ExpandString (tmp_path, _countof(tmp_path)); | ||||
|     if (PathIsRelativeW (tmp_path)) | ||||
|     GetDlgItemText(hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     ExpandString(tmp_path, _countof(tmp_path)); | ||||
|     if (PathIsRelativeW(tmp_path)) | ||||
|     { | ||||
|         MessageBox (hdlg, L"Specified log directory is not an absolute path", | ||||
|                     L"Option error", MB_OK); | ||||
|         MessageBox(hdlg, L"Specified log directory is not an absolute path", | ||||
|                    L"Option error", MB_OK); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     BOOL status; | ||||
|     int tmp = GetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, &status, FALSE); | ||||
|     int tmp = GetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, &status, FALSE); | ||||
|     /* Restrict the port offset to sensible range -- port used is this + upto ~4000 as connection index */ | ||||
|     if (!status || (tmp < 1 || tmp > 61000)) | ||||
|     { | ||||
|         MessageBox (hdlg, L"Specified port is not valid (must be in the range 1 to 61000)", | ||||
|                     L"Option error", MB_OK); | ||||
|         MessageBox(hdlg, L"Specified port is not valid (must be in the range 1 to 61000)", | ||||
|                    L"Option error", MB_OK); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); | ||||
|     if (!status || tmp < 0) | ||||
|     { | ||||
|         MessageBox (hdlg, L"Specified mute interval is not valid (must be a positive integer)", | ||||
|                     L"Option error", MB_OK); | ||||
|         MessageBox(hdlg, L"Specified mute interval is not valid (must be a positive integer)", | ||||
|                    L"Option error", MB_OK); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|  | @ -614,159 +646,202 @@ CheckAdvancedDlgParams (HWND hdlg) | |||
| } | ||||
| 
 | ||||
| static BOOL | ||||
| SaveAdvancedDlgParams (HWND hdlg) | ||||
| SaveAdvancedDlgParams(HWND hdlg) | ||||
| { | ||||
|     WCHAR tmp_path[MAX_PATH], tmp_path1[MAX_PATH]; | ||||
|     UINT tmp; | ||||
|     BOOL status; | ||||
| 
 | ||||
|     GetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir, _countof(o.config_dir)); | ||||
|     GetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir, _countof(o.config_dir)); | ||||
| 
 | ||||
|     GetDlgItemText (hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     wcsncpy (tmp_path1, tmp_path, _countof(tmp_path1)); | ||||
|     ExpandString (tmp_path1, _countof(tmp_path1)); | ||||
|     GetDlgItemText(hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); | ||||
|     wcsncpy(tmp_path1, tmp_path, _countof(tmp_path1)); | ||||
|     ExpandString(tmp_path1, _countof(tmp_path1)); | ||||
| 
 | ||||
|     if (EnsureDirExists (tmp_path1)) /* this will try to create the path if needed */ | ||||
|         wcsncpy (o.log_dir, tmp_path, _countof(o.log_dir)); /* save unexpanded path */ | ||||
|     if (EnsureDirExists(tmp_path1))  /* this will try to create the path if needed */ | ||||
|     { | ||||
|         wcsncpy(o.log_dir, tmp_path, _countof(o.log_dir));  /* save unexpanded path */ | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ShowLocalizedMsg(IDS_ERR_CREATE_PATH, L"Log", tmp_path1); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     GetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string, _countof(o.ext_string)); | ||||
|     GetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string, _countof(o.ext_string)); | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_PRECONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status && tmp > 0) o.preconnectscript_timeout = tmp; | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_PRECONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status && tmp > 0) | ||||
|     { | ||||
|         o.preconnectscript_timeout = tmp; | ||||
|     } | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_CONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status) o.connectscript_timeout = tmp; | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_CONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status) | ||||
|     { | ||||
|         o.connectscript_timeout = tmp; | ||||
|     } | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_DISCONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status && tmp > 0) o.disconnectscript_timeout = tmp; | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_DISCONNECT_TIMEOUT, &status, FALSE); | ||||
|     if (status && tmp > 0) | ||||
|     { | ||||
|         o.disconnectscript_timeout = tmp; | ||||
|     } | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, &status, FALSE); | ||||
|     if (status) o.mgmt_port_offset = tmp; | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, &status, FALSE); | ||||
|     if (status) | ||||
|     { | ||||
|         o.mgmt_port_offset = tmp; | ||||
|     } | ||||
| 
 | ||||
|     tmp = GetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); | ||||
|     if (status) o.popup_mute_interval = tmp; | ||||
|     tmp = GetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); | ||||
|     if (status) | ||||
|     { | ||||
|         o.popup_mute_interval = tmp; | ||||
|     } | ||||
| 
 | ||||
|     o.ovpn_engine = IsDlgButtonChecked(hdlg, ID_RB_ENGINE_OVPN3) ? | ||||
|         OPENVPN_ENGINE_OVPN3 : OPENVPN_ENGINE_OVPN2; | ||||
|                     OPENVPN_ENGINE_OVPN3 : OPENVPN_ENGINE_OVPN2; | ||||
| 
 | ||||
|     SaveRegistryKeys (); | ||||
|     ExpandOptions (); | ||||
|     SaveRegistryKeys(); | ||||
|     ExpandOptions(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| LoadAdvancedDlgParams (HWND hdlg) | ||||
| LoadAdvancedDlgParams(HWND hdlg) | ||||
| { | ||||
|     SetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir); | ||||
|     SetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string); | ||||
|     SetDlgItemText (hdlg, ID_EDT_LOG_DIR, o.log_dir); | ||||
|     SetDlgItemInt (hdlg, ID_EDT_PRECONNECT_TIMEOUT, o.preconnectscript_timeout, FALSE); | ||||
|     SetDlgItemInt (hdlg, ID_EDT_CONNECT_TIMEOUT, o.connectscript_timeout, FALSE); | ||||
|     SetDlgItemInt (hdlg, ID_EDT_DISCONNECT_TIMEOUT, o.disconnectscript_timeout, FALSE); | ||||
|     SetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, o.mgmt_port_offset, FALSE); | ||||
|     SetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, o.popup_mute_interval, FALSE); | ||||
|     SetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir); | ||||
|     SetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string); | ||||
|     SetDlgItemText(hdlg, ID_EDT_LOG_DIR, o.log_dir); | ||||
|     SetDlgItemInt(hdlg, ID_EDT_PRECONNECT_TIMEOUT, o.preconnectscript_timeout, FALSE); | ||||
|     SetDlgItemInt(hdlg, ID_EDT_CONNECT_TIMEOUT, o.connectscript_timeout, FALSE); | ||||
|     SetDlgItemInt(hdlg, ID_EDT_DISCONNECT_TIMEOUT, o.disconnectscript_timeout, FALSE); | ||||
|     SetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, o.mgmt_port_offset, FALSE); | ||||
|     SetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, o.popup_mute_interval, FALSE); | ||||
|     if (o.config_menu_view == 0) | ||||
|         CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); | ||||
|     { | ||||
|         CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); | ||||
|     } | ||||
|     else if (o.config_menu_view == 1) | ||||
|         CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); | ||||
|     { | ||||
|         CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); | ||||
|     } | ||||
|     else if (o.config_menu_view == 2) | ||||
|         CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); | ||||
|     { | ||||
|         CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); | ||||
|     } | ||||
| 
 | ||||
|     /* BALLOON3 sets echo msg display to  auto, BALLOON4 to never */ | ||||
|     if (o.disable_popup_messages) | ||||
|         CheckRadioButton (hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON4); | ||||
|     { | ||||
|         CheckRadioButton(hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON4); | ||||
|     } | ||||
|     else | ||||
|         CheckRadioButton (hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON3); | ||||
|     { | ||||
|         CheckRadioButton(hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON3); | ||||
|     } | ||||
| 
 | ||||
| #ifdef ENABLE_OVPN3 | ||||
|     CheckRadioButton(hdlg, ID_RB_ENGINE_OVPN2, ID_RB_ENGINE_OVPN3, | ||||
|         o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? ID_RB_ENGINE_OVPN3 : ID_RB_ENGINE_OVPN2); | ||||
|                      o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? ID_RB_ENGINE_OVPN3 : ID_RB_ENGINE_OVPN2); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| INT_PTR CALLBACK | ||||
| AdvancedSettingsDlgProc (HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) | ||||
| AdvancedSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) | ||||
| { | ||||
|     LPPSHNOTIFY psn; | ||||
| 
 | ||||
|     switch(msg) { | ||||
|     switch (msg) | ||||
|     { | ||||
| 
 | ||||
|     case WM_INITDIALOG: | ||||
|         /* Limit extension editbox to 4 chars. */ | ||||
|         SendMessage (GetDlgItem(hwndDlg, ID_EDT_CONFIG_EXT), EM_SETLIMITTEXT, 4, 0); | ||||
|         /* Limit management port editbox to 5 chars */ | ||||
|         SendMessage(GetDlgItem(hwndDlg, ID_EDT_MGMT_PORT), EM_SETLIMITTEXT, 5, 0); | ||||
|         /* Populate UI */ | ||||
|         LoadAdvancedDlgParams (hwndDlg); | ||||
|         break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         switch (LOWORD(wParam)) { | ||||
|         WCHAR path[MAX_PATH]; | ||||
| 
 | ||||
|         case ID_BTN_CONFIG_DIR: | ||||
|             GetDlgItemText (hwndDlg, ID_EDT_CONFIG_DIR, path, _countof(path)); | ||||
|             if (BrowseFolder (path, path, _countof(path))) | ||||
|                 SetDlgItemText (hwndDlg, ID_EDT_CONFIG_DIR, path); | ||||
|         case WM_INITDIALOG: | ||||
|             /* Limit extension editbox to 4 chars. */ | ||||
|             SendMessage(GetDlgItem(hwndDlg, ID_EDT_CONFIG_EXT), EM_SETLIMITTEXT, 4, 0); | ||||
|             /* Limit management port editbox to 5 chars */ | ||||
|             SendMessage(GetDlgItem(hwndDlg, ID_EDT_MGMT_PORT), EM_SETLIMITTEXT, 5, 0); | ||||
|             /* Populate UI */ | ||||
|             LoadAdvancedDlgParams(hwndDlg); | ||||
|             break; | ||||
| 
 | ||||
|         case ID_BTN_LOG_DIR: | ||||
|             GetDlgItemText (hwndDlg, ID_EDT_LOG_DIR, path, _countof(path)); | ||||
|             if (BrowseFolder (path, path, _countof(path))) | ||||
|                 SetDlgItemText (hwndDlg, ID_EDT_LOG_DIR, path); | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|         case WM_COMMAND: | ||||
|             switch (LOWORD(wParam)) | ||||
|             { | ||||
|                 WCHAR path[MAX_PATH]; | ||||
| 
 | ||||
|     case WM_NOTIFY: | ||||
|         psn = (LPPSHNOTIFY) lParam; | ||||
|         if (psn->hdr.code == (UINT) PSN_KILLACTIVE) | ||||
|         { | ||||
|             SetWindowLongPtr (hwndDlg, DWLP_MSGRESULT, (CheckAdvancedDlgParams(hwndDlg) ? FALSE : TRUE)); | ||||
|             return TRUE; | ||||
|         } | ||||
|         if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|         { | ||||
|             BOOL status = SaveAdvancedDlgParams (hwndDlg); | ||||
|             SetWindowLongPtr (hwndDlg, DWLP_MSGRESULT, status? PSNRET_NOERROR:PSNRET_INVALID); | ||||
|             return TRUE; | ||||
|         } | ||||
|         if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) | ||||
|             o.config_menu_view = 2; | ||||
|         else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON1)) | ||||
|             o.config_menu_view = 1; | ||||
|         else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) | ||||
|             o.config_menu_view = 0; | ||||
|         else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) | ||||
|             o.disable_popup_messages = 0; | ||||
|         else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) | ||||
|             o.disable_popup_messages = 1; | ||||
|         break; | ||||
|                 case ID_BTN_CONFIG_DIR: | ||||
|                     GetDlgItemText(hwndDlg, ID_EDT_CONFIG_DIR, path, _countof(path)); | ||||
|                     if (BrowseFolder(path, path, _countof(path))) | ||||
|                     { | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_CONFIG_DIR, path); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case ID_BTN_LOG_DIR: | ||||
|                     GetDlgItemText(hwndDlg, ID_EDT_LOG_DIR, path, _countof(path)); | ||||
|                     if (BrowseFolder(path, path, _countof(path))) | ||||
|                     { | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_LOG_DIR, path); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case WM_NOTIFY: | ||||
|             psn = (LPPSHNOTIFY) lParam; | ||||
|             if (psn->hdr.code == (UINT) PSN_KILLACTIVE) | ||||
|             { | ||||
|                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckAdvancedDlgParams(hwndDlg) ? FALSE : TRUE)); | ||||
|                 return TRUE; | ||||
|             } | ||||
|             if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|             { | ||||
|                 BOOL status = SaveAdvancedDlgParams(hwndDlg); | ||||
|                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, status ? PSNRET_NOERROR : PSNRET_INVALID); | ||||
|                 return TRUE; | ||||
|             } | ||||
|             if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) | ||||
|             { | ||||
|                 o.config_menu_view = 2; | ||||
|             } | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON1)) | ||||
|             { | ||||
|                 o.config_menu_view = 1; | ||||
|             } | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) | ||||
|             { | ||||
|                 o.config_menu_view = 0; | ||||
|             } | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) | ||||
|             { | ||||
|                 o.disable_popup_messages = 0; | ||||
|             } | ||||
|             else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) | ||||
|             { | ||||
|                 o.disable_popup_messages = 1; | ||||
|             } | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     return FALSE; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| CompareStringExpanded (const WCHAR *str1, const WCHAR *str2) | ||||
| CompareStringExpanded(const WCHAR *str1, const WCHAR *str2) | ||||
| { | ||||
|     WCHAR str1_cpy[MAX_PATH], str2_cpy[MAX_PATH]; | ||||
| 
 | ||||
|     wcsncpy (str1_cpy, str1, _countof(str1_cpy)); | ||||
|     wcsncpy (str2_cpy, str2, _countof(str2_cpy)); | ||||
|     wcsncpy(str1_cpy, str1, _countof(str1_cpy)); | ||||
|     wcsncpy(str2_cpy, str2, _countof(str2_cpy)); | ||||
|     str1_cpy[MAX_PATH-1] = L'\0'; | ||||
|     str2_cpy[MAX_PATH-1] = L'\0'; | ||||
| 
 | ||||
|     ExpandString (str1_cpy, _countof(str1_cpy)); | ||||
|     ExpandString (str2_cpy, _countof(str2_cpy)); | ||||
|     ExpandString(str1_cpy, _countof(str1_cpy)); | ||||
|     ExpandString(str2_cpy, _countof(str2_cpy)); | ||||
| 
 | ||||
|     return wcsicmp (str1_cpy, str2_cpy); | ||||
|     return wcsicmp(str1_cpy, str2_cpy); | ||||
| } | ||||
| 
 | ||||
| /* Hide the password save options from user */ | ||||
|  |  | |||
							
								
								
									
										17
									
								
								options.h
								
								
								
								
							
							
						
						
									
										17
									
								
								options.h
								
								
								
								
							|  | @ -249,16 +249,27 @@ typedef struct { | |||
| } options_t; | ||||
| 
 | ||||
| void InitOptions(options_t *); | ||||
| 
 | ||||
| void ProcessCommandLine(options_t *, TCHAR *); | ||||
| 
 | ||||
| int CountConnState(conn_state_t); | ||||
| connection_t* GetConnByManagement(SOCKET); | ||||
| connection_t* GetConnByName(const WCHAR *config_name); | ||||
| 
 | ||||
| connection_t *GetConnByManagement(SOCKET); | ||||
| 
 | ||||
| connection_t *GetConnByName(const WCHAR *config_name); | ||||
| 
 | ||||
| INT_PTR CALLBACK ScriptSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); | ||||
| 
 | ||||
| INT_PTR CALLBACK ConnectionSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); | ||||
| 
 | ||||
| INT_PTR CALLBACK AdvancedSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); | ||||
| 
 | ||||
| void DisableSavePasswords(connection_t *); | ||||
| 
 | ||||
| void DisablePopupMessages(connection_t *); | ||||
| 
 | ||||
| void ExpandOptions(void); | ||||
| 
 | ||||
| int CompareStringExpanded(const WCHAR *str1, const WCHAR *str2); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* ifndef OPTIONS_H */ | ||||
|  |  | |||
							
								
								
									
										4
									
								
								pkcs11.c
								
								
								
								
							
							
						
						
									
										4
									
								
								pkcs11.c
								
								
								
								
							|  | @ -553,7 +553,7 @@ display_certificate(HWND parent, connection_t *c, UINT i) | |||
|  */ | ||||
| #if defined(HAVE_LIBCRYPTUI) || defined (_MSC_VER) | ||||
|         CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, l->pe[i].cert.ctx, | ||||
|                                parent, L"Certificate", 0, NULL); | ||||
|                               parent, L"Certificate", 0, NULL); | ||||
| #else | ||||
|         (void) i; | ||||
|         (void) parent; | ||||
|  | @ -652,7 +652,7 @@ QueryPkcs11DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) | |||
|                 } | ||||
|                 if (ln->hdr.code == NM_DBLCLK && ln->iItem >= 0) | ||||
|                 { | ||||
|                    display_certificate(hwndDlg, c, (UINT) ln->iItem); | ||||
|                     display_certificate(hwndDlg, c, (UINT) ln->iItem); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
|  |  | |||
|  | @ -37,7 +37,9 @@ void | |||
| init_debug() | ||||
| { | ||||
|     if (!fp) | ||||
|     { | ||||
|         fp = _wfopen(L"C:\\Windows\\Temp\\openvpn-plap-debug.txt", L"a+,ccs=UTF-8"); | ||||
|     } | ||||
|     InitializeCriticalSection(&log_write); | ||||
| } | ||||
| 
 | ||||
|  | @ -45,7 +47,9 @@ void | |||
| uninit_debug() | ||||
| { | ||||
|     if (fp) | ||||
|     { | ||||
|         fclose(fp); | ||||
|     } | ||||
|     DeleteCriticalSection(&log_write); | ||||
| } | ||||
| 
 | ||||
|  | @ -58,8 +62,8 @@ x_dmsg(const char *file, const char *func, const wchar_t *fmt, ...) | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     va_list  args; | ||||
|     va_start (args, fmt); | ||||
|     va_list args; | ||||
|     va_start(args, fmt); | ||||
|     vswprintf(buf, _countof(buf), fmt, args); | ||||
|     va_end(args); | ||||
| 
 | ||||
|  | @ -93,7 +97,7 @@ void | |||
| debug_print_guid(const GUID *riid, const wchar_t *context) | ||||
| { | ||||
|     RPC_CSTR str = NULL; | ||||
|     if (UuidToStringA((GUID*) riid, &str) == RPC_S_OK) | ||||
|     if (UuidToStringA((GUID *) riid, &str) == RPC_S_OK) | ||||
|     { | ||||
|         x_dmsg(NULL, NULL, L"%ls %hs", context, str); | ||||
|         RpcStringFreeA(&str); | ||||
|  |  | |||
|  | @ -36,14 +36,17 @@ extern "C" { | |||
| #endif | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| #define dmsg(fmt, ...) x_dmsg(__FILE__, __func__, fmt, ##__VA_ARGS__) | ||||
| #define dmsg(fmt, ...) x_dmsg(__FILE__, __func__, fmt, ## __VA_ARGS__) | ||||
| #else | ||||
| #define dmsg(...) do { ; } while (0) | ||||
| #define dmsg(...) do {; } while (0) | ||||
| #endif | ||||
| 
 | ||||
| void x_dmsg(const char *file, const char *func, const wchar_t *fmt, ...); | ||||
| 
 | ||||
| void init_debug(); | ||||
| 
 | ||||
| void uninit_debug(); | ||||
| 
 | ||||
| void debug_print_guid(const GUID *riid, const wchar_t *context); | ||||
| 
 | ||||
| /* Shortcuts for cumbersome calls to COM methods of an object through its v-table */ | ||||
|  | @ -64,6 +67,5 @@ void debug_print_guid(const GUID *riid, const wchar_t *context); | |||
|  */ | ||||
| #ifdef DEFINE_GUID | ||||
| DEFINE_GUID(CLSID_OpenVPNProvider, 0x4fbb8b67, 0xcf02, 0x4982, 0xa7, 0xa8, | ||||
|                                    0x3d, 0xd0, 0x6a, 0x2c, 0x2e, 0xbd); | ||||
|             0x3d, 0xd0, 0x6a, 0x2c, 0x2e, 0xbd); | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,36 +59,55 @@ extern DWORD status_menu_id; | |||
| /* Methods in IConnectableCredentialProviderCredential that we need to define */ | ||||
| 
 | ||||
| /* IUnknown */ | ||||
| static HRESULT WINAPI QueryInterface(ICCPC *this, REFIID riid, void** ppv); | ||||
| static HRESULT WINAPI QueryInterface(ICCPC *this, REFIID riid, void **ppv); | ||||
| 
 | ||||
| static ULONG WINAPI AddRef(ICCPC *this); | ||||
| 
 | ||||
| static ULONG WINAPI Release(ICCPC *this); | ||||
| 
 | ||||
| /* ICredentialProviderCredential */ | ||||
| static HRESULT WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e); | ||||
| 
 | ||||
| static HRESULT WINAPI UnAdvise(ICCPC *this); | ||||
| 
 | ||||
| static HRESULT WINAPI SetSelected(ICCPC *this, BOOL *auto_logon); | ||||
| 
 | ||||
| static HRESULT WINAPI SetDeselected(ICCPC *this); | ||||
| 
 | ||||
| static HRESULT WINAPI GetFieldState(ICCPC *this, DWORD field, CREDENTIAL_PROVIDER_FIELD_STATE *fs, | ||||
|         CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis); | ||||
|                                     CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis); | ||||
| 
 | ||||
| static HRESULT WINAPI GetStringValue(ICCPC *this, DWORD index, WCHAR **ws); | ||||
| 
 | ||||
| static HRESULT WINAPI GetBitmapValue(ICCPC *this, DWORD field, HBITMAP *bmp); | ||||
| 
 | ||||
| static HRESULT WINAPI GetSubmitButtonValue(ICCPC *this, DWORD field, DWORD *adjacent); | ||||
| 
 | ||||
| static HRESULT WINAPI SetStringValue(ICCPC *this, DWORD field, const WCHAR *ws); | ||||
| 
 | ||||
| static HRESULT WINAPI GetCheckboxValue(ICCPC *this, DWORD field, BOOL *checked, wchar_t **label); | ||||
| 
 | ||||
| static HRESULT WINAPI GetComboBoxValueCount(ICCPC *this, DWORD field, DWORD *items, DWORD *selected_item); | ||||
| 
 | ||||
| static HRESULT WINAPI GetComboBoxValueAt(ICCPC *this, DWORD field, DWORD item, wchar_t **item_value); | ||||
| 
 | ||||
| static HRESULT WINAPI SetCheckboxValue(ICCPC *this, DWORD field, BOOL checked); | ||||
| 
 | ||||
| static HRESULT WINAPI SetComboBoxSelectedValue(ICCPC *this, DWORD field, DWORD selected_item); | ||||
| 
 | ||||
| static HRESULT WINAPI CommandLinkClicked(ICCPC *this, DWORD field); | ||||
| 
 | ||||
| static HRESULT WINAPI GetSerialization(ICCPC *this, | ||||
|     CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, | ||||
|     CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, | ||||
|     CREDENTIAL_PROVIDER_STATUS_ICON *icon); | ||||
|                                        CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, | ||||
|                                        CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, | ||||
|                                        CREDENTIAL_PROVIDER_STATUS_ICON *icon); | ||||
| 
 | ||||
| static HRESULT WINAPI ReportResult(ICCPC *this, NTSTATUS status, NTSTATUS substatus, | ||||
|     wchar_t **status_text, CREDENTIAL_PROVIDER_STATUS_ICON *icon); | ||||
|                                    wchar_t **status_text, CREDENTIAL_PROVIDER_STATUS_ICON *icon); | ||||
| 
 | ||||
| /* IConnectableCredentialProviderCredential */ | ||||
| static HRESULT WINAPI Connect(ICCPC *this, IQueryContinueWithStatus *qc); | ||||
| 
 | ||||
| static HRESULT WINAPI Disconnect(ICCPC *this); | ||||
| 
 | ||||
| /* use a static table for filling in the methods */ | ||||
|  | @ -169,7 +188,7 @@ Release(ICCPC *this) | |||
| } | ||||
| 
 | ||||
| static HRESULT WINAPI | ||||
| QueryInterface(ICCPC *this, REFIID riid, void** ppv) | ||||
| QueryInterface(ICCPC *this, REFIID riid, void **ppv) | ||||
| { | ||||
|     HRESULT hr; | ||||
| 
 | ||||
|  | @ -205,7 +224,8 @@ QueryInterface(ICCPC *this, REFIID riid, void** ppv) | |||
|  * making callbacks to notify changes asynchronously | ||||
|  */ | ||||
| static HRESULT | ||||
| WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) | ||||
| WINAPI | ||||
| Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) | ||||
| { | ||||
|     HWND hwnd; | ||||
| 
 | ||||
|  | @ -214,7 +234,9 @@ WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) | |||
|     OpenVPNConnection *oc = (OpenVPNConnection *) this; | ||||
| 
 | ||||
|     if (oc->events) | ||||
|     { | ||||
|         RELEASE(oc->events); | ||||
|     } | ||||
|     oc->events = e; | ||||
|     ADDREF(e); | ||||
| 
 | ||||
|  | @ -236,7 +258,9 @@ UnAdvise(ICCPC *this) | |||
|     OpenVPNConnection *oc = (OpenVPNConnection *) this; | ||||
| 
 | ||||
|     if (oc->events) | ||||
|     { | ||||
|         RELEASE(oc->events); | ||||
|     } | ||||
|     oc->events = NULL; | ||||
|     return S_OK; | ||||
| } | ||||
|  | @ -282,8 +306,8 @@ SetDeselected(ICCPC *this) | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| GetFieldState(UNUSED ICCPC *this, DWORD field, | ||||
|         CREDENTIAL_PROVIDER_FIELD_STATE *fs, | ||||
|         CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis) | ||||
|               CREDENTIAL_PROVIDER_FIELD_STATE *fs, | ||||
|               CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis) | ||||
| { | ||||
|     HRESULT hr; | ||||
| 
 | ||||
|  | @ -292,9 +316,13 @@ GetFieldState(UNUSED ICCPC *this, DWORD field, | |||
|     if (field < _countof(field_states)) | ||||
|     { | ||||
|         if (fs) | ||||
|         { | ||||
|             *fs = field_states[field]; | ||||
|         } | ||||
|         if (fis) | ||||
|         { | ||||
|             *fis = (field_desc[field].cpft == CPFT_SUBMIT_BUTTON) ?  CPFIS_FOCUSED : CPFIS_NONE; | ||||
|         } | ||||
|         hr = S_OK; | ||||
|     } | ||||
|     else | ||||
|  | @ -418,7 +446,7 @@ SetStringValue(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED const WCHAR *ws ) | |||
| 
 | ||||
| static HRESULT WINAPI | ||||
| GetCheckboxValue(UNUSED ICCPC *this, UNUSED DWORD field, | ||||
|     UNUSED BOOL *checked, UNUSED wchar_t **label) | ||||
|                  UNUSED BOOL *checked, UNUSED wchar_t **label) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return E_NOTIMPL; | ||||
|  | @ -426,7 +454,7 @@ GetCheckboxValue(UNUSED ICCPC *this, UNUSED DWORD field, | |||
| 
 | ||||
| static HRESULT WINAPI | ||||
| GetComboBoxValueCount(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD *items, | ||||
|     UNUSED DWORD *selected_item) | ||||
|                       UNUSED DWORD *selected_item) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return E_NOTIMPL; | ||||
|  | @ -434,7 +462,7 @@ GetComboBoxValueCount(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD *item | |||
| 
 | ||||
| static HRESULT WINAPI | ||||
| GetComboBoxValueAt(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD item, | ||||
|     UNUSED wchar_t **item_value) | ||||
|                    UNUSED wchar_t **item_value) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return E_NOTIMPL; | ||||
|  | @ -470,8 +498,8 @@ CommandLinkClicked(UNUSED ICCPC *this, UNUSED DWORD field) | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, | ||||
|     UNUSED CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, | ||||
|     CREDENTIAL_PROVIDER_STATUS_ICON *icon) | ||||
|                  UNUSED CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, | ||||
|                  CREDENTIAL_PROVIDER_STATUS_ICON *icon) | ||||
| { | ||||
|     HRESULT hr = S_OK; | ||||
| 
 | ||||
|  | @ -490,9 +518,13 @@ GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *re | |||
|         if (text && icon) | ||||
|         { | ||||
|             if (oc->connect_cancelled) | ||||
|             { | ||||
|                 hr = SHStrDupW(LoadLocalizedString(IDS_NFO_CONN_CANCELLED), text); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 hr = SHStrDupW(LoadLocalizedString(IDS_NFO_CONN_FAILED, oc->display_name), text); | ||||
|             } | ||||
| 
 | ||||
|             *icon = CPSI_ERROR; | ||||
|         } | ||||
|  | @ -513,7 +545,7 @@ GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *re | |||
| 
 | ||||
| static HRESULT WINAPI | ||||
| ReportResult(UNUSED ICCPC *this, UNUSED NTSTATUS status, UNUSED NTSTATUS substatus, | ||||
|     UNUSED wchar_t **status_text, UNUSED CREDENTIAL_PROVIDER_STATUS_ICON *icon) | ||||
|              UNUSED wchar_t **status_text, UNUSED CREDENTIAL_PROVIDER_STATUS_ICON *icon) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return E_NOTIMPL; | ||||
|  | @ -525,8 +557,8 @@ NotifyEvents(OpenVPNConnection *oc, const wchar_t *status) | |||
| { | ||||
|     if (oc->events) | ||||
|     { | ||||
|         oc->events->lpVtbl->SetFieldString(oc->events, (ICredentialProviderCredential*) oc, | ||||
|             STATUS_FIELD_INDEX, status); | ||||
|         oc->events->lpVtbl->SetFieldString(oc->events, (ICredentialProviderCredential *) oc, | ||||
|                                            STATUS_FIELD_INDEX, status); | ||||
|     } | ||||
|     if (oc->qc) | ||||
|     { | ||||
|  | @ -646,7 +678,7 @@ again: | |||
|     oc->qc = NULL; | ||||
|     SetActiveProfile(NULL); | ||||
| 
 | ||||
|     dmsg (L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel"); | ||||
|     dmsg(L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel"); | ||||
| 
 | ||||
|     return ISCONNECTED(oc->c) ? S_OK : E_FAIL; | ||||
| } | ||||
|  | @ -655,7 +687,7 @@ static HRESULT WINAPI | |||
| Disconnect(ICCPC *this) | ||||
| { | ||||
|     OpenVPNConnection *oc = (OpenVPNConnection *) this; | ||||
|     dmsg (L"profile <%ls>", oc->display_name); | ||||
|     dmsg(L"profile <%ls>", oc->display_name); | ||||
| 
 | ||||
|     NotifyEvents(oc, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTING)); | ||||
| 
 | ||||
|  | @ -679,8 +711,9 @@ OVPNConnection_Initialize(OpenVPNConnection *this, connection_t *conn, const wch | |||
| } | ||||
| 
 | ||||
| /* Copy field descriptor -- caller will free using CoTaskMemFree, alloc using compatible allocator */ | ||||
| HRESULT CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, | ||||
|                         const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in) | ||||
| HRESULT | ||||
| CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, | ||||
|                     const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in) | ||||
| { | ||||
|     HRESULT hr = S_OK; | ||||
| 
 | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ static const CREDENTIAL_PROVIDER_FIELD_STATE field_states[] = | |||
| 
 | ||||
| /** Helper to deep copy field descriptor */ | ||||
| HRESULT CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, | ||||
|                  const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in); | ||||
|                             const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in); | ||||
| 
 | ||||
| typedef struct OpenVPNConnection OpenVPNConnection; | ||||
| 
 | ||||
|  |  | |||
|  | @ -48,25 +48,29 @@ DllMain(HINSTANCE hinstDll, DWORD dwReason, UNUSED LPVOID pReserved) | |||
|             DisableThreadLibraryCalls(hinstDll); | ||||
|             init_debug(); | ||||
|             break; | ||||
| 
 | ||||
|         case DLL_PROCESS_DETACH: | ||||
|             uninit_debug(); | ||||
|             break; | ||||
| 
 | ||||
|         case DLL_THREAD_ATTACH: | ||||
|         case DLL_THREAD_DETACH: | ||||
|         break; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     hinst_global = hinstDll; /* global */ | ||||
|     return TRUE; | ||||
| } | ||||
| 
 | ||||
| void dll_addref() | ||||
| void | ||||
| dll_addref() | ||||
| { | ||||
|     InterlockedIncrement(&dll_ref_count); | ||||
|     dmsg(L"ref_count after increment = %lu", dll_ref_count); | ||||
| } | ||||
| 
 | ||||
| void dll_release() | ||||
| void | ||||
| dll_release() | ||||
| { | ||||
|     InterlockedDecrement(&dll_ref_count); | ||||
|     dmsg(L"ref_count after decrement = %lu", dll_ref_count); | ||||
|  | @ -79,9 +83,13 @@ void dll_release() | |||
| 
 | ||||
| /* ClassFactory methods we have to implement */ | ||||
| static ULONG WINAPI AddRef(IClassFactory *this); | ||||
| 
 | ||||
| static ULONG WINAPI Release(IClassFactory *this); | ||||
| 
 | ||||
| static HRESULT WINAPI QueryInterface(IClassFactory *this, REFIID riid, void **ppv); | ||||
| 
 | ||||
| static HRESULT WINAPI CreateInstance(IClassFactory *this, IUnknown *iunk, REFIID riid, void **ppv); | ||||
| 
 | ||||
| static HRESULT WINAPI LockServer(IClassFactory *this, BOOL lock); | ||||
| 
 | ||||
| /* template object for creation */ | ||||
|  | @ -116,7 +124,7 @@ static HRESULT WINAPI | |||
| QueryInterface(IClassFactory *this, REFIID riid, void **ppv) | ||||
| { | ||||
|     HRESULT hr; | ||||
|     dmsg (L"Entry"); | ||||
|     dmsg(L"Entry"); | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
|     debug_print_guid(riid, L"In CF_Queryinterface with iid = "); | ||||
|  | @ -184,7 +192,8 @@ LockServer(UNUSED IClassFactory *this, BOOL lock) | |||
| } | ||||
| 
 | ||||
| /* exported methods */ | ||||
| STDAPI DllCanUnloadNow() | ||||
| STDAPI | ||||
| DllCanUnloadNow() | ||||
| { | ||||
|     HRESULT hr; | ||||
| 
 | ||||
|  | @ -206,7 +215,8 @@ STDAPI DllCanUnloadNow() | |||
|  * create class of type rclsid. We support only OpenVPNProvider | ||||
|  * class and check it here. | ||||
|  */ | ||||
| STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) | ||||
| STDAPI | ||||
| DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     HRESULT hr; | ||||
|  |  | |||
|  | @ -33,10 +33,12 @@ extern HINSTANCE hinst_global; | |||
| HRESULT OpenVPNProvider_CreateInstance(REFIID riid, void **ppv); | ||||
| 
 | ||||
| void dll_addref(); | ||||
| 
 | ||||
| void dll_release(); | ||||
| 
 | ||||
| STDAPI DllCanUnloadNow(); | ||||
| STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv); | ||||
| 
 | ||||
| STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  |  | |||
|  | @ -47,25 +47,31 @@ typedef struct OpenVPNProvider | |||
| 
 | ||||
| /* methods we have to implement */ | ||||
| static HRESULT WINAPI QueryInterface(ICredentialProvider *this, REFIID riid, void **ppv); | ||||
| 
 | ||||
| static ULONG WINAPI AddRef(ICredentialProvider *this); | ||||
| 
 | ||||
| static ULONG WINAPI Release(ICredentialProvider *this); | ||||
| 
 | ||||
| static HRESULT WINAPI SetUsageScenario(ICredentialProvider *this, | ||||
|     CREDENTIAL_PROVIDER_USAGE_SCENARIO us, DWORD flags); | ||||
|                                        CREDENTIAL_PROVIDER_USAGE_SCENARIO us, DWORD flags); | ||||
| 
 | ||||
| static HRESULT WINAPI SetSerialization(ICredentialProvider *this, | ||||
|     const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs); | ||||
|                                        const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs); | ||||
| 
 | ||||
| static HRESULT WINAPI Advise(ICredentialProvider *this, ICredentialProviderEvents *e, UINT_PTR context); | ||||
| 
 | ||||
| static HRESULT WINAPI UnAdvise(ICredentialProvider *this); | ||||
| 
 | ||||
| static HRESULT WINAPI GetFieldDescriptorCount(ICredentialProvider *this, DWORD *count); | ||||
| 
 | ||||
| static HRESULT WINAPI GetFieldDescriptorAt(ICredentialProvider *this, DWORD index, | ||||
|     CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd); | ||||
|                                            CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd); | ||||
| 
 | ||||
| static HRESULT WINAPI GetCredentialCount(ICredentialProvider *this, DWORD *count, | ||||
|     DWORD *default_cred, BOOL *autologon_default); | ||||
|                                          DWORD *default_cred, BOOL *autologon_default); | ||||
| 
 | ||||
| static HRESULT WINAPI GetCredentialAt(ICredentialProvider *this, DWORD index, | ||||
|     ICredentialProviderCredential **c); | ||||
|                                       ICredentialProviderCredential **c); | ||||
| 
 | ||||
| /* a helper function for generating our connection array */ | ||||
| static HRESULT CreateOVPNConnectionArray(OpenVPNProvider *op); | ||||
|  | @ -118,7 +124,7 @@ OpenVPNProvider_free(OpenVPNProvider *this) | |||
|     { | ||||
|         if (this->connections[i]) | ||||
|         { | ||||
|             RELEASE((ICCPC*) this->connections[i]); | ||||
|             RELEASE((ICCPC *) this->connections[i]); | ||||
|         } | ||||
|     } | ||||
|     /* Destroy GUI threads and any associated data */ | ||||
|  | @ -200,7 +206,7 @@ QueryInterface(ICredentialProvider *this, REFIID riid, void **ppv) | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| SetUsageScenario(ICredentialProvider *this, | ||||
|     CREDENTIAL_PROVIDER_USAGE_SCENARIO us, UNUSED DWORD flags) | ||||
|                  CREDENTIAL_PROVIDER_USAGE_SCENARIO us, UNUSED DWORD flags) | ||||
| { | ||||
|     /* I think flags may be ignored for PLAP */ | ||||
| 
 | ||||
|  | @ -223,7 +229,7 @@ SetUsageScenario(ICredentialProvider *this, | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| SetSerialization(UNUSED ICredentialProvider *this, | ||||
|     UNUSED const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs) | ||||
|                  UNUSED const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return E_NOTIMPL; | ||||
|  | @ -234,7 +240,7 @@ SetSerialization(UNUSED ICredentialProvider *this, | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| Advise(UNUSED ICredentialProvider *this, | ||||
|     UNUSED ICredentialProviderEvents *e, UNUSED UINT_PTR ctx) | ||||
|        UNUSED ICredentialProviderEvents *e, UNUSED UINT_PTR ctx) | ||||
| { | ||||
|     dmsg(L"Entry"); | ||||
|     return S_OK; | ||||
|  | @ -273,7 +279,7 @@ GetFieldDescriptorCount(UNUSED ICredentialProvider *this, DWORD *count) | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| GetFieldDescriptorAt(UNUSED ICredentialProvider *this, DWORD index, | ||||
|     CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd) | ||||
|                      CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd) | ||||
| { | ||||
|     HRESULT hr = E_OUTOFMEMORY; | ||||
| 
 | ||||
|  | @ -315,7 +321,7 @@ GetFieldDescriptorAt(UNUSED ICredentialProvider *this, DWORD index, | |||
|  */ | ||||
| static HRESULT WINAPI | ||||
| GetCredentialCount(ICredentialProvider *this, DWORD *count, DWORD *default_cred, | ||||
|     BOOL *autologon_default) | ||||
|                    BOOL *autologon_default) | ||||
| { | ||||
|     OpenVPNProvider *op = (OpenVPNProvider *) this; | ||||
| 
 | ||||
|  | @ -341,7 +347,7 @@ GetCredentialAt(ICredentialProvider *this, DWORD index, ICredentialProviderCrede | |||
| 
 | ||||
|     OpenVPNProvider *op = (OpenVPNProvider *) this; | ||||
| 
 | ||||
|     if(index < op->conn_count && ic) | ||||
|     if (index < op->conn_count && ic) | ||||
|     { | ||||
|         hr = QUERY_INTERFACE((ICredentialProviderCredential *) op->connections[index], | ||||
|                              &IID_ICredentialProviderCredential, (void **)ic); | ||||
|  | @ -374,7 +380,7 @@ CreateOVPNConnectionArray(OpenVPNProvider *op) | |||
|     /* delete previous connections if any */ | ||||
|     for (size_t i = 0; i < op->conn_count; i++) | ||||
|     { | ||||
|         RELEASE((ICCPC*) op->connections[i]); | ||||
|         RELEASE((ICCPC *) op->connections[i]); | ||||
|     } | ||||
|     op->conn_count = 0; | ||||
| 
 | ||||
|  | @ -404,7 +410,7 @@ CreateOVPNConnectionArray(OpenVPNProvider *op) | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 RELEASE((ICCPC*) oc); | ||||
|                 RELEASE((ICCPC *) oc); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|  |  | |||
							
								
								
									
										98
									
								
								plap/stub.c
								
								
								
								
							
							
						
						
									
										98
									
								
								plap/stub.c
								
								
								
								
							|  | @ -31,7 +31,8 @@ | |||
| #include "localization.h" | ||||
| #include "ui_glue.h" | ||||
| 
 | ||||
| void PrintDebugMsg(wchar_t *msg) | ||||
| void | ||||
| PrintDebugMsg(wchar_t *msg) | ||||
| { | ||||
|     x_dmsg("GUI-source", "", msg); | ||||
| } | ||||
|  | @ -40,143 +41,176 @@ void | |||
| ErrorExit(UNUSED int exit_code, const wchar_t *msg) | ||||
| { | ||||
|     if (msg) | ||||
|     { | ||||
|         MessageBoxExW(NULL, msg, TEXT(PACKAGE_NAME), | ||||
|                       MB_OK | MB_SETFOREGROUND|MB_ICONERROR, GetGUILanguage()); | ||||
|     } | ||||
|     DetachAllOpenVPN(); | ||||
|     /* do not exit */ | ||||
| } | ||||
| 
 | ||||
| void RecreatePopupMenus(void) | ||||
| void | ||||
| RecreatePopupMenus(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| void CreatePopupMenus(void) | ||||
| void | ||||
| CreatePopupMenus(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| void OnNotifyTray(UNUSED LPARAM lp) | ||||
| void | ||||
| OnNotifyTray(UNUSED LPARAM lp) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void OnDestroyTray(void) | ||||
| void | ||||
| OnDestroyTray(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void ShowTrayIcon(void) | ||||
| void | ||||
| ShowTrayIcon(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void SetTrayIcon(UNUSED conn_state_t state) | ||||
| void | ||||
| SetTrayIcon(UNUSED conn_state_t state) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void SetMenuStatus(UNUSED connection_t *c, UNUSED conn_state_t state) | ||||
| void | ||||
| SetMenuStatus(UNUSED connection_t *c, UNUSED conn_state_t state) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void SetServiceMenuStatus(void) | ||||
| void | ||||
| SetServiceMenuStatus(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void ShowTrayBalloon(UNUSED wchar_t *s1, UNUSED wchar_t *s2) | ||||
| void | ||||
| ShowTrayBalloon(UNUSED wchar_t *s1, UNUSED wchar_t *s2) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void CheckAndSetTrayIcon(void) | ||||
| void | ||||
| CheckAndSetTrayIcon(void) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void RunPreconnectScript(UNUSED connection_t *c) | ||||
| void | ||||
| RunPreconnectScript(UNUSED connection_t *c) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void RunConnectScript(UNUSED connection_t *ic, UNUSED int run_as_service) | ||||
| void | ||||
| RunConnectScript(UNUSED connection_t *ic, UNUSED int run_as_service) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void RunDisconnectScript(UNUSED connection_t *c, UNUSED int run_as_service) | ||||
| void | ||||
| RunDisconnectScript(UNUSED connection_t *c, UNUSED int run_as_service) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| int SaveKeyPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) | ||||
| int | ||||
| SaveKeyPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) | ||||
| { | ||||
|     return 1; | ||||
| } | ||||
| int SaveAuthPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) | ||||
| int | ||||
| SaveAuthPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) | ||||
| { | ||||
|     return 1; | ||||
| } | ||||
| int SaveUsername(UNUSED const WCHAR *config_name, UNUSED const WCHAR *username) | ||||
| int | ||||
| SaveUsername(UNUSED const WCHAR *config_name, UNUSED const WCHAR *username) | ||||
| { | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| int RecallKeyPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) | ||||
| int | ||||
| RecallKeyPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| int RecallAuthPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) | ||||
| int | ||||
| RecallAuthPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| int RecallUsername(UNUSED const WCHAR *config_name, UNUSED WCHAR *username) | ||||
| int | ||||
| RecallUsername(UNUSED const WCHAR *config_name, UNUSED WCHAR *username) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| void DeleteSavedAuthPass(UNUSED const WCHAR *config_name) | ||||
| void | ||||
| DeleteSavedAuthPass(UNUSED const WCHAR *config_name) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| void DeleteSavedKeyPass(UNUSED const WCHAR *config_name) | ||||
| void | ||||
| DeleteSavedKeyPass(UNUSED const WCHAR *config_name) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void DeleteSavedPasswords(UNUSED const WCHAR *config_name) | ||||
| void | ||||
| DeleteSavedPasswords(UNUSED const WCHAR *config_name) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| BOOL IsAuthPassSaved(UNUSED const WCHAR *config_name) | ||||
| BOOL | ||||
| IsAuthPassSaved(UNUSED const WCHAR *config_name) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| BOOL IsKeyPassSaved(UNUSED const WCHAR *config_name) | ||||
| BOOL | ||||
| IsKeyPassSaved(UNUSED const WCHAR *config_name) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| void env_item_del_all(UNUSED struct env_item *head) | ||||
| void | ||||
| env_item_del_all(UNUSED struct env_item *head) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| void process_setenv(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) | ||||
| void | ||||
| process_setenv(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| BOOL AuthorizeConfig(UNUSED const connection_t *c) | ||||
| BOOL | ||||
| AuthorizeConfig(UNUSED const connection_t *c) | ||||
| { | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| void echo_msg_process(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) | ||||
| void | ||||
| echo_msg_process(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| void echo_msg_clear(UNUSED connection_t *c, UNUSED BOOL clear_history) | ||||
| void | ||||
| echo_msg_clear(UNUSED connection_t *c, UNUSED BOOL clear_history) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| void echo_msg_load(UNUSED connection_t *c) | ||||
| void | ||||
| echo_msg_load(UNUSED connection_t *c) | ||||
| { | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| BOOL CheckKeyFileWriteAccess(UNUSED connection_t *c) | ||||
| BOOL | ||||
| CheckKeyFileWriteAccess(UNUSED connection_t *c) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ OnStop_(connection_t *c, UNUSED char *msg) | |||
|  * in PLAP context. | ||||
|  */ | ||||
| static void | ||||
| OnInfoMsg_(connection_t* c, char* msg) | ||||
| OnInfoMsg_(connection_t *c, char *msg) | ||||
| { | ||||
|     if (strbegins(msg, "CR_TEXT:")) | ||||
|     { | ||||
|  | @ -167,7 +167,7 @@ InitializeUI(HINSTANCE hinstance) | |||
|     WSADATA wsaData; | ||||
| 
 | ||||
|     /* a session local semaphore to detect second instance */ | ||||
|     HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME"-PLAP"); | ||||
|     HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME "-PLAP"); | ||||
| 
 | ||||
|     srand(time(NULL)); | ||||
|     /* try to lock the semaphore, else we are not the first instance */ | ||||
|  | @ -188,7 +188,7 @@ InitializeUI(HINSTANCE hinstance) | |||
| 
 | ||||
|     dmsg(L"Starting OpenVPN UI v%hs", PACKAGE_VERSION); | ||||
| 
 | ||||
|     if(!GetModuleHandle(_T("RICHED20.DLL"))) | ||||
|     if (!GetModuleHandle(_T("RICHED20.DLL"))) | ||||
|     { | ||||
|         LoadLibrary(_T("RICHED20.DLL")); | ||||
|     } | ||||
|  | @ -202,20 +202,20 @@ InitializeUI(HINSTANCE hinstance) | |||
|      * Some handlers are replaced by local functions | ||||
|      */ | ||||
|     mgmt_rtmsg_handler handler[] = { | ||||
|       { ready_,    OnReady }, | ||||
|       { hold_,     OnHold }, | ||||
|       { log_,      OnLogLine }, | ||||
|       { state_,    OnStateChange_ }, | ||||
|       { password_, OnPassword_ }, | ||||
|       { proxy_,    OnProxy_ }, | ||||
|       { stop_,     OnStop_ }, | ||||
|       { needok_,   OnNeedOk_ }, | ||||
|       { needstr_,  OnNeedStr_ }, | ||||
|       { echo_,     OnEcho }, | ||||
|       { bytecount_,OnByteCount }, | ||||
|       { infomsg_,  OnInfoMsg_ }, | ||||
|       { timeout_,  OnTimeout }, | ||||
|       { 0,         NULL} | ||||
|         { ready_,    OnReady }, | ||||
|         { hold_,     OnHold }, | ||||
|         { log_,      OnLogLine }, | ||||
|         { state_,    OnStateChange_ }, | ||||
|         { password_, OnPassword_ }, | ||||
|         { proxy_,    OnProxy_ }, | ||||
|         { stop_,     OnStop_ }, | ||||
|         { needok_,   OnNeedOk_ }, | ||||
|         { needstr_,  OnNeedStr_ }, | ||||
|         { echo_,     OnEcho }, | ||||
|         { bytecount_, OnByteCount }, | ||||
|         { infomsg_,  OnInfoMsg_ }, | ||||
|         { timeout_,  OnTimeout }, | ||||
|         { 0,         NULL} | ||||
|     }; | ||||
| 
 | ||||
|     InitManagement(handler); | ||||
|  | @ -267,10 +267,14 @@ InitializeUI(HINSTANCE hinstance) | |||
| 
 | ||||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (c->flags & FLAG_DAEMON_PERSISTENT) num_persistent++; | ||||
|         if (c->flags & FLAG_DAEMON_PERSISTENT) | ||||
|         { | ||||
|             num_persistent++; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (o.service_state == service_disconnected && num_persistent > 0) { | ||||
|     if (o.service_state == service_disconnected && num_persistent > 0) | ||||
|     { | ||||
|         dmsg(L"Attempting to start automatic service"); | ||||
|         StartAutomaticService(); | ||||
|         CheckServiceStatus(); | ||||
|  | @ -301,7 +305,7 @@ FindPLAPConnections(connection_t *conn[], size_t max_count) | |||
| } | ||||
| 
 | ||||
| static void | ||||
| WaitOnThread (connection_t *c, DWORD timeout) | ||||
| WaitOnThread(connection_t *c, DWORD timeout) | ||||
| { | ||||
|     HANDLE h = OpenThread(THREAD_ALL_ACCESS, FALSE, c->threadId); | ||||
|     if (!h) | ||||
|  | @ -311,8 +315,8 @@ WaitOnThread (connection_t *c, DWORD timeout) | |||
|     } | ||||
| 
 | ||||
|     DWORD exit_code; | ||||
|     if (WaitForSingleObject(h, timeout) == WAIT_OBJECT_0 && | ||||
|         GetExitCodeThread(h, &exit_code) && exit_code != STILL_ACTIVE) | ||||
|     if (WaitForSingleObject(h, timeout) == WAIT_OBJECT_0 | ||||
|         && GetExitCodeThread(h, &exit_code) && exit_code != STILL_ACTIVE) | ||||
|     { | ||||
|         dmsg(L"Connection thread closed"); | ||||
|         goto out; | ||||
|  | @ -320,7 +324,7 @@ WaitOnThread (connection_t *c, DWORD timeout) | |||
| 
 | ||||
|     /* Kill the thread */ | ||||
|     dmsg(L"Force terminating a connection thread"); | ||||
|     TerminateThread (h, 1); | ||||
|     TerminateThread(h, 1); | ||||
|     c->hwndStatus = NULL; | ||||
|     c->threadId = 0; | ||||
| 
 | ||||
|  | @ -365,7 +369,7 @@ GetConnectionStatusText(connection_t *c, wchar_t *status, DWORD len) | |||
| void | ||||
| SetParentWindow(HWND hwnd) | ||||
| { | ||||
|    o.hWnd = hwnd; | ||||
|     o.hWnd = hwnd; | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -442,7 +446,7 @@ DeleteUI(void) | |||
|     FreeConfigList(&o); | ||||
|     CloseSemaphore(o.session_semaphore); | ||||
|     WSACleanup(); | ||||
|     memset (&o, 0, sizeof(o)); | ||||
|     memset(&o, 0, sizeof(o)); | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -527,7 +531,7 @@ RunProgressDialog(connection_t *c, PFTASKDIALOGCALLBACK cb_fn, LONG_PTR cb_data) | |||
|         .cButtons = _countof(extra_buttons), | ||||
|         .pButtons = extra_buttons, | ||||
|         .dwCommonButtons = TDCBF_CANCEL_BUTTON|TDCBF_RETRY_BUTTON, | ||||
|         .pszWindowTitle = L""PACKAGE_NAME" PLAP", | ||||
|         .pszWindowTitle = L""PACKAGE_NAME " PLAP", | ||||
|         .pszMainInstruction = main_text, | ||||
|         .pszContent = L"Starting", /* updated in progress callback */ | ||||
|         .pfCallback = cb_fn, | ||||
|  |  | |||
							
								
								
									
										272
									
								
								proxy.c
								
								
								
								
							
							
						
						
									
										272
									
								
								proxy.c
								
								
								
								
							|  | @ -52,95 +52,95 @@ ProxySettingsDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lPa | |||
| 
 | ||||
|     switch (msg) | ||||
|     { | ||||
|     case WM_INITDIALOG: | ||||
|         hIcon = LoadLocalizedIcon(ID_ICO_APP); | ||||
|         if (hIcon) | ||||
|         { | ||||
|             SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); | ||||
|             SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); | ||||
|         } | ||||
| 
 | ||||
|         /* Limit Port editbox to 5 chars. */ | ||||
|         SendMessage(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), EM_SETLIMITTEXT, 5, 0); | ||||
| 
 | ||||
|         LoadProxySettings(hwndDlg); | ||||
|         break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         switch (LOWORD(wParam)) | ||||
|         { | ||||
|         case ID_RB_PROXY_OPENVPN: | ||||
|             if (HIWORD(wParam) == BN_CLICKED) | ||||
|         case WM_INITDIALOG: | ||||
|             hIcon = LoadLocalizedIcon(ID_ICO_APP); | ||||
|             if (hIcon) | ||||
|             { | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); | ||||
|                 SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); | ||||
|                 SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); | ||||
|             } | ||||
| 
 | ||||
|             /* Limit Port editbox to 5 chars. */ | ||||
|             SendMessage(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), EM_SETLIMITTEXT, 5, 0); | ||||
| 
 | ||||
|             LoadProxySettings(hwndDlg); | ||||
|             break; | ||||
| 
 | ||||
|         case WM_COMMAND: | ||||
|             switch (LOWORD(wParam)) | ||||
|             { | ||||
|                 case ID_RB_PROXY_OPENVPN: | ||||
|                     if (HIWORD(wParam) == BN_CLICKED) | ||||
|                     { | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case ID_RB_PROXY_MSIE: | ||||
|                     if (HIWORD(wParam) == BN_CLICKED) | ||||
|                     { | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case ID_RB_PROXY_MANUAL: | ||||
|                     if (HIWORD(wParam) == BN_CLICKED) | ||||
|                     { | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), TRUE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), TRUE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), TRUE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), TRUE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), TRUE); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), TRUE); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case ID_RB_PROXY_HTTP: | ||||
|                     if (HIWORD(wParam) == BN_CLICKED) | ||||
|                     { | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address); | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 case ID_RB_PROXY_SOCKS: | ||||
|                     if (HIWORD(wParam) == BN_CLICKED) | ||||
|                     { | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address); | ||||
|                         SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case ID_RB_PROXY_MSIE: | ||||
|             if (HIWORD(wParam) == BN_CLICKED) | ||||
|         case WM_NOTIFY: | ||||
|             psn = (LPPSHNOTIFY) lParam; | ||||
|             if (psn->hdr.code == (UINT) PSN_KILLACTIVE) | ||||
|             { | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); | ||||
|                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckProxySettings(hwndDlg) ? FALSE : TRUE)); | ||||
|                 return TRUE; | ||||
|             } | ||||
|             else if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|             { | ||||
|                 SaveProxySettings(hwndDlg); | ||||
|                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); | ||||
|                 return TRUE; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case ID_RB_PROXY_MANUAL: | ||||
|             if (HIWORD(wParam) == BN_CLICKED) | ||||
|             { | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), TRUE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), TRUE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), TRUE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), TRUE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), TRUE); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), TRUE); | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case ID_RB_PROXY_HTTP: | ||||
|             if (HIWORD(wParam) == BN_CLICKED) | ||||
|             { | ||||
|                 SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address); | ||||
|                 SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port); | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case ID_RB_PROXY_SOCKS: | ||||
|             if (HIWORD(wParam) == BN_CLICKED) | ||||
|             { | ||||
|                 SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address); | ||||
|                 SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case WM_NOTIFY: | ||||
|         psn = (LPPSHNOTIFY) lParam; | ||||
|         if (psn->hdr.code == (UINT) PSN_KILLACTIVE) | ||||
|         { | ||||
|             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckProxySettings(hwndDlg) ? FALSE : TRUE)); | ||||
|         case WM_CLOSE: | ||||
|             EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|             return TRUE; | ||||
|         } | ||||
|         else if (psn->hdr.code == (UINT) PSN_APPLY) | ||||
|         { | ||||
|             SaveProxySettings(hwndDlg); | ||||
|             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); | ||||
|             return TRUE; | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case WM_CLOSE: | ||||
|         EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|         return TRUE; | ||||
|     } | ||||
|     return FALSE; | ||||
| } | ||||
|  | @ -250,9 +250,9 @@ SaveProxySettings(HWND hwndDlg) | |||
|         proxy_type_string[0] = _T('0'); | ||||
| 
 | ||||
|         GetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address, | ||||
|                     _countof(o.proxy_http_address)); | ||||
|                        _countof(o.proxy_http_address)); | ||||
|         GetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port, | ||||
|                     _countof(o.proxy_http_port)); | ||||
|                        _countof(o.proxy_http_port)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  | @ -260,9 +260,9 @@ SaveProxySettings(HWND hwndDlg) | |||
|         proxy_type_string[0] = _T('1'); | ||||
| 
 | ||||
|         GetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address, | ||||
|                     _countof(o.proxy_socks_address)); | ||||
|                        _countof(o.proxy_socks_address)); | ||||
|         GetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port, | ||||
|                     _countof(o.proxy_socks_port)); | ||||
|                        _countof(o.proxy_socks_port)); | ||||
|     } | ||||
| 
 | ||||
|     /* Open Registry for writing */ | ||||
|  | @ -300,7 +300,9 @@ GetProxyRegistrySettings() | |||
|     _sntprintf_0(proxy_subkey, _T("%ls\\proxy"), GUI_REGKEY_HKCU); | ||||
|     status = RegOpenKeyEx(HKEY_CURRENT_USER, proxy_subkey, 0, KEY_READ, ®key); | ||||
|     if (status != ERROR_SUCCESS) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     /* get registry settings */ | ||||
|     GetRegistryValue(regkey, _T("proxy_http_address"), o.proxy_http_address, _countof(o.proxy_http_address)); | ||||
|  | @ -338,53 +340,57 @@ ProxyAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 
 | ||||
|     switch (msg) | ||||
|     { | ||||
|     case WM_INITDIALOG: | ||||
|         /* Set connection for this dialog and show it */ | ||||
|         c = (connection_t *) lParam; | ||||
|         TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); | ||||
|         if (c->state == resuming) | ||||
|             ForceForegroundWindow(hwndDlg); | ||||
|         else | ||||
|             SetForegroundWindow(hwndDlg); | ||||
|         break; | ||||
| 
 | ||||
|     case WM_COMMAND: | ||||
|         switch (LOWORD(wParam)) | ||||
|         { | ||||
|         case ID_EDT_PROXY_USER: | ||||
|             if (HIWORD(wParam) == EN_UPDATE) | ||||
|         case WM_INITDIALOG: | ||||
|             /* Set connection for this dialog and show it */ | ||||
|             c = (connection_t *) lParam; | ||||
|             TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); | ||||
|             if (c->state == resuming) | ||||
|             { | ||||
|                 int len = Edit_GetTextLength((HWND) lParam); | ||||
|                 EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE)); | ||||
|                 ForceForegroundWindow(hwndDlg); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 SetForegroundWindow(hwndDlg); | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case IDOK: | ||||
|             c = (connection_t *) GetProp(hwndDlg, cfgProp); | ||||
|             proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS"); | ||||
|         case WM_COMMAND: | ||||
|             switch (LOWORD(wParam)) | ||||
|             { | ||||
|                 case ID_EDT_PROXY_USER: | ||||
|                     if (HIWORD(wParam) == EN_UPDATE) | ||||
|                     { | ||||
|                         int len = Edit_GetTextLength((HWND) lParam); | ||||
|                         EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE)); | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|             snprintf(fmt, sizeof(fmt), "username \"%s Proxy\" \"%%s\"", proxy_type); | ||||
|             ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_USER); | ||||
|                 case IDOK: | ||||
|                     c = (connection_t *) GetProp(hwndDlg, cfgProp); | ||||
|                     proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS"); | ||||
| 
 | ||||
|             snprintf(fmt, sizeof(fmt), "password \"%s Proxy\" \"%%s\"", proxy_type); | ||||
|             ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_PASS); | ||||
|                     snprintf(fmt, sizeof(fmt), "username \"%s Proxy\" \"%%s\"", proxy_type); | ||||
|                     ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_USER); | ||||
| 
 | ||||
|                     snprintf(fmt, sizeof(fmt), "password \"%s Proxy\" \"%%s\"", proxy_type); | ||||
|                     ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_PASS); | ||||
| 
 | ||||
|                     EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|                     return TRUE; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|         case WM_OVPN_STATE: /* state changed -- destroy the dialog */ | ||||
|             EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|             return TRUE; | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case WM_OVPN_STATE: /* state changed -- destroy the dialog */ | ||||
|         EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|         return TRUE; | ||||
|         case WM_CLOSE: | ||||
|             EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|             return TRUE; | ||||
| 
 | ||||
|     case WM_CLOSE: | ||||
|         EndDialog(hwndDlg, LOWORD(wParam)); | ||||
|         return TRUE; | ||||
| 
 | ||||
|     case WM_NCDESTROY: | ||||
|         RemoveProp(hwndDlg, cfgProp); | ||||
|         break; | ||||
|         case WM_NCDESTROY: | ||||
|             RemoveProp(hwndDlg, cfgProp); | ||||
|             break; | ||||
|     } | ||||
|     return FALSE; | ||||
| } | ||||
|  | @ -428,13 +434,15 @@ QueryWindowsProxySettings(const url_scheme scheme, LPCSTR host) | |||
|         LPWSTR old_url = auto_config_url; | ||||
|         DWORD flags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; | ||||
|         if (WinHttpDetectAutoProxyConfigUrl(flags, &auto_config_url)) | ||||
|         { | ||||
|             GlobalFree(old_url); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (auto_config_url) | ||||
|     { | ||||
|         HINTERNET session = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, | ||||
|             WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); | ||||
|                                         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); | ||||
|         if (session) | ||||
|         { | ||||
|             int size = _snwprintf(NULL, 0, L"%ls://%hs", UrlSchemeStr(scheme), host) + 1; | ||||
|  | @ -476,7 +484,9 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, | |||
|                  LPCSTR *type, LPCWSTR *host, LPCWSTR *port) | ||||
| { | ||||
|     if (proxy_str == NULL) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     LPCWSTR delim = L"; "; | ||||
|     LPWSTR ctx = NULL; | ||||
|  | @ -518,9 +528,13 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, | |||
|         { | ||||
|             LPWSTR server = token; | ||||
|             if (css) | ||||
|             { | ||||
|                 server = css + 3; | ||||
|             } | ||||
|             else if (eq) | ||||
|             { | ||||
|                 server = eq + 1; | ||||
|             } | ||||
| 
 | ||||
|             /* IPv6 addresses are surrounded by brackets */ | ||||
|             LPWSTR port_delim; | ||||
|  | @ -529,7 +543,9 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, | |||
|                 server += 1; | ||||
|                 LPWSTR end = wcschr(server, ']'); | ||||
|                 if (end == NULL) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 *end++ = '\0'; | ||||
| 
 | ||||
|                 port_delim = (*end == ':' ? end : NULL); | ||||
|  | @ -538,15 +554,21 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, | |||
|             { | ||||
|                 port_delim = wcsrchr(server, ':'); | ||||
|                 if (port_delim) | ||||
|                 { | ||||
|                     *port_delim = '\0'; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             *type = (scheme == HTTPS_URL ? "HTTP" : "SOCKS"); | ||||
|             *host = server; | ||||
|             if (port_delim) | ||||
|             { | ||||
|                 *port = port_delim + 1; | ||||
|             } | ||||
|             else | ||||
|                 *port = (scheme == HTTPS_URL ? L"80": L"1080"); | ||||
|             { | ||||
|                 *port = (scheme == HTTPS_URL ? L"80" : L"1080"); | ||||
|             } | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|  | @ -565,17 +587,23 @@ OnProxy(connection_t *c, char *line) | |||
|     LPSTR proto, host; | ||||
|     char *pos = strchr(line, ','); | ||||
|     if (pos == NULL) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     proto = ++pos; | ||||
|     pos = strchr(pos, ','); | ||||
|     if (pos == NULL) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     *pos = '\0'; | ||||
|     host = ++pos; | ||||
|     if (host[0] == '\0') | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     LPCSTR type = "NONE"; | ||||
|     LPCWSTR addr = L"", port = L""; | ||||
|  |  | |||
							
								
								
									
										4
									
								
								proxy.h
								
								
								
								
							
							
						
						
									
										4
									
								
								proxy.h
								
								
								
								
							|  | @ -23,13 +23,17 @@ | |||
| #define PROXY_H | ||||
| 
 | ||||
| INT_PTR CALLBACK ProxySettingsDialogFunc(HWND, UINT, WPARAM, LPARAM); | ||||
| 
 | ||||
| void QueryProxyAuth(connection_t *, proxy_t); | ||||
| 
 | ||||
| void OnProxy(connection_t *, char *); | ||||
| 
 | ||||
| int CheckProxySettings(HWND); | ||||
| 
 | ||||
| void LoadProxySettings(HWND); | ||||
| 
 | ||||
| void SaveProxySettings(HWND); | ||||
| 
 | ||||
| void GetProxyRegistrySettings(); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										393
									
								
								registry.c
								
								
								
								
							
							
						
						
									
										393
									
								
								registry.c
								
								
								
								
							|  | @ -43,159 +43,174 @@ struct regkey_str { | |||
|     int len; | ||||
|     const WCHAR *value; | ||||
| } regkey_str[] = { | ||||
|       {L"config_dir", o.config_dir, _countof(o.config_dir), L"%USERPROFILE%\\OpenVPN\\config"}, | ||||
|       {L"config_ext", o.ext_string, _countof(o.ext_string), L"ovpn"}, | ||||
|       {L"log_dir", o.log_dir, _countof(o.log_dir), L"%USERPROFILE%\\OpenVPN\\log"} | ||||
|     }; | ||||
|     {L"config_dir", o.config_dir, _countof(o.config_dir), L"%USERPROFILE%\\OpenVPN\\config"}, | ||||
|     {L"config_ext", o.ext_string, _countof(o.ext_string), L"ovpn"}, | ||||
|     {L"log_dir", o.log_dir, _countof(o.log_dir), L"%USERPROFILE%\\OpenVPN\\log"} | ||||
| }; | ||||
| 
 | ||||
| struct regkey_int { | ||||
|     const WCHAR *name; | ||||
|     DWORD *var; | ||||
|     DWORD value; | ||||
| } regkey_int[] = { | ||||
|       {L"log_append", &o.log_append, 0}, | ||||
|       {L"iservice_admin", &o.iservice_admin, 1}, | ||||
|       {L"show_balloon", &o.show_balloon, 1}, | ||||
|       {L"silent_connection", &o.silent_connection, 0}, | ||||
|       {L"preconnectscript_timeout", &o.preconnectscript_timeout, 10}, | ||||
|       {L"connectscript_timeout", &o.connectscript_timeout, 30}, | ||||
|       {L"disconnectscript_timeout", &o.disconnectscript_timeout, 10}, | ||||
|       {L"show_script_window", &o.show_script_window, 0}, | ||||
|       {L"config_menu_view", &o.config_menu_view, CONFIG_VIEW_AUTO}, | ||||
|       {L"popup_mute_interval", &o.popup_mute_interval, 24}, | ||||
|       {L"disable_popup_messages", &o.disable_popup_messages, 0}, | ||||
|       {L"management_port_offset", &o.mgmt_port_offset, 25340}, | ||||
|       {L"enable_peristent_connections", &o.enable_persistent, 2}, | ||||
|       {L"enable_auto_restart", &o.enable_auto_restart, 1}, | ||||
|       {L"ovpn_engine", &o.ovpn_engine, OPENVPN_ENGINE_OVPN2} | ||||
|     }; | ||||
|     {L"log_append", &o.log_append, 0}, | ||||
|     {L"iservice_admin", &o.iservice_admin, 1}, | ||||
|     {L"show_balloon", &o.show_balloon, 1}, | ||||
|     {L"silent_connection", &o.silent_connection, 0}, | ||||
|     {L"preconnectscript_timeout", &o.preconnectscript_timeout, 10}, | ||||
|     {L"connectscript_timeout", &o.connectscript_timeout, 30}, | ||||
|     {L"disconnectscript_timeout", &o.disconnectscript_timeout, 10}, | ||||
|     {L"show_script_window", &o.show_script_window, 0}, | ||||
|     {L"config_menu_view", &o.config_menu_view, CONFIG_VIEW_AUTO}, | ||||
|     {L"popup_mute_interval", &o.popup_mute_interval, 24}, | ||||
|     {L"disable_popup_messages", &o.disable_popup_messages, 0}, | ||||
|     {L"management_port_offset", &o.mgmt_port_offset, 25340}, | ||||
|     {L"enable_peristent_connections", &o.enable_persistent, 2}, | ||||
|     {L"enable_auto_restart", &o.enable_auto_restart, 1}, | ||||
|     {L"ovpn_engine", &o.ovpn_engine, OPENVPN_ENGINE_OVPN2} | ||||
| }; | ||||
| 
 | ||||
| static int | ||||
| RegValueExists (HKEY regkey, const WCHAR *name) | ||||
| RegValueExists(HKEY regkey, const WCHAR *name) | ||||
| { | ||||
|     return (RegQueryValueEx (regkey, name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS); | ||||
|     return (RegQueryValueEx(regkey, name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| GetGlobalRegistryKeys() | ||||
| { | ||||
|   TCHAR windows_dir[MAX_PATH]; | ||||
|   HKEY regkey; | ||||
|     TCHAR windows_dir[MAX_PATH]; | ||||
|     HKEY regkey; | ||||
| 
 | ||||
|   if (!GetWindowsDirectory(windows_dir, _countof(windows_dir))) { | ||||
|     /* can't get windows dir */ | ||||
|     ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR); | ||||
|     /* Use a default value */ | ||||
|     _sntprintf_0(windows_dir, L"C:\\Windows"); | ||||
|   } | ||||
| 
 | ||||
|   /* set default editor and log_viewer as a fallback for opening config/log files */ | ||||
|   _sntprintf_0(o.editor, L"%ls\\%ls", windows_dir, L"System32\\notepad.exe"); | ||||
|   _sntprintf_0(o.log_viewer, L"%ls", o.editor); | ||||
| 
 | ||||
|   /* Get path to OpenVPN installation. */ | ||||
|   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\OpenVPN"), 0, KEY_READ, ®key) | ||||
|       != ERROR_SUCCESS) | ||||
|     if (!GetWindowsDirectory(windows_dir, _countof(windows_dir))) | ||||
|     { | ||||
|       /* registry key not found */ | ||||
|       regkey = NULL; | ||||
|       ShowLocalizedMsg(IDS_ERR_OPEN_REGISTRY); | ||||
|     } | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T(""), o.install_path, _countof(o.install_path)) | ||||
|       || _tcslen(o.install_path) == 0) | ||||
|     { | ||||
|       /* error reading registry value */ | ||||
|       if (regkey) | ||||
|           ShowLocalizedMsg(IDS_ERR_READING_REGISTRY); | ||||
|       /* Use a sane default value */ | ||||
|       _sntprintf_0(o.install_path, _T("%ls"), _T("C:\\Program Files\\OpenVPN\\")); | ||||
|     } | ||||
|   if (o.install_path[_tcslen(o.install_path) - 1] != _T('\\')) | ||||
|     _tcscat(o.install_path, _T("\\")); | ||||
| 
 | ||||
|   /* an admin-defined global config dir defined in HKLM\OpenVPN\config_dir */ | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("config_dir"), o.global_config_dir, _countof(o.global_config_dir))) | ||||
|     { | ||||
|       /* use default = openvpnpath\config */ | ||||
|       _sntprintf_0(o.global_config_dir, _T("%lsconfig"), o.install_path); | ||||
|         /* can't get windows dir */ | ||||
|         ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR); | ||||
|         /* Use a default value */ | ||||
|         _sntprintf_0(windows_dir, L"C:\\Windows"); | ||||
|     } | ||||
| 
 | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir))) | ||||
|     /* set default editor and log_viewer as a fallback for opening config/log files */ | ||||
|     _sntprintf_0(o.editor, L"%ls\\%ls", windows_dir, L"System32\\notepad.exe"); | ||||
|     _sntprintf_0(o.log_viewer, L"%ls", o.editor); | ||||
| 
 | ||||
|     /* Get path to OpenVPN installation. */ | ||||
|     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\OpenVPN"), 0, KEY_READ, ®key) | ||||
|         != ERROR_SUCCESS) | ||||
|     { | ||||
|       /* use default = openvpnpath\config-auto */ | ||||
|       _sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path); | ||||
|         /* registry key not found */ | ||||
|         regkey = NULL; | ||||
|         ShowLocalizedMsg(IDS_ERR_OPEN_REGISTRY); | ||||
|     } | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T(""), o.install_path, _countof(o.install_path)) | ||||
|         || _tcslen(o.install_path) == 0) | ||||
|     { | ||||
|         /* error reading registry value */ | ||||
|         if (regkey) | ||||
|         { | ||||
|             ShowLocalizedMsg(IDS_ERR_READING_REGISTRY); | ||||
|         } | ||||
|         /* Use a sane default value */ | ||||
|         _sntprintf_0(o.install_path, _T("%ls"), _T("C:\\Program Files\\OpenVPN\\")); | ||||
|     } | ||||
|     if (o.install_path[_tcslen(o.install_path) - 1] != _T('\\')) | ||||
|     { | ||||
|         _tcscat(o.install_path, _T("\\")); | ||||
|     } | ||||
| 
 | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_dir))) | ||||
|     /* an admin-defined global config dir defined in HKLM\OpenVPN\config_dir */ | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("config_dir"), o.global_config_dir, _countof(o.global_config_dir))) | ||||
|     { | ||||
|       /* use default = openvpnpath\log */ | ||||
|       _sntprintf_0(o.global_log_dir, L"%lslog", o.install_path); | ||||
|         /* use default = openvpnpath\config */ | ||||
|         _sntprintf_0(o.global_config_dir, _T("%lsconfig"), o.install_path); | ||||
|     } | ||||
| 
 | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group))) | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir))) | ||||
|     { | ||||
|       _tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1); | ||||
|         /* use default = openvpnpath\config-auto */ | ||||
|         _sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path); | ||||
|     } | ||||
| 
 | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_path))) | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_dir))) | ||||
|     { | ||||
|       _sntprintf_0(o.exe_path, _T("%lsbin\\openvpn.exe"), o.install_path); | ||||
|         /* use default = openvpnpath\log */ | ||||
|         _sntprintf_0(o.global_log_dir, L"%lslog", o.install_path); | ||||
|     } | ||||
| 
 | ||||
|   if (!regkey || !GetRegistryValue(regkey, _T("priority"), o.priority_string, _countof(o.priority_string))) | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group))) | ||||
|     { | ||||
|       _tcsncpy(o.priority_string, _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string)-1); | ||||
|         _tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1); | ||||
|     } | ||||
|   if (!regkey || !GetRegistryValueNumeric(regkey, _T("disable_save_passwords"), &o.disable_save_passwords)) | ||||
|   { | ||||
|       o.disable_save_passwords = 0; | ||||
|   } | ||||
|   if (regkey) | ||||
|       RegCloseKey(regkey); | ||||
|   return true; | ||||
| 
 | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_path))) | ||||
|     { | ||||
|         _sntprintf_0(o.exe_path, _T("%lsbin\\openvpn.exe"), o.install_path); | ||||
|     } | ||||
| 
 | ||||
|     if (!regkey || !GetRegistryValue(regkey, _T("priority"), o.priority_string, _countof(o.priority_string))) | ||||
|     { | ||||
|         _tcsncpy(o.priority_string, _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string)-1); | ||||
|     } | ||||
|     if (!regkey || !GetRegistryValueNumeric(regkey, _T("disable_save_passwords"), &o.disable_save_passwords)) | ||||
|     { | ||||
|         o.disable_save_passwords = 0; | ||||
|     } | ||||
|     if (regkey) | ||||
|     { | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| GetRegistryKeys () | ||||
| GetRegistryKeys() | ||||
| { | ||||
|     HKEY regkey; | ||||
|     DWORD status; | ||||
|     int i; | ||||
| 
 | ||||
|     if (!GetGlobalRegistryKeys()) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     status = RegOpenKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, KEY_READ, ®key); | ||||
| 
 | ||||
|     for (i = 0 ; i < (int) _countof (regkey_str); ++i) | ||||
|     for (i = 0; i < (int) _countof(regkey_str); ++i) | ||||
|     { | ||||
|         if ( status != ERROR_SUCCESS || | ||||
|             !GetRegistryValue (regkey, regkey_str[i].name, regkey_str[i].var, regkey_str[i].len)) | ||||
|         if (status != ERROR_SUCCESS | ||||
|             || !GetRegistryValue(regkey, regkey_str[i].name, regkey_str[i].var, regkey_str[i].len)) | ||||
|         { | ||||
|             /* no value found in registry, use the default */ | ||||
|             wcsncpy (regkey_str[i].var, regkey_str[i].value, regkey_str[i].len); | ||||
|             wcsncpy(regkey_str[i].var, regkey_str[i].value, regkey_str[i].len); | ||||
|             regkey_str[i].var[regkey_str[i].len-1] = L'\0'; | ||||
|             PrintDebug(L"default: %ls = %ls", regkey_str[i].name, regkey_str[i].var); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             PrintDebug(L"from registry: %ls = %ls", regkey_str[i].name, regkey_str[i].var); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0 ; i < (int) _countof (regkey_int); ++i) | ||||
|     for (i = 0; i < (int) _countof(regkey_int); ++i) | ||||
|     { | ||||
|         if ( status != ERROR_SUCCESS || | ||||
|              !GetRegistryValueNumeric (regkey, regkey_int[i].name, regkey_int[i].var)) | ||||
|         if (status != ERROR_SUCCESS | ||||
|             || !GetRegistryValueNumeric(regkey, regkey_int[i].name, regkey_int[i].var)) | ||||
|         { | ||||
|             /* no value found in registry, use the default */ | ||||
|             *regkey_int[i].var = regkey_int[i].value; | ||||
|             PrintDebug(L"default: %ls = %lu", regkey_int[i].name, *regkey_int[i].var); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             PrintDebug(L"from registry: %ls = %lu", regkey_int[i].name, *regkey_int[i].var); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if ( status == ERROR_SUCCESS) | ||||
|         RegCloseKey (regkey); | ||||
|     if (status == ERROR_SUCCESS) | ||||
|     { | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
| 
 | ||||
|     if ((o.disconnectscript_timeout == 0)) | ||||
|     { | ||||
|  | @ -229,12 +244,12 @@ GetRegistryKeys () | |||
|         RegCloseKey(regkey); | ||||
|     } | ||||
| 
 | ||||
|     ExpandOptions (); | ||||
|     ExpandOptions(); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| SaveRegistryKeys () | ||||
| SaveRegistryKeys() | ||||
| { | ||||
|     HKEY regkey; | ||||
|     DWORD status; | ||||
|  | @ -245,27 +260,31 @@ SaveRegistryKeys () | |||
|                             KEY_WRITE|KEY_READ, NULL, ®key, NULL); | ||||
|     if (status != ERROR_SUCCESS) | ||||
|     { | ||||
|         ShowLocalizedMsg (IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); | ||||
|         ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); | ||||
|         goto out; | ||||
|     } | ||||
|     for (i = 0 ; i < (int) _countof (regkey_str); ++i) | ||||
|     for (i = 0; i < (int) _countof(regkey_str); ++i) | ||||
|     { | ||||
|         /* save only if the value differs from default or already present in registry */ | ||||
|         if ( CompareStringExpanded (regkey_str[i].var, regkey_str[i].value) != 0 || | ||||
|              RegValueExists(regkey, regkey_str[i].name) ) | ||||
|         if (CompareStringExpanded(regkey_str[i].var, regkey_str[i].value) != 0 | ||||
|             || RegValueExists(regkey, regkey_str[i].name) ) | ||||
|         { | ||||
|             if (!SetRegistryValue (regkey, regkey_str[i].name, regkey_str[i].var)) | ||||
|             if (!SetRegistryValue(regkey, regkey_str[i].name, regkey_str[i].var)) | ||||
|             { | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0 ; i < (int) _countof (regkey_int); ++i) | ||||
|     for (i = 0; i < (int) _countof(regkey_int); ++i) | ||||
|     { | ||||
|         if ( *regkey_int[i].var != regkey_int[i].value || | ||||
|              RegValueExists(regkey, regkey_int[i].name) ) | ||||
|         if (*regkey_int[i].var != regkey_int[i].value | ||||
|             || RegValueExists(regkey, regkey_int[i].name) ) | ||||
|         { | ||||
|             if (!SetRegistryValueNumeric (regkey, regkey_int[i].name, *regkey_int[i].var)) | ||||
|             if (!SetRegistryValueNumeric(regkey, regkey_int[i].name, *regkey_int[i].var)) | ||||
|             { | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     ret = true; | ||||
|  | @ -273,29 +292,33 @@ SaveRegistryKeys () | |||
| out: | ||||
| 
 | ||||
|     if (status == ERROR_SUCCESS) | ||||
|     { | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static BOOL | ||||
| GetRegistryVersion (version_t *v) | ||||
| GetRegistryVersion(version_t *v) | ||||
| { | ||||
|     HKEY regkey; | ||||
|     CLEAR (*v); | ||||
|     CLEAR(*v); | ||||
|     DWORD len = sizeof(*v); | ||||
| 
 | ||||
|     if (RegOpenKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, KEY_READ, ®key) == ERROR_SUCCESS) | ||||
|     { | ||||
|         if (RegGetValueW (regkey, NULL, L"version", RRF_RT_REG_BINARY, NULL, v, &len) | ||||
|               != ERROR_SUCCESS) | ||||
|             CLEAR (*v); | ||||
|         if (RegGetValueW(regkey, NULL, L"version", RRF_RT_REG_BINARY, NULL, v, &len) | ||||
|             != ERROR_SUCCESS) | ||||
|         { | ||||
|             CLEAR(*v); | ||||
|         } | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static BOOL | ||||
| SetRegistryVersion (const version_t *v) | ||||
| SetRegistryVersion(const version_t *v) | ||||
| { | ||||
|     HKEY regkey; | ||||
|     DWORD status; | ||||
|  | @ -305,12 +328,16 @@ SetRegistryVersion (const version_t *v) | |||
|                             KEY_WRITE, NULL, ®key, NULL); | ||||
|     if (status == ERROR_SUCCESS) | ||||
|     { | ||||
|         if (RegSetValueEx(regkey, L"version", 0, REG_BINARY, (const BYTE*) v, sizeof(*v)) == ERROR_SUCCESS) | ||||
|         if (RegSetValueEx(regkey, L"version", 0, REG_BINARY, (const BYTE *) v, sizeof(*v)) == ERROR_SUCCESS) | ||||
|         { | ||||
|             ret = true; | ||||
|         } | ||||
|         RegCloseKey(regkey); | ||||
|     } | ||||
|     else | ||||
|        PrintDebug (L"Eror opening/creating 'HKCU\\%ls' registry key", GUI_REGKEY_HKCU); | ||||
|     { | ||||
|         PrintDebug(L"Eror opening/creating 'HKCU\\%ls' registry key", GUI_REGKEY_HKCU); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -322,16 +349,18 @@ MigrateNilingsKeys() | |||
|     HKEY regkey, regkey_proxy, regkey_nilings; | ||||
| 
 | ||||
|     status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Nilings\\OpenVPN-GUI", 0, | ||||
|                              KEY_READ, ®key_nilings); | ||||
|     if (status != ERROR_SUCCESS) | ||||
|         return true; /* No old keys to migrate */ | ||||
| 
 | ||||
|     status = RegCreateKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, NULL, REG_OPTION_NON_VOLATILE, | ||||
|                                     KEY_ALL_ACCESS, NULL, ®key, NULL); | ||||
|                           KEY_READ, ®key_nilings); | ||||
|     if (status != ERROR_SUCCESS) | ||||
|     { | ||||
|         ShowLocalizedMsg (IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); | ||||
|         RegCloseKey (regkey_nilings); | ||||
|         return true; /* No old keys to migrate */ | ||||
| 
 | ||||
|     } | ||||
|     status = RegCreateKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, NULL, REG_OPTION_NON_VOLATILE, | ||||
|                             KEY_ALL_ACCESS, NULL, ®key, NULL); | ||||
|     if (status != ERROR_SUCCESS) | ||||
|     { | ||||
|         ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); | ||||
|         RegCloseKey(regkey_nilings); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|  | @ -343,112 +372,132 @@ MigrateNilingsKeys() | |||
|         DWORD ui_lang; | ||||
|         /* Move language setting from Nilings to GUI_REGKEY_HKCU */ | ||||
|         if (GetRegistryValueNumeric(regkey_nilings, L"ui_language", &ui_lang)) | ||||
|             SetRegistryValueNumeric (regkey, L"ui_language", ui_lang); | ||||
|         { | ||||
|             SetRegistryValueNumeric(regkey, L"ui_language", ui_lang); | ||||
|         } | ||||
| 
 | ||||
|         status = RegCopyTree (regkey_nilings, NULL, regkey_proxy); | ||||
|         status = RegCopyTree(regkey_nilings, NULL, regkey_proxy); | ||||
|         if (status == ERROR_SUCCESS) | ||||
|         { | ||||
|             RegDeleteValue (regkey_proxy, L"ui_language"); /* in case copied here */ | ||||
|             RegDeleteValue(regkey_proxy, L"ui_language");  /* in case copied here */ | ||||
|             ret = true; | ||||
|         } | ||||
|         RegCloseKey (regkey_proxy); | ||||
|         RegCloseKey(regkey_proxy); | ||||
|     } | ||||
|     else | ||||
|         PrintDebug (L"Error creating key 'proxy' in HKCU\\%ls", GUI_REGKEY_HKCU); | ||||
|     { | ||||
|         PrintDebug(L"Error creating key 'proxy' in HKCU\\%ls", GUI_REGKEY_HKCU); | ||||
|     } | ||||
| 
 | ||||
|     RegCloseKey (regkey); | ||||
|     RegCloseKey (regkey_nilings); | ||||
|     RegCloseKey(regkey); | ||||
|     RegCloseKey(regkey_nilings); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| UpdateRegistry (void) | ||||
| UpdateRegistry(void) | ||||
| { | ||||
|     version_t v; | ||||
| 
 | ||||
|     GetRegistryVersion (&v); | ||||
|     GetRegistryVersion(&v); | ||||
| 
 | ||||
|     if (memcmp(&v, &o.version, sizeof(v)) == 0) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     switch (v.major) | ||||
|     { | ||||
|         case 0: /* Cleanup GUI_REGKEY_HKCU and migrate any values under Nilings */ | ||||
| 
 | ||||
|             RegDeleteTree (HKEY_CURRENT_USER, GUI_REGKEY_HKCU); /* delete all values and subkeys */ | ||||
|             RegDeleteTree(HKEY_CURRENT_USER, GUI_REGKEY_HKCU);  /* delete all values and subkeys */ | ||||
| 
 | ||||
|             if (!MigrateNilingsKeys()) | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|         /* fall through to handle further updates */ | ||||
|         case 11: | ||||
|             /* current version -- nothing to do */ | ||||
|             break; | ||||
| 
 | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     SetRegistryVersion (&o.version); | ||||
|     PrintDebug (L"Registry updated to version %hu.%hu", o.version.major, o.version.minor); | ||||
|     SetRegistryVersion(&o.version); | ||||
|     PrintDebug(L"Registry updated to version %hu.%hu", o.version.major, o.version.minor); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| LONG GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len) | ||||
| LONG | ||||
| GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len) | ||||
| { | ||||
|   LONG status; | ||||
|   DWORD type; | ||||
|   DWORD data_len; | ||||
|     LONG status; | ||||
|     DWORD type; | ||||
|     DWORD data_len; | ||||
| 
 | ||||
|   data_len = len * sizeof(*data); | ||||
|     data_len = len * sizeof(*data); | ||||
| 
 | ||||
|   /* get a registry string */ | ||||
|   status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len); | ||||
|   if (status != ERROR_SUCCESS || type != REG_SZ) | ||||
|     return(0); | ||||
|     /* get a registry string */ | ||||
|     status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len); | ||||
|     if (status != ERROR_SUCCESS || type != REG_SZ) | ||||
|     { | ||||
|         return(0); | ||||
|     } | ||||
| 
 | ||||
|   data_len /= sizeof(*data); | ||||
|   if (data_len > 0) | ||||
|       data[data_len - 1] = L'\0'; /* REG_SZ strings are not guaranteed to be null-terminated */ | ||||
|   else | ||||
|       data[0] = L'\0'; | ||||
|     data_len /= sizeof(*data); | ||||
|     if (data_len > 0) | ||||
|     { | ||||
|         data[data_len - 1] = L'\0'; /* REG_SZ strings are not guaranteed to be null-terminated */ | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         data[0] = L'\0'; | ||||
|     } | ||||
| 
 | ||||
|   return(data_len); | ||||
|     return(data_len); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| LONG | ||||
| GetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD *data) | ||||
| { | ||||
|   DWORD type; | ||||
|   DWORD size = sizeof(*data); | ||||
|   LONG status = RegQueryValueEx(regkey, name, NULL, &type, (PBYTE) data, &size); | ||||
|   return (type == REG_DWORD && status == ERROR_SUCCESS) ? 1 : 0; | ||||
|     DWORD type; | ||||
|     DWORD size = sizeof(*data); | ||||
|     LONG status = RegQueryValueEx(regkey, name, NULL, &type, (PBYTE) data, &size); | ||||
|     return (type == REG_DWORD && status == ERROR_SUCCESS) ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| int SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data) | ||||
| int | ||||
| SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data) | ||||
| { | ||||
|   /* set a registry string */ | ||||
|   DWORD size = (_tcslen(data) + 1) * sizeof(*data); | ||||
|   if(RegSetValueEx(regkey, name, 0, REG_SZ, (PBYTE) data, size) != ERROR_SUCCESS) | ||||
|     /* set a registry string */ | ||||
|     DWORD size = (_tcslen(data) + 1) * sizeof(*data); | ||||
|     if (RegSetValueEx(regkey, name, 0, REG_SZ, (PBYTE) data, size) != ERROR_SUCCESS) | ||||
|     { | ||||
|       /* Error writing registry value */ | ||||
|       ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); | ||||
|       return(0); | ||||
|         /* Error writing registry value */ | ||||
|         ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); | ||||
|         return(0); | ||||
|     } | ||||
| 
 | ||||
|   return(1); | ||||
|     return(1); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| SetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD data) | ||||
| { | ||||
|   LONG status = RegSetValueEx(regkey, name, 0, REG_DWORD, (PBYTE) &data, sizeof(data)); | ||||
|   if (status == ERROR_SUCCESS) | ||||
|     return 1; | ||||
|     LONG status = RegSetValueEx(regkey, name, 0, REG_DWORD, (PBYTE) &data, sizeof(data)); | ||||
|     if (status == ERROR_SUCCESS) | ||||
|     { | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|   ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); | ||||
|   return 0; | ||||
|     ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -464,18 +513,24 @@ OpenConfigRegistryKey(const WCHAR *config_name, HKEY *regkey, BOOL create) | |||
|     WCHAR *name = malloc(count * sizeof(WCHAR)); | ||||
| 
 | ||||
|     if (!name) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     _snwprintf(name, count, fmt, config_name); | ||||
|     name[count-1] = L'\0'; | ||||
| 
 | ||||
|     if (!create) | ||||
|        status = RegOpenKeyEx (HKEY_CURRENT_USER, name, 0, KEY_READ | KEY_WRITE, regkey); | ||||
|     { | ||||
|         status = RegOpenKeyEx(HKEY_CURRENT_USER, name, 0, KEY_READ | KEY_WRITE, regkey); | ||||
|     } | ||||
|     else | ||||
|     /* create if key doesn't exist */ | ||||
|        status = RegCreateKeyEx(HKEY_CURRENT_USER, name, 0, NULL, | ||||
|                REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, regkey, NULL); | ||||
|     free (name); | ||||
|     { | ||||
|         /* create if key doesn't exist */ | ||||
|         status = RegCreateKeyEx(HKEY_CURRENT_USER, name, 0, NULL, | ||||
|                                 REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, regkey, NULL); | ||||
|     } | ||||
|     free(name); | ||||
| 
 | ||||
|     return (status == ERROR_SUCCESS); | ||||
| } | ||||
|  | @ -487,7 +542,9 @@ SetConfigRegistryValueBinary(const WCHAR *config_name, const WCHAR *name, const | |||
|     DWORD status; | ||||
| 
 | ||||
|     if (!OpenConfigRegistryKey(config_name, ®key, TRUE)) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|     status = RegSetValueEx(regkey, name, 0, REG_BINARY, data, len); | ||||
|     RegCloseKey(regkey); | ||||
| 
 | ||||
|  | @ -507,13 +564,19 @@ GetConfigRegistryValue(const WCHAR *config_name, const WCHAR *name, BYTE *data, | |||
|     HKEY regkey; | ||||
| 
 | ||||
|     if (!OpenConfigRegistryKey(config_name, ®key, FALSE)) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|     status = RegQueryValueEx(regkey, name, NULL, &type, data, &len); | ||||
|     RegCloseKey(regkey); | ||||
|     if (status == ERROR_SUCCESS) | ||||
|     { | ||||
|         return len; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -523,7 +586,9 @@ DeleteConfigRegistryValue(const WCHAR *config_name, const WCHAR *name) | |||
|     HKEY regkey; | ||||
| 
 | ||||
|     if (!OpenConfigRegistryKey(config_name, ®key, FALSE)) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|     status = RegDeleteValue(regkey, name); | ||||
|     RegCloseKey(regkey); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								registry.h
								
								
								
								
							
							
						
						
									
										12
									
								
								registry.h
								
								
								
								
							|  | @ -23,15 +23,25 @@ | |||
| #define REGISTRY_H | ||||
| 
 | ||||
| int GetRegistryKeys(void); | ||||
| 
 | ||||
| int SaveRegistryKeys(void); | ||||
| 
 | ||||
| int UpdateRegistry(void); | ||||
| 
 | ||||
| int GetRegKey(const TCHAR name[], TCHAR data[], const TCHAR default_data[], DWORD len); | ||||
| 
 | ||||
| LONG GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len); | ||||
| 
 | ||||
| LONG GetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD *data); | ||||
| 
 | ||||
| int SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data); | ||||
| 
 | ||||
| int SetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD data); | ||||
| 
 | ||||
| int SetConfigRegistryValueBinary(const WCHAR *config_name, const WCHAR *name, const BYTE *data, DWORD len); | ||||
| 
 | ||||
| DWORD GetConfigRegistryValue(const WCHAR *config_name, const WCHAR *name, BYTE *data, DWORD len); | ||||
| 
 | ||||
| int DeleteConfigRegistryValue(const WCHAR *config_name, const WCHAR *name); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef REGISTRY_H */ | ||||
|  |  | |||
							
								
								
									
										40
									
								
								save_pass.c
								
								
								
								
							
							
						
						
									
										40
									
								
								save_pass.c
								
								
								
								
							|  | @ -46,10 +46,10 @@ crypt_protect(BYTE *data, int szdata, char *entropy, BYTE **out) | |||
| 
 | ||||
|     data_in.pbData = data; | ||||
|     data_in.cbData = szdata; | ||||
|     e.pbData = (BYTE*) entropy; | ||||
|     e.cbData = entropy? strlen(entropy) : 0; | ||||
|     e.pbData = (BYTE *) entropy; | ||||
|     e.cbData = entropy ? strlen(entropy) : 0; | ||||
| 
 | ||||
|     if(CryptProtectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) | ||||
|     if (CryptProtectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) | ||||
|     { | ||||
|         *out = data_out.pbData; | ||||
|         return data_out.cbData; | ||||
|  | @ -62,15 +62,15 @@ static DWORD | |||
| crypt_unprotect(BYTE *data, int szdata, char *entropy, BYTE **out) | ||||
| { | ||||
|     DATA_BLOB data_in; | ||||
|     DATA_BLOB data_out = {0,0}; | ||||
|     DATA_BLOB data_out = {0, 0}; | ||||
|     DATA_BLOB e; | ||||
| 
 | ||||
|     data_in.pbData = data; | ||||
|     data_in.cbData = szdata; | ||||
|     e.pbData = (BYTE *) entropy; | ||||
|     e.cbData = entropy? strlen(entropy) : 0; | ||||
|     e.cbData = entropy ? strlen(entropy) : 0; | ||||
| 
 | ||||
|     if(CryptUnprotectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) | ||||
|     if (CryptUnprotectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) | ||||
|     { | ||||
|         *out = data_out.pbData; | ||||
|         return data_out.cbData; | ||||
|  | @ -78,7 +78,7 @@ crypt_unprotect(BYTE *data, int szdata, char *entropy, BYTE **out) | |||
|     else | ||||
|     { | ||||
|         PrintDebug(L"CryptUnprotectData: decryption failed"); | ||||
|         LocalFree (data_out.pbData); | ||||
|         LocalFree(data_out.pbData); | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  | @ -105,10 +105,14 @@ get_entropy(const WCHAR *config_name, char *e, int sz, BOOL generate) | |||
|         e[sz-1] = '\0'; | ||||
|         PrintDebug(L"Created new entropy string : %hs", e); | ||||
|         if (SetConfigRegistryValueBinary(config_name, ENTROPY_DATA, (BYTE *)e, sz)) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     if (generate) | ||||
|     { | ||||
|         PrintDebug(L"Failed to generate or save new entropy string -- using null string"); | ||||
|     } | ||||
|     *e = '\0'; | ||||
|     return; | ||||
| } | ||||
|  | @ -125,15 +129,17 @@ save_encrypted(const WCHAR *config_name, const WCHAR *password, const WCHAR *nam | |||
|     char entropy[ENTROPY_LEN+1]; | ||||
| 
 | ||||
|     get_entropy(config_name, entropy, sizeof(entropy), true); | ||||
|     len = crypt_protect((BYTE*) password, len, entropy, &out); | ||||
|     if(len > 0) | ||||
|     len = crypt_protect((BYTE *) password, len, entropy, &out); | ||||
|     if (len > 0) | ||||
|     { | ||||
|         SetConfigRegistryValueBinary(config_name, name, out, len); | ||||
|         LocalFree(out); | ||||
|         return 1; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -171,15 +177,19 @@ recall_encrypted(const WCHAR *config_name, WCHAR *password, DWORD capacity, cons | |||
| 
 | ||||
|     get_entropy(config_name, entropy, sizeof(entropy), false); | ||||
| 
 | ||||
|     memset (password, 0, capacity); | ||||
|     memset(password, 0, capacity); | ||||
| 
 | ||||
|     len = GetConfigRegistryValue(config_name, name, in, sizeof(in)); | ||||
|     if(len == 0) | ||||
|     if (len == 0) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     len = crypt_unprotect(in, len, entropy, &out); | ||||
|     if(len == 0) | ||||
|     if (len == 0) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     if (len <= capacity * sizeof(*password)) | ||||
|     { | ||||
|  | @ -188,7 +198,9 @@ recall_encrypted(const WCHAR *config_name, WCHAR *password, DWORD capacity, cons | |||
|         retval = 1; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         PrintDebug(L"recall_encrypted: saved '%ls' too long (len = %d bytes)", name, len); | ||||
|     } | ||||
| 
 | ||||
|     SecureZeroMemory(out, len); | ||||
|     LocalFree(out); | ||||
|  | @ -222,7 +234,7 @@ int | |||
| SaveUsername(const WCHAR *config_name, const WCHAR *username) | ||||
| { | ||||
|     DWORD len = (wcslen(username) + 1) * sizeof(*username); | ||||
|     SetConfigRegistryValueBinary(config_name, AUTH_USER_DATA,(BYTE *) username, len); | ||||
|     SetConfigRegistryValueBinary(config_name, AUTH_USER_DATA, (BYTE *) username, len); | ||||
|     return 1; | ||||
| } | ||||
| /*
 | ||||
|  | @ -237,7 +249,9 @@ RecallUsername(const WCHAR *config_name, WCHAR *username) | |||
| 
 | ||||
|     len = GetConfigRegistryValue(config_name, AUTH_USER_DATA, (BYTE *) username,  capacity); | ||||
|     if (len == 0) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|     username[USER_PASS_LEN-1] = L'\0'; | ||||
|     return 1; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										10
									
								
								save_pass.h
								
								
								
								
							
							
						
						
									
										10
									
								
								save_pass.h
								
								
								
								
							|  | @ -28,17 +28,25 @@ | |||
| #define KEY_PASS_LEN 128 | ||||
| 
 | ||||
| int SaveKeyPass(const WCHAR *config_name, const WCHAR *password); | ||||
| 
 | ||||
| int SaveAuthPass(const WCHAR *config_name, const WCHAR *password); | ||||
| 
 | ||||
| int SaveUsername(const WCHAR *config_name, const WCHAR *username); | ||||
| 
 | ||||
| int RecallKeyPass(const WCHAR *config_name, WCHAR *password); | ||||
| 
 | ||||
| int RecallAuthPass(const WCHAR *config_name, WCHAR *password); | ||||
| 
 | ||||
| int RecallUsername(const WCHAR *config_name, WCHAR *username); | ||||
| 
 | ||||
| void DeleteSavedAuthPass(const WCHAR *config_name); | ||||
| 
 | ||||
| void DeleteSavedKeyPass(const WCHAR *config_name); | ||||
| 
 | ||||
| void DeleteSavedPasswords(const WCHAR *config_name); | ||||
| 
 | ||||
| BOOL IsAuthPassSaved(const WCHAR *config_name); | ||||
| 
 | ||||
| BOOL IsKeyPassSaved(const WCHAR *config_name); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* ifndef SAVEPASS_H */ | ||||
|  |  | |||
							
								
								
									
										26
									
								
								scripts.c
								
								
								
								
							
							
						
						
									
										26
									
								
								scripts.c
								
								
								
								
							|  | @ -60,13 +60,15 @@ RunPreconnectScript(connection_t *c) | |||
| 
 | ||||
|     /* Return if no script exists */ | ||||
|     if (_tstat(cmdline, &st) == -1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Create the filename of the logfile
 | ||||
|     /* Create the filename of the logfile */ | ||||
|     TCHAR script_log_filename[MAX_PATH]; | ||||
|     _sntprintf_0(script_log_filename, _T("%ls\\%ls_pre.log"), o.log_dir, c->config_name); | ||||
| 
 | ||||
|     // Create the log file
 | ||||
|     /* Create the log file */ | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     CLEAR(sa); | ||||
|     sa.nLength = sizeof(SECURITY_ATTRIBUTES); | ||||
|  | @ -133,16 +135,20 @@ RunConnectScript(connection_t *c, int run_as_service) | |||
| 
 | ||||
|     /* Return if no script exists */ | ||||
|     if (_tstat(cmdline, &st) == -1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!run_as_service) | ||||
|     { | ||||
|         SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONN_SCRIPT)); | ||||
|     } | ||||
| 
 | ||||
|     // Create the filename of the logfile
 | ||||
|     /* Create the filename of the logfile */ | ||||
|     TCHAR script_log_filename[MAX_PATH]; | ||||
|     _sntprintf_0(script_log_filename, _T("%ls\\%ls_up.log"), o.log_dir, c->config_name); | ||||
| 
 | ||||
|     // Create the log file
 | ||||
|     /* Create the log file */ | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     CLEAR(sa); | ||||
|     sa.nLength = sizeof(SECURITY_ATTRIBUTES); | ||||
|  | @ -175,7 +181,9 @@ RunConnectScript(connection_t *c, int run_as_service) | |||
|     } | ||||
| 
 | ||||
|     if (o.connectscript_timeout == 0) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i <= (int) o.connectscript_timeout; i++) | ||||
|     { | ||||
|  | @ -188,7 +196,9 @@ RunConnectScript(connection_t *c, int run_as_service) | |||
|         if (exit_code != STILL_ACTIVE) | ||||
|         { | ||||
|             if (exit_code != 0) | ||||
|             { | ||||
|                 ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_CONN_SCRIPT_FAILED, exit_code); | ||||
|             } | ||||
|             goto out; | ||||
|         } | ||||
| 
 | ||||
|  | @ -227,16 +237,20 @@ RunDisconnectScript(connection_t *c, int run_as_service) | |||
| 
 | ||||
|     /* Return if no script exists */ | ||||
|     if (_tstat(cmdline, &st) == -1) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!run_as_service) | ||||
|     { | ||||
|         SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONN_SCRIPT)); | ||||
|     } | ||||
| 
 | ||||
|     // Create the filename of the logfile
 | ||||
|     /* Create the filename of the logfile */ | ||||
|     TCHAR script_log_filename[MAX_PATH]; | ||||
|     _sntprintf_0(script_log_filename, _T("%ls\\%ls_down.log"), o.log_dir, c->config_name); | ||||
| 
 | ||||
|     // Create the log file
 | ||||
|     /* Create the log file */ | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     CLEAR(sa); | ||||
|     sa.nLength = sizeof(SECURITY_ATTRIBUTES); | ||||
|  |  | |||
|  | @ -24,7 +24,9 @@ | |||
| #define SCRIPTS_H | ||||
| 
 | ||||
| void RunPreconnectScript(connection_t *); | ||||
| 
 | ||||
| void RunConnectScript(connection_t *, int run_as_service); | ||||
| 
 | ||||
| void RunDisconnectScript(connection_t *, int run_as_service); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										64
									
								
								service.c
								
								
								
								
							
							
						
						
									
										64
									
								
								service.c
								
								
								
								
							|  | @ -46,26 +46,32 @@ CheckIServiceStatus(BOOL warn) | |||
|     SERVICE_STATUS ssStatus; | ||||
|     BOOL ret = false; | ||||
| 
 | ||||
|     // Open a handle to the SC Manager database.
 | ||||
|     /* Open a handle to the SC Manager database. */ | ||||
|     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); | ||||
| 
 | ||||
|     if (NULL == schSCManager) | ||||
|     { | ||||
|         return(false); | ||||
|     } | ||||
| 
 | ||||
|     schService = OpenService(schSCManager, o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? | ||||
|         OPENVPN_SERVICE_NAME_OVPN3 : OPENVPN_SERVICE_NAME_OVPN2, SERVICE_QUERY_STATUS); | ||||
|                              OPENVPN_SERVICE_NAME_OVPN3 : OPENVPN_SERVICE_NAME_OVPN2, SERVICE_QUERY_STATUS); | ||||
| 
 | ||||
|     if (schService == NULL && | ||||
|         GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) | ||||
|     if (schService == NULL | ||||
|         && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) | ||||
|     { | ||||
|         /* warn that iservice is not installed */ | ||||
|         if (warn) | ||||
|         { | ||||
|             ShowLocalizedMsg(IDS_ERR_INSTALL_ISERVICE); | ||||
|         } | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     if (!QueryServiceStatus(schService, &ssStatus)) | ||||
|     { | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     if (ssStatus.dwCurrentState != SERVICE_RUNNING) | ||||
|     { | ||||
|  | @ -73,9 +79,13 @@ CheckIServiceStatus(BOOL warn) | |||
|         if (warn) | ||||
|         { | ||||
|             if (IsUserAdmin()) | ||||
|             { | ||||
|                 ShowLocalizedMsg(IDS_ERR_NOTSTARTED_ISERVICE_ADM); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ShowLocalizedMsg(IDS_ERR_NOTSTARTED_ISERVICE); | ||||
|             } | ||||
|         } | ||||
|         goto out; | ||||
|     } | ||||
|  | @ -83,42 +93,49 @@ CheckIServiceStatus(BOOL warn) | |||
| 
 | ||||
| out: | ||||
|     if (schService) | ||||
|     { | ||||
|         CloseServiceHandle(schService); | ||||
|     } | ||||
|     if (schSCManager) | ||||
|     { | ||||
|         CloseServiceHandle(schSCManager); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| VOID CheckServiceStatus() | ||||
| VOID | ||||
| CheckServiceStatus() | ||||
| { | ||||
|     SC_HANDLE schSCManager = NULL; | ||||
|     SC_HANDLE schService = NULL; | ||||
|     SERVICE_STATUS ssStatus; | ||||
| 
 | ||||
|     // Open a handle to the SC Manager database.
 | ||||
|     /* Open a handle to the SC Manager database. */ | ||||
|     schSCManager = OpenSCManager( | ||||
|         NULL,                    // local machine
 | ||||
|         NULL,                    // ServicesActive database
 | ||||
|         SC_MANAGER_CONNECT);     // Connect rights
 | ||||
|         NULL,                    /* local machine */ | ||||
|         NULL,                    /* ServicesActive database */ | ||||
|         SC_MANAGER_CONNECT);     /* Connect rights */ | ||||
| 
 | ||||
|     if (NULL == schSCManager) { | ||||
|     if (NULL == schSCManager) | ||||
|     { | ||||
|         o.service_state = service_noaccess; | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     schService = OpenService( | ||||
|         schSCManager,          // SCM database
 | ||||
|         _T("OpenVPNService"),  // service name
 | ||||
|         schSCManager,          /* SCM database */ | ||||
|         _T("OpenVPNService"),  /* service name */ | ||||
|         SERVICE_QUERY_STATUS); | ||||
| 
 | ||||
|     if (schService == NULL) { | ||||
|     if (schService == NULL) | ||||
|     { | ||||
|         o.service_state = service_noaccess; | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     if (!QueryServiceStatus( | ||||
|             schService,   // handle to service
 | ||||
|             &ssStatus) )  // address of status information structure
 | ||||
|             schService,   /* handle to service */ | ||||
|             &ssStatus) )  /* address of status information structure */ | ||||
|     { | ||||
|         /* query failed */ | ||||
|         o.service_state = service_noaccess; | ||||
|  | @ -139,25 +156,32 @@ VOID CheckServiceStatus() | |||
| 
 | ||||
| out: | ||||
|     if (schService) | ||||
|     { | ||||
|         CloseServiceHandle(schService); | ||||
|     } | ||||
|     if (schSCManager) | ||||
|     { | ||||
|         CloseServiceHandle(schSCManager); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* Attempt to start OpenVPN Automatc Service */ | ||||
| void StartAutomaticService(void) | ||||
| void | ||||
| StartAutomaticService(void) | ||||
| { | ||||
|     SC_HANDLE schSCManager = NULL; | ||||
|     SC_HANDLE schService = NULL; | ||||
| 
 | ||||
|     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); | ||||
| 
 | ||||
|     if (schSCManager) { | ||||
|     if (schSCManager) | ||||
|     { | ||||
|         schService = OpenService(schSCManager, L"OpenVPNService", SERVICE_START); | ||||
| 
 | ||||
|         if (schService) { | ||||
|              StartService(schService, 0, NULL); | ||||
|              CloseServiceHandle(schService); | ||||
|         if (schService) | ||||
|         { | ||||
|             StartService(schService, 0, NULL); | ||||
|             CloseServiceHandle(schService); | ||||
|         } | ||||
| 
 | ||||
|         CloseServiceHandle(schSCManager); | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ | |||
|  */ | ||||
| 
 | ||||
| VOID CheckServiceStatus(); | ||||
| 
 | ||||
| BOOL CheckIServiceStatus(BOOL warn); | ||||
| 
 | ||||
| /* Attempt to start OpenVPN Automatc Service */ | ||||
| void StartAutomaticService(void); | ||||
|  |  | |||
							
								
								
									
										147
									
								
								tray.c
								
								
								
								
							
							
						
						
									
										147
									
								
								tray.c
								
								
								
								
							|  | @ -50,13 +50,14 @@ NOTIFYICONDATA ni; | |||
| extern options_t o; | ||||
| 
 | ||||
| #define USE_NESTED_CONFIG_MENU ((o.config_menu_view == CONFIG_VIEW_AUTO && o.num_configs > 25)   \ | ||||
|                                  || (o.config_menu_view == CONFIG_VIEW_NESTED)) | ||||
|                                 || (o.config_menu_view == CONFIG_VIEW_NESTED)) | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| DeleteMenuBitmaps(void) | ||||
| { | ||||
|     if (hbmpConnecting) { | ||||
|     if (hbmpConnecting) | ||||
|     { | ||||
|         DeleteObject(hbmpConnecting); | ||||
|         hbmpConnecting = NULL; | ||||
|     } | ||||
|  | @ -92,8 +93,14 @@ CreateMenuBitmaps(void) | |||
|     { | ||||
|         DeleteObject(iconinfo.hbmMask); | ||||
|         DeleteObject(iconinfo.hbmColor); | ||||
|         if (maskDC) DeleteDC(maskDC); | ||||
|         if (imgDC) DeleteDC(imgDC); | ||||
|         if (maskDC) | ||||
|         { | ||||
|             DeleteDC(maskDC); | ||||
|         } | ||||
|         if (imgDC) | ||||
|         { | ||||
|             DeleteDC(imgDC); | ||||
|         } | ||||
|         MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Error creating DCs for drawing"); | ||||
|         return; | ||||
|     } | ||||
|  | @ -106,10 +113,14 @@ CreateMenuBitmaps(void) | |||
|     COLORREF ref = RGB(255, 255, 255); | ||||
|     COLORREF bg = GetSysColor(COLOR_MENU); | ||||
| 
 | ||||
|     for (int x = 0; x < cx; x++) { | ||||
|         for (int y = 0; y < cy; y++) { | ||||
|     for (int x = 0; x < cx; x++) | ||||
|     { | ||||
|         for (int y = 0; y < cy; y++) | ||||
|         { | ||||
|             if (GetPixel(maskDC, x, y) == ref) | ||||
|             { | ||||
|                 SetPixel(imgDC, x, y, bg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -132,13 +143,18 @@ CreateMenuBitmaps(void) | |||
| void | ||||
| AllocateConnectionMenu() | ||||
| { | ||||
|     if (hmenu_size >= o.num_configs) return; | ||||
|     if (hmenu_size >= o.num_configs) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|     HMENU *tmp  = (HMENU *) realloc(hMenuConn, sizeof(HMENU)*(o.num_configs + 50)); | ||||
|     if (tmp) { | ||||
|     if (tmp) | ||||
|     { | ||||
|         hmenu_size = o.num_configs + 50; | ||||
|         hMenuConn = tmp; | ||||
|     } | ||||
|     else { | ||||
|     else | ||||
|     { | ||||
|         o.num_configs = hmenu_size; | ||||
|         MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Allocation of hMenuConn failed. Ignoring configs beyond index = %d", o.num_configs); | ||||
|     } | ||||
|  | @ -175,7 +191,9 @@ CreatePopupMenus() | |||
|     for (int i = 0; i < o.num_groups; i++) | ||||
|     { | ||||
|         if (!o.groups[i].active) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|         o.groups[i].menu = CreatePopupMenu(); | ||||
|         o.groups[i].children = 0; /* we have to recount this when assigning menu position index */ | ||||
|     } | ||||
|  | @ -188,7 +206,8 @@ CreatePopupMenus() | |||
|     minfo.dwStyle |= MNS_NOTIFYBYPOS; | ||||
|     SetMenuInfo(hMenu, &minfo); | ||||
| 
 | ||||
|     if (o.num_configs == 1 && o.chead) { | ||||
|     if (o.num_configs == 1 && o.chead) | ||||
|     { | ||||
|         /* Set main menu's menudata to first connection */ | ||||
|         minfo.fMask = MIM_MENUDATA; | ||||
|         GetMenuInfo(hMenu, &minfo); | ||||
|  | @ -215,12 +234,13 @@ CreatePopupMenus() | |||
|         AppendMenu(hMenuImport, MF_STRING, IDM_IMPORT_AS, LoadLocalizedString(IDS_MENU_IMPORT_AS)); | ||||
|         AppendMenu(hMenuImport, MF_STRING, IDM_IMPORT_URL, LoadLocalizedString(IDS_MENU_IMPORT_URL)); | ||||
| 
 | ||||
|         AppendMenu(hMenu, MF_STRING ,IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS)); | ||||
|         AppendMenu(hMenu, MF_STRING ,IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE)); | ||||
|         AppendMenu(hMenu, MF_STRING, IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS)); | ||||
|         AppendMenu(hMenu, MF_STRING, IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE)); | ||||
| 
 | ||||
|         SetMenuStatus(o.chead,  o.chead->state); | ||||
|     } | ||||
|     else { | ||||
|     else | ||||
|     { | ||||
|         /* construct the submenu tree first */ | ||||
|         /* i = 0 is the root menu and has no parent */ | ||||
|         for (int i = 1; i < o.num_groups; i++) | ||||
|  | @ -240,7 +260,7 @@ CreatePopupMenus() | |||
|             this->pos = parent->children++; | ||||
| 
 | ||||
|             PrintDebug(L"Submenu %d named %ls added to parent %ls with position %d", | ||||
|                     i, this->name, parent->name, this->pos); | ||||
|                        i, this->name, parent->name, this->pos); | ||||
|         } | ||||
| 
 | ||||
|         /* add config file (connection) entries */ | ||||
|  | @ -268,11 +288,13 @@ CreatePopupMenus() | |||
|             c->pos = parent->children++; | ||||
| 
 | ||||
|             PrintDebug(L"Config %d named %ls added to submenu %ls with position %d", | ||||
|                         c->id, c->config_name, parent->name, c->pos); | ||||
|                        c->id, c->config_name, parent->name, c->pos); | ||||
|         } | ||||
| 
 | ||||
|         if (o.num_configs > 0) | ||||
|         { | ||||
|             AppendMenu(hMenu, MF_SEPARATOR, 0, 0); | ||||
|         } | ||||
| 
 | ||||
|         hMenuImport = CreatePopupMenu(); | ||||
|         AppendMenu(hMenu, MF_POPUP, (UINT_PTR) hMenuImport, LoadLocalizedString(IDS_MENU_IMPORT)); | ||||
|  | @ -337,17 +359,18 @@ OnNotifyTray(LPARAM lParam) | |||
| { | ||||
|     POINT pt; | ||||
| 
 | ||||
|     switch (lParam) { | ||||
|     case WM_RBUTTONUP: | ||||
|         RecreatePopupMenus(); | ||||
|     switch (lParam) | ||||
|     { | ||||
|         case WM_RBUTTONUP: | ||||
|             RecreatePopupMenus(); | ||||
| 
 | ||||
|         GetCursorPos(&pt); | ||||
|         SetForegroundWindow(o.hWnd); | ||||
|         TrackPopupMenu(hMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, o.hWnd, NULL); | ||||
|         PostMessage(o.hWnd, WM_NULL, 0, 0); | ||||
|         break; | ||||
|             GetCursorPos(&pt); | ||||
|             SetForegroundWindow(o.hWnd); | ||||
|             TrackPopupMenu(hMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, o.hWnd, NULL); | ||||
|             PostMessage(o.hWnd, WM_NULL, 0, 0); | ||||
|             break; | ||||
| 
 | ||||
|     case WM_LBUTTONDBLCLK: | ||||
|         case WM_LBUTTONDBLCLK: | ||||
|         { | ||||
|             int disconnected_conns = CountConnState(disconnected); | ||||
| 
 | ||||
|  | @ -355,26 +378,33 @@ OnNotifyTray(LPARAM lParam) | |||
| 
 | ||||
|             /* Start connection if only one config exist */ | ||||
|             if (o.num_configs == 1 && o.chead->state == disconnected) | ||||
|                     StartOpenVPN(o.chead); | ||||
|             { | ||||
|                 StartOpenVPN(o.chead); | ||||
|             } | ||||
|             /* show the status window of all connected/connecting profiles upto a max of 10 */ | ||||
|             else if (disconnected_conns < o.num_configs) { | ||||
|             else if (disconnected_conns < o.num_configs) | ||||
|             { | ||||
|                 int num_shown = 0; | ||||
|                 for (connection_t *c = o.chead; c; c = c->next) | ||||
|                 { | ||||
|                     if (c->state != disconnected && c->hwndStatus) { | ||||
|                     if (c->state != disconnected && c->hwndStatus) | ||||
|                     { | ||||
|                         ShowWindow(c->hwndStatus, SW_SHOW); | ||||
|                         SetForegroundWindow(c->hwndStatus); | ||||
|                         if (++num_shown >= 10) break; | ||||
|                         if (++num_shown >= 10) | ||||
|                         { | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case WM_OVPN_RESCAN: | ||||
|         /* Rescan config folders and recreate popup menus */ | ||||
|         RecreatePopupMenus(); | ||||
|         break; | ||||
|         case WM_OVPN_RESCAN: | ||||
|             /* Rescan config folders and recreate popup menus */ | ||||
|             RecreatePopupMenus(); | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -398,15 +428,15 @@ OnDestroyTray() | |||
| void | ||||
| ShowTrayIcon() | ||||
| { | ||||
|   ni.cbSize = sizeof(ni); | ||||
|   ni.uID = 0; | ||||
|   ni.hWnd = o.hWnd; | ||||
|   ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; | ||||
|   ni.uCallbackMessage = WM_NOTIFYICONTRAY; | ||||
|   ni.hIcon = LoadLocalizedSmallIcon(ID_ICO_DISCONNECTED); | ||||
|   _tcsncpy(ni.szTip, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip)); | ||||
|     ni.cbSize = sizeof(ni); | ||||
|     ni.uID = 0; | ||||
|     ni.hWnd = o.hWnd; | ||||
|     ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; | ||||
|     ni.uCallbackMessage = WM_NOTIFYICONTRAY; | ||||
|     ni.hIcon = LoadLocalizedSmallIcon(ID_ICO_DISCONNECTED); | ||||
|     _tcsncpy(ni.szTip, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip)); | ||||
| 
 | ||||
|   Shell_NotifyIcon(NIM_ADD, &ni); | ||||
|     Shell_NotifyIcon(NIM_ADD, &ni); | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -426,7 +456,8 @@ SetTrayIcon(conn_state_t state) | |||
|     first_conn = TRUE; | ||||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (c->state == connected) { | ||||
|         if (c->state == connected) | ||||
|         { | ||||
|             /* Append connection name to Icon Tip Msg */ | ||||
|             _tcsncat(msg, (first_conn ? msg_connected : _T(", ")), _countof(msg) - _tcslen(msg) - 1); | ||||
|             _tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1); | ||||
|  | @ -438,7 +469,8 @@ SetTrayIcon(conn_state_t state) | |||
|     first_conn = TRUE; | ||||
|     for (connection_t *c = o.chead; c; c = c->next) | ||||
|     { | ||||
|         if (c->state == connecting || c->state == resuming || c->state == reconnecting) { | ||||
|         if (c->state == connecting || c->state == resuming || c->state == reconnecting) | ||||
|         { | ||||
|             /* Append connection name to Icon Tip Msg */ | ||||
|             _tcsncat(msg, (first_conn ? msg_connecting : _T(", ")), _countof(msg) - _tcslen(msg) - 1); | ||||
|             _tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1); | ||||
|  | @ -446,7 +478,8 @@ SetTrayIcon(conn_state_t state) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (CountConnState(connected) == 1 && cc) { | ||||
|     if (CountConnState(connected) == 1 && cc) | ||||
|     { | ||||
|         /* Append "Connected since and assigned IP" to message */ | ||||
|         TCHAR time[50]; | ||||
| 
 | ||||
|  | @ -463,9 +496,13 @@ SetTrayIcon(conn_state_t state) | |||
| 
 | ||||
|     icon_id = ID_ICO_CONNECTING; | ||||
|     if (state == connected) | ||||
|     { | ||||
|         icon_id = ID_ICO_CONNECTED; | ||||
|     } | ||||
|     else if (state == disconnected) | ||||
|     { | ||||
|         icon_id = ID_ICO_DISCONNECTED; | ||||
|     } | ||||
| 
 | ||||
|     ni.cbSize = sizeof(ni); | ||||
|     ni.uID = 0; | ||||
|  | @ -490,9 +527,13 @@ CheckAndSetTrayIcon() | |||
|     { | ||||
|         if (CountConnState(connecting) != 0 || CountConnState(reconnecting) != 0 | ||||
|             ||  CountConnState(resuming) != 0) | ||||
|         { | ||||
|             SetTrayIcon(connecting); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             SetTrayIcon(disconnected); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -519,8 +560,14 @@ SetMenuStatus(connection_t *c, conn_state_t state) | |||
|     int checked = 0; | ||||
|     int i = c->id; | ||||
| 
 | ||||
|     if (state == connected || state == disconnecting) checked = 1; | ||||
|     else if (state != disconnected && state != detached && state != onhold) checked = 2; | ||||
|     if (state == connected || state == disconnecting) | ||||
|     { | ||||
|         checked = 1; | ||||
|     } | ||||
|     else if (state != disconnected && state != detached && state != onhold) | ||||
|     { | ||||
|         checked = 2; | ||||
|     } | ||||
| 
 | ||||
|     if (o.num_configs == 1) | ||||
|     { | ||||
|  | @ -553,9 +600,13 @@ SetMenuStatus(connection_t *c, conn_state_t state) | |||
|             EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED); | ||||
|         } | ||||
|         if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) | ||||
|         { | ||||
|             EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_GRAYED); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  | @ -584,7 +635,7 @@ SetMenuStatus(connection_t *c, conn_state_t state) | |||
|         CheckMenuItem(parent->menu, pos, MF_BYPOSITION | (checked ? MF_CHECKED : MF_UNCHECKED)); | ||||
| 
 | ||||
|         PrintDebug(L"Setting state of config %ls checked = %d, parent %ls, pos %d", | ||||
|                     c->config_name, checked, (parent->id == 0)? L"Main Menu" : L"SubMenu", pos); | ||||
|                    c->config_name, checked, (parent->id == 0) ? L"Main Menu" : L"SubMenu", pos); | ||||
| 
 | ||||
|         if (checked) /* also check all parent groups */ | ||||
|         { | ||||
|  | @ -625,8 +676,12 @@ SetMenuStatus(connection_t *c, conn_state_t state) | |||
|             EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED); | ||||
|         } | ||||
|         if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) | ||||
|         { | ||||
|             EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_GRAYED); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										12
									
								
								tray.h
								
								
								
								
							
							
						
						
									
										12
									
								
								tray.h
								
								
								
								
							|  | @ -46,15 +46,25 @@ | |||
| #define IDM_RECONNECTMENU       (1 + IDM_CLEARPASSMENU) | ||||
| 
 | ||||
| void RecreatePopupMenus(void); | ||||
| 
 | ||||
| void CreatePopupMenus(); | ||||
| 
 | ||||
| void OnNotifyTray(LPARAM); | ||||
| 
 | ||||
| void OnDestroyTray(void); | ||||
| 
 | ||||
| void ShowTrayIcon(); | ||||
| 
 | ||||
| void RemoveTrayIcon(); | ||||
| 
 | ||||
| void SetTrayIcon(conn_state_t); | ||||
| 
 | ||||
| void SetMenuStatus(connection_t *, conn_state_t); | ||||
| 
 | ||||
| void SetServiceMenuStatus(); | ||||
| 
 | ||||
| void ShowTrayBalloon(TCHAR *, TCHAR *); | ||||
| 
 | ||||
| void CheckAndSetTrayIcon(); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* ifndef TRAY_H */ | ||||
|  |  | |||
							
								
								
									
										188
									
								
								viewlog.c
								
								
								
								
							
							
						
						
									
										188
									
								
								viewlog.c
								
								
								
								
							|  | @ -37,112 +37,122 @@ | |||
| 
 | ||||
| extern options_t o; | ||||
| 
 | ||||
| void ViewLog(connection_t *c) | ||||
| void | ||||
| ViewLog(connection_t *c) | ||||
| { | ||||
|   TCHAR filename[2*MAX_PATH]; | ||||
|     TCHAR filename[2*MAX_PATH]; | ||||
| 
 | ||||
|   STARTUPINFO start_info; | ||||
|   PROCESS_INFORMATION proc_info; | ||||
|   SECURITY_ATTRIBUTES sa; | ||||
|   SECURITY_DESCRIPTOR sd; | ||||
|   HINSTANCE status; | ||||
|     STARTUPINFO start_info; | ||||
|     PROCESS_INFORMATION proc_info; | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     SECURITY_DESCRIPTOR sd; | ||||
|     HINSTANCE status; | ||||
| 
 | ||||
|   CLEAR (start_info); | ||||
|   CLEAR (proc_info); | ||||
|   CLEAR (sa); | ||||
|   CLEAR (sd); | ||||
|     CLEAR(start_info); | ||||
|     CLEAR(proc_info); | ||||
|     CLEAR(sa); | ||||
|     CLEAR(sd); | ||||
| 
 | ||||
|   /* Try first using file association */ | ||||
|   CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ | ||||
|   status = ShellExecuteW (o.hWnd, L"open", c->log_path, NULL, o.log_dir, SW_SHOWNORMAL); | ||||
|     /* Try first using file association */ | ||||
|     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ | ||||
|     status = ShellExecuteW(o.hWnd, L"open", c->log_path, NULL, o.log_dir, SW_SHOWNORMAL); | ||||
| 
 | ||||
|   if (status > (HINSTANCE) 32) /* Success */ | ||||
|     return; | ||||
|   else | ||||
|     PrintDebug (L"Opening log file using ShellExecute with verb = open failed" | ||||
|                  " for config '%ls' (status = %lu)", c->config_name, status); | ||||
| 
 | ||||
|   _sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, c->log_path); | ||||
| 
 | ||||
|   /* fill in STARTUPINFO struct */ | ||||
|   GetStartupInfo(&start_info); | ||||
|   start_info.cb = sizeof(start_info); | ||||
|   start_info.dwFlags = 0; | ||||
|   start_info.wShowWindow = SW_SHOWDEFAULT; | ||||
|   start_info.hStdInput = NULL; | ||||
|   start_info.hStdOutput = NULL; | ||||
| 
 | ||||
|   if (!CreateProcess(NULL, | ||||
| 		     filename, 	//commandline
 | ||||
| 		     NULL, | ||||
| 		     NULL, | ||||
| 		     TRUE, | ||||
| 		     CREATE_NEW_CONSOLE, | ||||
| 		     NULL, | ||||
| 		     o.log_dir,	//start-up dir
 | ||||
| 		     &start_info, | ||||
| 		     &proc_info)) | ||||
|     if (status > (HINSTANCE) 32) /* Success */ | ||||
|     { | ||||
|       /* could not start log viewer */ | ||||
|       ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer); | ||||
|         return; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         PrintDebug(L"Opening log file using ShellExecute with verb = open failed" | ||||
|                    " for config '%ls' (status = %lu)", c->config_name, status); | ||||
|     } | ||||
| 
 | ||||
|   CloseHandle(proc_info.hThread); | ||||
|   CloseHandle(proc_info.hProcess); | ||||
|     _sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, c->log_path); | ||||
| 
 | ||||
|     /* fill in STARTUPINFO struct */ | ||||
|     GetStartupInfo(&start_info); | ||||
|     start_info.cb = sizeof(start_info); | ||||
|     start_info.dwFlags = 0; | ||||
|     start_info.wShowWindow = SW_SHOWDEFAULT; | ||||
|     start_info.hStdInput = NULL; | ||||
|     start_info.hStdOutput = NULL; | ||||
| 
 | ||||
|     if (!CreateProcess(NULL, | ||||
|                        filename, /*commandline */ | ||||
|                        NULL, | ||||
|                        NULL, | ||||
|                        TRUE, | ||||
|                        CREATE_NEW_CONSOLE, | ||||
|                        NULL, | ||||
|                        o.log_dir, /*start-up dir */ | ||||
|                        &start_info, | ||||
|                        &proc_info)) | ||||
|     { | ||||
|         /* could not start log viewer */ | ||||
|         ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer); | ||||
|     } | ||||
| 
 | ||||
|     CloseHandle(proc_info.hThread); | ||||
|     CloseHandle(proc_info.hProcess); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void EditConfig(connection_t *c) | ||||
| void | ||||
| EditConfig(connection_t *c) | ||||
| { | ||||
|   TCHAR filename[2*MAX_PATH]; | ||||
|     TCHAR filename[2*MAX_PATH]; | ||||
| 
 | ||||
|   STARTUPINFO start_info; | ||||
|   PROCESS_INFORMATION proc_info; | ||||
|   SECURITY_ATTRIBUTES sa; | ||||
|   SECURITY_DESCRIPTOR sd; | ||||
|   HINSTANCE status; | ||||
|     STARTUPINFO start_info; | ||||
|     PROCESS_INFORMATION proc_info; | ||||
|     SECURITY_ATTRIBUTES sa; | ||||
|     SECURITY_DESCRIPTOR sd; | ||||
|     HINSTANCE status; | ||||
| 
 | ||||
|   CLEAR (start_info); | ||||
|   CLEAR (proc_info); | ||||
|   CLEAR (sa); | ||||
|   CLEAR (sd); | ||||
|     CLEAR(start_info); | ||||
|     CLEAR(proc_info); | ||||
|     CLEAR(sa); | ||||
|     CLEAR(sd); | ||||
| 
 | ||||
|   /* Try first using file association */ | ||||
|   _sntprintf_0(filename, L"%ls\\%ls", c->config_dir, c->config_file); | ||||
|     /* Try first using file association */ | ||||
|     _sntprintf_0(filename, L"%ls\\%ls", c->config_dir, c->config_file); | ||||
| 
 | ||||
|   CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ | ||||
|   status = ShellExecuteW (o.hWnd, L"open", filename, NULL, c->config_dir, SW_SHOWNORMAL); | ||||
|   if (status > (HINSTANCE) 32) | ||||
|     return; | ||||
|   else | ||||
|     PrintDebug (L"Opening config file using ShellExecute with verb = open failed" | ||||
|                  " for config '%ls' (status = %lu)", c->config_name, status); | ||||
| 
 | ||||
|   _sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, c->config_dir, c->config_file); | ||||
| 
 | ||||
|   /* fill in STARTUPINFO struct */ | ||||
|   GetStartupInfo(&start_info); | ||||
|   start_info.cb = sizeof(start_info); | ||||
|   start_info.dwFlags = 0; | ||||
|   start_info.wShowWindow = SW_SHOWDEFAULT; | ||||
|   start_info.hStdInput = NULL; | ||||
|   start_info.hStdOutput = NULL; | ||||
| 
 | ||||
|   if (!CreateProcess(NULL, | ||||
| 		     filename, 	//commandline
 | ||||
| 		     NULL, | ||||
| 		     NULL, | ||||
| 		     TRUE, | ||||
| 		     CREATE_NEW_CONSOLE, | ||||
| 		     NULL, | ||||
| 		     c->config_dir,	//start-up dir
 | ||||
| 		     &start_info, | ||||
| 		     &proc_info)) | ||||
|     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ | ||||
|     status = ShellExecuteW(o.hWnd, L"open", filename, NULL, c->config_dir, SW_SHOWNORMAL); | ||||
|     if (status > (HINSTANCE) 32) | ||||
|     { | ||||
|         /* could not start editor */  | ||||
| 	ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor); | ||||
|         return; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         PrintDebug(L"Opening config file using ShellExecute with verb = open failed" | ||||
|                    " for config '%ls' (status = %lu)", c->config_name, status); | ||||
|     } | ||||
| 
 | ||||
|   CloseHandle(proc_info.hThread); | ||||
|   CloseHandle(proc_info.hProcess); | ||||
|     _sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, c->config_dir, c->config_file); | ||||
| 
 | ||||
|     /* fill in STARTUPINFO struct */ | ||||
|     GetStartupInfo(&start_info); | ||||
|     start_info.cb = sizeof(start_info); | ||||
|     start_info.dwFlags = 0; | ||||
|     start_info.wShowWindow = SW_SHOWDEFAULT; | ||||
|     start_info.hStdInput = NULL; | ||||
|     start_info.hStdOutput = NULL; | ||||
| 
 | ||||
|     if (!CreateProcess(NULL, | ||||
|                        filename, /*commandline */ | ||||
|                        NULL, | ||||
|                        NULL, | ||||
|                        TRUE, | ||||
|                        CREATE_NEW_CONSOLE, | ||||
|                        NULL, | ||||
|                        c->config_dir,   /*start-up dir */ | ||||
|                        &start_info, | ||||
|                        &proc_info)) | ||||
|     { | ||||
|         /* could not start editor */ | ||||
|         ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor); | ||||
|     } | ||||
| 
 | ||||
|     CloseHandle(proc_info.hThread); | ||||
|     CloseHandle(proc_info.hProcess); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Frank Lichtenheld
						Frank Lichtenheld