-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTRIMCORE_Rsrc_VersionInfo.h
123 lines (100 loc) · 3.76 KB
/
TRIMCORE_Rsrc_VersionInfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef TRIMCORE_DLL_RSRC_VERSIONINFO_H
#define TRIMCORE_DLL_RSRC_VERSIONINFO_H
#include <winver.h>
#include <cstdint>
namespace TRIMCORE::Implementation {
struct StringSet {
const wchar_t * data;
std::uint16_t size;
};
TRIMCORE_DLL_IMPORT const void * VerInfo (HMODULE, StringSet *);
TRIMCORE_DLL_IMPORT const wchar_t * VerStrName (const StringSet *, const wchar_t *);
TRIMCORE_DLL_IMPORT const wchar_t * VerStrIndex (const StringSet *, unsigned int);
TRIMCORE_DLL_IMPORT bool VerInfoIsValid (const void *);
}
namespace TRIMCORE::Rsrc {
// VersionNumber
// - layout of file/product semantic version numbers stored in VS_FIXEDFILEINFO
// - TODO: string parsing?
//
struct VersionNumber {
std::uint16_t minor;
std::uint16_t major;
std::uint16_t build;
std::uint16_t patch; // also known as 'release' number
public:
std::uint64_t as_number () const {
return (std::uint64_t (this->major) << 48)
| (std::uint64_t (this->minor) << 32)
| (std::uint64_t (this->patch) << 16)
| (std::uint64_t (this->build) << 0);
}
bool operator == (const VersionNumber & other) const {
return *reinterpret_cast <const std::uint64_t *> (this)
== *reinterpret_cast <const std::uint64_t *> (&other);
}
bool operator < (const VersionNumber & other) const {
return this->as_number () < other.as_number ();
}
};
union FixedVersionInfo {
// fixed file info
// - access through names defined by Windows API
VS_FIXEDFILEINFO ffi;
// named structure members
// - more descriptive access through simply named members
struct {
std::uint32_t header [2];
VersionNumber file;
VersionNumber product;
struct {
std::uint32_t mask;
std::uint32_t file;
std::uint32_t os;
std::uint32_t type;
std::uint32_t subtype;
} flags;
// timestamp
// - big endian, otherwise a FILETIME number
struct {
std::uint32_t high;
std::uint32_t low;
} timestamp;
};
};
// VersionInfo
// - provides quick and easy access to VERSIONINFO resource of the module
// - searches for RT_VERSION block in .rsrc section and simply maps pointers here
// - better than 'GetFileVersionInfo' which loads the module and copies all the data
//
class VersionInfo {
Implementation::StringSet strings;
const void * ffi;
public:
inline explicit VersionInfo (HMODULE hModule)
: ffi (Implementation::VerInfo (hModule, &strings)) {}
VersionInfo (const VersionInfo &) = default;
// valid
// - retrieves if the info is placeholder (false) or actually valid (true)
//
inline bool valid () const {
return Implementation::VerInfoIsValid (this->ffi);
}
// access to fixed file info
// - version->file.major etc...
//
inline const FixedVersionInfo * operator -> () const {
return static_cast <const FixedVersionInfo *> (this->ffi);
}
// access strings
// - version [L"CompanyName"]; or version [1]
// - returns NULL if no such string found
inline const wchar_t * operator [] (const wchar_t * name) const {
return Implementation::VerStrName (&this->strings, name);
}
inline const wchar_t * operator [] (unsigned int index) const {
return Implementation::VerStrIndex (&this->strings, index);
}
};
}
#endif