2 * Dispatch API functions
4 * Copyright 2000 Francois Jacques, Macadamian Technologies Inc.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * TODO: Type coercion is implemented in variant.c but not called yet.
34 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
35 #include "winnls.h" /* for PRIMARYLANGID */
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ole);
40 WINE_DECLARE_DEBUG_CHANNEL(typelib);
42 static IDispatch * WINAPI StdDispatch_Construct(IUnknown * punkOuter, void * pvThis, ITypeInfo * pTypeInfo);
44 /******************************************************************************
45 * DispInvoke (OLEAUT32.30)
48 * Calls method of an object through its IDispatch interface.
51 * - Defer method invocation to ITypeInfo::Invoke()
57 HRESULT WINAPI DispInvoke(
58 VOID *_this, /* [in] object instance */
59 ITypeInfo *ptinfo, /* [in] object's type info */
60 DISPID dispidMember, /* [in] member id */
61 USHORT wFlags, /* [in] kind of method call */
62 DISPPARAMS *pparams, /* [in] array of arguments */
63 VARIANT *pvarResult, /* [out] result of method call */
64 EXCEPINFO *pexcepinfo, /* [out] information about exception */
65 UINT *puArgErr) /* [out] index of bad argument(if any) */
71 * For each param, call DispGetParam to perform type coercion
73 FIXME("Coercion of arguments not implemented\n");
75 hr = ICOM_CALL7(Invoke,
80 pparams, pvarResult, pexcepinfo, puArgErr);
86 /******************************************************************************
87 * DispGetIDsOfNames (OLEAUT32.29)
89 * Convert a set of names to dispids, based on information
90 * contained in object's type library.
93 * - Defers to ITypeInfo::GetIDsOfNames()
99 HRESULT WINAPI DispGetIDsOfNames(
100 ITypeInfo *ptinfo, /* [in] */
101 OLECHAR **rgszNames, /* [in] */
102 UINT cNames, /* [in] */
103 DISPID *rgdispid) /* [out] */
107 hr = ICOM_CALL3(GetIDsOfNames,
115 /******************************************************************************
116 * DispGetParam (OLEAUT32.28)
118 * Retrive a parameter from a DISPPARAMS structures and coerce it to
119 * specified variant type
122 * Coercion is done using system (0) locale.
128 HRESULT WINAPI DispGetParam(
129 DISPPARAMS *pdispparams, /* [in] */
130 UINT position, /* [in] */
131 VARTYPE vtTarg, /* [in] */
132 VARIANT *pvarResult, /* [out] */
133 UINT *puArgErr) /* [out] */
135 /* position is counted backwards */
139 TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
140 position, pdispparams->cArgs, pdispparams->cNamedArgs);
141 if (position < pdispparams->cArgs) {
142 /* positional arg? */
143 pos = pdispparams->cArgs - position - 1;
145 /* FIXME: is this how to handle named args? */
146 for (pos=0; pos<pdispparams->cNamedArgs; pos++)
147 if (pdispparams->rgdispidNamedArgs[pos] == position) break;
149 if (pos==pdispparams->cNamedArgs)
150 return DISP_E_PARAMNOTFOUND;
152 hr = VariantChangeType(pvarResult,
153 &pdispparams->rgvarg[pos],
155 if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
159 /******************************************************************************
160 * CreateStdDispatch [OLEAUT32.32]
162 HRESULT WINAPI CreateStdDispatch(
166 IUnknown** ppunkStdDisp)
168 TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, ppunkStdDisp);
170 *ppunkStdDisp = (LPUNKNOWN)StdDispatch_Construct(punkOuter, pvThis, ptinfo);
172 return E_OUTOFMEMORY;
176 /******************************************************************************
177 * CreateDispTypeInfo [OLEAUT32.31]
179 HRESULT WINAPI CreateDispTypeInfo(
180 INTERFACEDATA *pidata,
184 FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
190 ICOM_VFIELD(IDispatch);
191 IUnknown * outerUnknown;
193 ITypeInfo * pTypeInfo;
197 static HRESULT WINAPI StdDispatch_QueryInterface(
202 ICOM_THIS(StdDispatch, iface);
203 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
205 if (This->outerUnknown)
206 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
208 if (IsEqualIID(riid, &IID_IDispatch) ||
209 IsEqualIID(riid, &IID_IUnknown))
211 *ppvObject = (LPVOID)This;
212 IUnknown_AddRef((LPUNKNOWN)*ppvObject);
215 return E_NOINTERFACE;
218 static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface)
220 ICOM_THIS(StdDispatch, iface);
223 if (This->outerUnknown)
224 return IUnknown_AddRef(This->outerUnknown);
229 static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
231 ICOM_THIS(StdDispatch, iface);
233 TRACE("(%p)->()\n", This);
237 if (This->outerUnknown)
238 ret = IUnknown_Release(This->outerUnknown);
248 static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
250 TRACE("(%p)\n", pctinfo);
256 static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
258 ICOM_THIS(StdDispatch, iface);
259 TRACE("(%d, %lx, %p)\n", iTInfo, lcid, ppTInfo);
262 return DISP_E_BADINDEX;
263 *ppTInfo = This->pTypeInfo;
267 static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
269 ICOM_THIS(StdDispatch, iface);
270 TRACE("(%s, %p, %d, 0x%lx, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
272 if (!IsEqualGUID(riid, &IID_NULL))
274 FIXME(" expected riid == IID_NULL\n");
277 return DispGetIDsOfNames(This->pTypeInfo, rgszNames, cNames, rgDispId);
280 static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr)
282 ICOM_THIS(StdDispatch, iface);
283 TRACE("(%ld, %s, 0x%lx, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
285 if (!IsEqualGUID(riid, &IID_NULL))
287 FIXME(" expected riid == IID_NULL\n");
290 return DispInvoke(This->pvThis, This->pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
293 static ICOM_VTABLE(IDispatch) StdDispatch_VTable =
295 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
296 StdDispatch_QueryInterface,
299 StdDispatch_GetTypeInfoCount,
300 StdDispatch_GetTypeInfo,
301 StdDispatch_GetIDsOfNames,
305 static IDispatch * WINAPI StdDispatch_Construct(
306 IUnknown * punkOuter,
308 ITypeInfo * pTypeInfo)
310 StdDispatch * pStdDispatch;
312 pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch));
314 return (IDispatch *)pStdDispatch;
316 pStdDispatch->lpVtbl = &StdDispatch_VTable;
317 pStdDispatch->outerUnknown = punkOuter;
318 pStdDispatch->pvThis = pvThis;
319 pStdDispatch->pTypeInfo = pTypeInfo;
320 pStdDispatch->ref = 1;
322 return (IDispatch *)pStdDispatch;