BsWin32PlatformUtility.cpp 7.1 KB

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