|
|
1.1 root 1: /***
2: *disphelp.cpp - IDispatch helpers
3: *
4: * Copyright (C) 1992, Microsoft Corporation. All Rights Reserved.
5: * Information Contained Herein Is Proprietary and Confidential.
6: *
7: *Purpose:
8: * This file contains several useful IDispatch related utilities.
9: *
10: *****************************************************************************/
11:
12: #include <windows.h>
13: #include <ole2.h>
14: #include <dispatch.h>
15:
16: #include <stdarg.h>
17:
18: #include "disphelp.h"
19:
20: // Adjust for WIN16/WIN32 synchronization
21: #if defined(WIN32) && !defined(OLE2FINAL)
22: #define E_FAIL E_UNSPEC
23: #endif
24:
25: /* helper for DispBuildParams */
26: HRESULT PASCAL
27: CArgsOfFmt(DISPPARAMS FAR* pdispparams, char FAR* szFmt)
28: {
29: char FAR* sz;
30:
31: pdispparams->cArgs = 0;
32: pdispparams->cNamedArgs = 0;
33:
34: if(szFmt == NULL)
35: return NOERROR;
36:
37: for(sz = szFmt; *sz != '\0'; ++sz){
38: if(*sz == '&')
39: ++sz;
40:
41: switch(*sz){
42: case 'e':
43: case 'n':
44: case 'f':
45: case 'i': case 'I':
46: case 'r': case 'R':
47: case 'c':
48: case 'b':
49: case 's':
50: case 'd':
51: case 'v':
52: case 'D':
53: ++pdispparams->cArgs;
54: break;
55:
56: default:
57: return ResultFromScode(E_INVALIDARG);
58: }
59: }
60:
61: return NOERROR;
62: }
63:
64:
65: /* helper for DispBuildParams */
66: VARTYPE PASCAL
67: VtOfFmtChar(char ch)
68: {
69: switch(ch){
70: case 'e': return VT_EMPTY;
71: case 'n': return VT_NULL;
72: case 'f': return VT_BOOL;
73: case 'i': return VT_I2;
74: case 'I': return VT_I4;
75: case 'r': return VT_R4;
76: case 'R': return VT_R8;
77: case 'c': return VT_CY;
78: case 'b': return VT_BSTR;
79: case 's': return VT_ERROR;
80: case 'd': return VT_DATE;
81: case 'v': return VT_VARIANT;
82: case 'U': return VT_UNKNOWN;
83: case 'D': return VT_DISPATCH;
84: }
85:
86: // REVIEW: this is really an error
87: return VT_EMPTY;
88: }
89:
90:
91: /***
92: *PUBLIC DispBuildParams(DISPPARAMS**, UINT, DISPID*, char*, ...)
93: *Purpose:
94: * Construct a DISPPARAMS struct based on the given format string.
95: *
96: * '&' = mark the following record VT_BYREF
97: *
98: * 'e' = VT_EMPTY
99: * 'n' = VT_NULL
100: * 'f' = VT_BOOL 'f' as in flag
101: * 'i' = VT_I2
102: * 'I' = VT_I4
103: * 'r' = VT_R4
104: * 'R' = VT_R8
105: * 'c' = VT_CY
106: * 'b' = VT_BSTR
107: * 's' = VT_ERROR 's' as in scode
108: * 'd' = VT_DATE
109: * 'v' = VT_VARIANT
110: * 'D' = VT_DISPATCH
111: * 'U' = VT_UNKNOWN
112: *
113: #
114: *Entry:
115: * UNDONE
116: *
117: *Exit:
118: * UNDONE
119: *
120: ***********************************************************************/
121: extern "C" HRESULT FAR CDECL
122: DispBuildParams(
123: DISPPARAMS FAR* FAR* ppdispparams,
124: UINT cNamedArgs,
125: DISPID FAR* rgdispid,
126: char FAR* szFmt, ...)
127: {
128: int ix;
129: va_list args;
130: char FAR* sz;
131: HRESULT hresult;
132: VARIANTARG FAR* pvarg;
133:
134: VARTYPE vt, vtMode;
135: DISPPARAMS FAR* pdispparams;
136:
137:
138: pdispparams = new DISPPARAMS;
139: if(pdispparams == NULL)
140: return ResultFromScode(E_OUTOFMEMORY);
141:
142: // compute the total number of arguments represented by the format
143: // string, *and* validate the contents of the format string.
144: //
145: if((hresult = CArgsOfFmt(pdispparams, szFmt)) != NOERROR)
146: goto LFreeDispParams;
147:
148: // the total number of arguments numst be >= the number of named args.
149: //
150: if(pdispparams->cArgs < cNamedArgs){
151: hresult = ResultFromScode(E_INVALIDARG);
152: goto LFreeDispParams;
153: }
154: pdispparams->cNamedArgs = cNamedArgs;
155:
156: pdispparams->rgvarg = new VARIANTARG[pdispparams->cArgs];
157: if((pdispparams->rgvarg) == NULL){
158: hresult = ResultFromScode(E_OUTOFMEMORY);
159: goto LFreeDispParams;
160: }
161:
162: if(pdispparams->cNamedArgs == 0){
163: pdispparams->rgdispidNamedArgs = NULL;
164: }else{
165: pdispparams->rgdispidNamedArgs = new DISPID[pdispparams->cNamedArgs];
166: if((pdispparams->rgdispidNamedArgs) == NULL){
167: hresult = ResultFromScode(E_OUTOFMEMORY);
168: goto LFreeRgVarg;
169: }
170: for(UINT i = 0; i < cNamedArgs; ++i)
171: pdispparams->rgdispidNamedArgs[i] = rgdispid[cNamedArgs - i - 1];
172: }
173:
174: va_start(args, szFmt);
175: ix = pdispparams->cArgs;
176:
177: for(sz = szFmt; *sz != '\0'; ++sz){
178: --ix;
179:
180: vtMode = 0;
181: pvarg = &pdispparams->rgvarg[ix];
182:
183: if(*sz == '&'){
184: ++sz;
185: vtMode |= VT_BYREF;
186: }
187:
188: vt = VtOfFmtChar(*sz);
189:
190: if(vtMode & VT_BYREF){
191:
192: V_BYREF(pvarg) = va_arg(args, void FAR*);
193:
194: }else{
195:
196: switch(*sz){
197: case 'e': // VT_EMPTY
198: break;
199:
200: case 'n': // VT_NULL
201: V_I4(pvarg) = 0;
202: break;
203:
204: case 'I': // VT_I4
205: case 's': // VT_ERROR
206: V_I4(pvarg) = va_arg(args, long);
207: break;
208:
209: case 'f': // VT_BOOL
210: case 'i': // VT_I2
211: V_I2(pvarg) = va_arg(args, short);
212: break;
213:
214: case 'r': // VT_R4
215: V_R4(pvarg) = (float)va_arg(args, double);
216: break;
217:
218: case 'd': // VT_DATE
219: case 'R': // VT_R8
220: V_R8(pvarg) = va_arg(args, double);
221: break;
222:
223: case 'c': // VT_CY
224: V_CY(pvarg) = va_arg(args, CY);
225: break;
226:
227: case 'b': // VT_BSTR
228: //REVIEW: do we need to make a copy of this?
229: V_BSTR(pvarg) = va_arg(args, BSTR);
230: break;
231:
232: case 'v': // VT_VARIANT
233: V_VARIANTREF(pvarg) = va_arg(args, VARIANT FAR*);
234: break;
235:
236: case 'U': // VT_UNKNOWN
237: vt = VT_DISPATCH;
238: V_UNKNOWN(pvarg) = va_arg(args, IUnknown FAR*);
239: break;
240:
241: case 'D': // VT_DISPATCH
242: vt = VT_DISPATCH;
243: V_DISPATCH(pvarg) = va_arg(args, IDispatch FAR*);
244: break;
245:
246: default:
247: hresult = ResultFromScode(E_FAIL);
248: goto LFreeRgVarg;
249: }
250: }
251:
252: V_VT(pvarg) = vtMode | vt;
253: }
254:
255: *ppdispparams = pdispparams;
256:
257: return NOERROR;
258:
259:
260: LFreeRgVarg:;
261: delete pdispparams->rgvarg;
262:
263: LFreeDispParams:;
264: delete pdispparams;
265:
266: return hresult;
267: }
268:
269:
270: /***
271: *PUBLIC HRESULT DispFreeParams(DISPPARAMS*)
272: *Purpose:
273: * Free the given DISPPARAMS struct, and its contents.
274: *
275: *Entry:
276: * pdispparams = the DISPPARAMS structure to free
277: *
278: *Exit:
279: * return value = HRESULT
280: *
281: ***********************************************************************/
282: STDAPI
283: DispFreeParams(DISPPARAMS FAR* pdispparams)
284: {
285: UINT i;
286: HRESULT hresult;
287:
288: for(i = 0; i < pdispparams->cArgs; ++i){
289: if ((hresult = VariantClear(&pdispparams->rgvarg[i])) != NOERROR)
290: return hresult;
291: }
292:
293: delete pdispparams->rgvarg;
294: delete pdispparams->rgdispidNamedArgs;
295: delete pdispparams;
296:
297: return NOERROR;
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.