1// VersionInfo.cpp: implementation of the CVersionInfo class.
2//
3//////////////////////////////////////////////////////////////////////
4
5#include "stdafx.h"
6#include "bindinstall.h"
7#include "VersionInfo.h"
8#include <winver.h>
9
10#ifdef _DEBUG
11#undef THIS_FILE
12static char THIS_FILE[]=__FILE__;
13#define new DEBUG_NEW
14#endif
15
16//////////////////////////////////////////////////////////////////////
17// Construction/Destruction
18//////////////////////////////////////////////////////////////////////
19
20CVersionInfo::CVersionInfo(CString filename)
21{
22	HANDLE hFile;
23	WIN32_FIND_DATA fd;
24	memset(&fd, 0, sizeof(WIN32_FIND_DATA));
25
26	m_status = ERROR_SUCCESS;
27	m_isValid = FALSE;
28	m_filename = filename;
29
30	// See if the given file exists
31	hFile = FindFirstFile(filename, &fd);
32	if(hFile == INVALID_HANDLE_VALUE)
33	{
34		m_status = ERROR_FILE_NOT_FOUND;
35		m_versionInfo = NULL;
36		return;
37	}
38	FindClose(hFile);
39
40	// Extract the file info
41	DWORD handle;
42	DWORD viSize = GetFileVersionInfoSize((LPTSTR)(LPCTSTR)filename, &handle);
43	m_versionInfo = NULL;
44
45	if(viSize == 0)
46	{
47		m_status = GetLastError();
48	}
49	else
50	{
51		m_versionInfo = new char[viSize];
52
53		// Get the block of version info from the file
54		if(!GetFileVersionInfo((LPTSTR)(LPCTSTR)filename, handle, viSize, m_versionInfo))
55		{
56			if(m_versionInfo)
57			{
58				delete [] m_versionInfo;
59				m_versionInfo = NULL;
60			}
61			return;
62		}
63
64		// Now extract the sub block we are interested in
65		UINT versionLen = 0;
66		LPVOID viBlob = NULL;
67		if(!VerQueryValue(m_versionInfo, "\\", &viBlob, &versionLen))
68		{
69			if(m_versionInfo)
70			{
71				delete [] m_versionInfo;
72				m_versionInfo = NULL;
73			}
74			return;
75		}
76
77		// And finally the version info is ours
78		m_fixedInfo = (VS_FIXEDFILEINFO *)viBlob;
79
80		UINT blobLen = 0;
81
82		// If we got here, all is good
83	}
84	m_isValid = TRUE;
85}
86
87CVersionInfo::~CVersionInfo()
88{
89	m_fixedInfo = NULL;
90	if(m_versionInfo)
91	{
92		delete [] m_versionInfo;
93		m_versionInfo = NULL;
94	}
95}
96
97CString CVersionInfo::GetFileVersionString()
98{
99	return(QueryStringValue("FileVersion"));
100}
101
102CString CVersionInfo::GetProductVersionString()
103{
104	return(QueryStringValue("ProductVersion"));
105}
106
107CString CVersionInfo::GetComments()
108{
109	return(QueryStringValue("Comments"));
110}
111
112CString CVersionInfo::GetFileDescription()
113{
114	return(QueryStringValue("FileDescription"));
115}
116
117CString CVersionInfo::GetInternalName()
118{
119	return(QueryStringValue("InternalName"));
120}
121
122CString CVersionInfo::GetLegalCopyright()
123{
124	return(QueryStringValue("LegalCopyright"));
125}
126
127CString CVersionInfo::GetLegalTrademarks()
128{
129	return(QueryStringValue("LegalTrademarks"));
130}
131
132CString CVersionInfo::GetOriginalFileName()
133{
134	return(QueryStringValue("OriginalFilename"));
135}
136
137CString CVersionInfo::GetProductName()
138{
139	return(QueryStringValue("ProductName"));
140}
141
142CString CVersionInfo::GetSpecialBuildString()
143{
144	return(QueryStringValue("SpecialBuild"));
145}
146
147CString CVersionInfo::GetPrivateBuildString()
148{
149	return(QueryStringValue("PrivateBuild"));
150}
151
152CString CVersionInfo::GetCompanyName()
153{
154	return(QueryStringValue("CompanyName"));
155}
156
157#ifdef NOTUSED
158BOOL CVersionInfo::CopyFileCheckVersion(CVersionInfo &originalFile)
159{
160	_int64 myVer = GetFileVersion();
161	_int64 origVer = originalFile.GetFileVersion();
162
163	if(origVer > myVer)
164	{
165		CString msg;
166		msg.Format(IDS_EXISTING_NEWER, m_filename);
167		DWORD query = AfxMessageBox(msg, MB_YESNO);
168		if(query == IDNO)
169			return(TRUE);
170	}
171
172	return(CopyFileNoVersion(originalFile));
173}
174#endif
175
176BOOL CVersionInfo::CopyFileNoVersion(CVersionInfo &originalFile)
177{
178	int x = 7;
179	return(CopyFile(originalFile.GetFilename(), m_filename, FALSE));
180}
181
182
183_int64 CVersionInfo::GetFileVersion()
184{
185	_int64 ver = 0;
186
187	if(m_versionInfo)
188	{
189		ver = m_fixedInfo->dwFileVersionMS;
190		ver <<= 32;
191		ver += m_fixedInfo->dwFileVersionLS;
192	}
193	return(ver);
194}
195
196_int64 CVersionInfo::GetProductVersion()
197{
198	_int64 ver = 0;
199
200	if(m_versionInfo)
201	{
202		ver = m_fixedInfo->dwProductVersionMS;
203		ver <<= 32;
204		ver += m_fixedInfo->dwProductVersionLS;
205	}
206	return(ver);
207}
208
209_int64 CVersionInfo::GetFileDate()
210{
211	_int64 fDate = 0;
212
213	if(m_versionInfo)
214	{
215		fDate = m_fixedInfo->dwFileDateMS;
216		fDate <<= 32;
217		fDate += m_fixedInfo->dwFileDateLS;
218	}
219	return(fDate);
220}
221
222DWORD CVersionInfo::GetFileFlagMask()
223{
224	if(m_versionInfo)
225	{
226		return(m_fixedInfo->dwFileFlagsMask);
227	}
228	return(0);
229}
230
231DWORD CVersionInfo::GetFileFlags()
232{
233	if(m_versionInfo)
234	{
235		return(m_fixedInfo->dwFileFlags);
236	}
237	return(0);
238}
239
240DWORD CVersionInfo::GetFileOS()
241{
242	if(m_versionInfo)
243	{
244		return(m_fixedInfo->dwFileOS);
245	}
246	return(VOS_UNKNOWN);
247}
248
249DWORD CVersionInfo::GetFileType()
250{
251	if(m_versionInfo)
252	{
253		return(m_fixedInfo->dwFileType);
254	}
255	return(VFT_UNKNOWN);
256}
257
258DWORD CVersionInfo::GetFileSubType()
259{
260	if(m_versionInfo)
261	{
262		return(m_fixedInfo->dwFileSubtype);
263	}
264	return(VFT2_UNKNOWN);
265}
266
267CString CVersionInfo::QueryStringValue(CString value)
268{
269	UINT blobLen = 0;
270	LPVOID viBlob = NULL;
271
272	if(m_versionInfo)
273	{
274		char queryString[256];
275
276		// This code page value is for American English.  If you change the resources to be other than that
277		// You probably should change this to match it.
278		DWORD codePage = 0x040904B0;
279
280		sprintf(queryString, "\\StringFileInfo\\%08X\\%s", codePage, value);
281
282		if(VerQueryValue(m_versionInfo, queryString, &viBlob, &blobLen))
283			return((char *)viBlob);
284	}
285	return("Not Available");
286}
287