Otclient  14/8/2020
win32platform.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifdef WIN32
24 
25 #include "platform.h"
26 #include <winsock2.h>
27 #include <windows.h>
29 #include <boost/algorithm/string.hpp>
30 #include <tchar.h>
31 
32 void Platform::processArgs(std::vector<std::string>& args)
33 {
34  int nargs;
35  wchar_t **wchar_argv = CommandLineToArgvW(GetCommandLineW(), &nargs);
36  if(!wchar_argv)
37  return;
38 
39  args.clear();
40  if(wchar_argv) {
41  for(int i=0;i<nargs;++i)
42  args.push_back(stdext::utf16_to_utf8(wchar_argv[i]));
43  }
44 }
45 
46 bool Platform::spawnProcess(std::string process, const std::vector<std::string>& args)
47 {
48  std::string commandLine;
49  for(uint i = 0; i < args.size(); ++i)
50  commandLine += stdext::format(" \"%s\"", args[i]);
51 
52  boost::replace_all(process, "/", "\\");
53  if(!boost::ends_with(process, ".exe"))
54  process += ".exe";
55 
56  std::wstring wfile = stdext::utf8_to_utf16(process);
57  std::wstring wcommandLine = stdext::utf8_to_utf16(commandLine);
58 
59  if((size_t)ShellExecuteW(NULL, L"open", wfile.c_str(), wcommandLine.c_str(), NULL, SW_SHOWNORMAL) > 32)
60  return true;
61  return false;
62 }
63 
65 {
66  return GetCurrentProcessId();
67 }
68 
69 bool Platform::isProcessRunning(const std::string& name)
70 {
71  if(FindWindowA(name.c_str(), NULL) != NULL)
72  return true;
73  return false;
74 }
75 
76 bool Platform::killProcess(const std::string& name)
77 {
78  HWND window = FindWindowA(name.c_str(), NULL);
79  if(window == NULL)
80  return false;
81  DWORD pid = GetProcessId(window);
82  HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
83  if(handle == NULL)
84  return false;
85  bool ok = TerminateProcess(handle, 1) != 0;
86  CloseHandle(handle);
87  return ok;
88 }
89 
90 std::string Platform::getTempPath()
91 {
92  std::string ret;
93  wchar_t path[MAX_PATH];
94  GetTempPathW(MAX_PATH, path);
95  ret = stdext::utf16_to_utf8(path);
96  boost::replace_all(ret, "\\", "/");
97  return ret;
98 }
99 
100 std::string Platform::getCurrentDir()
101 {
102  std::string ret;
103  wchar_t path[MAX_PATH];
104  GetCurrentDirectoryW(MAX_PATH, path);
105  ret = stdext::utf16_to_utf8(path);
106  boost::replace_all(ret, "\\", "/");
107  ret += "/";
108  return ret;
109 }
110 
111 bool Platform::fileExists(std::string file)
112 {
113  boost::replace_all(file, "/", "\\");
114  std::wstring wfile = stdext::utf8_to_utf16(file);
115  DWORD dwAttrib = GetFileAttributesW(wfile.c_str());
116  return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
117 }
118 
119 bool Platform::copyFile(std::string from, std::string to)
120 {
121  boost::replace_all(from, "/", "\\");
122  boost::replace_all(to, "/", "\\");
123  if(CopyFileW(stdext::utf8_to_utf16(from).c_str(), stdext::utf8_to_utf16(to).c_str(), FALSE) == 0)
124  return false;
125  return true;
126 }
127 
128 bool Platform::removeFile(std::string file)
129 {
130  boost::replace_all(file, "/", "\\");
131  if(DeleteFileW(stdext::utf8_to_utf16(file).c_str()) == 0)
132  return false;
133  return true;
134 }
135 
137 {
138  boost::replace_all(file, "/", "\\");
139  std::wstring wfile = stdext::utf8_to_utf16(file);
140  WIN32_FILE_ATTRIBUTE_DATA fileAttrData;
141  memset(&fileAttrData, 0, sizeof(fileAttrData));
142  GetFileAttributesExW(wfile.c_str(), GetFileExInfoStandard, &fileAttrData);
143  ULARGE_INTEGER uli;
144  uli.LowPart = fileAttrData.ftLastWriteTime.dwLowDateTime;
145  uli.HighPart = fileAttrData.ftLastWriteTime.dwHighDateTime;
146  return uli.QuadPart;
147 }
148 
149 void Platform::openUrl(std::string url)
150 {
151  if(url.find("http://") == std::string::npos)
152  url.insert(0, "http://");
153  ShellExecuteW(NULL, L"open", stdext::utf8_to_utf16(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
154 }
155 
156 std::string Platform::getCPUName()
157 {
158  char buf[1024];
159  memset(buf, 0, sizeof(buf));
160  DWORD bufSize = sizeof(buf);
161  HKEY hKey;
162  if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
163  return "";
164  RegQueryValueExA(hKey, "ProcessorNameString", NULL, NULL, (LPBYTE)buf, (LPDWORD)&bufSize);
165  return buf;
166 }
167 
169 {
170  MEMORYSTATUSEX status;
171  status.dwLength = sizeof(status);
172  GlobalMemoryStatusEx(&status);
173  return status.ullTotalPhys;
174 }
175 
176 #ifndef PRODUCT_PROFESSIONAL
177 #define PRODUCT_PROFESSIONAL 0x00000030
178 #define VER_SUITE_WH_SERVER 0x00008000
179 #define VER_PLATFORM_WIN32s 0
180 #define VER_PLATFORM_WIN32_WINDOWS 1
181 #define VER_PLATFORM_WIN32_NT 2
182 #define PRODUCT_UNDEFINED 0x00000000
183 #define PRODUCT_ULTIMATE 0x00000001
184 #define PRODUCT_HOME_BASIC 0x00000002
185 #define PRODUCT_HOME_PREMIUM 0x00000003
186 #define PRODUCT_ENTERPRISE 0x00000004
187 #define PRODUCT_HOME_BASIC_N 0x00000005
188 #define PRODUCT_BUSINESS 0x00000006
189 #define PRODUCT_STANDARD_SERVER 0x00000007
190 #define PRODUCT_DATACENTER_SERVER 0x00000008
191 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
192 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A
193 #define PRODUCT_STARTER 0x0000000B
194 #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
195 #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
196 #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
197 #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
198 #define PRODUCT_BUSINESS_N 0x00000010
199 #define PRODUCT_WEB_SERVER 0x00000011
200 #define PRODUCT_CLUSTER_SERVER 0x00000012
201 #define PRODUCT_HOME_SERVER 0x00000013
202 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
203 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
204 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
205 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
206 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
207 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
208 #define PRODUCT_HOME_PREMIUM_N 0x0000001A
209 #define PRODUCT_ENTERPRISE_N 0x0000001B
210 #define PRODUCT_ULTIMATE_N 0x0000001C
211 #define PRODUCT_WEB_SERVER_CORE 0x0000001D
212 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
213 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
214 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
215 #define PRODUCT_SERVER_FOUNDATION 0x00000021
216 #define PRODUCT_HOME_PREMIUM_SERVER 0x00000022
217 #define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
218 #define PRODUCT_STANDARD_SERVER_V 0x00000024
219 #define PRODUCT_DATACENTER_SERVER_V 0x00000025
220 #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
221 #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
222 #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
223 #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
224 #define PRODUCT_HYPERV 0x0000002A
225 #define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B
226 #define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C
227 #define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D
228 #define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E
229 #define PRODUCT_STARTER_N 0x0000002F
230 #define PRODUCT_PROFESSIONAL 0x00000030
231 #define PRODUCT_PROFESSIONAL_N 0x00000031
232 #define PRODUCT_SB_SOLUTION_SERVER 0x00000032
233 #endif
234 
235 std::string Platform::getOSName()
236 {
237  typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
238  typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
239 
240  std::string ret;
241  OSVERSIONINFOEX osvi;
242  SYSTEM_INFO si;
243  PGNSI pGNSI;
244  PGPI pGPI;
245  BOOL bOsVersionInfoEx;
246  DWORD dwType;
247 
248  ZeroMemory(&si, sizeof(SYSTEM_INFO));
249  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
250 
251  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
252  bOsVersionInfoEx = VerifyVersionInfo(&osvi, 0, 0);
253 
254  if(!bOsVersionInfoEx)
255  return std::string();
256 
257  pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
258  if(NULL != pGNSI)
259  pGNSI(&si);
260  else
261  GetSystemInfo(&si);
262 
263  if(VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4) {
264  if(osvi.dwMajorVersion == 6) {
265  if(osvi.dwMinorVersion == 0) {
266  if(osvi.wProductType == VER_NT_WORKSTATION)
267  ret += "Windows Vista ";
268  else ret += "Windows Server 2008 ";
269  }
270 
271  if(osvi.dwMinorVersion == 1 || osvi.dwMinorVersion == 2)
272  {
273  if(osvi.wProductType == VER_NT_WORKSTATION && osvi.dwMinorVersion == 1)
274  ret += "Windows 7 ";
275  else
276  if(osvi.wProductType == VER_NT_WORKSTATION && osvi.dwMinorVersion == 2)
277  ret += "Windows 8 ";
278  else
279  ret += "Windows Server 2008 R2 ";
280  }
281 
282  pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
283 
284  pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
285 
286  switch(dwType)
287  {
288  case PRODUCT_ULTIMATE:
289  ret += "Ultimate Edition";
290  break;
291  case PRODUCT_PROFESSIONAL:
292  ret += "Professional";
293  break;
294  case PRODUCT_HOME_PREMIUM:
295  ret += "Home Premium Edition";
296  break;
297  case PRODUCT_HOME_BASIC:
298  ret += "Home Basic Edition";
299  break;
300  case PRODUCT_ENTERPRISE:
301  ret += "Enterprise Edition";
302  break;
303  case PRODUCT_BUSINESS:
304  ret += "Business Edition";
305  break;
306  case PRODUCT_STARTER:
307  ret += "Starter Edition";
308  break;
309  case PRODUCT_CLUSTER_SERVER:
310  ret += "Cluster Server Edition";
311  break;
312  case PRODUCT_DATACENTER_SERVER:
313  ret += "Datacenter Edition";
314  break;
315  case PRODUCT_DATACENTER_SERVER_CORE:
316  ret += "Datacenter Edition (core installation)";
317  break;
318  case PRODUCT_ENTERPRISE_SERVER:
319  ret += "Enterprise Edition";
320  break;
321  case PRODUCT_ENTERPRISE_SERVER_CORE:
322  ret += "Enterprise Edition (core installation)";
323  break;
324  case PRODUCT_ENTERPRISE_SERVER_IA64:
325  ret += "Enterprise Edition for Itanium-based Systems";
326  break;
327  case PRODUCT_SMALLBUSINESS_SERVER:
328  ret += "Small Business Server";
329  break;
330  case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
331  ret += "Small Business Server Premium Edition";
332  break;
333  case PRODUCT_STANDARD_SERVER:
334  ret += "Standard Edition";
335  break;
336  case PRODUCT_STANDARD_SERVER_CORE:
337  ret += "Standard Edition (core installation)";
338  break;
339  case PRODUCT_WEB_SERVER:
340  ret += "Web Server Edition";
341  break;
342  }
343  }
344 
345  if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
346  if(GetSystemMetrics(SM_SERVERR2))
347  ret += "Windows Server 2003 R2, ";
348  else if(osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
349  ret += "Windows Storage Server 2003";
350  else if(osvi.wSuiteMask & VER_SUITE_WH_SERVER)
351  ret += "Windows Home Server";
352  else if(osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
353  ret += "Windows XP Professional x64 Edition";
354  else
355  ret += "Windows Server 2003, ";
356 
357  if(osvi.wProductType != VER_NT_WORKSTATION) {
358  if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) {
359  if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
360  ret += "Datacenter Edition for Itanium-based Systems";
361  else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
362  ret += "Enterprise Edition for Itanium-based Systems";
363  }
364 
365  else if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
366  if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
367  ret += "Datacenter x64 Edition";
368  else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
369  ret += "Enterprise x64 Edition";
370  else
371  ret += "Standard x64 Edition";
372  } else {
373  if(osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
374  ret += "Compute Cluster Edition";
375  else if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
376  ret += "Datacenter Edition";
377  else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
378  ret += "Enterprise Edition";
379  else if(osvi.wSuiteMask & VER_SUITE_BLADE)
380  ret += "Web Edition";
381  else ret += "Standard Edition";
382  }
383  }
384  }
385 
386  if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
387  ret += "Windows XP ";
388  if(osvi.wSuiteMask & VER_SUITE_PERSONAL)
389  ret += "Home Edition";
390  else ret += "Professional";
391  }
392 
393  if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) {
394  ret += "Windows 2000 ";
395  if(osvi.wProductType == VER_NT_WORKSTATION) {
396  ret += "Professional";
397  } else {
398  if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
399  ret += "Datacenter Server";
400  else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
401  ret += "Advanced Server";
402  else ret += "Server";
403  }
404  }
405 
406  ret += stdext::format(" (build %d)", osvi.dwBuildNumber);
407 
408  if(osvi.dwMajorVersion >= 6 ) {
409  if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
410  ret += ", 64-bit";
411  else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
412  ret += ", 32-bit";
413  }
414  } else {
415  ret = "Windows";
416  }
417  return ret;
418 }
419 
420 
421 std::string Platform::traceback(const std::string& where, int level, int maxDepth)
422 {
423  std::stringstream ss;
424  ss << "\nat:";
425  ss << "\n\t[C++]: " << where;
426  return ss.str();
427 }
428 
429 #endif
Platform::getCurrentDir
std::string getCurrentDir()
Definition: unixplatform.cpp:83
Platform::getCPUName
std::string getCPUName()
Definition: unixplatform.cpp:127
stdext.h
Platform::removeFile
bool removeFile(std::string file)
Definition: unixplatform.cpp:105
Platform::getTempPath
std::string getTempPath()
Definition: unixplatform.cpp:78
Platform::getOSName
std::string getOSName()
Definition: unixplatform.cpp:159
Platform::openUrl
void openUrl(std::string url)
Definition: unixplatform.cpp:120
ticks_t
int64 ticks_t
Definition: types.h:43
Platform::killProcess
bool killProcess(const std::string &name)
Definition: unixplatform.cpp:73
stdext::format
std::string format()
Definition: format.h:82
Platform::copyFile
bool copyFile(std::string from, std::string to)
Definition: unixplatform.cpp:94
window
X11Window window
Definition: platformwindow.cpp:31
Platform::traceback
std::string traceback(const std::string &where, int level=1, int maxDepth=32)
Definition: unixplatform.cpp:172
Platform::getFileModificationTime
ticks_t getFileModificationTime(std::string file)
Definition: unixplatform.cpp:112
uint
unsigned int uint
Definition: types.h:31
Platform::processArgs
void processArgs(std::vector< std::string > &args)
Definition: unixplatform.cpp:34
Platform::fileExists
bool fileExists(std::string file)
Definition: unixplatform.cpp:99
platform.h
stdext::ends_with
bool ends_with(const std::string &str, const std::string &test)
Definition: string.cpp:258
Platform::isProcessRunning
bool isProcessRunning(const std::string &name)
Definition: unixplatform.cpp:68
stdext::replace_all
void replace_all(std::string &str, const std::string &search, const std::string &replacement)
Definition: string.cpp:268
Platform::getTotalSystemMemory
double getTotalSystemMemory()
Definition: unixplatform.cpp:143
Platform::spawnProcess
bool spawnProcess(std::string process, const std::vector< std::string > &args)
Definition: unixplatform.cpp:39
Platform::getProcessId
int getProcessId()
Definition: unixplatform.cpp:63