/* * This file is a part of TTCalc - a mathematical calculator * and is distributed under the (new) BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2006-2009, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name Tomasz Sowa nor the names of contributors to this * project may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "update.h" #include "programresources.h" #include "messages.h" #include "resource.h" #include "winmain.h" namespace Update { bool continue_download; int level; std::string url; std::string download_file_name; int major; int minor; int revision; } /* */ DownloadIni::DownloadIni() { file = 0; file_name = new char[MAX_PATH]; file_name[0] = 0; } DownloadIni::~DownloadIni() { if( file ) fclose(file); DeleteTmpFile(); delete [] file_name; } void DownloadIni::DeleteTmpFile() { if( file_name[0] != 0 ) DeleteFile(file_name); } const char * DownloadIni::GetFileName() { return file_name; } FILE * DownloadIni::CreateTmpFile() { char buf[MAX_PATH]; file = 0; file_name[0] = 0; if( !GetTempPath(MAX_PATH, buf) ) return 0; if( !GetTempFileName(buf, "ttcalc_", 0, file_name) ) { file_name[0] = 0; return 0; } file = fopen(file_name, "wb"); return file; } void DownloadIni::GetLen(HINTERNET conn) { char buf[100]; DWORD buf_len = sizeof(buf); DWORD index = 0; if( HttpQueryInfo(conn, HTTP_QUERY_CONTENT_LENGTH, buf, &buf_len, &index) ) all_len = atoi(buf); else all_len = 0; } bool DownloadIni::Init() { if( !CreateTmpFile() ) return false; Update::continue_download = true; return true; } bool DownloadIni::Read(char * buffer, size_t size) { if( !file ) return false; fwrite(buffer, size, 1, file); CheckMessages(); return Update::continue_download; } void DownloadIni::Close() { if( file ) fclose(file); file = 0; } /* */ void DownloadProgram::GetLen(HINTERNET conn) { char buf[100]; DWORD buf_len = sizeof(buf); DWORD index = 0; if( HttpQueryInfo(conn, HTTP_QUERY_CONTENT_LENGTH, buf, &buf_len, &index) ) all_len = atoi(buf); else all_len = 0; } bool DownloadProgram::Init() { file.open(Update::download_file_name.c_str(), std::ios_base::out | std::ios_base::binary); Update::continue_download = true; if( !file ) return false; return true; } bool DownloadProgram::Read(char * buffer, size_t size) { file.write(buffer, size); CheckMessages(); return Update::continue_download; } void DownloadProgram::Close() { file.close(); } namespace Update { /* */ bool CheckUpdateFromIni(HWND hwnd) { DownloadIni down_ini; down_ini.AttachProgress(GetDlgItem(hwnd, IDC_PROGRESS)); if( down_ini.DownloadUrl("http://ttcalc.sourceforge.net/ttcalc.ini") ) { IniParser iparser; std::string ini_value[3]; iparser.SectionCaseSensitive(false); iparser.Associate( "normal|url", &url ); iparser.Associate( "normal|version.major", &ini_value[0] ); iparser.Associate( "normal|version.minor", &ini_value[1] ); iparser.Associate( "normal|version.revision", &ini_value[2] ); IniParser::Error err = iparser.ReadFromFile( down_ini.GetFileName() ); if( err == IniParser::err_ok ) { major = atoi(ini_value[0].c_str()); minor = atoi(ini_value[1].c_str()); revision = atoi(ini_value[2].c_str()); if( major > TTCALC_MAJOR_VER ) return true; else if( major == TTCALC_MAJOR_VER && minor > TTCALC_MINOR_VER ) return true; else if( major == TTCALC_MAJOR_VER && minor == TTCALC_MINOR_VER && revision > TTCALC_REVISION_VER ) return true; } } return false; } void CheckUpdate(HWND hwnd) { char buffer[200]; EnableWindow(GetDlgItem(hwnd, IDOK), false); EnableWindow(GetDlgItem(hwnd, IDC_UPDATE_INFO1), false); if( CheckUpdateFromIni(hwnd) ) { level = 1; sprintf(buffer, "Version %d.%d.%d is available, press Next to download...", major, minor, revision); SetDlgItemText(hwnd, IDC_UPDATE_INFO1, buffer); } else { level = 100; SetDlgItemText(hwnd, IDC_UPDATE_INFO1, "There is not a new version available."); SetDlgItemText(hwnd, IDOK, "Finish"); ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), SW_HIDE); EnableWindow(GetDlgItem(hwnd, IDCANCEL), false); } EnableWindow(GetDlgItem(hwnd, IDOK), true); EnableWindow(GetDlgItem(hwnd, IDC_UPDATE_INFO1), true); } bool SaveDialog(HWND hwnd) { OPENFILENAME o; char buf[MAX_PATH]; strcpy(buf, "TTCalc_setup.exe"); o.lStructSize = sizeof(o); o.hwndOwner = hwnd; o.hInstance = GetPrgRes()->GetInstance(); o.lpstrFilter = "*.*\0*.*\0"; o.lpstrCustomFilter = 0; o.nMaxCustFilter = 0; o.nFilterIndex = 1; o.lpstrFile = buf; o.nMaxFile = MAX_PATH; o.lpstrFileTitle = 0; o.nMaxFileTitle = 0; o.lpstrInitialDir = 0; // dac pulpit o.lpstrTitle = 0; o.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; o.nFileOffset = 0; o.nFileExtension = 0; o.lpstrDefExt = 0; o.lCustData = 0; o.lpfnHook = 0; o.lpTemplateName = 0; if( GetSaveFileName(&o) ) { download_file_name = buf; return true; } return false; } bool DownloadUpdate(HWND hwnd) { DownloadProgram down; char buf[300]; EnableWindow(GetDlgItem(hwnd, IDOK), false); if( SaveDialog(hwnd) ) { _snprintf(buf, 100, "Downloading: %s", url.c_str()); SetDlgItemText(hwnd, IDC_UPDATE_INFO1, buf); down.AttachProgress(GetDlgItem(hwnd, IDC_PROGRESS)); if( down.DownloadUrl( url.c_str()) ) { SetDlgItemText(hwnd, IDC_UPDATE_INFO1, "File has been correctly saved."); } else { DeleteFile(download_file_name.c_str()); SetDlgItemText(hwnd, IDC_UPDATE_INFO1, "There was a problem with downloading, please try again later"); } ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), SW_HIDE); SetDlgItemText(hwnd, IDOK, "Finish"); level = 100; } EnableWindow(GetDlgItem(hwnd, IDOK), true); EnableWindow(GetDlgItem(hwnd, IDCANCEL), false); return false; } BOOL UpdateInit(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SetDlgItemText(hwnd, IDC_UPDATE_INFO1, "Press Next to check for the update..."); SetDlgItemText(hwnd, IDOK, "Next"); SetDlgItemText(hwnd, IDCANCEL, "Cancel"); return true; } BOOL UpdateCommand(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if( LOWORD(wParam) == IDCANCEL ) { continue_download = false; EndDialog(hwnd, 0); return 0; } if( LOWORD(wParam) == IDOK ) { switch(level) { case 0: CheckUpdate(hwnd); break; case 1: DownloadUpdate(hwnd); break; case 100: EndDialog(hwnd, 0); break; } return 0; } return 1; } void CreateUpdateMessagesTable(Messages & messages) { messages.Associate(WM_INITDIALOG, UpdateInit); messages.Associate(WM_COMMAND, UpdateCommand); } BOOL CALLBACK UpdateProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static Messages messages; if( messages.Empty() ) // initiation CreateUpdateMessagesTable(messages); return messages.Call(msg, hwnd, msg, wParam, lParam); } } // namespace void ShowUpdateDialog(HWND hwnd) { using namespace Update; level = 0; download_file_name.clear(); DialogBox(GetPrgRes()->GetInstance(), MAKEINTRESOURCE(IDD_UPDATE_DIALOG), hwnd, UpdateProc); }