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