tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

system_utils_win.cpp (6743B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // system_utils_win.cpp: Implementation of OS-specific functions for Windows
      8 
      9 #include "system_utils.h"
     10 
     11 #include <stdarg.h>
     12 #include <windows.h>
     13 #include <array>
     14 #include <vector>
     15 
     16 namespace angle
     17 {
     18 
     19 namespace
     20 {
     21 
     22 std::string GetPath(HMODULE module)
     23 {
     24    std::array<wchar_t, MAX_PATH> executableFileBuf;
     25    DWORD executablePathLen = GetModuleFileNameW(module, executableFileBuf.data(),
     26                                                 static_cast<DWORD>(executableFileBuf.size()));
     27    return Narrow(executablePathLen > 0 ? executableFileBuf.data() : L"");
     28 }
     29 
     30 std::string GetDirectory(HMODULE module)
     31 {
     32    std::string executablePath = GetPath(module);
     33    return StripFilenameFromPath(executablePath);
     34 }
     35 
     36 }  // anonymous namespace
     37 
     38 std::string GetExecutablePath()
     39 {
     40    return GetPath(nullptr);
     41 }
     42 
     43 std::string GetExecutableDirectory()
     44 {
     45    return GetDirectory(nullptr);
     46 }
     47 
     48 const char *GetSharedLibraryExtension()
     49 {
     50    return "dll";
     51 }
     52 
     53 Optional<std::string> GetCWD()
     54 {
     55    std::array<wchar_t, MAX_PATH> pathBuf;
     56    DWORD result = GetCurrentDirectoryW(static_cast<DWORD>(pathBuf.size()), pathBuf.data());
     57    if (result == 0)
     58    {
     59        return Optional<std::string>::Invalid();
     60    }
     61    return Narrow(pathBuf.data());
     62 }
     63 
     64 bool SetCWD(const char *dirName)
     65 {
     66    return (SetCurrentDirectoryW(Widen(dirName).c_str()) == TRUE);
     67 }
     68 
     69 const char *GetPathSeparatorForEnvironmentVar()
     70 {
     71    return ";";
     72 }
     73 
     74 double GetCurrentSystemTime()
     75 {
     76    LARGE_INTEGER frequency = {};
     77    QueryPerformanceFrequency(&frequency);
     78 
     79    LARGE_INTEGER curTime;
     80    QueryPerformanceCounter(&curTime);
     81 
     82    return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
     83 }
     84 
     85 double GetCurrentProcessCpuTime()
     86 {
     87    FILETIME creationTime = {};
     88    FILETIME exitTime     = {};
     89    FILETIME kernelTime   = {};
     90    FILETIME userTime     = {};
     91 
     92    // Note this will not give accurate results if the current thread is
     93    // scheduled for less than the tick rate, which is often 15 ms. In that
     94    // case, GetProcessTimes will not return different values, making it
     95    // possible to end up with 0 ms for a process that takes 93% of a core
     96    // (14/15 ms)!  An alternative is QueryProcessCycleTime but there is no
     97    // simple way to convert cycles back to seconds, and on top of that, it's
     98    // not supported pre-Windows Vista.
     99 
    100    // Returns 100-ns intervals, so we want to divide by 1e7 to get seconds
    101    GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime);
    102 
    103    ULARGE_INTEGER kernelInt64;
    104    kernelInt64.LowPart      = kernelTime.dwLowDateTime;
    105    kernelInt64.HighPart     = kernelTime.dwHighDateTime;
    106    double systemTimeSeconds = static_cast<double>(kernelInt64.QuadPart) * 1e-7;
    107 
    108    ULARGE_INTEGER userInt64;
    109    userInt64.LowPart      = userTime.dwLowDateTime;
    110    userInt64.HighPart     = userTime.dwHighDateTime;
    111    double userTimeSeconds = static_cast<double>(userInt64.QuadPart) * 1e-7;
    112 
    113    return systemTimeSeconds + userTimeSeconds;
    114 }
    115 
    116 bool IsDirectory(const char *filename)
    117 {
    118    WIN32_FILE_ATTRIBUTE_DATA fileInformation;
    119 
    120    BOOL result =
    121        GetFileAttributesExW(Widen(filename).c_str(), GetFileExInfoStandard, &fileInformation);
    122    if (result)
    123    {
    124        DWORD attribs = fileInformation.dwFileAttributes;
    125        return (attribs != INVALID_FILE_ATTRIBUTES) && ((attribs & FILE_ATTRIBUTE_DIRECTORY) > 0);
    126    }
    127 
    128    return false;
    129 }
    130 
    131 bool IsDebuggerAttached()
    132 {
    133    return !!::IsDebuggerPresent();
    134 }
    135 
    136 void BreakDebugger()
    137 {
    138    __debugbreak();
    139 }
    140 
    141 const char *GetExecutableExtension()
    142 {
    143    return ".exe";
    144 }
    145 
    146 char GetPathSeparator()
    147 {
    148    return '\\';
    149 }
    150 
    151 std::string GetModuleDirectory()
    152 {
    153 // GetModuleHandleEx is unavailable on UWP
    154 #if !defined(ANGLE_IS_WINUWP)
    155    static int placeholderSymbol = 0;
    156    HMODULE module               = nullptr;
    157    if (GetModuleHandleExW(
    158            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
    159            reinterpret_cast<LPCWSTR>(&placeholderSymbol), &module))
    160    {
    161        return GetDirectory(module);
    162    }
    163 #endif
    164    return GetDirectory(nullptr);
    165 }
    166 
    167 std::string GetRootDirectory()
    168 {
    169    return "C:\\";
    170 }
    171 
    172 Optional<std::string> GetTempDirectory()
    173 {
    174    char tempDirOut[MAX_PATH + 1];
    175    GetTempPathA(MAX_PATH + 1, tempDirOut);
    176    std::string tempDir = std::string(tempDirOut);
    177 
    178    if (tempDir.length() < 0 || tempDir.length() > MAX_PATH)
    179    {
    180        return Optional<std::string>::Invalid();
    181    }
    182 
    183    if (tempDir.length() > 0 && tempDir.back() == '\\')
    184    {
    185        tempDir.pop_back();
    186    }
    187 
    188    return tempDir;
    189 }
    190 
    191 Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory)
    192 {
    193    char fileName[MAX_PATH + 1];
    194    if (GetTempFileNameA(directory.c_str(), "ANGLE", 0, fileName) == 0)
    195        return Optional<std::string>::Invalid();
    196 
    197    return std::string(fileName);
    198 }
    199 
    200 std::string GetLibraryPath(void *libraryHandle)
    201 {
    202    if (!libraryHandle)
    203    {
    204        return "";
    205    }
    206 
    207    std::array<wchar_t, MAX_PATH> buffer;
    208    if (GetModuleFileNameW(reinterpret_cast<HMODULE>(libraryHandle), buffer.data(),
    209                           buffer.size()) == 0)
    210    {
    211        return "";
    212    }
    213 
    214    return Narrow(buffer.data());
    215 }
    216 
    217 void *GetLibrarySymbol(void *libraryHandle, const char *symbolName)
    218 {
    219    if (!libraryHandle)
    220    {
    221        fprintf(stderr, "Module was not loaded\n");
    222        return nullptr;
    223    }
    224 
    225    return reinterpret_cast<void *>(
    226        GetProcAddress(reinterpret_cast<HMODULE>(libraryHandle), symbolName));
    227 }
    228 
    229 void CloseSystemLibrary(void *libraryHandle)
    230 {
    231    if (libraryHandle)
    232    {
    233        FreeLibrary(reinterpret_cast<HMODULE>(libraryHandle));
    234    }
    235 }
    236 std::string Narrow(const std::wstring_view &utf16)
    237 {
    238    if (utf16.empty())
    239    {
    240        return {};
    241    }
    242    int requiredSize = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()),
    243                                           nullptr, 0, nullptr, nullptr);
    244    std::string utf8(requiredSize, '\0');
    245    WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0],
    246                        requiredSize, nullptr, nullptr);
    247    return utf8;
    248 }
    249 
    250 std::wstring Widen(const std::string_view &utf8)
    251 {
    252    if (utf8.empty())
    253    {
    254        return {};
    255    }
    256    int requiredSize =
    257        MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
    258    std::wstring utf16(requiredSize, L'\0');
    259    MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0],
    260                        requiredSize);
    261    return utf16;
    262 }
    263 
    264 }  // namespace angle