ReactOS 0.4.15-dev-7958-gcd0bb1a
automation.c
Go to the documentation of this file.
1/*
2 * Implementation of OLE Automation for Microsoft Installer (msi.dll)
3 *
4 * Copyright 2007 Misha Koshelev
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define COBJMACROS
22
23#include <stdarg.h>
24#include "windef.h"
25#include "winbase.h"
26#include "winerror.h"
27#include "winuser.h"
28#include "winreg.h"
29#include "msidefs.h"
30#include "msipriv.h"
31#include "activscp.h"
32#include "oleauto.h"
33#include "shlwapi.h"
34#include "wine/debug.h"
35
36#include "msiserver.h"
37#include "msiserver_dispids.h"
38
40
41#define REG_INDEX_CLASSES_ROOT 0
42#define REG_INDEX_DYN_DATA 6
43
45
46/* function that is called from AutomationObject::Invoke, specific to this type of object */
48 DISPID dispIdMember, REFIID riid, LCID lcid, WORD flags, DISPPARAMS* pDispParams,
49 VARIANT* result, EXCEPINFO* ei, UINT* arg_err);
50/* function that is called from AutomationObject::Release when the object is being freed
51 to free any private data structures (or NULL) */
53
54typedef struct {
58} tid_id_t;
59
60
61static HRESULT database_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
63static HRESULT record_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
64static HRESULT session_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
65static HRESULT list_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
66static void list_free(AutomationObject*);
68static HRESULT view_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
69
70static tid_id_t tid_ids[] = {
71 { &DIID_Database, database_invoke },
72 { &DIID_Installer, installer_invoke },
73 { &DIID_Record, record_invoke },
74 { &DIID_Session, session_invoke },
75 { &DIID_StringList, list_invoke, list_free },
76 { &DIID_SummaryInfo, summaryinfo_invoke },
77 { &DIID_View, view_invoke }
78};
79
82
84{
85 return tid_ids[tid].riid;
86}
87
89{
90 HRESULT hr;
91
92 if (!typelib)
93 {
94 ITypeLib *lib;
95
96 hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, LOCALE_NEUTRAL, &lib);
97 if (FAILED(hr)) {
98 hr = LoadTypeLib(L"msiserver.tlb", &lib);
99 if (FAILED(hr)) {
100 ERR("Could not load msiserver.tlb\n");
101 return hr;
102 }
103 }
104
106 ITypeLib_Release(lib);
107 }
108
109 if (!typeinfos[tid])
110 {
111 ITypeInfo *ti;
112
113 hr = ITypeLib_GetTypeInfoOfGuid(typelib, get_riid_from_tid(tid), &ti);
114 if (FAILED(hr)) {
115 ERR("Could not load ITypeInfo for %s\n", debugstr_guid(get_riid_from_tid(tid)));
116 return hr;
117 }
118
120 ITypeInfo_Release(ti);
121 }
122
124 return S_OK;
125}
126
128{
129 unsigned i;
130
131 for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
132 if (typeinfos[i])
133 ITypeInfo_Release(typeinfos[i]);
134
135 if (typelib)
136 ITypeLib_Release(typelib);
137}
138
139/*
140 * AutomationObject - "base" class for all automation objects. For each interface, we implement Invoke function
141 * called from AutomationObject::Invoke.
142 */
147
148 /* type id for this class */
150
151 /* The MSI handle of the current object */
153};
154
155typedef struct {
157 int count;
159} ListObject;
160
165
166/* ListEnumerator - IEnumVARIANT implementation for MSI automation lists */
167typedef struct {
170
171 /* Current position and pointer to AutomationObject that stores actual data */
175
176typedef struct {
180
182{
183 return CONTAINING_RECORD(iface, AutomationObject, IProvideMultipleClassInfo_iface);
184}
185
187{
188 return CONTAINING_RECORD(iface, AutomationObject, IDispatch_iface);
189}
190
191/* AutomationObject methods */
193{
195
196 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
197
198 if (ppvObject == NULL)
199 return E_INVALIDARG;
200
201 *ppvObject = 0;
202
206 *ppvObject = &This->IDispatch_iface;
209 IsEqualGUID(riid, &IID_IProvideMultipleClassInfo))
210 *ppvObject = &This->IProvideMultipleClassInfo_iface;
211 else
212 {
213 TRACE("() : asking for unsupported interface %s\n", debugstr_guid(riid));
214 return E_NOINTERFACE;
215 }
216
217 IDispatch_AddRef(iface);
218
219 return S_OK;
220}
221
223{
225
226 TRACE("(%p/%p)\n", iface, This);
227
228 return InterlockedIncrement(&This->ref);
229}
230
232{
235
236 TRACE("(%p/%p)\n", iface, This);
237
238 if (!ref)
239 {
240 if (tid_ids[This->tid].fn_free) tid_ids[This->tid].fn_free(This);
241 MsiCloseHandle(This->msiHandle);
242 msi_free(This);
243 }
244
245 return ref;
246}
247
249 IDispatch* iface,
250 UINT* pctinfo)
251{
253
254 TRACE("(%p/%p)->(%p)\n", iface, This, pctinfo);
255 *pctinfo = 1;
256 return S_OK;
257}
258
260 IDispatch* iface,
261 UINT iTInfo,
262 LCID lcid,
263 ITypeInfo** ppTInfo)
264{
266 HRESULT hr;
267
268 TRACE( "(%p/%p)->(%u, %ld, %p)\n", iface, This, iTInfo, lcid, ppTInfo );
269
270 hr = get_typeinfo(This->tid, ppTInfo);
271 if (FAILED(hr))
272 return hr;
273
274 ITypeInfo_AddRef(*ppTInfo);
275 return hr;
276}
277
279 IDispatch* iface,
280 REFIID riid,
281 LPOLESTR* rgszNames,
282 UINT cNames,
283 LCID lcid,
284 DISPID* rgDispId)
285{
287 ITypeInfo *ti;
288 HRESULT hr;
289
290 TRACE("(%p/%p)->(%s, %p, %u, %ld, %p)\n", iface, This,
291 debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
292
293 if (!IsEqualGUID(riid, &IID_NULL)) return E_INVALIDARG;
294
295 hr = get_typeinfo(This->tid, &ti);
296 if (FAILED(hr))
297 return hr;
298
299 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
300 if (hr == DISP_E_UNKNOWNNAME)
301 {
302 UINT idx;
303 for (idx=0; idx<cNames; idx++)
304 {
305 if (rgDispId[idx] == DISPID_UNKNOWN)
306 FIXME("Unknown member %s, clsid %s\n", debugstr_w(rgszNames[idx]), debugstr_guid(get_riid_from_tid(This->tid)));
307 }
308 }
309 return hr;
310}
311
312/* Maximum number of allowed function parameters+1 */
313#define MAX_FUNC_PARAMS 20
314
315/* Some error checking is done here to simplify individual object function invocation */
317 IDispatch* iface,
318 DISPID dispIdMember,
319 REFIID riid,
320 LCID lcid,
321 WORD wFlags,
322 DISPPARAMS* pDispParams,
323 VARIANT* pVarResult,
324 EXCEPINFO* pExcepInfo,
325 UINT* puArgErr)
326{
328 HRESULT hr;
329 unsigned int uArgErr;
330 VARIANT varResultDummy;
331 BSTR bstrName = NULL;
332 ITypeInfo *ti;
333
334 TRACE("(%p/%p)->(%ld, %s, %ld, %d, %p, %p, %p, %p)\n", iface, This,
335 dispIdMember, debugstr_guid(riid), lcid, wFlags,
336 pDispParams, pVarResult, pExcepInfo, puArgErr);
337
338 if (!IsEqualIID(riid, &IID_NULL))
339 {
340 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
341 return DISP_E_UNKNOWNNAME;
342 }
343
344 if (wFlags & DISPATCH_PROPERTYGET && !pVarResult)
345 {
346 ERR("NULL pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
348 }
349
350 /* This simplifies our individual object invocation functions */
351 if (puArgErr == NULL) puArgErr = &uArgErr;
352 if (pVarResult == NULL) pVarResult = &varResultDummy;
353
354 hr = get_typeinfo(This->tid, &ti);
355 if (FAILED(hr))
356 return hr;
357
358 /* Assume return type is void unless determined otherwise */
359 VariantInit(pVarResult);
360
361 /* If we are tracing, we want to see the name of the member we are invoking */
362 if (TRACE_ON(msi))
363 {
364 ITypeInfo_GetDocumentation(ti, dispIdMember, &bstrName, NULL, NULL, NULL);
365 TRACE("method %ld, %s\n", dispIdMember, debugstr_w(bstrName));
366 }
367
368 hr = tid_ids[This->tid].fn_invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
369
370 if (hr == DISP_E_MEMBERNOTFOUND) {
371 if (bstrName == NULL) ITypeInfo_GetDocumentation(ti, dispIdMember, &bstrName, NULL, NULL, NULL);
372 FIXME("method %ld, %s wflags %d not implemented, clsid %s\n", dispIdMember, debugstr_w(bstrName), wFlags,
374 }
375 else if (pExcepInfo &&
377 hr == DISP_E_EXCEPTION)) {
378 WCHAR szExceptionDescription[MAX_PATH];
379 BSTR bstrParamNames[MAX_FUNC_PARAMS];
380 unsigned namesNo, i;
381 BOOL bFirst = TRUE;
382
383 if (FAILED(ITypeInfo_GetNames(ti, dispIdMember, bstrParamNames,
384 MAX_FUNC_PARAMS, &namesNo)))
385 {
386 TRACE("failed to retrieve names for dispIdMember %ld\n", dispIdMember);
387 }
388 else
389 {
390 memset(szExceptionDescription, 0, sizeof(szExceptionDescription));
391 for (i=0; i<namesNo; i++)
392 {
393 if (bFirst) bFirst = FALSE;
394 else {
395 lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], L",");
396 }
397 lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], bstrParamNames[i]);
398 SysFreeString(bstrParamNames[i]);
399 }
400
401 memset(pExcepInfo, 0, sizeof(EXCEPINFO));
402 pExcepInfo->wCode = 1000;
403 pExcepInfo->bstrSource = SysAllocString(L"Msi API Error");
404 pExcepInfo->bstrDescription = SysAllocString(szExceptionDescription);
406 }
407 }
408
409 /* Make sure we free the return variant if it is our dummy variant */
410 if (pVarResult == &varResultDummy) VariantClear(pVarResult);
411
412 /* Free function name if we retrieved it */
413 SysFreeString(bstrName);
414
415 TRACE("returning %#lx, %s\n", hr, SUCCEEDED(hr) ? "ok" : "not ok");
416
417 return hr;
418}
419
420static const struct IDispatchVtbl AutomationObjectVtbl =
421{
429};
430
431/*
432 * IProvideMultipleClassInfo methods
433 */
434
437 REFIID riid,
438 VOID** ppvoid)
439{
441 return IDispatch_QueryInterface(&This->IDispatch_iface, riid, ppvoid);
442}
443
445{
447 return IDispatch_AddRef(&This->IDispatch_iface);
448}
449
451{
453 return IDispatch_Release(&This->IDispatch_iface);
454}
455
457{
459 HRESULT hr;
460
461 TRACE("(%p/%p)->(%p)\n", iface, This, ppTI);
462
463 hr = get_typeinfo(This->tid, ppTI);
464 if (SUCCEEDED(hr))
465 ITypeInfo_AddRef(*ppTI);
466
467 return hr;
468}
469
471{
473 TRACE("(%p/%p)->(%lu, %s)\n", iface, This, dwGuidKind, debugstr_guid(pGUID));
474
475 if (dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID)
476 return E_INVALIDARG;
477 else {
478 *pGUID = *get_riid_from_tid(This->tid);
479 return S_OK;
480 }
481}
482
484{
486
487 TRACE("(%p/%p)->(%p)\n", iface, This, pcti);
488 *pcti = 1;
489 return S_OK;
490}
491
493 ULONG iti,
495 ITypeInfo** ti,
496 DWORD* pdwTIFlags,
497 ULONG* pcdispidReserved,
498 IID* piidPrimary,
499 IID* piidSource)
500{
502
503 TRACE("(%p/%p)->(%lu, %#lx, %p, %p, %p, %p, %p)\n", iface, This, iti, dwFlags, ti, pdwTIFlags, pcdispidReserved,
504 piidPrimary, piidSource);
505
506 if (iti != 0)
507 return E_INVALIDARG;
508
509 if (dwFlags & MULTICLASSINFO_GETTYPEINFO)
510 {
511 HRESULT hr = get_typeinfo(This->tid, ti);
512 if (FAILED(hr))
513 return hr;
514
515 ITypeInfo_AddRef(*ti);
516 }
517
518 if (dwFlags & MULTICLASSINFO_GETNUMRESERVEDDISPIDS)
519 {
520 *pdwTIFlags = 0;
521 *pcdispidReserved = 0;
522 }
523
524 if (dwFlags & MULTICLASSINFO_GETIIDPRIMARY)
525 *piidPrimary = *get_riid_from_tid(This->tid);
526
527 if (dwFlags & MULTICLASSINFO_GETIIDSOURCE)
528 *piidSource = *get_riid_from_tid(This->tid);
529
530 return S_OK;
531}
532
533static const IProvideMultipleClassInfoVtbl ProvideMultipleClassInfoVtbl =
534{
542};
543
545{
546 TRACE("%p, %lu, %s\n", This, msiHandle, debugstr_guid(get_riid_from_tid(tid)));
547
548 This->IDispatch_iface.lpVtbl = &AutomationObjectVtbl;
549 This->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl;
550 This->ref = 1;
551 This->msiHandle = msiHandle;
552 This->tid = tid;
553}
554
555/*
556 * ListEnumerator methods
557 */
558
560{
561 return CONTAINING_RECORD(iface, ListEnumerator, IEnumVARIANT_iface);
562}
563
565 void** ppvObject)
566{
568
569 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
570
571 if (ppvObject == NULL)
572 return E_INVALIDARG;
573
574 *ppvObject = 0;
575
577 IsEqualGUID(riid, &IID_IEnumVARIANT))
578 {
579 *ppvObject = &This->IEnumVARIANT_iface;
580 }
581 else
582 {
583 TRACE("() : asking for unsupported interface %s\n",debugstr_guid(riid));
584 return E_NOINTERFACE;
585 }
586
587 IEnumVARIANT_AddRef(iface);
588 return S_OK;
589}
590
592{
594
595 TRACE("(%p/%p)\n", iface, This);
596
597 return InterlockedIncrement(&This->ref);
598}
599
601{
604
605 TRACE("(%p/%p)\n", iface, This);
606
607 if (!ref)
608 {
609 if (This->list) IDispatch_Release(&This->list->autoobj.IDispatch_iface);
610 msi_free(This);
611 }
612
613 return ref;
614}
615
617 ULONG* fetched)
618{
620 ULONG i, local;
621
622 TRACE("%p, %lu, %p, %p\n", iface, celt, rgVar, fetched);
623
624 if (fetched) *fetched = 0;
625
626 if (!rgVar)
627 return S_FALSE;
628
629 for (local = 0; local < celt; local++)
630 VariantInit(&rgVar[local]);
631
632 for (i = This->pos, local = 0; i < This->list->count && local < celt; i++, local++)
633 VariantCopy(&rgVar[local], &This->list->data[i]);
634
635 if (fetched) *fetched = local;
636 This->pos = i;
637
638 return (local < celt) ? S_FALSE : S_OK;
639}
640
642{
644
645 TRACE("%p, %lu\n", iface, celt);
646
647 This->pos += celt;
648 if (This->pos >= This->list->count)
649 {
650 This->pos = This->list->count;
651 return S_FALSE;
652 }
653
654 return S_OK;
655}
656
658{
660
661 TRACE("(%p)\n", iface);
662
663 This->pos = 0;
664 return S_OK;
665}
666
668{
670 HRESULT hr;
671
672 TRACE("(%p,%p)\n", iface, ppEnum);
673
674 if (ppEnum == NULL)
675 return S_FALSE;
676
677 *ppEnum = NULL;
678 hr = create_list_enumerator(This->list, (LPVOID *)ppEnum);
679 if (FAILED(hr))
680 {
681 if (*ppEnum) IEnumVARIANT_Release(*ppEnum);
682 return hr;
683 }
684
685 return S_OK;
686}
687
688static const struct IEnumVARIANTVtbl ListEnumerator_Vtbl =
689{
697};
698
699/* Create a list enumerator, placing the result in the pointer ppObj. */
701{
703
704 TRACE("(%p, %p)\n", list, ppObj);
705
706 object = msi_alloc(sizeof(ListEnumerator));
707
708 /* Set all the VTable references */
709 object->IEnumVARIANT_iface.lpVtbl = &ListEnumerator_Vtbl;
710 object->ref = 1;
711
712 /* Store data that was passed */
713 object->pos = 0;
714 object->list = list;
715 if (list) IDispatch_AddRef(&list->autoobj.IDispatch_iface);
716
717 *ppObj = object;
718 return S_OK;
719}
720
721/*
722 * Individual Object Invocation Functions
723 */
724
725/* Helper function that copies a passed parameter instead of using VariantChangeType like the actual DispGetParam.
726 This function is only for VARIANT type parameters that have several types that cannot be properly discriminated
727 using DispGetParam/VariantChangeType. */
729 DISPPARAMS *pdispparams, /* [in] Parameter list */
730 UINT *position, /* [in] Position of parameter to copy in pdispparams; on return will contain calculated position */
731 VARIANT *pvarResult) /* [out] Destination for resulting variant */
732{
733 /* position is counted backwards */
734 UINT pos;
735
736 TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
737 *position, pdispparams->cArgs, pdispparams->cNamedArgs);
738 if (*position < pdispparams->cArgs) {
739 /* positional arg? */
740 pos = pdispparams->cArgs - *position - 1;
741 } else {
742 /* FIXME: is this how to handle named args? */
743 for (pos=0; pos<pdispparams->cNamedArgs; pos++)
744 if (pdispparams->rgdispidNamedArgs[pos] == *position) break;
745
746 if (pos==pdispparams->cNamedArgs)
748 }
749 *position = pos;
750 return VariantCopyInd(pvarResult,
751 &pdispparams->rgvarg[pos]);
752}
753
756 DISPID dispIdMember,
757 REFIID riid,
758 LCID lcid,
759 WORD wFlags,
760 DISPPARAMS* pDispParams,
761 VARIANT* pVarResult,
762 EXCEPINFO* pExcepInfo,
763 UINT* puArgErr)
764{
765 UINT ret;
766 VARIANTARG varg0, varg1;
767 FILETIME ft, ftlocal;
768 SYSTEMTIME st;
769 HRESULT hr;
770
771 VariantInit(&varg0);
772 VariantInit(&varg1);
773
774 switch (dispIdMember)
775 {
778 {
779 UINT type;
780 INT value;
781 DWORD size = 0;
782 DATE date;
783 LPWSTR str;
784
785 static WCHAR szEmpty[] = L"";
786
787 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
788 if (FAILED(hr)) return hr;
789 ret = MsiSummaryInfoGetPropertyW(This->msiHandle, V_I4(&varg0), &type, &value,
790 &ft, szEmpty, &size);
791 if (ret != ERROR_SUCCESS &&
793 {
794 ERR("MsiSummaryInfoGetProperty returned %d\n", ret);
795 return DISP_E_EXCEPTION;
796 }
797
798 switch (type)
799 {
800 case VT_EMPTY:
801 break;
802
803 case VT_I2:
804 case VT_I4:
805 V_VT(pVarResult) = VT_I4;
806 V_I4(pVarResult) = value;
807 break;
808
809 case VT_LPSTR:
810 if (!(str = msi_alloc(++size * sizeof(WCHAR))))
811 ERR("Out of memory\n");
812 else if ((ret = MsiSummaryInfoGetPropertyW(This->msiHandle, V_I4(&varg0), &type, NULL,
813 NULL, str, &size)) != ERROR_SUCCESS)
814 ERR("MsiSummaryInfoGetProperty returned %d\n", ret);
815 else
816 {
817 V_VT(pVarResult) = VT_BSTR;
818 V_BSTR(pVarResult) = SysAllocString(str);
819 }
820 msi_free(str);
821 break;
822
823 case VT_FILETIME:
824 FileTimeToLocalFileTime(&ft, &ftlocal);
825 FileTimeToSystemTime(&ftlocal, &st);
827
828 V_VT(pVarResult) = VT_DATE;
829 V_DATE(pVarResult) = date;
830 break;
831
832 default:
833 ERR("Unhandled variant type %d\n", type);
834 }
835 }
836 else if (wFlags & DISPATCH_PROPERTYPUT)
837 {
838 UINT posValue = DISPID_PROPERTYPUT;
839
840 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
841 if (FAILED(hr)) return hr;
842 hr = DispGetParam_CopyOnly(pDispParams, &posValue, &varg1);
843 if (FAILED(hr))
844 {
845 *puArgErr = posValue;
846 return hr;
847 }
848
849 switch (V_VT(&varg1))
850 {
851 case VT_I2:
852 case VT_I4:
853 ret = MsiSummaryInfoSetPropertyW(This->msiHandle, V_I4(&varg0), V_VT(&varg1), V_I4(&varg1), NULL, NULL);
854 break;
855
856 case VT_DATE:
857 VariantTimeToSystemTime(V_DATE(&varg1), &st);
858 SystemTimeToFileTime(&st, &ftlocal);
859 LocalFileTimeToFileTime(&ftlocal, &ft);
860 ret = MsiSummaryInfoSetPropertyW(This->msiHandle, V_I4(&varg0), VT_FILETIME, 0, &ft, NULL);
861 break;
862
863 case VT_BSTR:
864 ret = MsiSummaryInfoSetPropertyW(This->msiHandle, V_I4(&varg0), VT_LPSTR, 0, NULL, V_BSTR(&varg1));
865 break;
866
867 default:
868 FIXME("Unhandled variant type %d\n", V_VT(&varg1));
869 VariantClear(&varg1);
870 return DISP_E_EXCEPTION;
871 }
872
873 if (ret != ERROR_SUCCESS)
874 {
875 ERR("MsiSummaryInfoSetPropertyW returned %d\n", ret);
876 return DISP_E_EXCEPTION;
877 }
878 }
879 else return DISP_E_MEMBERNOTFOUND;
880 break;
881
884 UINT count;
886 ERR("MsiSummaryInfoGetPropertyCount returned %d\n", ret);
887 else
888 {
889 V_VT(pVarResult) = VT_I4;
890 V_I4(pVarResult) = count;
891 }
892 }
893 else return DISP_E_MEMBERNOTFOUND;
894 break;
895
896 default:
898 }
899
900 VariantClear(&varg1);
901 VariantClear(&varg0);
902
903 return S_OK;
904}
905
908 DISPID dispIdMember,
909 REFIID riid,
910 LCID lcid,
911 WORD wFlags,
912 DISPPARAMS* pDispParams,
913 VARIANT* pVarResult,
914 EXCEPINFO* pExcepInfo,
915 UINT* puArgErr)
916{
917 WCHAR *szString;
918 DWORD dwLen = 0;
919 UINT ret;
920 VARIANTARG varg0, varg1;
921 HRESULT hr;
922
923 VariantInit(&varg0);
924 VariantInit(&varg1);
925
926 switch (dispIdMember)
927 {
930 V_VT(pVarResult) = VT_I4;
931 V_I4(pVarResult) = MsiRecordGetFieldCount(This->msiHandle);
932 }
933 else return DISP_E_MEMBERNOTFOUND;
934 break;
935
938 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
939 if (FAILED(hr)) return hr;
940 V_VT(pVarResult) = VT_BSTR;
941 V_BSTR(pVarResult) = NULL;
942 if ((ret = MsiRecordGetStringW(This->msiHandle, V_I4(&varg0), NULL, &dwLen)) == ERROR_SUCCESS)
943 {
944 if (!(szString = msi_alloc((++dwLen)*sizeof(WCHAR))))
945 ERR("Out of memory\n");
946 else if ((ret = MsiRecordGetStringW(This->msiHandle, V_I4(&varg0), szString, &dwLen)) == ERROR_SUCCESS)
947 V_BSTR(pVarResult) = SysAllocString(szString);
948 msi_free(szString);
949 }
950 if (ret != ERROR_SUCCESS)
951 ERR("MsiRecordGetString returned %d\n", ret);
952 } else if (wFlags & DISPATCH_PROPERTYPUT) {
953 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
954 if (FAILED(hr)) return hr;
955 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
956 if (FAILED(hr)) return hr;
957 if ((ret = MsiRecordSetStringW(This->msiHandle, V_I4(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS)
958 {
959 VariantClear(&varg1);
960 ERR("MsiRecordSetString returned %d\n", ret);
961 return DISP_E_EXCEPTION;
962 }
963 }
964 else return DISP_E_MEMBERNOTFOUND;
965 break;
966
969 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
970 if (FAILED(hr)) return hr;
971 V_VT(pVarResult) = VT_I4;
972 V_I4(pVarResult) = MsiRecordGetInteger(This->msiHandle, V_I4(&varg0));
973 } else if (wFlags & DISPATCH_PROPERTYPUT) {
974 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
975 if (FAILED(hr)) return hr;
976 hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr);
977 if (FAILED(hr)) return hr;
978 if ((ret = MsiRecordSetInteger(This->msiHandle, V_I4(&varg0), V_I4(&varg1))) != ERROR_SUCCESS)
979 {
980 ERR("MsiRecordSetInteger returned %d\n", ret);
981 return DISP_E_EXCEPTION;
982 }
983 }
984 else return DISP_E_MEMBERNOTFOUND;
985 break;
986
987 default:
989 }
990
991 VariantClear(&varg1);
992 VariantClear(&varg0);
993
994 return S_OK;
995}
996
997static HRESULT create_record(MSIHANDLE msiHandle, IDispatch **disp)
998{
1000
1001 record = msi_alloc(sizeof(*record));
1002 if (!record) return E_OUTOFMEMORY;
1003
1005
1006 *disp = &record->IDispatch_iface;
1007
1008 return S_OK;
1009}
1010
1013 DISPID dispIdMember,
1014 REFIID riid,
1015 LCID lcid,
1016 WORD wFlags,
1017 DISPPARAMS* pDispParams,
1018 VARIANT* pVarResult,
1019 EXCEPINFO* pExcepInfo,
1020 UINT* puArgErr)
1021{
1023 IUnknown *pUnk = NULL;
1024 HRESULT hr;
1025
1026 switch (dispIdMember)
1027 {
1029 if (wFlags & DISPATCH_METHOD) {
1030 V_VT(pVarResult) = VT_UNKNOWN;
1032 V_UNKNOWN(pVarResult) = pUnk;
1033 else
1034 ERR("failed to create IEnumVARIANT object, hresult %#lx\n", hr);
1035 }
1036 else return DISP_E_MEMBERNOTFOUND;
1037 break;
1038
1039 case DISPID_LIST_ITEM:
1042
1044 hr = DispGetParam(pDispParams, 0, VT_I4, &index, puArgErr);
1045 if (FAILED(hr)) return hr;
1046 if (V_I4(&index) < 0 || V_I4(&index) >= list->count)
1047 return DISP_E_BADINDEX;
1048 VariantCopy(pVarResult, &list->data[V_I4(&index)]);
1049 }
1050 else return DISP_E_MEMBERNOTFOUND;
1051 break;
1052
1053 case DISPID_LIST_COUNT:
1055 V_VT(pVarResult) = VT_I4;
1056 V_I4(pVarResult) = list->count;
1057 }
1058 else return DISP_E_MEMBERNOTFOUND;
1059 break;
1060
1061 default:
1062 return DISP_E_MEMBERNOTFOUND;
1063 }
1064
1065 return S_OK;
1066}
1067
1069{
1071 int i;
1072
1073 for (i = 0; i < list->count; i++)
1074 VariantClear(&list->data[i]);
1075 msi_free(list->data);
1076}
1077
1078static HRESULT get_products_count(const WCHAR *product, int *len)
1079{
1080 int i = 0;
1081
1082 while (1)
1083 {
1084 WCHAR dataW[GUID_SIZE];
1085 UINT ret;
1086
1087 /* all or related only */
1088 if (product)
1089 ret = MsiEnumRelatedProductsW(product, 0, i, dataW);
1090 else
1091 ret = MsiEnumProductsW(i, dataW);
1092
1093 if (ret == ERROR_NO_MORE_ITEMS) break;
1094
1095 if (ret != ERROR_SUCCESS)
1096 return DISP_E_EXCEPTION;
1097
1098 i++;
1099 }
1100
1101 *len = i;
1102
1103 return S_OK;
1104}
1105
1106static HRESULT create_list(const WCHAR *product, IDispatch **dispatch)
1107{
1109 HRESULT hr;
1110 int i;
1111
1112 list = msi_alloc_zero(sizeof(ListObject));
1113 if (!list) return E_OUTOFMEMORY;
1114
1116
1117 *dispatch = &list->autoobj.IDispatch_iface;
1118
1119 hr = get_products_count(product, &list->count);
1120 if (hr != S_OK)
1121 {
1122 IDispatch_Release(*dispatch);
1123 return hr;
1124 }
1125
1126 list->data = msi_alloc(list->count*sizeof(VARIANT));
1127 if (!list->data)
1128 {
1129 IDispatch_Release(*dispatch);
1130 return E_OUTOFMEMORY;
1131 }
1132
1133 for (i = 0; i < list->count; i++)
1134 {
1135 WCHAR dataW[GUID_SIZE];
1136 UINT ret;
1137
1138 /* all or related only */
1139 if (product)
1140 ret = MsiEnumRelatedProductsW(product, 0, i, dataW);
1141 else
1142 ret = MsiEnumProductsW(i, dataW);
1143
1144 if (ret == ERROR_NO_MORE_ITEMS) break;
1145
1146 V_VT(&list->data[i]) = VT_BSTR;
1147 V_BSTR(&list->data[i]) = SysAllocString(dataW);
1148 }
1149
1150 return S_OK;
1151}
1152
1155 DISPID dispIdMember,
1156 REFIID riid,
1157 LCID lcid,
1158 WORD wFlags,
1159 DISPPARAMS* pDispParams,
1160 VARIANT* pVarResult,
1161 EXCEPINFO* pExcepInfo,
1162 UINT* puArgErr)
1163{
1164 MSIHANDLE msiHandle;
1165 UINT ret;
1166 VARIANTARG varg0, varg1;
1167 HRESULT hr;
1168
1169 VariantInit(&varg0);
1170 VariantInit(&varg1);
1171
1172 switch (dispIdMember)
1173 {
1175 if (wFlags & DISPATCH_METHOD)
1176 {
1177 hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &varg0, puArgErr);
1178 if (SUCCEEDED(hr) && V_DISPATCH(&varg0) != NULL)
1179 MsiViewExecute(This->msiHandle, ((AutomationObject *)V_DISPATCH(&varg0))->msiHandle);
1180 else
1181 MsiViewExecute(This->msiHandle, 0);
1182 }
1183 else return DISP_E_MEMBERNOTFOUND;
1184 break;
1185
1186 case DISPID_VIEW_FETCH:
1187 if (wFlags & DISPATCH_METHOD)
1188 {
1189 V_VT(pVarResult) = VT_DISPATCH;
1190 if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS)
1191 {
1192 if (FAILED(hr = create_record(msiHandle, &V_DISPATCH(pVarResult))))
1193 ERR("failed to create Record object, hresult %#lx\n", hr);
1194 }
1195 else if (ret == ERROR_NO_MORE_ITEMS)
1196 V_DISPATCH(pVarResult) = NULL;
1197 else
1198 {
1199 ERR("MsiViewFetch returned %d\n", ret);
1200 return DISP_E_EXCEPTION;
1201 }
1202 }
1203 else return DISP_E_MEMBERNOTFOUND;
1204 break;
1205
1206 case DISPID_VIEW_MODIFY:
1207 if (wFlags & DISPATCH_METHOD)
1208 {
1209 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1210 if (FAILED(hr)) return hr;
1211 hr = DispGetParam(pDispParams, 1, VT_DISPATCH, &varg1, puArgErr);
1212 if (FAILED(hr)) return hr;
1213 if (!V_DISPATCH(&varg1)) return DISP_E_EXCEPTION;
1214 if ((ret = MsiViewModify(This->msiHandle, V_I4(&varg0), ((AutomationObject *)V_DISPATCH(&varg1))->msiHandle)) != ERROR_SUCCESS)
1215 {
1216 VariantClear(&varg1);
1217 ERR("MsiViewModify returned %d\n", ret);
1218 return DISP_E_EXCEPTION;
1219 }
1220 }
1221 else return DISP_E_MEMBERNOTFOUND;
1222 break;
1223
1224 case DISPID_VIEW_CLOSE:
1225 if (wFlags & DISPATCH_METHOD)
1226 {
1227 MsiViewClose(This->msiHandle);
1228 }
1229 else return DISP_E_MEMBERNOTFOUND;
1230 break;
1231
1232 default:
1233 return DISP_E_MEMBERNOTFOUND;
1234 }
1235
1236 VariantClear(&varg1);
1237 VariantClear(&varg0);
1238
1239 return S_OK;
1240}
1241
1243 DISPPARAMS* pDispParams,
1244 VARIANT* pVarResult,
1245 EXCEPINFO* pExcepInfo,
1246 UINT* puArgErr)
1247{
1248 if (!(wFlags & DISPATCH_METHOD))
1249 return DISP_E_MEMBERNOTFOUND;
1250
1251 FIXME("\n");
1252
1253 VariantInit(pVarResult);
1254 return S_OK;
1255}
1256
1259 DISPID dispIdMember,
1260 REFIID riid,
1261 LCID lcid,
1262 WORD wFlags,
1263 DISPPARAMS* pDispParams,
1264 VARIANT* pVarResult,
1265 EXCEPINFO* pExcepInfo,
1266 UINT* puArgErr)
1267{
1269 MSIHANDLE msiHandle;
1270 UINT ret;
1271 VARIANTARG varg0, varg1;
1272 HRESULT hr;
1273
1274 VariantInit(&varg0);
1275 VariantInit(&varg1);
1276
1277 switch (dispIdMember)
1278 {
1281 {
1282 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1283 if (FAILED(hr))
1284 V_I4(&varg0) = 0;
1285
1286 V_VT(pVarResult) = VT_DISPATCH;
1287 if ((ret = MsiGetSummaryInformationW(This->msiHandle, NULL, V_I4(&varg0), &msiHandle)) == ERROR_SUCCESS)
1288 {
1289 hr = create_summaryinfo(msiHandle, &dispatch);
1290 if (SUCCEEDED(hr))
1291 V_DISPATCH(pVarResult) = dispatch;
1292 else
1293 ERR("failed to create SummaryInfo object: %#lx\n", hr);
1294 }
1295 else
1296 {
1297 ERR("MsiGetSummaryInformation returned %d\n", ret);
1298 return DISP_E_EXCEPTION;
1299 }
1300 }
1301 else return DISP_E_MEMBERNOTFOUND;
1302 break;
1303
1305 if (wFlags & DISPATCH_METHOD)
1306 {
1307 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1308 if (FAILED(hr)) return hr;
1309 V_VT(pVarResult) = VT_DISPATCH;
1310 if ((ret = MsiDatabaseOpenViewW(This->msiHandle, V_BSTR(&varg0), &msiHandle)) == ERROR_SUCCESS)
1311 {
1312 if (SUCCEEDED(hr = create_view(msiHandle, &dispatch)))
1313 V_DISPATCH(pVarResult) = dispatch;
1314 else
1315 ERR("failed to create View object, hresult %#lx\n", hr);
1316 }
1317 else
1318 {
1319 VariantClear(&varg0);
1320 ERR("MsiDatabaseOpenView returned %d\n", ret);
1321 return DISP_E_EXCEPTION;
1322 }
1323 }
1324 else return DISP_E_MEMBERNOTFOUND;
1325 break;
1326
1328 return DatabaseImpl_LastErrorRecord(wFlags, pDispParams,
1329 pVarResult, pExcepInfo,
1330 puArgErr);
1331
1332 default:
1333 return DISP_E_MEMBERNOTFOUND;
1334 }
1335
1336 VariantClear(&varg1);
1337 VariantClear(&varg0);
1338
1339 return S_OK;
1340}
1341
1344 DISPID dispIdMember,
1345 REFIID riid,
1346 LCID lcid,
1347 WORD wFlags,
1348 DISPPARAMS* pDispParams,
1349 VARIANT* pVarResult,
1350 EXCEPINFO* pExcepInfo,
1351 UINT* puArgErr)
1352{
1354 WCHAR *szString;
1355 DWORD dwLen = 0;
1356 MSIHANDLE msiHandle;
1357 LANGID langId;
1358 UINT ret;
1359 INSTALLSTATE iInstalled, iAction;
1360 VARIANTARG varg0, varg1;
1361 HRESULT hr;
1362
1363 VariantInit(&varg0);
1364 VariantInit(&varg1);
1365
1366 switch (dispIdMember)
1367 {
1370 V_VT(pVarResult) = VT_DISPATCH;
1371 IDispatch_AddRef(session->installer);
1372 V_DISPATCH(pVarResult) = session->installer;
1373 }
1374 else return DISP_E_MEMBERNOTFOUND;
1375 break;
1376
1379 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1380 if (FAILED(hr)) return hr;
1381 V_VT(pVarResult) = VT_BSTR;
1382 V_BSTR(pVarResult) = NULL;
1383 if ((ret = MsiGetPropertyW(This->msiHandle, V_BSTR(&varg0), NULL, &dwLen)) == ERROR_SUCCESS)
1384 {
1385 if (!(szString = msi_alloc((++dwLen)*sizeof(WCHAR))))
1386 ERR("Out of memory\n");
1387 else if ((ret = MsiGetPropertyW(This->msiHandle, V_BSTR(&varg0), szString, &dwLen)) == ERROR_SUCCESS)
1388 V_BSTR(pVarResult) = SysAllocString(szString);
1389 msi_free(szString);
1390 }
1391 if (ret != ERROR_SUCCESS)
1392 ERR("MsiGetProperty returned %d\n", ret);
1393 } else if (wFlags & DISPATCH_PROPERTYPUT) {
1394 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1395 if (FAILED(hr)) return hr;
1396 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
1397 if (FAILED(hr)) {
1398 VariantClear(&varg0);
1399 return hr;
1400 }
1401 if ((ret = MsiSetPropertyW(This->msiHandle, V_BSTR(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS)
1402 {
1403 VariantClear(&varg0);
1404 VariantClear(&varg1);
1405 ERR("MsiSetProperty returned %d\n", ret);
1406 return DISP_E_EXCEPTION;
1407 }
1408 }
1409 else return DISP_E_MEMBERNOTFOUND;
1410 break;
1411
1414 langId = MsiGetLanguage(This->msiHandle);
1415 V_VT(pVarResult) = VT_I4;
1416 V_I4(pVarResult) = langId;
1417 }
1418 else return DISP_E_MEMBERNOTFOUND;
1419 break;
1420
1423 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1424 if (FAILED(hr)) return hr;
1425 V_VT(pVarResult) = VT_BOOL;
1426 V_BOOL(pVarResult) = MsiGetMode(This->msiHandle, V_I4(&varg0)) ? VARIANT_TRUE : VARIANT_FALSE;
1427 } else if (wFlags & DISPATCH_PROPERTYPUT) {
1428 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1429 if (FAILED(hr)) return hr;
1430 hr = DispGetParam(pDispParams, 1, VT_BOOL, &varg1, puArgErr);
1431 if (FAILED(hr)) return hr;
1432 if ((ret = MsiSetMode(This->msiHandle, V_I4(&varg0), V_BOOL(&varg1))) != ERROR_SUCCESS)
1433 {
1434 ERR("MsiSetMode returned %d\n", ret);
1435 return DISP_E_EXCEPTION;
1436 }
1437 }
1438 else return DISP_E_MEMBERNOTFOUND;
1439 break;
1440
1443 V_VT(pVarResult) = VT_DISPATCH;
1444 if ((msiHandle = MsiGetActiveDatabase(This->msiHandle)))
1445 {
1447
1448 if (SUCCEEDED(hr = create_database(msiHandle, &dispatch)))
1449 V_DISPATCH(pVarResult) = dispatch;
1450 else
1451 ERR("failed to create Database object, hresult %#lx\n", hr);
1452 }
1453 else
1454 {
1455 ERR("MsiGetActiveDatabase failed\n");
1456 return DISP_E_EXCEPTION;
1457 }
1458 }
1459 else return DISP_E_MEMBERNOTFOUND;
1460 break;
1461
1463 if (wFlags & DISPATCH_METHOD) {
1464 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1465 if (FAILED(hr)) return hr;
1466 ret = MsiDoActionW(This->msiHandle, V_BSTR(&varg0));
1467 V_VT(pVarResult) = VT_I4;
1468 switch (ret)
1469 {
1471 V_I4(pVarResult) = msiDoActionStatusNoAction;
1472 break;
1473 case ERROR_SUCCESS:
1474 V_I4(pVarResult) = msiDoActionStatusSuccess;
1475 break;
1477 V_I4(pVarResult) = msiDoActionStatusUserExit;
1478 break;
1480 V_I4(pVarResult) = msiDoActionStatusFailure;
1481 break;
1483 V_I4(pVarResult) = msiDoActionStatusSuspend;
1484 break;
1485 case ERROR_MORE_DATA:
1486 V_I4(pVarResult) = msiDoActionStatusFinished;
1487 break;
1489 V_I4(pVarResult) = msiDoActionStatusWrongState;
1490 break;
1491 case ERROR_INVALID_DATA:
1492 V_I4(pVarResult) = msiDoActionStatusBadActionData;
1493 break;
1494 default:
1495 VariantClear(&varg0);
1496 FIXME("MsiDoAction returned unhandled value %d\n", ret);
1497 return DISP_E_EXCEPTION;
1498 }
1499 }
1500 else return DISP_E_MEMBERNOTFOUND;
1501 break;
1502
1504 if (wFlags & DISPATCH_METHOD) {
1505 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1506 if (FAILED(hr)) return hr;
1507 V_VT(pVarResult) = VT_I4;
1508 V_I4(pVarResult) = MsiEvaluateConditionW(This->msiHandle, V_BSTR(&varg0));
1509 }
1510 else return DISP_E_MEMBERNOTFOUND;
1511 break;
1512
1514 if(!(wFlags & DISPATCH_METHOD))
1515 return DISP_E_MEMBERNOTFOUND;
1516
1517 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1518 if (FAILED(hr)) return hr;
1519 hr = DispGetParam(pDispParams, 1, VT_DISPATCH, &varg1, puArgErr);
1520 if (FAILED(hr)) return hr;
1521
1522 V_VT(pVarResult) = VT_I4;
1523 V_I4(pVarResult) =
1524 MsiProcessMessage(This->msiHandle, V_I4(&varg0), ((AutomationObject *)V_DISPATCH(&varg1))->msiHandle);
1525 break;
1526
1528 if (wFlags & DISPATCH_METHOD) {
1529 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1530 if (FAILED(hr)) return hr;
1531 if ((ret = MsiSetInstallLevel(This->msiHandle, V_I4(&varg0))) != ERROR_SUCCESS)
1532 {
1533 ERR("MsiSetInstallLevel returned %d\n", ret);
1534 return DISP_E_EXCEPTION;
1535 }
1536 }
1537 else return DISP_E_MEMBERNOTFOUND;
1538 break;
1539
1542 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1543 if (FAILED(hr)) return hr;
1544 V_VT(pVarResult) = VT_I4;
1545 if ((ret = MsiGetFeatureStateW(This->msiHandle, V_BSTR(&varg0), &iInstalled, &iAction)) == ERROR_SUCCESS)
1546 V_I4(pVarResult) = iInstalled;
1547 else
1548 {
1549 ERR("MsiGetFeatureState returned %d\n", ret);
1550 V_I4(pVarResult) = msiInstallStateUnknown;
1551 }
1552 }
1553 else return DISP_E_MEMBERNOTFOUND;
1554 break;
1555
1558 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1559 if (FAILED(hr)) return hr;
1560 V_VT(pVarResult) = VT_I4;
1561 if ((ret = MsiGetFeatureStateW(This->msiHandle, V_BSTR(&varg0), &iInstalled, &iAction)) == ERROR_SUCCESS)
1562 V_I4(pVarResult) = iAction;
1563 else
1564 {
1565 ERR("MsiGetFeatureState returned %d\n", ret);
1566 V_I4(pVarResult) = msiInstallStateUnknown;
1567 }
1568 } else if (wFlags & DISPATCH_PROPERTYPUT) {
1569 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1570 if (FAILED(hr)) return hr;
1571 hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr);
1572 if (FAILED(hr)) {
1573 VariantClear(&varg0);
1574 return hr;
1575 }
1576 if ((ret = MsiSetFeatureStateW(This->msiHandle, V_BSTR(&varg0), V_I4(&varg1))) != ERROR_SUCCESS)
1577 {
1578 VariantClear(&varg0);
1579 ERR("MsiSetFeatureState returned %d\n", ret);
1580 return DISP_E_EXCEPTION;
1581 }
1582 }
1583 else return DISP_E_MEMBERNOTFOUND;
1584 break;
1585
1586 default:
1587 return DISP_E_MEMBERNOTFOUND;
1588 }
1589
1590 VariantClear(&varg1);
1591 VariantClear(&varg0);
1592
1593 return S_OK;
1594}
1595
1596/* Fill the variant pointed to by pVarResult with the value & size returned by RegQueryValueEx as dictated by the
1597 * registry value type. Used by Installer::RegistryValue. */
1598static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize)
1599{
1600 WCHAR *szString = (WCHAR *)lpData;
1601 LPWSTR szNewString = NULL;
1602 DWORD dwNewSize = 0;
1603 int idx;
1604
1605 switch (dwType)
1606 {
1607 /* Registry strings may not be null terminated so we must use SysAllocStringByteLen/Len */
1608 case REG_MULTI_SZ: /* Multi SZ change internal null characters to newlines */
1609 idx = (dwSize/sizeof(WCHAR))-1;
1610 while (idx >= 0 && !szString[idx]) idx--;
1611 for (; idx >= 0; idx--)
1612 if (!szString[idx]) szString[idx] = '\n';
1613 /* fall through */
1614 case REG_SZ:
1615 V_VT(pVarResult) = VT_BSTR;
1616 V_BSTR(pVarResult) = SysAllocStringByteLen((LPCSTR)szString, dwSize);
1617 break;
1618
1619 case REG_EXPAND_SZ:
1620 if (!(dwNewSize = ExpandEnvironmentStringsW(szString, szNewString, dwNewSize)))
1621 ERR("ExpandEnvironmentStrings returned error %lu\n", GetLastError());
1622 else if (!(szNewString = msi_alloc(dwNewSize * sizeof(WCHAR))))
1623 ERR("Out of memory\n");
1624 else if (!(dwNewSize = ExpandEnvironmentStringsW(szString, szNewString, dwNewSize)))
1625 ERR("ExpandEnvironmentStrings returned error %lu\n", GetLastError());
1626 else
1627 {
1628 V_VT(pVarResult) = VT_BSTR;
1629 V_BSTR(pVarResult) = SysAllocStringLen(szNewString, dwNewSize);
1630 }
1631 msi_free(szNewString);
1632 break;
1633
1634 case REG_DWORD:
1635 V_VT(pVarResult) = VT_I4;
1636 V_I4(pVarResult) = *((DWORD *)lpData);
1637 break;
1638
1639 case REG_QWORD:
1640 V_VT(pVarResult) = VT_BSTR;
1641 V_BSTR(pVarResult) = SysAllocString(L"(REG_\?\?)"); /* Weird string, don't know why native returns it */
1642 break;
1643
1644 case REG_BINARY:
1645 V_VT(pVarResult) = VT_BSTR;
1646 V_BSTR(pVarResult) = SysAllocString(L"(REG_BINARY)");
1647 break;
1648
1649 case REG_NONE:
1650 V_VT(pVarResult) = VT_EMPTY;
1651 break;
1652
1653 default:
1654 FIXME("Unhandled registry value type %lu\n", dwType);
1655 }
1656}
1657
1659 DISPPARAMS* pDispParams,
1660 VARIANT* pVarResult,
1661 EXCEPINFO* pExcepInfo,
1662 UINT* puArgErr)
1663{
1664 HRESULT hr;
1665 VARIANTARG varg0;
1666 MSIHANDLE hrec;
1667
1668 if (!(wFlags & DISPATCH_METHOD))
1669 return DISP_E_MEMBERNOTFOUND;
1670
1671 VariantInit(&varg0);
1672 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1673 if (FAILED(hr))
1674 return hr;
1675
1676 V_VT(pVarResult) = VT_DISPATCH;
1677
1678 hrec = MsiCreateRecord(V_I4(&varg0));
1679 if (!hrec)
1680 return DISP_E_EXCEPTION;
1681
1682 return create_record(hrec, &V_DISPATCH(pVarResult));
1683}
1684
1686 WORD wFlags,
1687 DISPPARAMS* pDispParams,
1688 VARIANT* pVarResult,
1689 EXCEPINFO* pExcepInfo,
1690 UINT* puArgErr)
1691{
1692 UINT ret;
1693 HRESULT hr;
1694 MSIHANDLE hpkg;
1696 VARIANTARG varg0, varg1;
1697
1698 if (!(wFlags & DISPATCH_METHOD))
1699 return DISP_E_MEMBERNOTFOUND;
1700
1701 if (pDispParams->cArgs == 0)
1702 return DISP_E_TYPEMISMATCH;
1703
1704 if (V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1]) != VT_BSTR)
1705 return DISP_E_TYPEMISMATCH;
1706
1707 VariantInit(&varg0);
1708 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1709 if (FAILED(hr))
1710 return hr;
1711
1712 VariantInit(&varg1);
1713 if (pDispParams->cArgs == 2)
1714 {
1715 hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr);
1716 if (FAILED(hr))
1717 goto done;
1718 }
1719 else
1720 {
1721 V_VT(&varg1) = VT_I4;
1722 V_I4(&varg1) = 0;
1723 }
1724
1725 V_VT(pVarResult) = VT_DISPATCH;
1726
1727 ret = MsiOpenPackageExW(V_BSTR(&varg0), V_I4(&varg1), &hpkg);
1728 if (ret != ERROR_SUCCESS)
1729 {
1731 goto done;
1732 }
1733
1734 hr = create_session(hpkg, &This->IDispatch_iface, &dispatch);
1735 if (SUCCEEDED(hr))
1736 V_DISPATCH(pVarResult) = dispatch;
1737
1738done:
1739 VariantClear(&varg0);
1740 VariantClear(&varg1);
1741 return hr;
1742}
1743
1745 DISPPARAMS* pDispParams,
1746 VARIANT* pVarResult,
1747 EXCEPINFO* pExcepInfo,
1748 UINT* puArgErr)
1749{
1750 HRESULT hr;
1751 VARIANTARG varg0;
1752
1753 if (!(wFlags & DISPATCH_METHOD))
1754 return DISP_E_MEMBERNOTFOUND;
1755
1756 VariantInit(&varg0);
1757 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1758 if (FAILED(hr))
1759 return hr;
1760
1761 FIXME("%s\n", debugstr_w(V_BSTR(&varg0)));
1762
1763 VariantInit(pVarResult);
1764
1765 VariantClear(&varg0);
1766 return S_OK;
1767}
1768
1770 DISPPARAMS* pDispParams,
1771 VARIANT* pVarResult,
1772 EXCEPINFO* pExcepInfo,
1773 UINT* puArgErr)
1774{
1775 UINT ret;
1776 HRESULT hr;
1777 MSIHANDLE hdb;
1779 VARIANTARG varg0, varg1;
1780
1781 if (!(wFlags & DISPATCH_METHOD))
1782 return DISP_E_MEMBERNOTFOUND;
1783
1784 VariantInit(&varg0);
1785 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1786 if (FAILED(hr))
1787 return hr;
1788
1789 VariantInit(&varg1);
1790 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
1791 if (FAILED(hr))
1792 goto done;
1793
1794 V_VT(pVarResult) = VT_DISPATCH;
1795
1796 ret = MsiOpenDatabaseW(V_BSTR(&varg0), V_BSTR(&varg1), &hdb);
1797 if (ret != ERROR_SUCCESS)
1798 {
1800 goto done;
1801 }
1802
1803 hr = create_database(hdb, &dispatch);
1804 if (SUCCEEDED(hr))
1805 V_DISPATCH(pVarResult) = dispatch;
1806
1807done:
1808 VariantClear(&varg0);
1809 VariantClear(&varg1);
1810 return hr;
1811}
1812
1814 DISPPARAMS* pDispParams,
1815 VARIANT* pVarResult,
1816 EXCEPINFO* pExcepInfo,
1817 UINT* puArgErr)
1818{
1819 UINT ret;
1820 HRESULT hr;
1821 MSIHANDLE hsuminfo;
1823 VARIANTARG varg0, varg1;
1824
1826 return DISP_E_MEMBERNOTFOUND;
1827
1828 VariantInit(&varg1);
1829 hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr);
1830 if (FAILED(hr))
1831 return hr;
1832
1833 VariantInit(&varg0);
1834 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1835 if (FAILED(hr))
1836 return hr;
1837
1838 ret = MsiGetSummaryInformationW(0, V_BSTR(&varg0), V_I4(&varg1), &hsuminfo);
1839 VariantClear(&varg0);
1840 if (ret != ERROR_SUCCESS)
1841 return DISP_E_EXCEPTION;
1842
1843 hr = create_summaryinfo(hsuminfo, &dispatch);
1844 if (FAILED(hr))
1845 return hr;
1846
1847 V_VT(pVarResult) = VT_DISPATCH;
1848 V_DISPATCH(pVarResult) = dispatch;
1849 return S_OK;
1850}
1851
1853 DISPPARAMS* pDispParams,
1854 VARIANT* pVarResult,
1855 EXCEPINFO* pExcepInfo,
1856 UINT* puArgErr)
1857{
1858 HRESULT hr;
1859 VARIANTARG varg0;
1861
1863 return DISP_E_MEMBERNOTFOUND;
1864
1866 {
1867 VariantInit(&varg0);
1868 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1869 if (FAILED(hr))
1870 return hr;
1871
1872 ui = MsiSetInternalUI(V_I4(&varg0), NULL);
1874 return DISP_E_EXCEPTION;
1875 }
1876 else if (wFlags & DISPATCH_PROPERTYGET)
1877 {
1880 return DISP_E_EXCEPTION;
1881
1882 V_VT(pVarResult) = VT_I4;
1883 V_I4(pVarResult) = ui;
1884 }
1885
1886 return S_OK;
1887}
1888
1890 DISPPARAMS* pDispParams,
1891 VARIANT* pVarResult,
1892 EXCEPINFO* pExcepInfo,
1893 UINT* puArgErr)
1894{
1895 if (!(wFlags & DISPATCH_METHOD))
1896 return DISP_E_MEMBERNOTFOUND;
1897
1898 FIXME("\n");
1899
1900 VariantInit(pVarResult);
1901 return S_OK;
1902}
1903
1905 DISPPARAMS* pDispParams,
1906 VARIANT* pVarResult,
1907 EXCEPINFO* pExcepInfo,
1908 UINT* puArgErr)
1909{
1910 UINT ret;
1911 HRESULT hr;
1912 VARIANTARG varg0, varg1;
1913
1914 if (!(wFlags & DISPATCH_METHOD))
1915 return DISP_E_MEMBERNOTFOUND;
1916
1917 VariantInit(&varg0);
1918 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
1919 if (FAILED(hr))
1920 return hr;
1921
1922 VariantInit(&varg1);
1923 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
1924 if (FAILED(hr))
1925 goto done;
1926
1927 ret = MsiInstallProductW(V_BSTR(&varg0), V_BSTR(&varg1));
1928 if (ret != ERROR_SUCCESS)
1929 {
1931 goto done;
1932 }
1933
1934done:
1935 VariantClear(&varg0);
1936 VariantClear(&varg1);
1937 return hr;
1938}
1939
1941 VARIANT* pVarResult,
1942 EXCEPINFO* pExcepInfo,
1943 UINT* puArgErr)
1944{
1945 HRESULT hr;
1946 DLLVERSIONINFO verinfo;
1948
1950 return DISP_E_MEMBERNOTFOUND;
1951
1952 verinfo.cbSize = sizeof(DLLVERSIONINFO);
1953 hr = DllGetVersion(&verinfo);
1954 if (FAILED(hr))
1955 return hr;
1956
1957 swprintf(version, ARRAY_SIZE(version), L"%d.%d.%d.%d", verinfo.dwMajorVersion, verinfo.dwMinorVersion,
1958 verinfo.dwBuildNumber, verinfo.dwPlatformID);
1959
1960 V_VT(pVarResult) = VT_BSTR;
1961 V_BSTR(pVarResult) = SysAllocString(version);
1962 return S_OK;
1963}
1964
1966 DISPPARAMS* pDispParams,
1967 VARIANT* pVarResult,
1968 EXCEPINFO* pExcepInfo,
1969 UINT* puArgErr)
1970{
1971 if (!(wFlags & DISPATCH_METHOD))
1972 return DISP_E_MEMBERNOTFOUND;
1973
1974 FIXME("\n");
1975
1976 VariantInit(pVarResult);
1977 return S_OK;
1978}
1979
1981 DISPPARAMS* pDispParams,
1982 VARIANT* pVarResult,
1983 EXCEPINFO* pExcepInfo,
1984 UINT* puArgErr)
1985{
1986 UINT ret;
1987 HKEY hkey = NULL;
1988 HRESULT hr;
1989 UINT posValue;
1990 DWORD type, size;
1991 LPWSTR szString = NULL;
1992 VARIANTARG varg0, varg1, varg2;
1993
1994 if (!(wFlags & DISPATCH_METHOD))
1995 return DISP_E_MEMBERNOTFOUND;
1996
1997 VariantInit(&varg0);
1998 hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
1999 if (FAILED(hr))
2000 return hr;
2001
2002 VariantInit(&varg1);
2003 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
2004 if (FAILED(hr))
2005 goto done;
2006
2007 /* Save valuePos so we can save puArgErr if we are unable to do our type
2008 * conversions.
2009 */
2010 posValue = 2;
2011 VariantInit(&varg2);
2012 hr = DispGetParam_CopyOnly(pDispParams, &posValue, &varg2);
2013 if (FAILED(hr))
2014 goto done;
2015
2016 if (V_I4(&varg0) >= REG_INDEX_CLASSES_ROOT &&
2017 V_I4(&varg0) <= REG_INDEX_DYN_DATA)
2018 {
2019 V_I4(&varg0) |= (UINT_PTR)HKEY_CLASSES_ROOT;
2020 }
2021
2022 ret = RegOpenKeyW((HKEY)(UINT_PTR)V_I4(&varg0), V_BSTR(&varg1), &hkey);
2023
2024 /* Only VT_EMPTY case can do anything if the key doesn't exist. */
2025 if (ret != ERROR_SUCCESS && V_VT(&varg2) != VT_EMPTY)
2026 {
2028 goto done;
2029 }
2030
2031 /* Third parameter can be VT_EMPTY, VT_I4, or VT_BSTR */
2032 switch (V_VT(&varg2))
2033 {
2034 /* Return VT_BOOL clarifying whether registry key exists or not. */
2035 case VT_EMPTY:
2036 V_VT(pVarResult) = VT_BOOL;
2037 V_BOOL(pVarResult) = (ret == ERROR_SUCCESS) ? VARIANT_TRUE : VARIANT_FALSE;
2038 break;
2039
2040 /* Return the value of specified key if it exists. */
2041 case VT_BSTR:
2042 ret = RegQueryValueExW(hkey, V_BSTR(&varg2),
2043 NULL, NULL, NULL, &size);
2044 if (ret != ERROR_SUCCESS)
2045 {
2047 goto done;
2048 }
2049
2050 szString = msi_alloc(size);
2051 if (!szString)
2052 {
2053 hr = E_OUTOFMEMORY;
2054 goto done;
2055 }
2056
2057 ret = RegQueryValueExW(hkey, V_BSTR(&varg2), NULL,
2058 &type, (LPBYTE)szString, &size);
2059 if (ret != ERROR_SUCCESS)
2060 {
2061 msi_free(szString);
2063 goto done;
2064 }
2065
2067 (LPBYTE)szString, size);
2068 msi_free(szString);
2069 break;
2070
2071 /* Try to make it into VT_I4, can use VariantChangeType for this. */
2072 default:
2073 hr = VariantChangeType(&varg2, &varg2, 0, VT_I4);
2074 if (FAILED(hr))
2075 {
2076 if (hr == DISP_E_TYPEMISMATCH)
2077 *puArgErr = posValue;
2078
2079 goto done;
2080 }
2081
2082 /* Retrieve class name or maximum value name or subkey name size. */
2083 if (!V_I4(&varg2))
2084 ret = RegQueryInfoKeyW(hkey, NULL, &size, NULL, NULL, NULL,
2085 NULL, NULL, NULL, NULL, NULL, NULL);
2086 else if (V_I4(&varg2) > 0)
2088 NULL, NULL, &size, NULL, NULL, NULL);
2089 else /* V_I4(&varg2) < 0 */
2090 ret = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, &size,
2091 NULL, NULL, NULL, NULL, NULL, NULL);
2092
2093 if (ret != ERROR_SUCCESS)
2094 goto done;
2095
2096 szString = msi_alloc(++size * sizeof(WCHAR));
2097 if (!szString)
2098 {
2099 hr = E_OUTOFMEMORY;
2100 goto done;
2101 }
2102
2103 if (!V_I4(&varg2))
2104 ret = RegQueryInfoKeyW(hkey, szString, &size,NULL, NULL, NULL,
2105 NULL, NULL, NULL, NULL, NULL, NULL);
2106 else if (V_I4(&varg2) > 0)
2107 ret = RegEnumValueW(hkey, V_I4(&varg2)-1, szString,
2108 &size, 0, 0, NULL, NULL);
2109 else /* V_I4(&varg2) < 0 */
2110 ret = RegEnumKeyW(hkey, -1 - V_I4(&varg2), szString, size);
2111
2112 if (ret == ERROR_SUCCESS)
2113 {
2114 V_VT(pVarResult) = VT_BSTR;
2115 V_BSTR(pVarResult) = SysAllocString(szString);
2116 }
2117
2118 msi_free(szString);
2119 }
2120
2121done:
2122 VariantClear(&varg0);
2123 VariantClear(&varg1);
2124 VariantClear(&varg2);
2125 RegCloseKey(hkey);
2126 return hr;
2127}
2128
2130 DISPPARAMS* pDispParams,
2131 VARIANT* pVarResult,
2132 EXCEPINFO* pExcepInfo,
2133 UINT* puArgErr)
2134{
2135 if (!(wFlags & DISPATCH_METHOD))
2136 return DISP_E_MEMBERNOTFOUND;
2137
2138 FIXME("\n");
2139
2140 VariantInit(pVarResult);
2141 return S_OK;
2142}
2143
2145 DISPPARAMS* pDispParams,
2146 VARIANT* pVarResult,
2147 EXCEPINFO* pExcepInfo,
2148 UINT* puArgErr)
2149{
2150 if (!(wFlags & DISPATCH_METHOD))
2151 return DISP_E_MEMBERNOTFOUND;
2152
2153 FIXME("\n");
2154
2155 VariantInit(pVarResult);
2156 return S_OK;
2157}
2158
2160 DISPPARAMS* pDispParams,
2161 VARIANT* pVarResult,
2162 EXCEPINFO* pExcepInfo,
2163 UINT* puArgErr)
2164{
2165 if (!(wFlags & DISPATCH_METHOD))
2166 return DISP_E_MEMBERNOTFOUND;
2167
2168 FIXME("\n");
2169
2170 VariantInit(pVarResult);
2171 return S_OK;
2172}
2173
2175 DISPPARAMS* pDispParams,
2176 VARIANT* pVarResult,
2177 EXCEPINFO* pExcepInfo,
2178 UINT* puArgErr)
2179{
2180 if (!(wFlags & DISPATCH_METHOD))
2181 return DISP_E_MEMBERNOTFOUND;
2182
2183 FIXME("\n");
2184
2185 VariantInit(pVarResult);
2186 return S_OK;
2187}
2188
2190 DISPPARAMS* pDispParams,
2191 VARIANT* pVarResult,
2192 EXCEPINFO* pExcepInfo,
2193 UINT* puArgErr)
2194{
2195 HRESULT hr;
2196 VARIANTARG varg0;
2197
2199 return DISP_E_MEMBERNOTFOUND;
2200
2201 VariantInit(&varg0);
2202 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
2203 if (FAILED(hr))
2204 return hr;
2205
2206 V_VT(pVarResult) = VT_I4;
2207 V_I4(pVarResult) = MsiQueryProductStateW(V_BSTR(&varg0));
2208
2209 VariantClear(&varg0);
2210 return S_OK;
2211}
2212
2214 DISPPARAMS* pDispParams,
2215 VARIANT* pVarResult,
2216 EXCEPINFO* pExcepInfo,
2217 UINT* puArgErr)
2218{
2219 UINT ret;
2220 HRESULT hr;
2221 DWORD size;
2222 LPWSTR str = NULL;
2223 VARIANTARG varg0, varg1;
2224
2226 return DISP_E_MEMBERNOTFOUND;
2227
2228 VariantInit(&varg0);
2229 hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
2230 if (FAILED(hr))
2231 return hr;
2232
2233 VariantInit(&varg1);
2234 hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr);
2235 if (FAILED(hr))
2236 goto done;
2237
2238 V_VT(pVarResult) = VT_BSTR;
2239 V_BSTR(pVarResult) = NULL;
2240
2241 ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), NULL, &size);
2242 if (ret != ERROR_SUCCESS)
2243 {
2245 goto done;
2246 }
2247
2248 str = msi_alloc(++size * sizeof(WCHAR));
2249 if (!str)
2250 {
2251 hr = E_OUTOFMEMORY;
2252 goto done;
2253 }
2254
2255 ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), str, &size);
2256 if (ret != ERROR_SUCCESS)
2257 {
2259 goto done;
2260 }
2261
2262 V_BSTR(pVarResult) = SysAllocString(str);
2263 hr = S_OK;
2264
2265done:
2266 msi_free(str);
2267 VariantClear(&varg0);
2268 VariantClear(&varg1);
2269 return hr;
2270}
2271
2273 DISPPARAMS* pDispParams,
2274 VARIANT* result,
2275 EXCEPINFO* pExcepInfo,
2276 UINT* puArgErr)
2277{
2279 HRESULT hr;
2280
2281 if (!(flags & DISPATCH_PROPERTYGET))
2282 return DISP_E_MEMBERNOTFOUND;
2283
2285 if (FAILED(hr))
2286 return hr;
2287
2290
2291 return hr;
2292}
2293
2295 DISPPARAMS* pDispParams,
2296 VARIANT* result,
2297 EXCEPINFO* pExcepInfo,
2298 UINT* puArgErr)
2299{
2301 VARIANTARG related;
2302 HRESULT hr;
2303
2304 if (!(flags & DISPATCH_PROPERTYGET))
2305 return DISP_E_MEMBERNOTFOUND;
2306
2307 VariantInit(&related);
2308 hr = DispGetParam(pDispParams, 0, VT_BSTR, &related, puArgErr);
2309 if (FAILED(hr))
2310 return hr;
2311
2312 hr = create_list(V_BSTR(&related), &dispatch);
2313 VariantClear(&related);
2314
2317
2318 return hr;
2319}
2320
2323 DISPID dispIdMember,
2324 REFIID riid,
2325 LCID lcid,
2326 WORD wFlags,
2327 DISPPARAMS* pDispParams,
2328 VARIANT* pVarResult,
2329 EXCEPINFO* pExcepInfo,
2330 UINT* puArgErr)
2331{
2332 switch (dispIdMember)
2333 {
2335 return InstallerImpl_CreateRecord(wFlags, pDispParams,
2336 pVarResult, pExcepInfo, puArgErr);
2337
2339 return InstallerImpl_OpenPackage(This, wFlags, pDispParams,
2340 pVarResult, pExcepInfo, puArgErr);
2341
2343 return InstallerImpl_OpenProduct(wFlags, pDispParams,
2344 pVarResult, pExcepInfo, puArgErr);
2345
2347 return InstallerImpl_OpenDatabase(wFlags, pDispParams,
2348 pVarResult, pExcepInfo, puArgErr);
2349
2351 return InstallerImpl_SummaryInformation(wFlags, pDispParams,
2352 pVarResult, pExcepInfo,
2353 puArgErr);
2354
2356 return InstallerImpl_UILevel(wFlags, pDispParams,
2357 pVarResult, pExcepInfo, puArgErr);
2358
2360 return InstallerImpl_EnableLog(wFlags, pDispParams,
2361 pVarResult, pExcepInfo, puArgErr);
2362
2364 return InstallerImpl_InstallProduct(wFlags, pDispParams,
2365 pVarResult, pExcepInfo,
2366 puArgErr);
2367
2369 return InstallerImpl_Version(wFlags, pVarResult,
2370 pExcepInfo, puArgErr);
2371
2373 return InstallerImpl_LastErrorRecord(wFlags, pDispParams,
2374 pVarResult, pExcepInfo,
2375 puArgErr);
2376
2378 return InstallerImpl_RegistryValue(wFlags, pDispParams,
2379 pVarResult, pExcepInfo,
2380 puArgErr);
2381
2383 return InstallerImpl_Environment(wFlags, pDispParams,
2384 pVarResult, pExcepInfo, puArgErr);
2385
2387 return InstallerImpl_FileAttributes(wFlags, pDispParams,
2388 pVarResult, pExcepInfo,
2389 puArgErr);
2390
2392 return InstallerImpl_FileSize(wFlags, pDispParams,
2393 pVarResult, pExcepInfo, puArgErr);
2394
2396 return InstallerImpl_FileVersion(wFlags, pDispParams,
2397 pVarResult, pExcepInfo, puArgErr);
2398
2400 return InstallerImpl_ProductState(wFlags, pDispParams,
2401 pVarResult, pExcepInfo, puArgErr);
2402
2404 return InstallerImpl_ProductInfo(wFlags, pDispParams,
2405 pVarResult, pExcepInfo, puArgErr);
2406
2408 return InstallerImpl_Products(wFlags, pDispParams,
2409 pVarResult, pExcepInfo, puArgErr);
2410
2412 return InstallerImpl_RelatedProducts(wFlags, pDispParams,
2413 pVarResult, pExcepInfo,
2414 puArgErr);
2415
2416 default:
2417 return DISP_E_MEMBERNOTFOUND;
2418 }
2419}
2420
2421HRESULT create_msiserver(IUnknown *outer, void **ppObj)
2422{
2423 AutomationObject *installer;
2424
2425 TRACE("(%p %p)\n", outer, ppObj);
2426
2427 if (outer)
2428 return CLASS_E_NOAGGREGATION;
2429
2430 installer = msi_alloc(sizeof(AutomationObject));
2431 if (!installer) return E_OUTOFMEMORY;
2432
2434
2435 *ppObj = &installer->IDispatch_iface;
2436
2437 return S_OK;
2438}
2439
2441{
2443
2444 session = msi_alloc(sizeof(SessionObject));
2445 if (!session) return E_OUTOFMEMORY;
2446
2447 init_automation_object(&session->autoobj, msiHandle, Session_tid);
2448
2449 session->installer = installer;
2450 *disp = &session->autoobj.IDispatch_iface;
2451
2452 return S_OK;
2453}
2454
2456{
2457 AutomationObject *database;
2458
2459 TRACE("%lu %p\n", msiHandle, dispatch);
2460
2461 database = msi_alloc(sizeof(AutomationObject));
2462 if (!database) return E_OUTOFMEMORY;
2463
2464 init_automation_object(database, msiHandle, Database_tid);
2465
2466 *dispatch = &database->IDispatch_iface;
2467
2468 return S_OK;
2469}
2470
2472{
2474
2475 TRACE("%lu %p\n", msiHandle, dispatch);
2476
2477 view = msi_alloc(sizeof(AutomationObject));
2478 if (!view) return E_OUTOFMEMORY;
2479
2481
2482 *dispatch = &view->IDispatch_iface;
2483
2484 return S_OK;
2485}
2486
2488{
2490
2491 info = msi_alloc(sizeof(*info));
2492 if (!info) return E_OUTOFMEMORY;
2493
2495
2496 *disp = &info->IDispatch_iface;
2497
2498 return S_OK;
2499}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
STDAPI DllGetVersion(DLLVERSIONINFO *info)
Definition: browseui.cpp:221
Definition: list.h:37
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR szEmpty[]
Definition: provider.c:50
unsigned int idx
Definition: utils.c:41
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
double DATE
Definition: compat.h:2253
OLECHAR * BSTR
Definition: compat.h:2293
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
@ VT_BSTR
Definition: compat.h:2303
@ VT_LPSTR
Definition: compat.h:2324
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_I4
Definition: compat.h:2298
@ VT_FILETIME
Definition: compat.h:2329
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221
BOOL WINAPI LocalFileTimeToFileTime(IN CONST FILETIME *lpLocalFileTime, OUT LPFILETIME lpFileTime)
Definition: time.c:253
static HRESULT create_list(const WCHAR *product, IDispatch **dispatch)
Definition: automation.c:1106
static HRESULT summaryinfo_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:754
static HRESULT WINAPI AutomationObject_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: automation.c:278
static HRESULT WINAPI ProvideMultipleClassInfo_GetGUID(IProvideMultipleClassInfo *iface, DWORD dwGuidKind, GUID *pGUID)
Definition: automation.c:470
static HRESULT DispGetParam_CopyOnly(DISPPARAMS *pdispparams, UINT *position, VARIANT *pvarResult)
Definition: automation.c:728
static const struct IDispatchVtbl AutomationObjectVtbl
Definition: automation.c:420
static HRESULT InstallerImpl_SummaryInformation(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1813
static tid_id_t tid_ids[]
Definition: automation.c:70
static HRESULT InstallerImpl_Products(WORD flags, DISPPARAMS *pDispParams, VARIANT *result, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2272
static HRESULT InstallerImpl_FileSize(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2159
#define REG_INDEX_CLASSES_ROOT
Definition: automation.c:41
static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize)
Definition: automation.c:1598
static void list_free(AutomationObject *)
Definition: automation.c:1068
static HRESULT database_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:1257
static HRESULT InstallerImpl_ProductState(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2189
static HRESULT WINAPI AutomationObject_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: automation.c:259
HRESULT create_session(MSIHANDLE msiHandle, IDispatch *installer, IDispatch **disp)
Definition: automation.c:2440
static ITypeLib * typelib
Definition: automation.c:80
static HRESULT WINAPI ListEnumerator_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched)
Definition: automation.c:616
static HRESULT WINAPI ProvideMultipleClassInfo_QueryInterface(IProvideMultipleClassInfo *iface, REFIID riid, VOID **ppvoid)
Definition: automation.c:435
static ULONG WINAPI ProvideMultipleClassInfo_Release(IProvideMultipleClassInfo *iface)
Definition: automation.c:450
static HRESULT WINAPI ListEnumerator_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
Definition: automation.c:667
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
Definition: automation.c:88
static HRESULT session_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:1342
static HRESULT InstallerImpl_OpenProduct(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1744
static AutomationObject * impl_from_IProvideMultipleClassInfo(IProvideMultipleClassInfo *iface)
Definition: automation.c:181
static const struct IEnumVARIANTVtbl ListEnumerator_Vtbl
Definition: automation.c:688
void(* auto_free_func)(AutomationObject *This)
Definition: automation.c:52
static HRESULT create_record(MSIHANDLE msiHandle, IDispatch **disp)
Definition: automation.c:997
static const IProvideMultipleClassInfoVtbl ProvideMultipleClassInfoVtbl
Definition: automation.c:533
static AutomationObject * impl_from_IDispatch(IDispatch *iface)
Definition: automation.c:186
static HRESULT WINAPI ListEnumerator_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppvObject)
Definition: automation.c:564
static HRESULT InstallerImpl_UILevel(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1852
static HRESULT view_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:1153
static HRESULT WINAPI ProvideMultipleClassInfo_GetClassInfo(IProvideMultipleClassInfo *iface, ITypeInfo **ppTI)
Definition: automation.c:456
static HRESULT InstallerImpl_InstallProduct(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1904
static HRESULT InstallerImpl_RegistryValue(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1980
static HRESULT WINAPI ListEnumerator_Reset(IEnumVARIANT *iface)
Definition: automation.c:657
static HRESULT create_view(MSIHANDLE, IDispatch **)
Definition: automation.c:2471
static HRESULT record_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:906
static HRESULT InstallerImpl_RelatedProducts(WORD flags, DISPPARAMS *pDispParams, VARIANT *result, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2294
static ULONG WINAPI ProvideMultipleClassInfo_AddRef(IProvideMultipleClassInfo *iface)
Definition: automation.c:444
static HRESULT WINAPI ListEnumerator_Skip(IEnumVARIANT *iface, ULONG celt)
Definition: automation.c:641
static ULONG WINAPI ListEnumerator_AddRef(IEnumVARIANT *iface)
Definition: automation.c:591
void release_typelib(void)
Definition: automation.c:127
static HRESULT InstallerImpl_LastErrorRecord(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1965
static HRESULT InstallerImpl_CreateRecord(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1658
static HRESULT WINAPI AutomationObject_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
Definition: automation.c:192
#define MAX_FUNC_PARAMS
Definition: automation.c:313
static HRESULT InstallerImpl_EnableLog(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1889
static const IID * get_riid_from_tid(tid_t tid)
Definition: automation.c:83
static HRESULT InstallerImpl_FileVersion(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2174
static HRESULT WINAPI ProvideMultipleClassInfo_GetInfoOfIndex(IProvideMultipleClassInfo *iface, ULONG iti, DWORD dwFlags, ITypeInfo **ti, DWORD *pdwTIFlags, ULONG *pcdispidReserved, IID *piidPrimary, IID *piidSource)
Definition: automation.c:492
static HRESULT get_products_count(const WCHAR *product, int *len)
Definition: automation.c:1078
static HRESULT WINAPI AutomationObject_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:316
static HRESULT installer_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:2321
HRESULT create_msiserver(IUnknown *outer, void **ppObj)
Definition: automation.c:2421
HRESULT(* auto_invoke_func)(AutomationObject *This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *pDispParams, VARIANT *result, EXCEPINFO *ei, UINT *arg_err)
Definition: automation.c:47
static void init_automation_object(AutomationObject *This, MSIHANDLE msiHandle, tid_t tid)
Definition: automation.c:544
static ULONG WINAPI AutomationObject_AddRef(IDispatch *iface)
Definition: automation.c:222
static ULONG WINAPI ListEnumerator_Release(IEnumVARIANT *iface)
Definition: automation.c:600
static HRESULT InstallerImpl_ProductInfo(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2213
static ULONG WINAPI AutomationObject_Release(IDispatch *iface)
Definition: automation.c:231
static HRESULT DatabaseImpl_LastErrorRecord(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1242
static HRESULT WINAPI AutomationObject_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
Definition: automation.c:248
static HRESULT WINAPI ProvideMultipleClassInfo_GetMultiTypeInfoCount(IProvideMultipleClassInfo *iface, ULONG *pcti)
Definition: automation.c:483
static HRESULT InstallerImpl_FileAttributes(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2144
#define REG_INDEX_DYN_DATA
Definition: automation.c:42
static HRESULT InstallerImpl_Environment(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:2129
static HRESULT list_invoke(AutomationObject *, DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *)
Definition: automation.c:1011
static HRESULT InstallerImpl_OpenDatabase(WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1769
static HRESULT create_list_enumerator(ListObject *, void **)
Definition: automation.c:700
static HRESULT InstallerImpl_Version(WORD wFlags, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1940
static ITypeInfo * typeinfos[LAST_tid]
Definition: automation.c:81
static ListEnumerator * impl_from_IEnumVARIANT(IEnumVARIANT *iface)
Definition: automation.c:559
static HRESULT InstallerImpl_OpenPackage(AutomationObject *This, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: automation.c:1685
static HRESULT create_summaryinfo(MSIHANDLE, IDispatch **)
Definition: automation.c:2487
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
UINT WINAPI MsiDoActionW(MSIHANDLE hInstall, LPCWSTR szAction)
Definition: install.c:64
LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
Definition: install.c:1541
UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
Definition: install.c:1597
UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, INSTALLSTATE iState)
Definition: install.c:947
UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, const WCHAR *szFeature, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
Definition: install.c:1088
UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
Definition: install.c:763
BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
Definition: install.c:670
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
Definition: msi.c:230
UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szBuffer, LPDWORD pcchValueBuf)
Definition: msi.c:1287
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
Definition: msi.c:2226
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
Definition: package.c:1674
UINT WINAPI MsiGetPropertyW(MSIHANDLE hinst, const WCHAR *name, WCHAR *buf, DWORD *sz)
Definition: package.c:2385
UINT WINAPI MsiOpenPackageExW(const WCHAR *szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1612
UINT WINAPI MsiSetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
Definition: package.c:2149
INT WINAPI MsiProcessMessage(MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, MSIHANDLE hRecord)
Definition: package.c:2017
UINT WINAPI MsiRecordSetStringW(MSIHANDLE handle, UINT iField, const WCHAR *szValue)
Definition: record.c:604
int WINAPI MsiRecordGetInteger(MSIHANDLE handle, UINT iField)
Definition: record.c:237
MSIHANDLE WINAPI MsiCreateRecord(UINT cParams)
Definition: record.c:92
UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, UINT iField, WCHAR *szValue, DWORD *pcchValue)
Definition: record.c:482
UINT WINAPI MsiRecordSetInteger(MSIHANDLE handle, UINT iField, int iVal)
Definition: record.c:303
UINT WINAPI MsiRecordGetFieldCount(MSIHANDLE handle)
Definition: record.c:113
UINT WINAPI MsiEnumProductsW(DWORD index, WCHAR *lpguid)
Definition: registry.c:1040
UINT WINAPI MsiEnumRelatedProductsW(const WCHAR *szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, WCHAR *lpProductBuf)
Definition: registry.c:1557
UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, const WCHAR *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:514
UINT WINAPI MsiSummaryInfoGetPropertyW(MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, INT *piValue, FILETIME *pftValue, WCHAR *szValueBuf, DWORD *pcchValueBuf)
Definition: suminfo.c:788
UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
Definition: suminfo.c:606
UINT WINAPI MsiSummaryInfoSetPropertyW(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const WCHAR *szValue)
Definition: suminfo.c:907
HRESULT WINAPI DispGetParam(DISPPARAMS *pdispparams, UINT position, VARTYPE vtTarg, VARIANT *pvarResult, UINT *puArgErr)
Definition: dispatch.c:116
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:531
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:458
#define swprintf
Definition: precomp.h:40
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define local
Definition: zutil.h:30
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
tid_t
Definition: ieframe.h:311
@ LAST_tid
Definition: ieframe.h:317
REFIID riid
Definition: atlbase.h:39
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
__u16 date
Definition: mkdosfs.c:8
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static TfClientId tid
#define create_database(name, tables, num_tables)
Definition: utils.h:42
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
enum tagINSTALLUILEVEL INSTALLUILEVEL
@ INSTALLUILEVEL_NOCHANGE
Definition: msi.h:64
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
static void msi_free(void *mem)
Definition: msipriv.h:1159
@ View_tid
Definition: msipriv.h:1125
@ Session_tid
Definition: msipriv.h:1122
@ Database_tid
Definition: msipriv.h:1119
@ SummaryInfo_tid
Definition: msipriv.h:1124
@ StringList_tid
Definition: msipriv.h:1123
@ Record_tid
Definition: msipriv.h:1121
@ Installer_tid
Definition: msipriv.h:1120
#define GUID_SIZE
Definition: msipriv.h:733
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord)
Definition: msiquery.c:720
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:469
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:518
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:236
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
MSICONDITION WINAPI MsiEvaluateConditionW(MSIHANDLE, LPCWSTR)
#define DISPID_VIEW_CLOSE
#define DISPID_RECORD_INTEGERDATA
#define DISPID_LIST_COUNT
#define DISPID_INSTALLER_UILEVEL
#define DISPID_SESSION_DOACTION
#define DISPID_INSTALLER_LASTERRORRECORD
#define DISPID_INSTALLER_FILEVERSION
#define DISPID_SESSION_DATABASE
#define DISPID_DATABASE_OPENVIEW
#define DISPID_INSTALLER_OPENPRODUCT
#define DISPID_INSTALLER_VERSION
#define DISPID_SESSION_FEATURECURRENTSTATE
#define DISPID_INSTALLER_RELATEDPRODUCTS
#define DISPID_SESSION_PROPERTY
#define DISPID_RECORD_STRINGDATA
#define DISPID_RECORD_FIELDCOUNT
#define DISPID_VIEW_MODIFY
#define DISPID_SESSION_INSTALLER
#define DISPID_INSTALLER_PRODUCTINFO
#define DISPID_INSTALLER_PRODUCTS
#define DISPID_INSTALLER_REGISTRYVALUE
#define DISPID_SESSION_SETINSTALLLEVEL
#define DISPID_VIEW_EXECUTE
#define DISPID_INSTALLER_FILEATTRIBUTES
#define DISPID_VIEW_FETCH
#define DISPID_LIST__NEWENUM
#define DISPID_INSTALLER_ENABLELOG
#define DISPID_DATABASE_SUMMARYINFORMATION
#define DISPID_SUMMARYINFO_PROPERTY
#define DISPID_INSTALLER_CREATERECORD
#define DISPID_SESSION_MESSAGE
#define DISPID_INSTALLER_INSTALLPRODUCT
#define DISPID_SUMMARYINFO_PROPERTYCOUNT
#define DISPID_INSTALLER_OPENPACKAGE
#define DISPID_SESSION_MODE
#define DISPID_SESSION_LANGUAGE
#define DISPID_INSTALLER_PRODUCTSTATE
#define DISPID_SESSION_EVALUATECONDITION
#define DISPID_SESSION_FEATUREREQUESTSTATE
#define DISPID_INSTALLER_OPENDATABASE
#define DISPID_INSTALLER_ENVIRONMENT
#define DISPID_INSTALLER_FILESIZE
#define DISPID_INSTALLER_SUMMARYINFORMATION
#define DISPID_LIST_ITEM
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define REG_BINARY
Definition: nt_native.h:1496
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define LOCALE_NEUTRAL
#define L(x)
Definition: ntvdm.h:50
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:428
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
UINT ui
Definition: oleauto.h:49
#define V_I4(A)
Definition: oleauto.h:247
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define V_DATE(A)
Definition: oleauto.h:231
const GUID IID_IProvideClassInfo
const GUID IID_IProvideClassInfo2
const GUID IID_IDispatch
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
#define list
Definition: rosglue.h:35
const WCHAR * str
#define REG_QWORD
Definition: sdbapi.c:597
#define REG_DWORD
Definition: sdbapi.c:596
DWORD LCID
Definition: nls.h:13
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
struct _DllVersionInfo DLLVERSIONINFO
#define TRACE(s)
Definition: solgame.cpp:4
IProvideMultipleClassInfo IProvideMultipleClassInfo_iface
Definition: automation.c:145
MSIHANDLE msiHandle
Definition: automation.c:152
IDispatch IDispatch_iface
Definition: automation.c:144
IEnumVARIANT IEnumVARIANT_iface
Definition: automation.c:168
ListObject * list
Definition: automation.c:173
AutomationObject autoobj
Definition: automation.c:156
VARIANT * data
Definition: automation.c:158
IDispatch * installer
Definition: automation.c:178
AutomationObject autoobj
Definition: automation.c:177
DWORD dwMajorVersion
Definition: shlwapi.h:1955
DWORD dwBuildNumber
Definition: shlwapi.h:1957
DWORD dwMinorVersion
Definition: shlwapi.h:1956
DWORD dwPlatformID
Definition: shlwapi.h:1958
Definition: send.c:48
REFIID riid
Definition: automation.c:55
auto_invoke_func fn_invoke
Definition: automation.c:56
auto_free_func fn_free
Definition: automation.c:57
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
Definition: variant.c:1317
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut)
Definition: variant.c:1286
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
int INSTALLSTATE
Definition: winemsi.idl:31
unsigned long MSIHANDLE
Definition: winemsi.idl:27
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:960
#define ERROR_INVALID_HANDLE_STATE
Definition: winerror.h:967
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define DISP_E_EXCEPTION
Definition: winerror.h:2518
#define DISP_E_BADINDEX
Definition: winerror.h:2520
#define ERROR_INSTALL_SUSPEND
Definition: winerror.h:962
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:984
#define DISP_E_PARAMNOTOPTIONAL
Definition: winerror.h:2524
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184