123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- #include "il2cpp-config.h"
- #if !IL2CPP_USE_GENERIC_ENVIRONMENT && IL2CPP_TARGET_WINDOWS
- #include "WindowsHelpers.h"
- #if !IL2CPP_TARGET_XBOXONE && !IL2CPP_TARGET_WINDOWS_GAMES
- #include <Shlobj.h>
- #endif
- // Windows.h defines GetEnvironmentVariable as GetEnvironmentVariableW for unicode and this will
- // change the string "Environment::GetEnvironmentVariable" below to "Environment::GetEnvironmentVariableW"
- // in the preprocessor. So we undef to avoid this issue and use GetEnvironmentVariableW directly.
- // Same for SetEnvironmentVariable
- #undef GetEnvironmentVariable
- #undef SetEnvironmentVariable
- #include "os/Environment.h"
- #include "utils/StringUtils.h"
- #include <string>
- #define BUFFER_SIZE 1024
- namespace il2cpp
- {
- namespace os
- {
- std::string Environment::GetMachineName()
- {
- Il2CppChar computerName[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD size = sizeof(computerName) / sizeof(computerName[0]);
- if (!GetComputerNameW(computerName, &size))
- return NULL;
- return utils::StringUtils::Utf16ToUtf8(computerName);
- }
- int32_t Environment::GetProcessorCount()
- {
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return info.dwNumberOfProcessors;
- }
- // GetVersionEx is deprecated on desktop in Windows SDK, and we shim it for WinRT
- #pragma warning( push )
- #pragma warning( disable : 4996 )
- std::string Environment::GetOsVersionString()
- {
- OSVERSIONINFO verinfo;
- verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&verinfo))
- {
- char version[64];
- /* maximum string length is 35 bytes
- 3 x 10 bytes per number, 1 byte for 0, 3 x 1 byte for dots, 1 for NULL */
- sprintf(version, "%ld.%ld.%ld.0",
- verinfo.dwMajorVersion,
- verinfo.dwMinorVersion,
- verinfo.dwBuildNumber);
- return version;
- }
- return "0.0.0.0";
- }
- #pragma warning( pop )
- std::string Environment::GetOsUserName()
- {
- #if !IL2CPP_TARGET_WINDOWS_GAMES
- Il2CppChar user_name[256 + 1];
- DWORD user_name_size = ARRAYSIZE(user_name);
- if (GetUserNameW(user_name, &user_name_size))
- return utils::StringUtils::Utf16ToUtf8(user_name);
- #endif // !IL2CPP_TARGET_WINDOWS_GAMES
- return "Unknown";
- }
- std::string Environment::GetEnvironmentVariable(const std::string& name)
- {
- std::vector<Il2CppChar> buffer(BUFFER_SIZE);
- const UTF16String varName = utils::StringUtils::Utf8ToUtf16(name.c_str());
- DWORD ret = GetEnvironmentVariableW(varName.c_str(), &buffer[0], BUFFER_SIZE);
- if (ret == 0) // Not found
- return std::string();
- if (ret < BUFFER_SIZE) // Found and fits into buffer
- return utils::StringUtils::Utf16ToUtf8(&buffer[0]);
- // Requires bigger buffer
- IL2CPP_ASSERT(ret >= BUFFER_SIZE);
- buffer.resize(ret + 1);
- ret = GetEnvironmentVariableW(varName.c_str(), &buffer[0], ret + 1);
- IL2CPP_ASSERT(ret != 0);
- return utils::StringUtils::Utf16ToUtf8(&buffer[0]);
- }
- void Environment::SetEnvironmentVariable(const std::string& name, const std::string& value)
- {
- const UTF16String varName = utils::StringUtils::Utf8ToUtf16(name.c_str());
- if (value.empty())
- SetEnvironmentVariableW((LPWSTR)varName.c_str(), NULL);
- else
- {
- const UTF16String varValue = utils::StringUtils::Utf8ToUtf16(value.c_str());
- SetEnvironmentVariableW((LPWSTR)varName.c_str(), (LPWSTR)varValue.c_str());
- }
- }
- std::vector<std::string> Environment::GetEnvironmentVariableNames()
- {
- WCHAR* env_strings;
- WCHAR* env_string;
- WCHAR* equal_str;
- std::vector<std::string> result;
- env_strings = GetEnvironmentStringsW();
- if (env_strings)
- {
- env_string = env_strings;
- while (*env_string != '\0')
- {
- // Skip over environment variables starting with '='
- if (*env_string != '=')
- {
- equal_str = wcschr(env_string, '=');
- result.push_back(utils::StringUtils::Utf16ToUtf8(env_string, (int)(equal_str - env_string)));
- }
- while (*env_string != '\0')
- env_string++;
- env_string++;
- }
- FreeEnvironmentStringsW(env_strings);
- }
- return result;
- }
- std::string Environment::GetHomeDirectory()
- {
- #if IL2CPP_TARGET_WINDOWS_DESKTOP
- std::string home_directory;
- PWSTR profile_path = NULL;
- HRESULT hr = SHGetKnownFolderPath(FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &profile_path);
- if (SUCCEEDED(hr))
- {
- home_directory = utils::StringUtils::Utf16ToUtf8(profile_path);
- CoTaskMemFree(profile_path);
- }
- if (home_directory.empty())
- {
- home_directory = GetEnvironmentVariable("USERPROFILE");
- }
- if (home_directory.empty())
- {
- std::string drive = GetEnvironmentVariable("HOMEDRIVE");
- std::string path = GetEnvironmentVariable("HOMEPATH");
- if (!drive.empty() && !path.empty())
- home_directory = drive + path;
- }
- return home_directory;
- #else
- IL2CPP_NOT_IMPLEMENTED_ICALL(Environment::GetHomeDirectory);
- return std::string();
- #endif
- }
- std::vector<std::string> SplitLogicalDriveString(Il2CppChar *buffer, DWORD size)
- {
- std::vector<std::string> retVal;
- Il2CppChar *ptr = buffer;
- for (DWORD i = 0; i < size; ++i)
- {
- Il2CppChar c = buffer[i];
- if (c == 0)
- {
- retVal.push_back(utils::StringUtils::Utf16ToUtf8(ptr));
- ptr = &buffer[i + 1];
- }
- }
- return retVal;
- }
- std::vector<std::string> Environment::GetLogicalDrives()
- {
- #if IL2CPP_TARGET_WINDOWS_DESKTOP
- std::vector<Il2CppChar> buffer(BUFFER_SIZE);
- DWORD size = GetLogicalDriveStringsW(BUFFER_SIZE, &buffer[0]);
- if (size == 0)
- return std::vector<std::string>();
- if (size > BUFFER_SIZE)
- {
- buffer.resize(size + 1);
- size = GetLogicalDriveStringsW(size + 1, &buffer[0]);
- IL2CPP_ASSERT(size != 0);
- }
- return SplitLogicalDriveString(&buffer[0], size);
- #else
- return std::vector<std::string>();
- #endif
- }
- void Environment::Exit(int result)
- {
- ::exit(result);
- }
- NORETURN void Environment::Abort()
- {
- // __fastfail() is available since VS2012
- #if _MSC_VER >= 1700
- __fastfail(FAST_FAIL_FATAL_APP_EXIT);
- #else
- abort();
- #endif
- }
- #if IL2CPP_TARGET_WINDOWS_DESKTOP
- utils::Expected<std::string> Environment::GetWindowsFolderPath(int32_t folder)
- {
- Il2CppChar path[MAX_PATH];
- if (SUCCEEDED(SHGetFolderPathW(NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path)))
- return utils::StringUtils::Utf16ToUtf8(path);
- return std::string();
- }
- typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
- utils::Expected<bool> Environment::Is64BitOs()
- {
- BOOL isWow64Process = false;
- // Supported on XP SP2 and higher
- //IsWow64Process is not available on all supported versions of Windows.
- //Use GetModuleHandle to get a handle to the DLL that contains the function
- //and GetProcAddress to get a pointer to the function if available.
- LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
- GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
- if (NULL != fnIsWow64Process)
- {
- if (fnIsWow64Process(GetCurrentProcess(), &isWow64Process))
- {
- return isWow64Process == TRUE;
- }
- }
- return false;
- }
- #elif IL2CPP_TARGET_WINDOWS_GAMES
- utils::Expected<std::string> Environment::GetWindowsFolderPath(int32_t folder)
- {
- return std::string();
- }
- utils::Expected<bool> Environment::Is64BitOs()
- {
- #if _WIN64 // the IsWow64Process(used above) function is not available on Windows Games,this is the best available.
- return true;
- #else
- return false;
- #endif
- }
- #endif
- }
- }
- #endif
|