/** * @file updater.cpp * @brief Windows auto-updater * * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. * $License$ */ // // Usage: updater -url [-name ] [-program ] [-silent] // #include #include #include #include #include "llpreprocessor.h" #include "llfile.h" #define BUFSIZE 8192 int gTotalBytesRead = 0; 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 Second Life 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://secondlife.com/download/ \n" L"to download the latest version of Second Life.\n", NULL, MB_OK); return 1; } if (cancelled) { // silently exit return 0; } if (!success) { MessageBox(gWindow, L"Second Life 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; }