| OLD | NEW |
| (Empty) |
| 1 // Copyright 2003-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include "omaha/base/file_ver.h" | |
| 17 #include "omaha/base/commontypes.h" | |
| 18 #include "omaha/base/debug.h" | |
| 19 | |
| 20 namespace omaha { | |
| 21 | |
| 22 // TODO(omaha): Write unittest for this class. | |
| 23 | |
| 24 FileVer::FileVer() { | |
| 25 file_ver_data_ = NULL; | |
| 26 lang_charset_ = 0; | |
| 27 } | |
| 28 | |
| 29 FileVer::~FileVer() { | |
| 30 Close(); | |
| 31 } | |
| 32 | |
| 33 void FileVer::Close() { | |
| 34 delete[] file_ver_data_; | |
| 35 file_ver_data_ = NULL; | |
| 36 lang_charset_ = 0; | |
| 37 } | |
| 38 | |
| 39 BOOL FileVer::Open(const TCHAR* lpszModuleName) { | |
| 40 ASSERT1(lpszModuleName); | |
| 41 | |
| 42 // Get the version information size and allocate the buffer. | |
| 43 DWORD handle; | |
| 44 DWORD ver_info_size = | |
| 45 ::GetFileVersionInfoSize(const_cast<TCHAR*>(lpszModuleName), &handle); | |
| 46 if (ver_info_size == 0) { | |
| 47 return FALSE; | |
| 48 } | |
| 49 | |
| 50 // Get version information. | |
| 51 // file_ver_data_ is allocated here and deleted in Close() (or implicitly | |
| 52 // in the destructor). | |
| 53 file_ver_data_ = new byte[ver_info_size]; | |
| 54 ASSERT1(file_ver_data_); | |
| 55 if (!file_ver_data_) { | |
| 56 return FALSE; | |
| 57 } | |
| 58 | |
| 59 if (!::GetFileVersionInfo(const_cast<TCHAR*>(lpszModuleName), handle, | |
| 60 ver_info_size, | |
| 61 reinterpret_cast<void**>(file_ver_data_))) { | |
| 62 Close(); | |
| 63 return FALSE; | |
| 64 } | |
| 65 | |
| 66 // Get the first language and character-set identifier. | |
| 67 UINT query_size = 0; | |
| 68 DWORD* translation_table = NULL; | |
| 69 if (!::VerQueryValue(file_ver_data_, | |
| 70 _T("\\VarFileInfo\\Translation"), | |
| 71 reinterpret_cast<void**>(&translation_table), | |
| 72 &query_size) || | |
| 73 query_size == 0) { | |
| 74 Close(); | |
| 75 return FALSE; | |
| 76 } | |
| 77 | |
| 78 ASSERT1(query_size != 0); | |
| 79 ASSERT1(translation_table); | |
| 80 | |
| 81 // Create charset. | |
| 82 lang_charset_ = MAKELONG(HIWORD(translation_table[0]), | |
| 83 LOWORD(translation_table[0])); | |
| 84 return TRUE; | |
| 85 } | |
| 86 | |
| 87 CString FileVer::QueryValue(const TCHAR* lpszValueName) const { | |
| 88 ASSERT1(lpszValueName); | |
| 89 | |
| 90 if (file_ver_data_ == NULL) { | |
| 91 return (CString)_T(""); | |
| 92 } | |
| 93 | |
| 94 // Query version information value. | |
| 95 UINT query_size = 0; | |
| 96 LPVOID query_data = NULL; | |
| 97 CString str_query_value, str_block_name; | |
| 98 str_block_name.Format(_T("\\StringFileInfo\\%08lx\\%s"), | |
| 99 lang_charset_, | |
| 100 lpszValueName); | |
| 101 | |
| 102 if (::VerQueryValue(reinterpret_cast<void**>(file_ver_data_), | |
| 103 str_block_name.GetBuffer(0), | |
| 104 &query_data, | |
| 105 &query_size) && | |
| 106 query_size != 0 && | |
| 107 query_data) { | |
| 108 str_query_value = reinterpret_cast<const TCHAR*>(query_data); | |
| 109 } | |
| 110 | |
| 111 str_block_name.ReleaseBuffer(); | |
| 112 | |
| 113 return str_query_value; | |
| 114 } | |
| 115 | |
| 116 BOOL FileVer::GetFixedInfo(VS_FIXEDFILEINFO& vsffi) const { // NOLINT | |
| 117 if (file_ver_data_ == NULL) { | |
| 118 return FALSE; | |
| 119 } | |
| 120 | |
| 121 UINT query_size = 0; | |
| 122 VS_FIXEDFILEINFO* pVsffi = NULL; | |
| 123 if (::VerQueryValue(reinterpret_cast<void**>(file_ver_data_), | |
| 124 _T("\\"), | |
| 125 reinterpret_cast<void**>(&pVsffi), | |
| 126 &query_size) && | |
| 127 query_size != 0 && | |
| 128 pVsffi) { | |
| 129 vsffi = *pVsffi; | |
| 130 return TRUE; | |
| 131 } | |
| 132 | |
| 133 return FALSE; | |
| 134 } | |
| 135 | |
| 136 CString FileVer::FormatFixedFileVersion() const { | |
| 137 CString str_version; | |
| 138 VS_FIXEDFILEINFO vsffi = {0}; | |
| 139 | |
| 140 if (GetFixedInfo(vsffi)) { | |
| 141 str_version.Format(NOTRANSL(_T("%u.%u.%u.%u")), | |
| 142 HIWORD(vsffi.dwFileVersionMS), | |
| 143 LOWORD(vsffi.dwFileVersionMS), | |
| 144 HIWORD(vsffi.dwFileVersionLS), | |
| 145 LOWORD(vsffi.dwFileVersionLS)); | |
| 146 } | |
| 147 return str_version; | |
| 148 } | |
| 149 | |
| 150 CString FileVer::FormatFixedProductVersion() const { | |
| 151 CString str_version; | |
| 152 VS_FIXEDFILEINFO vsffi = {0}; | |
| 153 | |
| 154 if (GetFixedInfo(vsffi)) { | |
| 155 str_version.Format(NOTRANSL(_T("%u.%u.%u.%u")), | |
| 156 HIWORD(vsffi.dwProductVersionMS), | |
| 157 LOWORD(vsffi.dwProductVersionMS), | |
| 158 HIWORD(vsffi.dwProductVersionLS), | |
| 159 LOWORD(vsffi.dwProductVersionLS)); | |
| 160 } | |
| 161 return str_version; | |
| 162 } | |
| 163 | |
| 164 ULONGLONG FileVer::GetFileVersionAsULONGLONG() const { | |
| 165 ULONGLONG version = 0; | |
| 166 VS_FIXEDFILEINFO vsffi = {0}; | |
| 167 | |
| 168 if (GetFixedInfo(vsffi)) { | |
| 169 version = MAKEDLLVERULL(HIWORD(vsffi.dwProductVersionMS), | |
| 170 LOWORD(vsffi.dwProductVersionMS), | |
| 171 HIWORD(vsffi.dwProductVersionLS), | |
| 172 LOWORD(vsffi.dwProductVersionLS)); | |
| 173 } | |
| 174 return version; | |
| 175 } | |
| 176 | |
| 177 } // namespace omaha | |
| 178 | |
| OLD | NEW |