forked from WinMerge/winmerge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlwdisp.h
269 lines (225 loc) · 7.88 KB
/
lwdisp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/* File: lwdisp.h - light weight dispatch API
* Author: Jochen Tucht 2003/01/09
* Copyright (C) 2003 herbert dahm datensysteme GmbH
*
* Declaration file for lwdisp.c
*
* Purpose: - Create windows scripting objects (scriptlets)
* - Invoke methods and access properties
* - Implement callback interfaces to be invoked by scriptlets
*
* License: THIS FILE CONTAINS FREE SOURCE CODE. IT IS PROVIDED *AS IS*, WITHOUT
* WARRANTY OF ANY KIND. YOU MAY USE IT AT YOUR OWN RISK, AS LONG AS
* YOU KEEP IT IN A SEPARATE FILE AND PRESERVE THIS COMMENT.
* CHANGES MUST BE RECORDED IN THE MODIFICATION HISTORY BELOW SO THERE
* IS EVIDENCE THAT THE FILE DIFFERS FROM EARLIER RELEASES. THE LEVEL
* OF DETAIL IS UP TO YOU. YOU MAY SET THE BY: ENTRY TO "NOBODY@ALL"
* IF YOU DON'T WANT TO EXPOSE YOUR NAME. SUBSEQUENT CHANGES MAY BE
* REFLECTED BY A SINGLE RECORD CARRYING THE DATE OF THE LATEST CHANGE.
*
DATE: BY: DESCRIPTION:
========== ================== ================================================
2003/11/28 Laoran header and RCS ID
*/
#pragma once
#ifdef __cplusplus
extern "C"{
#endif
#ifdef _MSC_VER
#define UNUSED_ARG(ARG) ARG
#elif defined(__GNUC__)
#define UNUSED_ARG(ARG) ARG
#else
#define UNUSED_ARG(ARG)
#endif
// macros for use with ValidateArgs()
// parameter types: by value VTs
#define VTS_I2 "\x02" // a 'short'
#define VTS_I4 "\x03" // a 'long'
#define VTS_R4 "\x04" // a 'float'
#define VTS_R8 "\x05" // a 'double'
#define VTS_CY "\x06" // a 'CY' or 'CY*'
#define VTS_DATE "\x07" // a 'DATE'
#define VTS_WBSTR "\x08" // an 'LPCOLESTR'
#define VTS_DISPATCH "\x09" // an 'IDispatch*'
#define VTS_SCODE "\x0A" // an 'SCODE'
#define VTS_BOOL "\x0B" // a 'BOOL'
#define VTS_VARIANT "\x0C" // a 'const VARIANT&' or 'VARIANT*'
#define VTS_UNKNOWN "\x0D" // an 'IUnknown*'
#if defined(_UNICODE) || defined(OLE2ANSI)
#define VTS_BSTR VTS_WBSTR// an 'LPCOLESTR'
#define VT_BSTRT VT_BSTR
#else
#define VTS_BSTR "\x0E" // an 'LPCSTR'
#define VT_BSTRA 14
#define VT_BSTRT VT_BSTRA
#endif
#ifndef VTS_UI1
#define VTS_UI1 "\x0F" // a 'BYTE'
#endif
// parameter types: by reference VTs
#define VTS_PI2 "\x42" // a 'short*'
#define VTS_PI4 "\x43" // a 'long*'
#define VTS_PR4 "\x44" // a 'float*'
#define VTS_PR8 "\x45" // a 'double*'
#define VTS_PCY "\x46" // a 'CY*'
#define VTS_PDATE "\x47" // a 'DATE*'
#define VTS_PBSTR "\x48" // a 'BSTR*'
#define VTS_PDISPATCH "\x49" // an 'IDispatch**'
#define VTS_PSCODE "\x4A" // an 'SCODE*'
#define VTS_PBOOL "\x4B" // a 'VARIANT_BOOL*'
#define VTS_PVARIANT "\x4C" // a 'VARIANT*'
#define VTS_PUNKNOWN "\x4D" // an 'IUnknown**'
// special VT_ and VTS_ values
#define VTS_NONE NULL // used for members with 0 params
// macros for use with wsprintfA(), wsprintfW()
#ifdef _UNICODE
#define WVA_TSTR L"%s"
#define AVA_TSTR "%S"
#define TVA_BSTR L"%s"
#else
#define WVA_TSTR L"%S"
#define AVA_TSTR "%s"
#define TVA_BSTR "%S"
#endif
// misc. macros
#define DIMOF(a) (sizeof(a)/sizeof(*a))
/**
* @param source : if 0, create an object of the class registered as *progid*
* @param progid : if 0, create an object from file *source*
* If both source and progid defined, ask *source* to create an object of class *progid*
*/
LPDISPATCH NTAPI CreateDispatchBySource(LPCTSTR source, LPCWSTR progid);
/**
* @brief invoke helper (__stdcall)
*
* @note Free all variants passed to it (except ByRef ones)
*/
STDAPI invokeV(LPDISPATCH, VARIANT *, DISPID, LPCCH, VARIANT *);
/**
* @brief invoke helper (by ordinal)
*
* @note Free all variants passed to it (except ByRef ones)
*/
STDAPIV invokeA(LPDISPATCH, VARIANT *, DISPID, LPCCH, VARIANT *);
/**
* @brief invoke helper (by function name)
*
* @note Free all variants passed to it (except ByRef ones)
*/
STDAPIV invokeW(LPDISPATCH, VARIANT *, LPCOLESTR, LPCCH, VARIANT *);
// macros for use with invoke*()
#define opFxn &((PCH)(DISPATCH_METHOD<<8))
#define opPut &((PCH)(DISPATCH_PROPERTYPUT<<8))
#define opGet &((PCH)(DISPATCH_PROPERTYGET<<8))
#define opSet &((PCH)(DISPATCH_PROPERTYPUTREF<<8))
// ::invokeW(piDispatch, LODD(Foo), ...) will fail silently if the interface
// lacks the requested method or property
#define LODD(NAME) ((BSTR)((PCH)L###NAME+1))
// convert given arguments to requested types
STDAPI ValidateArgs(VARIANT *argv, UINT argc, LPCCH pvt);
// in place conversion of BSTR to LPCCH
// IN PLACE TRANSFORMATION OF WCHAR TO CHAR IS NOT CORRECT
/*
PCH NTAPI B2A(BSTR);
LPCTSTR NTAPI B2T(BSTR);
*/
// callback interface related declarations
typedef HRESULT(NTAPI*LWDispFxn)
(PVOID, HRESULT, VARIANT *, VARIANT *, UINT, EXCEPINFO *);
STDAPI LWDefProc
(PVOID, HRESULT, VARIANT *, VARIANT *, UINT, EXCEPINFO *);
struct LWDispRef
{
LPCWSTR pwcName;
LWDispFxn pfnProc;
};
struct LWDispatch;
struct LWDispVtbl
{
HRESULT(STDMETHODCALLTYPE*QueryInterface)(
struct LWDispatch *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void **ppvObject);
ULONG(STDMETHODCALLTYPE*AddRef)(struct LWDispatch *This);
ULONG(STDMETHODCALLTYPE*Release)(struct LWDispatch *This);
HRESULT(STDMETHODCALLTYPE*GetTypeInfoCount)(
struct LWDispatch *This,
/* [out] */ UINT *pctinfo);
HRESULT(STDMETHODCALLTYPE*GetTypeInfo)(
struct LWDispatch *This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo);
HRESULT(STDMETHODCALLTYPE*GetIDsOfNames)(
struct LWDispatch *This,
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId);
HRESULT(STDMETHODCALLTYPE*Invoke)(
struct LWDispatch *This,
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr);
};
struct LWDispatch
{
const struct LWDispVtbl *lpVtbl;
void *target;
const struct LWDispMap *map;
ULONG refc;
};
const struct LWDispVtbl *NTAPI LWDispSubclass(struct LWDispVtbl *);
IDispatch *NTAPI LWDispatch(void *target, const void *disp_map,
const struct LWDispVtbl *, struct LWDispatch *);
// functions to build VARIANT arguments from various data types
// LWArg for objects
VARIANT NTAPI LWArg(LPDISPATCH);
// LWArg for wide and ansi character strings
VARIANT NTAPI LWArgW(LPCWSTR);
VARIANT NTAPI LWArgA(LPCSTR);
#ifdef _UNICODE
#define LWArgT LWArgW
#else
#define LWArgT LWArgA
#endif
// Generic LWArg for everything that does not involve dynamic allocation or
// reference counting. Use LWVT macro to compute the UINT argument.
VARIANT NTAPI LWArgV(UINT, ...);
#define LWVT(t) (sizeof(V_##t((VARIANT*)0)) << 8 | VT_##t)
// assign variant type and data in one statement
#define V_VAR(r,t) V_VT(r)=VT_##t,V_##t(r)
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
// LWDispMap implementation macros for C++
#define DISPMAP_FXN(NAME) \
HRESULT *_##NAME, NAME(HRESULT, VARIANT *, VARIANT *, UINT, EXCEPINFO *); \
static HRESULT NTAPI NAME##_(PVOID p, HRESULT sc, VARIANT *ret, VARIANT *argv, UINT argc, EXCEPINFO *e) \
{ return ((P*)p)->NAME(sc, ret, argv, argc, e); }
#define DISPMAP_REF(NAME) {L###NAME,NAME##_}
#define DISPMAP(T) \
enum {COUNT = (sizeof(P) - sizeof(T)) / sizeof(HRESULT*)}; \
static const struct\
{ \
LWDispFxn pfnProc; \
int count; \
struct LWDispRef ref[COUNT]; \
} map =
// VARIANT derivative to hold a result value
struct LWRet: public VARIANT
{
LWRet() {VariantInit(this);}
~ LWRet() {VariantClear(this);}
};
#else
// Sorry, no extra support for plain old C...
#endif