diff options
Diffstat (limited to 'plugins/ProxySwitch/src')
-rw-r--r-- | plugins/ProxySwitch/src/ip.cpp | 728 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/main.cpp | 367 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/opt.cpp | 191 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/proxy.cpp | 304 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/resource.h | 41 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/stdafx.cxx | 18 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/stdafx.h | 212 | ||||
-rw-r--r-- | plugins/ProxySwitch/src/version.h | 13 |
8 files changed, 1874 insertions, 0 deletions
diff --git a/plugins/ProxySwitch/src/ip.cpp b/plugins/ProxySwitch/src/ip.cpp new file mode 100644 index 0000000000..abd793e3eb --- /dev/null +++ b/plugins/ProxySwitch/src/ip.cpp @@ -0,0 +1,728 @@ +/* +proxySwitch + +The plugin watches IP address changes, reports them via popups and adjusts +the proxy settings of Miranda and Internet Explorer accordingly. +*/ + +#include "stdafx.h" + +//#define IP_DEBUG +#ifdef IP_DEBUG +#pragma comment (lib, "user32") +#pragma comment (lib, "iphlpapi") +#pragma comment (lib, "ws2_32") +#define PopupMyIPAddrs(x) printf("PopupMyIPAddrs(%s)\n", x); +#define GetCurrentProcessId() 13604 +NETWORK_INTERFACE_LIST NIF_List; +CRITICAL_SECTION csNIF_List; +char opt_hideIntf[MAX_IPLIST_LENGTH]; +void UpdateInterfacesMenu (void) { } +PLUGINLINK *pluginLink; +int main(void) { + NETWORK_INTERFACE_LIST list; + char opt[200] = "2.252.83.0-2.252.85.0;10.100.0.0/16;2.252.83.32-38;;;32.64.128.0/255.255.255.0"; + IP_RANGE_LIST range; + InitializeCriticalSection(&csNIF_List); + lstrcpy(opt_hideIntf, "VMnet*"); + printf("Started\n"); + printf("IP Helper procs: %s\n", Load_ExIpHelper_Procedures() ? "Loaded" : "Not found"); + if ( Create_NIF_List( &list ) >=0 ) { + printf("%s\n", Print_NIF_List(list, NULL)); + + Create_Range_List( &range, opt, FALSE ); + printf("'%s' matches: %s\n", opt, Match_Range_List(range, list) ? "yes" : "no" ); + Free_Range_List( &range ); + + + Free_NIF_List( &list ); + } + DeleteCriticalSection(&csNIF_List); + printf("Finished\n"); + return 0; +} +#endif + +wchar_t tempstr[MAX_SECONDLINE]; + +/* ################################################################################ */ + +#ifndef IP_DEBUG +void IP_WatchDog (void *arg) { + OVERLAPPED overlap; + DWORD ret; + wchar_t msg[300]; + HANDLE event_list[2]; + HANDLE hand = WSACreateEvent(); + overlap.hEvent = WSACreateEvent(); + + for (;;) { + + ret = NotifyAddrChange(&hand, &overlap); + if (ret != NO_ERROR && WSAGetLastError() != WSA_IO_PENDING) { + wchar_t err[100]; + mir_snwprintf(err, L"NotifyAddrChange Error: %d/nRestart Miranda IM to restore IP monitor.", WSAGetLastError()); + ERRORMSG(err); + break; + } + + event_list[0] = overlap.hEvent; + event_list[1] = hEventRebound; + + ret = MsgWaitForMultipleObjectsEx( 2, event_list, INFINITE, 0, MWMO_ALERTABLE ); + if (ret == WAIT_IO_COMPLETION && Miranda_IsTerminated()) break; + if (ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT || ret == (WAIT_OBJECT_0+1) ) { + NETWORK_INTERFACE_LIST list; + + if ( Create_NIF_List_Ex( &list ) >=0 ) { + int change = INCUPD_INTACT; + + EnterCriticalSection(&csNIF_List); + change = IncUpdate_NIF_List(&NIF_List, list); + if ( change != INCUPD_INTACT && change != INCUPD_CONN_BIND ) { + char proxy = -1; + int change_Miranda = 0; + int reset_Miranda = 0; + int change_IE = 0; + int change_Firefox = 0; + IP_RANGE_LIST range; + + if ( proxy == -1 ) { + Create_Range_List( &range, opt_useProxy, TRUE ); + if ( Match_Range_List( range, NIF_List ) ) proxy = 1; + Free_Range_List( &range ); + } + if ( proxy == -1 ) { + Create_Range_List( &range, opt_noProxy, FALSE ); + if ( Match_Range_List( range, NIF_List ) ) proxy = 0; + Free_Range_List( &range ); + } + if ( proxy == -1 ) { + Create_Range_List( &range, opt_useProxy, FALSE ); + if ( Match_Range_List( range, NIF_List ) ) proxy = 1; + Free_Range_List( &range ); + } + + if ( proxy != -1 && proxy != Get_Miranda_Proxy_Status() ) change_Miranda = reset_Miranda = opt_miranda; + if ( proxy != -1 && proxy != Get_IE_Proxy_Status() ) change_IE = opt_ie; + if ( proxy != -1 && proxy != Get_Firefox_Proxy_Status() ) change_Firefox = opt_firefox; + if ( opt_alwayReconnect ) reset_Miranda = 1; + + mir_wstrcpy(msg, L""); + if ( opt_showProxyState && change_Miranda ) { + mir_wstrcat(msg, TranslateT("\nMiranda ")); + mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct")); + } + if ( opt_showProxyState && change_IE ) { + mir_wstrcat(msg, TranslateT("\nExplorer ")); + mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct")); + } + if ( opt_showProxyState && change_Firefox ) { + mir_wstrcat(msg, TranslateT("\nFirefox ")); + mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct")); + } + UpdateInterfacesMenu(); + PopupMyIPAddrs(mir_wstrlen(msg) ? msg : NULL); + + if ( change_IE ) Set_IE_Proxy_Status( proxy ); + if ( change_Firefox ) Set_Firefox_Proxy_Status( proxy ); + if ( reset_Miranda ) { + PROTO_SETTINGS protocols; + Disconnect_All_Protocols( &protocols, change_Miranda ); + Sleep( 1000 ); + if ( change_Miranda ) Set_Miranda_Proxy_Status( proxy ); + Connect_All_Protocols( &protocols ); + } + } + LeaveCriticalSection(&csNIF_List); + + Free_NIF_List( &list ); + } + } + + ResetEvent(hEventRebound); + WSAResetEvent(hand); + WSAResetEvent(overlap.hEvent); + } + + WSACloseEvent(hand); + WSACloseEvent(overlap.hEvent); +} +#endif + +/* ################################################################################ */ + +int Create_NIF_List_Ex (NETWORK_INTERFACE_LIST *list) { + UINT delay = 1; + int out; + + while ( (out = Create_NIF_List(list)) == -2 && delay < 10 ) { + Sleep(delay*50); + delay++; + } + if (out == -2) ERRORMSG(TranslateT("Cannot retrieve IP or Adapter data.")); + return out < 0 ? -1 : out; +} + +PNETWORK_INTERFACE Find_NIF_IP(NETWORK_INTERFACE_LIST list, const LONG IP) { + UCHAR idx = 0; + UCHAR i; + + while (idx < list.count) { + for (i = 0; i < list.item[idx].IPcount; i++) { + if (list.item[idx].IP[i] == IP) return &(list.item[idx]); + } + idx++; + } + return NULL; +} + +int Create_NIF_List (NETWORK_INTERFACE_LIST *list) { + + PIP_ADAPTER_INFO pAdapterInfo, pAdapt; + PIP_ADDR_STRING pAddrStr; + PIP_ADAPTER_ADDRESSES pAddresses, pAddr; + PNETWORK_INTERFACE nif; + ULONG outBufLen; + wchar_t *tmp_opt, *intf, *rest, *name; + BOOL skip; + DWORD out; + UCHAR idx; + + // prepare and load IP_ADAPTER_ADDRESSES + outBufLen = 0; + if (GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) { + pAddresses = (PIP_ADAPTER_ADDRESSES) malloc(outBufLen); + if (pAddresses == NULL) { + ERRORMSG(TranslateT("Cannot allocate memory for pAddresses")); + return -1; + } + if ((out = GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen)) != ERROR_SUCCESS) { + free(pAddresses); + return -2; + } + } else { + ERRORMSG(TranslateT("GetAdaptersAddresses sizing failed")); + return -1; + } + + // prepare and load IP_ADAPTER_INFO + outBufLen = 0; + if (GetAdaptersInfo(NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) { + pAdapterInfo = (PIP_ADAPTER_INFO) malloc(outBufLen); + if (pAdapterInfo == NULL) { + ERRORMSG(TranslateT("Cannot allocate memory for pAdapterInfo")); + free(pAddresses); + return -1; + } + if (GetAdaptersInfo(pAdapterInfo, &outBufLen) != NO_ERROR) { + free(pAdapterInfo); + free(pAddresses); + return -2; + } + } else { + ERRORMSG(TranslateT("GetAdaptersInfo sizing failed")); + free(pAddresses); + return -1; + } + + ZeroMemory(list, sizeof(NETWORK_INTERFACE_LIST)); + + pAdapt = pAdapterInfo; + while (pAdapt) { + + // add a new interface into the list + list->count++; + list->item = (PNETWORK_INTERFACE)mir_realloc( list->item, list->count * sizeof(NETWORK_INTERFACE) ); + nif = &(list->item[list->count - 1]); + ZeroMemory(nif, sizeof(NETWORK_INTERFACE)); + + // copy AdapterName + nif->AdapterName = (char*)mir_alloc(mir_strlen(pAdapt->AdapterName)+4); + nif->AdapterName = mir_strdup(pAdapt->AdapterName); + + // find its FriendlyName and copy it + pAddr = pAddresses; + while(pAddr && mir_strcmp(pAddr->AdapterName, pAdapt->AdapterName)) { + pAddr = pAddr->Next; + } + if ( pAddr ) { + nif->FriendlyName = (wchar_t*)mir_alloc(wcslen(pAddr->FriendlyName)+4); + nif->FriendlyName = mir_wstrdup(pAddr->FriendlyName); + } + + skip = FALSE; + tmp_opt = intf = rest = mir_wstrdup( opt_hideIntf ); + while ( rest && rest[0] && ! skip ) { + rest = wcschr( rest, ';' ); + if ( rest != NULL ) { + rest[0] = 0; + rest++; + } + if ( intf[0] ) { + if ( intf[mir_wstrlen(intf)-1] == '*' && mir_wstrlen(intf)-1 <= mir_wstrlen(nif->FriendlyName) ) { + intf[mir_wstrlen(intf)-1] = 0; + name = nif->FriendlyName; + skip = TRUE; + while ( intf[0] ) { + if ( intf[0] != name[0] ) { + skip = FALSE; + break; + } + intf++; + name++; + } + } + if ( mir_wstrcmp(nif->FriendlyName, intf) == 0 ) { + skip = TRUE; + } + } + intf = rest; + } + free(tmp_opt); + + if ( skip ) { + list->count--; + list->item = (PNETWORK_INTERFACE)mir_realloc( list->item, list->count * sizeof(NETWORK_INTERFACE) ); + pAdapt = pAdapt->Next; + continue; + } + + // get required size for IPstr and IP + outBufLen = 0; + pAddrStr = &(pAdapt->IpAddressList); + while(pAddrStr) { + if ( strcmp("0.0.0.0", pAddrStr->IpAddress.String) ) { + nif->IPcount++; // count IP addresses + outBufLen += strlen(pAddrStr->IpAddress.String); // count length of IPstr + } + pAddrStr = pAddrStr->Next; + if (pAddrStr) outBufLen += 2; // count length of IPstr (add ", ") + } + + // create IPstr and IP + if ( nif->IPcount ) { + nif->IPstr = (char*)mir_alloc( outBufLen+4 ); + strcpy(nif->IPstr, ""); + nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) ); + outBufLen = 0; + pAddrStr = &(pAdapt->IpAddressList); + while(pAddrStr) { + if ( strcmp("0.0.0.0", pAddrStr->IpAddress.String) ) { + strcat( nif->IPstr, pAddrStr->IpAddress.String ); + nif->IP[outBufLen] = inet_addr( pAddrStr->IpAddress.String ); + outBufLen++; + } + pAddrStr = pAddrStr->Next; + if (pAddrStr) strcat( nif->IPstr, ", "); + } + nif->IP[outBufLen] = 0L; + } + pAdapt = pAdapt->Next; + } + + free(pAdapterInfo); + free(pAddresses); + + EnterCriticalSection(&csConnection_List); + for ( idx=0 ; idx < Connection_List.count ; idx++ ) { + nif = Find_NIF_IP( *list, Connection_List.item[idx].IP ); + if ( nif ) { + nif->Bound = 1; + } + } + LeaveCriticalSection(&csConnection_List); + + return 0; +} + +/* ################################################################################ */ + +PNETWORK_INTERFACE Find_NIF_AdapterName ( NETWORK_INTERFACE_LIST list, const char *AdapterName) { + UCHAR idx = 0; + + while ( idx < list.count ) { + if ( strcmp(list.item[idx].AdapterName, AdapterName) == 0 ) return &(list.item[idx]); + idx++; + } + return NULL; +} + +PNETWORK_INTERFACE Find_NIF_MenuItem ( NETWORK_INTERFACE_LIST list, const HGENMENU MenuItem) { + UCHAR idx = 0; + + while ( idx < list.count ) { + if ( list.item[idx].MenuItem == MenuItem ) return &(list.item[idx]); + idx++; + } + return NULL; +} + +/* ################################################################################ */ + +BOOL Compare_NIF_Lists (NETWORK_INTERFACE_LIST list1, NETWORK_INTERFACE_LIST list2) { + UCHAR idx = 0; + + if ( list1.count != list2.count ) return 1; + while ( idx < list1.count ) { + if ( mir_strcmp(list1.item[idx].AdapterName, list2.item[idx].AdapterName) ) return 1; + if ( mir_strcmp(list1.item[idx].IPstr, list2.item[idx].IPstr) ) return 1; + if ( mir_wstrcmp(list1.item[idx].FriendlyName, list2.item[idx].FriendlyName) ) return 1; + idx++; + } + return 0; +} + +/* ################################################################################ */ + +int IncUpdate_NIF_List (NETWORK_INTERFACE_LIST *trg, NETWORK_INTERFACE_LIST src) { + UCHAR idx; + PNETWORK_INTERFACE nif; + int change = INCUPD_INTACT; + + for (idx = 0 ; idx < src.count ; idx++) { + nif = Find_NIF_AdapterName( *trg, src.item[idx].AdapterName ); + if ( nif ) { + if ( nif->Disabled ) nif->Disabled = 0; + if ( strcmp(NVL(nif->IPstr), NVL(src.item[idx].IPstr)) ) { + if (nif->IPstr) free(nif->IPstr); + nif->IPstr = src.item[idx].IPstr ? mir_strdup( src.item[idx].IPstr ) : NULL; + INCUPD(change, INCUPD_UPDATED); + } + if ( mir_wstrcmp(NVLW(nif->FriendlyName), NVLW(src.item[idx].FriendlyName)) ) { + if (nif->FriendlyName) free(nif->FriendlyName); + nif->FriendlyName = src.item[idx].FriendlyName ? mir_wstrdup( src.item[idx].FriendlyName ) : NULL; + INCUPD(change, INCUPD_UPDATED); + } + if ( nif->IPcount != src.item[idx].IPcount ) { + if ( nif->IPcount > src.item[idx].IPcount && nif->Bound ) { + INCUPD(change, INCUPD_CONN_LOST ); + UnboundConnections( nif->IP, src.item[idx].IP ); + } + nif->IPcount = src.item[idx].IPcount; + if (nif->IP) free(nif->IP); + if (src.item[idx].IP) { + nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) ); + memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) ); + } else { + nif->IP = NULL; + } + INCUPD(change, INCUPD_UPDATED); + } else { + if ( nif->IPcount > 0 && memcmp( nif->IP, src.item[idx].IP, nif->IPcount * sizeof(LONG) ) ) { + free(nif->IP); + nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) ); + memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) ); + INCUPD(change, INCUPD_UPDATED); + } + } + if ( nif->Bound != src.item[idx].Bound ) { + nif->Bound = src.item[idx].Bound; + INCUPD(change, INCUPD_CONN_BIND); + } + } else { + trg->count++; + trg->item = (PNETWORK_INTERFACE)mir_realloc( trg->item, trg->count * sizeof(NETWORK_INTERFACE) ); + nif = &(trg->item[trg->count - 1]); + ZeroMemory(nif, sizeof(NETWORK_INTERFACE)); + nif->AdapterName = src.item[idx].AdapterName ? mir_strdup( src.item[idx].AdapterName ) : NULL; + nif->FriendlyName = src.item[idx].FriendlyName ? mir_wstrdup( src.item[idx].FriendlyName ) : NULL; + nif->IPstr = src.item[idx].IPstr ? strdup( src.item[idx].IPstr ) : NULL; + nif->IPcount = src.item[idx].IPcount; + nif->Bound = src.item[idx].Bound; + if ( nif->IPcount > 0 ) { + nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) ); + memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) ); + } + INCUPD(change, INCUPD_UPDATED); + } + } + for (idx = 0 ; idx < trg->count ; idx++) { + if ( trg->item[idx].Disabled ) continue; + nif = Find_NIF_AdapterName( src, trg->item[idx].AdapterName ); + if ( ! nif ) { + if ( trg->item[idx].Bound ) { + INCUPD(change, INCUPD_CONN_LOST ); + UnboundConnections( trg->item[idx].IP, NULL ); + } else { + INCUPD(change, INCUPD_UPDATED ); + } + if (trg->item[idx].IPstr) free(trg->item[idx].IPstr); + if (trg->item[idx].IP) free(trg->item[idx].IP); + trg->item[idx].IPstr = NULL; + trg->item[idx].IPcount = 0; + trg->item[idx].IP = NULL; + trg->item[idx].Bound = FALSE; + trg->item[idx].Disabled = 1; + } + } + return change; +} + +/* ################################################################################ */ + +wchar_t *Print_NIF (PNETWORK_INTERFACE nif) { + ZeroMemory( tempstr, sizeof(tempstr) ); + mir_snwprintf( tempstr, L"%s:\t%s", nif->FriendlyName, nif->IPstr ? _A2T(nif->IPstr) : TranslateT("disconnected")); + return tempstr; +} + +wchar_t *Print_NIF_List (NETWORK_INTERFACE_LIST list, wchar_t *msg) { + UCHAR idx; + int pos = 0; + + ZeroMemory( tempstr, sizeof(tempstr) ); + for( idx = 0 ; idx < list.count ; idx++ ) { + pos += mir_snwprintf( tempstr+pos, _countof(tempstr), L"%s:\t%s%s%s\n", + list.item[idx].FriendlyName, + list.item[idx].Bound ? L"[u]":L"", + list.item[idx].IPstr ? _A2T(list.item[idx].IPstr) : TranslateT("disconnected"), + list.item[idx].Bound ? L"[/u]":L"" + ); + } + if ( msg ) mir_wstrcat(tempstr, msg); else tempstr[mir_wstrlen(tempstr)-1] = 0; + return tempstr; +} + +/* ################################################################################ */ + +void Free_NIF (PNETWORK_INTERFACE nif) { + if (nif->AdapterName) free(nif->AdapterName); + if (nif->FriendlyName) free(nif->FriendlyName); + if (nif->IPstr) free(nif->IPstr); + if (nif->IP) free(nif->IP); + ZeroMemory(nif, sizeof(NETWORK_INTERFACE)); +} + +void Free_NIF_List (NETWORK_INTERFACE_LIST *list) { + UCHAR idx; + + for( idx = 0 ; idx < list->count ; idx++ ) { + Free_NIF( &(list->item[idx]) ); + } + free( list->item ); + ZeroMemory(list, sizeof(NETWORK_INTERFACE_LIST)); +} + +/* ################################################################################ */ + +void Parse_Range ( PIP_RANGE range, wchar_t *str, BOOL prioritized ) { + wchar_t *ext; + unsigned long num; + + range->cmpType = CMP_SKIP; + + if ((str[0] == '!' && ! prioritized) || (str[0] != '!' && prioritized)) { + range->mask = range->net = 0L; + return; + } + if (str[0] == '!') str++; + + // ip/mask + if ( (ext = wcschr( str, '/' )) != NULL ) { + ext[0] = 0; ext++; + + // ip/bits (10.0.0.1/16) + if ( wcsspn(ext, DIGITS) == mir_wstrlen(ext) ) { + num = _wtol(ext); + if ( num >= 0 && num <= 32 && (range->net = inet_addr(_T2A(str))) != INADDR_NONE ) { + range->cmpType = CMP_MASK; + range->mask = NETORDER(num ? ~(0xFFFFFFFF >> (num)) : ~0); + range->net = range->net & range->mask; + } + } else { + + // ip/subnet (10.0.0.1/255.255.0.0) + if ( (range->net = inet_addr(_T2A(str))) != INADDR_NONE && (range->mask = inet_addr(_T2A(ext))) != INADDR_NONE ) { + for ( num = 0 ; num < 32 ; num++ ) { + if ( range->mask == NETORDER(num ? ~(0xFFFFFFFF >> (32-num)) : ~0)) { + range->cmpType = CMP_MASK; + range->net = range->net & range->mask; + break; + } + } + }} + } else { + + // ipbegin-end + if ( (ext = wcschr( str, '-' )) != NULL ) { + ext[0] = 0; ext++; + + // ipA.B.C.D1-D2 (10.0.0.1-12) + if ( wcsspn(ext, DIGITS) == mir_wstrlen(ext) ) { + num = _wtol(ext); + if ( num > 0 && num <= 255 && (range->loIP = inet_addr(_T2A(str))) != INADDR_NONE && (range->loIP >> 24) <= num ) { + range->cmpType = CMP_SPAN; + range->hiIP = ((range->loIP & 0x00FFFFFF) | (num << 24)); + range->loIP = (range->loIP); + } + } else { + + // ipstart-ipend (10.0.0.1-10.0.10.255) + if ( (range->loIP = inet_addr(_T2A(str))) != INADDR_NONE && (range->hiIP = inet_addr(_T2A(ext))) != INADDR_NONE ) { + + range->loIP = (range->loIP); + range->hiIP = (range->hiIP); + if ( range->loIP <= range->hiIP ) { + range->cmpType = CMP_SPAN; + } + } + }} else { + + // ip + if ( mir_wstrlen(str) > 0 && (range->net = inet_addr(_T2A(str))) != INADDR_NONE ) { + range->cmpType = CMP_MASK; + range->mask = 0xFFFFFFFF; + }}} + + if ( range->cmpType == CMP_SKIP ) { + range->mask = range->net = 0L; + } +} + +int Create_Range_List ( IP_RANGE_LIST *list, wchar_t *str, BOOL prioritized ) { + wchar_t *range, *rest, *tmp; + int size, idx; + + ZeroMemory(list, sizeof(IP_RANGE_LIST)); + + // get expected number of ranges + range = str; + size = mir_wstrlen( range ) > 0 ? 1 : 0; + while ( range[0] ) { if ( range[0] == ';') size++; range++; }; + + if (size == 0) return 0; + + // alloc required space + list->item = (PIP_RANGE)mir_alloc( size * sizeof( IP_RANGE ) ); + ZeroMemory( list->item, size * sizeof( IP_RANGE ) ); + + tmp = range = rest = mir_wstrdup( str ); + idx = 0; + while ( rest && rest[0] ) { + rest = wcschr( rest, ';' ); + if ( rest != NULL ) { + rest[0] = 0; + rest++; + } + Parse_Range( &(list->item[idx]), range, prioritized ); + if ( list->item[idx].cmpType != CMP_SKIP ) idx++; + range = rest; + } + + list->count = idx; + list->item = (PIP_RANGE)mir_realloc( list->item, (idx+1) * sizeof( IP_RANGE ) ); + + ZeroMemory( &(list->item[idx]), sizeof( IP_RANGE ) ); + list->item[idx].cmpType = CMP_END; + + free( tmp ); + + return 0; +} + +int Match_Range_List (IP_RANGE_LIST range, NETWORK_INTERFACE_LIST nif) { + PIP_RANGE rng; + UCHAR idx; + ULONG *ip; + + if ( range.count == 0 || nif.count == 0 ) return 0; + + rng = range.item; + while( rng->cmpType != CMP_END ) { + + switch ( rng->cmpType ) { + case CMP_SKIP: + break; + + case CMP_MASK: + for ( idx = 0 ; idx < nif.count ; idx++ ) { + ip = (ULONG *)nif.item[idx].IP; + while (ip && *ip) { + if ( (ULONG)(*ip & rng->mask) == rng->net ) return 1; + ip++; + } + } + break; + + case CMP_SPAN: + for ( idx = 0 ; idx < nif.count ; idx++ ) { + ip = (ULONG *)nif.item[idx].IP; + while (ip && *ip) { + if ( (NETORDER(rng->loIP) <= NETORDER(*ip)) && (NETORDER(*ip) <= NETORDER(rng->hiIP)) ) return 1; + ip++; + } + } + break; + } + rng++; + } + + return 0; +} + +void Free_Range_List (IP_RANGE_LIST *list) { + if ( list->item ) free( list->item ); + ZeroMemory(list, sizeof(IP_RANGE_LIST)); +} + + +int ManageConnections (WPARAM wParam,LPARAM lParam) { + NETLIBCONNECTIONEVENTINFO *info = (NETLIBCONNECTIONEVENTINFO *)wParam; + int found; + UCHAR i; + + EnterCriticalSection(&csConnection_List); + found = -1; + for (i=0 ; i<Connection_List.count ; i++) { + if ( Connection_List.item[i].IP == info->local.sin_addr.s_addr && Connection_List.item[i].Port == info->local.sin_port ) { + found = i; + break; + } + } + if ( (found >= 0 && info->connected) || (found == -1 && !info->connected)) { + LeaveCriticalSection(&csConnection_List); + return 0; + } + if ( found >= 0 ) { + Connection_List.count--; + for( i=found ; i<Connection_List.count ; i++ ) memcpy( &(Connection_List.item[i]), &(Connection_List.item[i+1]), sizeof(ACTIVE_CONNECTION) ); + } else { + if ( Connection_List.count >= Connection_List._alloc ) { + Connection_List._alloc += 10; + Connection_List.item = (PACTIVE_CONNECTION)mir_realloc( Connection_List.item, Connection_List._alloc * sizeof(ACTIVE_CONNECTION) ); + } + Connection_List.item[Connection_List.count].IP = info->local.sin_addr.s_addr; + Connection_List.item[Connection_List.count].Port = info->local.sin_port; + Connection_List.count++; + } + LeaveCriticalSection(&csConnection_List); + + SetEvent( hEventRebound ); + + return 0; +} + +void UnboundConnections ( LONG *OldIP, LONG *NewIP ) { + UCHAR i, j; + LONG *IP; + + while ( OldIP != NULL && *OldIP != 0 ) { + IP = NewIP; + while ( IP != NULL && *IP != 0 && *IP != *OldIP ) IP++; + if ( IP == NULL || *IP != *OldIP ) { + EnterCriticalSection(&csConnection_List); + i = 0; + while ( i < Connection_List.count ) { + if (Connection_List.item[i].IP == (ULONG)*OldIP) { + Connection_List.count--; + for( j=i ; j<Connection_List.count ; j++ ) memcpy( &(Connection_List.item[j]), &(Connection_List.item[j+1]), sizeof(ACTIVE_CONNECTION) ); + } else { + i++; + } + } + LeaveCriticalSection(&csConnection_List); + } + OldIP++; + } +} diff --git a/plugins/ProxySwitch/src/main.cpp b/plugins/ProxySwitch/src/main.cpp new file mode 100644 index 0000000000..5266e901aa --- /dev/null +++ b/plugins/ProxySwitch/src/main.cpp @@ -0,0 +1,367 @@ +/* +proxySwitch + +The plugin watches IP address changes, reports them via popups and adjusts +the proxy settings of Miranda and Internet Explorer accordingly. +*/ + +#include "stdafx.h" + +CMPlugin g_plugin; + +PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + // {4DF0C267-6EFB-4410-B651-385F87158509} + { 0x4df0c267, 0x6efb, 0x4410,{ 0xb6, 0x51, 0x38, 0x5f, 0x87, 0x15, 0x85, 0x9 } } +}; + +CMPlugin::CMPlugin() : + PLUGIN<CMPlugin>(MODULENAME, pluginInfoEx) +{} + +HGENMENU hEnableDisablePopupMenu = 0; + +NETWORK_INTERFACE_LIST NIF_List; +CRITICAL_SECTION csNIF_List; +ACTIVE_CONNECTION_LIST Connection_List; +CRITICAL_SECTION csConnection_List; +HANDLE hEventRebound = NULL; + +wchar_t opt_useProxy[MAX_IPLIST_LENGTH]; +wchar_t opt_noProxy[MAX_IPLIST_LENGTH]; +wchar_t opt_hideIntf[MAX_IPLIST_LENGTH]; +UINT opt_defaultColors; +UINT opt_popups; +UINT opt_showProxyState; +UINT opt_miranda; +UINT opt_ie; +UINT opt_firefox; +UINT opt_showMyIP; +UINT opt_showProxyIP; +UINT opt_alwayReconnect; +UINT opt_startup; +UINT opt_not_restarted; +COLORREF opt_bgColor; +COLORREF opt_txtColor; + +UINT opt_popupPluginInstalled; + +static HANDLE hEventConnect = NULL; +static HANDLE hEventDisconnect = NULL; +static HANDLE hSvcCopyClip0 = NULL; +static HANDLE hSvcCopyClip1 = NULL; +static HANDLE hSvcCopyClip2 = NULL; +static HANDLE hSvcCopyClip3 = NULL; +static HANDLE hSvcCopyClip4 = NULL; +static HANDLE hSvcCopyClip5 = NULL; +static HANDLE hSvcPopupSwitch = NULL; +static HANDLE hSvcProxyDisable = NULL; +static HANDLE hSvcProxyEnable = NULL; +static HANDLE hSvcShowMyIP = NULL; + +/* ################################################################################ */ + +static int ShowMyIPAddrs(WPARAM wParam, LPARAM lParam) +{ + PopupMyIPAddrs(NULL); + return 0; +} + +void PopupMyIPAddrs(wchar_t *msg) +{ + POPUPDATAW ppd; + NETWORK_INTERFACE_LIST list; + + ZeroMemory(&ppd, sizeof(ppd)); + + if (Create_NIF_List_Ex(&list) >= 0) { + + wcsncpy_s(ppd.lpwzText, Print_NIF_List(list, msg), _TRUNCATE); + + if (opt_popupPluginInstalled) { + LoadSettings(); + ppd.lchIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_PROXY)); + wcsncpy_s(ppd.lpwzContactName, TranslateT("Current IP address"), _TRUNCATE); + ppd.colorBack = opt_defaultColors ? 0 : opt_bgColor; + ppd.colorText = opt_defaultColors ? 0 : opt_txtColor; + CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); + } + else { + MessageBox(NULL, ppd.lpwzText, _A2T(MODULENAME), MB_OK | MB_ICONINFORMATION); + } + + Free_NIF_List(&list); + } +} + +static int ProxyEnable(WPARAM wParam, LPARAM lParam) +{ + Set_IE_Proxy_Status(1); + Set_Miranda_Proxy_Status(1); + Set_Firefox_Proxy_Status(1); + return 0; +} + +static int ProxyDisable(WPARAM wParam, LPARAM lParam) +{ + Set_IE_Proxy_Status(0); + Set_Miranda_Proxy_Status(0); + Set_Firefox_Proxy_Status(0); + return 0; +} + +/* ################################################################################ */ + +void CopyIP2Clipboard(UCHAR idx) +{ + EnterCriticalSection(&csNIF_List); + if (NIF_List.item[idx].IPcount == 0) { + LeaveCriticalSection(&csNIF_List); + return; + } + if (!OpenClipboard(NULL)) { + LeaveCriticalSection(&csNIF_List); + return; + } + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, (HANDLE)NIF_List.item[idx].IPstr); + CloseClipboard(); + LeaveCriticalSection(&csNIF_List); +} + +static int CopyIP2Clipboard0(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(0); return 0; } +static int CopyIP2Clipboard1(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(1); return 0; } +static int CopyIP2Clipboard2(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(2); return 0; } +static int CopyIP2Clipboard3(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(3); return 0; } +static int CopyIP2Clipboard4(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(4); return 0; } +static int CopyIP2Clipboard5(WPARAM wParam, LPARAM lParam) { CopyIP2Clipboard(5); return 0; } + +void UpdateInterfacesMenu(void) +{ + UCHAR idx; + CMenuItem mi(g_plugin); + char svc[60]; + + if (!opt_showProxyIP && !opt_not_restarted) return; + + EnterCriticalSection(&csNIF_List); + for (idx = 0; idx < NIF_List.count; idx++) { + if (NIF_List.item[idx].MenuItem) { + // set new name and flags + //mi.name.w = Print_NIF(&(NIF_List.item[idx])); + //if (NIF_List.item[idx].IPcount == 0) mi.flags |= CMIF_GRAYED; + //mi.flags |= CMIM_FLAGS | CMIM_NAME; + // update menu item + Menu_ModifyItem(NIF_List.item[idx].MenuItem, Print_NIF(&(NIF_List.item[idx])), INVALID_HANDLE_VALUE, CMIF_GRAYED); + //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)NIF_List.item[idx].MenuItem, (LPARAM)&mi); + } + else { + // add a new menu item + sprintf(svc, "%s%d", MS_PROXYSWITCH_COPYIP2CLIP, idx); + mi.position = 0xC00000; + mi.flags = CMIF_UNICODE; + mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Proxy Settings && Interfaces"), 0xC0000000); + Menu_ConfigureItem(mi.root, MCI_OPT_UID, "68AB766F-09F1-4C4C-9AE1-4135617741C9"); + + SET_UID(mi, 0x8295e40d, 0xa262, 0x434b, 0xa4, 0xb3, 0x57, 0x6b, 0xe0, 0xfc, 0x8f, 0x68); + mi.name.w = Print_NIF(&(NIF_List.item[idx])); + mi.pszService = svc; + //mi.pszPopupName = Translate("Proxy Settings && Interfaces"); + //mi.popupPosition = 0xC0000000; + NIF_List.item[idx].MenuItem = Menu_AddMainMenuItem(&mi); + // menu cannot be grayed when creating, so we have to do it after that + if (NIF_List.item[idx].IPcount == 0) { + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + //mi.flags |= CMIF_GRAYED; + Menu_ModifyItem(NIF_List.item[idx].MenuItem, Print_NIF(&(NIF_List.item[idx])), INVALID_HANDLE_VALUE, CMIF_GRAYED); + //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)NIF_List.item[idx].MenuItem, (LPARAM)&mi); + } + // create and register service for this menu item + switch (idx) { + case 0: hSvcCopyClip0 = CreateServiceFunction(svc, CopyIP2Clipboard0); break; + case 1: hSvcCopyClip1 = CreateServiceFunction(svc, CopyIP2Clipboard1); break; + case 2: hSvcCopyClip2 = CreateServiceFunction(svc, CopyIP2Clipboard2); break; + case 3: hSvcCopyClip3 = CreateServiceFunction(svc, CopyIP2Clipboard3); break; + case 4: hSvcCopyClip4 = CreateServiceFunction(svc, CopyIP2Clipboard4); break; + case 5: hSvcCopyClip5 = CreateServiceFunction(svc, CopyIP2Clipboard5); break; + } + } + } + LeaveCriticalSection(&csNIF_List); +} + +/* ################################################################################ */ + +void UpdatePopupMenu(BOOL State) +{ + CMenuItem mi(g_plugin); + + if (!hEnableDisablePopupMenu) return; + + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + + // popup is now disabled + if (State == FALSE) { + mi.name.w = LPGENW("Enable &IP change notification"); + mi.hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_NOTIF_0)); + + // popup is now enabled + } + else { + mi.name.w = LPGENW("Disable &IP change notification"); + mi.hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_NOTIF_1)); + } + //mi.flags = CMIM_ICON | CMIM_NAME; + + // update menu item + Menu_ModifyItem(hEnableDisablePopupMenu, mi.name.w); + //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hEnableDisablePopupMenu, (LPARAM)&mi); +} + +static int PopupSwitch(WPARAM wParam, LPARAM lParam) +{ + opt_popups = !opt_popups; + UpdatePopupMenu(opt_popups); + SaveSettings(); + return 0; +} + +/* ################################################################################ */ + +int CMPlugin::Load() +{ + char proxy = -1; + IP_RANGE_LIST range; + + opt_startup = FALSE; + opt_not_restarted = FALSE; + + LoadSettings(); + + InitializeCriticalSection(&csConnection_List); + InitializeCriticalSection(&csNIF_List); + + ZeroMemory(&Connection_List, sizeof(Connection_List)); + Create_NIF_List_Ex(&NIF_List); + + if (opt_ie || opt_miranda || opt_firefox) { + Create_Range_List(&range, opt_useProxy, TRUE); + if (Match_Range_List(range, NIF_List)) proxy = 1; + Free_Range_List(&range); + if (proxy == -1) { + Create_Range_List(&range, opt_noProxy, FALSE); + if (Match_Range_List(range, NIF_List)) proxy = 0; + Free_Range_List(&range); + } + if (proxy == -1) { + Create_Range_List(&range, opt_useProxy, FALSE); + if (Match_Range_List(range, NIF_List)) proxy = 1; + Free_Range_List(&range); + } + if (proxy != -1) { + if (opt_miranda && Get_Miranda_Proxy_Status() != proxy) Set_Miranda_Proxy_Status(proxy); + if (opt_ie && Get_IE_Proxy_Status() != proxy) Set_IE_Proxy_Status(proxy); + if (opt_firefox && Get_Firefox_Proxy_Status() != proxy) Set_Firefox_Proxy_Status(proxy); + } + } + + HookEvent(ME_OPT_INITIALISE, OptInit); + HookEvent(ME_SYSTEM_MODULESLOADED, Init); + HookEvent(ME_NETLIB_EVENT_CONNECTED, ManageConnections); + HookEvent(ME_NETLIB_EVENT_DISCONNECTED, ManageConnections); + + return 0; +} + +int Init(WPARAM wParam, LPARAM lParam) +{ + CMenuItem mi(g_plugin); + + opt_popupPluginInstalled = ServiceExists(MS_POPUP_ADDPOPUP); + + + hEventRebound = CreateEvent(NULL, TRUE, FALSE, NULL); + mir_forkthread(IP_WatchDog, 0); + + if (opt_showMyIP) { + hSvcShowMyIP = CreateServiceFunction(MS_PROXYSWITCH_SHOWMYIPADDRS, ShowMyIPAddrs); + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + SET_UID(mi, 0x53b0835b, 0x7162, 0x4272, 0x83, 0x3b, 0x3f, 0x60, 0x9e, 0xe, 0x76, 0x4a); + mi.position = 0xC0000000; + mi.flags = CMIF_UNICODE; + mi.hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_LOGO)); + mi.name.w = LPGENW("Show my &IP Addresses"); + mi.pszService = MS_PROXYSWITCH_SHOWMYIPADDRS; + Menu_AddMainMenuItem(&mi); + } + + if (opt_showProxyIP) { + + hSvcProxyDisable = CreateServiceFunction(MS_PROXYSWITCH_PROXYDISABLE, ProxyDisable); + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + SET_UID(mi, 0xf93289a9, 0x3bad, 0x424b, 0xb2, 0x72, 0x14, 0xa7, 0x45, 0xa5, 0x8, 0x9c); + mi.position = 1; + mi.name.w = LPGENW("Disable Proxy"); + mi.pszService = MS_PROXYSWITCH_PROXYDISABLE; + mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Proxy Settings && Interfaces"), 0xC0000000); + Menu_ConfigureItem(mi.root, MCI_OPT_UID, "A9684E9E-E621-4962-986F-576897928D27"); + //mi.pszPopupName = Translate("Proxy Settings && Interfaces"); + //mi.popupPosition = 0xC0000000; + Menu_AddMainMenuItem(&mi); + + hSvcProxyEnable = CreateServiceFunction(MS_PROXYSWITCH_PROXYENABLE, ProxyEnable); + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + mi.position = 1; + mi.name.w = LPGENW("Enable Proxy"); + mi.pszService = MS_PROXYSWITCH_PROXYENABLE; + mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Proxy Settings && Interfaces"), 0xC0000000); + Menu_ConfigureItem(mi.root, MCI_OPT_UID, "B37E5BBE-19CF-4C78-AE53-A0DB11656C36"); + //mi.pszPopupName = Translate("Proxy Settings && Interfaces"); + //mi.popupPosition = 0xC0000000; + Menu_AddMainMenuItem(&mi); + + UpdateInterfacesMenu(); + } + + if (opt_popupPluginInstalled) { + hSvcPopupSwitch = CreateServiceFunction(MS_PROXYSWITCH_POPUPSWITCH, PopupSwitch); + //ZeroMemory(&mi, sizeof(mi)); + //mi.cbSize = sizeof(mi); + mi.name.w = LPGENW("IP Change Notification"); + mi.hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_LOGO)); + mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("PopUps"), 0xC0000000); + Menu_ConfigureItem(mi.root, MCI_OPT_UID, "185AC334-E90E-46C6-83A2-D4E36CB257D9"); + //mi.pszPopupName = Translate("PopUps"); + mi.pszService = MS_PROXYSWITCH_POPUPSWITCH; + hEnableDisablePopupMenu = Menu_AddMainMenuItem(&mi); + + UpdatePopupMenu(opt_popups); + } + + return 0; +} + +int CMPlugin::Unload() +{ + if (hEventRebound) + CloseHandle(hEventRebound); + EnterCriticalSection(&csNIF_List); + Free_NIF_List(&NIF_List); + LeaveCriticalSection(&csNIF_List); + DeleteCriticalSection(&csNIF_List); + DeleteCriticalSection(&csConnection_List); + return 0; +} diff --git a/plugins/ProxySwitch/src/opt.cpp b/plugins/ProxySwitch/src/opt.cpp new file mode 100644 index 0000000000..44273f705e --- /dev/null +++ b/plugins/ProxySwitch/src/opt.cpp @@ -0,0 +1,191 @@ +/* +proxySwitch + +The plugin watches IP address changes, reports them via popups and adjusts +the proxy settings of Miranda and Internet Explorer accordingly. +*/ + +#include "stdafx.h" + +int help_shown; + +void ShowHelp( HWND hdlg, int showhide_help ) { + int showhide_others = showhide_help == SW_SHOW ? SW_HIDE : SW_SHOW; + help_shown = showhide_help; + + ShowWindow(GetDlgItem(hdlg, IDC_HELP_1), showhide_help); + ShowWindow(GetDlgItem(hdlg, IDC_HELP_2), showhide_help); + ShowWindow(GetDlgItem(hdlg, IDC_HELP_3), showhide_help); + + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_MIRANDA), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_IE), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_FIREFOX), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_PROXYIPMENU), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_SHOWMYIPMENU), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_DEFAULTCOLORS), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_SHOWPROXYSTATUS), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_ALWAY_RECONNECT), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_CHECK_POPUPS), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_BGCOLOR), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_TEXTCOLOR), showhide_others); + ShowWindow(GetDlgItem(hdlg, IDC_EDIT_HIDEINTF), showhide_others); +} + + +BOOL CALLBACK OptionsProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam) { + + switch(msg) { + + case WM_INITDIALOG: + opt_startup = TRUE; + LoadSettings(); + ShowHelp( hdlg, SW_HIDE ); + SetDlgItemText(hdlg, IDC_EDIT_USEPROXY, opt_useProxy); + SetDlgItemText(hdlg, IDC_EDIT_NOPROXY, opt_noProxy); + CheckDlgButton(hdlg, IDC_CHECK_MIRANDA, opt_miranda ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_IE, opt_ie ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_FIREFOX, opt_firefox ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_SHOWMYIPMENU, opt_showMyIP ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_PROXYIPMENU, opt_showProxyIP ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_ALWAY_RECONNECT, opt_alwayReconnect ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemText(hdlg, IDC_EDIT_HIDEINTF, opt_hideIntf); + SendDlgItemMessage(hdlg,IDC_BGCOLOR,CPM_SETCOLOUR,0,opt_bgColor); + SendDlgItemMessage(hdlg,IDC_TEXTCOLOR,CPM_SETCOLOUR,0,opt_txtColor); + CheckDlgButton(hdlg, IDC_CHECK_POPUPS, opt_popups ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_DEFAULTCOLORS, opt_defaultColors ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hdlg, IDC_CHECK_SHOWPROXYSTATUS, opt_showProxyState ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_FIREFOX), Firefox_Installed()); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_POPUPS), opt_popupPluginInstalled); + EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOR), opt_popupPluginInstalled && opt_popups && !opt_defaultColors); + EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOR), opt_popupPluginInstalled && opt_popups && !opt_defaultColors); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_DEFAULTCOLORS), opt_popupPluginInstalled && opt_popups); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_SHOWPROXYSTATUS), opt_popupPluginInstalled && opt_popups); + ShowWindow(GetDlgItem(hdlg, IDC_RESTARTREQUIRED), opt_not_restarted ? SW_SHOW : SW_HIDE); + TranslateDialogDefault(hdlg); + opt_startup = FALSE; + return 1; + + case WM_NOTIFY: + switch (((LPNMHDR)lparam)->code) { + case PSN_APPLY: + opt_not_restarted = opt_not_restarted || IsDlgButtonChecked(hdlg,IDC_CHECK_PROXYIPMENU) != opt_showProxyIP || IsDlgButtonChecked(hdlg,IDC_CHECK_SHOWMYIPMENU) != opt_showMyIP; + ShowWindow(GetDlgItem(hdlg, IDC_RESTARTREQUIRED), opt_not_restarted ? SW_SHOW : SW_HIDE); + GetDlgItemText(hdlg,IDC_EDIT_NOPROXY,opt_noProxy,MAX_IPLIST_LENGTH); + GetDlgItemText(hdlg,IDC_EDIT_USEPROXY,opt_useProxy,MAX_IPLIST_LENGTH); + GetDlgItemText(hdlg,IDC_EDIT_HIDEINTF,opt_hideIntf,MAX_IPLIST_LENGTH); + opt_miranda = IsDlgButtonChecked(hdlg,IDC_CHECK_MIRANDA); + opt_ie = IsDlgButtonChecked(hdlg,IDC_CHECK_IE); + opt_firefox = IsDlgButtonChecked(hdlg,IDC_CHECK_FIREFOX); + opt_showMyIP = IsDlgButtonChecked(hdlg,IDC_CHECK_SHOWMYIPMENU); + opt_showProxyIP = IsDlgButtonChecked(hdlg,IDC_CHECK_PROXYIPMENU); + opt_alwayReconnect = IsDlgButtonChecked(hdlg,IDC_CHECK_ALWAY_RECONNECT); + opt_popups = IsDlgButtonChecked(hdlg,IDC_CHECK_POPUPS); + opt_defaultColors = IsDlgButtonChecked(hdlg,IDC_CHECK_DEFAULTCOLORS); + opt_showProxyState = IsDlgButtonChecked(hdlg,IDC_CHECK_SHOWPROXYSTATUS); + opt_bgColor = SendDlgItemMessage(hdlg,IDC_BGCOLOR,CPM_GETCOLOUR,0,0); + opt_txtColor = SendDlgItemMessage(hdlg,IDC_TEXTCOLOR,CPM_GETCOLOUR,0,0); + SaveSettings(); + UpdatePopupMenu(opt_popups); + return 1; + } + break; + + case WM_COMMAND: + if (opt_startup) return 0; + if (HIWORD(wparam)==BN_CLICKED && GetFocus()==(HWND)lparam && LOWORD(wparam)!=IDC_BTN_HELP) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0); + switch(LOWORD(wparam)) { + + case IDC_BTN_HELP: + ShowHelp( hdlg, help_shown == SW_SHOW ? SW_HIDE : SW_SHOW ); + break; + + case IDC_EDIT_USEPROXY: + case IDC_EDIT_NOPROXY: + case IDC_EDIT_HIDEINTF: + if (HIWORD(wparam) == EN_CHANGE && (HWND)lparam == GetFocus()) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0); + break; + + case IDC_BGCOLOR: + case IDC_TEXTCOLOR: + if (HIWORD(wparam) == CPN_COLOURCHANGED) SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); + break; + + case IDC_CHECK_PROXYIPMENU: + case IDC_CHECK_SHOWMYIPMENU: + ShowWindow(GetDlgItem(hdlg, IDC_RESTARTREQUIRED), opt_not_restarted || (IsDlgButtonChecked(hdlg,IDC_CHECK_PROXYIPMENU) != opt_showProxyIP || IsDlgButtonChecked(hdlg,IDC_CHECK_SHOWMYIPMENU) != opt_showMyIP) ? SW_SHOW : SW_HIDE ); + break; + + case IDC_CHECK_DEFAULTCOLORS: + case IDC_CHECK_POPUPS: + if ( ! opt_popupPluginInstalled ) break; + EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOR), IsDlgButtonChecked(hdlg,IDC_CHECK_POPUPS) && !IsDlgButtonChecked(hdlg,IDC_CHECK_DEFAULTCOLORS)); + EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOR), IsDlgButtonChecked(hdlg,IDC_CHECK_POPUPS) && !IsDlgButtonChecked(hdlg,IDC_CHECK_DEFAULTCOLORS)); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_DEFAULTCOLORS), IsDlgButtonChecked(hdlg,IDC_CHECK_POPUPS)); + EnableWindow(GetDlgItem(hdlg, IDC_CHECK_SHOWPROXYSTATUS), IsDlgButtonChecked(hdlg,IDC_CHECK_POPUPS)); + SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); + break; + } + break; + + case WM_CLOSE: + EndDialog(hdlg,0); + break; + } + return 0; +} + + +int OptInit(WPARAM wParam,LPARAM lParam) { + OPTIONSDIALOGPAGE odp = { 0 }; + + //ZeroMemory(&odp,sizeof(odp)); + //odp.cbSize=sizeof(odp); + odp.position=95600; + odp.hInstance= g_plugin.getInst(); + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pfnDlgProc=OptionsProc; + odp.szGroup.w=LPGENW("Network"); + odp.szTitle.w= LPGENW("proxySwitch"); + odp.flags=ODPF_BOLDGROUPS | ODPF_UNICODE; + g_plugin.addOptions(wParam, &odp); + + return 0; +} + +void LoadSettings(void) { + DBVARIANT dbv; + if (db_get(NULL, MODULENAME,"UseProxyIPNets",&dbv)) lstrcpy(opt_useProxy, L""); else lstrcpy(opt_useProxy, dbv.pwszVal); + db_free(&dbv); + if (db_get(NULL, MODULENAME,"NoProxyIPNets",&dbv)) lstrcpy(opt_noProxy, L""); else lstrcpy(opt_noProxy, dbv.pwszVal); + db_free(&dbv); + if (db_get(NULL, MODULENAME,"HideInterfaces",&dbv)) lstrcpy(opt_hideIntf, L""); else lstrcpy(opt_hideIntf, dbv.pwszVal); + db_free(&dbv); + opt_miranda = db_get_b(NULL, MODULENAME,"ManageMirandaProxy",TRUE); + opt_ie = db_get_b(NULL,MODULENAME,"ManageIEProxy",FALSE); + opt_firefox = db_get_b(NULL,MODULENAME,"ManageFirefoxProxy",FALSE) && Firefox_Installed(); + opt_alwayReconnect = db_get_b(NULL,MODULENAME,"AlwaysReconnect",FALSE); + opt_showMyIP = db_get_b(NULL,MODULENAME,"ShowMyIP",TRUE); + opt_showProxyIP = db_get_b(NULL,MODULENAME,"ShowProxyIP",TRUE); + opt_popups = db_get_b(NULL,MODULENAME,"PopupEnabled",TRUE); + opt_defaultColors = db_get_b(NULL,MODULENAME,"PopupDefaultColors",TRUE); + opt_showProxyState = db_get_b(NULL,MODULENAME,"ShowProxyStatus",TRUE); + opt_bgColor = db_get_dw(NULL,MODULENAME,"PopupBgColor",GetSysColor(COLOR_BTNFACE)); + opt_txtColor = db_get_dw(NULL,MODULENAME,"PopupTxtColor",GetSysColor(COLOR_WINDOWTEXT)); +} + +void SaveSettings(void) { + db_set_ws(NULL, MODULENAME, "UseProxyIPNets", opt_useProxy); + db_set_ws(NULL, MODULENAME, "NoProxyIPNets", opt_noProxy); + db_set_ws(NULL, MODULENAME, "HideInterfaces", opt_hideIntf); + db_set_b(NULL, MODULENAME, "ManageMirandaProxy", (BYTE)opt_miranda ); + db_set_b(NULL, MODULENAME, "ManageIEProxy", (BYTE)opt_ie ); + db_set_b(NULL, MODULENAME, "ManageFirefoxProxy", (BYTE)opt_firefox ); + db_set_b(NULL, MODULENAME, "AlwaysReconnect", (BYTE)opt_alwayReconnect); + db_set_b(NULL, MODULENAME, "ShowMyIP", (BYTE)opt_showMyIP ); + db_set_b(NULL, MODULENAME, "ShowProxyIP", (BYTE)opt_showProxyIP ); + db_set_b(NULL, MODULENAME, "PopupEnabled", (BYTE)opt_popups ); + db_set_b(NULL, MODULENAME, "PopupDefaultColors", (BYTE)opt_defaultColors ); + db_set_b(NULL, MODULENAME, "ShowProxyStatus", (BYTE)opt_showProxyState); + db_set_dw(NULL, MODULENAME, "PopupBgColor", (DWORD)opt_bgColor ); + db_set_dw(NULL, MODULENAME, "PopupTxtColor", (DWORD)opt_txtColor ); +} diff --git a/plugins/ProxySwitch/src/proxy.cpp b/plugins/ProxySwitch/src/proxy.cpp new file mode 100644 index 0000000000..5e5ad46e65 --- /dev/null +++ b/plugins/ProxySwitch/src/proxy.cpp @@ -0,0 +1,304 @@ +/* +proxySwitch + +The plugin watches IP address changes, reports them via popups and adjusts +the proxy settings of Miranda and Internet Explorer accordingly. +*/ + +#include "stdafx.h" + +/* ################################################################################ */ + +int Enum_Settings(const char *szSetting,LPARAM lParam) { + PPROXY_SETTINGS ps = (PPROXY_SETTINGS)lParam; + + if ( strcmp(szSetting, "NLUseProxy") != 0 && stricmp(szSetting, "useproxy") != 0 ) return 0; + + if ( ps->count >= ps->_alloc ) { + ps->_alloc += 10; + ps->item = (PPROXY_SETTING)mir_realloc( ps->item, ps->_alloc * sizeof(PROXY_SETTING) ); + ZeroMemory( &(ps->item[ps->count]), 10 * sizeof(PROXY_SETTING) ); + } + strncpy( ps->item[ps->count].ModuleName, ps->_current_module, MAXLABELLENGTH-1 ); + strncpy( ps->item[ps->count].SettingName, szSetting, MAXLABELLENGTH-1 ); + ps->count++; + + return 0; +} + +int Enum_Modules(const char *szModuleName,DWORD ofsModuleName,LPARAM lParam) { + //DBCONTACTENUMSETTINGS e; + MCONTACT hContact = NULL; + + ((PPROXY_SETTINGS)lParam)->_current_module = szModuleName; + + //e.pfnEnumProc = Enum_Settings; + //e.lParam = lParam; + //e.szModule = szModuleName; + db_enum_settings(hContact, (DBSETTINGENUMPROC)Enum_Settings, szModuleName, (void*)lParam); + //CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact,(LPARAM)&e); + + return 0; +} + +/* ################################################################################ */ + +void Create_Proxy_Settings_List ( PPROXY_SETTINGS ps ) { + + ZeroMemory( ps, sizeof(PROXY_SETTINGS) ); + ps->_alloc = 10; + ps->item = (PPROXY_SETTING)mir_alloc( ps->_alloc * sizeof(PROXY_SETTING) ); + ZeroMemory( ps->item, ps->_alloc * sizeof(PROXY_SETTING) ); + + db_enum_modules((DBMODULEENUMPROC)Enum_Modules); + //CallService(MS_DB_MODULES_ENUM, (WPARAM)ps, (LPARAM)Enum_Modules ); + + ps->_alloc = ps->count+1; + ps->item = (PPROXY_SETTING)mir_realloc( ps->item, ps->_alloc * sizeof(PROXY_SETTING) ); + ZeroMemory( &(ps->item[ps->count]), sizeof(PROXY_SETTING)); + ps->_current_module = NULL; +} + +/* ################################################################################ */ + +void Free_Proxy_Settings_List( PPROXY_SETTINGS ps ) { + if ( ps->item ) free( ps->item ); + ZeroMemory( ps, sizeof(PROXY_SETTINGS) ); +} + +/* ################################################################################ */ + +char Get_Miranda_Proxy_Status (void) { + PROXY_SETTINGS ps; + int i, p; + char proxy; + proxy = PROXY_NO_CONFIG; + + Create_Proxy_Settings_List( &ps ); + for ( i = 0 ; i < ps.count ; i++ ) { + p = db_get_b(NULL,ps.item[i].ModuleName,ps.item[i].SettingName,FALSE); + if (proxy == PROXY_NO_CONFIG) { proxy = p; continue; } + if (proxy != p) { proxy = PROXY_MIXED; break; } + } + Free_Proxy_Settings_List( &ps ); + return proxy; +} + +/* ################################################################################ */ + +void Set_Miranda_Proxy_Status (char proxy) { + PROXY_SETTINGS ps; + NETLIBUSERSETTINGS nlus; + int i; + + if ( proxy < 0 ) return; + Create_Proxy_Settings_List( &ps ); + for ( i = 0 ; i < ps.count ; i++ ) { + if ( ps.item[i].SettingName[0] != 0 ) db_set_b(NULL,ps.item[i].ModuleName,ps.item[i].SettingName,proxy); + ZeroMemory( &nlus, sizeof(nlus) ); + nlus.cbSize = sizeof(nlus); + if (Netlib_GetUserSettingsByName(ps.item[i].ModuleName, &nlus) ) { + nlus.useProxy = proxy; + nlus.szProxyAuthPassword = NEWSTR_ALLOCA(nlus.szProxyAuthPassword); + nlus.szProxyAuthUser = NEWSTR_ALLOCA(nlus.szProxyAuthUser); + nlus.szProxyServer = NEWSTR_ALLOCA(nlus.szProxyServer); + nlus.szIncomingPorts = NEWSTR_ALLOCA(nlus.szIncomingPorts); + nlus.szOutgoingPorts = NEWSTR_ALLOCA(nlus.szOutgoingPorts); + Netlib_SetUserSettingsByName(ps.item[i].ModuleName, &nlus); + } + } + Free_Proxy_Settings_List( &ps ); +} + +/* ################################################################################ */ + +char Get_IE_Proxy_Status (void) { + INTERNET_PER_CONN_OPTION_LIST list; + INTERNET_PER_CONN_OPTION option[1]; + unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); + + option[0].dwOption = INTERNET_PER_CONN_FLAGS; + + list.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); + list.pszConnection = NULL; + list.dwOptionCount = 1; + list.dwOptionError = 0; + list.pOptions = option; + + if(!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &nSize)) return -1; + + return + option[0].Value.dwValue & PROXY_TYPE_PROXY ? 1 : 0; +} + +/* ################################################################################ */ + +void Set_IE_Proxy_Status (char proxy) { + INTERNET_PER_CONN_OPTION_LIST list; + INTERNET_PER_CONN_OPTION option[1]; + unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); + + if ( proxy < 0 ) return; + option[0].dwOption = INTERNET_PER_CONN_FLAGS; + option[0].Value.dwValue = proxy ? PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT : PROXY_TYPE_DIRECT; + + list.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); + list.pszConnection = NULL; + list.dwOptionCount = 1; + list.dwOptionError = 0; + list.pOptions = option; + + if(!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, nSize)) return; + + InternetQueryOption( NULL, INTERNET_OPTION_SETTINGS_CHANGED , NULL, 0 ); + InternetQueryOption( NULL, INTERNET_OPTION_REFRESH , NULL, 0 ); +} + +/* ################################################################################ */ + +char Get_Firefox_Proxy_Status (void) { + wchar_t path[MAX_PATH]; + wchar_t prefs[MAX_PATH]; + char line[500]; + FILE *fP; + struct _stat info; + struct _wfinddata_t dir; + long hFile; + char *setting; + int p, proxy; + + ZeroMemory(&info, sizeof(info)); + proxy = PROXY_NO_CONFIG; + if ( ! SHGetSpecialFolderPath(NULL, path, CSIDL_APPDATA, 0) ) return proxy; + mir_wstrcat(path, L"\\Mozilla\\Firefox\\Profiles\\*"); + if( (hFile = _wfindfirst( path, &dir )) != -1L ) { + do { + if (! (dir.attrib & _A_SUBDIR) || dir.name[0] == '.') continue; + mir_wstrcpy(prefs, path); prefs[mir_wstrlen(prefs)-1] = 0; + mir_wstrcat(prefs, dir.name); + mir_wstrcat(prefs, L"\\prefs.js"); + if ( (fP = _wfopen(prefs, L"r")) != NULL ) { + p = 0; + while ( fgets(line, 500, fP) ) { + if ( (setting = strstr( line, "user_pref(\"network.proxy.type\",")) != NULL ) { + setting += 31; + p = atoi(setting); + p = p == 3 ? 0 : p > 0; + break; + } + } + fclose(fP); + proxy = proxy == -2 ? p : (proxy == p ? p : -1); + } + } while (_wfindnext( hFile, &dir ) == 0); + _findclose( hFile ); + } + return proxy; +} + +/* ################################################################################ */ + +void Set_Firefox_Proxy_Status (char proxy) { + wchar_t path[MAX_PATH]; + wchar_t prefsR[MAX_PATH]; + wchar_t prefsW[MAX_PATH]; + char line[500]; + FILE *fR, *fW; + struct _stat info; + struct _wfinddata_t dir; + long hFile; + char done; + + ZeroMemory(&info, sizeof(info)); + if ( ! SHGetSpecialFolderPath(NULL, path, CSIDL_APPDATA, 0) ) return; + mir_wstrcat(path, L"\\Mozilla\\Firefox\\Profiles\\*"); + if( (hFile = _wfindfirst( path, &dir )) != -1L ) { + do { + if (! (dir.attrib & _A_SUBDIR) || dir.name[0] == '.') continue; + mir_wstrcpy(prefsR, path); prefsR[mir_wstrlen(prefsR)-1] = 0; + mir_wstrcat(prefsR, dir.name); + mir_wstrcat(prefsR, L"\\prefs.js"); + done = 0; + if ((fR = _wfopen(prefsR, L"r")) != NULL) { + mir_wstrcpy(prefsW, prefsR); + mir_wstrcat(prefsW, L"~"); + if ((fW = _wfopen(prefsW, L"w")) != NULL) { + while ( fgets(line, 500, fR) ) { + if ( strstr( line, "\"network.proxy.type\"")) continue; + if ( strstr( line, "\"network.proxy") && ! done) { + fprintf(fW, "user_pref(\"network.proxy.type\", %d);\n", proxy); + done = 1; + } + fprintf(fW, "%s", line); + } + if (! done) { + fprintf(fW, "user_pref(\"network.proxy.type\", %d);\n", proxy); + done = 1; + } + fclose(fW); + } + fclose(fR); + } + if ( done ) { + _wremove(prefsR); + _wrename(prefsW, prefsR); + } + } while (_wfindnext( hFile, &dir ) == 0); + _findclose( hFile ); + } +} + +/* ################################################################################ */ + +char Firefox_Installed(void) { + wchar_t path[MAX_PATH]; + struct _stat info; + ZeroMemory(&info, sizeof(info)); + + if ( SHGetSpecialFolderPath(NULL, path, CSIDL_APPDATA, 0) ) { + mir_wstrcat(path, L"\\Mozilla\\Firefox\\Profiles"); + if ( _wstat(path, &info) == 0 && info.st_mode & _S_IFDIR == _S_IFDIR) { + return 1; + } + } + return 0; +} + +/* ################################################################################ */ + +void Disconnect_All_Protocols (PPROTO_SETTINGS settings, int disconnect) { + int count, c, i, status; + PROTOCOLDESCRIPTOR **plist; + + Proto_EnumProtocols(&c, &plist); + + ZeroMemory( settings, sizeof (PROTO_SETTINGS) ); + settings->item = (PPROTO_SETTING)mir_alloc( c * sizeof(PROTO_SETTING) ); + ZeroMemory( settings->item, c * sizeof(PROTO_SETTING) ); + + for( i=0 ; i<c ; i++ ) { + if ( plist[i]->type != PROTOTYPE_PROTOCOL ) continue; + if ( CallProtoService( plist[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0 ) == 0 ) continue; + status = CallProtoService( plist[i]->szName, PS_GETSTATUS, 0, 0 ); + mir_strncpy( settings->item[count].ProtoName, plist[i]->szName, MAXLABELLENGTH-1 ); + if ( status != ID_STATUS_OFFLINE && disconnect ) { + CallProtoService( plist[i]->szName, PS_SETSTATUS, ID_STATUS_OFFLINE, 0 ); + } + if ( status < MAX_CONNECT_RETRIES ) status = ID_STATUS_ONLINE; + if ( status == ID_STATUS_OFFLINE ) status = ID_STATUS_ONLINE; + settings->item[count].Status = status; + count++; + } + settings->count = count; +} + +/* ################################################################################ */ + +void Connect_All_Protocols (PPROTO_SETTINGS settings) { + int i; + for( i=0 ; i<settings->count ; i++ ) { + CallProtoService( settings->item[i].ProtoName, PS_SETSTATUS, settings->item[i].Status, 0 ); + } + free( settings->item ); + ZeroMemory( settings, sizeof (PROTO_SETTINGS) ); +} diff --git a/plugins/ProxySwitch/src/resource.h b/plugins/ProxySwitch/src/resource.h new file mode 100644 index 0000000000..8fa07ce325 --- /dev/null +++ b/plugins/ProxySwitch/src/resource.h @@ -0,0 +1,41 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by proxySwitch.rc +// +#define IDI_LOGO 101 +#define IDI_PROXY 102 +#define IDI_NOPROXY 103 +#define IDD_OPTIONS 103 +#define IDI_NOTIF_0 104 +#define IDI_NOTIF_1 105 +#define IDC_EDIT_USEPROXY 1002 +#define IDC_EDIT_NOPROXY 1004 +#define IDC_CHECK_DEFAULTCOLORS 1009 +#define IDC_CHECK_POPUPS 1010 +#define IDC_CHECK_MIRANDA 1014 +#define IDC_CHECK_IE 1015 +#define IDC_CHECK_IE2 1016 +#define IDC_CHECK_FIREFOX 1016 +#define IDC_CHECK_SHOWMYIPMENU 1021 +#define IDC_CHECK_PROXYIPMENU 1022 +#define IDC_CHECK_ALWAY_RECONNECT 1024 +#define IDC_EDIT_HIDEINTF 1025 +#define IDC_RESTARTREQUIRED 1026 +#define IDC_BTN_HELP 1027 +#define IDC_HELP_1 1028 +#define IDC_HELP_2 1029 +#define IDC_HELP_3 1030 +#define IDC_CHECK_SHOWPROXYSTATUS 1031 +#define IDC_TEXTCOLOR 2041 +#define IDC_BGCOLOR 2042 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1032 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/ProxySwitch/src/stdafx.cxx b/plugins/ProxySwitch/src/stdafx.cxx new file mode 100644 index 0000000000..18ec0f9dc4 --- /dev/null +++ b/plugins/ProxySwitch/src/stdafx.cxx @@ -0,0 +1,18 @@ +/* +Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "stdafx.h"
\ No newline at end of file diff --git a/plugins/ProxySwitch/src/stdafx.h b/plugins/ProxySwitch/src/stdafx.h new file mode 100644 index 0000000000..b29a511db7 --- /dev/null +++ b/plugins/ProxySwitch/src/stdafx.h @@ -0,0 +1,212 @@ +#ifndef proxySwitch_h +#define proxySwitch_h + +#include <winsock2.h> +#include <windows.h> +#include <iprtrmib.h> +#include <iphlpapi.h> +#include <stdio.h> +#include <commctrl.h> +#include <Wininet.h> +#include <shlobj.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <io.h> +#include <malloc.h> + +#include "newpluginapi.h" +#include "m_system.h" +#include "m_options.h" +#include "m_clist.h" +#include "m_skin.h" +#include "m_langpack.h" +#include "m_popup.h" +#include "m_database.h" +#include "m_netlib.h" +#include "m_utils.h" +#include "m_protocols.h" +#include "m_protosvc.h" + +#include <m_proxySwitch.h> + +#include "resource.h" +#include "version.h" + +#define MODULENAME "ProxySwitch" + +struct CMPlugin : public PLUGIN<CMPlugin> +{ + CMPlugin(); + + int Load() override; + int Unload() override; +}; + +#define NVL(x) x == NULL ? "" : x +#define NVLW(x) x == NULL ? L"" : x +#define ERRORMSG(msg) MessageBox(NULL,msg,_A2T(MODULENAME),MB_OK | MB_ICONERROR); +#define MAX_IPLIST_LENGTH 500 + +/**** Types ********************************************************************************/ + +// structure holding network interface description and information +typedef struct { + char *AdapterName; + wchar_t *FriendlyName; + char *IPstr; + LONG *IP; + UCHAR IPcount; + HGENMENU MenuItem; + BOOL Bound; + BOOL Disabled; +} NETWORK_INTERFACE, *PNETWORK_INTERFACE; + +// list of structures holding network interfaces description and information +typedef struct { + PNETWORK_INTERFACE item; + UCHAR count; +} NETWORK_INTERFACE_LIST; + +// structure holding an information about local end of an active connections +typedef struct { + ULONG IP; + unsigned short Port; +} ACTIVE_CONNECTION, *PACTIVE_CONNECTION; + +// list of structures holding local end of active connections +typedef struct { + PACTIVE_CONNECTION item; + UCHAR count; + UCHAR _alloc; +} ACTIVE_CONNECTION_LIST; + + +/**** Global variables *********************************************************************/ + +extern NETWORK_INTERFACE_LIST NIF_List; +extern ACTIVE_CONNECTION_LIST Connection_List; +extern CRITICAL_SECTION csNIF_List; +extern CRITICAL_SECTION csConnection_List; +extern HANDLE hEventRebound; + +/**** Options ******************************************************************************/ + +extern wchar_t opt_useProxy[MAX_IPLIST_LENGTH]; +extern wchar_t opt_noProxy[MAX_IPLIST_LENGTH]; +extern wchar_t opt_hideIntf[MAX_IPLIST_LENGTH]; +extern UINT opt_defaultColors; +extern UINT opt_popups; +extern UINT opt_showProxyState; +extern UINT opt_miranda; +extern UINT opt_ie; +extern UINT opt_firefox; +extern UINT opt_showMyIP; +extern UINT opt_showProxyIP; +extern UINT opt_alwayReconnect; +extern UINT opt_startup; +extern UINT opt_not_restarted; +extern COLORREF opt_bgColor; +extern COLORREF opt_txtColor; + +extern UINT opt_popupPluginInstalled; + +void LoadSettings(void); +void SaveSettings(void); + +/**** Service & Event handlers *************************************************************/ + +void PopupMyIPAddrs(wchar_t *msg); + +int OptInit(WPARAM wParam,LPARAM lParam); +int Init (WPARAM wParam,LPARAM lParam); +void UpdateInterfacesMenu(void); +void UpdatePopupMenu(BOOL State); + +/**** Network ******************************************************************************/ + +#define NETORDER(a) ((((a) & 0xFFL)<<24) | (((a) & 0xFF00L)<<8) | (((a) & 0xFF0000L)>>8) | (((a) & 0xFF000000L)>>24)) + +#define INCUPD_INTACT 0 +#define INCUPD_CONN_BIND 1 +#define INCUPD_UPDATED 2 +#define INCUPD_CONN_LOST 3 +#define INCUPD(x, y) x = (x) > (y) ? (x) : (y) + +#define DIGITS L"0123456789" +#define CMP_SKIP 0 +#define CMP_MASK 1 +#define CMP_SPAN 2 +#define CMP_END 3 + +typedef struct { + unsigned char cmpType; + union { ULONG loIP; ULONG net; }; + union { ULONG hiIP; ULONG mask; }; +} IP_RANGE, *PIP_RANGE; + +typedef struct { + PIP_RANGE item; + UCHAR count; +} IP_RANGE_LIST; + +void IP_WatchDog (void *arg); + +int Create_NIF_List (NETWORK_INTERFACE_LIST *list); +int Create_NIF_List_Ex (NETWORK_INTERFACE_LIST *list); +BOOL Compare_NIF_Lists (NETWORK_INTERFACE_LIST list1, NETWORK_INTERFACE_LIST list2); +int IncUpdate_NIF_List (NETWORK_INTERFACE_LIST *trg, NETWORK_INTERFACE_LIST src); +wchar_t *Print_NIF_List (NETWORK_INTERFACE_LIST list, wchar_t *msg); +wchar_t *Print_NIF (PNETWORK_INTERFACE nif); +void Free_NIF (PNETWORK_INTERFACE nif); +void Free_NIF_List (NETWORK_INTERFACE_LIST *list); + +int Create_Range_List (IP_RANGE_LIST *list, wchar_t *str, BOOL prioritized ); +int Match_Range_List (IP_RANGE_LIST range, NETWORK_INTERFACE_LIST ip); +void Free_Range_List (IP_RANGE_LIST *list); + +int ManageConnections (WPARAM wParam,LPARAM lParam); +void UnboundConnections (LONG *OldIP, LONG *NewIP); + +/**** Proxy/Connection Modification and Query routines *************************************/ + +#define MAXLABELLENGTH 64 + +#define PROXY_NO_CONFIG -2 +#define PROXY_MIXED -1 +#define PROXY_DISABLED 0 +#define PROXY_ENABLED 1 + +typedef struct { + char ModuleName[MAXLABELLENGTH]; + char SettingName[MAXLABELLENGTH]; +} PROXY_SETTING, *PPROXY_SETTING; + +typedef struct { + PPROXY_SETTING item; + UCHAR count; + const char *_current_module; + UCHAR _alloc; +} PROXY_SETTINGS, *PPROXY_SETTINGS; + +typedef struct { + char ProtoName[MAXLABELLENGTH]; + DWORD Status; +} PROTO_SETTING, *PPROTO_SETTING; + +typedef struct { + PPROTO_SETTING item; + UCHAR count; +} PROTO_SETTINGS, *PPROTO_SETTINGS; + +void Create_Proxy_Settings_List ( PPROXY_SETTINGS ps ); +void Free_Proxy_Settings_List( PPROXY_SETTINGS ps ); +char Get_Miranda_Proxy_Status (void); +void Set_Miranda_Proxy_Status (char proxy); +char Get_IE_Proxy_Status (void); +void Set_IE_Proxy_Status (char proxy); +char Get_Firefox_Proxy_Status (void); +void Set_Firefox_Proxy_Status (char proxy); +char Firefox_Installed(void); +void Disconnect_All_Protocols (PPROTO_SETTINGS settings, int disconnect); +void Connect_All_Protocols (PPROTO_SETTINGS settings); +#endif diff --git a/plugins/ProxySwitch/src/version.h b/plugins/ProxySwitch/src/version.h new file mode 100644 index 0000000000..d2fc801bf4 --- /dev/null +++ b/plugins/ProxySwitch/src/version.h @@ -0,0 +1,13 @@ +#define __MAJOR_VERSION 1 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 1 + +#include <stdver.h> + +#define __PLUGIN_NAME "ProxySwitch" +#define __FILENAME "ProxySwitch.dll" +#define __DESCRIPTION "The plugin watches IP address changes, displays popups, and adjusts the proxy settings of Miranda, Internet Explorer and Firefox." +#define __AUTHOR "Petr Smejkal" +#define __AUTHORWEB "https://miranda-ng.org/p/ProxySwitch/" +#define __COPYRIGHT "© 2005 Petr Smejkal" |