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