WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
MSI.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2024 Amebis
4 Copyright © 2016 GÉANT
5*/
6
8
9#pragma once
10
11#include "Common.h"
12#include <MsiQuery.h>
13#include <string>
14#include <vector>
15
18
20template<class _Traits, class _Ax>
21static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
22{
23 assert(0); // TODO: Test this code.
24
25 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
26 DWORD dwSize = _countof(szStackBuffer);
27 UINT uiResult;
28
29 // Try with stack buffer first.
30 uiResult = ::MsiGetPropertyA(hInstall, szName, szStackBuffer, &dwSize);
31 if (uiResult == ERROR_SUCCESS) {
32 // Copy from stack.
33 sValue.assign(szStackBuffer, dwSize);
34 return ERROR_SUCCESS;
35 } else if (uiResult == ERROR_MORE_DATA) {
36 // Allocate buffer on heap to read the string data into and read it.
37 sValue.resize(dwSize++);
38 return ::MsiGetPropertyA(hInstall, szName, &sValue[0], &dwSize);
39 } else {
40 // Return error code.
41 return uiResult;
42 }
43}
44
50template<class _Traits, class _Ax>
51static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
52{
53 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
54 DWORD dwSize = _countof(szStackBuffer);
55 UINT uiResult;
56
57 // Try with stack buffer first.
58 uiResult = ::MsiGetPropertyW(hInstall, szName, szStackBuffer, &dwSize);
59 if (uiResult == ERROR_SUCCESS) {
60 // Copy from stack.
61 sValue.assign(szStackBuffer, dwSize);
62 return ERROR_SUCCESS;
63 } else if (uiResult == ERROR_MORE_DATA) {
64 // Allocate buffer on heap to read the string data into and read it.
65 sValue.resize(dwSize++);
66 return ::MsiGetPropertyW(hInstall, szName, &sValue[0], &dwSize);
67 } else {
68 // Return error code.
69 return uiResult;
70 }
71}
72
74template<class _Traits, class _Ax>
75static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
76{
77 assert(0); // TODO: Test this code.
78
79 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
80 DWORD dwSize = _countof(szStackBuffer);
81 UINT uiResult;
82
83 // Try with stack buffer first.
84 uiResult = ::MsiRecordGetStringA(hRecord, iField, szStackBuffer, &dwSize);
85 if (uiResult == ERROR_SUCCESS) {
86 // Copy from stack.
87 sValue.assign(szStackBuffer, dwSize);
88 return ERROR_SUCCESS;
89 } else if (uiResult == ERROR_MORE_DATA) {
90 // Allocate buffer on heap to read the string data into and read it.
91 sValue.resize(dwSize++);
92 return ::MsiRecordGetStringA(hRecord, iField, &sValue[0], &dwSize);
93 } else {
94 // Return error code.
95 return uiResult;
96 }
97}
98
104template<class _Traits, class _Ax>
105static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
106{
107 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
108 DWORD dwSize = _countof(szStackBuffer);
109 UINT uiResult;
110
111 // Try with stack buffer first.
112 uiResult = ::MsiRecordGetStringW(hRecord, iField, szStackBuffer, &dwSize);
113 if (uiResult == ERROR_SUCCESS) {
114 // Copy from stack.
115 sValue.assign(szStackBuffer, dwSize);
116 return ERROR_SUCCESS;
117 } else if (uiResult == ERROR_MORE_DATA) {
118 // Allocate buffer on heap to read the string data into and read it.
119 sValue.resize(dwSize++);
120 return ::MsiRecordGetStringW(hRecord, iField, &sValue[0], &dwSize);
121 } else {
122 // Return error code.
123 return uiResult;
124 }
125}
126
128template<class _Traits, class _Ax>
129static UINT MsiFormatRecordA(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
130{
131 assert(0); // TODO: Test this code.
132
133 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
134 DWORD dwSize = _countof(szStackBuffer);
135 UINT uiResult;
136
137 // Try with stack buffer first.
138 uiResult = ::MsiFormatRecordA(hInstall, hRecord, szStackBuffer, &dwSize);
139 if (uiResult == ERROR_SUCCESS) {
140 // Copy from stack.
141 sValue.assign(szStackBuffer, dwSize);
142 return ERROR_SUCCESS;
143 } else if (uiResult == ERROR_MORE_DATA) {
144 // Allocate buffer on heap to format the string data into and read it.
145 sValue.resize(dwSize++);
146 return ::MsiFormatRecordA(hInstall, hRecord, &sValue[0], &dwSize);
147 } else {
148 // Return error code.
149 return uiResult;
150 }
151}
152
158template<class _Traits, class _Ax>
159static UINT MsiFormatRecordW(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
160{
161 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
162 DWORD dwSize = _countof(szStackBuffer);
163 UINT uiResult;
164
165 // Try with stack buffer first.
166 uiResult = ::MsiFormatRecordW(hInstall, hRecord, szStackBuffer, &dwSize);
167 if (uiResult == ERROR_SUCCESS) {
168 // Copy from stack.
169 sValue.assign(szStackBuffer, dwSize);
170 return ERROR_SUCCESS;
171 } else if (uiResult == ERROR_MORE_DATA) {
172 // Allocate buffer on heap to format the string data into and read it.
173 sValue.resize(dwSize++);
174 return ::MsiFormatRecordW(hInstall, hRecord, &sValue[0], &dwSize);
175 } else {
176 // Return error code.
177 return uiResult;
178 }
179}
180
186template<class _Ty, class _Ax>
187static UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData)
188{
189 assert(0); // TODO: Test this code.
190
191 DWORD dwSize = 0;
192 UINT uiResult;
193
194 // Query the actual data length first.
195 uiResult = ::MsiRecordReadStream(hRecord, iField, NULL, &dwSize);
196 if (uiResult == ERROR_SUCCESS) {
197 binData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
198 return ::MsiRecordReadStream(hRecord, iField, reinterpret_cast<char*>(binData.data()), &dwSize);
199 } else {
200 // Return error code.
201 return uiResult;
202 }
203}
204
206template<class _Traits, class _Ax>
207static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Out_ std::basic_string<char, _Traits, _Ax> &sValue)
208{
209 assert(0); // TODO: Test this code.
210
211 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
212 DWORD dwSize = _countof(szStackBuffer);
213 UINT uiResult;
214
215 // Try with stack buffer first.
216 uiResult = ::MsiGetTargetPathA(hInstall, szFolder, szStackBuffer, &dwSize);
217 if (uiResult == ERROR_SUCCESS) {
218 // Copy from stack.
219 sValue.assign(szStackBuffer, dwSize);
220 return ERROR_SUCCESS;
221 } else if (uiResult == ERROR_MORE_DATA) {
222 // Allocate buffer on heap to format the string data into and read it.
223 sValue.resize(dwSize++);
224 return ::MsiGetTargetPathA(hInstall, szFolder, &sValue[0], &dwSize);
225 } else {
226 // Return error code.
227 return uiResult;
228 }
229}
230
236template<class _Traits, class _Ax>
237static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
238{
239 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
240 DWORD dwSize = _countof(szStackBuffer);
241 UINT uiResult;
242
243 // Try with stack buffer first.
244 uiResult = ::MsiGetTargetPathW(hInstall, szFolder, szStackBuffer, &dwSize);
245 if (uiResult == ERROR_SUCCESS) {
246 // Copy from stack.
247 sValue.assign(szStackBuffer, dwSize);
248 return ERROR_SUCCESS;
249 } else if (uiResult == ERROR_MORE_DATA) {
250 // Allocate buffer on heap to format the string data into and read it.
251 sValue.resize(dwSize++);
252 return ::MsiGetTargetPathW(hInstall, szFolder, &sValue[0], &dwSize);
253 } else {
254 // Return error code.
255 return uiResult;
256 }
257}
258
260template<class _Traits, class _Ax>
261static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
262{
263 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
264 DWORD dwSize = _countof(szStackBuffer);
265 INSTALLSTATE state;
266
267 // Try with stack buffer first.
268 state = ::MsiGetComponentPathA(szProduct, szComponent, szStackBuffer, &dwSize);
269 if (state >= INSTALLSTATE_BROKEN) {
270 // Copy from stack.
271 sValue.assign(szStackBuffer, dwSize);
272 return state;
273 } else if (state == INSTALLSTATE_MOREDATA) {
274 // Allocate buffer on heap to format the string data into and read it.
275 sValue.resize(dwSize++);
276 return ::MsiGetComponentPathA(szProduct, szComponent, &sValue[0], &dwSize);
277 } else {
278 // Return error code.
279 return state;
280 }
281}
282
288template<class _Traits, class _Ax>
289static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWSTR szComponent, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
290{
291 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
292 DWORD dwSize = _countof(szStackBuffer);
293 INSTALLSTATE state;
294
295 // Try with stack buffer first.
296 state = ::MsiGetComponentPathW(szProduct, szComponent, szStackBuffer, &dwSize);
297 if (state >= INSTALLSTATE_BROKEN) {
298 // Copy from stack.
299 sValue.assign(szStackBuffer, dwSize);
300 return state;
301 } else if (state == INSTALLSTATE_MOREDATA) {
302 // Allocate buffer on heap to format the string data into and read it.
303 sValue.resize(dwSize++);
304 return ::MsiGetComponentPathW(szProduct, szComponent, &sValue[0], &dwSize);
305 } else {
306 // Return error code.
307 return state;
308 }
309}
310
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition Common.h:94
static UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Formats record field data and properties using a format string and stores it in a std::wstring string...
Definition MSI.h:159
static UINT MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Gets the value for an installer property and stores it in a std::wstring string.
Definition MSI.h:51
static UINT MsiGetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, std::basic_string< char, _Traits, _Ax > &sValue)
Returns the full target path for a folder in the Directory table and stores it in a std::wstring stri...
Definition MSI.h:207
static INSTALLSTATE MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent, std::basic_string< char, _Traits, _Ax > &sValue)
Returns the full path to an installed component. If the key path for the component is a registry key ...
Definition MSI.h:261
static UINT MsiRecordGetStringW(MSIHANDLE hRecord, unsigned int iField, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Returns the string value of a record field and stores it in a std::wstring string.
Definition MSI.h:105
static UINT MsiGetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Returns the full target path for a folder in the Directory table and stores it in a std::wstring stri...
Definition MSI.h:237
static UINT MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, std::basic_string< char, _Traits, _Ax > &sValue)
Gets the value for an installer property and stores it in a std::wstring string.
Definition MSI.h:21
static UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string< char, _Traits, _Ax > &sValue)
Formats record field data and properties using a format string and stores it in a std::wstring string...
Definition MSI.h:129
static UINT MsiRecordReadStream(MSIHANDLE hRecord, unsigned int iField, std::vector< _Ty, _Ax > &binData)
Reads bytes from a record stream field into a std::vector buffer.
Definition MSI.h:187
static INSTALLSTATE MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Returns the full path to an installed component. If the key path for the component is a registry key ...
Definition MSI.h:289
static UINT MsiRecordGetStringA(MSIHANDLE hRecord, unsigned int iField, std::basic_string< char, _Traits, _Ax > &sValue)
Returns the string value of a record field and stores it in a std::wstring string.
Definition MSI.h:75