msi automation patches

Misha Koshelev mk144210 at bcm.tmc.edu
Wed Feb 28 12:28:46 CST 2007


Ok, so since my patches weren't commited to git yet, I've consolidated
the new automation changes I've made in the attached patches. James and
Rob, if they look good to you I will submit these version to
wine-patches (so my total will once again be four patches, 1 is
http://www.winehq.org/pipermail/wine-patches/2007-February/036359.html ,
2 and 3 attached, and 4 is 
http://www.winehq.org/pipermail/wine-patches/2007-February/036362.html ) and
wait to submit anything more for automation until all 4 patches are in.

Please let me know Rob (I used DispGetParam, thanks a lot, so probably just need to 
look at my AutomationObject::Invoke and then the individual object Invoke handlers in
the 0003 patch below) and James (I guess in regards to comments and formatting).

Thanks a lot
Misha
-------------- next part --------------
From 7a26ec8da0ca6d2b031a35191a865882cf5a64b4 Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Wed, 28 Feb 2007 12:08:52 -0600
Subject: msi: Expand IDL file to contain all OLE automation interfaces.
---
 dlls/msi/msiserver.idl       |  873 +++++++++++++++++++++++++++++++++++++++---
 dlls/msi/msiserver_dispids.h |  180 +++++++++
 2 files changed, 993 insertions(+), 60 deletions(-)

diff --git a/dlls/msi/msiserver.idl b/dlls/msi/msiserver.idl
index 9966d90..8735b7c 100644
--- a/dlls/msi/msiserver.idl
+++ b/dlls/msi/msiserver.idl
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007 Mike McCormack
+ * Copyright (C) 2007 Misha Koshelev
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,14 +17,21 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "msiserver_dispids.h"
 import "unknwn.idl";
 import "wtypes.idl";
 import "objidl.idl";
 import "oaidl.idl";
 
-[ uuid(000C1092-0000-0000-C000-000000000046), version(1.0) ]
+[
+    uuid(000C1092-0000-0000-C000-000000000046),
+    version(1.0),
+    helpstring("Microsoft Windows Installer Object Library")
+]
 library WindowsInstaller
 {
+    /* TLib :
+     * Forward declare all types defined in this typelib */
     dispinterface Installer;
     dispinterface Record;
     dispinterface Session;
@@ -37,87 +45,832 @@ library WindowsInstaller
     dispinterface Product;
     dispinterface Patch;
 
-    [ uuid(000C1090-0000-0000-C000-000000000046) ]
-    dispinterface Installer
-    {
-    properties:
-    methods:
-    }
-
-    [ uuid(000C1093-0000-0000-C000-000000000046) ]
-    dispinterface Record
-    {
-    properties:
-    methods:
-    }
-
-    [ uuid(000C1095-0000-0000-C000-000000000046) ]
-    dispinterface StringList
-    {
+    typedef enum {
+        msiUILevelNoChange = 0,
+        msiUILevelDefault = 1,
+        msiUILevelNone = 2,
+        msiUILevelBasic = 3,
+        msiUILevelReduced = 4,
+        msiUILevelFull = 5,
+        msiUILevelHideCancel = 32,
+        msiUILevelProgressOnly = 64,
+        msiUILevelEndDialog = 128,
+        msiUILevelSourceResOnly = 256
+    } MsiUILevel;
+
+    typedef enum {
+        msiInstallStateNotUsed = -7,
+        msiInstallStateBadConfig = -6,
+        msiInstallStateIncomplete = -5,
+        msiInstallStateSourceAbsent = -4,
+        msiInstallStateInvalidArg = -2,
+        msiInstallStateUnknown = -1,
+        msiInstallStateBroken = 0,
+        msiInstallStateAdvertised = 1,
+        msiInstallStateRemoved = 1,
+        msiInstallStateAbsent = 2,
+        msiInstallStateLocal = 3,
+        msiInstallStateSource = 4,
+        msiInstallStateDefault = 5
+    } MsiInstallState;
+
+    typedef enum {
+        msiReinstallModeFileMissing = 2,
+        msiReinstallModeFileOlderVersion = 4,
+        msiReinstallModeFileEqualVersion = 8,
+        msiReinstallModeFileExact = 16,
+        msiReinstallModeFileVerify = 32,
+        msiReinstallModeFileReplace = 64,
+        msiReinstallModeMachineData = 128,
+        msiReinstallModeUserData = 256,
+        msiReinstallModeShortcut = 512,
+        msiReinstallModePackage = 1024
+    } MsiReinstallMode;
+
+    typedef enum {
+        msiInstallTypeDefault = 0,
+        msiInstallTypeNetworkImage = 1,
+        msiInstallTypeSingleInstance = 2
+    } MsiInstallType;
+
+    typedef enum {
+        msiInstallModeNoSourceResolution = -3,
+        msiInstallModeNoDetection = -2,
+        msiInstallModeExisting = -1,
+        msiInstallModeDefault = 0
+    } MsiInstallMode;
+
+    typedef enum {
+        msiSignatureInfoCertificate = 0,
+        msiSignatureInfoHash = 1
+    } MsiSignatureInfo;
+
+    typedef enum {
+        msiReadStreamInteger = 0,
+        msiReadStreamBytes = 1,
+        msiReadStreamAnsi = 2,
+        msiReadStreamDirect = 3
+    } MsiReadStream;
+
+    typedef enum {
+        msiRunModeAdmin = 0,
+        msiRunModeAdvertise = 1,
+        msiRunModeMaintenance = 2,
+        msiRunModeRollbackEnabled = 3,
+        msiRunModeLogEnabled = 4,
+        msiRunModeOperations = 5,
+        msiRunModeRebootAtEnd = 6,
+        msiRunModeRebootNow = 7,
+        msiRunModeCabinet = 8,
+        msiRunModeSourceShortNames = 9,
+        msiRunModeTargetShortNames = 10,
+        msiRunModeWindows9x = 12,
+        msiRunModeZawEnabled = 13,
+        msiRunModeScheduled = 16,
+        msiRunModeRollback = 17,
+        msiRunModeCommit = 18
+    } MsiRunMode;
+
+    typedef enum {
+        msiInstallContextFirstVisible = 0,
+        msiInstallContextUserManaged = 1,
+        msiInstallContextUser = 2,
+        msiInstallContextMachine = 4,
+        msiInstallContextAllUserManaged = 8
+    } MsiInstallContext;
+
+    [
+        uuid(000C1090-0000-0000-C000-000000000046),
+        helpcontext(0x00002328)
+    ]
+    dispinterface Installer {
         properties:
+        [id(DISPID_INSTALLER_UILEVEL)]
+            MsiUILevel UILevel;
         methods:
-    }
+        [id(DISPID_INSTALLER_CREATERECORD)]
+            Record* CreateRecord([in] long Count);
+        [id(DISPID_INSTALLER_OPENPACKAGE)]
+            Session* OpenPackage(
+                [in] VARIANT PackagePath,
+                [in, optional, defaultvalue(0)] long Options);
+        [id(DISPID_INSTALLER_OPENPRODUCT)]
+            Session* OpenProduct([in] BSTR ProductCode);
+        [id(DISPID_INSTALLER_OPENDATABASE)]
+            Database* OpenDatabase(
+                [in] BSTR DatabasePath,
+                [in] VARIANT OpenMode);
+        [id(DISPID_INSTALLER_SUMMARYINFORMATION), propget]
+            SummaryInfo* SummaryInformation(
+                [in] BSTR PackagePath,
+                [in, optional, defaultvalue(0)] long UpdateCount);
+        [id(DISPID_INSTALLER_ENABLELOG)]
+            void EnableLog(
+                [in] BSTR LogMode,
+                [in] BSTR LogFile);
+        [id(DISPID_INSTALLER_INSTALLPRODUCT)]
+            void InstallProduct(
+                [in] BSTR PackagePath,
+                [in, optional, defaultvalue("0")] BSTR PropertyValues);
+        [id(DISPID_INSTALLER_VERSION), propget]
+            BSTR Version();
+        [id(DISPID_INSTALLER_LASTERRORRECORD)]
+            Record* LastErrorRecord();
+        [id(DISPID_INSTALLER_REGISTRYVALUE)]
+            BSTR RegistryValue(
+                [in] VARIANT Root,
+                [in] BSTR Key,
+                [in, optional] VARIANT Value);
+        [id(DISPID_INSTALLER_FILEATTRIBUTES)]
+            long FileAttributes([in] BSTR FilePath);
+        [id(DISPID_INSTALLER_FILESIZE)]
+            long FileSize([in] BSTR FilePath);
+        [id(DISPID_INSTALLER_FILEVERSION)]
+            BSTR FileVersion(
+                [in] BSTR FilePath,
+                [in, optional] VARIANT Language);
+        [id(DISPID_INSTALLER_ENVIRONMENT), propget]
+            BSTR Environment([in] BSTR Variable);
+        [id(DISPID_INSTALLER_ENVIRONMENT), propput]
+            void Environment(
+                [in] BSTR Variable,
+                [in] BSTR rhs);
+        [id(DISPID_INSTALLER_PRODUCTSTATE), propget]
+            MsiInstallState ProductState([in] BSTR Product);
+        [id(DISPID_INSTALLER_PRODUCTINFO), propget]
+            BSTR ProductInfo(
+                [in] BSTR Product,
+                [in] BSTR Attribute);
+        [id(DISPID_INSTALLER_CONFIGUREPRODUCT)]
+            void ConfigureProduct(
+                [in] BSTR Product,
+                [in] long InstallLevel,
+                [in] MsiInstallState InstallState);
+        [id(DISPID_INSTALLER_REINSTALLPRODUCT)]
+            void ReinstallProduct(
+                [in] BSTR Product,
+                [in] MsiReinstallMode ReinstallMode);
+        [id(DISPID_INSTALLER_COLLECTUSERINFO)]
+            void CollectUserInfo([in] BSTR Product);
+        [id(DISPID_INSTALLER_APPLYPATCH)]
+            void ApplyPatch(
+                [in] BSTR PatchPackage,
+                [in] BSTR InstallPackage,
+                [in] MsiInstallType InstallType,
+                [in] BSTR CommandLine);
+        [id(DISPID_INSTALLER_FEATUREPARENT), propget]
+            BSTR FeatureParent(
+                [in] BSTR Product,
+                [in] BSTR Feature);
+        [id(DISPID_INSTALLER_FEATURESTATE), propget]
+            MsiInstallState FeatureState(
+                [in] BSTR Product,
+                [in] BSTR Feature);
+        [id(DISPID_INSTALLER_USEFEATURE)]
+            void UseFeature(
+                [in] BSTR Product,
+                [in] BSTR Feature,
+                [in] MsiInstallMode InstallMode);
+        [id(DISPID_INSTALLER_FEATUREUSAGECOUNT), propget]
+            long FeatureUsageCount(
+                [in] BSTR Product,
+                [in] BSTR Feature);
+        [id(DISPID_INSTALLER_FEATUREUSAGEDATE), propget]
+            DATE FeatureUsageDate(
+                [in] BSTR Product,
+                [in] BSTR Feature);
+        [id(DISPID_INSTALLER_CONFIGUREFEATURE)]
+            void ConfigureFeature(
+                [in] BSTR Product,
+                [in] BSTR Feature,
+                [in] MsiInstallState InstallState);
+        [id(DISPID_INSTALLER_REINSTALLFEATURE)]
+            void ReinstallFeature(
+                [in] BSTR Product,
+                [in] BSTR Feature,
+                [in] MsiReinstallMode ReinstallMode);
+        [id(DISPID_INSTALLER_PROVIDECOMPONENT)]
+            BSTR ProvideComponent(
+                [in] BSTR Product,
+                [in] BSTR Feature,
+                [in] BSTR Component,
+                [in] long InstallMode);
+        [id(DISPID_INSTALLER_COMPONENTPATH), propget]
+            BSTR ComponentPath(
+                [in] BSTR Product,
+                [in] BSTR Component);
+        [id(DISPID_INSTALLER_PROVIDEQUALIFIEDCOMPONENT)]
+            BSTR ProvideQualifiedComponent(
+                [in] BSTR Category,
+                [in] BSTR Qualifier,
+                [in] long InstallMode);
+        [id(DISPID_INSTALLER_QUALIFIERDESCRIPTION), propget]
+            BSTR QualifierDescription(
+                [in] BSTR Category,
+                [in] BSTR Qualifier);
+        [id(DISPID_INSTALLER_COMPONENTQUALIFIERS), propget]
+            StringList* ComponentQualifiers([in] BSTR Category);
+        [id(DISPID_INSTALLER_PRODUCTS), propget]
+            StringList* Products();
+        [id(DISPID_INSTALLER_FEATURES), propget]
+            StringList* Features([in] BSTR Product);
+        [id(DISPID_INSTALLER_COMPONENTS), propget]
+            StringList* Components();
+        [id(DISPID_INSTALLER_COMPONENTCLIENTS), propget]
+            StringList* ComponentClients([in] BSTR Component);
+        [id(DISPID_INSTALLER_PATCHES), propget]
+            StringList* Patches([in] BSTR Product);
+        [id(DISPID_INSTALLER_RELATEDPRODUCTS), propget]
+            StringList* RelatedProducts([in] BSTR UpgradeCode);
+        [id(DISPID_INSTALLER_PATCHINFO), propget]
+            BSTR PatchInfo(
+                [in] BSTR Patch,
+                [in] BSTR Attribute);
+        [id(DISPID_INSTALLER_PATCHTRANSFORMS), propget]
+            BSTR PatchTransforms(
+                [in] BSTR Product,
+                [in] BSTR Patch);
+        [id(DISPID_INSTALLER_ADDSOURCE)]
+            void AddSource(
+                [in] BSTR Product,
+                [in] BSTR User,
+                [in] BSTR Source);
+        [id(DISPID_INSTALLER_CLEARSOURCELIST)]
+            void ClearSourceList(
+                [in] BSTR Product,
+                [in] BSTR User);
+        [id(DISPID_INSTALLER_FORCESOURCELISTRESOLUTION)]
+            void ForceSourceListResolution(
+                [in] BSTR Product,
+                [in] BSTR User);
+        [id(DISPID_INSTALLER_GETSHORTCUTTARGET), propget]
+            Record* GetShortcutTarget([in] BSTR ShortcutPath);
+        [id(DISPID_INSTALLER_FILEHASH)]
+            Record* FileHash(
+                [in] BSTR FilePath,
+                [in] long Options);
+        [id(DISPID_INSTALLER_FILESIGNATUREINFO)]
+            SAFEARRAY(unsigned char) FileSignatureInfo(
+                [in] BSTR FilePath,
+                [in] long Options,
+                [in] MsiSignatureInfo Format);
+        [id(DISPID_INSTALLER_REMOVEPATCHES)]
+            void RemovePatches(
+                [in] BSTR PatchList,
+                [in] BSTR Product,
+                [in] MsiInstallType UninstallType,
+                [in, optional, defaultvalue("0")] BSTR PropertyList);
+        [id(DISPID_INSTALLER_APPLYMULTIPLEPATCHES)]
+            void ApplyMultiplePatches(
+                [in] BSTR PatchPackage,
+                [in] BSTR Product,
+                [in] BSTR PropertiesList);
+        [id(DISPID_INSTALLER_PRODUCT), propget]
+            Product* Product(
+                [in] BSTR Product,
+                [in] BSTR UserSid,
+                [in] MsiInstallContext iContext);
+        [id(DISPID_INSTALLER_PATCH), propget]
+            Patch* Patch(
+                [in] BSTR PatchCode,
+                [in] BSTR ProductCode,
+                [in] BSTR UserSid,
+                [in] MsiInstallContext iContext);
+        [id(DISPID_INSTALLER_PRODUCTSEX), propget]
+            RecordList* ProductsEx(
+                [in] BSTR Product,
+                [in] BSTR UserSid,
+                [in] long Contexts);
+        [id(DISPID_INSTALLER_PATCHESEX), propget]
+            RecordList* PatchesEx(
+                [in] BSTR Product,
+                [in] BSTR UserSid,
+                [in] long Contexts,
+                [in] long filter);
+        [id(DISPID_INSTALLER_EXTRACTPATCHXMLDATA)]
+            BSTR ExtractPatchXMLData([in] BSTR PatchPath);
+    };
 
-    [ uuid(000C1096-0000-0000-C000-000000000046) ]
-    dispinterface RecordList
-    {
+    [
+        uuid(000C1093-0000-0000-C000-000000000046),
+        helpcontext(0x00002454)
+    ]
+    dispinterface Record {
         properties:
         methods:
-    }
+        [id(DISPID_RECORD_STRINGDATA), propget]
+            BSTR StringData([in] long Field);
+        [id(DISPID_RECORD_STRINGDATA), propput]
+            void StringData(
+                [in] long Field,
+                [in] BSTR rhs);
+        [id(DISPID_RECORD_INTEGERDATA), propget]
+            long IntegerData([in] long Field);
+        [id(DISPID_RECORD_INTEGERDATA), propput]
+            void IntegerData(
+                [in] long Field,
+                [in] long rhs);
+        [id(DISPID_RECORD_SETSTREAM)]
+            void SetStream(
+                [in] long Field,
+                [in] BSTR FilePath);
+        [id(DISPID_RECORD_READSTREAM)]
+            BSTR ReadStream(
+                [in] long Field,
+                [in] long Length,
+                [in] MsiReadStream Format);
+        [id(DISPID_RECORD_FIELDCOUNT), propget]
+            long FieldCount();
+        [id(DISPID_RECORD_ISNULL), propget]
+            VARIANT_BOOL IsNull([in] long Field);
+        [id(DISPID_RECORD_DATASIZE), propget]
+            long DataSize([in] long Field);
+        [id(DISPID_RECORD_CLEARDATA)]
+            void ClearData();
+        [id(DISPID_RECORD_FORMATTEXT)]
+            BSTR FormatText();
+    };
 
-    [ uuid(000C109A-0000-0000-C000-000000000046) ]
-    dispinterface UIPreview
-    {
+    typedef enum {
+        msiDoActionStatusNoAction = 0,
+        msiDoActionStatusSuccess = 1,
+        msiDoActionStatusUserExit = 2,
+        msiDoActionStatusFailure = 3,
+        msiDoActionStatusSuspend = 4,
+        msiDoActionStatusFinished = 5,
+        msiDoActionStatusWrongState = 6,
+        msiDoActionStatusBadActionData = 7
+    } MsiDoActionStatus;
+
+    typedef enum {
+        msiEvaluateConditionFalse = 0,
+        msiEvaluateConditionTrue = 1,
+        msiEvaluateConditionNone = 2,
+        msiEvaluateConditionError = 3
+    } _MsiEvaluateCondition; /* Added underscore to avoid conflict with function name */
+
+    typedef enum {
+        msiMessageStatusError = -1,
+        msiMessageStatusNone = 0,
+        msiMessageStatusOk = 1,
+        msiMessageStatusCancel = 2,
+        msiMessageStatusAbort = 3,
+        msiMessageStatusRetry = 4,
+        msiMessageStatusIgnore = 5,
+        msiMessageStatusYes = 6,
+        msiMessageStatusNo = 7
+    } MsiMessageStatus;
+
+    typedef enum {
+        msiMessageTypeFatalExit = 0,
+        msiMessageTypeError = 16777216,
+        msiMessageTypeWarning = 33554432,
+        msiMessageTypeUser = 50331648,
+        msiMessageTypeInfo = 67108864,
+        msiMessageTypeFilesInUse = 83886080,
+        msiMessageTypeResolveSource = 100663296,
+        msiMessageTypeOutOfDiskSpace = 117440512,
+        msiMessageTypeActionStart = 134217728,
+        msiMessageTypeActionData = 150994944,
+        msiMessageTypeProgress = 167772160,
+        msiMessageTypeCommonData = 184549376,
+        msiMessageTypeOk = 0,
+        msiMessageTypeOkCancel = 1,
+        msiMessageTypeAbortRetryIgnore = 2,
+        msiMessageTypeYesNoCancel = 3,
+        msiMessageTypeYesNo = 4,
+        msiMessageTypeRetryCancel = 5,
+        msiMessageTypeDefault1 = 0,
+        msiMessageTypeDefault2 = 256,
+        msiMessageTypeDefault3 = 512
+    } MsiMessageType;
+
+    typedef enum {
+        msiCostTreeSelfOnly = 0,
+        msiCostTreeChildren = 1,
+        msiCostTreeParents = 2
+    } MsiCostTree;
+
+    typedef enum {
+        msiDatabaseStateRead = 0,
+        msiDatabaseStateWrite = 1
+    } MsiDatabaseState;
+
+    [
+        uuid(000C109E-0000-0000-C000-000000000046),
+        helpcontext(0x000025e4)
+    ]
+    dispinterface Session {
         properties:
         methods:
-    }
+        [id(DISPID_SESSION_INSTALLER), propget]
+            Installer* Installer();
+        [id(DISPID_SESSION_PROPERTY), propget]
+            BSTR Property([in] BSTR Name);
+        [id(DISPID_SESSION_PROPERTY), propput]
+            void Property(
+                [in] BSTR Name,
+                [in] BSTR rhs);
+        [id(DISPID_SESSION_LANGUAGE), propget]
+            long Language();
+        [id(DISPID_SESSION_MODE), propget]
+            VARIANT_BOOL Mode([in] MsiRunMode Flag);
+        [id(DISPID_SESSION_MODE), propput]
+            void Mode(
+                [in] MsiRunMode Flag,
+                [in] VARIANT_BOOL rhs);
+        [id(DISPID_SESSION_DATABASE), propget]
+            Database* Database();
+        [id(DISPID_SESSION_SOURCEPATH), propget]
+            BSTR SourcePath([in] BSTR Folder);
+        [id(DISPID_SESSION_TARGETPATH), propget]
+            BSTR TargetPath([in] BSTR Folder);
+        [id(DISPID_SESSION_TARGETPATH), propput]
+            void TargetPath(
+                [in] BSTR Folder,
+                [in] BSTR rhs);
+        [id(DISPID_SESSION_DOACTION)]
+            MsiDoActionStatus DoAction([in] BSTR Action);
+        [id(DISPID_SESSION_SEQUENCE)]
+            MsiDoActionStatus Sequence(
+                [in] BSTR Table,
+                [in, optional] VARIANT Mode);
+        [id(DISPID_SESSION_EVALUATECONDITION)]
+            _MsiEvaluateCondition EvaluateCondition([in] BSTR Expression);
+        [id(DISPID_SESSION_FORMATRECORD)]
+            BSTR FormatRecord([in] Record* Record);
+        [id(DISPID_SESSION_MESSAGE)]
+            MsiMessageStatus Message(
+                [in] MsiMessageType Kind,
+                [in] Record* Record);
+        [id(DISPID_SESSION_FEATURECURRENTSTATE), propget]
+            MsiInstallState FeatureCurrentState([in] BSTR Feature);
+        [id(DISPID_SESSION_FEATUREREQUESTSTATE), propget]
+            MsiInstallState FeatureRequestState([in] BSTR Feature);
+        [id(DISPID_SESSION_FEATUREREQUESTSTATE), propput]
+            void FeatureRequestState(
+                [in] BSTR Feature,
+                [in] MsiInstallState rhs);
+        [id(DISPID_SESSION_FEATUREVALIDSTATES), propget]
+            long FeatureValidStates([in] BSTR Feature);
+        [id(DISPID_SESSION_FEATURECOST), propget]
+            long FeatureCost(
+                [in] BSTR Feature,
+                [in] MsiCostTree CostTree,
+                [in] MsiInstallState State);
+        [id(DISPID_SESSION_COMPONENTCURRENTSTATE), propget]
+            MsiInstallState ComponentCurrentState([in] BSTR Component);
+        [id(DISPID_SESSION_COMPONENTREQUESTSTATE), propget]
+            MsiInstallState ComponentRequestState([in] BSTR Component);
+        [id(DISPID_SESSION_COMPONENTREQUESTSTATE), propput]
+            void ComponentRequestState(
+                [in] BSTR Component,
+                [in] MsiInstallState rhs);
+        [id(DISPID_SESSION_SETINSTALLLEVEL)]
+            void SetInstallLevel([in] long Level);
+        [id(DISPID_SESSION_VERIFYDISKSPACE), propget]
+            VARIANT_BOOL VerifyDiskSpace();
+        [id(DISPID_SESSION_PRODUCTPROPERTY), propget]
+            BSTR ProductProperty([in] BSTR Property);
+        [id(DISPID_SESSION_FEATUREINFO), propget]
+            FeatureInfo* FeatureInfo([in] BSTR Feature);
+        [id(DISPID_SESSION_COMPONENTCOSTS), propget]
+            RecordList* ComponentCosts(
+                [in] BSTR Component,
+                [in] MsiInstallState State);
+    };
+
+    typedef enum {
+        msiTransformErrorNone = 0,
+        msiTransformErrorAddExistingRow = 1,
+        msiTransformErrorDeleteNonExistingRow = 2,
+        msiTransformErrorAddExistingTable = 4,
+        msiTransformErrorDeleteNonExistingTable = 8,
+        msiTransformErrorUpdateNonExistingRow = 16,
+        msiTransformErrorChangeCodePage = 32,
+        msiTransformErrorViewTransform = 256
+    } MsiTransformError;
+
+    typedef enum {
+        msiTransformValidationNone = 0,
+        msiTransformValidationLanguage = 1,
+        msiTransformValidationProduct = 2,
+        msiTransformValidationPlatform = 4,
+        msiTransformValidationMajorVer = 8,
+        msiTransformValidationMinorVer = 16,
+        msiTransformValidationUpdateVer = 32,
+        msiTransformValidationLess = 64,
+        msiTransformValidationLessOrEqual = 128,
+        msiTransformValidationEqual = 256,
+        msiTransformValidationGreaterOrEqual = 512,
+        msiTransformValidationGreater = 1024,
+        msiTransformValidationUpgradeCode = 2048
+    } MsiTransformValidation;
 
-    [ uuid(000C109B-0000-0000-C000-000000000046) ]
-    dispinterface SummaryInfo
-    {
+    [
+        uuid(000C109D-0000-0000-C000-000000000046),
+        helpcontext(0x0000251c)
+    ]
+    dispinterface Database {
         properties:
         methods:
-    }
+        [id(DISPID_DATABASE_DATABASESTATE), propget]
+            MsiDatabaseState DatabaseState();
+        [id(DISPID_DATABASE_SUMMARYINFORMATION), propget]
+            SummaryInfo* SummaryInformation([in, optional, defaultvalue(0)] long UpdateCount);
+        [id(DISPID_DATABASE_OPENVIEW)]
+            View* OpenView([in] BSTR Sql);
+        [id(DISPID_DATABASE_COMMIT)]
+            void Commit();
+        [id(DISPID_DATABASE_PRIMARYKEYS), propget]
+            Record* PrimaryKeys([in] BSTR Table);
+        [id(DISPID_DATABASE_IMPORT)]
+            void Import(
+                [in] BSTR Folder,
+                [in] BSTR File);
+        [id(DISPID_DATABASE_EXPORT)]
+            void Export(
+                [in] BSTR Table,
+                [in] BSTR Folder,
+                [in] BSTR File);
+        [id(DISPID_DATABASE_MERGE)]
+            VARIANT_BOOL Merge(
+                [in] Database* Database,
+                [in, optional, defaultvalue("0")] BSTR ErrorTable);
+        [id(DISPID_DATABASE_GENERATETRANSFORM)]
+            VARIANT_BOOL GenerateTransform(
+                [in] Database* ReferenceDatabase,
+                [in, optional, defaultvalue("0")] BSTR TransformFile);
+        [id(DISPID_DATABASE_APPLYTRANSFORM)]
+            void ApplyTransform(
+                [in] BSTR TransformFile,
+                [in] MsiTransformError ErrorConditions);
+        [id(DISPID_DATABASE_ENABLEUIPREVIEW)]
+            UIPreview* EnableUIPreview();
+        [id(DISPID_DATABASE_TABLEPERSISTENT), propget]
+            _MsiEvaluateCondition TablePersistent([in] BSTR Table);
+        [id(DISPID_DATABASE_CREATETRANSFORMSUMMARYINFO)]
+            void CreateTransformSummaryInfo(
+                [in] Database* ReferenceDatabase,
+                [in] BSTR TransformFile,
+                [in] MsiTransformError ErrorConditions,
+                [in] MsiTransformValidation Validation);
+    };
 
-    [ uuid(000C109C-0000-0000-C000-000000000046) ]
-    dispinterface View
-    {
+    [
+        uuid(000C109B-0000-0000-C000-000000000046),
+        helpcontext(0x00002580)
+    ]
+    dispinterface SummaryInfo {
         properties:
         methods:
-    }
+        [id(DISPID_SUMMARYINFO_PROPERTY), propget]
+            VARIANT Property([in] long Pid);
+        [id(DISPID_SUMMARYINFO_PROPERTY), propput]
+            void Property(
+                [in] long Pid,
+                [in] VARIANT rhs);
+        [id(DISPID_SUMMARYINFO_PROPERTYCOUNT), propget]
+            long PropertyCount();
+        [id(DISPID_SUMMARYINFO_PERSIST)]
+            void Persist();
+    };
 
-    [ uuid(000C109D-0000-0000-C000-000000000046) ]
-    dispinterface Database
-    {
+    typedef enum {
+        msiViewModifySeek = -1,
+        msiViewModifyRefresh = 0,
+        msiViewModifyInsert = 1,
+        msiViewModifyUpdate = 2,
+        msiViewModifyAssign = 3,
+        msiViewModifyReplace = 4,
+        msiViewModifyMerge = 5,
+        msiViewModifyDelete = 6,
+        msiViewModifyInsertTemporary = 7,
+        msiViewModifyValidate = 8,
+        msiViewModifyValidateNew = 9,
+        msiViewModifyValidateField = 10,
+        msiViewModifyValidateDelete = 11
+    } _MsiViewModify; /* Added underscore to avoid conflict with MsiViewModify function in msiquery.h */
+
+    typedef enum {
+        msiColumnInfoNames = 0,
+        msiColumnInfoTypes = 1
+    } MsiColumnInfo;
+
+    [
+        uuid(000C109C-0000-0000-C000-000000000046),
+        helpcontext(0x000024b8)
+    ]
+    dispinterface View {
+        properties:
+        methods:
+        [id(DISPID_VIEW_EXECUTE)]
+            void Execute([in, optional, defaultvalue(0)] Record* Params);
+        [id(DISPID_VIEW_FETCH)]
+            Record* Fetch();
+        [id(DISPID_VIEW_MODIFY)]
+            void Modify(
+                [in] _MsiViewModify Mode,
+                Record* Record);
+        [id(DISPID_VIEW_COLUMNINFO), propget]
+            Record* ColumnInfo([in] MsiColumnInfo Info);
+        [id(DISPID_VIEW_CLOSE)]
+            void Close();
+        [id(DISPID_VIEW_GETERROR)]
+            BSTR GetError();
+    };
+
+    [
+        uuid(000C109A-0000-0000-C000-000000000046),
+        helpcontext(0x00002648)
+    ]
+    dispinterface UIPreview {
+        properties:
+        methods:
+        [id(DISPID_UIPREVIEW_PROPERTY), propget]
+            BSTR Property([in] BSTR Name);
+        [id(DISPID_UIPREVIEW_PROPERTY), propput]
+            void Property(
+                [in] BSTR Name,
+                [in] BSTR rhs);
+        [id(DISPID_UIPREVIEW_VIEWDIALOG)]
+            void ViewDialog([in] BSTR Dialog);
+        [id(DISPID_UIPREVIEW_VIEWBILLBOARD)]
+            void ViewBillboard(
+                [in] BSTR Control,
+                [in] BSTR Billboard);
+    };
+
+    [
+        uuid(000C109F-0000-0000-C000-000000000046),
+        helpcontext(0x0000238c)
+    ]
+    dispinterface FeatureInfo {
         properties:
+        [id(DISPID_FEATUREINFO_ATTRIBUTES)]
+            long Attributes;
         methods:
-    }
-
-    [ uuid(000C109E-0000-0000-C000-000000000046) ]
-    dispinterface Session
-    {
-    properties:
-    methods:
-    }
-
-    [ uuid(000C109F-0000-0000-C000-000000000046) ]
-    dispinterface FeatureInfo
-    {
+        [id(DISPID_FEATUREINFO_TITLE), propget]
+            BSTR Title();
+        [id(DISPID_FEATUREINFO_DESCRIPTION), propget]
+            BSTR Description();
+    };
+
+    [
+        uuid(000C1096-0000-0000-C000-000000000046),
+        helpcontext(0x000023f3)
+    ]
+    dispinterface RecordList {
+        properties:
+        methods:
+        [id(DISPID_RECORDLIST__NEWENUM)]
+            IUnknown _NewEnum();
+        [id(DISPID_RECORDLIST_ITEM), propget]
+            Record* Item(long Index);
+        [id(DISPID_RECORDLIST_COUNT), propget]
+            long Count();
+    };
+
+    [
+        uuid(000C1095-0000-0000-C000-000000000046),
+        helpcontext(0x000023f0)
+    ]
+    dispinterface StringList {
         properties:
         methods:
-    }
+        [id(DISPID_STRINGLIST__NEWENUM)]
+            IUnknown _NewEnum();
+        [id(DISPID_STRINGLIST_ITEM), propget]
+            BSTR Item(long Index);
+        [id(DISPID_STRINGLIST_COUNT), propget]
+            long Count();
+    };
 
-    [ uuid(000C10A0-0000-0000-C000-000000000046) ]
-    dispinterface Product
-    {
+    typedef enum {
+        msiInstallSourceTypeUnknown = 0,
+        msiInstallSourceTypeNetwork = 1,
+        msiInstallSourceTypeURL = 2,
+        msiInstallSourceTypeMedia = 4
+    } MsiInstallSourceType;
+
+    [
+        uuid(000C10A0-0000-0000-C000-000000000046),
+        helpcontext(0x00002396)
+    ]
+    dispinterface Product {
         properties:
         methods:
-    }
+        [id(DISPID_PRODUCT_PRODUCTCODE), propget]
+            BSTR ProductCode();
+        [id(DISPID_PRODUCT_USERSID), propget]
+            BSTR UserSid();
+        [id(DISPID_PRODUCT_CONTEXT), propget]
+            MsiInstallContext Context();
+        [id(DISPID_PRODUCT_STATE), propget]
+            MsiInstallState State();
+        [id(DISPID_PRODUCT_INSTALLPROPERTY), propget]
+            BSTR InstallProperty([in] BSTR Name);
+        [id(DISPID_PRODUCT_COMPONENTSTATE), propget]
+            MsiInstallState ComponentState([in] BSTR Component);
+        [id(DISPID_PRODUCT_FEATURESTATE), propget]
+            MsiInstallState FeatureState([in] BSTR Feature);
+        [id(DISPID_PRODUCT_SOURCES), propget]
+            StringList* Sources([in] long SourceType);
+        [id(DISPID_PRODUCT_MEDIADISKS), propget]
+            RecordList* MediaDisks();
+        [id(DISPID_PRODUCT_SOURCELISTADDSOURCE)]
+            void SourceListAddSource(
+                [in] MsiInstallSourceType iSourceType,
+                [in] BSTR Source,
+                [in] long dwIndex);
+        [id(DISPID_PRODUCT_SOURCELISTADDMEDIADISK)]
+            void SourceListAddMediaDisk(
+                [in] long dwDiskId,
+                [in] BSTR VolumeLabel,
+                [in] BSTR DiskPrompt);
+        [id(DISPID_PRODUCT_SOURCELISTCLEARSOURCE)]
+            void SourceListClearSource(
+                [in] MsiInstallSourceType iSourceType,
+                [in] BSTR Source);
+        [id(DISPID_PRODUCT_SOURCELISTCLEARMEDIADISK)]
+            void SourceListClearMediaDisk([in] long iDiskId);
+        [id(DISPID_PRODUCT_SOURCELISTCLEARALL)]
+            void SourceListClearAll([in] MsiInstallSourceType iSourceType);
+        [id(DISPID_PRODUCT_SOURCELISTFORCERESOLUTION)]
+            void SourceListForceResolution();
+        [id(DISPID_PRODUCT_SOURCELISTINFO), propget]
+            BSTR SourceListInfo([in] BSTR Property);
+        [id(DISPID_PRODUCT_SOURCELISTINFO), propput]
+            void SourceListInfo(
+                [in] BSTR Property,
+                [in] BSTR retval);
+    };
 
-    [ uuid(000C10A1-0000-0000-C000-000000000046) ]
-    dispinterface Patch
-    {
+    [
+        uuid(000C10A1-0000-0000-C000-000000000046),
+        helpcontext(0x000023aa)
+    ]
+    dispinterface Patch {
         properties:
         methods:
-    }
-}
+        [id(DISPID_PATCH_PATCHCODE), propget]
+            BSTR PatchCode();
+        [id(DISPID_PATCH_PRODUCTCODE), propget]
+            BSTR ProductCode();
+        [id(DISPID_PATCH_USERSID), propget]
+            BSTR UserSid();
+        [id(DISPID_PATCH_CONTEXT), propget]
+            MsiInstallContext Context();
+        [id(DISPID_PATCH_STATE), propget]
+            MsiInstallState State();
+        [id(DISPID_PATCH_SOURCES), propget]
+            StringList* Sources([in] long SourceType);
+        [id(DISPID_PATCH_MEDIADISKS), propget]
+            RecordList* MediaDisks();
+        [id(DISPID_PATCH_SOURCELISTADDSOURCE)]
+            void SourceListAddSource(
+                [in] MsiInstallSourceType iSourceType,
+                [in] BSTR Source,
+                [in] long dwIndex);
+        [id(DISPID_PATCH_SOURCELISTADDMEDIADISK)]
+            void SourceListAddMediaDisk(
+                [in] long dwDiskId,
+                [in] BSTR VolumeLabel,
+                [in] BSTR DiskPrompt);
+        [id(DISPID_PATCH_SOURCELISTCLEARSOURCE)]
+            void SourceListClearSource(
+                [in] MsiInstallSourceType iSourceType,
+                [in] BSTR Source);
+        [id(DISPID_PATCH_SOURCELISTCLEARMEDIADISK)]
+            void SourceListClearMediaDisk([in] long iDiskId);
+        [id(DISPID_PATCH_SOURCELISTCLEARALL)]
+            void SourceListClearAll([in] MsiInstallSourceType iSourceType);
+        [id(DISPID_PATCH_SOURCELISTFORCERESOLUTION)]
+            void SourceListForceResolution();
+        [id(DISPID_PATCH_SOURCELISTINFO), propget]
+            BSTR SourceListInfo([in] BSTR Property);
+        [id(DISPID_PATCH_SOURCELISTINFO), propput]
+            void SourceListInfo(
+                [in] BSTR Property,
+                [in] BSTR retval);
+        [id(DISPID_PATCH_PATCHPROPERTY), propget]
+            BSTR PatchProperty([in] BSTR Property);
+    };
+
+    typedef enum {
+        msiDatabaseNullInteger = -2147483648
+    } Constants;
+
+    typedef enum {
+        msiOpenDatabaseModeReadOnly = 0,
+        msiOpenDatabaseModeTransact = 1,
+        msiOpenDatabaseModeDirect = 2,
+        msiOpenDatabaseModeCreate = 3,
+        msiOpenDatabaseModeCreateDirect = 4,
+        msiOpenDatabaseModePatchFile = 32
+    } MsiOpenDatabaseMode;
+
+    typedef enum {
+        msiSignatureOptionInvalidHashFatal = 1
+    } MsiSignatureOption;
+};
diff --git a/dlls/msi/msiserver_dispids.h b/dlls/msi/msiserver_dispids.h
new file mode 100644
index 0000000..093efb0
--- /dev/null
+++ b/dlls/msi/msiserver_dispids.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007 Misha Koshelev
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define DISPID_INSTALLER_UILEVEL 6
+#define DISPID_INSTALLER_CREATERECORD 1
+#define DISPID_INSTALLER_OPENPACKAGE 2
+#define DISPID_INSTALLER_OPENPRODUCT 3
+#define DISPID_INSTALLER_OPENDATABASE 4
+#define DISPID_INSTALLER_SUMMARYINFORMATION 5
+#define DISPID_INSTALLER_ENABLELOG 7
+#define DISPID_INSTALLER_INSTALLPRODUCT 8
+#define DISPID_INSTALLER_VERSION 9
+#define DISPID_INSTALLER_LASTERRORRECORD 10
+#define DISPID_INSTALLER_REGISTRYVALUE 11
+#define DISPID_INSTALLER_FILEATTRIBUTES 13
+#define DISPID_INSTALLER_FILESIZE 15
+#define DISPID_INSTALLER_FILEVERSION 16
+#define DISPID_INSTALLER_ENVIRONMENT 12
+#define DISPID_INSTALLER_PRODUCTSTATE 17
+#define DISPID_INSTALLER_PRODUCTINFO 18
+#define DISPID_INSTALLER_CONFIGUREPRODUCT 19
+#define DISPID_INSTALLER_REINSTALLPRODUCT 20
+#define DISPID_INSTALLER_COLLECTUSERINFO 21
+#define DISPID_INSTALLER_APPLYPATCH 22
+#define DISPID_INSTALLER_FEATUREPARENT 23
+#define DISPID_INSTALLER_FEATURESTATE 24
+#define DISPID_INSTALLER_USEFEATURE 25
+#define DISPID_INSTALLER_FEATUREUSAGECOUNT 26
+#define DISPID_INSTALLER_FEATUREUSAGEDATE 27
+#define DISPID_INSTALLER_CONFIGUREFEATURE 28
+#define DISPID_INSTALLER_REINSTALLFEATURE 29
+#define DISPID_INSTALLER_PROVIDECOMPONENT 30
+#define DISPID_INSTALLER_COMPONENTPATH 31
+#define DISPID_INSTALLER_PROVIDEQUALIFIEDCOMPONENT 32
+#define DISPID_INSTALLER_QUALIFIERDESCRIPTION 33
+#define DISPID_INSTALLER_COMPONENTQUALIFIERS 34
+#define DISPID_INSTALLER_PRODUCTS 35
+#define DISPID_INSTALLER_FEATURES 36
+#define DISPID_INSTALLER_COMPONENTS 37
+#define DISPID_INSTALLER_COMPONENTCLIENTS 38
+#define DISPID_INSTALLER_PATCHES 39
+#define DISPID_INSTALLER_RELATEDPRODUCTS 40
+#define DISPID_INSTALLER_PATCHINFO 41
+#define DISPID_INSTALLER_PATCHTRANSFORMS 42
+#define DISPID_INSTALLER_ADDSOURCE 43
+#define DISPID_INSTALLER_CLEARSOURCELIST 44
+#define DISPID_INSTALLER_FORCESOURCELISTRESOLUTION 45
+#define DISPID_INSTALLER_GETSHORTCUTTARGET 46
+#define DISPID_INSTALLER_FILEHASH 47
+#define DISPID_INSTALLER_FILESIGNATUREINFO 48
+#define DISPID_INSTALLER_REMOVEPATCHES 49
+#define DISPID_INSTALLER_APPLYMULTIPLEPATCHES 51
+#define DISPID_INSTALLER_PRODUCT 53
+#define DISPID_INSTALLER_PATCH 56
+#define DISPID_INSTALLER_PRODUCTSEX 52
+#define DISPID_INSTALLER_PATCHESEX 55
+#define DISPID_INSTALLER_EXTRACTPATCHXMLDATA 57
+
+#define DISPID_RECORD_STRINGDATA 1
+#define DISPID_RECORD_INTEGERDATA 2
+#define DISPID_RECORD_SETSTREAM 3
+#define DISPID_RECORD_READSTREAM 4
+#define DISPID_RECORD_FIELDCOUNT 0
+#define DISPID_RECORD_ISNULL 6
+#define DISPID_RECORD_DATASIZE 5
+#define DISPID_RECORD_CLEARDATA 7
+#define DISPID_RECORD_FORMATTEXT 8
+
+#define DISPID_SESSION_INSTALLER 1
+#define DISPID_SESSION_PROPERTY 2
+#define DISPID_SESSION_LANGUAGE 3
+#define DISPID_SESSION_MODE 4
+#define DISPID_SESSION_DATABASE 5
+#define DISPID_SESSION_SOURCEPATH 6
+#define DISPID_SESSION_TARGETPATH 7
+#define DISPID_SESSION_DOACTION 8
+#define DISPID_SESSION_SEQUENCE 9
+#define DISPID_SESSION_EVALUATECONDITION 10
+#define DISPID_SESSION_FORMATRECORD 11
+#define DISPID_SESSION_MESSAGE 12
+#define DISPID_SESSION_FEATURECURRENTSTATE 13
+#define DISPID_SESSION_FEATUREREQUESTSTATE 14
+#define DISPID_SESSION_FEATUREVALIDSTATES 15
+#define DISPID_SESSION_FEATURECOST 16
+#define DISPID_SESSION_COMPONENTCURRENTSTATE 17
+#define DISPID_SESSION_COMPONENTREQUESTSTATE 18
+#define DISPID_SESSION_SETINSTALLLEVEL 19
+#define DISPID_SESSION_VERIFYDISKSPACE 20
+#define DISPID_SESSION_PRODUCTPROPERTY 21
+#define DISPID_SESSION_FEATUREINFO 22
+#define DISPID_SESSION_COMPONENTCOSTS 23
+
+#define DISPID_DATABASE_DATABASESTATE 1
+#define DISPID_DATABASE_SUMMARYINFORMATION 2
+#define DISPID_DATABASE_OPENVIEW 3
+#define DISPID_DATABASE_COMMIT 4
+#define DISPID_DATABASE_PRIMARYKEYS 5
+#define DISPID_DATABASE_IMPORT 6
+#define DISPID_DATABASE_EXPORT 7
+#define DISPID_DATABASE_MERGE 8
+#define DISPID_DATABASE_GENERATETRANSFORM 9
+#define DISPID_DATABASE_APPLYTRANSFORM 10
+#define DISPID_DATABASE_ENABLEUIPREVIEW 11
+#define DISPID_DATABASE_TABLEPERSISTENT 12
+#define DISPID_DATABASE_CREATETRANSFORMSUMMARYINFO 13
+
+#define DISPID_SUMMARYINFO_PROPERTY 1
+#define DISPID_SUMMARYINFO_PROPERTYCOUNT 2
+#define DISPID_SUMMARYINFO_PERSIST 3
+
+#define DISPID_VIEW_EXECUTE 1
+#define DISPID_VIEW_FETCH 2
+#define DISPID_VIEW_MODIFY 3
+#define DISPID_VIEW_COLUMNINFO 5
+#define DISPID_VIEW_CLOSE 4
+#define DISPID_VIEW_GETERROR 6
+
+#define DISPID_UIPREVIEW_PROPERTY 1
+#define DISPID_UIPREVIEW_VIEWDIALOG 2
+#define DISPID_UIPREVIEW_VIEWBILLBOARD 3
+
+#define DISPID_FEATUREINFO_ATTRIBUTES 3
+#define DISPID_FEATUREINFO_TITLE 1
+#define DISPID_FEATUREINFO_DESCRIPTION 2
+
+#define DISPID_RECORDLIST__NEWENUM -4
+#define DISPID_RECORDLIST_ITEM 0
+#define DISPID_RECORDLIST_COUNT 1
+
+#define DISPID_STRINGLIST__NEWENUM -4
+#define DISPID_STRINGLIST_ITEM 0
+#define DISPID_STRINGLIST_COUNT 1
+
+#define DISPID_PRODUCT_PRODUCTCODE 1
+#define DISPID_PRODUCT_USERSID 2
+#define DISPID_PRODUCT_CONTEXT 3
+#define DISPID_PRODUCT_STATE 4
+#define DISPID_PRODUCT_INSTALLPROPERTY 5
+#define DISPID_PRODUCT_COMPONENTSTATE 6
+#define DISPID_PRODUCT_FEATURESTATE 7
+#define DISPID_PRODUCT_SOURCES 14
+#define DISPID_PRODUCT_MEDIADISKS 15
+#define DISPID_PRODUCT_SOURCELISTADDSOURCE 8
+#define DISPID_PRODUCT_SOURCELISTADDMEDIADISK 9
+#define DISPID_PRODUCT_SOURCELISTCLEARSOURCE 10
+#define DISPID_PRODUCT_SOURCELISTCLEARMEDIADISK 11
+#define DISPID_PRODUCT_SOURCELISTCLEARALL 12
+#define DISPID_PRODUCT_SOURCELISTFORCERESOLUTION 13
+#define DISPID_PRODUCT_SOURCELISTINFO 16
+
+#define DISPID_PATCH_PATCHCODE 1
+#define DISPID_PATCH_PRODUCTCODE 2
+#define DISPID_PATCH_USERSID 3
+#define DISPID_PATCH_CONTEXT 4
+#define DISPID_PATCH_STATE 5
+#define DISPID_PATCH_SOURCES 12
+#define DISPID_PATCH_MEDIADISKS 13
+#define DISPID_PATCH_SOURCELISTADDSOURCE 6
+#define DISPID_PATCH_SOURCELISTADDMEDIADISK 7
+#define DISPID_PATCH_SOURCELISTCLEARSOURCE 8
+#define DISPID_PATCH_SOURCELISTCLEARMEDIADISK 9
+#define DISPID_PATCH_SOURCELISTCLEARALL 10
+#define DISPID_PATCH_SOURCELISTFORCERESOLUTION 11
+#define DISPID_PATCH_SOURCELISTINFO 14
+#define DISPID_PATCH_PATCHPROPERTY 15
-- 
1.4.1

-------------- next part --------------
From 5a41c336b7c27d70ce50bdc7e930a6bf6692c7ce Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Wed, 28 Feb 2007 12:10:18 -0600
Subject: msi: Add partial, expandable OLE automation support.
---
 dlls/msi/Makefile.in  |    3 
 dlls/msi/automation.c |  826 +++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msi/msipriv.h    |    4 
 3 files changed, 833 insertions(+), 0 deletions(-)

diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in
index 5fb0941..3418fb5 100644
--- a/dlls/msi/Makefile.in
+++ b/dlls/msi/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
 	action.c \
 	alter.c \
 	appsearch.c \
+	automation.c \
 	classes.c \
 	create.c \
 	custom.c \
@@ -47,6 +48,8 @@ C_SRCS = \
 	upgrade.c \
 	where.c
 
+IDL_H_SRCS = msiserver.idl
+IDL_I_SRCS = msiserver.idl
 IDL_TLB_SRCS = msiserver.idl
 
 BISON_SRCS = \
diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c
new file mode 100644
index 0000000..cfb2cf1
--- /dev/null
+++ b/dlls/msi/automation.c
@@ -0,0 +1,826 @@
+/*
+ * Implementation of OLE Automation for Microsoft Installer (msi.dll)
+ *
+ * Copyright 2007 Misha Koshelev
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winuser.h"
+#include "msidefs.h"
+#include "msipriv.h"
+#include "activscp.h"
+#include "oleauto.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msiserver.h"
+#include "msiserver_dispids.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/* FIXME: I don't know how big this should be */
+#define MAX_MSI_STRING 1000
+
+/*
+ * AutomationObject - "base" class for all automation objects. For each interface, we implement Invoke function
+ *                    called from AutomationObject::Invoke, and pass this function to create_automation_object.
+ */
+
+typedef interface AutomationObject AutomationObject;
+
+interface AutomationObject {
+    /*
+     * VTables - We provide IDispatch, IProvideClassInfo, IProvideClassInfo2, IProvideMultipleClassInfo
+     */
+    const IDispatchVtbl *lpVtbl;
+    const IProvideClassInfoVtbl *lpvtblIProvideClassInfo;
+    const IProvideClassInfo2Vtbl *lpvtblIProvideClassInfo2;
+    const IProvideMultipleClassInfoVtbl *lpvtblIProvideMultipleClassInfo;
+    
+    /* Object reference count */
+    LONG ref;
+
+    /* Clsid for this class and it's appropriate ITypeInfo object */
+    LPCLSID clsid;
+    ITypeInfo *iTypeInfo;
+
+    /* The MSI handle of the current object */
+    MSIHANDLE msiHandle;
+
+    /* A function that is called from AutomationObject::Invoke, specific to this type of object. */
+    HRESULT (STDMETHODCALLTYPE *funcInvoke)(
+        AutomationObject* This,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr);
+};
+
+/* VTables */
+static const struct IDispatchVtbl AutomationObject_Vtbl; 
+static const struct IProvideClassInfoVtbl AutomationObject_IProvideClassInfo_Vtbl; 
+static const struct IProvideClassInfo2Vtbl AutomationObject_IProvideClassInfo2_Vtbl; 
+static const struct IProvideMultipleClassInfoVtbl AutomationObject_IProvideMultipleClassInfo_Vtbl; 
+
+/* Load type info so we don't have to process GetIDsOfNames */
+HRESULT WINAPI LoadTypeInfo(IDispatch *iface, ITypeInfo **pptinfo, REFIID clsid, LCID lcid)
+{
+    HRESULT hr;
+    LPTYPELIB pLib = NULL;
+    LPTYPEINFO pInfo = NULL;
+    WCHAR szMsiServer[] = {'m','s','i','s','e','r','v','e','r','.','t','l','b'};
+
+    TRACE("(%p)->(%s,%d)\n", iface, debugstr_guid(clsid), lcid);    
+    
+    /* Load registered type library */
+    hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, lcid, &pLib);
+    if (FAILED(hr)) {
+	hr = LoadTypeLib(szMsiServer, &pLib);
+	if (FAILED(hr)) {
+	    ERR("Could not load msiserver.tlb\n");
+	    return hr;
+	}
+    }
+
+    /* Get type information for object */
+    hr = ITypeLib_GetTypeInfoOfGuid(pLib, clsid, &pInfo);
+    ITypeLib_Release(pLib);
+    if (FAILED(hr)) {
+	ERR("Could not load ITypeInfo for %s\n", debugstr_guid(clsid));
+	return hr;
+    }
+    *pptinfo = pInfo;
+    return S_OK;
+}
+
+/* Create the automation object, placing the result in the pointer ppObj. The automation object is created
+ * with the appropriate clsid and invocation function. */
+HRESULT create_automation_object(MSIHANDLE msiHandle, IUnknown *pUnkOuter, LPVOID *ppObj, REFIID clsid, 
+	    HRESULT (STDMETHODCALLTYPE *funcInvoke)(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,
+						    VARIANT*,EXCEPINFO*,UINT*))
+{
+    AutomationObject *object;
+    HRESULT hr;
+
+    TRACE("(%ld,%p,%p,%s,%p)\n", (unsigned long)msiHandle, pUnkOuter, ppObj, debugstr_guid(clsid), funcInvoke);
+
+    if( pUnkOuter )
+	return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AutomationObject));
+
+    /* Set all the VTable references */
+    object->lpVtbl = &AutomationObject_Vtbl;
+    object->lpvtblIProvideClassInfo = &AutomationObject_IProvideClassInfo_Vtbl;
+    object->lpvtblIProvideClassInfo2 = &AutomationObject_IProvideClassInfo2_Vtbl;
+    object->lpvtblIProvideMultipleClassInfo = &AutomationObject_IProvideMultipleClassInfo_Vtbl;
+    object->ref = 1;
+
+    /* Store data that was passed */
+    object->msiHandle = msiHandle;
+    object->clsid = (LPCLSID)clsid;
+    object->funcInvoke = funcInvoke;
+
+    /* Load our TypeInfo so we don't have to process GetIDsOfNames */
+    object->iTypeInfo = NULL;
+    hr = LoadTypeInfo((IDispatch *)object, &object->iTypeInfo, clsid, 0x0);
+    if (FAILED(hr)) { 
+	HeapFree(GetProcessHeap(), 0, object);
+	return hr;
+    }
+
+    *ppObj = object;
+
+    return S_OK;
+}
+
+/* Macros to get pointer to AutomationObject from the other VTables. */
+static inline AutomationObject *obj_from_IProvideClassInfo( IProvideClassInfo *iface )
+{
+    return (AutomationObject *)((char*)iface - FIELD_OFFSET(AutomationObject, lpvtblIProvideClassInfo));
+}
+
+static inline AutomationObject *obj_from_IProvideClassInfo2( IProvideClassInfo2 *iface )
+{
+    return (AutomationObject *)((char*)iface - FIELD_OFFSET(AutomationObject, lpvtblIProvideClassInfo2));
+}
+
+static inline AutomationObject *obj_from_IProvideMultipleClassInfo( IProvideMultipleClassInfo *iface )
+{
+    return (AutomationObject *)((char*)iface - FIELD_OFFSET(AutomationObject, lpvtblIProvideMultipleClassInfo));
+}
+
+/*
+ * AutomationObject methods
+ */
+
+/*** IUnknown methods ***/
+static HRESULT WINAPI AutomationObject_QueryInterface(IDispatch* iface, REFIID riid, void** ppvObject)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+
+    TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); 
+
+    if ( (This==0) || (ppvObject==0) )
+      return E_INVALIDARG;
+
+    *ppvObject = 0;
+
+    if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, This->clsid))
+        *ppvObject = This;
+    else if (IsEqualGUID(riid, &IID_IProvideClassInfo))
+	*ppvObject = (IProvideClassInfo*)&(This->lpvtblIProvideClassInfo);
+    else if (IsEqualGUID(riid, &IID_IProvideClassInfo2))
+	*ppvObject = (IProvideClassInfo2*)&(This->lpvtblIProvideClassInfo2);
+    else if (IsEqualGUID(riid, &IID_IProvideMultipleClassInfo))
+	*ppvObject = (IProvideMultipleClassInfo*)&(This->lpvtblIProvideMultipleClassInfo);
+
+    if ((*ppvObject)==0)
+    {
+	TRACE("() : asking for unsupported interface %s\n",debugstr_guid(riid));
+	return E_NOINTERFACE;
+    }
+
+    /*
+     * Query Interface always increases the reference count by one when it is
+     * successful
+     */
+    IClassFactory_AddRef(iface);
+
+    return S_OK;
+}
+
+static ULONG WINAPI AutomationObject_AddRef(IDispatch* iface)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+
+    TRACE("(%p/%p)\n", iface, This);
+
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI AutomationObject_Release(IDispatch* iface)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p/%p)\n", iface, This);
+
+    if (!ref) 
+    {
+	MsiCloseHandle(This->msiHandle);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+/*** IDispatch methods ***/
+static HRESULT WINAPI AutomationObject_GetTypeInfoCount(
+        IDispatch* iface,
+        UINT* pctinfo)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", iface, This, pctinfo);
+    *pctinfo = 1;
+    return S_OK;
+}
+
+static HRESULT WINAPI AutomationObject_GetTypeInfo(
+        IDispatch* iface,
+        UINT iTInfo,
+        LCID lcid,
+        ITypeInfo** ppTInfo)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+    TRACE("(%p/%p)->(%d,%d,%p)\n", iface, This, iTInfo, lcid, ppTInfo);
+
+    ITypeInfo_AddRef(This->iTypeInfo);
+    *ppTInfo = This->iTypeInfo;
+    return S_OK;
+}
+
+static HRESULT WINAPI AutomationObject_GetIDsOfNames(
+        IDispatch* iface,
+        REFIID riid,
+        LPOLESTR* rgszNames,
+        UINT cNames,
+        LCID lcid,
+        DISPID* rgDispId)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+    TRACE("(%p/%p)->(%p,%p,%d,%d,%p)\n", iface, This, riid, rgszNames, cNames, lcid, rgDispId);
+
+    if (!IsEqualGUID(riid, &IID_NULL)) return E_INVALIDARG;
+    return ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames, rgDispId);
+}
+
+/* Some error checking is done here to simplify individual object function invocation */
+static HRESULT WINAPI AutomationObject_Invoke(
+        IDispatch* iface,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr)
+{
+    AutomationObject *This = (AutomationObject *)iface;
+    HRESULT hr;
+    unsigned int uArgErr;
+    VARIANT varResultDummy;
+    BSTR bstrName = NULL;
+
+    TRACE("(%p/%p)->(%d,%p,%d,%d,%p,%p,%p,%p)\n", iface, This, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+
+    if (!IsEqualIID(riid, &IID_NULL))
+    {
+	ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
+	return DISP_E_UNKNOWNNAME;
+    }
+
+    if (!pDispParams)
+    {
+	ERR("NULL pDispParams not allowed\n");
+	return DISP_E_PARAMNOTOPTIONAL;
+    }
+
+    if (wFlags & DISPATCH_PROPERTYGET && !pVarResult)
+    {
+	ERR("NULL pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
+	return DISP_E_PARAMNOTOPTIONAL;
+    }
+
+    /* This simplifies our individual object invocation functions */
+    if (puArgErr == NULL) puArgErr = &uArgErr;
+    if (pVarResult == NULL) pVarResult = &varResultDummy;
+
+    /* Assume return type is void unless determined otherwise */
+    VariantInit(pVarResult);
+
+    /* If we are tracing, we want to see the name of the member we are invoking */
+    if (TRACE_ON(msi))
+    {
+	ITypeInfo_GetDocumentation(This->iTypeInfo, dispIdMember, &bstrName, NULL, NULL, NULL);
+	TRACE("Method %d, %s\n", dispIdMember, debugstr_w(bstrName));
+    }
+
+    hr = This->funcInvoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
+
+    if (hr == DISP_E_MEMBERNOTFOUND) {
+	if (bstrName == NULL) ITypeInfo_GetDocumentation(This->iTypeInfo, dispIdMember, &bstrName, NULL, NULL, NULL);
+	FIXME("Method %d, %s wflags %d not implemented, clsid %s\n", dispIdMember, debugstr_w(bstrName), wFlags, debugstr_guid(This->clsid));
+    }
+
+    TRACE("Returning %d, %s\n", hr, hr == S_OK ? "ok" : "not ok");
+
+    return hr;
+}
+
+static const struct IDispatchVtbl AutomationObject_Vtbl = 
+{
+    AutomationObject_QueryInterface,
+    AutomationObject_AddRef,
+    AutomationObject_Release,
+    AutomationObject_GetTypeInfoCount,
+    AutomationObject_GetTypeInfo,
+    AutomationObject_GetIDsOfNames,
+    AutomationObject_Invoke
+};
+
+/*
+ * IProvideClassInfo methods 
+ */
+
+static HRESULT WINAPI AutomationObject_IProvideClassInfo_QueryInterface(
+  IProvideClassInfo* iface,
+  REFIID     riid,
+  VOID**     ppvoid)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo(iface);
+    return AutomationObject_QueryInterface((IDispatch *)This, riid, ppvoid);
+}
+
+static ULONG WINAPI AutomationObject_IProvideClassInfo_AddRef(IProvideClassInfo* iface)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo(iface);
+    return AutomationObject_AddRef((IDispatch *)This);
+}
+
+static ULONG WINAPI AutomationObject_IProvideClassInfo_Release(IProvideClassInfo* iface)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo(iface);
+    return AutomationObject_Release((IDispatch *)This);
+}
+
+static HRESULT WINAPI AutomationObject_GetClassInfo(IProvideClassInfo* iface, ITypeInfo** ppTI)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo(iface);
+
+    TRACE("(%p/%p)->(%p)\n", iface, This, ppTI);
+    return LoadTypeInfo((IDispatch *)This, ppTI, This->clsid, 0);
+}
+
+static const IProvideClassInfoVtbl AutomationObject_IProvideClassInfo_Vtbl =
+{
+    AutomationObject_IProvideClassInfo_QueryInterface,
+    AutomationObject_IProvideClassInfo_AddRef,
+    AutomationObject_IProvideClassInfo_Release,    
+    AutomationObject_GetClassInfo
+};
+
+/*
+ * IProvideClassInfo2 methods
+ */
+
+static HRESULT WINAPI AutomationObject_IProvideClassInfo2_QueryInterface(
+  IProvideClassInfo2* iface,
+  REFIID     riid,
+  VOID**     ppvoid)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo2(iface);
+    return AutomationObject_QueryInterface((IDispatch *)This, riid, ppvoid);
+}
+
+static ULONG WINAPI AutomationObject_IProvideClassInfo2_AddRef(IProvideClassInfo2* iface)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo2(iface);
+    return AutomationObject_AddRef((IDispatch *)This);
+}
+
+static ULONG WINAPI AutomationObject_IProvideClassInfo2_Release(IProvideClassInfo2* iface)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo2(iface);
+    return AutomationObject_Release((IDispatch *)This);
+}
+
+static HRESULT WINAPI AutomationObject_IProvideClassInfo2_GetClassInfo(IProvideClassInfo2* iface, ITypeInfo** ppTI)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo2(iface);
+    return AutomationObject_GetClassInfo((IProvideClassInfo*)&(This->lpvtblIProvideClassInfo), ppTI);    
+}
+
+static HRESULT WINAPI AutomationObject_GetGUID(IProvideClassInfo2* iface, DWORD dwGuidKind, GUID* pGUID)
+{
+    AutomationObject *This = obj_from_IProvideClassInfo2(iface);
+    TRACE("(%p/%p)->(%d,%s)\n", iface, This, dwGuidKind, debugstr_guid(pGUID));
+    
+    if (dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID)
+	return E_INVALIDARG;
+    else {
+	*pGUID = *This->clsid;
+	return S_OK;
+    }
+}
+
+static const IProvideClassInfo2Vtbl AutomationObject_IProvideClassInfo2_Vtbl =
+{
+    AutomationObject_IProvideClassInfo2_QueryInterface,
+    AutomationObject_IProvideClassInfo2_AddRef,
+    AutomationObject_IProvideClassInfo2_Release,    
+    AutomationObject_IProvideClassInfo2_GetClassInfo,    
+    AutomationObject_GetGUID
+};
+
+/* 
+ * IProvideMultipleClassInfo methods
+ */
+
+static HRESULT WINAPI AutomationObject_IProvideMultipleClassInfo_QueryInterface(
+  IProvideMultipleClassInfo* iface,
+  REFIID     riid,
+  VOID**     ppvoid)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+    return AutomationObject_QueryInterface((IDispatch *)This, riid, ppvoid);
+}
+
+static ULONG WINAPI AutomationObject_IProvideMultipleClassInfo_AddRef(IProvideMultipleClassInfo* iface)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+    return AutomationObject_AddRef((IDispatch *)This);
+}
+
+static ULONG WINAPI AutomationObject_IProvideMultipleClassInfo_Release(IProvideMultipleClassInfo* iface)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+    return AutomationObject_Release((IDispatch *)This);
+}
+
+static HRESULT WINAPI AutomationObject_IProvideMultipleClassInfo_GetClassInfo(IProvideMultipleClassInfo* iface, ITypeInfo** ppTI)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+    return AutomationObject_GetClassInfo((IProvideClassInfo*)&(This->lpvtblIProvideClassInfo), ppTI);    
+}
+
+static HRESULT WINAPI AutomationObject_IProvideMultipleClassInfo_GetGUID(IProvideMultipleClassInfo* iface, DWORD dwGuidKind, GUID* pGUID)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+    return AutomationObject_GetGUID((IProvideClassInfo2*)&(This->lpvtblIProvideClassInfo2), dwGuidKind, pGUID);
+}
+
+static HRESULT WINAPI AutomationObject_GetMultiTypeInfoCount(IProvideMultipleClassInfo* iface, ULONG* pcti)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+
+    TRACE("(%p/%p)->(%p)\n", iface, This, pcti);
+    *pcti = 1;
+    return S_OK;
+}
+
+static HRESULT WINAPI AutomationObject_GetInfoOfIndex(IProvideMultipleClassInfo* iface,
+        ULONG iti,
+        DWORD dwFlags,
+        ITypeInfo** pptiCoClass,
+        DWORD* pdwTIFlags,
+        ULONG* pcdispidReserved,
+        IID* piidPrimary,
+        IID* piidSource)
+{
+    AutomationObject *This = obj_from_IProvideMultipleClassInfo(iface);
+
+    TRACE("(%p/%p)->(%d,%d,%p,%p,%p,%p,%p)\n", iface, This, iti, dwFlags, pptiCoClass, pdwTIFlags, pcdispidReserved, piidPrimary, piidSource);
+    
+    if (iti != 0)
+	return E_INVALIDARG;
+
+    if (dwFlags & MULTICLASSINFO_GETTYPEINFO)
+	LoadTypeInfo((IDispatch *)This, pptiCoClass, This->clsid, 0);
+
+    if (dwFlags & MULTICLASSINFO_GETNUMRESERVEDDISPIDS)
+    {
+	*pdwTIFlags = 0;
+	*pcdispidReserved = 0;
+    }
+
+    if (dwFlags & MULTICLASSINFO_GETIIDPRIMARY){
+	*piidPrimary = *This->clsid;
+    }
+
+    if (dwFlags & MULTICLASSINFO_GETIIDSOURCE){
+        *piidSource = *This->clsid;
+    }
+
+    return S_OK;
+}
+
+static const IProvideMultipleClassInfoVtbl AutomationObject_IProvideMultipleClassInfo_Vtbl =
+{
+    AutomationObject_IProvideMultipleClassInfo_QueryInterface,
+    AutomationObject_IProvideMultipleClassInfo_AddRef,
+    AutomationObject_IProvideMultipleClassInfo_Release,    
+    AutomationObject_IProvideMultipleClassInfo_GetClassInfo,
+    AutomationObject_IProvideMultipleClassInfo_GetGUID,
+    AutomationObject_GetMultiTypeInfoCount,
+    AutomationObject_GetInfoOfIndex
+};
+
+/*
+ * Individual Object Invocation Functions
+ */
+
+HRESULT WINAPI RecordImpl_Invoke(
+        AutomationObject* This,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr)
+{
+    WCHAR szString[MAX_MSI_STRING];
+    DWORD dwLen = MAX_MSI_STRING;
+    UINT ret;
+    VARIANTARG varg0, varg1;
+    HRESULT hr;
+
+    VariantInit(&varg0);
+    VariantInit(&varg1);
+
+    switch (dispIdMember) 
+    {
+	case DISPID_RECORD_STRINGDATA:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_BSTR;
+		if ((ret = MsiRecordGetStringW(This->msiHandle, V_I4(&varg0), szString, &dwLen)) == ERROR_SUCCESS)
+                    V_BSTR(pVarResult) = SysAllocString(szString);
+		else
+		{
+		    TRACE("MsiRecordGetString returned %d\n", ret);
+                    V_BSTR(pVarResult) = NULL;
+		}
+	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_BSTR, &varg1, puArgErr);
+                if (hr != S_OK) return hr;
+		if ((ret = MsiRecordSetStringW(This->msiHandle, V_I4(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS)
+                    TRACE("MsiRecordSetString returned %d\n", ret);
+	    }
+	    break;
+            
+         default:
+            return DISP_E_MEMBERNOTFOUND; 
+    }
+
+    return S_OK;
+}
+
+HRESULT WINAPI ViewImpl_Invoke(
+        AutomationObject* This,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr)
+{
+    MSIHANDLE msiHandle;
+    IDispatch *iDispatch = NULL;
+    UINT ret;
+    VARIANTARG varg0, varg1;
+    HRESULT hr;
+
+    VariantInit(&varg0);
+    VariantInit(&varg1);
+
+    switch (dispIdMember) 
+    {
+	case DISPID_VIEW_EXECUTE:
+	    if (wFlags & DISPATCH_METHOD)
+	    {
+                hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &varg0, puArgErr); 
+                if (hr == S_OK)
+                    MsiViewExecute(This->msiHandle, ((AutomationObject *)V_DISPATCH(&varg0))->msiHandle);
+                else
+                    MsiViewExecute(This->msiHandle, 0);
+	    }
+	    break;
+
+	case DISPID_VIEW_FETCH:
+	    if (wFlags & DISPATCH_METHOD)
+	    { 
+                V_VT(pVarResult) = VT_DISPATCH;
+		if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS) 
+		    create_automation_object(msiHandle, NULL, (LPVOID)&iDispatch, &DIID_Record, RecordImpl_Invoke);
+		else TRACE("MsiViewFetch returned %d\n", ret);
+                V_DISPATCH(pVarResult) = iDispatch;
+	    }
+	    break;
+
+	case DISPID_VIEW_CLOSE:
+	    if (wFlags & DISPATCH_METHOD)
+	    { 
+		MsiViewClose(This->msiHandle);
+	    }
+	    break;
+
+         default:
+            return DISP_E_MEMBERNOTFOUND; 
+    }
+
+    return S_OK;
+}
+
+HRESULT WINAPI DatabaseImpl_Invoke(
+        AutomationObject* This,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr)
+{
+    MSIHANDLE msiHandle;
+    IDispatch *iDispatch = NULL;
+    UINT ret;
+    VARIANTARG varg0, varg1;
+    HRESULT hr;
+
+    VariantInit(&varg0);
+    VariantInit(&varg1);
+
+    switch (dispIdMember) 
+    {
+	case DISPID_DATABASE_OPENVIEW:
+	    if (wFlags & DISPATCH_METHOD)
+	    { 
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_DISPATCH;
+		if ((ret = MsiDatabaseOpenViewW(This->msiHandle, V_BSTR(&varg0), &msiHandle)) == ERROR_SUCCESS) 
+		    create_automation_object(msiHandle, NULL, (LPVOID)&iDispatch, &DIID_View, ViewImpl_Invoke);
+		else TRACE("MsiDatabaseOpenView returned %d\n", ret);
+	        V_DISPATCH(pVarResult) = iDispatch;
+	    }
+	    break;
+            
+         default:
+            return DISP_E_MEMBERNOTFOUND; 
+    }
+
+    return S_OK;
+}
+
+HRESULT WINAPI SessionImpl_Invoke(
+        AutomationObject* This,
+        DISPID dispIdMember,
+        REFIID riid,
+        LCID lcid,
+        WORD wFlags,
+        DISPPARAMS* pDispParams,
+        VARIANT* pVarResult,
+        EXCEPINFO* pExcepInfo,
+        UINT* puArgErr)
+{
+    WCHAR szString[MAX_MSI_STRING];
+    DWORD dwLen = MAX_MSI_STRING;
+    IDispatch *iDispatch = NULL;
+    MSIHANDLE msiHandle;
+    LANGID langId;
+    UINT ret;
+    INSTALLSTATE iInstalled, iAction;
+    VARIANTARG varg0, varg1;
+    HRESULT hr;
+
+    VariantInit(&varg0);
+    VariantInit(&varg1);
+
+    switch (dispIdMember)
+    {
+	case DISPID_SESSION_PROPERTY:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_BSTR;
+		if (MsiGetPropertyW(This->msiHandle, V_BSTR(&varg0), szString, &dwLen) == ERROR_SUCCESS)
+                    V_BSTR(pVarResult) = SysAllocString(szString);
+                else
+                    V_BSTR(pVarResult) = NULL;
+	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_BSTR, &varg1, puArgErr);
+                if (hr != S_OK) return hr;
+		if ((ret = MsiSetPropertyW(This->msiHandle, V_BSTR(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS) 
+                    TRACE("MsiSetProperty returned %d\n", ret);
+	    }
+	    break;
+
+	case DISPID_SESSION_LANGUAGE:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+		langId = MsiGetLanguage(This->msiHandle);
+                V_VT(pVarResult) = VT_I4;
+                V_I4(pVarResult) = langId;
+	    } 
+	    break;
+
+	case DISPID_SESSION_MODE:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_BOOL;
+		V_BOOL(pVarResult) = MsiGetMode(This->msiHandle, V_I4(&varg0));
+	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_BOOL, &varg1, puArgErr);
+                if (hr != S_OK) return hr;
+		if ((ret = MsiSetMode(This->msiHandle, V_I4(&varg0), V_BOOL(&varg1))) != ERROR_SUCCESS)
+                    TRACE("MsiSetMode returned %d\n", ret);
+	    }
+	    break;
+
+	case DISPID_SESSION_DATABASE:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                V_VT(pVarResult) = VT_DISPATCH;
+		if ((msiHandle = MsiGetActiveDatabase(This->msiHandle))) 
+		    create_automation_object(msiHandle, NULL, (LPVOID)&iDispatch, &DIID_Database, DatabaseImpl_Invoke);
+		else TRACE("MsiGetActiveDatabase failed\n");
+                V_DISPATCH(pVarResult) = iDispatch;
+	    }
+	    break;
+
+	case DISPID_SESSION_FEATURECURRENTSTATE:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_I4;
+		if ((ret = MsiGetFeatureStateW(This->msiHandle, V_BSTR(&varg0), &iInstalled, &iAction)) == ERROR_SUCCESS) 
+		    V_I4(pVarResult) = iInstalled;
+		else 
+		{
+		    TRACE("MsiGetFeatureState returned %d\n", ret);
+                    V_I4(pVarResult) = msiInstallStateUnknown;
+		}
+	    } 
+	    break;
+
+	case DISPID_SESSION_FEATUREREQUESTSTATE:
+	    if (wFlags & DISPATCH_PROPERTYGET) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                V_VT(pVarResult) = VT_I4;
+		if ((ret = MsiGetFeatureStateW(This->msiHandle, V_BSTR(&varg0), &iInstalled, &iAction)) == ERROR_SUCCESS) 
+		    V_I4(pVarResult) = iAction;
+		else 
+		{
+		    TRACE("MsiGetFeatureState returned %d\n", ret);
+                    V_I4(pVarResult) = msiInstallStateUnknown;
+		}
+	    } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+                if (hr != S_OK) return hr;
+                hr = DispGetParam(pDispParams, DISPID_PROPERTYPUT, VT_I4, &varg1, puArgErr);
+                if (hr != S_OK) return hr;
+		if ((ret = MsiSetFeatureStateW(This->msiHandle, V_BSTR(&varg0), V_I4(&varg1))) != ERROR_SUCCESS)
+                    TRACE("MsiSetFeatureState returned %d\n", ret);
+	    }
+	    break;
+
+         default:
+            return DISP_E_MEMBERNOTFOUND; 
+    }
+
+    return S_OK;
+}
+
+/* Wrapper around create_automation_object to create a session object. */
+HRESULT create_session(MSIHANDLE msiHandle, IDispatch **pDispatch)
+{
+    return create_automation_object(msiHandle, NULL, (LPVOID)pDispatch, &DIID_Session, SessionImpl_Invoke);
+}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 971f71e..23768c0 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -788,6 +788,10 @@ extern VOID ControlEvent_SubscribeToEven
 extern VOID ControlEvent_UnSubscribeToEvent( MSIPACKAGE *package, LPCWSTR event,
                                       LPCWSTR control, LPCWSTR attribute );
 
+/* OLE automation */
+extern HRESULT create_session(MSIHANDLE msiHandle, IDispatch **pDispatch);
+extern HRESULT WINAPI LoadTypeInfo(IDispatch *iface, ITypeInfo **pptinfo, REFIID clsid, LCID lcid);
+
 /* User Interface messages from the actions */
 extern void ui_progress(MSIPACKAGE *, int, int, int, int);
 extern void ui_actiondata(MSIPACKAGE *, LPCWSTR, MSIRECORD *);
-- 
1.4.1



More information about the wine-devel mailing list