00001 #include "OSDependent/OLE.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 HRESULT
00018 OLE::createObject(LPOLESTR pszProgID, IDispatch FAR* FAR* ppdisp)
00019 {
00020 CLSID clsid;
00021 HRESULT hr;
00022 LPUNKNOWN punk = NULL;
00023 LPDISPATCH pdisp = NULL;
00024
00025 *ppdisp = NULL;
00026
00027
00028 hr = CLSIDFromProgID(pszProgID, &clsid);
00029 if (FAILED(hr))
00030 goto error;
00031
00032
00033 hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER,
00034 IID_IUnknown, (void FAR* FAR*)&punk);
00035 if (FAILED(hr))
00036 goto error;
00037
00038 hr = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
00039 if (FAILED(hr))
00040 goto error;
00041
00042 *ppdisp = pdisp;
00043 punk->Release();
00044 return NOERROR;
00045
00046 error:
00047 if (punk) punk->Release();
00048 if (pdisp) pdisp->Release();
00049 return hr;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 HRESULT
00113 OLE::invoke(LPDISPATCH pdisp,
00114 WORD wFlags,
00115 LPVARIANT pvRet,
00116 EXCEPINFO FAR* pexcepinfo,
00117 UINT FAR* pnArgErr,
00118 LPOLESTR pszName,
00119 LPCTSTR pszFmt,
00120 ...)
00121 {
00122 va_list argList;
00123 va_start(argList, pszFmt);
00124 DISPID dispid;
00125 HRESULT hr;
00126 VARIANTARG* pvarg = NULL;
00127
00128 if (pdisp == NULL)
00129 return ResultFromScode(E_INVALIDARG);
00130
00131
00132 hr = pdisp->GetIDsOfNames(IID_NULL, &pszName, 1, LOCALE_USER_DEFAULT, &dispid);
00133 if(FAILED(hr))
00134 return hr;
00135
00136 DISPPARAMS dispparams;
00137 _fmemset(&dispparams, 0, sizeof dispparams);
00138
00139
00140 if (pszFmt != NULL)
00141 countArgsInFormat(pszFmt, &dispparams.cArgs);
00142
00143
00144
00145 DISPID dispidNamed = DISPID_PROPERTYPUT;
00146 if (wFlags & DISPATCH_PROPERTYPUT)
00147 {
00148 if (dispparams.cArgs == 0)
00149 return ResultFromScode(E_INVALIDARG);
00150 dispparams.cNamedArgs = 1;
00151 dispparams.rgdispidNamedArgs = &dispidNamed;
00152 }
00153
00154 if (dispparams.cArgs != 0)
00155 {
00156
00157 pvarg = new VARIANTARG[dispparams.cArgs];
00158 if(pvarg == NULL)
00159 return ResultFromScode(E_OUTOFMEMORY);
00160 dispparams.rgvarg = pvarg;
00161 _fmemset(pvarg, 0, sizeof(VARIANTARG) * dispparams.cArgs);
00162
00163
00164 LPCTSTR psz = pszFmt;
00165 pvarg += dispparams.cArgs - 1;
00166
00167 while (psz = getNextVarType(psz, &pvarg->vt))
00168 {
00169 if (pvarg < dispparams.rgvarg)
00170 {
00171 hr = ResultFromScode(E_INVALIDARG);
00172 goto cleanup;
00173 }
00174 switch (pvarg->vt)
00175 {
00176 case VT_I2:
00177 V_I2(pvarg) = va_arg(argList, short);
00178 break;
00179 case VT_I4:
00180 V_I4(pvarg) = va_arg(argList, long);
00181 break;
00182 case VT_R4:
00183 V_R4(pvarg) = va_arg(argList, float);
00184 break;
00185 case VT_DATE:
00186 case VT_R8:
00187 V_R8(pvarg) = va_arg(argList, double);
00188 break;
00189 case VT_CY:
00190 V_CY(pvarg) = va_arg(argList, CY);
00191 break;
00192 case VT_BSTR:
00193 V_BSTR(pvarg) = SysAllocString(va_arg(argList, OLECHAR FAR*));
00194 if (pvarg->bstrVal == NULL)
00195 {
00196 hr = ResultFromScode(E_OUTOFMEMORY);
00197 pvarg->vt = VT_EMPTY;
00198 goto cleanup;
00199 }
00200 break;
00201 case VT_DISPATCH:
00202 V_DISPATCH(pvarg) = va_arg(argList, LPDISPATCH);
00203 break;
00204 case VT_ERROR:
00205 V_ERROR(pvarg) = va_arg(argList, SCODE);
00206 break;
00207 case VT_BOOL:
00208 V_BOOL(pvarg) = va_arg(argList, BOOL) ? -1 : 0;
00209 break;
00210 case VT_VARIANT:
00211 *pvarg = va_arg(argList, VARIANTARG);
00212 break;
00213 case VT_UNKNOWN:
00214 V_UNKNOWN(pvarg) = va_arg(argList, LPUNKNOWN);
00215 break;
00216
00217 case VT_I2|VT_BYREF:
00218 V_I2REF(pvarg) = va_arg(argList, short FAR*);
00219 break;
00220 case VT_I4|VT_BYREF:
00221 V_I4REF(pvarg) = va_arg(argList, long FAR*);
00222 break;
00223 case VT_R4|VT_BYREF:
00224 V_R4REF(pvarg) = va_arg(argList, float FAR*);
00225 break;
00226 case VT_R8|VT_BYREF:
00227 V_R8REF(pvarg) = va_arg(argList, double FAR*);
00228 break;
00229 case VT_DATE|VT_BYREF:
00230 V_DATEREF(pvarg) = va_arg(argList, DATE FAR*);
00231 break;
00232 case VT_CY|VT_BYREF:
00233 V_CYREF(pvarg) = va_arg(argList, CY FAR*);
00234 break;
00235 case VT_BSTR|VT_BYREF:
00236 V_BSTRREF(pvarg) = va_arg(argList, BSTR FAR*);
00237 break;
00238 case VT_DISPATCH|VT_BYREF:
00239 V_DISPATCHREF(pvarg) = va_arg(argList, LPDISPATCH FAR*);
00240 break;
00241 case VT_ERROR|VT_BYREF:
00242 V_ERRORREF(pvarg) = va_arg(argList, SCODE FAR*);
00243 break;
00244 case VT_BOOL|VT_BYREF:
00245 {
00246 BOOL FAR* pbool = va_arg(argList, BOOL FAR*);
00247 *pbool = 0;
00248 V_BOOLREF(pvarg) = (VARIANT_BOOL FAR*)pbool;
00249 }
00250 break;
00251 case VT_VARIANT|VT_BYREF:
00252 V_VARIANTREF(pvarg) = va_arg(argList, VARIANTARG FAR*);
00253 break;
00254 case VT_UNKNOWN|VT_BYREF:
00255 V_UNKNOWNREF(pvarg) = va_arg(argList, LPUNKNOWN FAR*);
00256 break;
00257
00258 default:
00259 {
00260 hr = ResultFromScode(E_INVALIDARG);
00261 goto cleanup;
00262 }
00263 break;
00264 }
00265
00266 --pvarg;
00267 }
00268 }
00269
00270
00271
00272 if (pvRet)
00273 VariantInit(pvRet);
00274
00275 try {
00276 hr = pdisp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, wFlags,
00277 &dispparams, pvRet, pexcepinfo, pnArgErr);
00278 }
00279 catch (...) {
00280 hr = E_FAIL;
00281 }
00282
00283 cleanup:
00284
00285 if (dispparams.cArgs != 0)
00286 {
00287 VARIANTARG FAR* pvarg = dispparams.rgvarg;
00288 UINT cArgs = dispparams.cArgs;
00289
00290 while (cArgs--)
00291 {
00292 switch (pvarg->vt)
00293 {
00294 case VT_BSTR:
00295 VariantClear(pvarg);
00296 break;
00297 }
00298 ++pvarg;
00299 }
00300 }
00301
00302 va_end(argList);
00303 return hr;
00304 }
00305
00306 HRESULT
00307 OLE::countArgsInFormat(LPCTSTR pszFmt, UINT FAR *pn)
00308 {
00309 *pn = 0;
00310
00311 if(pszFmt == NULL)
00312 return NOERROR;
00313
00314 while (*pszFmt)
00315 {
00316 if (*pszFmt == '&')
00317 pszFmt++;
00318
00319 switch(*pszFmt)
00320 {
00321 case 'b':
00322 case 'i':
00323 case 'I':
00324 case 'r':
00325 case 'R':
00326 case 'c':
00327 case 's':
00328 case 'e':
00329 case 'd':
00330 case 'v':
00331 case 'D':
00332 case 'U':
00333 ++*pn;
00334 pszFmt++;
00335 break;
00336 case '\0':
00337 default:
00338 return ResultFromScode(E_INVALIDARG);
00339 }
00340 }
00341 return NOERROR;
00342 }
00343
00344
00345 LPCTSTR
00346 OLE::getNextVarType(LPCTSTR pszFmt, VARTYPE FAR* pvt)
00347 {
00348 *pvt = 0;
00349 if (*pszFmt == '&')
00350 {
00351 *pvt = VT_BYREF;
00352 pszFmt++;
00353 if (!*pszFmt)
00354 return NULL;
00355 }
00356 switch(*pszFmt)
00357 {
00358 case 'b':
00359 *pvt |= VT_BOOL;
00360 break;
00361 case 'i':
00362 *pvt |= VT_I2;
00363 break;
00364 case 'I':
00365 *pvt |= VT_I4;
00366 break;
00367 case 'r':
00368 *pvt |= VT_R4;
00369 break;
00370 case 'R':
00371 *pvt |= VT_R8;
00372 break;
00373 case 'c':
00374 *pvt |= VT_CY;
00375 break;
00376 case 's':
00377 *pvt |= VT_BSTR;
00378 break;
00379 case 'e':
00380 *pvt |= VT_ERROR;
00381 break;
00382 case 'd':
00383 *pvt |= VT_DATE;
00384 break;
00385 case 'v':
00386 *pvt |= VT_VARIANT;
00387 break;
00388 case 'U':
00389 *pvt |= VT_UNKNOWN;
00390 break;
00391 case 'D':
00392 *pvt |= VT_DISPATCH;
00393 break;
00394 case '\0':
00395 return NULL;
00396 default:
00397 return NULL;
00398 }
00399 return ++pszFmt;
00400 }
00401