diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-31 11:56:14 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-31 18:01:06 -0700 |
commit | 47582b162368e8edf7a3b11c13b8e9dabc5f0a26 (patch) | |
tree | 2c4063eff325684bed39de0edacd7866a257ae02 /src/dtf/SfxCA/RemoteMsi.cpp | |
parent | 167296c42497c4e95f0d5d71168542d747655981 (diff) | |
download | wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.gz wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.bz2 wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.zip |
Provide managed CA and Embedded UI DTF libraries via NuGet
Lots of refactoring to bring the SFX tooling back into the 'dtf'
layer since they are (in the end) tightly coupled to some DTF
assemblies. Also refactored the DTF tests into their own folder
and added a couple integration tests to build using the new CA/UI
NuGet package.
Closes wixtoolset/issues#6080
Diffstat (limited to 'src/dtf/SfxCA/RemoteMsi.cpp')
-rw-r--r-- | src/dtf/SfxCA/RemoteMsi.cpp | 629 |
1 files changed, 629 insertions, 0 deletions
diff --git a/src/dtf/SfxCA/RemoteMsi.cpp b/src/dtf/SfxCA/RemoteMsi.cpp new file mode 100644 index 00000000..ba59fdf7 --- /dev/null +++ b/src/dtf/SfxCA/RemoteMsi.cpp | |||
@@ -0,0 +1,629 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | #include "RemoteMsiSession.h" | ||
5 | |||
6 | |||
7 | // | ||
8 | // Ensures that the request buffer is large enough to hold a request, | ||
9 | // reallocating the buffer if necessary. | ||
10 | // It will also reduce the buffer size if the previous allocation was very large. | ||
11 | // | ||
12 | static __success(return == 0) UINT EnsureBufSize(__deref_out_ecount(*pcchBuf) wchar_t** pszBuf, __deref_inout DWORD* pcchBuf, DWORD cchRequired) | ||
13 | { | ||
14 | // It will also reduce the buffer size if the previous allocation was very large. | ||
15 | if (*pcchBuf < cchRequired || (LARGE_BUFFER_THRESHOLD/2 < *pcchBuf && cchRequired < *pcchBuf)) | ||
16 | { | ||
17 | if (*pszBuf != NULL) | ||
18 | { | ||
19 | SecureZeroMemory(*pszBuf, *pcchBuf); | ||
20 | delete[] *pszBuf; | ||
21 | } | ||
22 | |||
23 | *pcchBuf = max(MIN_BUFFER_STRING_SIZE, cchRequired); | ||
24 | *pszBuf = new wchar_t[*pcchBuf]; | ||
25 | |||
26 | if (*pszBuf == NULL) | ||
27 | { | ||
28 | return ERROR_OUTOFMEMORY; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | return ERROR_SUCCESS; | ||
33 | } | ||
34 | |||
35 | typedef int (WINAPI *PMsiFunc_I_I)(int in1, __out int* out1); | ||
36 | typedef int (WINAPI *PMsiFunc_II_I)(int in1, int in2, __out int* out1); | ||
37 | typedef int (WINAPI *PMsiFunc_IS_I)(int in1, __in_z wchar_t* in2, __out int* out1); | ||
38 | typedef int (WINAPI *PMsiFunc_ISI_I)(int in1, __in_z wchar_t* in2, int in3, __out int* out1); | ||
39 | typedef int (WINAPI *PMsiFunc_ISII_I)(int in1, __in_z wchar_t* in2, int in3, int in4, __out int* out1); | ||
40 | typedef int (WINAPI *PMsiFunc_IS_II)(int in1, __in_z wchar_t* in2, __out int* out1, __out int* out2); | ||
41 | typedef MSIDBERROR (WINAPI *PMsiEFunc_I_S)(int in1, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); | ||
42 | typedef int (WINAPI *PMsiFunc_I_S)(int in1, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); | ||
43 | typedef int (WINAPI *PMsiFunc_II_S)(int in1, int in2, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); | ||
44 | typedef int (WINAPI *PMsiFunc_IS_S)(int in1, __in_z wchar_t* in2, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); | ||
45 | typedef int (WINAPI *PMsiFunc_ISII_SII)(int in1, __in_z wchar_t* in2, int in3, int in4, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1, __out int* out2, __out int* out3); | ||
46 | |||
47 | UINT MsiFunc_I_I(PMsiFunc_I_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
48 | { | ||
49 | int in1 = pReq->fields[0].iValue; | ||
50 | int out1; | ||
51 | UINT ret = (UINT) func(in1, &out1); | ||
52 | if (ret == 0) | ||
53 | { | ||
54 | pResp->fields[1].vt = VT_I4; | ||
55 | pResp->fields[1].iValue = out1; | ||
56 | } | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | UINT MsiFunc_II_I(PMsiFunc_II_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
61 | { | ||
62 | int in1 = pReq->fields[0].iValue; | ||
63 | int in2 = pReq->fields[1].iValue; | ||
64 | int out1; | ||
65 | UINT ret = (UINT) func(in1, in2, &out1); | ||
66 | if (ret == 0) | ||
67 | { | ||
68 | pResp->fields[1].vt = VT_I4; | ||
69 | pResp->fields[1].iValue = out1; | ||
70 | } | ||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | UINT MsiFunc_IS_I(PMsiFunc_IS_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
75 | { | ||
76 | int in1 = pReq->fields[0].iValue; | ||
77 | wchar_t* in2 = pReq->fields[1].szValue; | ||
78 | int out1; | ||
79 | UINT ret = (UINT) func(in1, in2, &out1); | ||
80 | if (ret == 0) | ||
81 | { | ||
82 | pResp->fields[1].vt = VT_I4; | ||
83 | pResp->fields[1].iValue = out1; | ||
84 | } | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | UINT MsiFunc_ISI_I(PMsiFunc_ISI_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
89 | { | ||
90 | int in1 = pReq->fields[0].iValue; | ||
91 | wchar_t* in2 = pReq->fields[1].szValue; | ||
92 | int in3 = pReq->fields[2].iValue; | ||
93 | int out1; | ||
94 | UINT ret = (UINT) func(in1, in2, in3, &out1); | ||
95 | if (ret == 0) | ||
96 | { | ||
97 | pResp->fields[1].vt = VT_I4; | ||
98 | pResp->fields[1].iValue = out1; | ||
99 | } | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | UINT MsiFunc_ISII_I(PMsiFunc_ISII_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
104 | { | ||
105 | int in1 = pReq->fields[0].iValue; | ||
106 | wchar_t* in2 = pReq->fields[1].szValue; | ||
107 | int in3 = pReq->fields[2].iValue; | ||
108 | int in4 = pReq->fields[3].iValue; | ||
109 | int out1; | ||
110 | UINT ret = (UINT) func(in1, in2, in3, in4, &out1); | ||
111 | if (ret == 0) | ||
112 | { | ||
113 | pResp->fields[1].vt = VT_I4; | ||
114 | pResp->fields[1].iValue = out1; | ||
115 | } | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | UINT MsiFunc_IS_II(PMsiFunc_IS_II func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) | ||
120 | { | ||
121 | int in1 = pReq->fields[0].iValue; | ||
122 | wchar_t* in2 = pReq->fields[1].szValue; | ||
123 | int out1, out2; | ||
124 | UINT ret = (UINT) func(in1, in2, &out1, &out2); | ||
125 | if (ret == 0) | ||
126 | { | ||
127 | pResp->fields[1].vt = VT_I4; | ||
128 | pResp->fields[1].iValue = out1; | ||
129 | pResp->fields[2].vt = VT_I4; | ||
130 | pResp->fields[2].iValue = out2; | ||
131 | } | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | UINT MsiFunc_I_S(PMsiFunc_I_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) | ||
136 | { | ||
137 | int in1 = pReq->fields[0].iValue; | ||
138 | szBuf[0] = L'\0'; | ||
139 | DWORD cchValue = cchBuf; | ||
140 | UINT ret = (UINT) func(in1, szBuf, &cchValue); | ||
141 | if (ret == ERROR_MORE_DATA) | ||
142 | { | ||
143 | ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); | ||
144 | if (ret == 0) | ||
145 | { | ||
146 | ret = (UINT) func(in1, szBuf, &cchValue); | ||
147 | } | ||
148 | } | ||
149 | if (ret == 0) | ||
150 | { | ||
151 | pResp->fields[1].vt = VT_LPWSTR; | ||
152 | pResp->fields[1].szValue = szBuf; | ||
153 | } | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | MSIDBERROR MsiEFunc_I_S(PMsiEFunc_I_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) | ||
158 | { | ||
159 | int in1 = pReq->fields[0].iValue; | ||
160 | szBuf[0] = L'\0'; | ||
161 | DWORD cchValue = cchBuf; | ||
162 | MSIDBERROR ret = func(in1, szBuf, &cchValue); | ||
163 | if (ret == MSIDBERROR_MOREDATA) | ||
164 | { | ||
165 | if (0 == EnsureBufSize(&szBuf, &cchBuf, ++cchValue)) | ||
166 | { | ||
167 | ret = func(in1, szBuf, &cchValue); | ||
168 | } | ||
169 | } | ||
170 | if (ret != MSIDBERROR_MOREDATA) | ||
171 | { | ||
172 | pResp->fields[1].vt = VT_LPWSTR; | ||
173 | pResp->fields[1].szValue = szBuf; | ||
174 | } | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | UINT MsiFunc_II_S(PMsiFunc_II_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) | ||
179 | { | ||
180 | int in1 = pReq->fields[0].iValue; | ||
181 | int in2 = pReq->fields[1].iValue; | ||
182 | szBuf[0] = L'\0'; | ||
183 | DWORD cchValue = cchBuf; | ||
184 | UINT ret = (UINT) func(in1, in2, szBuf, &cchValue); | ||
185 | if (ret == ERROR_MORE_DATA) | ||
186 | { | ||
187 | ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); | ||
188 | if (ret == 0) | ||
189 | { | ||
190 | ret = (UINT) func(in1, in2, szBuf, &cchValue); | ||
191 | } | ||
192 | } | ||
193 | if (ret == 0) | ||
194 | { | ||
195 | pResp->fields[1].vt = VT_LPWSTR; | ||
196 | pResp->fields[1].szValue = szBuf; | ||
197 | } | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | UINT MsiFunc_IS_S(PMsiFunc_IS_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) | ||
202 | { | ||
203 | int in1 = pReq->fields[0].iValue; | ||
204 | wchar_t* in2 = pReq->fields[1].szValue; | ||
205 | szBuf[0] = L'\0'; | ||
206 | DWORD cchValue = cchBuf; | ||
207 | UINT ret = (UINT) func(in1, in2, szBuf, &cchValue); | ||
208 | if (ret == ERROR_MORE_DATA) | ||
209 | { | ||
210 | ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); | ||
211 | if (ret == 0) | ||
212 | { | ||
213 | ret = (UINT) func(in1, in2, szBuf, &cchValue); | ||
214 | } | ||
215 | } | ||
216 | if (ret == 0) | ||
217 | { | ||
218 | pResp->fields[1].vt = VT_LPWSTR; | ||
219 | pResp->fields[1].szValue = szBuf; | ||
220 | } | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | UINT MsiFunc_ISII_SII(PMsiFunc_ISII_SII func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) | ||
225 | { | ||
226 | int in1 = pReq->fields[0].iValue; | ||
227 | wchar_t* in2 = pReq->fields[1].szValue; | ||
228 | int in3 = pReq->fields[2].iValue; | ||
229 | int in4 = pReq->fields[3].iValue; | ||
230 | szBuf[0] = L'\0'; | ||
231 | DWORD cchValue = cchBuf; | ||
232 | int out2, out3; | ||
233 | UINT ret = (UINT) func(in1, in2, in3, in4, szBuf, &cchValue, &out2, &out3); | ||
234 | if (ret == ERROR_MORE_DATA) | ||
235 | { | ||
236 | ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); | ||
237 | if (ret == 0) | ||
238 | { | ||
239 | ret = (UINT) func(in1, in2, in3, in4, szBuf, &cchValue, &out2, &out3); | ||
240 | } | ||
241 | } | ||
242 | if (ret == 0) | ||
243 | { | ||
244 | pResp->fields[1].vt = VT_LPWSTR; | ||
245 | pResp->fields[1].szValue = szBuf; | ||
246 | pResp->fields[2].vt = VT_I4; | ||
247 | pResp->fields[2].iValue = out2; | ||
248 | pResp->fields[3].vt = VT_I4; | ||
249 | pResp->fields[3].iValue = out3; | ||
250 | } | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | void RemoteMsiSession::ProcessRequest(RequestId id, const RequestData* pReq, RequestData* pResp) | ||
255 | { | ||
256 | SecureZeroMemory(pResp, sizeof(RequestData)); | ||
257 | |||
258 | UINT ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, 1024); | ||
259 | |||
260 | if (0 == ret) | ||
261 | { | ||
262 | switch (id) | ||
263 | { | ||
264 | case RemoteMsiSession::EndSession: | ||
265 | { | ||
266 | this->ExitCode = pReq->fields[0].iValue; | ||
267 | } | ||
268 | break; | ||
269 | case RemoteMsiSession::MsiCloseHandle: | ||
270 | { | ||
271 | MSIHANDLE h = (MSIHANDLE) pReq->fields[0].iValue; | ||
272 | ret = ::MsiCloseHandle(h); | ||
273 | } | ||
274 | break; | ||
275 | case RemoteMsiSession::MsiProcessMessage: | ||
276 | { | ||
277 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
278 | INSTALLMESSAGE eMessageType = (INSTALLMESSAGE) pReq->fields[1].iValue; | ||
279 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[2].iValue; | ||
280 | ret = ::MsiProcessMessage(hInstall, eMessageType, hRecord); | ||
281 | } | ||
282 | break; | ||
283 | case RemoteMsiSession::MsiGetProperty: | ||
284 | { | ||
285 | ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetProperty, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
286 | } | ||
287 | break; | ||
288 | case RemoteMsiSession::MsiSetProperty: | ||
289 | { | ||
290 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
291 | const wchar_t* szName = pReq->fields[1].szValue; | ||
292 | const wchar_t* szValue = pReq->fields[2].szValue; | ||
293 | ret = ::MsiSetProperty(hInstall, szName, szValue); | ||
294 | } | ||
295 | break; | ||
296 | case RemoteMsiSession::MsiCreateRecord: | ||
297 | { | ||
298 | UINT cParams = pReq->fields[0].uiValue; | ||
299 | ret = ::MsiCreateRecord(cParams); | ||
300 | } | ||
301 | break; | ||
302 | case RemoteMsiSession::MsiRecordGetFieldCount: | ||
303 | { | ||
304 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
305 | ret = ::MsiRecordGetFieldCount(hRecord); | ||
306 | } | ||
307 | break; | ||
308 | case RemoteMsiSession::MsiRecordGetInteger: | ||
309 | { | ||
310 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
311 | UINT iField = pReq->fields[1].uiValue; | ||
312 | ret = ::MsiRecordGetInteger(hRecord, iField); | ||
313 | } | ||
314 | break; | ||
315 | case RemoteMsiSession::MsiRecordSetInteger: | ||
316 | { | ||
317 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
318 | UINT iField = pReq->fields[1].uiValue; | ||
319 | int iValue = pReq->fields[2].iValue; | ||
320 | ret = ::MsiRecordSetInteger(hRecord, iField, iValue); | ||
321 | } | ||
322 | break; | ||
323 | case RemoteMsiSession::MsiRecordGetString: | ||
324 | { | ||
325 | ret = MsiFunc_II_S((PMsiFunc_II_S) ::MsiRecordGetString, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
326 | } | ||
327 | break; | ||
328 | case RemoteMsiSession::MsiRecordSetString: | ||
329 | { | ||
330 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
331 | UINT iField = pReq->fields[1].uiValue; | ||
332 | const wchar_t* szValue = pReq->fields[2].szValue; | ||
333 | ret = ::MsiRecordSetString(hRecord, iField, szValue); | ||
334 | } | ||
335 | break; | ||
336 | case RemoteMsiSession::MsiRecordClearData: | ||
337 | { | ||
338 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
339 | ret = ::MsiRecordClearData(hRecord); | ||
340 | } | ||
341 | break; | ||
342 | case RemoteMsiSession::MsiRecordIsNull: | ||
343 | { | ||
344 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
345 | UINT iField = pReq->fields[1].uiValue; | ||
346 | ret = ::MsiRecordIsNull(hRecord, iField); | ||
347 | } | ||
348 | break; | ||
349 | case RemoteMsiSession::MsiFormatRecord: | ||
350 | { | ||
351 | ret = MsiFunc_II_S((PMsiFunc_II_S) ::MsiFormatRecord, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
352 | } | ||
353 | break; | ||
354 | case RemoteMsiSession::MsiGetActiveDatabase: | ||
355 | { | ||
356 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
357 | ret = (UINT) ::MsiGetActiveDatabase(hInstall); | ||
358 | } | ||
359 | break; | ||
360 | case RemoteMsiSession::MsiDatabaseOpenView: | ||
361 | { | ||
362 | ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiDatabaseOpenView, pReq, pResp); | ||
363 | } | ||
364 | break; | ||
365 | case RemoteMsiSession::MsiViewExecute: | ||
366 | { | ||
367 | MSIHANDLE hView = (MSIHANDLE) pReq->fields[0].iValue; | ||
368 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[1].iValue; | ||
369 | ret = ::MsiViewExecute(hView, hRecord); | ||
370 | } | ||
371 | break; | ||
372 | case RemoteMsiSession::MsiViewFetch: | ||
373 | { | ||
374 | ret = MsiFunc_I_I((PMsiFunc_I_I) ::MsiViewFetch, pReq, pResp); | ||
375 | } | ||
376 | break; | ||
377 | case RemoteMsiSession::MsiViewModify: | ||
378 | { | ||
379 | MSIHANDLE hView = (MSIHANDLE) pReq->fields[0].iValue; | ||
380 | MSIMODIFY eModifyMode = (MSIMODIFY) pReq->fields[1].iValue; | ||
381 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[2].iValue; | ||
382 | ret = ::MsiViewModify(hView, eModifyMode, hRecord); | ||
383 | } | ||
384 | break; | ||
385 | case RemoteMsiSession::MsiViewGetError: | ||
386 | { | ||
387 | ret = MsiEFunc_I_S((PMsiEFunc_I_S) ::MsiViewGetError, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
388 | } | ||
389 | break; | ||
390 | case RemoteMsiSession::MsiViewGetColumnInfo: | ||
391 | { | ||
392 | ret = MsiFunc_II_I((PMsiFunc_II_I) ::MsiViewGetColumnInfo, pReq, pResp); | ||
393 | } | ||
394 | break; | ||
395 | case RemoteMsiSession::MsiDatabaseGetPrimaryKeys: | ||
396 | { | ||
397 | ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiDatabaseGetPrimaryKeys, pReq, pResp); | ||
398 | } | ||
399 | break; | ||
400 | case RemoteMsiSession::MsiDatabaseIsTablePersistent: | ||
401 | { | ||
402 | MSIHANDLE hDb = (MSIHANDLE) pReq->fields[0].iValue; | ||
403 | const wchar_t* szTable = pReq->fields[1].szValue; | ||
404 | ret = ::MsiDatabaseIsTablePersistent(hDb, szTable); | ||
405 | } | ||
406 | break; | ||
407 | case RemoteMsiSession::MsiDoAction: | ||
408 | { | ||
409 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
410 | const wchar_t* szAction = pReq->fields[1].szValue; | ||
411 | ret = ::MsiDoAction(hInstall, szAction); | ||
412 | } | ||
413 | break; | ||
414 | case RemoteMsiSession::MsiEnumComponentCosts: | ||
415 | { | ||
416 | ret = MsiFunc_ISII_SII((PMsiFunc_ISII_SII) ::MsiEnumComponentCosts, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
417 | } | ||
418 | break; | ||
419 | case RemoteMsiSession::MsiEvaluateCondition: | ||
420 | { | ||
421 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
422 | const wchar_t* szCondition = pReq->fields[1].szValue; | ||
423 | ret = ::MsiEvaluateCondition(hInstall, szCondition); | ||
424 | } | ||
425 | break; | ||
426 | case RemoteMsiSession::MsiGetComponentState: | ||
427 | { | ||
428 | ret = MsiFunc_IS_II((PMsiFunc_IS_II) ::MsiGetComponentState, pReq, pResp); | ||
429 | } | ||
430 | break; | ||
431 | case RemoteMsiSession::MsiGetFeatureCost: | ||
432 | { | ||
433 | ret = MsiFunc_ISII_I((PMsiFunc_ISII_I) ::MsiGetFeatureCost, pReq, pResp); | ||
434 | } | ||
435 | break; | ||
436 | case RemoteMsiSession::MsiGetFeatureState: | ||
437 | { | ||
438 | ret = MsiFunc_IS_II((PMsiFunc_IS_II) ::MsiGetFeatureState, pReq, pResp); | ||
439 | } | ||
440 | break; | ||
441 | case RemoteMsiSession::MsiGetFeatureValidStates: | ||
442 | { | ||
443 | ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiGetFeatureValidStates, pReq, pResp); | ||
444 | } | ||
445 | break; | ||
446 | case RemoteMsiSession::MsiGetLanguage: | ||
447 | { | ||
448 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
449 | ret = ::MsiGetLanguage(hInstall); | ||
450 | } | ||
451 | break; | ||
452 | case RemoteMsiSession::MsiGetLastErrorRecord: | ||
453 | { | ||
454 | ret = ::MsiGetLastErrorRecord(); | ||
455 | } | ||
456 | break; | ||
457 | case RemoteMsiSession::MsiGetMode: | ||
458 | { | ||
459 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
460 | MSIRUNMODE iRunMode = (MSIRUNMODE) pReq->fields[1].iValue; | ||
461 | ret = ::MsiGetMode(hInstall, iRunMode); | ||
462 | } | ||
463 | break; | ||
464 | case RemoteMsiSession::MsiGetSourcePath: | ||
465 | { | ||
466 | ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetSourcePath, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
467 | } | ||
468 | break; | ||
469 | case RemoteMsiSession::MsiGetSummaryInformation: | ||
470 | { | ||
471 | ret = MsiFunc_ISI_I((PMsiFunc_ISI_I) ::MsiGetSummaryInformation, pReq, pResp); | ||
472 | } | ||
473 | break; | ||
474 | case RemoteMsiSession::MsiGetTargetPath: | ||
475 | { | ||
476 | ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetTargetPath, pReq, pResp, m_pBufSend, m_cbBufSend); | ||
477 | } | ||
478 | break; | ||
479 | case RemoteMsiSession::MsiRecordDataSize: | ||
480 | { | ||
481 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
482 | UINT iField = pReq->fields[1].uiValue; | ||
483 | ret = ::MsiRecordDataSize(hRecord, iField); | ||
484 | } | ||
485 | break; | ||
486 | case RemoteMsiSession::MsiRecordReadStream: | ||
487 | { | ||
488 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
489 | UINT iField = pReq->fields[1].uiValue; | ||
490 | DWORD cbRead = (DWORD) pReq->fields[2].uiValue; | ||
491 | ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, (cbRead + 1) / 2); | ||
492 | if (ret == 0) | ||
493 | { | ||
494 | ret = ::MsiRecordReadStream(hRecord, iField, (char*) m_pBufSend, &cbRead); | ||
495 | if (ret == 0) | ||
496 | { | ||
497 | pResp->fields[1].vt = VT_STREAM; | ||
498 | pResp->fields[1].szValue = m_pBufSend; | ||
499 | pResp->fields[2].vt = VT_I4; | ||
500 | pResp->fields[2].uiValue = (UINT) cbRead; | ||
501 | } | ||
502 | } | ||
503 | } | ||
504 | break; | ||
505 | case RemoteMsiSession::MsiRecordSetStream: | ||
506 | { | ||
507 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
508 | UINT iField = pReq->fields[1].uiValue; | ||
509 | const wchar_t* szFilePath = pReq->fields[2].szValue; | ||
510 | ret = ::MsiRecordSetStream(hRecord, iField, szFilePath); | ||
511 | } | ||
512 | break; | ||
513 | case RemoteMsiSession::MsiSequence: | ||
514 | { | ||
515 | MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; | ||
516 | const wchar_t* szTable = pReq->fields[1].szValue; | ||
517 | UINT iSequenceMode = pReq->fields[2].uiValue; | ||
518 | ret = ::MsiSequence(hRecord, szTable, iSequenceMode); | ||
519 | } | ||
520 | break; | ||
521 | case RemoteMsiSession::MsiSetComponentState: | ||
522 | { | ||
523 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
524 | const wchar_t* szComponent = pReq->fields[1].szValue; | ||
525 | INSTALLSTATE iState = (INSTALLSTATE) pReq->fields[2].iValue; | ||
526 | ret = ::MsiSetComponentState(hInstall, szComponent, iState); | ||
527 | } | ||
528 | break; | ||
529 | case RemoteMsiSession::MsiSetFeatureAttributes: | ||
530 | { | ||
531 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
532 | const wchar_t* szFeature = pReq->fields[1].szValue; | ||
533 | DWORD dwAttrs = (DWORD) pReq->fields[2].uiValue; | ||
534 | ret = ::MsiSetFeatureAttributes(hInstall, szFeature, dwAttrs); | ||
535 | } | ||
536 | break; | ||
537 | case RemoteMsiSession::MsiSetFeatureState: | ||
538 | { | ||
539 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
540 | const wchar_t* szFeature = pReq->fields[1].szValue; | ||
541 | INSTALLSTATE iState = (INSTALLSTATE) pReq->fields[2].iValue; | ||
542 | ret = ::MsiSetFeatureState(hInstall, szFeature, iState); | ||
543 | } | ||
544 | break; | ||
545 | case RemoteMsiSession::MsiSetInstallLevel: | ||
546 | { | ||
547 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
548 | int iInstallLevel = pReq->fields[1].iValue; | ||
549 | ret = ::MsiSetInstallLevel(hInstall, iInstallLevel); | ||
550 | } | ||
551 | break; | ||
552 | case RemoteMsiSession::MsiSetMode: | ||
553 | { | ||
554 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
555 | MSIRUNMODE iRunMode = (MSIRUNMODE) pReq->fields[1].uiValue; | ||
556 | BOOL fState = (BOOL) pReq->fields[2].iValue; | ||
557 | ret = ::MsiSetMode(hInstall, iRunMode, fState); | ||
558 | } | ||
559 | break; | ||
560 | case RemoteMsiSession::MsiSetTargetPath: | ||
561 | { | ||
562 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
563 | const wchar_t* szFolder = pReq->fields[1].szValue; | ||
564 | const wchar_t* szFolderPath = pReq->fields[2].szValue; | ||
565 | ret = ::MsiSetTargetPath(hInstall, szFolder, szFolderPath); | ||
566 | } | ||
567 | break; | ||
568 | case RemoteMsiSession::MsiSummaryInfoGetProperty: | ||
569 | { | ||
570 | MSIHANDLE hSummaryInfo = (MSIHANDLE) pReq->fields[0].iValue; | ||
571 | UINT uiProperty = pReq->fields[1].uiValue; | ||
572 | UINT uiDataType; | ||
573 | int iValue; | ||
574 | FILETIME ftValue; | ||
575 | m_pBufSend[0] = L'\0'; | ||
576 | DWORD cchValue = m_cbBufSend; | ||
577 | ret = ::MsiSummaryInfoGetProperty(hSummaryInfo, uiProperty, &uiDataType, &iValue, &ftValue, m_pBufSend, &cchValue); | ||
578 | if (ret == ERROR_MORE_DATA) | ||
579 | { | ||
580 | ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, ++cchValue); | ||
581 | if (ret == 0) | ||
582 | { | ||
583 | ret = ::MsiSummaryInfoGetProperty(hSummaryInfo, uiProperty, &uiDataType, &iValue, &ftValue, m_pBufSend, &cchValue); | ||
584 | } | ||
585 | } | ||
586 | if (ret == 0) | ||
587 | { | ||
588 | pResp->fields[1].vt = VT_UI4; | ||
589 | pResp->fields[1].uiValue = uiDataType; | ||
590 | |||
591 | switch (uiDataType) | ||
592 | { | ||
593 | case VT_I2: | ||
594 | case VT_I4: | ||
595 | pResp->fields[2].vt = VT_I4; | ||
596 | pResp->fields[2].iValue = iValue; | ||
597 | break; | ||
598 | case VT_FILETIME: | ||
599 | pResp->fields[2].vt = VT_UI4; | ||
600 | pResp->fields[2].iValue = ftValue.dwHighDateTime; | ||
601 | pResp->fields[3].vt = VT_UI4; | ||
602 | pResp->fields[3].iValue = ftValue.dwLowDateTime; | ||
603 | break; | ||
604 | case VT_LPSTR: | ||
605 | pResp->fields[2].vt = VT_LPWSTR; | ||
606 | pResp->fields[2].szValue = m_pBufSend; | ||
607 | break; | ||
608 | } | ||
609 | } | ||
610 | } | ||
611 | break; | ||
612 | case RemoteMsiSession::MsiVerifyDiskSpace: | ||
613 | { | ||
614 | MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; | ||
615 | ret = ::MsiVerifyDiskSpace(hInstall); | ||
616 | } | ||
617 | break; | ||
618 | |||
619 | default: | ||
620 | { | ||
621 | ret = ERROR_INVALID_FUNCTION; | ||
622 | } | ||
623 | break; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | pResp->fields[0].vt = VT_UI4; | ||
628 | pResp->fields[0].uiValue = ret; | ||
629 | } | ||