00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_VERSION_INFO
00049 #define WINSTL_INCL_WINSTL_SYSTEM_HPP_VERSION_INFO
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define WINSTL_VER_WINSTL_SYSTEM_HPP_VERSION_INFO_MAJOR 5
00053 # define WINSTL_VER_WINSTL_SYSTEM_HPP_VERSION_INFO_MINOR 2
00054 # define WINSTL_VER_WINSTL_SYSTEM_HPP_VERSION_INFO_REVISION 8
00055 # define WINSTL_VER_WINSTL_SYSTEM_HPP_VERSION_INFO_EDIT 126
00056 #endif
00057
00058
00059
00060
00061
00062 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00063 # include <winstl/winstl.h>
00064 #endif
00065 #ifndef WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS
00066 # include <winstl/error/exceptions.hpp>
00067 #endif
00068 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00069 _MSC_VER < 1200
00070 # if defined(UNICODE) || \
00071 defined(_UNICODE)
00072 # error winstl::version_info is not supported on Visual C++ 5.0 (or previous) with UNICODE compilations
00073 # endif
00074 # define WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
00075 #else
00076 # ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
00077 # include <winstl/filesystem/file_path_buffer.hpp>
00078 # endif
00079 #endif
00080 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00081 # include <winstl/memory/processheap_allocator.hpp>
00082 #endif
00083 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
00084 # include <stlsoft/conversion/sap_cast.hpp>
00085 #endif
00086 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00087 # include <stlsoft/shims/access/string.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00090 # include <stlsoft/util/std/iterator_helper.hpp>
00091 #endif
00092 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00093 # include <stlsoft/collections/util/collections.hpp>
00094 #endif
00095
00096 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00097 # include <stdexcept>
00098 #endif
00099
00100 #ifndef STLSOFT_INCL_H_WCHAR
00101 # define STLSOFT_INCL_H_WCHAR
00102 # include <wchar.h>
00103 #endif
00104
00105 #ifdef STLSOFT_UNITTEST
00106 # include <stdio.h>
00107 #endif
00108
00109
00110
00111
00112
00113 #ifndef _WINSTL_NO_NAMESPACE
00114 # if defined(_STLSOFT_NO_NAMESPACE) || \
00115 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00116
00117 namespace winstl
00118 {
00119 # else
00120
00121
00122 namespace stlsoft
00123 {
00124
00125 namespace winstl_project
00126 {
00127
00128 # endif
00129 #endif
00130
00131
00132
00133
00134
00135 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00136
00137
00138
00139
00140
00141 template<ss_typename_param_k T>
00142 struct hdr
00143 {
00144 template<int N>
00145 struct hdr_
00146 {
00147 WORD wLength;
00148 WORD wValueLength;
00149 WORD wType;
00150 WCHAR szKey[1];
00151 };
00152
00153 };
00154
00155 typedef hdr<int>::hdr_<1> VS_VERSIONINFO_hdr;
00156 typedef hdr<int>::hdr_<2> StringFileInfo_hdr;
00157 typedef hdr<int>::hdr_<3> VarFileInfo_hdr;
00158 typedef hdr<int>::hdr_<4> Var_hdr;
00159 typedef hdr<int>::hdr_<5> StringTable_hdr;
00160 typedef hdr<int>::hdr_<6> String_hdr;
00161
00162 template<ss_typename_param_k T>
00163 T* rounded_ptr(T* p, ss_size_t n)
00164 {
00165 union
00166 {
00167 T* p;
00168 ss_size_t cb;
00169 } u;
00170
00171 u.p = p;
00172
00173 u.cb = ((n - 1) + u.cb) & ~(n- 1);
00174
00175 WINSTL_ASSERT(ptr_byte_diff(u.p, p) >= 0);
00176
00177 return u.p;
00178 }
00179
00180 template<ss_typename_param_k T>
00181 T* rounded_ptr(T* p, ss_ptrdiff_t byteOffset, ss_size_t n)
00182 {
00183
00184 #if defined(STLSOFT_COMPILER_IS_BORLAND)
00185 void const* pv = &byteOffset[(char*)p];
00186 #else
00187 void const* pv = ptr_byte_offset(p, byteOffset);
00188 #endif
00189
00190 WINSTL_ASSERT(((char*)pv - (char*)p) == byteOffset);
00191
00192 T* p_ = static_cast<T*>(pv);
00193 T* r = rounded_ptr(p_, n);
00194
00195 #ifdef STLSOFT_COMPILER_IS_BORLAND
00196 STLSOFT_SUPPRESS_UNUSED(p);
00197 STLSOFT_SUPPRESS_UNUSED(byteOffset);
00198 #endif
00199
00200 WINSTL_ASSERT(ptr_byte_diff(r, p_) >= 0);
00201
00202 return r;
00203 }
00204
00205 #endif
00206
00207
00208
00209
00210
00211 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00212
00216 class version_info_exception
00217 : public windows_exception
00218 {
00221 public:
00222 typedef windows_exception parent_class_type;
00223 typedef version_info_exception class_type;
00225
00228 public:
00229 version_info_exception(char const* reason, error_code_type err)
00230 : parent_class_type(reason, err)
00231 {}
00233 };
00234 #endif
00235
00240 class fixed_file_info
00241 {
00242 typedef fixed_file_info class_type;
00243
00244 public:
00246 fixed_file_info(VS_FIXEDFILEINFO const* ffi);
00247
00248 public:
00249 ws_uint16_t ApiVerHigh() const;
00250 ws_uint16_t ApiVerLow() const;
00251
00253 ws_uint16_t FileVerMajor() const;
00255 ws_uint16_t FileVerMinor() const;
00257 ws_uint16_t FileVerRevision() const;
00259 ws_uint16_t FileVerBuild() const;
00260
00262 ws_uint16_t ProductVerMajor() const;
00264 ws_uint16_t ProductVerMinor() const;
00266 ws_uint16_t ProductVerRevision() const;
00268 ws_uint16_t ProductVerBuild() const;
00269
00271 ws_uint32_t FileFlagsMask() const;
00273 ws_uint32_t FileFlags() const;
00274
00276 ws_uint32_t FileOS() const;
00277
00279 ws_uint32_t FileType() const;
00281 ws_uint32_t FileSubtype() const;
00282
00284 FILETIME const& FileDateTime() const;
00285
00286 private:
00287 static FILETIME calc_FileDateTime_(VS_FIXEDFILEINFO const* ffi);
00288
00289 private:
00290 VS_FIXEDFILEINFO const* const m_ffi;
00291 FILETIME const m_fileDateTime;
00292
00293 private:
00294 class_type& operator =(class_type const&);
00295 };
00296
00301 class VsVar
00302 {
00303 public:
00305 typedef VsVar class_type;
00306
00308 struct LangCodePage
00309 {
00311 ss_uint16_t language;
00313 ss_uint16_t codePage;
00314 };
00315 public:
00317 VsVar(Var_hdr const* p);
00318
00320 ss_size_t length() const;
00321
00323 LangCodePage const& operator [](ss_size_t index) const;
00324
00325 private:
00326 Var_hdr const* m_p;
00327 LangCodePage const* m_values;
00328 };
00329
00334 class VsString
00335 {
00336 public:
00338 typedef VsString class_type;
00339
00340 public:
00342 VsString(String_hdr const* p);
00343
00345 wchar_t const* name() const;
00346
00348 wchar_t const* value() const;
00349
00350 private:
00351 wchar_t const* m_name;
00352 wchar_t const* m_value;
00353 };
00354
00359 class VsStringTable
00360 : public stlsoft_ns_qual(stl_collection_tag)
00361 {
00362 public:
00364 typedef VsStringTable class_type;
00366 typedef VsString value_type;
00367
00368 public:
00370 VsStringTable(StringTable_hdr const* p);
00371
00373 wchar_t const* Key() const;
00374
00376 class const_iterator
00377 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(forward_iterator_tag)
00378 , value_type
00379 , ws_ptrdiff_t
00380 , void
00381 , value_type
00382 >
00383 {
00384 public:
00386 typedef const_iterator class_type;
00388 typedef VsString value_type;
00389
00390 public:
00392 const_iterator(void const* p);
00393
00395 class_type& operator ++();
00396
00398 class_type operator ++(int);
00399
00400 value_type operator *() const;
00401
00402 ws_bool_t operator ==(class_type const& rhs) const;
00403
00404 ws_bool_t operator !=(class_type const& rhs) const;
00405
00406 private:
00407 void const* m_p;
00408 };
00409
00410 const_iterator begin() const;
00411
00412 const_iterator end() const;
00413
00414 private:
00415 StringTable_hdr const* m_p;
00416 void const* m_strings;
00417 };
00418
00423 class VsVarFileInfo
00424 : public stlsoft_ns_qual(stl_collection_tag)
00425 {
00426 public:
00428 typedef VsVarFileInfo class_type;
00430 typedef VsVar value_type;
00431
00432 public:
00436 VsVarFileInfo(VarFileInfo_hdr const* p);
00437
00439 wchar_t const* Key() const;
00440
00442 class const_iterator
00443 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(forward_iterator_tag)
00444 , value_type
00445 , ws_ptrdiff_t
00446 , void
00447 , value_type
00448 >
00449 {
00450 public:
00452 typedef const_iterator class_type;
00453
00454 public:
00456 const_iterator(void const* p);
00457
00459 class_type& operator ++();
00460
00462 class_type operator ++(int);
00463
00464 value_type operator *() const;
00465
00466 ws_bool_t operator ==(class_type const& rhs) const;
00467
00468 ws_bool_t operator !=(class_type const& rhs) const;
00469
00470 private:
00471 void const* m_p;
00472 };
00473
00474 const_iterator begin() const;
00475
00476 const_iterator end() const;
00477
00478 private:
00479 VarFileInfo_hdr const* m_p;
00480 void const* m_vars;
00481 };
00482
00487 class VsStringFileInfo
00488 : public stlsoft_ns_qual(stl_collection_tag)
00489 {
00490 public:
00492 typedef VsStringFileInfo class_type;
00494 typedef VsStringTable value_type;
00495 public:
00497 VsStringFileInfo(StringFileInfo_hdr const* p);
00498
00500 wchar_t const* Key() const;
00501
00505 class const_iterator
00506 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(forward_iterator_tag)
00507 , value_type
00508 , ws_ptrdiff_t
00509 , void
00510 , value_type
00511 >
00512 {
00513 public:
00515 typedef const_iterator class_type;
00517 typedef VsStringTable value_type;
00518
00519 public:
00521 const_iterator(void const* p);
00522
00524 class_type& operator ++();
00525
00527 class_type operator ++(int);
00528
00529 value_type operator *() const;
00530
00531 ws_bool_t operator ==(class_type const& rhs) const;
00532
00533 ws_bool_t operator !=(class_type const& rhs) const;
00534
00535 private:
00536 void const* m_p;
00537 };
00538
00539 const_iterator begin() const;
00540
00541 const_iterator end() const;
00542
00543 private:
00544 StringFileInfo_hdr const* m_p;
00545 void const* m_vars;
00546 };
00547
00548
00553 class version_info
00554 {
00555 private:
00556 typedef processheap_allocator<ws_byte_t> allocator_type;
00557 public:
00559 typedef version_info class_type;
00560
00563 public:
00567 ss_explicit_k version_info(ws_char_a_t const* moduleName);
00568
00572 ss_explicit_k version_info(ws_char_w_t const* moduleName);
00573
00575 ~version_info() stlsoft_throw_0();
00577
00580 public:
00582 ws_size_t Length() const;
00583
00585 ws_size_t ValueLength() const;
00586
00588 ws_size_t Type() const;
00589
00591 wchar_t const* Key() const;
00592
00594 fixed_file_info FixedFileInfo() const;
00595
00597 ws_bool_t HasVarFileInfo() const;
00598
00600 VsVarFileInfo VarFileInfo() const;
00601
00603 ws_bool_t HasStringFileInfo() const;
00604
00606 VsStringFileInfo StringFileInfo() const;
00608
00609 private:
00610 static VS_VERSIONINFO_hdr const* retrieve_module_info_block_(ws_char_a_t const* moduleName);
00611
00612 static VS_VERSIONINFO_hdr const* retrieve_module_info_block_(ws_char_w_t const* moduleName);
00613
00614 static wchar_t const* calc_key_(void const* pv);
00615
00616 static VS_FIXEDFILEINFO const* calc_ffi_(wchar_t const* key);
00617
00618 static WORD const* calc_children_(VS_FIXEDFILEINFO const* ffi);
00619
00620 private:
00621 void init_();
00622
00623 private:
00624 VS_VERSIONINFO_hdr const* const m_hdr;
00625 wchar_t const* const m_key;
00626 VS_FIXEDFILEINFO const* const m_ffi;
00627 WORD const* const m_children;
00628 StringFileInfo_hdr const* m_sfi;
00629 VarFileInfo_hdr const* m_vfi;
00630
00631
00632 private:
00633 version_info(class_type const& rhs);
00634 class_type& operator =(class_type const& rhs);
00635 };
00636
00638
00639
00640 #ifdef STLSOFT_UNITTEST
00641 # include "./unittest/version_info_unittest_.h"
00642 #endif
00643
00644
00645
00646
00647
00648 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00649
00650 inline FILETIME fixed_file_info::calc_FileDateTime_(VS_FIXEDFILEINFO const* ffi)
00651 {
00652 FILETIME ft = { ffi->dwFileDateLS, ffi->dwFileDateMS };
00653
00654 return ft;
00655 }
00656
00657 inline fixed_file_info::fixed_file_info(VS_FIXEDFILEINFO const* ffi)
00658 : m_ffi(ffi)
00659 , m_fileDateTime(calc_FileDateTime_(ffi))
00660 {}
00661
00662 inline ws_uint16_t fixed_file_info::ApiVerHigh() const
00663 {
00664 return HIWORD(m_ffi->dwStrucVersion);
00665 }
00666
00667 inline ws_uint16_t fixed_file_info::ApiVerLow() const
00668 {
00669 return LOWORD(m_ffi->dwStrucVersion);
00670 }
00671
00672 inline ws_uint16_t fixed_file_info::FileVerMajor() const
00673 {
00674 return HIWORD(m_ffi->dwFileVersionMS);
00675 }
00676
00677 inline ws_uint16_t fixed_file_info::FileVerMinor() const
00678 {
00679 return LOWORD(m_ffi->dwFileVersionMS);
00680 }
00681
00682 inline ws_uint16_t fixed_file_info::FileVerRevision() const
00683 {
00684 return HIWORD(m_ffi->dwFileVersionLS);
00685 }
00686
00687 inline ws_uint16_t fixed_file_info::FileVerBuild() const
00688 {
00689 return LOWORD(m_ffi->dwFileVersionLS);
00690 }
00691
00692 inline ws_uint16_t fixed_file_info::ProductVerMajor() const
00693 {
00694 return HIWORD(m_ffi->dwProductVersionMS);
00695 }
00696
00697 inline ws_uint16_t fixed_file_info::ProductVerMinor() const
00698 {
00699 return LOWORD(m_ffi->dwProductVersionMS);
00700 }
00701
00702 inline ws_uint16_t fixed_file_info::ProductVerRevision() const
00703 {
00704 return HIWORD(m_ffi->dwProductVersionLS);
00705 }
00706
00707 inline ws_uint16_t fixed_file_info::ProductVerBuild() const
00708 {
00709 return LOWORD(m_ffi->dwProductVersionLS);
00710 }
00711
00712 inline ws_uint32_t fixed_file_info::FileFlagsMask() const
00713 {
00714 return m_ffi->dwFileFlagsMask;
00715 }
00716
00717 inline ws_uint32_t fixed_file_info::FileFlags() const
00718 {
00719 return m_ffi->dwFileFlags;
00720 }
00721
00722 inline ws_uint32_t fixed_file_info::FileOS() const
00723 {
00724 return m_ffi->dwFileOS;
00725 }
00726
00727 inline ws_uint32_t fixed_file_info::FileType() const
00728 {
00729 return m_ffi->dwFileType;
00730 }
00731
00732 inline ws_uint32_t fixed_file_info::FileSubtype() const
00733 {
00734 return m_ffi->dwFileSubtype;
00735 }
00736
00737 inline FILETIME const& fixed_file_info::FileDateTime() const
00738 {
00739 return m_fileDateTime;
00740 }
00741
00742 inline VsVar::VsVar(Var_hdr const* p)
00743 : m_p(p)
00744 {
00745 WINSTL_ASSERT(0 == ::wcsncmp(p->szKey, L"Translation", 12));
00746
00747 m_values = sap_cast<LangCodePage const*>(rounded_ptr(&p->szKey[1 + ::wcslen(p->szKey)], 4));
00748 }
00749
00750 inline ss_size_t VsVar::length() const
00751 {
00752 return m_p->wValueLength / sizeof(LangCodePage);
00753 }
00754
00755 inline VsVar::LangCodePage const& VsVar::operator [](ss_size_t index) const
00756 {
00757 return m_values[index];
00758 }
00759
00760 inline VsString::VsString(String_hdr const* p)
00761 : m_name(p->szKey)
00762 {
00763 m_value = sap_cast<wchar_t const*>(rounded_ptr(&p->szKey[1 + ::wcslen(p->szKey)], 4));
00764 }
00765
00766 inline wchar_t const* VsString::name() const
00767 {
00768 return m_name;
00769 }
00770
00771 inline wchar_t const* VsString::value() const
00772 {
00773 return m_value;
00774 }
00775
00776 inline VsStringTable::VsStringTable(StringTable_hdr const* p)
00777 : m_p(p)
00778 {
00779 m_strings = rounded_ptr(&p->szKey[1 + ::wcslen(p->szKey)], 4);
00780 }
00781
00782 inline wchar_t const* VsStringTable::Key() const
00783 {
00784 WINSTL_ASSERT(NULL != m_p);
00785
00786 return m_p->szKey;
00787 }
00788
00789 inline VsStringTable::const_iterator::const_iterator(void const* p)
00790 : m_p(p)
00791 {}
00792
00793 inline VsStringTable::const_iterator::class_type& VsStringTable::const_iterator::operator ++()
00794 {
00795 String_hdr const* str = static_cast<String_hdr const*>(m_p);
00796
00797 m_p = rounded_ptr(m_p, str->wLength, 4);
00798
00799 return *this;
00800 }
00801
00802 inline VsStringTable::const_iterator::class_type VsStringTable::const_iterator::operator ++(int)
00803 {
00804 const_iterator ret(*this);
00805
00806 operator ++();
00807
00808 return ret;
00809 }
00810
00811 inline VsString VsStringTable::const_iterator::operator *() const
00812 {
00813 String_hdr const* str = static_cast<String_hdr const*>(m_p);
00814
00815 return VsString(str);
00816 }
00817
00818 inline ws_bool_t VsStringTable::const_iterator::operator ==(VsStringTable::const_iterator::class_type const& rhs) const
00819 {
00820 return m_p == rhs.m_p;
00821 }
00822
00823 inline ws_bool_t VsStringTable::const_iterator::operator !=(VsStringTable::const_iterator::class_type const& rhs) const
00824 {
00825 return !operator ==(rhs);
00826 }
00827
00828 inline VsStringTable::const_iterator VsStringTable::begin() const
00829 {
00830 return const_iterator(m_strings);
00831 }
00832
00833 inline VsStringTable::const_iterator VsStringTable::end() const
00834 {
00835 return const_iterator(rounded_ptr(m_p, m_p->wLength, 4));
00836 }
00837
00838 inline VsVarFileInfo::VsVarFileInfo(VarFileInfo_hdr const* p)
00839 : m_p(p)
00840 {
00841 WINSTL_ASSERT(0 == ::wcsncmp(p->szKey, L"VarFileInfo", 12));
00842
00843 m_vars = rounded_ptr(&p->szKey[1 + ::wcslen(p->szKey)], 4);
00844 }
00845
00846 inline wchar_t const* VsVarFileInfo::Key() const
00847 {
00848 WINSTL_ASSERT(NULL != m_p);
00849
00850 return m_p->szKey;
00851 }
00852
00853 inline VsVarFileInfo::const_iterator::const_iterator(void const* p)
00854 : m_p(p)
00855 {}
00856
00857 inline VsVarFileInfo::const_iterator::class_type& VsVarFileInfo::const_iterator::operator ++()
00858 {
00859 Var_hdr const* var = static_cast<Var_hdr const*>(m_p);
00860
00861 m_p = rounded_ptr(m_p, var->wLength, 4);
00862
00863 return *this;
00864 }
00865
00866 inline VsVarFileInfo::const_iterator::class_type VsVarFileInfo::const_iterator::operator ++(int)
00867 {
00868 const_iterator ret(*this);
00869
00870 operator ++();
00871
00872 return ret;
00873 }
00874
00875 inline VsVar VsVarFileInfo::const_iterator::operator *() const
00876 {
00877 Var_hdr const* var = static_cast<Var_hdr const*>(m_p);
00878
00879 return VsVar(var);
00880 }
00881
00882 inline ws_bool_t VsVarFileInfo::const_iterator::operator ==(class_type const& rhs) const
00883 {
00884 return m_p == rhs.m_p;
00885 }
00886
00887 inline ws_bool_t VsVarFileInfo::const_iterator::operator !=(class_type const& rhs) const
00888 {
00889 return !operator ==(rhs);
00890 }
00891
00892 inline VsVarFileInfo::const_iterator VsVarFileInfo::begin() const
00893 {
00894 return const_iterator(m_vars);
00895 }
00896
00897 inline VsVarFileInfo::const_iterator VsVarFileInfo::end() const
00898 {
00899 return const_iterator(rounded_ptr(m_p, m_p->wLength, 4));
00900 }
00901
00902 inline VsStringFileInfo::VsStringFileInfo(StringFileInfo_hdr const* p)
00903 : m_p(p)
00904 {
00905 WINSTL_ASSERT(0 == ::wcsncmp(p->szKey, L"StringFileInfo", 15));
00906
00907 m_vars = rounded_ptr(&p->szKey[1 + ::wcslen(p->szKey)], 4);
00908 }
00909
00910 inline wchar_t const* VsStringFileInfo::Key() const
00911 {
00912 WINSTL_ASSERT(NULL != m_p);
00913
00914 return m_p->szKey;
00915 }
00916
00917 inline VsStringFileInfo::const_iterator::const_iterator(void const* p)
00918 : m_p(p)
00919 {}
00920
00921 inline VsStringFileInfo::const_iterator::class_type& VsStringFileInfo::const_iterator::operator ++()
00922 {
00923 StringTable_hdr const* strtbl = static_cast<StringTable_hdr const*>(m_p);
00924
00925 m_p = rounded_ptr(m_p, strtbl->wLength, 4);
00926
00927 return *this;
00928 }
00929
00930 inline VsStringFileInfo::const_iterator::class_type VsStringFileInfo::const_iterator::operator ++(int)
00931 {
00932 const_iterator ret(*this);
00933
00934 operator ++();
00935
00936 return ret;
00937 }
00938
00939 inline VsStringTable VsStringFileInfo::const_iterator::operator *() const
00940 {
00941 StringTable_hdr const* strtbl = static_cast<StringTable_hdr const*>(m_p);
00942
00943 return VsStringTable(strtbl);
00944 }
00945
00946 inline ws_bool_t VsStringFileInfo::const_iterator::operator ==(class_type const& rhs) const
00947 {
00948 return m_p == rhs.m_p;
00949 }
00950
00951 inline ws_bool_t VsStringFileInfo::const_iterator::operator !=(class_type const& rhs) const
00952 {
00953 return !operator ==(rhs);
00954 }
00955
00956 inline VsStringFileInfo::const_iterator VsStringFileInfo::begin() const
00957 {
00958 return const_iterator(m_vars);
00959 }
00960
00961 inline VsStringFileInfo::const_iterator VsStringFileInfo::end() const
00962 {
00963 return const_iterator(rounded_ptr(m_p, m_p->wLength, 4));
00964 }
00965
00966 inline version_info::version_info(ws_char_a_t const* moduleName)
00967 : m_hdr(retrieve_module_info_block_(moduleName))
00968 , m_key(calc_key_(m_hdr))
00969 , m_ffi(calc_ffi_(m_key))
00970 , m_children(calc_children_(m_ffi))
00971 , m_sfi(NULL)
00972 , m_vfi(NULL)
00973 {
00974 init_();
00975 }
00976
00977 inline version_info::version_info(ws_char_w_t const* moduleName)
00978 : m_hdr(retrieve_module_info_block_(moduleName))
00979 , m_key(calc_key_(m_hdr))
00980 , m_ffi(calc_ffi_(m_key))
00981 , m_children(calc_children_(m_ffi))
00982 , m_sfi(NULL)
00983 , m_vfi(NULL)
00984 {
00985 init_();
00986 }
00987
00988 inline version_info::~version_info() stlsoft_throw_0()
00989 {
00990 allocator_type allocator;
00991
00992 allocator.deallocate(const_cast<ws_byte_t*>(sap_cast<ws_byte_t const*>(m_hdr)));
00993 }
00994
00995 inline ws_size_t version_info::Length() const
00996 {
00997 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
00998 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
00999 if(NULL == m_hdr)
01000 {
01001 return 0;
01002 }
01003 #else
01004 WINSTL_ASSERT(NULL != m_hdr);
01005 #endif
01006
01007 return *(sap_cast<WORD const*>(m_hdr) + 0);
01008 }
01009
01010 inline ws_size_t version_info::ValueLength() const
01011 {
01012 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
01013 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01014 if(NULL == m_hdr)
01015 {
01016 return 0;
01017 }
01018 #else
01019 WINSTL_ASSERT(NULL != m_hdr);
01020 #endif
01021
01022 return *(sap_cast<WORD const*>(m_hdr) + 1);
01023 }
01024
01025 inline ws_size_t version_info::Type() const
01026 {
01027 WINSTL_ASSERT(NULL != m_hdr);
01028
01029 return *(sap_cast<WORD const*>(m_hdr) + 2);
01030 }
01031
01032 inline wchar_t const* version_info::Key() const
01033 {
01034 WINSTL_ASSERT(NULL != m_hdr);
01035
01036 return m_key;
01037 }
01038
01039 inline fixed_file_info version_info::FixedFileInfo() const
01040 {
01041 WINSTL_ASSERT(NULL != m_hdr);
01042
01043 return fixed_file_info(m_ffi);
01044 }
01045
01046 inline ws_bool_t version_info::HasVarFileInfo() const
01047 {
01048 return NULL != m_vfi;
01049 }
01050
01051 inline VsVarFileInfo version_info::VarFileInfo() const
01052 {
01053 WINSTL_ASSERT(NULL != m_vfi);
01054
01055 return VsVarFileInfo(m_vfi);
01056 }
01057
01058 inline ws_bool_t version_info::HasStringFileInfo() const
01059 {
01060 return NULL != m_sfi;
01061 }
01062
01063 inline VsStringFileInfo version_info::StringFileInfo() const
01064 {
01065 WINSTL_ASSERT(NULL != m_sfi);
01066
01067 return VsStringFileInfo(m_sfi);
01068 }
01069
01070 inline VS_VERSIONINFO_hdr const* version_info::retrieve_module_info_block_(ws_char_a_t const* moduleName)
01071 {
01072 #ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
01073 ws_char_a_t buffer[1 + WINSTL_CONST_MAX_PATH];
01074 #else
01075 basic_file_path_buffer<ws_char_a_t> buffer;
01076 #endif
01077
01078 if( NULL == moduleName &&
01079 #ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
01080 0 != ::GetModuleFileNameA(NULL, &buffer[0], STLSOFT_NUM_ELEMENTS(buffer)))
01081 #else
01082 0 != ::GetModuleFileNameA(NULL, &buffer[0], DWORD(buffer.size())))
01083 #endif
01084 {
01085 moduleName = stlsoft_ns_qual(c_str_ptr)(buffer);
01086 }
01087 else
01088 {
01089
01090
01091
01092 HINSTANCE hinst = ::LoadLibraryExA(moduleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
01093
01094 if(NULL == hinst)
01095 {
01096 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01097 STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
01098 #else
01099 return NULL;
01100 #endif
01101 }
01102 else
01103 {
01104 ::FreeLibrary(hinst);
01105 }
01106 }
01107
01108 allocator_type allocator;
01109 ws_dword_t cb = ::GetFileVersionInfoSizeA(const_cast<ws_char_a_t*>(moduleName), NULL);
01110 void *pv = (0 == cb) ? NULL : allocator.allocate(cb);
01111
01112 #if !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01113
01114
01115 if( 0 != cb &&
01116 pv == NULL)
01117 {
01118 ::GetLastError();
01119
01120 return NULL;
01121 }
01122 #endif
01123
01124 WINSTL_ASSERT(0 == cb || pv != NULL);
01125
01126 if( 0 == cb ||
01127 !::GetFileVersionInfoA(const_cast<ws_char_a_t*>(moduleName), 0, cb, pv))
01128 {
01129 allocator.deallocate(static_cast<ws_byte_t*>(pv), cb);
01130
01131 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01132 STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
01133 #else
01134 return NULL;
01135 #endif
01136 }
01137
01138 WINSTL_ASSERT(pv != NULL);
01139
01140 return static_cast<VS_VERSIONINFO_hdr*>(pv);
01141 }
01142
01143 inline VS_VERSIONINFO_hdr const* version_info::retrieve_module_info_block_(ws_char_w_t const* moduleName)
01144 {
01145 #ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
01146 ws_char_w_t buffer[1 + WINSTL_CONST_MAX_PATH];
01147 #else
01148 basic_file_path_buffer<ws_char_w_t> buffer;
01149 #endif
01150
01151 if( NULL == moduleName &&
01152 #ifdef WINSTL_VERSION_INFO_NO_USE_FILE_PATH_BUFFER
01153 0 != ::GetModuleFileNameW(NULL, &buffer[0], STLSOFT_NUM_ELEMENTS(buffer)))
01154 #else
01155 0 != ::GetModuleFileNameW(NULL, &buffer[0], DWORD(buffer.size())))
01156 #endif
01157 {
01158 moduleName = stlsoft_ns_qual(c_str_ptr)(buffer);
01159 }
01160 else
01161 {
01162
01163
01164
01165 HINSTANCE hinst = ::LoadLibraryExW(moduleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
01166
01167 if(NULL == hinst)
01168 {
01169 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01170 STLSOFT_THROW_X(version_info_exception("Could not elicit version information from module", ::GetLastError()));
01171 #else
01172 return NULL;
01173 #endif
01174 }
01175 else
01176 {
01177 ::FreeLibrary(hinst);
01178 }
01179 }
01180
01181 allocator_type allocator;
01182 ws_dword_t cb = ::GetFileVersionInfoSizeW(const_cast<ws_char_w_t*>(moduleName), NULL);
01183 void *pv = (0 == cb) ? NULL : allocator.allocate(cb);
01184
01185 #ifndef STLSOFT_CF_THROW_BAD_ALLOC
01186 if( 0 != cb &&
01187 pv == NULL)
01188 {
01189 return NULL;
01190 }
01191 #endif
01192
01193 if( 0 == cb ||
01194 !::GetFileVersionInfoW(const_cast<ws_char_w_t*>(moduleName), 0, cb, pv))
01195 {
01196 allocator.deallocate(static_cast<ws_byte_t*>(pv), cb);
01197
01198 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01199 STLSOFT_THROW_X((version_info_exception("Could not elicit version information from module", ::GetLastError())));
01200 #else
01201 pv = NULL;
01202 #endif
01203 }
01204
01205 return static_cast<VS_VERSIONINFO_hdr*>(pv);
01206 }
01207
01208 inline wchar_t const* version_info::calc_key_(void const* pv)
01209 {
01210 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
01211 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01212 if(NULL == pv)
01213 {
01214 return NULL;
01215 }
01216 #else
01217 WINSTL_ASSERT(NULL != pv);
01218 #endif
01219
01220 #ifdef _DEBUG
01221
01222
01223
01224
01225 {
01226 char const* keyA = reinterpret_cast<char const*>(static_cast<WORD const*>(pv) + 2);
01227
01228 if(0 == ::strncmp("VS_VERSION_INFO", keyA, 16))
01229 {
01230 keyA = NULL;
01231 }
01232 }
01233 #endif
01234
01235 wchar_t const* key = reinterpret_cast<wchar_t const*>(static_cast<WORD const*>(pv) + 3);
01236
01237 WINSTL_ASSERT(0 == ::wcsncmp(L"VS_VERSION_INFO", key, 16));
01238
01239 return key;
01240 }
01241
01242 inline VS_FIXEDFILEINFO const* version_info::calc_ffi_(wchar_t const* key)
01243 {
01244 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
01245 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01246 if(NULL == key)
01247 {
01248 return NULL;
01249 }
01250 #else
01251 WINSTL_ASSERT(NULL != key);
01252 #endif
01253
01254 return sap_cast<VS_FIXEDFILEINFO const*>(rounded_ptr(&key[1 + ::wcslen(key)], 4));
01255 }
01256
01257 inline WORD const* version_info::calc_children_(VS_FIXEDFILEINFO const* ffi)
01258 {
01259 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
01260 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01261 if(NULL == ffi)
01262 {
01263 return NULL;
01264 }
01265 #else
01266 WINSTL_ASSERT(NULL != ffi);
01267 #endif
01268
01269 return sap_cast<WORD const*>(rounded_ptr(&ffi[1], 4));
01270 }
01271
01272 inline void version_info::init_()
01273 {
01274 #if !defined(STLSOFT_CF_EXCEPTION_SUPPORT) || \
01275 !defined(STLSOFT_CF_THROW_BAD_ALLOC)
01276 if(NULL == m_hdr)
01277 {
01278 return;
01279 }
01280 #else
01281 WINSTL_ASSERT(NULL != m_hdr);
01282 #endif
01283
01284 #ifdef _DEBUG
01285
01286 VS_FIXEDFILEINFO *ffi = NULL;
01287 UINT cchInfo = 0;
01288
01289 WINSTL_ASSERT(::VerQueryValueA(const_cast<VS_VERSIONINFO_hdr*>(m_hdr), "\\", reinterpret_cast<void**>(&ffi), &cchInfo));
01290 WINSTL_ASSERT(ffi == m_ffi);
01291 #endif
01292
01293
01294
01295 void const * pv = m_children;
01296 void const *const end = rounded_ptr(m_hdr, m_hdr->wLength, 4);
01297
01298 WINSTL_ASSERT(ptr_byte_diff(end, pv) >= 0);
01299
01300 for(; pv != end; )
01301 {
01302 union
01303 {
01304 void const *pv_;
01305 StringFileInfo_hdr const *psfi;
01306 VarFileInfo_hdr const *pvfi;
01307 } u;
01308
01309 u.pv_ = pv;
01310
01311 WINSTL_ASSERT(ptr_byte_diff(pv, m_hdr) < m_hdr->wLength);
01312
01313 if(0 == ::wcsncmp(u.psfi->szKey, L"StringFileInfo", 15))
01314 {
01315 WINSTL_ASSERT(NULL == m_sfi);
01316
01317 m_sfi = u.psfi;
01318
01319 pv = rounded_ptr(pv, u.psfi->wLength, 4);
01320 }
01321 else if(0 == ::wcsncmp(u.psfi->szKey, L"VarFileInfo", 12))
01322 {
01323 WINSTL_ASSERT(NULL == m_vfi);
01324
01325 m_vfi = u.pvfi;
01326
01327 pv = rounded_ptr(pv, u.pvfi->wLength, 4);
01328 }
01329 else
01330 {
01331 #ifdef STLSOFT_UNITTEST
01332 ::wprintf(L"Unexpected contents of VS_VERSIONINFO children. pv: 0x%08x; Key: %.*s\n", pv, 20, u.psfi->szKey);
01333 #endif
01334
01335 WINSTL_MESSAGE_ASSERT("Unexpected contents of VS_VERSIONINFO children", NULL == m_vfi);
01336
01337 break;
01338 }
01339
01340 WINSTL_ASSERT(ptr_byte_diff(pv, end) <= 0);
01341 }
01342
01343 WINSTL_ASSERT(ptr_byte_diff(pv, m_hdr) == m_hdr->wLength);
01344
01345 #ifdef _DEBUG
01346 fixed_file_info fixedInfo = FixedFileInfo();
01347
01348 ws_uint16_t j = fixedInfo.FileVerMajor();
01349 ws_uint16_t n = fixedInfo.FileVerMinor();
01350 ws_uint16_t r = fixedInfo.FileVerRevision();
01351 ws_uint16_t b = fixedInfo.FileVerBuild();
01352
01353 STLSOFT_SUPPRESS_UNUSED(j);
01354 STLSOFT_SUPPRESS_UNUSED(n);
01355 STLSOFT_SUPPRESS_UNUSED(r);
01356 STLSOFT_SUPPRESS_UNUSED(b);
01357 #endif
01358 }
01359
01360 #endif
01361
01362
01363
01364 #ifndef _WINSTL_NO_NAMESPACE
01365 # if defined(_STLSOFT_NO_NAMESPACE) || \
01366 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01367 }
01368 # else
01369 }
01370 }
01371 # endif
01372 #endif
01373
01374
01375
01376 #endif
01377
01378