/* 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 (mir_strcmp(szSetting, "NLUseProxy") != 0 && mir_strcmpi(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)); } mir_strncpy(ps->item[ps->count].ModuleName, ps->_current_module, MAXLABELLENGTH - 1); mir_strncpy(ps->item[ps->count].SettingName, szSetting, MAXLABELLENGTH - 1); ps->count++; return 0; } int Enum_Modules(const char *szModuleName, uint32_t, 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) mir_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(0, 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(0, 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 = 0, 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); } mir_free(settings->item); ZeroMemory(settings, sizeof(PROTO_SETTINGS)); }