VS_FIXEDFILEINFO getFixedFileInfo()

in src/shared/WindowsVersion.cc [98:137]


VS_FIXEDFILEINFO getFixedFileInfo(const std::wstring &path) {
    // version.dll is not a conventional KnownDll, so if we link to it, there's
    // a danger of accidentally loading a malicious DLL.  In a more typical
    // application, perhaps we'd guard against this security issue by
    // controlling which directories this code runs in (e.g. *not* the
    // "Downloads" directory), but that's harder for the winpty library.
    OsModule versionDll(
        (getSystemDirectory() + L"\\version.dll").c_str(),
        OsModule::LoadErrorBehavior::Throw);
    GET_VERSION_DLL_API(GetFileVersionInfoSizeW);
    GET_VERSION_DLL_API(GetFileVersionInfoW);
    GET_VERSION_DLL_API(VerQueryValueW);
    DWORD size = pGetFileVersionInfoSizeW(path.c_str(), nullptr);
    if (!size) {
        // I see ERROR_FILE_NOT_FOUND on Win7 and
        // ERROR_RESOURCE_DATA_NOT_FOUND on WinXP.
        if (GetLastError() == ERROR_FILE_NOT_FOUND ||
                GetLastError() == ERROR_RESOURCE_DATA_NOT_FOUND) {
            throw ModuleNotFound();
        } else {
            throwWindowsError(
                (L"GetFileVersionInfoSizeW failed on " + path).c_str());
        }
    }
    std::unique_ptr<char[]> versionBuffer(new char[size]);
    if (!pGetFileVersionInfoW(path.c_str(), 0, size, versionBuffer.get())) {
        throwWindowsError((L"GetFileVersionInfoW failed on " + path).c_str());
    }
    VS_FIXEDFILEINFO *versionInfo = nullptr;
    UINT versionInfoSize = 0;
    if (!pVerQueryValueW(
                versionBuffer.get(), L"\\",
                reinterpret_cast<void**>(&versionInfo), &versionInfoSize) ||
            versionInfo == nullptr ||
            versionInfoSize != sizeof(VS_FIXEDFILEINFO) ||
            versionInfo->dwSignature != 0xFEEF04BD) {
        throwWinptyException((L"VerQueryValueW failed on " + path).c_str());
    }
    return *versionInfo;
}