⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 version_info.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:
    return *this;
}

inline VsStringFileInfo::const_iterator::class_type VsStringFileInfo::const_iterator::operator ++(int)
{
    const_iterator  ret(*this);

    operator ++();

    return ret;
}

inline VsStringTable VsStringFileInfo::const_iterator::operator *() const
{
    StringTable_hdr const* strtbl = static_cast<StringTable_hdr const*>(m_p);

    return VsStringTable(strtbl);
}

inline ws_bool_t VsStringFileInfo::const_iterator::operator ==(class_type const& rhs) const
{
    return m_p == rhs.m_p;
}

inline ws_bool_t VsStringFileInfo::const_iterator::operator !=(class_type const& rhs) const
{
    return !operator ==(rhs);
}

inline VsStringFileInfo::const_iterator VsStringFileInfo::begin() const
{
    return const_iterator(m_vars);
}

inline VsStringFileInfo::const_iterator VsStringFileInfo::end() const
{
    return const_iterator(rounded_ptr(m_p, m_p->wLength, 4));
}

inline /* ss_explicit_k */ version_info::version_info(ws_char_a_t const* moduleName)
    : m_hdr(retrieve_module_info_block_(moduleName))
    , m_key(calc_key_(m_hdr))
    , m_ffi(calc_ffi_(m_key))
    , m_children(calc_children_(m_ffi))
    , m_sfi(NULL)
    , m_vfi(NULL)
{
    init_();
}

inline /* ss_explicit_k */ version_info::version_info(ws_char_w_t const* moduleName)
    : m_hdr(retrieve_module_info_block_(moduleName))
    , m_key(calc_key_(m_hdr))
    , m_ffi(calc_ffi_(m_key))
    , m_children(calc_children_(m_ffi))
    , m_sfi(NULL)
    , m_vfi(NULL)
{
    init_();
}

inline version_info::~version_info() stlsoft_throw_0()
{
    allocator_type  allocator;

    allocator.deallocate(const_cast<ws_byte_t*>(sap_cast<ws_byte_t const*>(m_hdr)));
}

inline ws_size_t version_info::Length() const
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == m_hdr)
    {
        return 0;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != m_hdr);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

    return *(sap_cast<WORD const*>(m_hdr) + 0);
}

inline ws_size_t version_info::ValueLength() const
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == m_hdr)
    {
        return 0;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != m_hdr);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

    return *(sap_cast<WORD const*>(m_hdr) + 1);
}

inline ws_size_t version_info::Type() const
{
    WINSTL_ASSERT(NULL != m_hdr);

    return *(sap_cast<WORD const*>(m_hdr) + 2);
}

inline wchar_t const* version_info::Key() const
{
    WINSTL_ASSERT(NULL != m_hdr);

    return m_key;
}

inline fixed_file_info version_info::FixedFileInfo() const
{
    WINSTL_ASSERT(NULL != m_hdr);

    return fixed_file_info(m_ffi);
}

inline ws_bool_t version_info::HasVarFileInfo() const
{
    return NULL != m_vfi;
}

inline VsVarFileInfo version_info::VarFileInfo() const
{
    WINSTL_ASSERT(NULL != m_vfi);

    return VsVarFileInfo(m_vfi);
}

inline ws_bool_t version_info::HasStringFileInfo() const
{
    return NULL != m_sfi;
}

inline VsStringFileInfo version_info::StringFileInfo() const
{
    WINSTL_ASSERT(NULL != m_sfi);

    return VsStringFileInfo(m_sfi);
}

inline /* static */ VS_VERSIONINFO_hdr const* version_info::retrieve_module_info_block_(ws_char_a_t const* moduleName)
{
#ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
    ws_char_a_t                         buffer[1 + _MAX_PATH];
#else /* ?WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
    basic_file_path_buffer<ws_char_a_t> buffer;
#endif /* WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */

    if( NULL == moduleName &&
#ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
        0 != ::GetModuleFileNameA(NULL, &buffer[0], STLSOFT_NUM_ELEMENTS(buffer)))
#else /* ?WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
        0 != ::GetModuleFileNameA(NULL, &buffer[0], buffer.size()))
#endif /* WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
    {
        moduleName = stlsoft_ns_qual(c_str_ptr)(buffer);
    }
    else
    {
        // Must verify it can be loaded, i.e. is a 32-bit resource
        //
        // TODO: Work out how to support 16-bit versions
        HINSTANCE   hinst   =   ::LoadLibraryExA(moduleName, NULL, LOAD_LIBRARY_AS_DATAFILE);

        if(NULL == hinst)
        {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
            STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
            return NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
        }
        else
        {
            ::FreeLibrary(hinst);
        }
    }

    allocator_type      allocator;
    ws_dword_t          cb  =   ::GetFileVersionInfoSizeA(const_cast<ws_char_a_t*>(moduleName), NULL);
    void                *pv =   (0 == cb) ? NULL : allocator.allocate(cb);

#if !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    // If bad_alloc will not be thrown, then we need to check for NULL, but only act on it
    // if cb is non-zero
    if( 0 != cb &&
        pv == NULL)
    {
        ::GetLastError();

        return NULL;
    }
#endif /* !STLSOFT_CF_THROW_BAD_ALLOC */

    WINSTL_ASSERT(0 == cb || pv != NULL);

    if( 0 == cb ||
        !::GetFileVersionInfoA(const_cast<ws_char_a_t*>(moduleName), 0, cb, pv))
    {
        allocator.deallocate(static_cast<ws_byte_t*>(pv), cb);

#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
        STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
        return NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
    }

    WINSTL_ASSERT(pv != NULL);

    return static_cast<VS_VERSIONINFO_hdr*>(pv);
}

inline /* static */ VS_VERSIONINFO_hdr const* version_info::retrieve_module_info_block_(ws_char_w_t const* moduleName)
{
#ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
    ws_char_w_t                         buffer[1 + _MAX_PATH];
#else /* ?WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
    basic_file_path_buffer<ws_char_w_t> buffer;
#endif /* WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */

    if( NULL == moduleName &&
#ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
        0 != ::GetModuleFileNameW(NULL, &buffer[0], STLSOFT_NUM_ELEMENTS(buffer)))
#else /* ?WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
        0 != ::GetModuleFileNameW(NULL, &buffer[0], buffer.size()))
#endif /* WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER */
    {
        moduleName = stlsoft_ns_qual(c_str_ptr)(buffer);
    }
    else
    {
        // Must verify it can be loaded, i.e. is a 32-bit resource
        //
        // TODO: Work out how to support 16-bit versions
        HINSTANCE   hinst   =   ::LoadLibraryExW(moduleName, NULL, LOAD_LIBRARY_AS_DATAFILE);

        if(NULL == hinst)
        {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
            STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
            return NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
        }
        else
        {
            ::FreeLibrary(hinst);
        }
    }

    allocator_type  allocator;
    ws_dword_t      cb  =   ::GetFileVersionInfoSizeW(const_cast<ws_char_w_t*>(moduleName), NULL);
    void            *pv =   (0 == cb) ? NULL : allocator.allocate(cb);

#ifndef STLSOFT_CF_THROW_BAD_ALLOC
    if( 0 != cb &&
        pv == NULL)
    {
        return NULL;
    }
#endif /* !STLSOFT_CF_THROW_BAD_ALLOC */

    if( 0 == cb ||
        !::GetFileVersionInfoW(const_cast<ws_char_w_t*>(moduleName), 0, cb, pv))
    {
        allocator.deallocate(static_cast<ws_byte_t*>(pv), cb);

#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
        STLSOFT_THROW_X((version_info_exception("Could not elicit version information from module", ::GetLastError())));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
        pv = NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
    }

    return static_cast<VS_VERSIONINFO_hdr*>(pv);
}

inline /* static */ wchar_t const* version_info::calc_key_(void const* pv)
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == pv)
    {
        return NULL;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != pv);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

#ifdef _DEBUG
    // Bit of 16-bit resource code here
    //
    // This is reasonably safe, because if it is unicode, then the n-limited string comparison
    // will simply return non-0, rather than potentially going off and crashing
    {
        char const* keyA = reinterpret_cast<char const*>(static_cast<WORD const*>(pv) + 2);

        if(0 == ::strncmp("VS_VERSION_INFO", keyA, 16))
        {
            keyA = NULL;
        }
    }
#endif /* _DEBUG */

    wchar_t const* key = reinterpret_cast<wchar_t const*>(static_cast<WORD const*>(pv) + 3);

    WINSTL_ASSERT(0 == ::wcsncmp(L"VS_VERSION_INFO", key, 16));

    return key;
}

inline /* static */ VS_FIXEDFILEINFO const* version_info::calc_ffi_(wchar_t const* key)
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == key)
    {
        return NULL;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != key);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

    return sap_cast<VS_FIXEDFILEINFO const*>(rounded_ptr(&key[1 + ::wcslen(key)], 4));
}

inline /* static */ WORD const* version_info::calc_children_(VS_FIXEDFILEINFO const* ffi)
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == ffi)
    {
        return NULL;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != ffi);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

    return sap_cast<WORD const*>(rounded_ptr(&ffi[1], 4));
}

inline void version_info::init_()
{
#if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
    !defined(STLSOFT_CF_THROW_BAD_ALLOC)
    if(NULL == m_hdr)
    {
        return;
    }
#else /* ? exceptions */
    WINSTL_ASSERT(NULL != m_hdr);
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT || !STLSOFT_CF_THROW_BAD_ALLOC */

#ifdef _DEBUG
    // Check that ffi is the same as the pointer returned from VerQueryValue("\\");
    VS_FIXEDFILEINFO    *ffi    =   NULL;
    UINT                cchInfo =   0;

    WINSTL_ASSERT(::VerQueryValueA(const_cast<VS_VERSIONINFO_hdr*>(m_hdr), "\\", reinterpret_cast<void**>(&ffi), &cchInfo));
    WINSTL_ASSERT(ffi == m_ffi);
#endif /* _DEBUG */

    // Now we must parse the children.

    void const  *       pv  =   m_children;
    void const  *const  end =   rounded_ptr(m_hdr, m_hdr->wLength, 4);

    WINSTL_ASSERT(ptr_byte_diff(end, pv) >= 0);

    for(; pv != end; )
    {
        union
        {
            void const                  *pv_;
            StringFileInfo_hdr const    *psfi;
            VarFileInfo_hdr const       *pvfi;
        } u;

        u.pv_ = pv;

        WINSTL_ASSERT(ptr_byte_diff(pv, m_hdr) < m_hdr->wLength);

        if(0 == ::wcsncmp(u.psfi->szKey, L"StringFileInfo", 15))
        {
            WINSTL_ASSERT(NULL == m_sfi);

            m_sfi = u.psfi;

            pv = rounded_ptr(pv, u.psfi->wLength, 4);
        }
        else if(0 == ::wcsncmp(u.psfi->szKey, L"VarFileInfo", 12))
        {
            WINSTL_ASSERT(NULL == m_vfi);

            m_vfi = u.pvfi;

            pv = rounded_ptr(pv, u.pvfi->wLength, 4);
        }
        else
        {
#ifdef STLSOFT_UNITTEST
            ::wprintf(L"Unexpected contents of VS_VERSIONINFO children. pv: 0x%08x; Key: %.*s\n", pv, 20, u.psfi->szKey);
#endif /* STLSOFT_UNITTEST */

            WINSTL_MESSAGE_ASSERT("Unexpected contents of VS_VERSIONINFO children", NULL == m_vfi);

            break;
        }

        WINSTL_ASSERT(ptr_byte_diff(pv, end) <= 0);
    }

    WINSTL_ASSERT(ptr_byte_diff(pv, m_hdr) == m_hdr->wLength);

#ifdef _DEBUG
    fixed_file_info fixedInfo = FixedFileInfo();

    ws_uint16_t    j   =   fixedInfo.FileVerMajor();
    ws_uint16_t    n   =   fixedInfo.FileVerMinor();
    ws_uint16_t    r   =   fixedInfo.FileVerRevision();
    ws_uint16_t    b   =   fixedInfo.FileVerBuild();

    STLSOFT_SUPPRESS_UNUSED(j);
    STLSOFT_SUPPRESS_UNUSED(n);
    STLSOFT_SUPPRESS_UNUSED(r);
    STLSOFT_SUPPRESS_UNUSED(b);
#endif /* _DEBUG */
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _WINSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace winstl
# else
} // namespace winstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_WINSTL_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* WINSTL_INCL_WINSTL_SYSTEM_HPP_VERSION_INFO */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -