pvupdate.cpp
1 /******************************************************************************* 2 * pvupdate.cpp 3 * 4 * This module implements update checking routines. 5 * 6 * Author: Christopher J. Cason. 7 * 8 * --------------------------------------------------------------------------- 9 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7. 10 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd. 11 * 12 * POV-Ray is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU Affero General Public License as 14 * published by the Free Software Foundation, either version 3 of the 15 * License, or (at your option) any later version. 16 * 17 * POV-Ray is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Affero General Public License for more details. 21 * 22 * You should have received a copy of the GNU Affero General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. 24 * --------------------------------------------------------------------------- 25 * POV-Ray is based on the popular DKB raytracer version 2.12. 26 * DKBTrace was originally written by David K. Buck. 27 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. 28 * --------------------------------------------------------------------------- 29 * $File: //depot/public/povray/3.x/windows/pvupdate.cpp $ 30 * $Revision: #1 $ 31 * $Change: 6069 $ 32 * $DateTime: 2013/11/06 11:59:40 $ 33 * $Author: chrisc $ 34 *******************************************************************************/ 35 36 #define POVWIN_FILE 37 #define _WIN32_IE COMMONCTRL_VERSION 38 39 #include <windows.h> 40 #include <wininet.h> 41 #include <stdio.h> 42 43 #include "pvengine.h" 44 45 // this must be the last file included 46 #include "syspovdebug.h" 47 48 #pragma comment(lib, "wininet") 49 50 #define HTTPFLAGS INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD 51 52 #ifndef INTERNET_CONNECTION_CONFIGURED 53 #define INTERNET_CONNECTION_CONFIGURED 0x40 54 #define INTERNET_CONNECTION_OFFLINE 0x20 55 #define INTERNET_RAS_INSTALLED 0x10 56 #endif 57 58 #ifndef SM_CMONITORS 59 #define SM_CMONITORS 80 60 #endif 61 62 #ifndef SM_REMOTESESSION 63 #define SM_REMOTESESSION 0x1000 64 #endif 65 66 #define SCRIPTPATH "/updates/checkv2" 67 68 using std::string; 69 70 namespace povwin 71 { 72 73 static char *GetInstallTime (void) 74 { 75 HKEY key ; 76 DWORD len ; 77 static char str [64] ; 78 79 len = sizeof (str) ; 80 if (RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\POV-Ray", 0, KEY_READ, &key) == ERROR_SUCCESS) 81 { 82 if (RegQueryValueEx (key, INSTALLTIMEKEY, 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) 83 { 84 RegCloseKey (key) ; 85 return (str) ; 86 } 87 RegCloseKey (key) ; 88 } 89 return (NULL) ; 90 } 91 92 bool InternetConnected (void) 93 { 94 DWORD flags ; 95 96 BOOL result = InternetGetConnectedState (&flags, 0) ; 97 if ((flags & INTERNET_CONNECTION_OFFLINE) != 0) 98 return (false) ; 99 return (result != 0) ; 100 } 101 102 // -1 == error, 0 == no update, 1 == update 103 int IsUpdateAvailable (bool SendSysinfo, char *CurrentVersion, string& NewVersion, string& Info) 104 { 105 int result = -1 ; 106 char poststr [2048] ; 107 char user_agent[128]; 108 char str[128]; 109 char *s = poststr ; 110 char *InstalledOn ; 111 HDC hdc ; 112 HKEY key ; 113 DWORD len; 114 DWORD header = 0 ; 115 DWORD n ; 116 FILETIME file_time ; 117 SYSTEMTIME system_time ; 118 SYSTEM_INFO sysinfo ; 119 OSVERSIONINFO version_info ; 120 MEMORYSTATUSEX mem_status ; 121 122 if (!InternetConnected ()) 123 return (-1) ; 124 if ((InstalledOn = GetInstallTime ()) == NULL) 125 { 126 GetSystemTime (&system_time) ; 127 if (SystemTimeToFileTime (&system_time, &file_time)) 128 reg_printf (true, "Software\\POV-Ray", INSTALLTIMEKEY, "%I64u", ((__int64) file_time.dwHighDateTime << 32) | file_time.dwLowDateTime) ; 129 if ((InstalledOn = GetInstallTime ()) == NULL) 130 InstalledOn = "Unknown" ; 131 } 132 sprintf (user_agent, "POVWIN %s", CurrentVersion) ; 133 HINTERNET iHandle = InternetOpen (user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0) ; 134 if (iHandle == NULL) 135 return (-1) ; 136 HINTERNET cHandle = InternetConnect (iHandle, "winupdate.povray.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0) ; 137 if (cHandle == NULL) 138 { 139 InternetCloseHandle (iHandle) ; 140 return (-1) ; 141 } 142 HINTERNET hHandle = HttpOpenRequest (cHandle, "POST", SCRIPTPATH, NULL, NULL, NULL, HTTPFLAGS, 0) ; 143 if (hHandle == NULL) 144 { 145 InternetCloseHandle (iHandle) ; 146 InternetCloseHandle (cHandle) ; 147 return (-1) ; 148 } 149 if (InstalledOn == NULL) 150 InstalledOn = "Unknown" ; 151 s += sprintf (s, "CurrentVersion=%s\n", CurrentVersion) ; 152 s += sprintf (s, "InstallDate=%s\n", InstalledOn) ; 153 if (SendSysinfo) 154 { 155 strcpy (s, "&NoInfo=false\n") ; 156 GetSystemInfo (&sysinfo) ; 157 s += sprintf (s, "CPUArchitecture=0x%04x\n", (DWORD) sysinfo.wProcessorArchitecture) ; 158 s += sprintf (s, "NumberOfCPUs=0x%04x\n", sysinfo.dwNumberOfProcessors) ; 159 s += sprintf (s, "ProcessorType=0x%04x\n", sysinfo.dwProcessorType) ; 160 s += sprintf (s, "ProcessorLevel=0x%04x\n", (DWORD) sysinfo.wProcessorLevel) ; 161 s += sprintf (s, "ProcessorRevision=0x%04x\n", (DWORD) sysinfo.wProcessorRevision) ; 162 163 version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO) ; 164 GetVersionEx (&version_info) ; 165 166 s += sprintf (s, "OSVersion=%u.%u\n", version_info.dwMajorVersion, version_info.dwMinorVersion) ; 167 s += sprintf (s, "OSBuild=0x%08x\n", version_info.dwBuildNumber) ; 168 s += sprintf (s, "CSDVersion=%s\n", version_info.szCSDVersion) ; 169 170 hdc = GetDC (NULL) ; 171 s += sprintf (s, "BitsPerPixel=%u\n", GetDeviceCaps (hdc, BITSPIXEL)) ; 172 s += sprintf (s, "HorzRes=%u\n", GetDeviceCaps (hdc, HORZRES)) ; 173 s += sprintf (s, "VertRes=%u\n", GetDeviceCaps (hdc, VERTRES)) ; 174 ReleaseDC (NULL, hdc) ; 175 176 s += sprintf (s, "NumberOfMonitors=%u\n", GetSystemMetrics (SM_CMONITORS)) ; 177 s += sprintf (s, "HasMouseWheel=%u\n", GetSystemMetrics (SM_MOUSEWHEELPRESENT)) ; 178 s += sprintf (s, "Remote=%u\n", GetSystemMetrics (SM_REMOTESESSION)) ; 179 180 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\Description\\System\\CentralProcessor\\0", 0, KEY_READ, &key) == ERROR_SUCCESS) 181 { 182 len = sizeof (n) ; 183 if (RegQueryValueEx (key, "~MHZ", 0, NULL, (BYTE *) &n, &len) == ERROR_SUCCESS) 184 s += sprintf (s, "CPUFrequency=%u\n", n) ; 185 186 len = sizeof (n) ; 187 if (RegQueryValueEx (key, "FeatureSet", 0, NULL, (BYTE *) &n, &len) == ERROR_SUCCESS) 188 s += sprintf (s, "FeatureSet=0x%08x\n", n) ; 189 190 len = sizeof (str) ; 191 if (RegQueryValueEx (key, "ProcessorNameString", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) 192 s += sprintf (s, "CPUName=%s\n", str) ; 193 194 len = sizeof (str) ; 195 if (RegQueryValueEx (key, "Identifier", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) 196 s += sprintf (s, "CPUIdentifier=%s\n", str) ; 197 198 len = sizeof (str) ; 199 if (RegQueryValueEx (key, "VendorIdentifier", 0, NULL, (BYTE *) str, &len) == ERROR_SUCCESS) 200 s += sprintf (s, "VendorIdentifier=%s\n", str) ; 201 202 RegCloseKey (key) ; 203 } 204 205 mem_status.dwLength = sizeof (MEMORYSTATUSEX) ; 206 GlobalMemoryStatusEx(&mem_status) ; 207 s += sprintf (s, "PhysicalMemory=%I64u\n", mem_status.ullTotalPhys) ; 208 209 if (GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SLANGUAGE, str, sizeof (str))) 210 s += sprintf (s, "DefaultLanguage=%s\n", str) ; 211 } 212 else 213 strcpy (s, "NoInfo=true\n ") ; 214 if (HttpSendRequest (hHandle, NULL, 0, poststr, (DWORD) strlen (poststr))) 215 { 216 result = -3; 217 len = sizeof(str); 218 if (HttpQueryInfo (hHandle, HTTP_QUERY_STATUS_CODE, str, &len, &header)) 219 { 220 if (len == 3 && memcmp (str, "200", 3) == 0) 221 { 222 char *reply = new char[131072]; 223 if (InternetReadFile (hHandle, reply, 131071, &len)) 224 { 225 reply[len] = '\0' ; 226 result = 0 ; 227 if (memcmp (reply, "YES ", 4) == 0) 228 { 229 result = 1 ; 230 Info.clear(); 231 NewVersion = reply + 4; 232 string::size_type pos = NewVersion.find(' '); 233 if (pos != string::npos) 234 { 235 Info = NewVersion.substr(pos); 236 NewVersion.resize(pos); 237 } 238 if (NewVersion.length() == 0) 239 result = -4; 240 } 241 else if ((len == 2 && memcmp (reply, "NO", 2) == 0) || (len == 3 && memcmp (reply, "NO\n", 3) == 0)) 242 result = 0 ; 243 else if ((len == 6 && memcmp (reply, "BADVER", 6) == 0) || (len == 7 && memcmp (reply, "BADVER\n", 7) == 0)) 244 result = -2 ; 245 else 246 result = -4 ; 247 } 248 delete[] reply; 249 } 250 } 251 } 252 InternetCloseHandle (hHandle) ; 253 InternetCloseHandle (cHandle) ; 254 InternetCloseHandle (iHandle) ; 255 return (result) ; 256 } 257 258 } // end of namespace povwin