BsWin32PlatformUtility.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsPrerequisitesUtil.h"
  4. #include "Win32/BsWin32PlatformUtility.h"
  5. #include "BsColor.h"
  6. #include <windows.h>
  7. #include <iphlpapi.h>
  8. #include <VersionHelpers.h>
  9. namespace bs
  10. {
  11. GPUInfo PlatformUtility::sGPUInfo;
  12. void PlatformUtility::terminate(bool force)
  13. {
  14. if (!force)
  15. PostQuitMessage(0);
  16. else
  17. TerminateProcess(GetCurrentProcess(), 0);
  18. }
  19. void PlatformUtility::copyToClipboard(const WString& string)
  20. {
  21. HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (string.size() + 1) * sizeof(WString::value_type));
  22. WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
  23. string.copy(buffer, string.size());
  24. buffer[string.size()] = '\0';
  25. GlobalUnlock(hData);
  26. if (OpenClipboard(NULL))
  27. {
  28. EmptyClipboard();
  29. SetClipboardData(CF_UNICODETEXT, hData);
  30. CloseClipboard();
  31. }
  32. else
  33. {
  34. GlobalFree(hData);
  35. }
  36. }
  37. WString PlatformUtility::copyFromClipboard()
  38. {
  39. if (OpenClipboard(NULL))
  40. {
  41. HANDLE hData = GetClipboardData(CF_UNICODETEXT);
  42. if (hData != NULL)
  43. {
  44. WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
  45. WString string(buffer);
  46. GlobalUnlock(hData);
  47. CloseClipboard();
  48. return string;
  49. }
  50. else
  51. {
  52. CloseClipboard();
  53. return L"";
  54. }
  55. }
  56. return L"";
  57. }
  58. WString PlatformUtility::keyCodeToUnicode(UINT32 keyCode)
  59. {
  60. static HKL keyboardLayout = GetKeyboardLayout(0);
  61. static UINT8 keyboarState[256];
  62. if (GetKeyboardState(keyboarState) == FALSE)
  63. return 0;
  64. UINT virtualKey = MapVirtualKeyExW(keyCode, 1, keyboardLayout);
  65. wchar_t output[2];
  66. int count = ToUnicodeEx(virtualKey, keyCode, keyboarState, output, 2, 0, keyboardLayout);
  67. if (count > 0)
  68. return WString(output, count);
  69. return StringUtil::WBLANK;
  70. }
  71. bool PlatformUtility::getMACAddress(MACAddress& address)
  72. {
  73. std::memset(&address, 0, sizeof(address));
  74. PIP_ADAPTER_INFO adapterInfo = bs_alloc<IP_ADAPTER_INFO>();
  75. ULONG len = sizeof(IP_ADAPTER_INFO);
  76. DWORD rc = GetAdaptersInfo(adapterInfo, &len);
  77. if (rc == ERROR_BUFFER_OVERFLOW)
  78. {
  79. bs_free(adapterInfo);
  80. adapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(bs_alloc(len));
  81. }
  82. else if (rc != ERROR_SUCCESS)
  83. {
  84. bs_free(adapterInfo);
  85. return false;
  86. }
  87. if (GetAdaptersInfo(adapterInfo, &len) == NO_ERROR)
  88. {
  89. PIP_ADAPTER_INFO curAdapter = nullptr;
  90. curAdapter = adapterInfo;
  91. while (curAdapter)
  92. {
  93. if (curAdapter->Type == MIB_IF_TYPE_ETHERNET && curAdapter->AddressLength == sizeof(address))
  94. {
  95. std::memcpy(&address, curAdapter->Address, curAdapter->AddressLength);
  96. return true;
  97. }
  98. curAdapter = curAdapter->Next;
  99. }
  100. }
  101. bs_free(adapterInfo);
  102. return false;
  103. }
  104. typedef LONG NTSTATUS, *PNTSTATUS;
  105. typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
  106. RTL_OSVERSIONINFOW GetRealOSVersion()
  107. {
  108. HMODULE handle = GetModuleHandleW(L"ntdll.dll");
  109. if (handle)
  110. {
  111. RtlGetVersionPtr rtlGetVersionFunc = (RtlGetVersionPtr)GetProcAddress(handle, "RtlGetVersion");
  112. if (rtlGetVersionFunc != nullptr)
  113. {
  114. RTL_OSVERSIONINFOW rovi = { 0 };
  115. rovi.dwOSVersionInfoSize = sizeof(rovi);
  116. if (rtlGetVersionFunc(&rovi) == 0)
  117. return rovi;
  118. }
  119. }
  120. RTL_OSVERSIONINFOW rovi = { 0 };
  121. return rovi;
  122. }
  123. SystemInfo PlatformUtility::getSystemInfo()
  124. {
  125. SystemInfo output;
  126. INT32 CPUInfo[4] = { -1 };
  127. // Get CPU manufacturer
  128. __cpuid(CPUInfo, 0);
  129. output.cpuManufacturer = String(12, ' ');
  130. memcpy((char*)output.cpuManufacturer.data(), &CPUInfo[1], 4);
  131. memcpy((char*)output.cpuManufacturer.data() + 4, &CPUInfo[3], 4);
  132. memcpy((char*)output.cpuManufacturer.data() + 8, &CPUInfo[2], 4);
  133. // Get CPU brand string
  134. char brandString[48];
  135. //// Get the information associated with each extended ID.
  136. __cpuid(CPUInfo, 0x80000000);
  137. UINT32 numExtensionIds = CPUInfo[0];
  138. for (UINT32 i = 0x80000000; i <= numExtensionIds; ++i)
  139. {
  140. __cpuid(CPUInfo, i);
  141. if (i == 0x80000002)
  142. memcpy(brandString, CPUInfo, sizeof(CPUInfo));
  143. else if (i == 0x80000003)
  144. memcpy(brandString + 16, CPUInfo, sizeof(CPUInfo));
  145. else if (i == 0x80000004)
  146. memcpy(brandString + 32, CPUInfo, sizeof(CPUInfo));
  147. }
  148. output.cpuModel = brandString;
  149. // Get number of CPU cores
  150. SYSTEM_INFO sysInfo;
  151. GetSystemInfo(&sysInfo);
  152. output.cpuNumCores = (UINT32)sysInfo.dwNumberOfProcessors;
  153. // Get CPU clock speed
  154. HKEY hKey;
  155. long status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ,
  156. &hKey);
  157. if (status == ERROR_SUCCESS)
  158. {
  159. DWORD mhz;
  160. DWORD bufferSize = 4;
  161. RegQueryValueEx(hKey, "~MHz", NULL, NULL, (LPBYTE) &mhz, &bufferSize);
  162. output.cpuClockSpeedMhz = (UINT32)mhz;
  163. }
  164. else
  165. output.cpuClockSpeedMhz = 0;
  166. // Get amount of system memory
  167. MEMORYSTATUSEX statex;
  168. statex.dwLength = sizeof(statex);
  169. GlobalMemoryStatusEx(&statex);
  170. output.memoryAmountMb = (UINT32)(statex.ullTotalPhys / (1024 * 1024));
  171. if (BS_ARCH_TYPE == BS_ARCHITECTURE_x86_64)
  172. output.osIs64Bit = true;
  173. else
  174. {
  175. HANDLE process = GetCurrentProcess();
  176. BOOL is64Bit = false;
  177. IsWow64Process(process, (PBOOL)&is64Bit);
  178. output.osIs64Bit = is64Bit > 0;
  179. }
  180. // Get OS version
  181. output.osName = "Windows " + toString((UINT32)GetRealOSVersion().dwMajorVersion);
  182. // Get GPU info
  183. output.gpuInfo = sGPUInfo;
  184. return output;
  185. }
  186. String PlatformUtility::generateUUID()
  187. {
  188. UUID uuid;
  189. UuidCreate(&uuid);
  190. UINT8* uuidStr;
  191. UuidToStringA(&uuid, &uuidStr);
  192. String output((char*)uuidStr);
  193. RpcStringFreeA(&uuidStr);
  194. return output;
  195. }
  196. void PlatformUtility::open(const Path& path)
  197. {
  198. ShellExecute(nullptr, "open", path.toString().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
  199. }
  200. HBITMAP Win32PlatformUtility::createBitmap(const Color* pixels, UINT32 width, UINT32 height, bool premultiplyAlpha)
  201. {
  202. BITMAPINFO bi;
  203. ZeroMemory(&bi, sizeof(BITMAPINFO));
  204. bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  205. bi.bmiHeader.biWidth = width;
  206. bi.bmiHeader.biHeight = height;
  207. bi.bmiHeader.biPlanes = 1;
  208. bi.bmiHeader.biBitCount = 32;
  209. bi.bmiHeader.biCompression = BI_RGB;
  210. HDC hDC = GetDC(nullptr);
  211. void* data = nullptr;
  212. HBITMAP hBitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, (void**)&data, nullptr, 0);
  213. HDC hBitmapDC = CreateCompatibleDC(hDC);
  214. ReleaseDC(nullptr, hDC);
  215. //Select the bitmaps to DC
  216. HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hBitmap);
  217. //Scan each pixel of the source bitmap and create the masks
  218. Color pixel;
  219. DWORD *dst = (DWORD*)data;
  220. for (UINT32 y = 0; y < height; ++y)
  221. {
  222. for (UINT32 x = 0; x < width; ++x)
  223. {
  224. UINT32 revY = height - y - 1;
  225. pixel = pixels[revY * width + x];
  226. if (premultiplyAlpha)
  227. {
  228. pixel.r *= pixel.a;
  229. pixel.g *= pixel.a;
  230. pixel.b *= pixel.a;
  231. }
  232. *dst = pixel.getAsBGRA();
  233. dst++;
  234. }
  235. }
  236. SelectObject(hBitmapDC, hOldBitmap);
  237. DeleteDC(hBitmapDC);
  238. return hBitmap;
  239. }
  240. }