29 using namespace basis;
34 #ifndef BOOT_STRAPPING
36 #include <__build_version.h>
40 #define __build_FILE_VERSION "108.420.1024.10008"
51 #define render_ptr(ptr) from_unicode_temp( (UTF16 *) ptr)
53 #define render_ptr(ptr) ( (char *) ptr)
61 version_checker::version_checker(
const astring &library_file_name,
63 : _library_file_name(new
astring(library_file_name)),
64 _expected_version(new
version(expected_version)),
65 _version_complaint(new
astring(version_complaint))
70 WHACK(_library_file_name);
71 WHACK(_expected_version);
72 WHACK(_version_complaint);
77 return astring(class_name()) +
": library_file_name=" + *_library_file_name
78 +
", expected_version=" + _expected_version->
text_form()
79 +
", complaint_message=" + *_version_complaint;
84 astring version_disabler = environment::TMP();
85 version_disabler +=
"/no_version_check.txt";
86 FILE *always_okay = fopen(version_disabler.
s(),
"r");
93 if (version_found.
compatible(*_expected_version))
return true;
102 #if defined(__WIN32__)
103 return bool(
get_handle(library_file_name) != 0);
106 return true || library_file_name.
t();
113 #if defined(__WIN32__)
114 return GetModuleHandle(to_unicode_temp(library_file_name));
122 #if defined(__UNIX__)
124 if (module_handle) {}
125 return application_configuration::application_name();
126 #elif defined(__WIN32__)
129 GetModuleFileName((HMODULE)module_handle, low_buff,
MAX_ABS_PATH - 1);
130 astring buff = from_unicode_temp(low_buff);
134 #pragma message("module_name unknown for this operating system.")
135 return application_configuration::application_name();
149 #if defined(__WIN32__)
152 required_size = GetFileVersionInfoSize(to_unicode_temp(filename), &module_handle);
154 required_size = 0 && filename.
t();
156 if (!required_size)
return false;
157 to_fill.
reset(required_size);
160 bool success =
false;
161 #if defined(__WIN32__)
163 success = GetFileVersionInfo(to_unicode_temp(filename), module_handle,
164 required_size, to_fill.
access());
176 #if defined(__WIN32__)
180 void *pointer_to_language_structure;
182 if (!VerQueryValue(version_chunk.
access(),
183 to_unicode_temp(
"\\VarFileInfo\\Translation"),
184 &pointer_to_language_structure, &data_size))
187 high = LOWORD(*(
unsigned int *)pointer_to_language_structure);
188 low = HIWORD(*(
unsigned int *)pointer_to_language_structure);
190 high = 0 && version_chunk.
length();
200 #if defined(__UNIX__)
222 astring root_key(astring::SPRINTF,
"\\StringFileInfo\\%04x%04x", high, low);
227 abyte *file_version_pointer;
229 if (!VerQueryValue(version_info_found.
access(),
230 to_unicode_temp(file_version_key),
231 (LPVOID *)&file_version_pointer, &data_size))
233 version_string = render_ptr(file_version_pointer);
236 for (
int i = 0; i < version_string.
length(); i++) {
237 if (version_string[i] ==
' ') {
238 version_string.
zap(i, i);
246 return version::from_text(version_string);
262 astring root_key(astring::SPRINTF,
"\\StringFileInfo\\%04x%04x", high, low);
265 bool total_success =
true;
275 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
276 +
astring(
"\\FileVersion")), &data_pointer, &data_size))
277 total_success =
false;
279 to_fill.
file_version = version::from_text(render_ptr(data_pointer));
282 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
283 +
astring(
"\\CompanyName")), &data_pointer, &data_size))
284 total_success =
false;
289 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
290 +
astring(
"\\FileDescription")), &data_pointer, &data_size))
291 total_success =
false;
296 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
297 +
astring(
"\\InternalName")), &data_pointer, &data_size))
298 total_success =
false;
303 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
304 +
astring(
"\\LegalCopyright")), &data_pointer, &data_size))
305 total_success =
false;
307 to_fill.
copyright = render_ptr(data_pointer);
310 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
311 +
astring(
"\\LegalTrademarks")), &data_pointer, &data_size))
312 total_success =
false;
314 to_fill.
trademarks = render_ptr(data_pointer);
317 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
318 +
astring(
"\\OriginalFilename")), &data_pointer, &data_size))
319 total_success =
false;
324 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
325 +
astring(
"\\ProductName")), &data_pointer, &data_size))
326 total_success =
false;
331 if (!VerQueryValue(version_info_found.
access(), to_unicode_temp(root_key
332 +
astring(
"\\ProductVersion")), &data_pointer, &data_size))
333 total_success =
false;
335 to_fill.
product_version = version::from_text(render_ptr(data_pointer));
340 return total_success;
344 const version &expected_version,
const version &version_found)
const
346 astring to_show(
"There has been a Version Mismatch: The module \"");
351 to_show +=
astring(
"\" cannot load. This is because the file \"");
352 to_show += library_file_name;
353 to_show +=
astring(
"\" was expected to have a version of [");
357 to_show +=
astring(
"] but it instead had a version of [");
361 to_show += *_version_complaint;
363 #if defined(__UNIX__)
366 #elif defined(__WIN32__)
367 MessageBox(0, to_unicode_temp(to_show),
368 to_unicode_temp(
"version_checking::failure"), MB_OK);
374 astring to_show(
"There has been a failure in Version Checking: The file \"");
376 to_show +=
astring(
"\" could not be loaded or found. ");
377 to_show += *_version_complaint;
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
int length() const
Returns the current length of the string.
void to_lower()
to_lower modifies "this" by replacing capitals with lower-case.
A very common template for a dynamic array of bytes.
Holds all information about a file's versioning.
basis::astring product_name
basis::astring company_name
basis::astring description
basis::astring original_name
basis::astring trademarks
basis::astring internal_name
Holds a file's version identifier.
virtual basis::astring text_form() const
bool compatible(const version &that) const
returns true if this is compatible with "that" version on win32.
basis::astring flex_text_form(version_style style=DOTS, int including=-1) const
returns a textual form of the version number.
void complain_cannot_load(const basis::astring &library_file_name) const
Reports that the dll could not be loaded.
bool good_version() const
Performs the actual version check.
virtual ~version_checker()
Destructor releases any resources.
static bool get_record(const basis::astring &pathname, structures::version_record &to_fill)
Retrieves a version record for the file at "pathname".
static bool retrieve_version_info(const basis::astring &filename, basis::byte_array &to_fill)
Retrieves the version info for the "filename" into the array "to_fill".
static bool get_language(basis::byte_array &version_chunk, basis::un_short &high, basis::un_short &low)
Gets the language identifier out of the "version_chunk".
static basis::astring get_name(const void *to_find)
returns the name of the HMODULE specified by "to_find".
static basis::astring module_name(const void *module_handle)
returns the module name where this object resides; only sensible on win32.
void complain_wrong_version(const basis::astring &library_file_name, const structures::version &expected_version, const structures::version &version_found) const
Reports that the file has the wrong version.
static bool loaded(const basis::astring &library_file_name)
returns true if the "library_file_name" is currently loaded.
basis::astring text_form() const
static structures::version retrieve_version(const basis::astring &pathname)
Returns the version given a "pathname" to the DLL or EXE file.
static void * get_handle(const basis::astring &library_file_name)
retrieves the module handle for the "library_file_name".
#define continuable_error(c, f, i)
#define NULL_POINTER
The value representing a pointer to nothing.
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
unsigned char abyte
A fairly important unit which is seldom defined...
unsigned int un_int
Abbreviated name for unsigned integers.
unsigned short un_short
Abbreviated name for unsigned short integers.
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
Support for unicode builds.
Aids in achievement of platform independence.