/******************************************************************************* * pvupdate.cpp * * This module implements update checking routines. * * Author: Christopher J. Cason. * * --------------------------------------------------------------------------- * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7. * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd. * * POV-Ray is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * POV-Ray is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * --------------------------------------------------------------------------- * POV-Ray is based on the popular DKB raytracer version 2.12. * DKBTrace was originally written by David K. Buck. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. * --------------------------------------------------------------------------- * $File: //depot/public/povray/3.x/windows/pvupdate.cpp $ * $Revision: #1 $ * $Change: 6069 $ * $DateTime: 2013/11/06 11:59:40 $ * $Author: chrisc $ *******************************************************************************/ #define POVWIN_FILE #define _WIN32_IE COMMONCTRL_VERSION #include #include #include #include "pvengine.h" // this must be the last file included #include "syspovdebug.h" #pragma comment(lib, "wininet") #define HTTPFLAGS INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD #ifndef INTERNET_CONNECTION_CONFIGURED #define INTERNET_CONNECTION_CONFIGURED 0x40 #define INTERNET_CONNECTION_OFFLINE 0x20 #define INTERNET_RAS_INSTALLED 0x10 #endif #ifndef SM_CMONITORS #define SM_CMONITORS 80 #endif #ifndef SM_REMOTESESSION #define SM_REMOTESESSION 0x1000 #endif #define SCRIPTPATH "/updates/checkv2" using std::string; namespace povwin { static char *GetInstallTime (void) { HKEY key ; DWORD len ; static char str [64] ; len = sizeof (str) ; if (RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\POV-Ray", 0, KEY_READ, &key) == ERROR_SUCCESS) { if (RegQueryValueEx (key, INSTALLTIMEKEY, 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) { RegCloseKey (key) ; return (str) ; } RegCloseKey (key) ; } return (NULL) ; } bool InternetConnected (void) { DWORD flags ; BOOL result = InternetGetConnectedState (&flags, 0) ; if ((flags & INTERNET_CONNECTION_OFFLINE) != 0) return (false) ; return (result != 0) ; } // -1 == error, 0 == no update, 1 == update int IsUpdateAvailable (bool SendSysinfo, char *CurrentVersion, string& NewVersion, string& Info) { int result = -1 ; char poststr [2048] ; char user_agent[128]; char str[128]; char *s = poststr ; char *InstalledOn ; HDC hdc ; HKEY key ; DWORD len; DWORD header = 0 ; DWORD n ; FILETIME file_time ; SYSTEMTIME system_time ; SYSTEM_INFO sysinfo ; OSVERSIONINFO version_info ; MEMORYSTATUSEX mem_status ; if (!InternetConnected ()) return (-1) ; if ((InstalledOn = GetInstallTime ()) == NULL) { GetSystemTime (&system_time) ; if (SystemTimeToFileTime (&system_time, &file_time)) reg_printf (true, "Software\\POV-Ray", INSTALLTIMEKEY, "%I64u", ((__int64) file_time.dwHighDateTime << 32) | file_time.dwLowDateTime) ; if ((InstalledOn = GetInstallTime ()) == NULL) InstalledOn = "Unknown" ; } sprintf (user_agent, "POVWIN %s", CurrentVersion) ; HINTERNET iHandle = InternetOpen (user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0) ; if (iHandle == NULL) return (-1) ; HINTERNET cHandle = InternetConnect (iHandle, "winupdate.povray.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0) ; if (cHandle == NULL) { InternetCloseHandle (iHandle) ; return (-1) ; } HINTERNET hHandle = HttpOpenRequest (cHandle, "POST", SCRIPTPATH, NULL, NULL, NULL, HTTPFLAGS, 0) ; if (hHandle == NULL) { InternetCloseHandle (iHandle) ; InternetCloseHandle (cHandle) ; return (-1) ; } if (InstalledOn == NULL) InstalledOn = "Unknown" ; s += sprintf (s, "CurrentVersion=%s\n", CurrentVersion) ; s += sprintf (s, "InstallDate=%s\n", InstalledOn) ; if (SendSysinfo) { strcpy (s, "&NoInfo=false\n") ; GetSystemInfo (&sysinfo) ; s += sprintf (s, "CPUArchitecture=0x%04x\n", (DWORD) sysinfo.wProcessorArchitecture) ; s += sprintf (s, "NumberOfCPUs=0x%04x\n", sysinfo.dwNumberOfProcessors) ; s += sprintf (s, "ProcessorType=0x%04x\n", sysinfo.dwProcessorType) ; s += sprintf (s, "ProcessorLevel=0x%04x\n", (DWORD) sysinfo.wProcessorLevel) ; s += sprintf (s, "ProcessorRevision=0x%04x\n", (DWORD) sysinfo.wProcessorRevision) ; version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO) ; GetVersionEx (&version_info) ; s += sprintf (s, "OSVersion=%u.%u\n", version_info.dwMajorVersion, version_info.dwMinorVersion) ; s += sprintf (s, "OSBuild=0x%08x\n", version_info.dwBuildNumber) ; s += sprintf (s, "CSDVersion=%s\n", version_info.szCSDVersion) ; hdc = GetDC (NULL) ; s += sprintf (s, "BitsPerPixel=%u\n", GetDeviceCaps (hdc, BITSPIXEL)) ; s += sprintf (s, "HorzRes=%u\n", GetDeviceCaps (hdc, HORZRES)) ; s += sprintf (s, "VertRes=%u\n", GetDeviceCaps (hdc, VERTRES)) ; ReleaseDC (NULL, hdc) ; s += sprintf (s, "NumberOfMonitors=%u\n", GetSystemMetrics (SM_CMONITORS)) ; s += sprintf (s, "HasMouseWheel=%u\n", GetSystemMetrics (SM_MOUSEWHEELPRESENT)) ; s += sprintf (s, "Remote=%u\n", GetSystemMetrics (SM_REMOTESESSION)) ; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\Description\\System\\CentralProcessor\\0", 0, KEY_READ, &key) == ERROR_SUCCESS) { len = sizeof (n) ; if (RegQueryValueEx (key, "~MHZ", 0, NULL, (BYTE *) &n, &len) == ERROR_SUCCESS) s += sprintf (s, "CPUFrequency=%u\n", n) ; len = sizeof (n) ; if (RegQueryValueEx (key, "FeatureSet", 0, NULL, (BYTE *) &n, &len) == ERROR_SUCCESS) s += sprintf (s, "FeatureSet=0x%08x\n", n) ; len = sizeof (str) ; if (RegQueryValueEx (key, "ProcessorNameString", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) s += sprintf (s, "CPUName=%s\n", str) ; len = sizeof (str) ; if (RegQueryValueEx (key, "Identifier", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) s += sprintf (s, "CPUIdentifier=%s\n", str) ; len = sizeof (str) ; if (RegQueryValueEx (key, "VendorIdentifier", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) s += sprintf (s, "VendorIdentifier=%s\n", str) ; RegCloseKey (key) ; } mem_status.dwLength = sizeof (MEMORYSTATUSEX) ; GlobalMemoryStatusEx(&mem_status) ; s += sprintf (s, "PhysicalMemory=%I64u\n", mem_status.ullTotalPhys) ; if (GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SLANGUAGE, str, sizeof (str))) s += sprintf (s, "DefaultLanguage=%s\n", str) ; } else strcpy (s, "NoInfo=true\n ") ; if (HttpSendRequest (hHandle, NULL, 0, poststr, (DWORD) strlen (poststr))) { result = -3; len = sizeof(str); if (HttpQueryInfo (hHandle, HTTP_QUERY_STATUS_CODE, str, &len, &header)) { if (len == 3 && memcmp (str, "200", 3) == 0) { char *reply = new char[131072]; if (InternetReadFile (hHandle, reply, 131071, &len)) { reply[len] = '\0' ; result = 0 ; if (memcmp (reply, "YES ", 4) == 0) { result = 1 ; Info.clear(); NewVersion = reply + 4; string::size_type pos = NewVersion.find(' '); if (pos != string::npos) { Info = NewVersion.substr(pos); NewVersion.resize(pos); } if (NewVersion.length() == 0) result = -4; } else if ((len == 2 && memcmp (reply, "NO", 2) == 0) || (len == 3 && memcmp (reply, "NO\n", 3) == 0)) result = 0 ; else if ((len == 6 && memcmp (reply, "BADVER", 6) == 0) || (len == 7 && memcmp (reply, "BADVER\n", 7) == 0)) result = -2 ; else result = -4 ; } delete[] reply; } } } InternetCloseHandle (hHandle) ; InternetCloseHandle (cHandle) ; InternetCloseHandle (iHandle) ; return (result) ; } } // end of namespace povwin