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