#ifdef WINAMPX #define WIN32_LEAN_AND_MEAN 1 #include #include "stdio.h" #include "proxydt.h" #include #include ".\ws2tcpip.h" #include ".\wininet.h" #include "../jnetlib/jnetlib.h" #include extern void SendMetadata( char *data, int arg ); HRESULT JNetLibDownloadToFile(LPVOID lpUnused1, LPSTR lpWPADLocation, LPSTR lpTempFile, LPVOID lpUnused2, LPVOID lpUnused3); enum { BK_UNKNOWN = 0, BK_IE4 = 1, BK_NETSCAPE4 = 2, BK_NETSCAPE6 = 3, BK_MOZILLA = 4, BK_FIREFOX = 5 }; // browser info struct typedef struct{ LPSTR lpName; BOOL bSupported; }BK_INFO; // browser info BK_INFO BrowserInfo[] = { "Unknown", FALSE, "IE 4.0+", TRUE, "Netscape 4 or 5", FALSE, "Netscape 6+", TRUE, "Mozilla", TRUE, "Firefox", TRUE }; // Global variables int gBrowserKind = BK_UNKNOWN; int gTryAuto = 1; // Exported C functions extern "C" BOOL ProxyInit(); extern "C" void ProxyDeInit(); extern "C" int ResolvProxyFromURL(LPSTR lpURL, LPSTR lpHostname, LPSTR lpDest); // Global C functions BOOL IsIEProxySet(); int GetIESettings(); int ResolveURL_IE(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort); BOOL IsFirefoxProxySet(); int GetFirefoxSettings(); int ResolveURL_Firefox(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort); BOOL IsMozillaProxySet(); int GetMozillaSettings(); int ResolveURL_Mozilla(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort); int GetDefaultBrowser(); int ReadWPADFile(LPSTR lpWPADLocation, LPSTR pIPAddress, int *pnPort); int GetFirefoxOrMozillaSettings(BOOL bFirefox); BOOL IsFirefoxOrMozillaProxySet(BOOL bFirefox); int ResolveURL_MozillaOrFirefox(BOOL bFirefox, LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort); // exported functions extern "C" BOOL ProxyInit() { BOOL bRet; bRet = FALSE; gBrowserKind = GetDefaultBrowser(); switch(gBrowserKind) { case BK_IE4: bRet = IsIEProxySet(); break; case BK_MOZILLA: bRet = IsMozillaProxySet(); break; case BK_FIREFOX: bRet = IsFirefoxProxySet(); break; } return bRet; } extern "C" void ProxyDeInit() { } extern "C" int ResolvProxyFromURL(LPSTR lpURL, LPSTR lpHostname, LPSTR lpDest) { // lpURL = URL to resolve // lpHostname = hostname // lpDest = where to store the result, such as "www.proxyserver.com:8080" char szIPAddress[MAX_PATH] = {0}; int ret, nPort=0; lpDest[0]=0; if(lpURL && lpHostname && lpDest) { switch(gBrowserKind) { case BK_IE4: ret = ResolveURL_IE(lpURL, lpHostname, szIPAddress, sizeof(szIPAddress), &nPort); break; case BK_MOZILLA: ret = ResolveURL_Mozilla(lpURL, lpHostname, szIPAddress, sizeof(szIPAddress), &nPort); break; case BK_FIREFOX: ret = ResolveURL_Firefox(lpURL, lpHostname, szIPAddress, sizeof(szIPAddress), &nPort); break; } if(ret == 0) { if ( szIPAddress[0] ) { wsprintf(lpDest, "%s:%d", szIPAddress, nPort); return 1; } else return 0; } else return 0; } else return -1; } int GetDefaultBrowser() { DWORD dwSize, dwType; TCHAR valueBuf[MAX_PATH] = {0}; DWORD valueSize = sizeof(valueBuf); HKEY hKey; long lRet; memset(valueBuf, 0, sizeof(valueBuf)); lRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, "http\\shell\\open\\ddeexec\\Application", 0, KEY_READ, &hKey); if (lRet == ERROR_SUCCESS) { dwSize = valueSize; lRet = RegQueryValueEx(hKey, "", NULL, &dwType, (LPBYTE)valueBuf, &dwSize); if(lRet == ERROR_SUCCESS && dwType == REG_SZ) { if (_tcsicmp(_T("NSShell"), valueBuf) == 0) { //NS 4.x return BK_NETSCAPE4; } else if (_tcsicmp(_T("IExplore"), valueBuf) == 0) { //IE 4+ return BK_IE4; } else if (_tcsicmp(_T("Mozilla"), valueBuf) == 0) { //Mozilla return BK_MOZILLA; } else if (_tcsicmp(_T("Firefox"), valueBuf) == 0) { //Firefox return BK_FIREFOX; } } } RegCloseKey(hKey); lRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, "http\\shell\\open\\command", 0, KEY_READ, &hKey); if(lRet == ERROR_SUCCESS) { dwSize = valueSize; lRet = RegQueryValueEx(hKey, "", NULL, &dwType, (LPBYTE)valueBuf, &dwSize); if(lRet == ERROR_SUCCESS && dwType == REG_SZ) { if(strstr(valueBuf, "MOZILLA")) { return BK_MOZILLA; } if(strstr(valueBuf, "NETSCAPE")) { return BK_MOZILLA; } if(strstr(valueBuf, "FIREFOX")) { return BK_FIREFOX; } } } RegCloseKey(hKey); return BK_UNKNOWN; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // helper functions for JSProxy.dll DWORD __stdcall ResolveHostName(LPSTR lpszHostName, LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize); BOOL __stdcall IsResolvable(LPSTR lpszHost); DWORD __stdcall GetIPAddress(LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize); BOOL __stdcall IsInNet(LPSTR lpszIPAddress, LPSTR lpszDest, LPSTR lpszMask); // functions to get IE checkbox state BOOL GetAutomaticallyDetectSettingsCheckboxState(); BOOL GetUseAProxyServerForYourLanCheckboxState(); BOOL GetAutomaticConfigurationScriptCheckboxState(); BOOL GetBypassProxyServerForLocalAddressesCheckboxState(); // functions to actually get an IP address and port # of the proxy server int GetAutomaticDetectSettings(LPSTR lpIPAddress, int *pnPort); int GetProxyServerForLanProxySettings(LPSTR lpIPAddress, int *pnPort); int GetAutoConfigScriptProxySettings(LPSTR lpIPAddress, int *pnPort); // various helper functions BOOL IsDirect(LPSTR proxy); BOOL IsAProxy(LPSTR proxy); void reportFuncErr(TCHAR* funcName); char * strstri(LPSTR lpOne, LPSTR lpTwo); int GetProxyIP(LPSTR proxy, LPSTR szProxyIP); int GetProxyPort(LPSTR proxy); // some global variables char gszURL[1025] = {0}; char gszHost[256] = {0}; // returns TRUE if the user has set a proxy in IE BOOL IsIEProxySet() { BOOL bAutomaticallyDetectSettings = GetAutomaticallyDetectSettingsCheckboxState(); BOOL bUseAutomaticConfigurationScript = GetAutomaticConfigurationScriptCheckboxState(); BOOL bUseAProxyServerForYourLan = GetUseAProxyServerForYourLanCheckboxState(); if(bAutomaticallyDetectSettings || bUseAutomaticConfigurationScript || bUseAProxyServerForYourLan) { return TRUE; } return FALSE; } int ResolveURL_IE(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort) { // get the state of the four checkboxes in the proxy settings dialog for IE BOOL bAutomaticallyDetectSettings = GetAutomaticallyDetectSettingsCheckboxState(); BOOL bUseAutomaticConfigurationScript = GetAutomaticConfigurationScriptCheckboxState(); BOOL bUseAProxyServerForYourLan = GetUseAProxyServerForYourLanCheckboxState(); //BOOL bBypassProxyServerForLocalAddresses = GetBypassProxyServerForLocalAddressesCheckboxState(); int ret; lstrcpyn(gszURL, lpURL, 1025); lstrcpyn(gszHost, lpHostname, 256); // if nothing checked, return if(!bAutomaticallyDetectSettings && !bUseAutomaticConfigurationScript && !bUseAProxyServerForYourLan) { return 0; } // if all three checkboxes on... if(bAutomaticallyDetectSettings && gTryAuto) { // try the automatic configuration next ret = GetAutomaticDetectSettings(lpIPAddress, pnPort); if(ret == 0 && *pnPort) { return 0; } gTryAuto = 0; } if ( bUseAutomaticConfigurationScript) { // try the automatic config script method first ret = GetAutoConfigScriptProxySettings(lpIPAddress, pnPort); if(ret == 0 && *pnPort ) { return 0; } } if ( bUseAProxyServerForYourLan) { // if still no success, try the "Use a proxy server for your lan" settings ret = GetProxyServerForLanProxySettings(lpIPAddress, pnPort); if(ret == 0 && *pnPort) { return 0; } } // no success... return 0; } // handles the "Automatically Detect" checkbox int GetAutomaticDetectSettings(LPSTR lpIPAddress, int *pnPort) { // By not specifying a domain name, Windows uses the local domain name, // so form an http request to go to http://wpad/wpad.dat, // store results in szWPADLocation and call URLDownloadToFileA() if(lpIPAddress && pnPort) { // download wpad.dat from the URL in szURL return ReadWPADFile("http://wpad/wpad.dat", lpIPAddress, pnPort); } return -1; } // handles the "Use automatic configuration script" checkbox int GetAutoConfigScriptProxySettings(LPSTR lpIPAddress, int *pnPort) { DWORD dwType, dwSize; HKEY hKey; char szWPADLocation[MAX_PATH] = {0}; long lRet; int retval = -1; if(!lpIPAddress) { return retval; } if(!pnPort) { return retval; } // use the registry read of HKCU\\software\microsoft\windows\current version\internet settings to see if "Use Automatic Configuration Script" is checked lstrcpyn(szWPADLocation, "", MAX_PATH); lRet = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hKey); if (lRet == ERROR_SUCCESS) { dwSize = sizeof(szWPADLocation); lRet = RegQueryValueEx(hKey, "AutoConfigURL", NULL, &dwType, (LPBYTE)szWPADLocation, &dwSize); if(lRet == ERROR_SUCCESS && dwType == REG_SZ) { retval = ReadWPADFile(szWPADLocation, lpIPAddress, pnPort); } } RegCloseKey(hKey); return retval; //0 = success } // handles the "Use a proxy server for your LAN" checkbox int GetProxyServerForLanProxySettings(LPSTR lpIPAddress, int *pnPort) { DWORD dwType, dwSize; HKEY hKey; BOOL bDirectOrProxy; char szProxy[MAX_PATH] = {0}; long lRet; int retval = -1; if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } lRet = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hKey); if (lRet == ERROR_SUCCESS) { dwSize = sizeof(szProxy); lRet = RegQueryValueEx(hKey, "ProxyServer", NULL, &dwType, (LPBYTE)szProxy, &dwSize); if(lRet == ERROR_SUCCESS && dwType == REG_SZ) { retval = 0; bDirectOrProxy = FALSE; if(IsDirect(szProxy)) { // string is something like "DIRECT" // It's a 'direct' kind of proxy. bDirectOrProxy = TRUE; // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } } if(IsAProxy(szProxy)) { char szProxyIP[MAX_PATH] = {0}; // string is something like "D bDirectOrProxy = TRUE; GetProxyIP(szProxy, szProxyIP); // It's a 'regular' kind of proxy, with an IP of %s and a port of %d\n", szProxyIP, GetProxyPort(szProxy) // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, szProxyIP); } if(pnPort) { *pnPort = GetProxyPort(szProxy); } } if(!bDirectOrProxy) { // string is something like "10.0.0.1:4543" LPSTR lpColon = NULL; if ( isdigit(szProxy[0]) ) { lpColon = strchr(szProxy, ':'); if(lpColon) { *lpColon = '\0'; // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, szProxy); } *lpColon = ':'; if(pnPort) { *pnPort = GetProxyPort(szProxy); } } } else if ( strstr(szProxy,"http=") ) { char *p = strstr(szProxy,"http="); int offset= strlen("http="); char *semi = strchr(p+offset, ';'); if(semi) { *semi= '\0'; } lpColon = strchr(p+offset, ':'); if(lpColon) { *lpColon = '\0'; } // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, p+offset); } if (lpColon) if(pnPort) { *pnPort = (short)atoi(lpColon+1); } if ( !*pnPort ) *pnPort = 80; } else { if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } } } } } RegCloseKey(hKey); return retval; } int ReadWPADFile(LPSTR lpWPADLocation, LPSTR lpIPAddress, int *pnPort) { // Declare function pointers for the three autoproxy functions pfnInternetInitializeAutoProxyDll pInternetInitializeAutoProxyDll; pfnInternetDeInitializeAutoProxyDll pInternetDeInitializeAutoProxyDll; pfnInternetGetProxyInfo pInternetGetProxyInfo; // Declare and populate an AutoProxyHelperVtbl structure, and then // place a pointer to it in a containing AutoProxyHelperFunctions // structure, which will be passed to InternetInitializeAutoProxyDll: AutoProxyHelperVtbl Vtbl = {IsResolvable, GetIPAddress, ResolveHostName, IsInNet }; AutoProxyHelperFunctions HelperFunctions = { &Vtbl }; HMODULE hModJS; HRESULT hr; char szTempPath[MAX_PATH] = {0}; char szTempFile[MAX_PATH] = {0}; int retval = 0; if(!(hModJS = LoadLibrary("jsproxy.dll"))) { reportFuncErr("LoadLibrary"); return -1; } if(!(pInternetInitializeAutoProxyDll = (pfnInternetInitializeAutoProxyDll) GetProcAddress(hModJS, "InternetInitializeAutoProxyDll")) || !(pInternetDeInitializeAutoProxyDll = (pfnInternetDeInitializeAutoProxyDll) GetProcAddress(hModJS, "InternetDeInitializeAutoProxyDll")) || !(pInternetGetProxyInfo = (pfnInternetGetProxyInfo) GetProcAddress(hModJS, "InternetGetProxyInfo"))) { FreeLibrary(hModJS); reportFuncErr("GetProcAddress"); return -1; } if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } GetTempPathA(sizeof(szTempPath)/sizeof(szTempPath[0]), szTempPath); GetTempFileNameA(szTempPath, "X", 2, szTempFile); //printf(" Downloading %s ...\n", lpWPADLocation); hr = JNetLibDownloadToFile(NULL, lpWPADLocation, szTempFile, NULL, NULL); if(hr == S_OK) { if(!pInternetInitializeAutoProxyDll(0, szTempFile, NULL, &HelperFunctions, NULL)) { //printf(" Calling 'InternetInitializeAutoProxyDll' in JSPROXY.DLL failed\n (usually because 'Use Automatic Configuration Script' checkbox is OFF)\n"); pInternetDeInitializeAutoProxyDll(NULL, 0); FreeLibrary(hModJS); retval = -1; }else{ // printf("\n InternetInitializeAutoProxyDll returned: %d\n", returnVal); // Delete the temporary file // (or, to examine the auto-config script, comment out the // file delete and substitute the following printf call) // printf("\n The auto-config script temporary file is:\n %s\n", szTempFile); DeleteFileA(szTempFile); DWORD dwSize = 0; LPSTR pProxy = NULL; if(!pInternetGetProxyInfo((LPSTR)gszURL, sizeof(gszURL), (LPSTR)gszHost, sizeof(gszHost), &pProxy, &dwSize)) { reportFuncErr("InternetGetProxyInfo"); retval = -1; }else{ // printf("\n Proxy is: %s\n", proxy); if(IsDirect(pProxy)) { //printf(" It's a 'direct' kind of proxy.\n"); // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } } if(IsAProxy(pProxy)) { char szProxyIP[MAX_PATH] = {0}; GetProxyIP(pProxy, szProxyIP); //printf(" It's a 'regular' kind of proxy, with an IP of %s and a port of %d\n", szProxyIP, GetProxyPort(szProxy)); // set the 'out' parameters if(lpIPAddress) { strcpy(lpIPAddress, szProxyIP); } if(pnPort) { *pnPort = GetProxyPort(pProxy); } } } } }else{ //printf(" Error downloading %s (hr=0x%X)\n", lpWPADLocation, hr); // there is no proxy, go direct if(lpIPAddress) { strcpy(lpIPAddress, ""); } if(pnPort) { *pnPort = 0; } retval = 0; } if(!pInternetDeInitializeAutoProxyDll(NULL, 0)) { reportFuncErr("InternetDeInitializeAutoProxyDll"); } return retval; // 0 = success } // Puts "10.0.0.1" into lpDest from a string like "PROXY 10.0.0.1:8088" // Returns 0 if success, -1 if an error int GetProxyIP(LPSTR lpProxy, LPSTR lpDest) { LPSTR lpData; LPSTR lpLastColon; BOOL bDone; char szProxy[MAX_PATH] = {0}; int ret = 0; if(lpProxy && lpDest) { lstrcpyn(szProxy, lpProxy, MAX_PATH); // find the last ":" in the string lpLastColon = NULL; lpData = szProxy; while(*lpData) { if(*lpData == ':') { lpLastColon = lpData; } lpData++; } if(lpLastColon) { // truncate the string at the last colon *lpLastColon = '\0'; bDone = FALSE; while(lpData > szProxy && !bDone) { if(*lpData == ' ') { bDone = TRUE; lpData++; }else{ lpData--; } } strcpy(lpDest, lpData); ret = 0; }else { strcpy(lpDest, lpProxy); ret =0; } }else{ ret = -1; } return ret; } // Returns 8088 from a string like "PROXY 10.0.0.1:8088" // Returns a port # if success, -1 if an error int GetProxyPort(LPSTR lpProxy) { LPSTR lpData; LPSTR lpLastColon = NULL; char szProxy[MAX_PATH] = {0}; int ret = -1; if(lpProxy) { lstrcpyn(szProxy, lpProxy, MAX_PATH); // find the last ":" in the string lpData = szProxy; while(*lpData) { if(*lpData == ':') { lpLastColon = lpData; } lpData++; } // from the last colon to the end of the string is the port number if ( lpLastColon ) { lpLastColon++; ret = (unsigned short)atoi(lpLastColon); } else ret = 80; } return ret; } BOOL IsDirect(LPSTR proxy) { BOOL bRet = FALSE; if(proxy) { if(strstri("DIRECT", proxy)) { bRet = TRUE; } } return bRet; } BOOL IsAProxy(LPSTR proxy) { BOOL bRet = FALSE; if(proxy) { if(strstri("PROXY", proxy)) { bRet = TRUE; } } return bRet; } // like strstr() but case-insensitive char * strstri(LPSTR lpOne, LPSTR lpTwo) { unsigned int b; char szOne[MAX_PATH] = {0}, szTwo[MAX_PATH] = {0}; if(lpOne && lpTwo) { strcpy(szOne, lpOne); strcpy(szTwo, lpTwo); for(b=0; b") == 0) { bBypassProxyServerForLocalAddresses = TRUE; } return bBypassProxyServerForLocalAddresses; } /* ================================================================== HELPER FUNCTIONS ================================================================== */ // ResolveHostName (a helper function) DWORD __stdcall ResolveHostName(LPSTR lpszHostName, LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize) { DWORD dwIPAddressSize; addrinfo Hints; LPADDRINFO lpAddrInfo; LPADDRINFO IPv4Only; DWORD error; // Figure out first whether to resolve a name or an address literal. // If getaddrinfo() with the AI_NUMERICHOST flag succeeds, then // lpszHostName points to a string representation of an IPv4 or IPv6 // address. Otherwise, getaddrinfo() should return EAI_NONAME. ZeroMemory(&Hints, sizeof(addrinfo)); Hints.ai_flags = AI_NUMERICHOST; // Only check for address literals. Hints.ai_family = PF_UNSPEC; // Accept any protocol family. Hints.ai_socktype = SOCK_STREAM; // Constrain results to stream socket. Hints.ai_protocol = IPPROTO_TCP; // Constrain results to TCP. error = getaddrinfo(lpszHostName, NULL, &Hints, &lpAddrInfo); if(error != EAI_NONAME) { if(error != 0) { error = (error == EAI_MEMORY) ? ERROR_NOT_ENOUGH_MEMORY : ERROR_INTERNET_NAME_NOT_RESOLVED; goto quit; } freeaddrinfo(lpAddrInfo); // An IP address (either v4 or v6) was passed in, so if there is // room in the lpszIPAddress buffer, copy it back out and return. dwIPAddressSize = lstrlen(lpszHostName); if((*lpdwIPAddressSize < dwIPAddressSize) || (lpszIPAddress == NULL)) { *lpdwIPAddressSize = dwIPAddressSize + 1; error = ERROR_INSUFFICIENT_BUFFER; goto quit; } lstrcpy(lpszIPAddress, lpszHostName); goto quit; } // Call getaddrinfo() again, this time with no flag set. Hints.ai_flags = 0; error = getaddrinfo(lpszHostName, NULL, &Hints, &lpAddrInfo); if(error != 0) { error = (error == EAI_MEMORY) ? ERROR_NOT_ENOUGH_MEMORY : ERROR_INTERNET_NAME_NOT_RESOLVED; goto quit; } // Convert the IP address in addrinfo into a string. // (the following code only handles IPv4 addresses) IPv4Only = lpAddrInfo; while(IPv4Only->ai_family != AF_INET) { IPv4Only = IPv4Only->ai_next; if(IPv4Only == NULL) { error = ERROR_INTERNET_NAME_NOT_RESOLVED; goto quit; } } error = getnameinfo(IPv4Only->ai_addr, (socklen_t)IPv4Only->ai_addrlen, lpszIPAddress, *lpdwIPAddressSize, NULL, 0, NI_NUMERICHOST); if(error != 0) error = ERROR_INTERNET_NAME_NOT_RESOLVED; quit: return(error); } // IsResolvable (a helper function) BOOL __stdcall IsResolvable(LPSTR lpszHost) { char szDummy[255] = {0}; DWORD dwDummySize = sizeof(szDummy) - 1; if(ResolveHostName(lpszHost, szDummy, &dwDummySize)) return(FALSE); return TRUE; } // GetIPAddress (a helper function) DWORD __stdcall GetIPAddress(LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize) { char szHostBuffer[255] = {0}; if(gethostname(szHostBuffer, sizeof(szHostBuffer) - 1) != ERROR_SUCCESS) return(ERROR_INTERNET_INTERNAL_ERROR); return(ResolveHostName(szHostBuffer, lpszIPAddress, lpdwIPAddressSize)); } // IsInNet (a helper function) BOOL __stdcall IsInNet(LPSTR lpszIPAddress, LPSTR lpszDest, LPSTR lpszMask) { DWORD dwDest; DWORD dwIpAddr; DWORD dwMask; dwIpAddr = inet_addr(lpszIPAddress); dwDest = inet_addr(lpszDest); dwMask = inet_addr(lpszMask); if((dwDest == INADDR_NONE) || (dwIpAddr == INADDR_NONE) || ((dwIpAddr & dwMask) != dwDest)) return(FALSE); return(TRUE); } // reportFuncErr (simple error reporting) void reportFuncErr(TCHAR* funcName) { //printf(" ERROR: %s failed with error number %d.\n", funcName, GetLastError()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// class CProfileFolder { public: int GetProfileFolder(LPSTR lpProfileFolder, BOOL bFirefox); private: int GetProfileFolder_9598ME(LPSTR lpProfileFolder, BOOL bFirefox); int GetProfileFolder_2000XP(LPSTR lpProfileFolder, BOOL bFirefox); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// class CMozSettings { public: CMozSettings(BOOL bFirefox); virtual ~CMozSettings(); int GetPreference(LPSTR lpPreferenceWanted, int *pnDest); int GetPreference(LPSTR lpPreferenceWanted, LPSTR lpDest, int sizeof_dest); private: CProfileFolder m_pf; HGLOBAL m_hData; LPSTR m_lpData; int m_sizeof_data; }; int CProfileFolder::GetProfileFolder(LPSTR lpProfileFolder, BOOL bFirefox) { // See http://www.mozilla.org/support/firefox/edit for where I got this info: // On Windows XP/2000, the path is usually %AppData%\Mozilla\Firefox\Profiles\xxxxxxxx.default\, where xxxxxxxx is a random string of characters. Just browse to C:\Documents and Settings\[User Name]\Application Data\Mozilla\Firefox\Profiles\ and the rest should be obvious. // On Windows 95/98/Me, the path is usually C:\WINDOWS\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default\ // On Linux, the path is usually ~/.mozilla/firefox/xxxxxxxx.default/ // On Mac OS X, the path is usually ~/Library/Application Support/Firefox/Profiles/xxxxxxxx.default/ OSVERSIONINFO version; ZeroMemory(&version, sizeof(version)); version.dwOSVersionInfoSize = sizeof(version); GetVersionEx(&version); if(version.dwMajorVersion == 3) { return -1; // NT 3.51 not supported } if(version.dwMajorVersion == 4) { return GetProfileFolder_9598ME(lpProfileFolder, bFirefox); } if(version.dwMajorVersion >= 5) { return GetProfileFolder_2000XP(lpProfileFolder, bFirefox); } return -1; } // private function for GetProfileFolder() // on my test system, the folder to get is c:\windows\application data\mozilla\profiles\default\y3h9azmi.slt int CProfileFolder::GetProfileFolder_9598ME(LPSTR lpProfileFolder, BOOL bFirefox) { WIN32_FIND_DATA fd; HANDLE hFind; BOOL bDone, bFound; char szHomePath[MAX_PATH] = {0}; char szTemp[MAX_PATH] = {0}; if(lpProfileFolder) { GetEnvironmentVariable("WINDIR", szHomePath, sizeof(szHomePath)); strcpy(lpProfileFolder, szHomePath); if(bFirefox) { strcat(lpProfileFolder, "\\Application Data\\Mozilla\\Firefox\\Profiles\\"); }else{ strcat(lpProfileFolder, "\\Application Data\\Mozilla\\Profiles\\default\\"); } // find the first folder in the the path specified in szProfileFolder lstrcpyn(szTemp, lpProfileFolder, MAX_PATH-4); strcat(szTemp, "*.*"); bDone = FALSE; bFound = FALSE; hFind = FindFirstFile(szTemp, &fd); while(hFind != INVALID_HANDLE_VALUE && !bDone) { if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // we're at a directory. // make sure it's not "." or ".." if(fd.cFileName[0] != '.') { bFound = TRUE; } } bDone = !FindNextFile(hFind, &fd); } FindClose(hFind); if(bFound) { strcat(lpProfileFolder, fd.cFileName); return 0; } } return -1; } // private function for GetProfileFolder() int CProfileFolder::GetProfileFolder_2000XP(LPSTR lpProfileFolder, BOOL bFirefox) { WIN32_FIND_DATA fd; HANDLE hFind; BOOL bDone, bFound; char szHomePath[MAX_PATH] = {0}; char szTemp[MAX_PATH] = {0}; if(lpProfileFolder) { GetEnvironmentVariable("APPDATA", szHomePath, sizeof(szHomePath)); strcpy(lpProfileFolder, szHomePath); if(bFirefox) { strcat(lpProfileFolder, "\\Mozilla\\Firefox\\Profiles\\"); }else{ strcat(lpProfileFolder, "\\Mozilla\\Profiles\\default\\"); } // find the first folder in the the path specified in szProfileFolder strcpy(szTemp, lpProfileFolder); strcat(szTemp, "*.*"); bDone = FALSE; bFound = FALSE; hFind = FindFirstFile(szTemp, &fd); while(hFind != INVALID_HANDLE_VALUE && !bDone) { if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // we're at a directory. // make sure it's not "." or ".." if(fd.cFileName[0] != '.') { bFound = TRUE; } } bDone = !FindNextFile(hFind, &fd); } FindClose(hFind); if(bFound) { strcat(lpProfileFolder, fd.cFileName); return 0; } } return -1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// CMozSettings::CMozSettings(BOOL bFirefox) { WIN32_FIND_DATA fd; OFSTRUCT of; HANDLE hFind; HFILE hPrefsFile; char szProfileFolder[MAX_PATH] = {0}; char szPrefsFile[MAX_PATH] = {0}; int ret; m_hData = NULL; m_lpData = NULL; ret = m_pf.GetProfileFolder(szProfileFolder, bFirefox); if(ret == 0) { // We found the folder where prefs.js lives. Read it in. strcpy(szPrefsFile, szProfileFolder); strcat(szPrefsFile, "\\prefs.js"); // get the size of the file and alloc memory for it hFind = FindFirstFile(szPrefsFile, &fd); if(hFind != INVALID_HANDLE_VALUE) { m_hData = GlobalAlloc(GHND, fd.nFileSizeLow + 256); if(m_hData) { m_lpData = (LPSTR)GlobalLock(m_hData); if(m_lpData) { hPrefsFile = OpenFile(szPrefsFile, &of, OF_READ); if(hPrefsFile) { m_sizeof_data = fd.nFileSizeLow; _lread(hPrefsFile, m_lpData, m_sizeof_data); _lclose(hPrefsFile); hPrefsFile = NULL; } } } FindClose(hFind); } } } CMozSettings::~CMozSettings() { if(m_lpData) { GlobalUnlock(m_hData); m_lpData = NULL; } if(m_hData) { GlobalFree(m_hData); m_hData = NULL; } } int CMozSettings::GetPreference(LPSTR lpPreferenceWanted, LPSTR lpDest, int sizeof_dest) { LPSTR lpPointer, lpPointerEnd, lpData; LPSTR lpLineStart, lpSearchStart, lpFoundString, lpResult; BOOL bDone; int nDoubleQuoteCount, retval; retval = -1; if(m_lpData) { if(lpPreferenceWanted) { if(lpDest) { *lpDest = '\0'; bDone = FALSE; lpPointer = m_lpData; lpPointerEnd = lpPointer + m_sizeof_data; while(lpPointer < lpPointerEnd && !bDone) { if(strncmp(lpPointer, "user_pref(", 10) == 0) { lpLineStart = lpPointer; lpSearchStart = lpLineStart + 11; if(strncmp(lpSearchStart, lpPreferenceWanted, strlen(lpPreferenceWanted)) == 0) { lpFoundString = lpSearchStart + strlen(lpPreferenceWanted); // lpFoundString almost points to what we want. Skip over the " character it's at now, skip over the " character // starting the value we want and null-terminate what we want when we find the 3rd " character lpData = lpFoundString; nDoubleQuoteCount = 0; while(nDoubleQuoteCount <= 3 && !bDone && lpData < lpPointerEnd) { if(*lpData == '"') { nDoubleQuoteCount++; if(nDoubleQuoteCount == 2) { // we're at the starting quote lpResult = lpData; lpResult++; } if(nDoubleQuoteCount == 3) { // we're at the ending quote // null-terminate what we want, and copy it to the dest buffer *lpData = '\0'; lstrcpyn(lpDest, lpResult, sizeof_dest); bDone = TRUE; retval = 0; } } lpData++; } } } lpPointer++; } } } } return retval; } int CMozSettings::GetPreference(LPSTR lpPreferenceWanted, int *pnDest) { LPSTR lpPointer, lpPointerEnd, lpData; LPSTR lpLineStart, lpSearchStart, lpFoundString; BOOL bDone; int retval; retval = -1; if(m_lpData) { if(lpPreferenceWanted) { if(pnDest) { bDone = FALSE; lpPointer = m_lpData; lpPointerEnd = lpPointer + m_sizeof_data; while(lpPointer < lpPointerEnd && !bDone) { if(strncmp(lpPointer, "user_pref(", 10) == 0) { lpLineStart = lpPointer; lpSearchStart = lpLineStart + 11; if(strncmp(lpSearchStart, lpPreferenceWanted, strlen(lpPreferenceWanted)) == 0) { lpFoundString = lpSearchStart + strlen(lpPreferenceWanted); // lpFoundString almost points to what we want. Skip over the " character it's at now, skip over the "," // starting the value we want and null-terminate what we want when we find the 3rd " character lpData = lpFoundString; while(*lpData != ',' && lpData < lpPointerEnd) { lpData++; } if(*lpData == ',') { lpData++; lpFoundString = lpData; while(*lpData != ')' && lpData < lpPointerEnd) { lpData++; } if(*lpData == ')') { // null-terminate what we want, and copy it to the dest buffer *lpData = '\0'; *pnDest = atoi(lpFoundString); bDone = TRUE; retval = 0; } } } } lpPointer++; } } } } return retval; } //////////////////////////////////////////////////////////////////////// BOOL IsFirefoxProxySet() { return IsFirefoxOrMozillaProxySet(TRUE); } BOOL IsMozillaProxySet() { return IsFirefoxOrMozillaProxySet(FALSE); } BOOL IsFirefoxOrMozillaProxySet(BOOL bFirefox) { CMozSettings settings(bFirefox); int ret, nValue; ret = settings.GetPreference("network.proxy.type", &nValue); if(ret == 0) { switch(nValue) { case 0: // shouldn't get here break; case 1: // manual configuration return TRUE; case 2: // automatic configuration return TRUE; case 4: // auto-detect return TRUE; default: // don't know break; } } return FALSE; } int ResolveURL_Mozilla(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort) { return ResolveURL_MozillaOrFirefox(FALSE, lpURL, lpHostname, lpIPAddress, sizeof_address, pnPort); } int ResolveURL_Firefox(LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort) { return ResolveURL_MozillaOrFirefox(TRUE, lpURL, lpHostname, lpIPAddress, sizeof_address, pnPort); } int ResolveURL_MozillaOrFirefox(BOOL bFirefox, LPSTR lpURL, LPSTR lpHostname, LPSTR lpIPAddress, int sizeof_address, int *pnPort) { CMozSettings setting(bFirefox); int ret, nValue; // search for the "network.proxy.http" preference ret = setting.GetPreference("network.proxy.type", &nValue); if(ret == 0) { switch(nValue) { case 0: // shouldn't get here break; case 1: // manual configuration setting.GetPreference("network.proxy.http", lpIPAddress, sizeof_address); setting.GetPreference("network.proxy.http_port", pnPort); break; case 2: // automatic configuration { char szWPADLocation[MAX_PATH] = {0}; setting.GetPreference("network.proxy.autoconfig_url", szWPADLocation, sizeof(szWPADLocation)); ret = ReadWPADFile(szWPADLocation, lpIPAddress, pnPort); } break; case 4: // Auto-detect proxy settings for this network ret = ReadWPADFile("http://wpad/wpad.dat", lpIPAddress, pnPort); break; default: break; } } return ret; } // My function that downloads from a URL to a file using the Nullsoft JNetLib library instead of using // URLDownloadToFile(). Only parameters 2 and 3 are used, to mimick the parameters of URLDownloadToFile(). HRESULT JNetLibDownloadToFile(LPVOID lpUnused1, LPSTR lpWPADLocation, LPSTR lpTempFile, LPVOID lpUnused2, LPVOID lpUnused3) { api_httpreceiver *http=0; waServiceFactory *sf=0; OFSTRUCT of; HGLOBAL hData; HRESULT hRet = S_FALSE; // default return value LPSTR lpData; DWORD dwSize; HFILE hFile; BOOL bDone; //JNL jNetLib; int ret; if(lpWPADLocation && lpTempFile) { if (WASABI_API_SVC) { sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID); if (sf) http = (api_httpreceiver *)sf->getInterface(); } if (!http) return S_FALSE; // init the library and open a connection to the URL http->Open(); http->Connect(lpWPADLocation); // loop until JNetLib gets the data. // run() returns 0 if OK, -1 if error (call geterrorstr()), or 1 if connection closed. bDone = FALSE; while(!bDone) { ret = http->Run(); if(ret == -1 || ret == 1) { bDone = TRUE; } Sleep(50); } dwSize = (DWORD)http->GetContentLength(); if(dwSize && ret == 1) { // Got something! // Allocate memory for it and write it to lpTempFile hData = GlobalAlloc(GHND, dwSize + 100); if(hData) { lpData = (LPSTR)GlobalLock(hData); if(lpData) { http->GetBytes(lpData, (int)dwSize); // create the output file and write to it hFile = OpenFile(lpTempFile, &of, OF_CREATE); if(hFile != HFILE_ERROR) { _lwrite(hFile, lpData, (UINT)dwSize); _lclose(hFile); hRet = S_OK; // success } GlobalUnlock(hData); lpData = NULL; } GlobalFree(hData); hData = NULL; } } } if (http && sf) sf->releaseInterface(http); return hRet; } #endif