- Correct implementation of HUSKEY internals, including functions:
[wine] / dlls / oleaut32 / dispatch.c
1 /**
2  * Dispatch API functions
3  *
4  * Copyright 2000  Francois Jacques, Macadamian Technologies Inc.
5  *
6  * ---
7  *
8  * TODO: Type coercion is implemented in variant.c but not called yet.
9  */
10
11 #include "config.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <ctype.h>
17
18 #include "windef.h"
19 #include "ole.h"
20 #include "oleauto.h"
21 #include "winerror.h"
22 #include "winreg.h"         /* for HKEY_LOCAL_MACHINE */
23 #include "winnls.h"         /* for PRIMARYLANGID */
24
25 #include "wine/obj_oleaut.h"
26
27 #include "debugtools.h"
28
29 DEFAULT_DEBUG_CHANNEL(ole);
30 DECLARE_DEBUG_CHANNEL(typelib);
31
32
33 /******************************************************************************
34  *              DispInvoke (OLEAUT32.30)
35  *
36  *
37  * Calls method of an object through its IDispatch interface.
38  *
39  * NOTES
40  *              - Defer method invocation to ITypeInfo::Invoke()
41  *
42  * RETURNS
43  *
44  *              S_OK on success.
45  */
46 HRESULT WINAPI DispInvoke(
47         VOID       *_this,        /* [in] object instance */
48         ITypeInfo  *ptinfo,       /* [in] object's type info */
49         DISPID      dispidMember, /* [in] member id */
50         USHORT      wFlags,       /* [in] kind of method call */
51         DISPPARAMS *pparams,      /* [in] array of arguments */
52         VARIANT    *pvarResult,   /* [out] result of method call */
53         EXCEPINFO  *pexcepinfo,   /* [out] information about exception */
54         UINT       *puArgErr)     /* [out] index of bad argument(if any) */
55 {
56     HRESULT hr = E_FAIL;
57
58     /**
59      * TODO:
60      * For each param, call DispGetParam to perform type coercion
61      */
62     FIXME("Coercion of arguments not implemented\n");
63
64     hr = ICOM_CALL7(Invoke,
65                     ptinfo,
66                     _this,
67                     dispidMember,
68                     wFlags,
69                     pparams, pvarResult, pexcepinfo, puArgErr);
70
71     return (hr);
72 }
73
74
75 /******************************************************************************
76  *              DispGetIDsOfNames (OLEAUT32.29)
77  *
78  * Convert a set of names to dispids, based on information 
79  * contained in object's type library.
80  * 
81  * NOTES
82  *              - Defers to ITypeInfo::GetIDsOfNames()
83  *
84  * RETURNS
85  *
86  *              S_OK on success.
87  */
88 HRESULT WINAPI DispGetIDsOfNames(
89         ITypeInfo  *ptinfo,    /* [in] */
90         OLECHAR   **rgszNames, /* [in] */
91         UINT        cNames,    /* [in] */
92         DISPID     *rgdispid)  /* [out] */
93 {
94     HRESULT hr = E_FAIL;
95
96     hr = ICOM_CALL3(GetIDsOfNames,
97                     ptinfo,
98                     rgszNames,
99                     cNames,
100                     rgdispid);
101     return (hr);
102 }
103
104 /******************************************************************************
105  *              DispGetParam (OLEAUT32.28)
106  *
107  * Retrive a parameter from a DISPPARAMS structures and coerce it to
108  * specified variant type
109  *
110  * NOTES
111  *              Coercion is done using system (0) locale.
112  *
113  * RETURNS
114  *
115  *              S_OK on success.
116  */
117 HRESULT WINAPI DispGetParam(
118         DISPPARAMS *pdispparams, /* [in] */
119         UINT        position,    /* [in] */
120         VARTYPE     vtTarg,      /* [in] */
121         VARIANT    *pvarResult,  /* [out] */
122         UINT       *puArgErr)    /* [out] */
123 {
124     /* position is counted backwards */
125     UINT pos;
126     HRESULT hr;
127
128     TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
129           position, pdispparams->cArgs, pdispparams->cNamedArgs);
130     if (position < pdispparams->cArgs) {
131       /* positional arg? */
132       pos = pdispparams->cArgs - position - 1;
133     } else {
134       /* FIXME: is this how to handle named args? */
135       for (pos=0; pos<pdispparams->cNamedArgs; pos++)
136         if (pdispparams->rgdispidNamedArgs[pos] == position) break;
137
138       if (pos==pdispparams->cNamedArgs)
139         return DISP_E_PARAMNOTFOUND;
140     }
141     hr = VariantChangeType(pvarResult,
142                            &pdispparams->rgvarg[pos],
143                            0, vtTarg);
144     if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
145     return hr;
146 }