#include "common.h" #include "socket.h" /* #include typedef struct SettingsProcEnumParam_tag { int file_id; std::list *list; char *current_filename; char *temp_folder; } SettingsProcEnumParam; int SettingsEnumProc(const char *szSetting,LPARAM lParam) { SettingsProcEnumParam *param = (SettingsProcEnumParam *)lParam; if(strcmp(szSetting, param->current_filename) != 0) { int file_id = DBGetContactSettingDword(0, MODULE, szSetting, -1); if(file_id == param->file_id) { std::string new_file_name(param->temp_folder); new_file_name += "\\"; new_file_name += szSetting; param->list->push_back(new_file_name); } } return 0; } */ void ShowAndLogError(TCHAR *message) { } bool GetFile(char *url, TCHAR *temp_folder, char *plugin_name, char *version, bool dlls_only, int recurse_count /*=0*/) { if(recurse_count > MAX_REDIRECT_RECURSE) { NLog("GetFile: error, too many redirects"); return false; } TCHAR save_file[MAX_PATH]; if(url == 0 || temp_folder == 0 || plugin_name == 0) return false; // ensure temp_folder exists if(!CreatePath(options.temp_folder)) { DWORD err = GetLastError(); char buff[128]; sprintf(buff, "GetFile: error creating temp folder, code %d", (unsigned)err); NLog(buff); return false; } // ensure zip_folder exists, if necessary if(options.save_zips && !CreatePath(options.zip_folder)) { DWORD err = GetLastError(); char buff[128]; sprintf(buff, "GetFile: error creating zip folder, code %d", (unsigned)err); NLog(buff); return false; } _tcscpy(save_file, temp_folder); _tcscat(save_file, _T("\\")); TCHAR *temp_str = GetTString(plugin_name); _tcscat(save_file, temp_str); free(temp_str); if(version) { temp_str = GetTString(version); _tcscat(save_file, _T("_")); _tcscat(save_file, temp_str); free(temp_str); } // copt extension from url char *ext = strrchr(url, '.'); if(ext && *ext && strcmp(ext, ".dll") == 0) { _tcscat(save_file, _T(".dll")); } else { // default to zip extension (e.g. miranda fl) _tcscat(save_file, _T(".zip")); ext = ".zip"; } NETLIBHTTPREQUEST req = {0}; req.cbSize = sizeof(req); req.requestType = REQUEST_GET; req.szUrl = url; req.flags = NLHRF_NODUMP; NETLIBHTTPREQUEST *resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); if(resp) { if(resp->resultCode == 200) { HANDLE hSaveFile = CreateFile(save_file, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if(hSaveFile != INVALID_HANDLE_VALUE) { unsigned long bytes_written = 0; if(WriteFile(hSaveFile, resp->pData, resp->dataLength, &bytes_written, NULL) == TRUE) { CloseHandle(hSaveFile); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; if(ext && *ext && strcmp(ext, ".zip") == 0) { if(!options.no_unzip) { char *ans_save_file = GetAString(save_file), *ans_temp_folder = GetAString(temp_folder); //MessageBoxA(0, ans_temp_folder, ans_save_file, MB_OK); unzip_file(ans_save_file, ans_temp_folder); free(ans_save_file); free(ans_temp_folder); } if(options.save_zips) { TCHAR save_archive[MAX_PATH]; _tcscpy(save_archive, options.zip_folder); _tcscat(save_archive, _T("\\")); _tcscat(save_archive, save_file + _tcslen(temp_folder) + 1); DeleteFile(save_archive); if(!MoveFile(save_file, save_archive)) { char buff[128]; sprintf(buff, "GetFile: could not move file, code: %d", (unsigned)GetLastError()); NLog(buff); if(!DeleteFile(save_file)) { char buff[128]; sprintf(buff, "GetFile: error deleting file, code: %d", (unsigned)GetLastError()); NLog(buff); } } } else { if(!DeleteFile(save_file)) { char buff[128]; sprintf(buff, "GetFile: error deleting file, code: %d", (unsigned)GetLastError()); NLog(buff); } } if(dlls_only) { NLog("Deleting non-dlls"); DeleteNonDlls(temp_folder); } } return true; } else { char buff[128]; sprintf(buff, "GetFile: error writing file, code %d", (unsigned)GetLastError()); NLog(buff); } CloseHandle(hSaveFile); } else { char buff[128]; sprintf(buff, "GetFile: error creating file, code %d", (unsigned)GetLastError()); NLog(buff); } } else if(resp->resultCode >= 300 && resp->resultCode < 400) { // get new location bool ret = false; for(int i = 0; i < resp->headersCount; i++) { //MessageBox(0, resp->headers[i].szValue, resp->headers[i].szName, MB_OK); if(strcmp(resp->headers[i].szName, "Location") == 0) { ret = GetFile(resp->headers[i].szValue, temp_folder, plugin_name, version, dlls_only, recurse_count + 1); break; } } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; return ret; } else { TCHAR buff[1024]; _stprintf(buff, TranslateT("Failed to download \"%s\" - Invalid response, code %d"), plugin_name, resp->resultCode); ShowError(buff); char *ts = GetAString(buff); NLog(ts); free(ts); } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; } else { int err = GetLastError(); if(err) { TCHAR buff[1024]; _stprintf(buff, TranslateT("Failed to download \"%s\": "), plugin_name); int len = _tcslen(buff); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, buff + len, 512 - len, 0); ShowError(buff); char *ts = GetAString(buff); NLog(ts); free(ts); } } return false; } char *CheckVersionURL(char *url, BYTE *pbPrefixBytes, int cpbPrefixBytes, BYTE *pbVersionBytes, int cpbVersionBytes) { /* bool check = false; if(strncmp((char *)pbPrefixBytes, "My Details ", cpbPrefixBytes) == 0) { //MessageBox(0, "Checking version URL", "Updater -> My Details", MB_OK); check = true; } */ if(url == 0 || pbPrefixBytes == 0 || cpbPrefixBytes == 0 || pbVersionBytes == 0 || cpbVersionBytes == 0) return 0; /* if(check) { MessageBox(0, "Real URL check", "CheckVersionURL", MB_OK); MessageBox(0, url, "URL", MB_OK); MessageBox(0, (char *)pbPrefixBytes, "Prefix", MB_OK); MessageBox(0, (char *)pbVersionBytes, "Version", MB_OK); } */ NETLIBHTTPREQUEST req = {0}; req.cbSize = sizeof(req); req.requestType = REQUEST_GET; req.szUrl = url; req.flags = NLHRF_DUMPASTEXT; //NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER; NETLIBHTTPREQUEST *resp = (NETLIBHTTPREQUEST_tag *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); if(resp) { if(resp->resultCode == 200) { // find the location of the prefix int index, index2; for(int i = 0; i < resp->dataLength; i++) { index = 0; while(index < cpbPrefixBytes && i + index < resp->dataLength && (BYTE)resp->pData[i + index] == pbPrefixBytes[index]) index++; if(index == cpbPrefixBytes) { // we found the prefix - now compare the following bytes // i + index the first byte after the prefix index2 = 0; while(index2 + i + index < resp->dataLength && index2 < cpbVersionBytes && resp->pData[i + index + index2] == pbVersionBytes[index2]) index2++; if(index2 == cpbVersionBytes) { // same version as current //if(check) //MessageBox(0, "same version", "check url", MB_OK); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; return 0; } else { DWORD ver_current, ver_potential; char *buff = (char *)malloc(cpbVersionBytes + 1); strncpy(buff, (char *)pbVersionBytes, cpbVersionBytes); buff[cpbVersionBytes] = 0; // this is safe because pData finishes with a zero always (according to m_netlib.h docs) if(VersionFromString(buff, &ver_current) && VersionFromString(&resp->pData[i + index], &ver_potential)) { switch(options.ver_req) { case VR_MAJOR: ver_current &= 0xFF000000; ver_potential &= 0xFF000000; break; case VR_MINOR: ver_current &= 0xFFFF0000; ver_potential &= 0xFFFF0000; break; case VR_RELEASE: ver_current &= 0xFFFFFF00; ver_potential &= 0xFFFFFF00; break; case VR_BUILD: break; } //if(check) MessageBox(0, (char *)resp->pData[i + index], buff, MB_OK); free(buff); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; // we can covert the versions to DWORDS, so compare... if(ver_current < ver_potential) { char buff2[16]; CreateVersionString(ver_potential, buff2); return _strdup(buff2); } else return 0; } else { // invalid version(s), but different from current - assume it's an update free(buff); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; return _strdup(Translate("Yes")); } } } } } else if(resp->resultCode == 302) { // redirect char *ret = 0; // get new location for(int i = 0; i < resp->headersCount; i++) { //MessageBox(0, resp->headers[i].szValue, resp->headers[i].szName, MB_OK); if(strcmp(resp->headers[i].szName, "Location") == 0) { ret = CheckVersionURL(resp->headers[i].szValue, pbPrefixBytes, cpbPrefixBytes, pbVersionBytes, cpbVersionBytes); break; } } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; return ret; } else { char buff[128]; sprintf(buff, "CheckVersionURL: error, http result code %d", resp->resultCode); NLog(buff); } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); resp = 0; } else { int err = GetLastError(); if(err) { char buff[128]; sprintf(buff, "CheckVersionURL: error code %d", err); NLog(buff); return 0; } } return 0; } char *UpdateRequired(UpdateInternal *update_internal, bool *beta) { // determine whether update is required char *ret = 0, *ret_beta = 0; if(options.use_xml_backend && update_internal->file_id != -1) { if(update_internal->cat == MC_UNKNOWN) { if(XMLDataAvailable(MC_PLUGINS) && (ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, MC_PLUGINS))) { update_internal->cat = MC_PLUGINS; if(strcmp(ret, "same") == 0) { free(ret); ret = 0; } } else if(XMLDataAvailable(MC_LOCALIZATION) && (ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, MC_LOCALIZATION))) { update_internal->cat = MC_LOCALIZATION; if(strcmp(ret, "same") == 0) { free(ret); ret = 0; } } } else { ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, update_internal->cat); if(ret && strcmp(ret, "same") == 0) { free(ret); ret = 0; } } } else { ret = CheckVersionURL(update_internal->update.szVersionURL, update_internal->update.pbVersionPrefix, update_internal->update.cpbVersionPrefix, update_internal->update.pbVersion, update_internal->update.cpbVersion); } if(update_internal->update_options.use_beta) { ret_beta = CheckVersionURL(update_internal->update.szBetaVersionURL, update_internal->update.pbBetaVersionPrefix, update_internal->update.cpbBetaVersionPrefix, update_internal->update.pbVersion, update_internal->update.cpbVersion); } if(ret && !ret_beta) { if(beta) *beta = false; return ret; } else if(!ret && ret_beta) { if(beta) *beta = true; return ret_beta; } else if(ret && ret_beta) { // find highest version of ret and ret_beta //MessageBox(0, ret, ret_beta, MB_OK); DWORD vRet, vRetBeta; VersionFromString(ret, &vRet); VersionFromString(ret_beta, &vRetBeta); if(vRetBeta > vRet) { free(ret); if(beta) *beta = true; return ret_beta; } else { free(ret_beta); if(beta) *beta = false; return ret; } } return 0; }