1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2026-04-20 13:59:26 +03:00

Add custom HTTP header feature for HTTP proxy

A custom HTTP header can be used to bypass certain restrictions imposed on the network or to avoid speed limitations applied by the QoS.
This commit is contained in:
Davide Beatrici
2018-11-29 20:32:03 +01:00
parent 4be45342b7
commit aefbd2e903
29 changed files with 1665 additions and 120 deletions
+2
View File
@@ -8988,6 +8988,7 @@ void InRpcInternetSetting(INTERNET_SETTING *t, PACK *p)
t->ProxyPort = PackGetInt(p, "ProxyPort");
PackGetStr(p, "ProxyUsername", t->ProxyUsername, sizeof(t->ProxyUsername));
PackGetStr(p, "ProxyPassword", t->ProxyPassword, sizeof(t->ProxyPassword));
PackGetStr(p, "CustomHttpHeader", t->CustomHttpHeader, sizeof(t->CustomHttpHeader));
}
void OutRpcInternetSetting(PACK *p, INTERNET_SETTING *t)
{
@@ -9002,6 +9003,7 @@ void OutRpcInternetSetting(PACK *p, INTERNET_SETTING *t)
PackAddInt(p, "ProxyPort", t->ProxyPort);
PackAddStr(p, "ProxyUsername", t->ProxyUsername);
PackAddStr(p, "ProxyPassword", t->ProxyPassword);
PackAddStr(p, "CustomHttpHeader", t->CustomHttpHeader);
}
// RPC_AZURE_STATUS
+289
View File
@@ -7830,6 +7830,290 @@ UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, voi
return 0;
}
// Update the custom proxy HTTP header dialog
void CmProxyHttpHeaderDlgUpdate(HWND hWnd)
{
UINT i = 0;
bool ok = true;
LIST *names_list;
// Validate arguments
if (hWnd == NULL)
{
return;
}
names_list = NewList(NULL);
for (; i < LvNum(hWnd, L_VALUES_LIST); i++)
{
wchar_t *str = LvGetStr(hWnd, L_VALUES_LIST, i, 0);
UniTrim(str);
if (IsEmptyUniStr(str) || IsInListUniStr(names_list, str))
{
Free(str);
ok = false;
break;
}
Add(names_list, str);
}
FreeStrList(names_list);
SetEnable(hWnd, IDOK, ok);
}
// Update the custom proxy HTTP header dialog content
void CmProxyHttpHeaderDlgRefresh(HWND hWnd, CM_PROXY_HTTP_HEADER_DLG *d)
{
UINT i = 0;
LIST *list;
LVB *b;
CLIENT_OPTION *a;
// Validate arguments
if (hWnd == NULL || d == NULL)
{
return;
}
a = (CLIENT_OPTION *)d->ClientOption;
list = NewEntryList(a->CustomHttpHeader, "\r\n", ":");
b = LvInsertStart();
for (; i < LIST_NUM(list); i++)
{
INI_ENTRY *e = LIST_DATA(list, i);
wchar_t *name = CopyStrToUni(e->Key);
wchar_t *value = CopyStrToUni(e->Value);
UniTrimLeft(value);
LvInsertAdd(b, 0, NULL, 2, name, value);
Free(name);
Free(value);
}
LvInsertEnd(b, hWnd, L_VALUES_LIST);
FreeEntryList(list);
}
// Initialize the custom proxy HTTP header dialog
void CmProxyHttpHeaderDlgInit(HWND hWnd, CM_PROXY_HTTP_HEADER_DLG *d)
{
// Validate arguments
if (hWnd == NULL || d == NULL)
{
return;
}
LvSetEnhanced(hWnd, L_VALUES_LIST, true);
LvInitEx(hWnd, L_VALUES_LIST, true);
LvInsertColumn(hWnd, L_VALUES_LIST, 0, _UU("CM_HTTP_HEADER_COLUMN_0"), 150);
LvInsertColumn(hWnd, L_VALUES_LIST, 1, _UU("CM_HTTP_HEADER_COLUMN_1"), 150);
LvSetStyle(hWnd, L_VALUES_LIST, LVS_EX_GRIDLINES);
CmProxyHttpHeaderDlgRefresh(hWnd, d);
}
// Custom proxy HTTP header dialog control
UINT CmProxyHttpHeaderDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CM_PROXY_HTTP_HEADER_DLG *d = (CM_PROXY_HTTP_HEADER_DLG *)param;
CLIENT_OPTION *a = (d == NULL ? NULL : d->ClientOption);
UINT i = INFINITE;
// Validate arguments
if (hWnd == NULL || d == NULL || a == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
CmProxyHttpHeaderDlgInit(hWnd, d);
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
case WM_NOTIFY:
{
switch (((LPNMHDR)lParam)->code)
{
// Header divider being dragged (resizing columns)
case HDN_ITEMCHANGINGA:
case HDN_ITEMCHANGINGW:
if (d->EditBox != NULL)
{
RECT rect;
ListView_GetSubItemRect(DlgItem(hWnd, L_VALUES_LIST), d->CurrentItem, d->CurrentSubItem, LVIR_LABEL, &rect);
MoveWindow(d->EditBox, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true);
RedrawWindow(d->EditBox, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
}
break;
case LVN_ITEMCHANGED:
if (((LPNMHDR)lParam)->idFrom == L_VALUES_LIST)
{
CmProxyHttpHeaderDlgUpdate(hWnd);
}
break;
case NM_DBLCLK:
{
RECT rect;
LPNMLISTVIEW list_view = (LPNMLISTVIEW)lParam;
wchar_t *str;
d->CurrentItem = list_view->iItem;
d->CurrentSubItem = list_view->iSubItem;
str = LvGetStr(DlgItem(hWnd, L_VALUES_LIST), 0, d->CurrentItem, d->CurrentSubItem);
ListView_GetSubItemRect(DlgItem(hWnd, L_VALUES_LIST), d->CurrentItem, d->CurrentSubItem, LVIR_LABEL, &rect);
d->EditBox = CreateWindowExW(0, L"EDIT", str, WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT | ES_MULTILINE | ES_WANTRETURN, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DlgItem(hWnd, L_VALUES_LIST), NULL, GetModuleHandle(NULL), NULL);
Free(str);
DlgFont(d->EditBox, 0, 8, false);
EditBoxSetEnhanced(d->EditBox, 0, true);
FocusEx(d->EditBox, 0);
break;
}
case NM_CLICK:
case NM_RETURN:
if (d->EditBox != NULL)
{
wchar_t *new_name = GetText(d->EditBox, 0);
wchar_t *old_name = LvGetStr(hWnd, L_VALUES_LIST, d->CurrentItem, d->CurrentSubItem);
if (old_name != NULL)
{
if (UniStrCmp(new_name, old_name) != 0)
{
LvSetItem(hWnd, L_VALUES_LIST, d->CurrentItem, d->CurrentSubItem, new_name);
}
Free(old_name);
}
Free(new_name);
DestroyWindow(d->EditBox);
d->EditBox = NULL;
}
}
break;
}
case WM_COMMAND:
switch (wParam)
{
case B_NEW:
{
NMLISTVIEW lv;
if (d->EditBox != NULL)
{
DestroyWindow(d->EditBox);
}
i = LvInsertItem(hWnd, L_VALUES_LIST, 0, NULL, L"");
LvSelect(hWnd, L_VALUES_LIST, i);
Zero(&lv, sizeof(lv));
lv.hdr.code = NM_DBLCLK;
lv.iItem = i;
lv.iSubItem = 0;
SendMsg(hWnd, 0, WM_NOTIFY, 0, (LPARAM)&lv);
}
break;
case B_DELETE:
if (d->EditBox != NULL)
{
DestroyWindow(d->EditBox);
}
i = LvGetSelected(hWnd, L_VALUES_LIST);
if (i != INFINITE)
{
LvDeleteItem(hWnd, L_VALUES_LIST, i);
}
CmProxyHttpHeaderDlgUpdate(hWnd);
break;
case B_CLEAR:
if (d->EditBox != NULL)
{
DestroyWindow(d->EditBox);
}
LvReset(hWnd, L_VALUES_LIST);
CmProxyHttpHeaderDlgUpdate(hWnd);
break;
case IDOK:
{
UINT index = 0;
char *name = NULL;
char *value = NULL;
char http_header[HTTP_CUSTOM_HEADER_MAX_SIZE];
Zero(http_header, sizeof(http_header));
i = LvNum(hWnd, L_VALUES_LIST);
for (; index < i; index++)
{
char str[HTTP_CUSTOM_HEADER_MAX_SIZE];
name = LvGetStrA(hWnd, L_VALUES_LIST, index, 0);
value = LvGetStrA(hWnd, L_VALUES_LIST, index, 1);
Trim(name);
TrimLeft(value);
Format(str, sizeof(str), "%s: %s\r\n", name, value);
EnSafeHttpHeaderValueStr(str, ' ');
Free(name);
Free(value);
if ((StrLen(http_header) + StrLen(str)) < sizeof(a->CustomHttpHeader))
{
StrCat(http_header, sizeof(str), str);
}
else
{
MsgBox(hWnd, MB_ICONEXCLAMATION | MB_OK, _E(ERR_TOO_MANT_ITEMS));
return 1;
}
}
Zero(a->CustomHttpHeader, sizeof(a->CustomHttpHeader));
StrCpy(a->CustomHttpHeader, sizeof(a->CustomHttpHeader), http_header);
EndDialog(hWnd, true);
break;
}
case IDCANCEL:
Close(hWnd);
}
}
return 0;
}
// Custom proxy HTTP header dialog
bool CmProxyHttpHeaderDlg(HWND hWnd, CLIENT_OPTION *a)
{
CM_PROXY_HTTP_HEADER_DLG d;
// Validate arguments
if (a == NULL)
{
return false;
}
Zero(&d, sizeof(d));
d.ClientOption = a;
return Dialog(hWnd, D_CM_PROXY_HTTP_HEADER, CmProxyHttpHeaderDlgProc, &d);
}
// Update the proxy server settings
void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)
{
@@ -7840,6 +8124,8 @@ void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)
return;
}
SetEnable(hWnd, B_HTTP_HEADER, a->ProxyType == PROXY_HTTP);
if (IsEmpty(hWnd, E_HOSTNAME))
{
ok = false;
@@ -7903,6 +8189,9 @@ UINT CmProxyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *par
switch (wParam)
{
case B_HTTP_HEADER:
CmProxyHttpHeaderDlg(hWnd, a);
break;
case IDOK:
GetTxtA(hWnd, E_HOSTNAME, a->ProxyName, sizeof(a->ProxyName));
GetTxtA(hWnd, E_USERNAME, a->ProxyUsername, sizeof(a->ProxyUsername));
+13 -1
View File
@@ -289,6 +289,14 @@ typedef struct CM_TRAFFIC_DLG
bool CloseDialogAfter; // Flag of whether or not to close the dialog
} CM_TRAFFIC_DLG;
typedef struct CM_PROXY_HTTP_HEADER_DLG
{
CLIENT_OPTION *ClientOption;
HWND EditBox;
UINT CurrentItem;
UINT CurrentSubItem;
} CM_PROXY_HTTP_HEADER_DLG;
// Internet connection settings
typedef struct CM_INTERNET_SETTING
{
@@ -639,4 +647,8 @@ void CmProxyDlgSet(HWND hWnd, CLIENT_OPTION *o, CM_INTERNET_SETTING *setting);
bool CmGetProxyServerNameAndPortFromIeProxyRegStr(char *name, UINT name_size, UINT *port, char *str, char *server_type);
void *CmUpdateJumpList(UINT start_id);
void CmProxyHttpHeaderDlgUpdate(HWND hWnd);
void CmProxyHttpHeaderDlgRefresh(HWND hWnd, CM_PROXY_HTTP_HEADER_DLG *d);
void CmProxyHttpHeaderDlgInit(HWND hWnd, CM_PROXY_HTTP_HEADER_DLG *d);
UINT CmProxyHttpHeaderDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param);
bool CmProxyHttpHeaderDlg(HWND hWnd, CLIENT_OPTION *a);
+8
View File
@@ -4424,6 +4424,7 @@ void InRpcClientOption(CLIENT_OPTION *c, PACK *p)
PackGetStr(p, "ProxyName", c->ProxyName, sizeof(c->ProxyName));
PackGetStr(p, "ProxyUsername", c->ProxyUsername, sizeof(c->ProxyUsername));
PackGetStr(p, "ProxyPassword", c->ProxyPassword, sizeof(c->ProxyPassword));
PackGetStr(p, "CustomHttpHeader", c->CustomHttpHeader, sizeof(c->CustomHttpHeader));
PackGetStr(p, "HubName", c->HubName, sizeof(c->HubName));
PackGetStr(p, "DeviceName", c->DeviceName, sizeof(c->DeviceName));
c->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
@@ -4449,6 +4450,7 @@ void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
PackAddStr(p, "ProxyName", c->ProxyName);
PackAddStr(p, "ProxyUsername", c->ProxyUsername);
PackAddStr(p, "ProxyPassword", c->ProxyPassword);
PackAddStr(p, "CustomHttpHeader", c->CustomHttpHeader);
PackAddStr(p, "HubName", c->HubName);
PackAddStr(p, "DeviceName", c->DeviceName);
PackAddInt(p, "Port", c->Port);
@@ -9404,6 +9406,7 @@ CLIENT_OPTION *CiLoadClientOption(FOLDER *f)
StrCpy(o->ProxyPassword, sizeof(o->ProxyPassword), s);
Free(s);
FreeBuf(b);
CfgGetStr(f, "CustomHttpHeader", o->CustomHttpHeader, sizeof(o->CustomHttpHeader));
o->NumRetry = CfgGetInt(f, "NumRetry");
o->RetryInterval = CfgGetInt(f, "RetryInterval");
CfgGetStr(f, "HubName", o->HubName, sizeof(o->HubName));
@@ -9729,6 +9732,8 @@ bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root)
FreeBuf(pw);
}
CfgGetStr(proxy, "CustomHttpHeader", t.CustomHttpHeader, sizeof(t.CustomHttpHeader));
Copy(&c->CommonProxySetting, &t, sizeof(INTERNET_SETTING));
}
@@ -9938,6 +9943,7 @@ void CiWriteClientOption(FOLDER *f, CLIENT_OPTION *o)
b = EncryptPassword(o->ProxyPassword);
CfgAddByte(f, "ProxyPassword", b->Buf, b->Size);
FreeBuf(b);
CfgAddStr(f, "CustomHttpHeader", o->CustomHttpHeader);
CfgAddInt(f, "NumRetry", o->NumRetry);
CfgAddInt(f, "RetryInterval", o->RetryInterval);
CfgAddStr(f, "HubName", o->HubName);
@@ -10272,6 +10278,8 @@ void CiWriteSettingToCfg(CLIENT *c, FOLDER *root)
FreeBuf(pw);
}
CfgAddStr(proxy, "CustomHttpHeader", t->CustomHttpHeader);
}
// CA
+459 -1
View File
@@ -3054,6 +3054,9 @@ void PcMain(PC *pc)
{"AccountEncryptEnable", PcAccountEncryptEnable},
{"AccountCompressEnable", PcAccountCompressEnable},
{"AccountCompressDisable", PcAccountCompressDisable},
{"AccountHttpHeaderAdd", PcAccountHttpHeaderAdd},
{"AccountHttpHeaderDelete", PcAccountHttpHeaderDelete},
{"AccountHttpHeaderGet", PcAccountHttpHeaderGet},
{"AccountProxyNone", PcAccountProxyNone},
{"AccountProxyHttp", PcAccountProxyHttp},
{"AccountProxySocks", PcAccountProxySocks},
@@ -5112,6 +5115,226 @@ UINT PcAccountCompressDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *pa
return ret;
}
UINT PcAccountHttpHeaderAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"NAME", CmdPrompt, _UU("CMD_AccountHttpHeader_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"DATA", CmdPrompt, _UU("CMD_AccountHttpHeader_Prompt_Data"), NULL, NULL},
};
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
UINT i = 0;
TOKEN_LIST *tokens = NULL;
HTTP_HEADER *header = NULL;
char *name = GetParamStr(o, "NAME");
Trim(name);
header = NewHttpHeader("", "", "");
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
AddHttpValueStr(header, tokens->Token[i]);
}
FreeToken(tokens);
if (GetHttpValue(header, name) == NULL)
{
RPC_CLIENT_CREATE_ACCOUNT z;
char s[HTTP_CUSTOM_HEADER_MAX_SIZE];
Format(s, sizeof(s), "%s: %s\r\n", name, GetParamStr(o, "DATA"));
EnSafeHttpHeaderValueStr(s, ' ');
if ((StrLen(s) + StrLen(t.ClientOption->CustomHttpHeader)) < sizeof(t.ClientOption->CustomHttpHeader)) {
StrCat(t.ClientOption->CustomHttpHeader, sizeof(s), s);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
ret = CcSetAccount(pc->RemoteClient, &z);
}
else
{
// Error has occurred
ret = ERR_TOO_MANT_ITEMS;
}
}
else
{
// Error has occurred
ret = ERR_OBJECT_EXISTS;
}
FreeHttpHeader(header);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
UINT PcAccountHttpHeaderDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"NAME", CmdPrompt, _UU("CMD_AccountHttpHeader_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// Get the parameter list
LIST *o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
UINT i = 0;
TOKEN_LIST *tokens = NULL;
RPC_CLIENT_CREATE_ACCOUNT z;
char *value = GetParamStr(o, "NAME");
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
Zero(z.ClientOption->CustomHttpHeader, sizeof(z.ClientOption->CustomHttpHeader));
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
if (StartWith(tokens->Token[i], value) == false)
{
StrCat(z.ClientOption->CustomHttpHeader, sizeof(z.ClientOption->CustomHttpHeader), tokens->Token[i]);
StrCat(z.ClientOption->CustomHttpHeader, 1, "\r\n");
}
}
ret = CcSetAccount(pc->RemoteClient, &z);
}
else
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
UINT PcAccountHttpHeaderGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// Get the parameter list
LIST *o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
// Release of the parameter list
FreeParamValueList(o);
if (ret == ERR_NO_ERROR)
{
wchar_t unistr[HTTP_CUSTOM_HEADER_MAX_SIZE];
TOKEN_LIST *tokens = NULL;
UINT i = 0;
CT *ct = CtNew();
CtInsertColumn(ct, _UU("CMD_CT_STD_COLUMN_1"), false);
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
StrToUni(unistr, sizeof(unistr), tokens->Token[i]);
CtInsert(ct, unistr);
}
CtFreeEx(ct, c, false);
}
else
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
return ret;
}
// Set the connection method of the connection settings to the direct TCP/IP connection
UINT PcAccountProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
@@ -7476,6 +7699,9 @@ void PsMain(PS *ps)
{"CascadeCompressEnable", PsCascadeCompressEnable},
{"CascadeCompressDisable", PsCascadeCompressDisable},
{"CascadeProxyNone", PsCascadeProxyNone},
{"CascadeHttpHeaderAdd", PsCascadeHttpHeaderAdd},
{"CascadeHttpHeaderDelete", PsCascadeHttpHeaderDelete},
{"CascadeHttpHeaderGet", PsCascadeHttpHeaderGet},
{"CascadeProxyHttp", PsCascadeProxyHttp},
{"CascadeProxySocks", PsCascadeProxySocks},
{"CascadeProxySocks5", PsCascadeProxySocks5},
@@ -13580,6 +13806,238 @@ UINT PsCascadeCompressDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *pa
return 0;
}
UINT PsCascadeHttpHeaderAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PS *ps = (PS *)param;
UINT ret = ERR_NO_ERROR;
RPC_CREATE_LINK t;
// Parameter list that can be specified
PARAM args[] =
{
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"NAME", CmdPrompt, _UU("CMD_CascadeHttpHeader_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"DATA", CmdPrompt, _UU("CMD_CascadeHttpHeader_Prompt_Data"), NULL, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
c->Write(c, _UU("CMD_Hub_Not_Selected"));
return ERR_INVALID_PARAMETER;
}
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), GetParamUniStr(o, "[name]"));
ret = ScGetLink(ps->Rpc, &t);
if (ret == ERR_NO_ERROR)
{
UINT i = 0;
TOKEN_LIST *tokens = NULL;
HTTP_HEADER *header = NULL;
char *name = GetParamStr(o, "NAME");
Trim(name);
header = NewHttpHeader("", "", "");
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
AddHttpValueStr(header, tokens->Token[i]);
}
FreeToken(tokens);
if (GetHttpValue(header, name) == NULL)
{
char s[HTTP_CUSTOM_HEADER_MAX_SIZE];
Format(s, sizeof(s), "%s: %s\r\n", name, GetParamStr(o, "DATA"));
EnSafeHttpHeaderValueStr(s, ' ');
if ((StrLen(s) + StrLen(t.ClientOption->CustomHttpHeader)) < sizeof(t.ClientOption->CustomHttpHeader)) {
StrCat(t.ClientOption->CustomHttpHeader, sizeof(s), s);
ret = ScSetLink(ps->Rpc, &t);
}
else
{
// Error has occurred
ret = ERR_TOO_MANT_ITEMS;
}
}
else
{
// Error has occurred
ret = ERR_OBJECT_EXISTS;
}
FreeHttpHeader(header);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
FreeRpcCreateLink(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
UINT PsCascadeHttpHeaderDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PS *ps = (PS *)param;
UINT ret = ERR_NO_ERROR;
RPC_CREATE_LINK t;
// Parameter list that can be specified
PARAM args[] =
{
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"NAME", CmdPrompt, _UU("CMD_CascadeHttpHeader_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
c->Write(c, _UU("CMD_Hub_Not_Selected"));
return ERR_INVALID_PARAMETER;
}
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), GetParamUniStr(o, "[name]"));
ret = ScGetLink(ps->Rpc, &t);
if (ret == ERR_NO_ERROR)
{
UINT i = 0;
TOKEN_LIST *tokens = NULL;
char *value = GetParamStr(o, "NAME");
Zero(t.ClientOption->CustomHttpHeader, sizeof(t.ClientOption->CustomHttpHeader));
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
if (StartWith(tokens->Token[i], value) == false)
{
StrCat(t.ClientOption->CustomHttpHeader, sizeof(t.ClientOption->CustomHttpHeader), tokens->Token[i]);
StrCat(t.ClientOption->CustomHttpHeader, 1, "\r\n");
}
}
ret = ScSetLink(ps->Rpc, &t);
}
else
{
// Error has occurred
CmdPrintError(c, ret);
}
FreeRpcCreateLink(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
UINT PsCascadeHttpHeaderGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PS *ps = (PS *)param;
UINT ret = ERR_NO_ERROR;
RPC_CREATE_LINK t;
// Parameter list that can be specified
PARAM args[] =
{
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
c->Write(c, _UU("CMD_Hub_Not_Selected"));
return ERR_INVALID_PARAMETER;
}
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), GetParamUniStr(o, "[name]"));
ret = ScGetLink(ps->Rpc, &t);
// Release of the parameter list
FreeParamValueList(o);
if (ret == ERR_NO_ERROR)
{
wchar_t unistr[HTTP_CUSTOM_HEADER_MAX_SIZE];
TOKEN_LIST *tokens = NULL;
UINT i = 0;
CT *ct = CtNew();
CtInsertColumn(ct, _UU("CMD_CT_STD_COLUMN_1"), false);
tokens = ParseToken(t.ClientOption->CustomHttpHeader, "\r\n");
for (i = 0; i < tokens->NumTokens; i++)
{
StrToUni(unistr, sizeof(unistr), tokens->Token[i]);
CtInsert(ct, unistr);
}
CtFreeEx(ct, c, false);
}
else
{
// Error has occurred
CmdPrintError(c, ret);
}
FreeRpcCreateLink(&t);
return ret;
}
// Set the cascade connection method to the TCP/IP direct connection mode
UINT PsCascadeProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
@@ -13593,7 +14051,7 @@ UINT PsCascadeProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
+6
View File
@@ -453,6 +453,9 @@ UINT PcAccountEncryptDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *par
UINT PcAccountEncryptEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountCompressEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountCompressDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountHttpHeaderAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountHttpHeaderDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountHttpHeaderGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountProxyHttp(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountProxySocks(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
@@ -591,6 +594,9 @@ UINT PsCascadeEncryptEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
UINT PsCascadeEncryptDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeCompressEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeCompressDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeHttpHeaderAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeHttpHeaderDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeHttpHeaderGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeProxyHttp(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeProxySocks(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
+29 -28
View File
@@ -163,34 +163,35 @@ struct RC4_KEY_PAIR
// Client Options
struct CLIENT_OPTION
{
wchar_t AccountName[MAX_ACCOUNT_NAME_LEN + 1]; // Connection setting name
char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name
UINT Port; // Port number
UINT PortUDP; // UDP port number (0: Use only TCP)
UINT ProxyType; // Type of proxy
char ProxyName[MAX_HOST_NAME_LEN + 1]; // Proxy server name
UINT ProxyPort; // Port number of the proxy server
char ProxyUsername[MAX_PROXY_USERNAME_LEN + 1]; // Maximum user name length
char ProxyPassword[MAX_PROXY_PASSWORD_LEN + 1]; // Maximum password length
UINT NumRetry; // Automatic retries
UINT RetryInterval; // Retry interval
char HubName[MAX_HUBNAME_LEN + 1]; // HUB name
UINT MaxConnection; // Maximum number of concurrent TCP connections
bool UseEncrypt; // Use encrypted communication
bool UseCompress; // Use data compression
bool HalfConnection; // Use half connection in TCP
bool NoRoutingTracking; // Disable the routing tracking
char DeviceName[MAX_DEVICE_NAME_LEN + 1]; // VLAN device name
UINT AdditionalConnectionInterval; // Connection attempt interval when additional connection establish
UINT ConnectionDisconnectSpan; // Disconnection interval
bool HideStatusWindow; // Hide the status window
bool HideNicInfoWindow; // Hide the NIC status window
bool RequireMonitorMode; // Monitor port mode
bool RequireBridgeRoutingMode; // Bridge or routing mode
bool DisableQoS; // Disable the VoIP / QoS function
bool FromAdminPack; // For Administration Pack
bool NoUdpAcceleration; // Do not use UDP acceleration mode
UCHAR HostUniqueKey[SHA1_SIZE]; // Host unique key
wchar_t AccountName[MAX_ACCOUNT_NAME_LEN + 1]; // Connection setting name
char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name
UINT Port; // Port number
UINT PortUDP; // UDP port number (0: Use only TCP)
UINT ProxyType; // Type of proxy
char ProxyName[MAX_HOST_NAME_LEN + 1]; // Proxy server name
UINT ProxyPort; // Port number of the proxy server
char ProxyUsername[MAX_PROXY_USERNAME_LEN + 1]; // Maximum user name length
char ProxyPassword[MAX_PROXY_PASSWORD_LEN + 1]; // Maximum password length
char CustomHttpHeader[HTTP_CUSTOM_HEADER_MAX_SIZE + 1]; // Custom HTTP proxy header
UINT NumRetry; // Automatic retries
UINT RetryInterval; // Retry interval
char HubName[MAX_HUBNAME_LEN + 1]; // HUB name
UINT MaxConnection; // Maximum number of concurrent TCP connections
bool UseEncrypt; // Use encrypted communication
bool UseCompress; // Use data compression
bool HalfConnection; // Use half connection in TCP
bool NoRoutingTracking; // Disable the routing tracking
char DeviceName[MAX_DEVICE_NAME_LEN + 1]; // VLAN device name
UINT AdditionalConnectionInterval; // Connection attempt interval when additional connection establish
UINT ConnectionDisconnectSpan; // Disconnection interval
bool HideStatusWindow; // Hide the status window
bool HideNicInfoWindow; // Hide the NIC status window
bool RequireMonitorMode; // Monitor port mode
bool RequireBridgeRoutingMode; // Bridge or routing mode
bool DisableQoS; // Disable the VoIP / QoS function
bool FromAdminPack; // For Administration Pack
bool NoUdpAcceleration; // Do not use UDP acceleration mode
UCHAR HostUniqueKey[SHA1_SIZE]; // Host unique key
};
// Client authentication data
+67 -19
View File
@@ -6022,6 +6022,7 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
w.ProxyPort = o->ProxyPort;
StrCpy(w.ProxyUsername, sizeof(w.ProxyUsername), o->ProxyUsername);
StrCpy(w.ProxyPassword, sizeof(w.ProxyPassword), o->ProxyPassword);
StrCpy(w.CustomHttpHeader, sizeof(w.CustomHttpHeader), w.CustomHttpHeader);
switch (o->ProxyType)
{
@@ -6078,9 +6079,7 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
PrintStatus(sess, tmp);
// Proxy connection
s = ProxyConnectEx(c, w.ProxyHostName, w.ProxyPort,
w.HostName, w.Port, w.ProxyUsername, w.ProxyPassword,
additional_connect, (bool *)cancel_flag, hWnd);
s = ProxyConnectEx3(c, &w, additional_connect, (bool *)cancel_flag, hWnd, 0);
if (s == NULL)
{
// Connection failure
@@ -6654,6 +6653,22 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
char *server_host_name, UINT server_port,
char *username, char *password, bool additional_connect,
bool *cancel_flag, void *hWnd, UINT timeout)
{
WPC_CONNECT wpc_connect;
Zero(&wpc_connect, sizeof(wpc_connect));
StrCpy(wpc_connect.ProxyHostName, sizeof(wpc_connect.ProxyHostName), proxy_host_name);
wpc_connect.ProxyPort = proxy_port;
StrCpy(wpc_connect.HostName, sizeof(wpc_connect.HostName), server_host_name);
wpc_connect.Port = server_port;
StrCpy(wpc_connect.ProxyUsername, sizeof(wpc_connect.ProxyUsername), username);
StrCpy(wpc_connect.ProxyPassword, sizeof(wpc_connect.ProxyPassword), password);
return ProxyConnectEx3(c, &wpc_connect, additional_connect, cancel_flag, hWnd, timeout);
}
SOCK *ProxyConnectEx3(CONNECTION *c, WPC_CONNECT *wpc_connect,
bool additional_connect, bool *cancel_flag, void *hWnd,
UINT timeout)
{
SOCK *s = NULL;
bool use_auth = false;
@@ -6665,17 +6680,16 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
char server_host_name_tmp[256];
UINT i, len;
// Validate arguments
if (c == NULL || proxy_host_name == NULL || proxy_port == 0 || server_host_name == NULL ||
server_port == 0)
if (c == NULL || IsEmptyStr(wpc_connect->ProxyHostName) || wpc_connect->ProxyPort == 0 || IsEmptyStr(wpc_connect->HostName) || wpc_connect->Port == 0)
{
if( c != NULL)
if (c != NULL)
{
c->Err = ERR_PROXY_CONNECT_FAILED;
}
return NULL;
}
if (username != NULL && password != NULL &&
(StrLen(username) != 0 || StrLen(password) != 0))
if ((IsEmptyStr(wpc_connect->ProxyUsername) || IsEmptyStr(wpc_connect->ProxyPassword)) == false)
{
use_auth = true;
}
@@ -6688,7 +6702,7 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
}
Zero(server_host_name_tmp, sizeof(server_host_name_tmp));
StrCpy(server_host_name_tmp, sizeof(server_host_name_tmp), server_host_name);
StrCpy(server_host_name_tmp, sizeof(server_host_name_tmp), wpc_connect->HostName);
len = StrLen(server_host_name_tmp);
@@ -6701,7 +6715,7 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
}
// Connection
s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, NULL);
s = TcpConnectEx3(wpc_connect->ProxyHostName, wpc_connect->ProxyPort, timeout, cancel_flag, hWnd, true, NULL, false, NULL);
if (s == NULL)
{
// Failure
@@ -6726,27 +6740,61 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
StrToIP(&ip, server_host_name_tmp);
IPToStr(iptmp, sizeof(iptmp), &ip);
Format(tmp, sizeof(tmp), "[%s]:%u", iptmp, server_port);
Format(tmp, sizeof(tmp), "[%s]:%u", iptmp, wpc_connect->Port);
}
else
{
Format(tmp, sizeof(tmp), "%s:%u", server_host_name_tmp, server_port);
Format(tmp, sizeof(tmp), "%s:%u", server_host_name_tmp, wpc_connect->Port);
}
h = NewHttpHeader("CONNECT", tmp, "HTTP/1.0");
AddHttpValue(h, NewHttpValue("User-Agent", (c->Cedar == NULL ? DEFAULT_USER_AGENT : c->Cedar->HttpUserAgent)));
AddHttpValue(h, NewHttpValue("Host", server_host_name_tmp));
AddHttpValue(h, NewHttpValue("Content-Length", "0"));
AddHttpValue(h, NewHttpValue("Proxy-Connection", "Keep-Alive"));
AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
if (use_auth)
if (IsEmptyStr(wpc_connect->CustomHttpHeader) == false)
{
TOKEN_LIST *tokens = ParseToken(wpc_connect->CustomHttpHeader, "\r\n");
if (tokens != NULL)
{
for (i = 0; i < tokens->NumTokens; i++)
{
AddHttpValueStr(h, tokens->Token[i]);
}
FreeToken(tokens);
}
}
if (GetHttpValue(h, "User-Agent") == NULL)
{
AddHttpValue(h, NewHttpValue("User-Agent", (c->Cedar == NULL ? DEFAULT_USER_AGENT : c->Cedar->HttpUserAgent)));
}
if (GetHttpValue(h, "Host") == NULL)
{
AddHttpValue(h, NewHttpValue("Host", server_host_name_tmp));
}
if (GetHttpValue(h, "Content-Length") == NULL)
{
AddHttpValue(h, NewHttpValue("Content-Length", "0"));
}
if (GetHttpValue(h, "Proxy-Connection") == NULL)
{
AddHttpValue(h, NewHttpValue("Proxy-Connection", "Keep-Alive"));
}
if (GetHttpValue(h, "Pragma") == NULL)
{
AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
}
if (use_auth && GetHttpValue(h, "Proxy-Authorization") == NULL)
{
wchar_t tmp[MAX_SIZE];
UniFormat(tmp, sizeof(tmp), _UU("STATUS_3"), server_host_name_tmp);
// Generate the authentication string
Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s",
username, password);
wpc_connect->ProxyUsername, wpc_connect->ProxyPassword);
// Base64 encode
Zero(auth_b64_str, sizeof(auth_b64_str));
+3
View File
@@ -265,6 +265,9 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
char *server_host_name, UINT server_port,
char *username, char *password, bool additional_connect,
bool *cancel_flag, void *hWnd, UINT timeout);
SOCK *ProxyConnectEx3(CONNECTION *c, WPC_CONNECT *wpc_connect,
bool additional_connect, bool *cancel_flag, void *hWnd,
UINT timeout);
SOCK *SocksConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
char *server_host_name, UINT server_port,
char *username, bool additional_connect,
+2
View File
@@ -247,6 +247,7 @@ UINT SmProxyDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
a.ProxyPort = t->ProxyPort;
StrCpy(a.ProxyUsername, sizeof(a.ProxyUsername), t->ProxyUsername);
StrCpy(a.ProxyPassword, sizeof(a.ProxyPassword), t->ProxyPassword);
StrCpy(a.CustomHttpHeader, sizeof(a.CustomHttpHeader), t->CustomHttpHeader);
if (CmProxyDlg(hWnd, &a))
{
@@ -255,6 +256,7 @@ UINT SmProxyDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
t->ProxyPort = a.ProxyPort;
StrCpy(t->ProxyUsername, sizeof(t->ProxyUsername), a.ProxyUsername);
StrCpy(t->ProxyPassword, sizeof(t->ProxyPassword), a.ProxyPassword);
StrCpy(t->CustomHttpHeader, sizeof(t->CustomHttpHeader), a.CustomHttpHeader);
}
SmProxyDlgUpdate(hWnd, t);
+4
View File
@@ -2945,6 +2945,8 @@ bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)
FreeBuf(pw);
}
CfgGetStr(f8, "CustomHttpHeader", t.CustomHttpHeader, sizeof(t.CustomHttpHeader));
GetMachineHostName(machine_name, sizeof(machine_name));
CfgGetStr(f8, "LocalHostname", machine_name2, sizeof(machine_name2));
@@ -3314,6 +3316,8 @@ FOLDER *SiWriteConfigurationToCfg(SERVER *s)
FreeBuf(pw);
}
CfgAddStr(ddns_folder, "CustomHttpHeader", t->CustomHttpHeader);
}
}
+180
View File
@@ -4086,6 +4086,186 @@ void LvRename(HWND hWnd, UINT id, UINT pos)
ListView_EditLabel(DlgItem(hWnd, id), pos);
}
// Enhanced function
LRESULT CALLBACK LvEnhancedProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WNDPROC func = NULL;
if (MsIsNt())
{
func = (WNDPROC)GetPropW(hWnd, L"ORIGINAL_FUNC");
}
else
{
func = (WNDPROC)GetPropA(hWnd, "ORIGINAL_FUNC");
}
if (func == NULL)
{
Debug("LvEnhancedProc(): GetProp() returned NULL!\n");
return 1;
}
switch (msg)
{
case WM_HSCROLL:
case WM_VSCROLL:
case WM_MOUSEWHEEL:
{
// Prevent graphical glitches with the edit box by sending the NM_RETURN signal
// to the parent dialog (the parent dialog has to delete the edit box on NM_RETURN)
NMHDR nmh;
nmh.code = NM_RETURN;
nmh.idFrom = GetDlgCtrlID(hWnd);
nmh.hwndFrom = hWnd;
SendMsg(GetParent(hWnd), 0, WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh);
break;
}
case WM_CLOSE:
// Prevent list view from disappearing after pressing ESC in an edit box
return 0;
case WM_NCDESTROY:
// Restore original function during destruction
LvSetEnhanced(hWnd, 0, false);
}
if (MsIsNt())
{
return CallWindowProcW(func, hWnd, msg, wParam, lParam);
}
else
{
return CallWindowProcA(func, hWnd, msg, wParam, lParam);
}
}
// Toggle enhanced function
void LvSetEnhanced(HWND hWnd, UINT id, bool enable)
{
// Validate arguments
if (hWnd == NULL)
{
return;
}
if (enable)
{
if (MsIsNt())
{
const HANDLE fn = (HANDLE)SetWindowLongPtrW(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)LvEnhancedProc);
SetPropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC", fn);
}
else
{
const HANDLE fn = (HANDLE)SetWindowLongPtrA(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)LvEnhancedProc);
SetPropA(DlgItem(hWnd, id), "ORIGINAL_FUNC", fn);
}
}
else
{
if (MsIsNt())
{
SetWindowLongPtrW(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)GetPropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC"));
RemovePropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC");
}
else
{
SetWindowLongPtrA(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)GetPropA(DlgItem(hWnd, id), "ORIGINAL_FUNC"));
RemovePropA(DlgItem(hWnd, id), "ORIGINAL_FUNC");
}
}
}
// Enhanced function
LRESULT CALLBACK EditBoxEnhancedProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WNDPROC func = NULL;
if (MsIsNt())
{
func = (WNDPROC)GetPropW(hWnd, L"ORIGINAL_FUNC");
}
else
{
func = (WNDPROC)GetPropA(hWnd, "ORIGINAL_FUNC");
}
if (func == NULL)
{
Debug("EditBoxEnhancedProc(): GetProp() returned NULL!\n");
return 1;
}
switch (msg)
{
case WM_CHAR:
switch (wParam)
{
// CTRL + A
case 1:
SelectEdit(hWnd, 0);
return 0;
case VK_RETURN:
SendMsg(GetParent(hWnd), 0, WM_KEYDOWN, VK_RETURN, 0);
return 0;
case VK_ESCAPE:
DestroyWindow(hWnd);
return 0;
}
break;
case WM_NCDESTROY:
// Restore original function during destruction
EditBoxSetEnhanced(hWnd, 0, false);
}
if (MsIsNt())
{
return CallWindowProcW(func, hWnd, msg, wParam, lParam);
}
else
{
return CallWindowProcA(func, hWnd, msg, wParam, lParam);
}
}
// Toggle enhanced function
void EditBoxSetEnhanced(HWND hWnd, UINT id, bool enable)
{
// Validate arguments
if (hWnd == NULL)
{
return;
}
if (enable)
{
if (MsIsNt())
{
const HANDLE fn = (HANDLE)SetWindowLongPtrW(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)EditBoxEnhancedProc);
SetPropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC", fn);
}
else
{
const HANDLE fn = (HANDLE)SetWindowLongPtrA(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)EditBoxEnhancedProc);
SetPropA(DlgItem(hWnd, id), "ORIGINAL_FUNC", fn);
}
}
else
{
if (MsIsNt())
{
SetWindowLongPtrW(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)GetPropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC"));
RemovePropW(DlgItem(hWnd, id), L"ORIGINAL_FUNC");
}
else
{
SetWindowLongPtrA(DlgItem(hWnd, id), GWLP_WNDPROC, (LONG_PTR)GetPropA(DlgItem(hWnd, id), "ORIGINAL_FUNC"));
RemovePropA(DlgItem(hWnd, id), "ORIGINAL_FUNC");
}
}
}
// Show the menu
void PrintMenu(HWND hWnd, HMENU hMenu)
{
+2
View File
@@ -776,6 +776,8 @@ void RemoveShortcutKeyStrFromMenu(HMENU hMenu);
UINT GetMenuNum(HMENU hMenu);
void PrintMenu(HWND hWnd, HMENU hMenu);
void LvRename(HWND hWnd, UINT id, UINT pos);
void LvSetEnhanced(HWND hWnd, UINT id, bool enable);
void EditBoxSetEnhanced(HWND hWnd, UINT id, bool enable);
void AllowFGWindow(UINT process_id);
HWND SearchWindow(wchar_t *caption);
char *RemoteDlg(HWND hWnd, char *regkey, UINT icon, wchar_t *caption, wchar_t *title, char *default_host);
+3 -3
View File
@@ -631,9 +631,7 @@ SOCK *WpcSockConnectEx(WPC_CONNECT *param, UINT *error_code, UINT timeout, bool
break;
case PROXY_HTTP:
sock = ProxyConnectEx2(&c, param->ProxyHostName, param->ProxyPort,
param->HostName, param->Port,
param->ProxyUsername, param->ProxyPassword, false, cancel, NULL, timeout);
sock = ProxyConnectEx3(&c, param, false, cancel, NULL, timeout);
if (sock == NULL)
{
err = c.Err;
@@ -687,6 +685,7 @@ SOCK *WpcSockConnect2(char *hostname, UINT port, INTERNET_SETTING *t, UINT *erro
c.ProxyPort = t->ProxyPort;
StrCpy(c.ProxyUsername, sizeof(c.ProxyUsername), t->ProxyUsername);
StrCpy(c.ProxyPassword, sizeof(c.ProxyPassword), t->ProxyPassword);
StrCpy(c.CustomHttpHeader, sizeof(c.CustomHttpHeader), t->CustomHttpHeader);
return WpcSockConnect(&c, error_code, timeout);
}
@@ -779,6 +778,7 @@ BUF *HttpRequestEx3(URL_DATA *data, INTERNET_SETTING *setting,
con.ProxyPort = setting->ProxyPort;
StrCpy(con.ProxyUsername, sizeof(con.ProxyUsername), setting->ProxyUsername);
StrCpy(con.ProxyPassword, sizeof(con.ProxyPassword), setting->ProxyPassword);
StrCpy(con.CustomHttpHeader, sizeof(con.CustomHttpHeader), setting->CustomHttpHeader);
if (setting->ProxyType != PROXY_HTTP || data->Secure)
{
+16 -14
View File
@@ -126,25 +126,27 @@
// Connection parameters
struct WPC_CONNECT
{
char HostName[MAX_HOST_NAME_LEN + 1]; // Host name
UINT Port; // Port number
UINT ProxyType; // Type of proxy server
char ProxyHostName[MAX_HOST_NAME_LEN + 1]; // Proxy server host name
UINT ProxyPort; // Proxy server port number
char ProxyUsername[MAX_USERNAME_LEN + 1]; // Proxy server user name
char ProxyPassword[MAX_USERNAME_LEN + 1]; // Proxy server password
bool UseCompress; // Use of compression
bool DontCheckCert; // Do not check the certificate
char HostName[MAX_HOST_NAME_LEN + 1]; // Host name
UINT Port; // Port number
UINT ProxyType; // Type of proxy server
char ProxyHostName[MAX_HOST_NAME_LEN + 1]; // Proxy server host name
UINT ProxyPort; // Proxy server port number
char ProxyUsername[MAX_USERNAME_LEN + 1]; // Proxy server user name
char ProxyPassword[MAX_USERNAME_LEN + 1]; // Proxy server password
char CustomHttpHeader[HTTP_CUSTOM_HEADER_MAX_SIZE + 1]; // Custom HTTP header
bool UseCompress; // Use of compression
bool DontCheckCert; // Do not check the certificate
};
// Internet connection settings
struct INTERNET_SETTING
{
UINT ProxyType; // Type of proxy server
char ProxyHostName[MAX_HOST_NAME_LEN + 1]; // Proxy server host name
UINT ProxyPort; // Proxy server port number
char ProxyUsername[MAX_USERNAME_LEN + 1]; // Proxy server user name
char ProxyPassword[MAX_USERNAME_LEN + 1]; // Proxy server password
UINT ProxyType; // Type of proxy server
char ProxyHostName[MAX_HOST_NAME_LEN + 1]; // Proxy server host name
UINT ProxyPort; // Proxy server port number
char ProxyUsername[MAX_USERNAME_LEN + 1]; // Proxy server user name
char ProxyPassword[MAX_USERNAME_LEN + 1]; // Proxy server password
char CustomHttpHeader[HTTP_CUSTOM_HEADER_MAX_SIZE + 1]; // Custom HTTP header
};
// URL