Subject: winex/dlls/oleaut32 proxy.c,1.9,1.10Update of /var/lib/cvsd/cvsroot/winex/dlls/oleaut32
In directory agravaine:/tmp/cvs-serv31037/dlls/oleaut32
Modified Files:
proxy.c
Log Message:
Attempt to handle TKIND_DISPATCH in typelib-based COM proxies/stubs.
Index: proxy.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/oleaut32/proxy.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- proxy.c 27 Jun 2004 02:56:22 -0000 1.9
+++ proxy.c 27 Apr 2007 13:12:42 -0000 1.10
@@ -662,6 +662,51 @@
return S_OK;
}
+static HRESULT TL_GetInterface(LPTYPEINFO *ppInfo, TYPEKIND *kind)
+{
+ LPTYPEATTR pAttr;
+ IID iid;
+ HRESULT hr;
+
+ hr = ITypeInfo_GetTypeAttr(*ppInfo, &pAttr);
+ if (FAILED(hr)) {
+ ERR("could not get type attr for interface\n");
+ return hr;
+ }
+ memcpy(&iid, &pAttr->guid, sizeof(iid));
+ *kind = pAttr->typekind;
+ ITypeInfo_ReleaseTypeAttr(*ppInfo, pAttr);
+
+ if (*kind == TKIND_DISPATCH) {
+ HREFTYPE hType;
+ /* if this is a dual interface, look for TKIND_INTERFACE part,
+ * otherwise just return the dispinterface */
+ hr = ITypeInfo_GetRefTypeOfImplType(*ppInfo, -1, &hType);
+ if (SUCCEEDED(hr)) {
+ LPTYPEINFO pDInfo;
+ hr = ITypeInfo_GetRefTypeInfo(*ppInfo, hType, &pDInfo);
+ if (SUCCEEDED(hr)) {
+ TRACE("using real interface (%ld) for IID %s\n", hType, debugstr_guid(&iid));
+ ITypeInfo_Release(*ppInfo);
+ *ppInfo = pDInfo;
+ /* this is supposed to be is an interface.. */
+ *kind = TKIND_INTERFACE;
+ } else {
+ TRACE("failed to locate real interface (%ld) for IID %s\n", hType, debugstr_guid(&iid));
+ }
+ } else {
+ TRACE("no real interface for IID %s\n", debugstr_guid(&iid));
+ }
+ } else
+ if (*kind != TKIND_INTERFACE) {
+ ERR("invalid type kind %d for IID %s\n", *kind, debugstr_guid(&iid));
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+
/******************** STUB ********************/
/* FIXME: should layer on top of rpcrt4 */
@@ -968,6 +1013,8 @@
PSOAProxyImpl *This = VTBL_UPCAST(PSOAProxyImpl,iface);
TRACE("(%p)->Release()\n",This);
if (!--(This->ref)) {
+ /* FIXME: we may be leaking memory here; */
+ /* should deallocate vtbl and release typeinfo */
HeapFree(GetProcessHeap(),0,This);
return 0;
}
@@ -1168,8 +1215,7 @@
types = pAttr->cImplTypes;
funcs = pAttr->cFuncs;
ITypeInfo_ReleaseTypeAttr(pInfo, pAttr);
- /* FIXME: we could handle TKIND_DISPATCH by looking for
- * its associated TKIND_INTERFACE with GetRefTypeOfImplType */
+
if (kind != TKIND_INTERFACE) {
ERR("invalid type kind %d for IID %s\n", kind, debugstr_guid(&iid));
return NULL;
@@ -1293,6 +1339,9 @@
/*******************************************************************************
* PSOAFactoryBuffer
*/
+extern const CLSID CLSID_PSDispatch;
+extern HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
+
static HRESULT WINAPI PSOAFactory_QueryInterface(LPPSFACTORYBUFFER iface,
REFIID riid,
LPVOID *obj) {
@@ -1329,11 +1378,30 @@
debugstr_guid(riid),ppProxy,ppv);
hr = OA_LoadInterfaceTypeLib(riid, &pTlib);
if (SUCCEEDED(hr)) {
+ TYPEKIND kind;
hr = ITypeLib_GetTypeInfoOfGuid(pTlib, riid, &pInfo);
ITypeLib_Release(pTlib);
if (FAILED(hr)) {
return E_FAIL;
}
+ hr = TL_GetInterface(&pInfo, &kind);
+ if (FAILED(hr)) {
+ ITypeInfo_Release(pInfo);
+ return hr;
+ }
+
+ if (kind == TKIND_DISPATCH) {
+ /* create standard IDispatch proxy */
+ LPPSFACTORYBUFFER pPS;
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (LPVOID *)&pPS);
+ if (SUCCEEDED(hr)) {
+ hr = IPSFactoryBuffer_CreateProxy(pPS, pUnkOuter, &IID_IDispatch, ppProxy, ppv);
+ IPSFactoryBuffer_Release(pPS);
+ }
+ ITypeInfo_Release(pInfo);
+ return hr;
+ }
+
proxy = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PSOAProxyImpl));
if (!proxy) {
ITypeInfo_Release(pInfo);
@@ -1366,11 +1434,30 @@
pUnkServer,ppStub);
hr = OA_LoadInterfaceTypeLib(riid, &pTlib);
if (SUCCEEDED(hr)) {
+ TYPEKIND kind;
hr = ITypeLib_GetTypeInfoOfGuid(pTlib, riid, &pInfo);
ITypeLib_Release(pTlib);
if (FAILED(hr)) {
return E_FAIL;
}
+ hr = TL_GetInterface(&pInfo, &kind);
+ if (FAILED(hr)) {
+ ITypeInfo_Release(pInfo);
+ return hr;
+ }
+
+ if (kind == TKIND_DISPATCH) {
+ /* create standard IDispatch stub */
+ LPPSFACTORYBUFFER pPS;
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (LPVOID *)&pPS);
+ if (SUCCEEDED(hr)) {
+ hr = IPSFactoryBuffer_CreateStub(pPS, &IID_IDispatch, pUnkServer, ppStub);
+ IPSFactoryBuffer_Release(pPS);
+ }
+ ITypeInfo_Release(pInfo);
+ return hr;
+ }
+
stub = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PSOAStubImpl));
if (!stub) {
ITypeInfo_Release(pInfo);
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.