Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michael Bond
wine
Commits
26c16313
Commit
26c16313
authored
17 years ago
by
Misha Koshelev
Committed by
Alexandre Julliard
17 years ago
Browse files
Options
Downloads
Patches
Plain Diff
msi: Add base class for OLE automation objects.
parent
d1c45886
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
.gitignore
+2
-0
2 additions, 0 deletions
.gitignore
dlls/msi/Makefile.in
+3
-0
3 additions, 0 deletions
dlls/msi/Makefile.in
dlls/msi/automation.c
+471
-0
471 additions, 0 deletions
dlls/msi/automation.c
with
476 additions
and
0 deletions
.gitignore
+
2
−
0
View file @
26c16313
...
...
@@ -335,7 +335,9 @@ dlls/msi/instadvert.bmp
dlls/msi/instlocal.bmp
dlls/msi/libmsi.def
dlls/msi/msi.res
dlls/msi/msiserver.h
dlls/msi/msiserver.tlb
dlls/msi/msiserver_i.c
dlls/msi/sql.tab.c
dlls/msi/sql.tab.h
dlls/msi/tests/*.ok
...
...
This diff is collapsed.
Click to expand it.
dlls/msi/Makefile.in
+
3
−
0
View file @
26c16313
...
...
@@ -12,6 +12,7 @@ C_SRCS = \
action.c
\
alter.c
\
appsearch.c
\
automation.c
\
classes.c
\
create.c
\
custom.c
\
...
...
@@ -48,6 +49,8 @@ C_SRCS = \
upgrade.c
\
where.c
IDL_H_SRCS
=
msiserver.idl
IDL_I_SRCS
=
msiserver.idl
IDL_TLB_SRCS
=
msiserver.idl
BISON_SRCS
=
\
...
...
This diff is collapsed.
Click to expand it.
dlls/msi/automation.c
0 → 100644
+
471
−
0
View file @
26c16313
/*
* 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"
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
/*
* 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
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
IProvideMultipleClassInfoVtbl
AutomationObject_IProvideMultipleClassInfo_Vtbl
;
/* Load type info so we don't have to process GetIDsOfNames */
HRESULT
load_type_info
(
IDispatch
*
iface
,
ITypeInfo
**
pptinfo
,
REFIID
clsid
,
LCID
lcid
)
{
HRESULT
hr
;
LPTYPELIB
pLib
=
NULL
;
LPTYPEINFO
pInfo
=
NULL
;
static
const
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
->
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
=
load_type_info
((
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_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
(
ppvObject
==
NULL
)
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
)
||
IsEqualGUID
(
riid
,
&
IID_IProvideClassInfo2
)
||
IsEqualGUID
(
riid
,
&
IID_IProvideMultipleClassInfo
))
*
ppvObject
=
&
This
->
lpvtblIProvideMultipleClassInfo
;
else
{
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
);
}
/* Maximum number of allowed function parameters+1 */
#define MAX_FUNC_PARAMS 20
/* 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
(
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
));
}
else
if
(
pExcepInfo
&&
(
hr
==
DISP_E_PARAMNOTFOUND
||
hr
==
DISP_E_EXCEPTION
))
{
static
const
WCHAR
szComma
[]
=
{
','
,
0
};
static
WCHAR
szExceptionSource
[]
=
{
'M'
,
's'
,
'i'
,
' '
,
'A'
,
'P'
,
'I'
,
' '
,
'E'
,
'r'
,
'r'
,
'o'
,
'r'
,
0
};
WCHAR
szExceptionDescription
[
MAX_PATH
];
BSTR
bstrParamNames
[
MAX_FUNC_PARAMS
];
unsigned
namesNo
,
i
;
BOOL
bFirst
=
TRUE
;
if
(
FAILED
(
ITypeInfo_GetNames
(
This
->
iTypeInfo
,
dispIdMember
,
bstrParamNames
,
MAX_FUNC_PARAMS
,
&
namesNo
)))
{
TRACE
(
"Failed to retrieve names for dispIdMember %d
\n
"
,
dispIdMember
);
}
else
{
memset
(
szExceptionDescription
,
0
,
sizeof
(
szExceptionDescription
));
for
(
i
=
0
;
i
<
namesNo
;
i
++
)
{
if
(
bFirst
)
bFirst
=
FALSE
;
else
{
lstrcpyW
(
&
szExceptionDescription
[
lstrlenW
(
szExceptionDescription
)],
szComma
);
}
lstrcpyW
(
&
szExceptionDescription
[
lstrlenW
(
szExceptionDescription
)],
bstrParamNames
[
i
]);
SysFreeString
(
bstrParamNames
[
i
]);
}
memset
(
pExcepInfo
,
0
,
sizeof
(
EXCEPINFO
));
pExcepInfo
->
wCode
=
1000
;
pExcepInfo
->
bstrSource
=
szExceptionSource
;
pExcepInfo
->
bstrDescription
=
szExceptionDescription
;
hr
=
DISP_E_EXCEPTION
;
}
}
/* Make sure we free the return variant if it is our dummy variant */
if
(
pVarResult
==
&
varResultDummy
)
VariantClear
(
pVarResult
);
/* Free function name if we retrieved it */
if
(
bstrName
)
SysFreeString
(
bstrName
);
TRACE
(
"Returning 0x%08x, %s
\n
"
,
hr
,
SUCCEEDED
(
hr
)
?
"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
};
/*
* 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
);
TRACE
(
"(%p/%p)->(%p)
\n
"
,
iface
,
This
,
ppTI
);
return
load_type_info
((
IDispatch
*
)
This
,
ppTI
,
This
->
clsid
,
0
);
}
static
HRESULT
WINAPI
AutomationObject_IProvideMultipleClassInfo_GetGUID
(
IProvideMultipleClassInfo
*
iface
,
DWORD
dwGuidKind
,
GUID
*
pGUID
)
{
AutomationObject
*
This
=
obj_from_IProvideMultipleClassInfo
(
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
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
)
load_type_info
((
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
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment