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