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
|
/***********************************************************************/
/* */
/* CamlIDL */
/* */
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
/* */
/* Copyright 1999 Institut National de Recherche en Informatique et */
/* en Automatique. All rights reserved. This file is distributed */
/* under the terms of the GNU Library General Public License. */
/* */
/***********************************************************************/
/* $Id: dispatch.c,v 1.2 2000-08-19 11:05:00 xleroy Exp $ */
/* Support for dispatch interfaces */
#include <string.h>
#include <stdio.h>
#include "camlidlruntime.h"
#include "comstuff.h"
/* Handle for module (for the DLL) */
HMODULE camlidl_module_handle = NULL;
/* Retrieves the number of type information interfaces that
the object provides (either 0 or 1). */
HRESULT STDMETHODCALLTYPE
camlidl_GetTypeInfoCount(struct camlidl_intf * self, UINT * count_type_info)
{
*count_type_info = 1;
return S_OK;
}
/* Retrieves the type information for the object */
HRESULT STDMETHODCALLTYPE
camlidl_GetTypeInfo(struct camlidl_intf * self, UINT iTypeInfo,
LCID localization, ITypeInfo ** res)
{
HRESULT hr;
int i;
ITypeInfo * tinfo;
if (iTypeInfo != 0) {
*res = NULL;
return DISP_E_BADINDEX;
}
tinfo = (ITypeInfo *) self->typeinfo;
/* Increase refcount of type info object */
tinfo->lpVtbl->AddRef(tinfo);
/* Return tinfo */
*res = tinfo;
return S_OK;
}
/* Find the dispatch IDs of the given method names */
HRESULT STDMETHODCALLTYPE
camlidl_GetIDsOfNames(struct camlidl_intf * self, REFIID iid,
OLECHAR** arrayNames, UINT countNames,
LCID localization, DISPID * arrayDispIDs)
{
ITypeInfo * tinfo;
if (! IsEqualIID(iid, &IID_NULL)) return DISP_E_UNKNOWNINTERFACE;
tinfo = (ITypeInfo *) self->typeinfo;
return tinfo->lpVtbl->GetIDsOfNames(tinfo, arrayNames,
countNames, arrayDispIDs);
}
/* Invoke a method by dynamic dispatch */
HRESULT STDMETHODCALLTYPE
camlidl_Invoke(struct camlidl_intf * self, DISPID dispidMember, REFIID iid,
LCID localization, WORD wFlags, DISPPARAMS * dispParams,
VARIANT * varResult, EXCEPINFO * excepInfo, UINT * argErr)
{
ITypeInfo * tinfo;
if (! IsEqualIID(iid, &IID_NULL)) return DISP_E_UNKNOWNINTERFACE;
tinfo = (ITypeInfo *) self->typeinfo;
SetErrorInfo(0, NULL);
return tinfo->lpVtbl->Invoke(tinfo, (IDispatch *) self,
dispidMember, wFlags, dispParams,
varResult, excepInfo, argErr);
}
/* Load the type info library for the object and store it in the
typeinfo field of the object */
static int camlidl_num_type_libraries = 0;
static void camlidl_read_num_type_libraries(void);
IUnknown * camlidl_find_typeinfo(IID * iid)
{
ITypeLib * tlib;
ITypeInfo * tinfo;
char module_path[_MAX_PATH];
char resname[_MAX_PATH + 4];
wchar_t wresname[_MAX_PATH + 4];
int i;
HRESULT hr;
/* Determine number of type libraries available (if not already done) */
if (camlidl_num_type_libraries == 0) camlidl_read_num_type_libraries();
/* Get the full name of the executable */
GetModuleFileName(camlidl_module_handle, module_path, _MAX_PATH);
/* Load the type libraries and query them */
for (i = 1; i <= camlidl_num_type_libraries; i++) {
/* Build the wide string <module_path>\<i> */
sprintf(resname, "%s\\%d", module_path, i);
mbstowcs(wresname, resname, _MAX_PATH + 4);
/* Load the type library */
hr = LoadTypeLib(wresname, &tlib);
if (FAILED(hr))
camlidl_error(hr, "Com.create_dispatch", "Cannot load type library");
/* Query the type library for the type info for the object */
hr = tlib->lpVtbl->GetTypeInfoOfGuid(tlib, iid, &tinfo);
/* Release the library */
tlib->lpVtbl->Release(tlib);
if (SUCCEEDED(hr)) return (IUnknown *) tinfo;
}
/* Not found: raise an exception */
camlidl_error(TYPE_E_ELEMENTNOTFOUND, "Com.make_",
"Cannot find type library for interface");
return NULL; /* not reached */
}
static void camlidl_read_num_type_libraries(void)
{
HRSRC hFound;
HGLOBAL hRes;
void * lpBuff;
hFound = FindResource(camlidl_module_handle, (char *)1, "num_typelibs");
if (hFound == NULL)
camlidl_error(0, "Com.make_", "Cannot find resource num_typelibs");
hRes = LoadResource(camlidl_module_handle, hFound);
if (hRes == NULL)
camlidl_error(0, "Com.make_", "Cannot load resource num_typelibs");
lpBuff = LockResource(hRes);
camlidl_num_type_libraries = *((WORD *) lpBuff);
UnlockResource(hRes);
FreeResource(hRes);
}
|