/** * @file updater.cpp * @brief Windows auto-updater * * $LicenseInfo:firstyear=2002&license=viewergpl$ * * Copyright (c) 2002-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ // // Usage: updater -url [-name ] [-program ] [-silent] // #include "linden_common.h" #include #include #define BUFSIZE 8192 int gTotalBytesRead = 0; DWORD gTotalBytes = -1; HWND gWindow = NULL; WCHAR gProgress[256]; char* gUpdateURL; char* gProgramName; char* gProductName; bool gIsSilent; #if _DEBUG FILE* logfile = 0; #endif char* wchars_to_utf8chars(WCHAR* in_chars) { int tlen = 0; WCHAR* twc = in_chars; while (*twc++ != 0) { tlen++; } char* outchars = new char[tlen]; char* res = outchars; for (int i=0; i [-name ] [-program ] [-silent]", L"Usage", MB_OK); return parse_args_result; } // Did we get a userserver to work with? if (!gUpdateURL) { MessageBox(gWindow, L"Please specify the download url from the command line", L"Error", MB_OK); return 1; } // Can't feed GetTempPath into GetTempFile directly if (0 == GetTempPathA(MAX_PATH - 14, update_exec_path)) { MessageBox(gWindow, L"Problem with GetTempPath()", L"Error", MB_OK); return 1; } if (0 == GetTempFileNameA(update_exec_path, NULL, 0, update_exec_path)) { MessageBox(gWindow, L"Problem with GetTempFileName()", L"Error", MB_OK); return 1; } // Hack hack hack ptr = strrchr(update_exec_path, '.'); *(ptr + 1) = 'e'; *(ptr + 2) = 'x'; *(ptr + 3) = 'e'; *(ptr + 4) = 0; WCHAR update_uri[4096]; mbstowcs(update_uri, gUpdateURL, 4096); int success; int cancelled; // Actually do the download #if _DEBUG fprintf(logfile,"Calling get_url_into_file\n"); fflush(logfile); #endif success = get_url_into_file(update_uri, update_exec_path, &cancelled); // WinInet can't tell us if we got a 404 or not. Therefor, we check // for the size of the downloaded file, and assume that our installer // will always be greater than 1MB. if (gTotalBytesRead < (1024 * 1024) && ! cancelled) { MessageBox(gWindow, L"The Imprudence auto-update has failed.\n" L"The problem may be caused by other software installed \n" L"on your computer, such as a firewall.\n" L"Please visit http://imprudenceviewer.org/download/ \n" L"to download the latest version of Imprudence.\n", NULL, MB_OK); return 1; } if (cancelled) { // silently exit return 0; } if (!success) { MessageBox(gWindow, L"Imprudence download failed.\n" L"Please try again later.", NULL, MB_OK); return 1; } // Construct some parameters. char params[2048]; /* Flawfinder: ignore */ if (gIsSilent && gProgramName) { _snprintf(params, sizeof(params), "/S /P=\"%s\"", gProgramName); /* Flawfinder: ignore */ params[2047] = '\0'; } else if (gProgramName) { _snprintf(params, sizeof(params), "/P=\"%s\"", gProgramName); /* Flawfinder: ignore */ params[2047] = '\0'; } else if (gIsSilent) { sprintf(params, "/S"); /* Flawfinder: ignore */ } else { params[0] = '\0'; } if (32 >= (int) ShellExecuteA(gWindow, "open", update_exec_path, params, "C:\\", SW_SHOWDEFAULT)) { // No shit: less than or equal to 32 means failure MessageBox(gWindow, L"ShellExecute failed. Please try again later.", NULL, MB_OK); return 1; } if (gIsSilent && gProductName) { WCHAR message[2048]; WCHAR wproduct[2048]; mbstowcs(wproduct, gProductName, 2048); wsprintf(message, L"Updating %s. %s will automatically start once the update is complete. This may take a minute...", wproduct, wproduct); MessageBox(gWindow, message, L"Download Complete", MB_OK); } return 0; }