diff options
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 | } | ||