From 73d3df3e280cf1bae4af6caa3585ee24a288edaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Sat, 14 Aug 2004 20:00:59 +0000 Subject: [PATCH] Sync to Wine-20040813: Alexandre Julliard - Avoid some non-portable makefile constructs, and get rid of the ALTNAMES variable. - Get rid of the non-standard ICOM_VTABLE macro. - Get rid of the non-standard ICOM_VFIELD macro. - Get rid of the non-standard ICOM_DEFINE macro. - Moved ICOM_THIS_MULTI definition out of objbase.h and into the files that use it. Mike McCormack - Added a test for stat'ing a memory based storage file. - stat on memory storage should return a NULL name, not "". Francois Gouget - Assorted spelling fixes. - Modify widl to put the C COM macros inside an #ifdef COBJMACROS block as is done in the Windows headers. - Add #define COBJMACROS where needed in Wine. - Fixes the compilation of the oleaut32/tests/olefont.c and urlmon/tests/url.c conformance tests with the Windows headers. Mike Hearn - Implement disconnect for proxies so that stubs are properly destroyed. - Disconnect proxies at COM shutdown to release the corresponding stubs. - Don't marshal IClassFactory into the local server pipe until we have connected, otherwise we might end up with stubs that are never used. - Pass -Embedding switch to EXE servers, more tracing. - Fix misleading warning ole CoGetClassObject. - Fix ref counting in StdMarshalImpl_MarshalInterface for case where the stub already exists. - Implement StdMarshal::ReleaseMarshalData. - Fix infinite loops by checking the return value of _invoke_onereq and bailing appropriately. - Add a comment on the SendReceive behaviour. Improve two others. - Unref stub after invoking on it. Robert Shearman - Remove unneeded STUBMGR_Start call. - Cleanup compobj_private.h. - Fix some inaccuracies in a comment and reformat. - Add static to non-exported marshal functions. - Remove unused marshal functions. - Rename several RPC functions. - Emit fixme for known local wrong behaviour. - Implement StdMarshal::ReleaseMarshalData. - Document wrong behaviour for IRunningObjectTable. - Fix infinite loops by checking the return value of _invoke_onereq and bailing appropriately. - Add a comment on the SendReceive behaviour. Improve two others. - Set RPC data representation. Jeroen Janssen - Updated some MSDN links in the code. svn path=/trunk/; revision=10535 --- reactos/lib/ole32/Makefile.in | 14 +- reactos/lib/ole32/antimoniker.c | 8 +- reactos/lib/ole32/bindctx.c | 6 +- reactos/lib/ole32/clipboard.c | 8 +- reactos/lib/ole32/compobj.c | 96 ++++++++------ reactos/lib/ole32/compobj_private.h | 51 +------- reactos/lib/ole32/compositemoniker.c | 12 +- reactos/lib/ole32/datacache.c | 24 ++-- reactos/lib/ole32/defaulthandler.c | 16 +-- reactos/lib/ole32/errorinfo.c | 20 +-- reactos/lib/ole32/filemoniker.c | 10 +- reactos/lib/ole32/ftmarshal.c | 8 +- reactos/lib/ole32/git.c | 8 +- reactos/lib/ole32/hglobalstream.c | 4 +- reactos/lib/ole32/ifs.c | 12 +- reactos/lib/ole32/ifs.h | 18 +-- reactos/lib/ole32/itemmoniker.c | 8 +- reactos/lib/ole32/marshal.c | 144 ++++++++++++++------- reactos/lib/ole32/memlockbytes.c | 4 +- reactos/lib/ole32/memlockbytes16.c | 6 +- reactos/lib/ole32/moniker.c | 30 ++++- reactos/lib/ole32/ole16.c | 8 +- reactos/lib/ole32/oleobj.c | 8 +- reactos/lib/ole32/oleproxy.c | 29 ++--- reactos/lib/ole32/rpc.c | 187 +++++++++++++++++++++------ reactos/lib/ole32/stg_stream.c | 2 +- reactos/lib/ole32/storage.c | 20 +-- reactos/lib/ole32/storage32.c | 10 +- reactos/lib/ole32/storage32.h | 14 +- reactos/lib/ole32/winehq2ros.patch | 61 +++++++-- 30 files changed, 519 insertions(+), 327 deletions(-) diff --git a/reactos/lib/ole32/Makefile.in b/reactos/lib/ole32/Makefile.in index 88c379e45e9..1bbe808ad65 100644 --- a/reactos/lib/ole32/Makefile.in +++ b/reactos/lib/ole32/Makefile.in @@ -5,11 +5,8 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = ole32.dll IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll -ALTNAMES = ole2.dll ole2nls.dll ole2conv.dll ole2prox.dll ole2thk.dll storage.dll compobj.dll EXTRALIBS = -luuid -SPEC_SRCS16 = $(ALTNAMES:.dll=.spec) - C_SRCS = \ antimoniker.c \ bindctx.c \ @@ -47,6 +44,15 @@ C_SRCS16 = \ ole2nls.c \ storage.c +SPEC_SRCS16 = \ + compobj.spec \ + ole2.spec \ + ole2conv.spec \ + ole2nls.spec \ + ole2prox.spec \ + ole2thk.spec \ + storage.spec + RC_SRCS = ole32res.rc version.rc RC_BINSRC = ole32res.rc RC_BINARIES = \ @@ -55,6 +61,8 @@ RC_BINARIES = \ drag_move.cur \ nodrop.cur +SUBDIRS = tests + @MAKE_DLL_RULES@ ### Dependencies: diff --git a/reactos/lib/ole32/antimoniker.c b/reactos/lib/ole32/antimoniker.c index f323ef49aa5..c664cb5922d 100644 --- a/reactos/lib/ole32/antimoniker.c +++ b/reactos/lib/ole32/antimoniker.c @@ -41,12 +41,12 @@ const CLSID CLSID_AntiMoniker = { /* AntiMoniker data structure */ typedef struct AntiMonikerImpl{ - ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/ /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether * two monikers are equal. That's whay IROTData interface is implemented by monikers. */ - ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/ ULONG ref; /* reference counter for this object */ @@ -104,7 +104,7 @@ HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* iface); /********************************************************************************/ /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/ /* IPersistStream and IMoniker functions. */ -static ICOM_VTABLE(IMoniker) VT_AntiMonikerImpl = +static IMonikerVtbl VT_AntiMonikerImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE AntiMonikerImpl_QueryInterface, @@ -134,7 +134,7 @@ static ICOM_VTABLE(IMoniker) VT_AntiMonikerImpl = /********************************************************************************/ /* Virtual function table for the IROTData class. */ -static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +static IROTDataVtbl VT_ROTDataImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE AntiMonikerROTDataImpl_QueryInterface, diff --git a/reactos/lib/ole32/bindctx.c b/reactos/lib/ole32/bindctx.c index 73b8ffb4f97..19642b0de68 100644 --- a/reactos/lib/ole32/bindctx.c +++ b/reactos/lib/ole32/bindctx.c @@ -48,7 +48,7 @@ typedef struct BindCtxObject{ /* BindCtx data strucrture */ typedef struct BindCtxImpl{ - ICOM_VFIELD(IBindCtx); /* VTable relative to the IBindCtx interface.*/ + IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/ ULONG ref; /* reference counter for this object */ @@ -83,7 +83,7 @@ HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This); HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,IUnknown* punk,LPOLESTR pszkey,DWORD *index); /* Virtual function table for the BindCtx class. */ -static ICOM_VTABLE(IBindCtx) VT_BindCtxImpl = +static IBindCtxVtbl VT_BindCtxImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE BindCtxImpl_QueryInterface, @@ -269,7 +269,7 @@ HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk) TRACE("(%p,%p)\n",This,punk); - /* check if the object was registred or not */ + /* check if the object was registered or not */ if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE) return MK_E_NOTBOUND; diff --git a/reactos/lib/ole32/clipboard.c b/reactos/lib/ole32/clipboard.c index 0bee6453d7e..6a58127bfed 100644 --- a/reactos/lib/ole32/clipboard.c +++ b/reactos/lib/ole32/clipboard.c @@ -94,7 +94,7 @@ struct OLEClipbrd /* * List all interface VTables here */ - ICOM_VTABLE(IDataObject)* lpvtbl1; /* IDataObject VTable */ + IDataObjectVtbl* lpvtbl1; /* IDataObject VTable */ /* * The hidden OLE clipboard window. This window is used as the bridge between the @@ -133,7 +133,7 @@ typedef struct OLEClipbrd OLEClipbrd; typedef struct { /* IEnumFORMATETC VTable */ - ICOM_VFIELD(IEnumFORMATETC); + IEnumFORMATETCVtbl *lpVtbl; /* IEnumFORMATETC fields */ UINT posFmt; /* current enumerator position */ @@ -248,7 +248,7 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Clone(LPENUMFORMATETC iface, LPE /* * Virtual function table for the OLEClipbrd's exposed IDataObject interface */ -static ICOM_VTABLE(IDataObject) OLEClipbrd_IDataObject_VTable = +static IDataObjectVtbl OLEClipbrd_IDataObject_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE OLEClipbrd_IDataObject_QueryInterface, @@ -268,7 +268,7 @@ static ICOM_VTABLE(IDataObject) OLEClipbrd_IDataObject_VTable = /* * Virtual function table for IEnumFORMATETC interface */ -static struct ICOM_VTABLE(IEnumFORMATETC) efvt = +static struct IEnumFORMATETCVtbl efvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE OLEClipbrd_IEnumFORMATETC_QueryInterface, diff --git a/reactos/lib/ole32/compobj.c b/reactos/lib/ole32/compobj.c index 96cc86e8901..685715620f5 100644 --- a/reactos/lib/ole32/compobj.c +++ b/reactos/lib/ole32/compobj.c @@ -152,12 +152,13 @@ void COMPOBJ_InitProcess( void ) { WNDCLASSA wclass; - /* Inter-thread RPCs are done through window messages rather than pipes. When - an interface is marshalled into another apartment in the same process, - a window of the following class is created. The *caller* of CoMarshalInterface - (ie the application) is responsible for pumping the message loop in that thread, - the WM_USER messages which point to the RPCs are then dispatched to COM_AptWndProc - by the users code. + /* Dispatching to the correct thread in an apartment is done through + * window messages rather than RPC transports. When an interface is + * marshalled into another apartment in the same process, a window of the + * following class is created. The *caller* of CoMarshalInterface (ie the + * application) is responsible for pumping the message loop in that thread. + * The WM_USER messages which point to the RPCs are then dispatched to + * COM_AptWndProc by the user's code. */ memset(&wclass, 0, sizeof(wclass)); wclass.lpfnWndProc = &COM_AptWndProc; @@ -511,6 +512,11 @@ void WINAPI CoUninitialize(void) RunningObjectTableImpl_UnInitialize(); + /* disconnect proxies to release the corresponding stubs. + * FIXME: native version might not do this and we might just be working + * around bugs elsewhere. */ + MARSHAL_Disconnect_Proxies(); + /* Release the references to the registered class objects */ COM_RevokeAllClasses(); @@ -903,6 +909,7 @@ HRESULT WINAPI CoGetPSClsid( /* Open the key.. */ if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey)) { + WARN("No PSFactoryBuffer object is registered for this IID\n"); HeapFree(GetProcessHeap(),0,buf); return (E_INVALIDARG); } @@ -1059,41 +1066,10 @@ _LocalServerThread(LPVOID param) { ULONG res; TRACE("Starting threader for %s.\n",debugstr_guid(&newClass->classIdentifier)); + strcpy(pipefn,PIPEPREF); WINE_StringFromCLSID(&newClass->classIdentifier,pipefn+strlen(PIPEPREF)); - hres = IUnknown_QueryInterface(newClass->classObject,&IID_IClassFactory,(LPVOID*)&classfac); - if (hres) return hres; - - hres = CreateStreamOnHGlobal(0,TRUE,&pStm); - if (hres) { - FIXME("Failed to create stream on hglobal.\n"); - return hres; - } - hres = CoMarshalInterface(pStm,&IID_IClassFactory,(LPVOID)classfac,0,NULL,0); - if (hres) { - FIXME("CoMarshalInterface failed, %lx!\n",hres); - return hres; - } - hres = IStream_Stat(pStm,&ststg,0); - if (hres) return hres; - - buflen = ststg.cbSize.u.LowPart; - buffer = HeapAlloc(GetProcessHeap(),0,buflen); - seekto.u.LowPart = 0; - seekto.u.HighPart = 0; - hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); - if (hres) { - FIXME("IStream_Seek failed, %lx\n",hres); - return hres; - } - hres = IStream_Read(pStm,buffer,buflen,&res); - if (hres) { - FIXME("Stream Read failed, %lx\n",hres); - return hres; - } - IStream_Release(pStm); - hPipe = CreateNamedPipeA( pipefn, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT, NULL ); @@ -1106,9 +1082,51 @@ _LocalServerThread(LPVOID param) { ERR("Failure during ConnectNamedPipe %lx, ABORT!\n",GetLastError()); break; } + + TRACE("marshalling IClassFactory to client\n"); + + hres = IUnknown_QueryInterface(newClass->classObject,&IID_IClassFactory,(LPVOID*)&classfac); + if (hres) return hres; + + hres = CreateStreamOnHGlobal(0,TRUE,&pStm); + if (hres) { + FIXME("Failed to create stream on hglobal.\n"); + return hres; + } + hres = CoMarshalInterface(pStm,&IID_IClassFactory,(LPVOID)classfac,0,NULL,0); + if (hres) { + FIXME("CoMarshalInterface failed, %lx!\n",hres); + return hres; + } + + IUnknown_Release(classfac); /* is this right? */ + + hres = IStream_Stat(pStm,&ststg,0); + if (hres) return hres; + + buflen = ststg.cbSize.u.LowPart; + buffer = HeapAlloc(GetProcessHeap(),0,buflen); + seekto.u.LowPart = 0; + seekto.u.HighPart = 0; + hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); + if (hres) { + FIXME("IStream_Seek failed, %lx\n",hres); + return hres; + } + + hres = IStream_Read(pStm,buffer,buflen,&res); + if (hres) { + FIXME("Stream Read failed, %lx\n",hres); + return hres; + } + + IStream_Release(pStm); + WriteFile(hPipe,buffer,buflen,&res,NULL); FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); + + TRACE("done marshalling IClassFactory\n"); } CloseHandle(hPipe); return 0; @@ -1352,7 +1370,7 @@ HRESULT WINAPI CoGetClassObject( if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) { /* failure: CLSID is not found in registry */ - WARN("class %s not registred\n", xclsid); + WARN("class %s not registered inproc\n", xclsid); hres = REGDB_E_CLASSNOTREG; } else { if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) { diff --git a/reactos/lib/ole32/compobj_private.h b/reactos/lib/ole32/compobj_private.h index b316636c2c9..ee4e33b4c58 100644 --- a/reactos/lib/ole32/compobj_private.h +++ b/reactos/lib/ole32/compobj_private.h @@ -55,7 +55,7 @@ typedef struct tagXIF { /* exported object */ typedef struct tagXOBJECT { - ICOM_VTABLE(IRpcStubBuffer) *lpVtbl; + IRpcStubBufferVtbl *lpVtbl; struct tagAPARTMENT *parent; struct tagXOBJECT *next; LPUNKNOWN obj; /* object identity (IUnknown) */ @@ -78,7 +78,7 @@ typedef struct tagIIF { /* imported object */ typedef struct tagIOBJECT { - ICOM_VTABLE(IRemUnknown) *lpVtbl; + IRemUnknownVtbl *lpVtbl; struct tagAPARTMENT *parent; struct tagIOBJECT *next; LPRPCCHANNELBUFFER chan; /* channel to object */ @@ -118,18 +118,9 @@ extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) extern void* StdGlobalInterfaceTableInstance; -inline static HRESULT -get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) { - HRESULT hres; - CLSID pxclsid; - - if ((hres = CoGetPSClsid(riid,&pxclsid))) - return hres; - return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf); -} - #define PIPEPREF "\\\\.\\pipe\\" #define OLESTUBMGR PIPEPREF"WINE_OLE_StubMgr" + /* Standard Marshalling definitions */ typedef struct _wine_marshal_id { DWORD processid; @@ -156,41 +147,11 @@ MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) { } HRESULT MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub); -HRESULT MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk); -HRESULT MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN punk, IRpcStubBuffer *stub); +void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid); +HRESULT MARSHAL_Disconnect_Proxies(); HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv); -typedef struct _wine_marshal_data { - DWORD dwDestContext; - DWORD mshlflags; -} wine_marshal_data; - - -#define REQTYPE_REQUEST 0 -typedef struct _wine_rpc_request_header { - DWORD reqid; - wine_marshal_id mid; - DWORD iMethod; - DWORD cbBuffer; -} wine_rpc_request_header; - -#define REQTYPE_RESPONSE 1 -typedef struct _wine_rpc_response_header { - DWORD reqid; - DWORD cbBuffer; - DWORD retval; -} wine_rpc_response_header; - -#define REQSTATE_START 0 -#define REQSTATE_REQ_QUEUED 1 -#define REQSTATE_REQ_WAITING_FOR_REPLY 2 -#define REQSTATE_REQ_GOT 3 -#define REQSTATE_INVOKING 4 -#define REQSTATE_RESP_QUEUED 5 -#define REQSTATE_RESP_GOT 6 -#define REQSTATE_DONE 6 - void STUBMGR_Start(); extern HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf); @@ -228,4 +189,6 @@ static inline APARTMENT* COM_CurrentApt(void) APARTMENT* COM_CreateApartment(DWORD model); HWND COM_GetApartmentWin(OXID oxid); +#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) + #endif /* __WINE_OLE_COMPOBJ_H */ diff --git a/reactos/lib/ole32/compositemoniker.c b/reactos/lib/ole32/compositemoniker.c index 6cc0c63e533..5743ef4f61e 100644 --- a/reactos/lib/ole32/compositemoniker.c +++ b/reactos/lib/ole32/compositemoniker.c @@ -44,13 +44,13 @@ const CLSID CLSID_CompositeMoniker = { /* CompositeMoniker data structure */ typedef struct CompositeMonikerImpl{ - ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/ /* The ROT (RunningObjectTable implementation) uses the IROTData * interface to test whether two monikers are equal. That's why IROTData * interface is implemented by monikers. */ - ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/ ULONG ref; /* reference counter for this object */ @@ -66,7 +66,7 @@ typedef struct CompositeMonikerImpl{ /* EnumMoniker data structure */ typedef struct EnumMonikerImpl{ - ICOM_VFIELD(IEnumMoniker); /* VTable relative to the IEnumMoniker interface.*/ + IEnumMonikerVtbl *lpVtbl; /* VTable relative to the IEnumMoniker interface.*/ ULONG ref; /* reference counter for this object */ @@ -148,7 +148,7 @@ HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tab /* Virtual function table for the CompositeMonikerImpl class which includes */ /* IPersist, IPersistStream and IMoniker functions. */ -static ICOM_VTABLE(IMoniker) VT_CompositeMonikerImpl = +static IMonikerVtbl VT_CompositeMonikerImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE CompositeMonikerImpl_QueryInterface, @@ -178,7 +178,7 @@ static ICOM_VTABLE(IMoniker) VT_CompositeMonikerImpl = /********************************************************************************/ /* Virtual function table for the IROTData class. */ -static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +static IROTDataVtbl VT_ROTDataImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE CompositeMonikerROTDataImpl_QueryInterface, @@ -189,7 +189,7 @@ static ICOM_VTABLE(IROTData) VT_ROTDataImpl = /********************************************************************************/ /* Virtual function table for the IROTData class */ -static ICOM_VTABLE(IEnumMoniker) VT_EnumMonikerImpl = +static IEnumMonikerVtbl VT_EnumMonikerImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE EnumMonikerImpl_QueryInterface, diff --git a/reactos/lib/ole32/datacache.c b/reactos/lib/ole32/datacache.c index c7cdec28038..75ff0d259a5 100644 --- a/reactos/lib/ole32/datacache.c +++ b/reactos/lib/ole32/datacache.c @@ -91,12 +91,12 @@ struct DataCache /* * List all interface VTables here */ - ICOM_VTABLE(IDataObject)* lpvtbl1; - ICOM_VTABLE(IUnknown)* lpvtbl2; - ICOM_VTABLE(IPersistStorage)* lpvtbl3; - ICOM_VTABLE(IViewObject2)* lpvtbl4; - ICOM_VTABLE(IOleCache2)* lpvtbl5; - ICOM_VTABLE(IOleCacheControl)* lpvtbl6; + IDataObjectVtbl* lpvtbl1; + IUnknownVtbl* lpvtbl2; + IPersistStorageVtbl* lpvtbl3; + IViewObject2Vtbl* lpvtbl4; + IOleCache2Vtbl* lpvtbl5; + IOleCacheControlVtbl* lpvtbl6; /* * Reference count of this object @@ -373,7 +373,7 @@ static HRESULT WINAPI DataCache_OnStop( /* * Virtual function tables for the DataCache class. */ -static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable = +static IUnknownVtbl DataCache_NDIUnknown_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_NDIUnknown_QueryInterface, @@ -381,7 +381,7 @@ static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable = DataCache_NDIUnknown_Release }; -static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable = +static IDataObjectVtbl DataCache_IDataObject_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_IDataObject_QueryInterface, @@ -398,7 +398,7 @@ static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable = DataCache_EnumDAdvise }; -static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable = +static IPersistStorageVtbl DataCache_IPersistStorage_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_IPersistStorage_QueryInterface, @@ -413,7 +413,7 @@ static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable = DataCache_HandsOffStorage }; -static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable = +static IViewObject2Vtbl DataCache_IViewObject2_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_IViewObject2_QueryInterface, @@ -428,7 +428,7 @@ static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable = DataCache_GetExtent }; -static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable = +static IOleCache2Vtbl DataCache_IOleCache2_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_IOleCache2_QueryInterface, @@ -443,7 +443,7 @@ static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable = DataCache_DiscardCache }; -static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable = +static IOleCacheControlVtbl DataCache_IOleCacheControl_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataCache_IOleCacheControl_QueryInterface, diff --git a/reactos/lib/ole32/defaulthandler.c b/reactos/lib/ole32/defaulthandler.c index 5286dad542b..6964f15334a 100644 --- a/reactos/lib/ole32/defaulthandler.c +++ b/reactos/lib/ole32/defaulthandler.c @@ -68,10 +68,10 @@ struct DefaultHandler /* * List all interface VTables here */ - ICOM_VTABLE(IOleObject)* lpvtbl1; - ICOM_VTABLE(IUnknown)* lpvtbl2; - ICOM_VTABLE(IDataObject)* lpvtbl3; - ICOM_VTABLE(IRunnableObject)* lpvtbl4; + IOleObjectVtbl* lpvtbl1; + IUnknownVtbl* lpvtbl2; + IDataObjectVtbl* lpvtbl3; + IRunnableObjectVtbl* lpvtbl4; /* * Reference count of this object @@ -323,7 +323,7 @@ static HRESULT WINAPI DefaultHandler_SetContainedObject( /* * Virtual function tables for the DefaultHandler class. */ -static ICOM_VTABLE(IOleObject) DefaultHandler_IOleObject_VTable = +static IOleObjectVtbl DefaultHandler_IOleObject_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DefaultHandler_QueryInterface, @@ -352,7 +352,7 @@ static ICOM_VTABLE(IOleObject) DefaultHandler_IOleObject_VTable = DefaultHandler_SetColorScheme }; -static ICOM_VTABLE(IUnknown) DefaultHandler_NDIUnknown_VTable = +static IUnknownVtbl DefaultHandler_NDIUnknown_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DefaultHandler_NDIUnknown_QueryInterface, @@ -360,7 +360,7 @@ static ICOM_VTABLE(IUnknown) DefaultHandler_NDIUnknown_VTable = DefaultHandler_NDIUnknown_Release, }; -static ICOM_VTABLE(IDataObject) DefaultHandler_IDataObject_VTable = +static IDataObjectVtbl DefaultHandler_IDataObject_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DefaultHandler_IDataObject_QueryInterface, @@ -377,7 +377,7 @@ static ICOM_VTABLE(IDataObject) DefaultHandler_IDataObject_VTable = DefaultHandler_EnumDAdvise }; -static ICOM_VTABLE(IRunnableObject) DefaultHandler_IRunnableObject_VTable = +static IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DefaultHandler_IRunnableObject_QueryInterface, diff --git a/reactos/lib/ole32/errorinfo.c b/reactos/lib/ole32/errorinfo.c index a946f4516d0..e24d9ca36e4 100644 --- a/reactos/lib/ole32/errorinfo.c +++ b/reactos/lib/ole32/errorinfo.c @@ -26,6 +26,8 @@ #include #include +#define COBJMACROS + #include "windef.h" #include "winbase.h" #include "oleauto.h" @@ -127,9 +129,9 @@ static VOID WINAPI ERRORINFO_SysFreeString(BSTR in) typedef struct ErrorInfoImpl { - ICOM_VTABLE(IErrorInfo) *lpvtei; - ICOM_VTABLE(ICreateErrorInfo) *lpvtcei; - ICOM_VTABLE(ISupportErrorInfo) *lpvtsei; + IErrorInfoVtbl *lpvtei; + ICreateErrorInfoVtbl *lpvtcei; + ISupportErrorInfoVtbl *lpvtsei; DWORD ref; GUID m_Guid; @@ -139,9 +141,9 @@ typedef struct ErrorInfoImpl DWORD m_dwHelpContext; } ErrorInfoImpl; -static ICOM_VTABLE(IErrorInfo) IErrorInfoImpl_VTable; -static ICOM_VTABLE(ICreateErrorInfo) ICreateErrorInfoImpl_VTable; -static ICOM_VTABLE(ISupportErrorInfo) ISupportErrorInfoImpl_VTable; +static IErrorInfoVtbl IErrorInfoImpl_VTable; +static ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable; +static ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable; /* converts a objectpointer to This @@ -300,7 +302,7 @@ static HRESULT WINAPI IErrorInfoImpl_GetHelpContext( return S_OK; } -static ICOM_VTABLE(IErrorInfo) IErrorInfoImpl_VTable = +static IErrorInfoVtbl IErrorInfoImpl_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IErrorInfoImpl_QueryInterface, @@ -402,7 +404,7 @@ static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext( return S_OK; } -static ICOM_VTABLE(ICreateErrorInfo) ICreateErrorInfoImpl_VTable = +static ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ICreateErrorInfoImpl_QueryInterface, @@ -453,7 +455,7 @@ static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo( return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE; } -static ICOM_VTABLE(ISupportErrorInfo) ISupportErrorInfoImpl_VTable = +static ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ISupportErrorInfoImpl_QueryInterface, diff --git a/reactos/lib/ole32/filemoniker.c b/reactos/lib/ole32/filemoniker.c index 0beaca26609..e55068d22d6 100644 --- a/reactos/lib/ole32/filemoniker.c +++ b/reactos/lib/ole32/filemoniker.c @@ -44,12 +44,12 @@ const CLSID CLSID_FileMoniker = { /* filemoniker data structure */ typedef struct FileMonikerImpl{ - ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/ /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether * two monikers are equal. That's whay IROTData interface is implemented by monikers. */ - ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/ ULONG ref; /* reference counter for this object */ @@ -111,7 +111,7 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** tabStr); /********************************************************************************/ /* Virtual function table for the FileMonikerImpl class which include IPersist,*/ /* IPersistStream and IMoniker functions. */ -static ICOM_VTABLE(IMoniker) VT_FileMonikerImpl = +static IMonikerVtbl VT_FileMonikerImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE FileMonikerImpl_QueryInterface, @@ -141,7 +141,7 @@ static ICOM_VTABLE(IMoniker) VT_FileMonikerImpl = /********************************************************************************/ /* Virtual function table for the IROTData class. */ -static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +static IROTDataVtbl VT_ROTDataImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE FileMonikerROTDataImpl_QueryInterface, @@ -983,7 +983,7 @@ HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, res= IRunningObjectTable_GetTimeOfLastChange(rot,iface,pFileTime); - if (FAILED(res)){ /* the moniker is not registred */ + if (FAILED(res)){ /* the moniker is not registered */ if (!GetFileAttributesExW(This->filePathName,GetFileExInfoStandard,&info)) return MK_E_NOOBJECT; diff --git a/reactos/lib/ole32/ftmarshal.c b/reactos/lib/ole32/ftmarshal.c index d0e39f09444..e6484167859 100644 --- a/reactos/lib/ole32/ftmarshal.c +++ b/reactos/lib/ole32/ftmarshal.c @@ -35,9 +35,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); typedef struct _FTMarshalImpl { - ICOM_VFIELD (IUnknown); + IUnknownVtbl *lpVtbl; DWORD ref; - ICOM_VTABLE (IMarshal) * lpvtblFTM; + IMarshalVtbl *lpvtblFTM; IUnknown *pUnkOuter; } FTMarshalImpl; @@ -90,7 +90,7 @@ ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface) return 0; } -static ICOM_VTABLE (IUnknown) iunkvt = +static IUnknownVtbl iunkvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IiFTMUnknown_fnQueryInterface, @@ -201,7 +201,7 @@ HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved return S_OK; } -ICOM_VTABLE (IMarshal) ftmvtbl = +IMarshalVtbl ftmvtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE FTMarshalImpl_QueryInterface, diff --git a/reactos/lib/ole32/git.c b/reactos/lib/ole32/git.c index c343d3709fb..7581155c348 100644 --- a/reactos/lib/ole32/git.c +++ b/reactos/lib/ole32/git.c @@ -70,7 +70,7 @@ typedef struct StdGITEntry /* Class data */ typedef struct StdGlobalInterfaceTableImpl { - ICOM_VFIELD(IGlobalInterfaceTable); + IGlobalInterfaceTableVtbl *lpVtbl; ULONG ref; struct StdGITEntry* firstEntry; @@ -92,7 +92,7 @@ static HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalI static HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv); /* Virtual function table */ -static ICOM_VTABLE(IGlobalInterfaceTable) StdGlobalInterfaceTableImpl_Vtbl = +static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE StdGlobalInterfaceTable_QueryInterface, @@ -349,7 +349,7 @@ static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) { return S_OK; } -static ICOM_VTABLE(IClassFactory) GITClassFactoryVtbl = { +static IClassFactoryVtbl GITClassFactoryVtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE GITCF_QueryInterface, GITCF_AddRef, @@ -357,7 +357,7 @@ static ICOM_VTABLE(IClassFactory) GITClassFactoryVtbl = { GITCF_CreateInstance, GITCF_LockServer }; -static ICOM_VTABLE(IClassFactory) *PGITClassFactoryVtbl = &GITClassFactoryVtbl; +static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl; HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) { *ppv = &PGITClassFactoryVtbl; diff --git a/reactos/lib/ole32/hglobalstream.c b/reactos/lib/ole32/hglobalstream.c index ba6e5870c58..1d22f359be3 100644 --- a/reactos/lib/ole32/hglobalstream.c +++ b/reactos/lib/ole32/hglobalstream.c @@ -52,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage); */ struct HGLOBALStreamImpl { - ICOM_VFIELD(IStream); /* Needs to be the first item in the stuct + IStreamVtbl *lpVtbl; /* Needs to be the first item in the stuct * since we want to cast this in a IStream pointer */ /* @@ -169,7 +169,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Clone( /* * Virtual function table for the HGLOBALStreamImpl class. */ -static ICOM_VTABLE(IStream) HGLOBALStreamImpl_Vtbl = +static IStreamVtbl HGLOBALStreamImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE HGLOBALStreamImpl_QueryInterface, diff --git a/reactos/lib/ole32/ifs.c b/reactos/lib/ole32/ifs.c index 6fa2cd5f3ec..89056c7be5a 100644 --- a/reactos/lib/ole32/ifs.c +++ b/reactos/lib/ole32/ifs.c @@ -45,10 +45,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(olemalloc); * *****************************************************************************/ /* set the vtable later */ -static ICOM_VTABLE(IMalloc) VT_IMalloc32; +static IMallocVtbl VT_IMalloc32; typedef struct { - ICOM_VFIELD(IMalloc); + IMallocVtbl *lpVtbl; DWORD dummy; /* nothing, we are static */ IMallocSpy * pSpy; /* the spy when active */ DWORD SpyedAllocationsLeft; /* number of spyed allocations left */ @@ -342,7 +342,7 @@ static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) { } } -static ICOM_VTABLE(IMalloc) VT_IMalloc32 = +static IMallocVtbl VT_IMalloc32 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IMalloc_fnQueryInterface, @@ -361,10 +361,10 @@ static ICOM_VTABLE(IMalloc) VT_IMalloc32 = *****************************************************************************/ /* set the vtable later */ -static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy; +static IMallocSpyVtbl VT_IMallocSpy; typedef struct { - ICOM_VFIELD(IMallocSpy); + IMallocSpyVtbl *lpVtbl; DWORD ref; } _MallocSpy; @@ -502,7 +502,7 @@ static void MallocSpyDumpLeaks() { TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft); } -static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy = +static IMallocSpyVtbl VT_IMallocSpy = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IMallocSpy_fnQueryInterface, diff --git a/reactos/lib/ole32/ifs.h b/reactos/lib/ole32/ifs.h index eba7409a557..badb4d24ba4 100644 --- a/reactos/lib/ole32/ifs.h +++ b/reactos/lib/ole32/ifs.h @@ -33,8 +33,6 @@ typedef LPCSTR LPCOLESTR16; * IMalloc16 interface */ -typedef struct IMalloc16 IMalloc16, *LPMALLOC16; - #undef INTERFACE #define INTERFACE IMalloc16 #define IMalloc16_METHODS \ @@ -45,17 +43,17 @@ typedef struct IMalloc16 IMalloc16, *LPMALLOC16; STDMETHOD_(DWORD,GetSize)(THIS_ LPVOID pv) PURE; \ STDMETHOD_(INT16,DidAlloc)(THIS_ LPVOID pv) PURE; \ STDMETHOD_(LPVOID,HeapMinimize)(THIS) PURE; -ICOM_DEFINE(IMalloc16,IUnknown) +DECLARE_INTERFACE_(IMalloc16,IUnknown) { IMalloc16_METHODS }; #undef INTERFACE +typedef struct IMalloc16 *LPMALLOC16; + /**********************************************************************/ extern LPMALLOC16 IMalloc16_Constructor(); /**********************************************************************/ -typedef struct ILockBytes16 *LPLOCKBYTES16, ILockBytes16; - #define INTERFACE ILockBytes #define ILockBytes16_METHODS \ IUnknown_METHODS \ @@ -66,7 +64,7 @@ typedef struct ILockBytes16 *LPLOCKBYTES16, ILockBytes16; STDMETHOD(LockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE; \ STDMETHOD(UnlockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE; \ STDMETHOD(Stat)(THIS_ STATSTG *pstatstg, DWORD grfStatFlag) PURE; -ICOM_DEFINE(ILockBytes16,IUnknown) +DECLARE_INTERFACE_(ILockBytes16,IUnknown) { ILockBytes16_METHODS }; #undef INTERFACE /**********************************************************************/ @@ -86,8 +84,6 @@ typedef struct tagSTATSTG16 DWORD reserved; } STATSTG16; -typedef struct IStream16 IStream16, *LPSTREAM16; - #define INTERFACE IStream16 #define IStream16_METHODS \ ISequentialStream_METHODS \ @@ -100,15 +96,13 @@ typedef struct IStream16 IStream16, *LPSTREAM16; STDMETHOD(UnlockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE; \ STDMETHOD(Stat)(THIS_ STATSTG* pstatstg, DWORD grfStatFlag) PURE; \ STDMETHOD(Clone)(THIS_ IStream16** ppstm) PURE; -ICOM_DEFINE(IStream16,ISequentialStream) +DECLARE_INTERFACE_(IStream16,ISequentialStream) { IStream16_METHODS }; #undef INTERFACE /**********************************************************************/ typedef OLECHAR16 **SNB16; -typedef struct IStorage16 IStorage16, *LPSTORAGE16; - #define INTERFACE IStorage16 #define IStorage16_METHODS \ IUnknown_METHODS \ @@ -127,7 +121,7 @@ typedef struct IStorage16 IStorage16, *LPSTORAGE16; STDMETHOD_(HRESULT,SetClass)(THIS_ REFCLSID clsid) PURE; \ STDMETHOD_(HRESULT,SetStateBits)(THIS_ DWORD grfStateBits, DWORD grfMask) PURE; \ STDMETHOD_(HRESULT,Stat)(THIS_ STATSTG* pstatstg, DWORD grfStatFlag) PURE; -ICOM_DEFINE(IStorage16,IUnknown) +DECLARE_INTERFACE_(IStorage16,IUnknown) { IStorage16_METHODS }; #undef INTERFACE #endif /* __WINE_OLE_IFS_H */ diff --git a/reactos/lib/ole32/itemmoniker.c b/reactos/lib/ole32/itemmoniker.c index b426f712f13..415390b75c5 100644 --- a/reactos/lib/ole32/itemmoniker.c +++ b/reactos/lib/ole32/itemmoniker.c @@ -43,12 +43,12 @@ const CLSID CLSID_ItemMoniker = { /* ItemMoniker data structure */ typedef struct ItemMonikerImpl{ - ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/ /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether * two monikers are equal. That's whay IROTData interface is implemented by monikers. */ - ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/ ULONG ref; /* reference counter for this object */ @@ -110,7 +110,7 @@ static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface, /********************************************************************************/ /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/ /* IPersistStream and IMoniker functions. */ -static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl = +static IMonikerVtbl VT_ItemMonikerImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ItemMonikerImpl_QueryInterface, @@ -140,7 +140,7 @@ static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl = /********************************************************************************/ /* Virtual function table for the IROTData class. */ -static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +static IROTDataVtbl VT_ROTDataImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ItemMonikerROTDataImpl_QueryInterface, diff --git a/reactos/lib/ole32/marshal.c b/reactos/lib/ole32/marshal.c index c03f84aeaa9..29f663f04fb 100644 --- a/reactos/lib/ole32/marshal.c +++ b/reactos/lib/ole32/marshal.c @@ -58,6 +58,21 @@ extern const CLSID CLSID_DfMarshal; * Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value! */ +inline static HRESULT +get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) { + HRESULT hres; + CLSID pxclsid; + + if ((hres = CoGetPSClsid(riid,&pxclsid))) + return hres; + return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf); +} + +typedef struct _wine_marshal_data { + DWORD dwDestContext; + DWORD mshlflags; +} wine_marshal_data; + typedef struct _mid2unknown { wine_marshal_id mid; LPUNKNOWN pUnk; @@ -67,6 +82,7 @@ typedef struct _mid2stub { wine_marshal_id mid; IRpcStubBuffer *stub; LPUNKNOWN pUnkServer; + BOOL valid; } mid2stub; static mid2stub *stubs = NULL; @@ -75,18 +91,19 @@ static int nrofstubs = 0; static mid2unknown *proxies = NULL; static int nrofproxies = 0; -HRESULT -MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk) { +void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid) { int i; for (i=0;iref++; return This->ref; } -ULONG WINAPI +static ULONG WINAPI StdMarshalImpl_Release(LPMARSHAL iface) { ICOM_THIS(StdMarshalImpl,iface); This->ref--; @@ -224,7 +232,7 @@ StdMarshalImpl_Release(LPMARSHAL iface) { return 0; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass( LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid @@ -233,7 +241,7 @@ StdMarshalImpl_GetUnmarshalClass( return S_OK; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax( LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize @@ -242,7 +250,7 @@ StdMarshalImpl_GetMarshalSizeMax( return S_OK; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_MarshalInterface( LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags @@ -256,6 +264,7 @@ StdMarshalImpl_MarshalInterface( IPSFactoryBuffer *psfacbuf; TRACE("(...,%s,...)\n",debugstr_guid(riid)); + IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk); mid.processid = GetCurrentProcessId(); mid.objectid = (DWORD)pUnk; /* FIXME */ @@ -268,12 +277,14 @@ StdMarshalImpl_MarshalInterface( hres = IStream_Write(pStm,&md,sizeof(md),&res); if (hres) return hres; - if (SUCCEEDED(MARSHAL_Find_Stub(&mid,&pUnk))) { - IUnknown_Release(pUnk); + if (SUCCEEDED(MARSHAL_Find_Stub_Buffer(&mid,&stub))) { + /* Find_Stub_Buffer gives us a ref but we want to keep it, as if we'd created a new one */ + TRACE("Found RpcStubBuffer %p\n", stub); return S_OK; } hres = get_facbuf_for_iid(riid,&psfacbuf); if (hres) return hres; + hres = IPSFactoryBuffer_CreateStub(psfacbuf,riid,pv,&stub); IPSFactoryBuffer_Release(psfacbuf); if (hres) { @@ -286,7 +297,7 @@ StdMarshalImpl_MarshalInterface( return S_OK; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface( LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv ) { @@ -307,6 +318,10 @@ StdMarshalImpl_UnmarshalInterface( FIXME("Calling back to ourselves for %s!\n",debugstr_guid(riid)); return S_OK; } + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_NULL)) { + /* should return proxy manager IUnknown object */ + FIXME("Special treatment required for IID of %s\n", debugstr_guid(riid)); + } hres = get_facbuf_for_iid(riid,&psfacbuf); if (hres) return hres; hres = IPSFactoryBuffer_CreateProxy(psfacbuf,NULL,riid,&rpcproxy,ppv); @@ -314,6 +329,9 @@ StdMarshalImpl_UnmarshalInterface( FIXME("Failed to create a proxy for %s\n",debugstr_guid(riid)); return hres; } + + MARSHAL_Register_Proxy(&mid, (LPUNKNOWN) rpcproxy); + hres = PIPE_GetNewPipeBuf(&mid,&chanbuf); IPSFactoryBuffer_Release(psfacbuf); if (hres) { @@ -332,19 +350,48 @@ StdMarshalImpl_UnmarshalInterface( return hres; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) { - FIXME("(), stub!\n"); + wine_marshal_id mid; + ULONG res; + HRESULT hres; + IRpcStubBuffer *stub = NULL; + int i; + + hres = IStream_Read(pStm,&mid,sizeof(mid),&res); + if (hres) return hres; + + for (i=0; i < nrofstubs; i++) + { + if (!stubs[i].valid) continue; + + if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid))) + { + stub = stubs[i].stub; + break; + } + } + + if (!stub) + { + FIXME("Could not map MID to stub??\n"); + return E_FAIL; + } + + res = IRpcStubBuffer_Release(stub); + stubs[i].valid = FALSE; + TRACE("stub refcount of %p is %ld\n", stub, res); + return S_OK; } -HRESULT WINAPI +static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) { FIXME("(), stub!\n"); return S_OK; } -ICOM_VTABLE(IMarshal) stdmvtbl = { +IMarshalVtbl stdmvtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE StdMarshalImpl_QueryInterface, StdMarshalImpl_AddRef, @@ -484,7 +531,10 @@ CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk, FIXME("Stream write failed, %lx\n",hres); goto release_marshal; } + + TRACE("Calling IMarshal::MarshalInterace\n"); hres = IMarshal_MarshalInterface(pMarshal,pStm,riid,pUnk,dwDestContext,pvDestContext,mshlflags); + if (hres) { if (IsEqualGUID(riid,&IID_IOleObject)) { ERR("WINE currently cannot marshal IOleObject interfaces. This means you cannot embed/link OLE objects between applications.\n"); @@ -701,7 +751,7 @@ SMCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) { return S_OK; } -static ICOM_VTABLE(IClassFactory) dfmarshalcfvtbl = { +static IClassFactoryVtbl dfmarshalcfvtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE SMCF_QueryInterface, SMCF_AddRef, @@ -709,7 +759,7 @@ static ICOM_VTABLE(IClassFactory) dfmarshalcfvtbl = { SMCF_CreateInstance, SMCF_LockServer }; -static ICOM_VTABLE(IClassFactory) *pdfmarshalcfvtbl = &dfmarshalcfvtbl; +static IClassFactoryVtbl *pdfmarshalcfvtbl = &dfmarshalcfvtbl; HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv) { diff --git a/reactos/lib/ole32/memlockbytes.c b/reactos/lib/ole32/memlockbytes.c index 00bbabe2a68..5fc32dd989a 100644 --- a/reactos/lib/ole32/memlockbytes.c +++ b/reactos/lib/ole32/memlockbytes.c @@ -53,7 +53,7 @@ struct HGLOBALLockBytesImpl * Needs to be the first item in the stuct * since we want to cast this in an ILockBytes pointer */ - ICOM_VFIELD(ILockBytes); + ILockBytesVtbl *lpVtbl; /* * Reference count @@ -140,7 +140,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Stat( /* * Virtual function table for the HGLOBALLockBytesImpl class. */ -static ICOM_VTABLE(ILockBytes) HGLOBALLockBytesImpl_Vtbl = +static ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE HGLOBALLockBytesImpl_QueryInterface, diff --git a/reactos/lib/ole32/memlockbytes16.c b/reactos/lib/ole32/memlockbytes16.c index 22e14f91775..ec8bdbd650d 100644 --- a/reactos/lib/ole32/memlockbytes16.c +++ b/reactos/lib/ole32/memlockbytes16.c @@ -52,7 +52,7 @@ struct HGLOBALLockBytesImpl16 * Needs to be the first item in the stuct * since we want to cast this in an ILockBytes pointer */ - ICOM_VFIELD(ILockBytes16); + ILockBytes16Vtbl *lpVtbl; ULONG ref; /* @@ -148,7 +148,7 @@ HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal, { HGLOBALLockBytesImpl16* newLockBytes; - static ICOM_VTABLE(ILockBytes16) vt16; + static ILockBytes16Vtbl vt16; static SEGPTR msegvt16; HMODULE16 hcomp = GetModuleHandle16("OLE2"); @@ -176,7 +176,7 @@ HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal, #undef VTENT msegvt16 = MapLS( &vt16 ); } - newLockBytes->lpVtbl = (ICOM_VTABLE(ILockBytes16)*)msegvt16; + newLockBytes->lpVtbl = (ILockBytes16Vtbl*)msegvt16; newLockBytes->ref = 0; /* * Initialize the support. diff --git a/reactos/lib/ole32/moniker.c b/reactos/lib/ole32/moniker.c index f5cbcaffe92..5d223ba7b6c 100644 --- a/reactos/lib/ole32/moniker.c +++ b/reactos/lib/ole32/moniker.c @@ -17,6 +17,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: + * - IRunningObjectTable should work interprocess, but currently doesn't. + * Native (on Win2k at least) uses an undocumented RPC interface, IROT, to + * communicate with RPCSS which contains the table of marshalled data. + * - IRunningObjectTable should use marshalling instead of simple ref + * counting as there is the possibility of using the running object table + * to access objects in other apartments. */ #include @@ -50,7 +58,7 @@ typedef struct RunObject{ /* define the RunningObjectTableImpl structure */ typedef struct RunningObjectTableImpl{ - ICOM_VFIELD(IRunningObjectTable); + IRunningObjectTableVtbl *lpVtbl; ULONG ref; RunObject* runObjTab; /* pointer to the first object in the table */ @@ -82,7 +90,7 @@ HRESULT WINAPI RunningObjectTableImpl_Destroy(); HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx); /* Virtual function table for the IRunningObjectTable class. */ -static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl = +static IRunningObjectTableVtbl VT_RunningObjectTableImpl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE RunningObjectTableImpl_QueryInterface, @@ -302,9 +310,12 @@ HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, return E_OUTOFMEMORY; } /* add a reference to the object in the strong registration case */ - if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) + if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) { + TRACE("strong registration, reffing %p\n", punkObject); + /* this is wrong; we should always add a reference to the object */ IUnknown_AddRef(punkObject); - + } + IMoniker_AddRef(pmkObjectName); return res; @@ -328,9 +339,12 @@ HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, return E_INVALIDARG; /* release the object if it was registered with a strong registrantion option */ - if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) + if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) { + TRACE("releasing %p\n", This->runObjTab[index].pObj); + /* this is also wrong; we should always release the object (see above) */ IUnknown_Release(This->runObjTab[index].pObj); - + } + IMoniker_Release(This->runObjTab[index].pmkObj); /* remove the object from the table */ @@ -373,8 +387,10 @@ HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface, *ppunkObject=0; /* verify if the object was registered before or not */ - if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) + if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) { + WARN("Moniker unavailable - needs to work interprocess?\n"); return MK_E_UNAVAILABLE; + } /* add a reference to the object then set output object argument */ IUnknown_AddRef(This->runObjTab[index].pObj); diff --git a/reactos/lib/ole32/ole16.c b/reactos/lib/ole32/ole16.c index 61e980e088d..b3ef66bd94c 100644 --- a/reactos/lib/ole32/ole16.c +++ b/reactos/lib/ole32/ole16.c @@ -64,7 +64,7 @@ LPMALLOC16 currentMalloc16=NULL; typedef struct { /* IUnknown fields */ - ICOM_VFIELD(IMalloc16); + IMalloc16Vtbl *lpVtbl; DWORD ref; /* IMalloc16 fields */ } IMalloc16Impl; @@ -178,7 +178,7 @@ LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) { LPMALLOC16 IMalloc16_Constructor() { - static ICOM_VTABLE(IMalloc16) vt16; + static IMalloc16Vtbl vt16; static SEGPTR msegvt16; IMalloc16Impl* This; HMODULE16 hcomp = GetModuleHandle16("COMPOBJ"); @@ -199,7 +199,7 @@ IMalloc16_Constructor() #undef VTENT msegvt16 = MapLS( &vt16 ); } - This->lpVtbl = (ICOM_VTABLE(IMalloc16)*)msegvt16; + This->lpVtbl = (IMalloc16Vtbl*)msegvt16; This->ref = 1; return (LPMALLOC16)MapLS( This ); } @@ -313,7 +313,7 @@ _xmalloc16(DWORD size, SEGPTR *ptr) { * everything we need. */ if (!K32WOWCallback16Ex( - (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL( + (DWORD)((IMalloc16Vtbl*)MapSL( (SEGPTR)((LPMALLOC16)MapSL((SEGPTR)mllc))->lpVtbl ) )->Alloc, WCB16_CDECL, diff --git a/reactos/lib/ole32/oleobj.c b/reactos/lib/ole32/oleobj.c index cced63a3066..fcbce41be4e 100644 --- a/reactos/lib/ole32/oleobj.c +++ b/reactos/lib/ole32/oleobj.c @@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); */ typedef struct OleAdviseHolderImpl { - ICOM_VFIELD(IOleAdviseHolder); + IOleAdviseHolderVtbl *lpVtbl; DWORD ref; @@ -63,7 +63,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER); /************************************************************************** * OleAdviseHolderImpl_VTable */ -static struct ICOM_VTABLE(IOleAdviseHolder) oahvt = +static struct IOleAdviseHolderVtbl oahvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE OleAdviseHolderImpl_QueryInterface, @@ -369,7 +369,7 @@ typedef struct DataAdviseConnection { typedef struct DataAdviseHolder { - ICOM_VFIELD(IDataAdviseHolder); + IDataAdviseHolderVtbl *lpVtbl; DWORD ref; DWORD maxCons; @@ -411,7 +411,7 @@ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( /************************************************************************** * DataAdviseHolderImpl_VTable */ -static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable = +static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE DataAdviseHolder_QueryInterface, diff --git a/reactos/lib/ole32/oleproxy.c b/reactos/lib/ole32/oleproxy.c index f92ca5a832f..d384b4197dc 100644 --- a/reactos/lib/ole32/oleproxy.c +++ b/reactos/lib/ole32/oleproxy.c @@ -19,15 +19,18 @@ */ /* Documentation on MSDN: + * + * (Top level COM documentation) + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/componentdevelopmentank.asp * * (COM Proxy) - * http://msdn.microsoft.com/library/en-us/com/comext_1q0p.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1q0p.asp * * (COM Stub) - * http://msdn.microsoft.com/library/en-us/com/comext_1lia.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1lia.asp * * (Marshal) - * http://msdn.microsoft.com/library/en-us/com/comext_1gfn.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1gfn.asp * */ @@ -81,7 +84,7 @@ const CLSID CLSID_PSFactoryBuffer = { 0x00000320, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, * COM will load the appropriate interface stubs and proxies as needed. */ typedef struct _CFStub { - ICOM_VTABLE(IRpcStubBuffer) *lpvtbl; + IRpcStubBufferVtbl *lpvtbl; DWORD ref; LPUNKNOWN pUnkServer; @@ -234,7 +237,7 @@ CFStub_DebugServerRelease(LPRPCSTUBBUFFER iface,void *pv) { FIXME("(%p), stub!\n",pv); } -static ICOM_VTABLE(IRpcStubBuffer) cfstubvt = { +static IRpcStubBufferVtbl cfstubvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE CFStub_QueryInterface, CFStub_AddRef, @@ -265,8 +268,8 @@ CFStub_Construct(LPRPCSTUBBUFFER *ppv) { * the refcount. */ typedef struct _CFProxy { - ICOM_VTABLE(IClassFactory) *lpvtbl_cf; - ICOM_VTABLE(IRpcProxyBuffer) *lpvtbl_proxy; + IClassFactoryVtbl *lpvtbl_cf; + IRpcProxyBufferVtbl *lpvtbl_proxy; DWORD ref; IRpcChannelBuffer *chanbuf; @@ -409,7 +412,7 @@ static HRESULT WINAPI CFProxy_LockServer(LPCLASSFACTORY iface,BOOL fLock) { return S_OK; } -static ICOM_VTABLE(IRpcProxyBuffer) pspbvtbl = { +static IRpcProxyBufferVtbl pspbvtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IRpcProxyBufferImpl_QueryInterface, IRpcProxyBufferImpl_AddRef, @@ -417,7 +420,7 @@ static ICOM_VTABLE(IRpcProxyBuffer) pspbvtbl = { IRpcProxyBufferImpl_Connect, IRpcProxyBufferImpl_Disconnect }; -static ICOM_VTABLE(IClassFactory) cfproxyvt = { +static IClassFactoryVtbl cfproxyvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE CFProxy_QueryInterface, CFProxy_AddRef, @@ -493,7 +496,7 @@ PSFacBuf_CreateStub( return E_FAIL; } -static ICOM_VTABLE(IPSFactoryBuffer) psfacbufvtbl = { +static IPSFactoryBufferVtbl psfacbufvtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE PSFacBuf_QueryInterface, PSFacBuf_AddRef, @@ -503,7 +506,7 @@ static ICOM_VTABLE(IPSFactoryBuffer) psfacbufvtbl = { }; /* This is the whole PSFactoryBuffer object, just the vtableptr */ -static ICOM_VTABLE(IPSFactoryBuffer) *lppsfac = &psfacbufvtbl; +static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl; /*********************************************************************** * DllGetClassObject [OLE32.@] @@ -513,10 +516,6 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) *ppv = NULL; if (IsEqualIID(rclsid,&CLSID_PSFactoryBuffer)) { *ppv = &lppsfac; - /* If we create a ps factory, we might need a stub manager later - * anyway - */ - STUBMGR_Start(); return S_OK; } if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&( diff --git a/reactos/lib/ole32/rpc.c b/reactos/lib/ole32/rpc.c index 44e0594f377..3cbb0f7323c 100644 --- a/reactos/lib/ole32/rpc.c +++ b/reactos/lib/ole32/rpc.c @@ -50,6 +50,38 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); +#define REQTYPE_REQUEST 0 +typedef struct _wine_rpc_request_header { + DWORD reqid; + wine_marshal_id mid; + DWORD iMethod; + DWORD cbBuffer; +} wine_rpc_request_header; + +#define REQTYPE_RESPONSE 1 +typedef struct _wine_rpc_response_header { + DWORD reqid; + DWORD cbBuffer; + DWORD retval; +} wine_rpc_response_header; + +/* used when shutting down a pipe, e.g. at the end of a process */ +#define REQTYPE_DISCONNECT 2 +typedef struct _wine_rpc_disconnect_header { + DWORD reqid; + wine_marshal_id mid; /* mid of stub to delete */ +} wine_rpc_disconnect_header; + + +#define REQSTATE_START 0 +#define REQSTATE_REQ_QUEUED 1 +#define REQSTATE_REQ_WAITING_FOR_REPLY 2 +#define REQSTATE_REQ_GOT 3 +#define REQSTATE_INVOKING 4 +#define REQSTATE_RESP_QUEUED 5 +#define REQSTATE_RESP_GOT 6 +#define REQSTATE_DONE 6 + typedef struct _wine_rpc_request { int state; HANDLE hPipe; /* temp copy of handle */ @@ -61,10 +93,11 @@ typedef struct _wine_rpc_request { static wine_rpc_request **reqs = NULL; static int nrofreqs = 0; -/* This pipe is _thread_ based */ +/* This pipe is _thread_ based, each thread which talks to a remote + * apartment (mid) has its own pipe */ typedef struct _wine_pipe { wine_marshal_id mid; /* target mid */ - DWORD tid; /* thread in which we execute */ + DWORD tid; /* thread which owns this outgoing pipe */ HANDLE hPipe; int pending; @@ -76,7 +109,7 @@ static wine_pipe *pipes = NULL; static int nrofpipes = 0; typedef struct _PipeBuf { - ICOM_VTABLE(IRpcChannelBuffer) *lpVtbl; + IRpcChannelBufferVtbl *lpVtbl; DWORD ref; wine_marshal_id mid; @@ -84,7 +117,7 @@ typedef struct _PipeBuf { } PipeBuf; static HRESULT WINAPI -_xread(HANDLE hf, LPVOID ptr, DWORD size) { +read_pipe(HANDLE hf, LPVOID ptr, DWORD size) { DWORD res; if (!ReadFile(hf,ptr,size,&res,NULL)) { FIXME("Failed to read from %p, le is %lx\n",hf,GetLastError()); @@ -124,7 +157,7 @@ drs(LPCSTR where) { } static HRESULT WINAPI -_xwrite(HANDLE hf, LPVOID ptr, DWORD size) { +write_pipe(HANDLE hf, LPVOID ptr, DWORD size) { DWORD res; if (!WriteFile(hf,ptr,size,&res,NULL)) { FIXME("Failed to write to %p, le is %lx\n",hf,GetLastError()); @@ -260,10 +293,25 @@ PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) { static ULONG WINAPI PipeBuf_Release(LPRPCCHANNELBUFFER iface) { ICOM_THIS(PipeBuf,iface); + wine_rpc_disconnect_header header; + HANDLE pipe; + DWORD reqtype = REQTYPE_DISCONNECT; + This->ref--; if (This->ref) return This->ref; - ERR("Free all stuff.\n"); + + FIXME("Free all stuff\n"); + + memcpy(&header.mid, &This->mid, sizeof(wine_marshal_id)); + + pipe = PIPE_FindByMID(&This->mid); + + write_pipe(pipe, &reqtype, sizeof(reqtype)); + write_pipe(pipe, &header, sizeof(wine_rpc_disconnect_header)); + + TRACE("written disconnect packet\n"); + HeapFree(GetProcessHeap(),0,This); return 0; } @@ -274,7 +322,7 @@ PipeBuf_GetBuffer( ) { /*ICOM_THIS(PipeBuf,iface);*/ - TRACE("(%p,%s), slightly wrong.\n",msg,debugstr_guid(riid)); + TRACE("(%p,%s)\n",msg,debugstr_guid(riid)); /* probably reuses IID in real. */ if (msg->cbBuffer && (msg->Buffer == NULL)) msg->Buffer = HeapAlloc(GetProcessHeap(),0,msg->cbBuffer); @@ -282,7 +330,7 @@ PipeBuf_GetBuffer( } static HRESULT -_invoke_onereq(wine_rpc_request *req) { +COM_InvokeAndRpcSend(wine_rpc_request *req) { IRpcStubBuffer *stub; RPCOLEMESSAGE msg; HRESULT hres; @@ -296,23 +344,25 @@ _invoke_onereq(wine_rpc_request *req) { msg.Buffer = req->Buffer; msg.iMethod = req->reqh.iMethod; msg.cbBuffer = req->reqh.cbBuffer; + msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION; req->state = REQSTATE_INVOKING; req->resph.retval = IRpcStubBuffer_Invoke(stub,&msg,NULL); + IUnknown_Release(stub); req->Buffer = msg.Buffer; req->resph.cbBuffer = msg.cbBuffer; reqtype = REQTYPE_RESPONSE; - hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype)); + hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype)); if (hres) return hres; - hres = _xwrite(req->hPipe,&(req->resph),sizeof(req->resph)); + hres = write_pipe(req->hPipe,&(req->resph),sizeof(req->resph)); if (hres) return hres; - hres = _xwrite(req->hPipe,req->Buffer,req->resph.cbBuffer); + hres = write_pipe(req->hPipe,req->Buffer,req->resph.cbBuffer); if (hres) return hres; req->state = REQSTATE_DONE; drs("invoke"); return S_OK; } -static HRESULT _read_one(wine_pipe *xpipe); +static HRESULT COM_RpcReceive(wine_pipe *xpipe); static HRESULT RPC_QueueRequestAndWait(wine_rpc_request *req) { @@ -333,27 +383,31 @@ RPC_QueueRequestAndWait(wine_rpc_request *req) { req->hPipe = xpipe->hPipe; req->state = REQSTATE_REQ_WAITING_FOR_REPLY; reqtype = REQTYPE_REQUEST; - hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype)); + hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype)); if (hres) return hres; - hres = _xwrite(req->hPipe,&(req->reqh),sizeof(req->reqh)); + hres = write_pipe(req->hPipe,&(req->reqh),sizeof(req->reqh)); if (hres) return hres; - hres = _xwrite(req->hPipe,req->Buffer,req->reqh.cbBuffer); + hres = write_pipe(req->hPipe,req->Buffer,req->reqh.cbBuffer); if (hres) return hres; - while (1) { - /*WaitForSingleObject(hRpcChanged,INFINITE);*/ - hres = _read_one(xpipe); + /* This loop is about allowing re-entrancy. While waiting for the + * response to one RPC we may receive a request starting another. */ + while (!hres) { + hres = COM_RpcReceive(xpipe); if (hres) break; for (i=0;istate==REQSTATE_REQ_GOT) && (xreq->hPipe==req->hPipe)) { - _invoke_onereq(xreq); + hres = COM_InvokeAndRpcSend(xreq); + if (hres) break; } } if (req->state == REQSTATE_RESP_GOT) return S_OK; } + if (FAILED(hres)) + WARN("-- 0x%08lx\n", hres); return hres; } @@ -411,7 +465,7 @@ PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface) { return S_OK; } -static ICOM_VTABLE(IRpcChannelBuffer) pipebufvt = { +static IRpcChannelBufferVtbl pipebufvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE PipeBuf_QueryInterface, PipeBuf_AddRef, @@ -467,12 +521,14 @@ PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) { static HRESULT create_server(REFCLSID rclsid) { + static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 }; HKEY key; char buf[200]; HRESULT hres = E_UNEXPECTED; char xclsid[80]; - WCHAR dllName[MAX_PATH+1]; - DWORD dllNameLen = sizeof(dllName); + WCHAR exe[MAX_PATH+1]; + DWORD exelen = sizeof(exe); + WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)]; STARTUPINFOW sinfo; PROCESS_INFORMATION pinfo; @@ -481,18 +537,35 @@ create_server(REFCLSID rclsid) { sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid); hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key); - if (hres != ERROR_SUCCESS) + if (hres != ERROR_SUCCESS) { + WARN("CLSID %s not registered as LocalServer32\n", xclsid); return REGDB_E_READREGDB; /* Probably */ + } - memset(dllName,0,sizeof(dllName)); - hres= RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)dllName,&dllNameLen); + memset(exe,0,sizeof(exe)); + hres= RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)exe, &exelen); RegCloseKey(key); - if (hres) - return REGDB_E_CLASSNOTREG; /* FIXME: check retval */ + if (hres) { + WARN("No default value for LocalServer32 key\n"); + return REGDB_E_CLASSNOTREG; /* FIXME: check retval */ + } + memset(&sinfo,0,sizeof(sinfo)); sinfo.cb = sizeof(sinfo); - if (!CreateProcessW(NULL,dllName,NULL,NULL,FALSE,0,NULL,NULL,&sinfo,&pinfo)) + + /* EXE servers are started with the -Embedding switch. MSDN also claims /Embedding is used, + 9x does -Embedding, perhaps an 9x/NT difference? */ + + strcpyW(command, exe); + strcatW(command, embedding); + + TRACE("activating local server '%s' for %s\n", debugstr_w(command), xclsid); + + if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) { + WARN("failed to run local server %s\n", debugstr_w(exe)); return E_FAIL; + } + return S_OK; } /* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */ @@ -508,6 +581,8 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { int tries = 0; #define MAXTRIES 10000 + TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid)); + strcpy(pipefn,PIPEPREF); WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF)); @@ -562,7 +637,7 @@ PIPE_StartRequestThread(HANDLE xhPipe) { wine_marshal_id remoteid; HRESULT hres; - hres = _xread(xhPipe,&remoteid,sizeof(remoteid)); + hres = read_pipe(xhPipe,&remoteid,sizeof(remoteid)); if (hres) { ERR("Failed to read remote mid!\n"); return; @@ -571,35 +646,62 @@ PIPE_StartRequestThread(HANDLE xhPipe) { } static HRESULT -_read_one(wine_pipe *xpipe) { +COM_RpcReceive(wine_pipe *xpipe) { DWORD reqtype; HRESULT hres = S_OK; HANDLE xhPipe = xpipe->hPipe; /*FIXME("%lx %d reading reqtype\n",GetCurrentProcessId(),xhPipe);*/ - hres = _xread(xhPipe,&reqtype,sizeof(reqtype)); + hres = read_pipe(xhPipe,&reqtype,sizeof(reqtype)); if (hres) goto end; EnterCriticalSection(&(xpipe->crit)); /*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/ - if (reqtype == REQTYPE_REQUEST) { + if (reqtype == REQTYPE_DISCONNECT) { /* only received by servers */ + wine_rpc_disconnect_header header; + IRpcStubBuffer *stub; + ULONG ret; + + hres = read_pipe(xhPipe, &header, sizeof(header)); + if (hres) { + ERR("could not read disconnect header\n"); + goto end; + } + + TRACE("read disconnect header\n"); + + hres = MARSHAL_Find_Stub_Buffer(&header.mid, &stub); + if (hres) { + ERR("could not locate stub to disconnect, mid.objectid=%p\n", (void*)header.mid.objectid); + goto end; + } + + + /* release reference added by MARSHAL_Find_Stub_Buffer call */ + IRpcStubBuffer_Release(stub); + /* release it for real */ + ret = IRpcStubBuffer_Release(stub); + /* FIXME: race */ + if (ret == 0) + MARSHAL_Invalidate_Stub_From_MID(&header.mid); + goto end; + } else if (reqtype == REQTYPE_REQUEST) { wine_rpc_request *xreq; RPC_GetRequest(&xreq); xreq->hPipe = xhPipe; - hres = _xread(xhPipe,&(xreq->reqh),sizeof(xreq->reqh)); + hres = read_pipe(xhPipe,&(xreq->reqh),sizeof(xreq->reqh)); if (hres) goto end; xreq->resph.reqid = xreq->reqh.reqid; xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer); - hres = _xread(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer); + hres = read_pipe(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer); if (hres) goto end; xreq->state = REQSTATE_REQ_GOT; goto end; - } - if (reqtype == REQTYPE_RESPONSE) { + } else if (reqtype == REQTYPE_RESPONSE) { wine_rpc_response_header resph; int i; - hres = _xread(xhPipe,&resph,sizeof(resph)); + hres = read_pipe(xhPipe,&resph,sizeof(resph)); if (hres) goto end; for (i=nrofreqs;i--;) { wine_rpc_request *xreq = reqs[i]; @@ -613,7 +715,7 @@ _read_one(wine_pipe *xpipe) { else xreq->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->resph.cbBuffer); - hres = _xread(xhPipe,xreq->Buffer,xreq->resph.cbBuffer); + hres = read_pipe(xhPipe,xreq->Buffer,xreq->resph.cbBuffer); if (hres) goto end; xreq->state = REQSTATE_RESP_GOT; /*PulseEvent(hRpcChanged);*/ @@ -635,18 +737,19 @@ static DWORD WINAPI _StubReaderThread(LPVOID param) { wine_pipe *xpipe = (wine_pipe*)param; HANDLE xhPipe = xpipe->hPipe; - HRESULT hres; + HRESULT hres = S_OK; TRACE("STUB reader thread %lx\n",GetCurrentProcessId()); - while (1) { + while (!hres) { int i; - hres = _read_one(xpipe); + hres = COM_RpcReceive(xpipe); if (hres) break; for (i=nrofreqs;i--;) { wine_rpc_request *xreq = reqs[i]; if ((xreq->state == REQSTATE_REQ_GOT) && (xreq->hPipe == xhPipe)) { - _invoke_onereq(xreq); + hres = COM_InvokeAndRpcSend(xreq); + if (!hres) break; } } } diff --git a/reactos/lib/ole32/stg_stream.c b/reactos/lib/ole32/stg_stream.c index b365ffe3851..e8a5b3b3cf8 100644 --- a/reactos/lib/ole32/stg_stream.c +++ b/reactos/lib/ole32/stg_stream.c @@ -46,7 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage); /* * Virtual function table for the StgStreamImpl class. */ -static ICOM_VTABLE(IStream) StgStreamImpl_Vtbl = +static IStreamVtbl StgStreamImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE StgStreamImpl_QueryInterface, diff --git a/reactos/lib/ole32/storage.c b/reactos/lib/ole32/storage.c index 664d661cec3..0a3fe8f8086 100644 --- a/reactos/lib/ole32/storage.c +++ b/reactos/lib/ole32/storage.c @@ -90,10 +90,10 @@ static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1}; #define SMALLBLOCKS_PER_BIGBLOCK (BIGSIZE/SMALLSIZE) #define READ_HEADER STORAGE_get_big_block(hf,-1,(LPBYTE)&sth);assert(!memcmp(STORAGE_magic,sth.magic,sizeof(STORAGE_magic))); -static ICOM_VTABLE(IStorage16) stvt16; -static ICOM_VTABLE(IStorage16) *segstvt16 = NULL; -static ICOM_VTABLE(IStream16) strvt16; -static ICOM_VTABLE(IStream16) *segstrvt16 = NULL; +static IStorage16Vtbl stvt16; +static IStorage16Vtbl *segstvt16 = NULL; +static IStream16Vtbl strvt16; +static IStream16Vtbl *segstrvt16 = NULL; /*ULONG WINAPI IStorage16_AddRef(LPSTORAGE16 this);*/ static void _create_istorage16(LPSTORAGE16 *stg); @@ -954,7 +954,7 @@ STORAGE_get_free_pps_entry(HANDLE hf) { typedef struct { /* IUnknown fields */ - ICOM_VFIELD(IStream16); + IStream16Vtbl *lpVtbl; DWORD ref; /* IStream16 fields */ SEGPTR thisptr; /* pointer to this struct as segmented */ @@ -1412,7 +1412,7 @@ static void _create_istream16(LPSTREAM16 *str) { VTENT(Stat); VTENT(Clone); #undef VTENT - segstrvt16 = (ICOM_VTABLE(IStream16)*)MapLS( &strvt16 ); + segstrvt16 = (IStream16Vtbl*)MapLS( &strvt16 ); } else { #define VTENT(xfn) strvt16.xfn = IStream16_fn##xfn; VTENT(QueryInterface); @@ -1448,7 +1448,7 @@ static void _create_istream16(LPSTREAM16 *str) { typedef struct { /* IUnknown fields */ - ICOM_VFIELD(IStream); + IStreamVtbl *lpVtbl; DWORD ref; /* IStream32 fields */ struct storage_pps_entry stde; @@ -1502,7 +1502,7 @@ ULONG WINAPI IStream_fnRelease(IStream* iface) { typedef struct { /* IUnknown fields */ - ICOM_VFIELD(IStorage16); + IStorage16Vtbl *lpVtbl; DWORD ref; /* IStorage16 fields */ SEGPTR thisptr; /* pointer to this struct as segmented */ @@ -1826,7 +1826,7 @@ static void _create_istorage16(LPSTORAGE16 *stg) { VTENT(SetStateBits) VTENT(Stat) #undef VTENT - segstvt16 = (ICOM_VTABLE(IStorage16)*)MapLS( &stvt16 ); + segstvt16 = (IStorage16Vtbl*)MapLS( &stvt16 ); } else { #define VTENT(xfn) stvt16.xfn = IStorage16_fn##xfn; VTENT(QueryInterface) @@ -1982,7 +1982,7 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt) args[5] = 0; if (!K32WOWCallback16Ex( - (DWORD)((ICOM_VTABLE(ILockBytes16)*)MapSL( + (DWORD)((ILockBytes16Vtbl*)MapSL( (SEGPTR)((LPLOCKBYTES16)MapSL(plkbyt))->lpVtbl) )->ReadAt, WCB16_PASCAL, diff --git a/reactos/lib/ole32/storage32.c b/reactos/lib/ole32/storage32.c index c182b8aae06..8c306cde6e3 100644 --- a/reactos/lib/ole32/storage32.c +++ b/reactos/lib/ole32/storage32.c @@ -158,7 +158,7 @@ static DWORD GetCreationModeFromSTGM(DWORD stgm); /* * Virtual function table for the IStorage32Impl class. */ -static ICOM_VTABLE(IStorage) Storage32Impl_Vtbl = +static IStorageVtbl Storage32Impl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE StorageBaseImpl_QueryInterface, @@ -184,7 +184,7 @@ static ICOM_VTABLE(IStorage) Storage32Impl_Vtbl = /* * Virtual function table for the Storage32InternalImpl class. */ -static ICOM_VTABLE(IStorage) Storage32InternalImpl_Vtbl = +static IStorageVtbl Storage32InternalImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE StorageBaseImpl_QueryInterface, @@ -210,7 +210,7 @@ static ICOM_VTABLE(IStorage) Storage32InternalImpl_Vtbl = /* * Virtual function table for the IEnumSTATSTGImpl class. */ -static ICOM_VTABLE(IEnumSTATSTG) IEnumSTATSTGImpl_Vtbl = +static IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IEnumSTATSTGImpl_QueryInterface, @@ -4104,7 +4104,9 @@ void StorageUtl_CopyPropertyToSTATSTG( /* * The copy of the string occurs only when the flag is not set */ - if ((statFlags & STATFLAG_NONAME) != 0) + if( ((statFlags & STATFLAG_NONAME) != 0) || + (source->name == NULL) || + (source->name[0] == 0) ) { destination->pwcsName = 0; } diff --git a/reactos/lib/ole32/storage32.h b/reactos/lib/ole32/storage32.h index f9b0fb27334..05ceaed9727 100644 --- a/reactos/lib/ole32/storage32.h +++ b/reactos/lib/ole32/storage32.h @@ -204,7 +204,7 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName */ struct StorageBaseImpl { - ICOM_VFIELD(IStorage); /* Needs to be the first item in the struct + IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct * since we want to cast this in a Storage32 pointer */ /* @@ -298,7 +298,7 @@ HRESULT WINAPI StorageBaseImpl_SetClass( */ struct StorageImpl { - ICOM_VFIELD(IStorage); /* Needs to be the first item in the struct + IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct * since we want to cast this in a Storage32 pointer */ /* @@ -498,7 +498,7 @@ void Storage32Impl_SetExtDepotBlock(StorageImpl* This, */ struct StorageInternalImpl { - ICOM_VFIELD(IStorage); /* Needs to be the first item in the struct + IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct * since we want to cast this in a Storage32 pointer */ /* @@ -542,8 +542,8 @@ HRESULT WINAPI StorageInternalImpl_Revert( */ struct IEnumSTATSTGImpl { - ICOM_VFIELD(IEnumSTATSTG); /* Needs to be the first item in the struct - * since we want to cast this in a IEnumSTATSTG pointer */ + IEnumSTATSTGVtbl *lpVtbl; /* Needs to be the first item in the struct + * since we want to cast this in a IEnumSTATSTG pointer */ ULONG ref; /* Reference count */ StorageImpl* parentStorage; /* Reference to the parent storage */ @@ -627,8 +627,8 @@ INT IEnumSTATSTGImpl_FindParentProperty( */ struct StgStreamImpl { - ICOM_VFIELD(IStream); /* Needs to be the first item in the struct - * since we want to cast this in a IStream pointer */ + IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct + * since we want to cast this in a IStream pointer */ /* * Reference count diff --git a/reactos/lib/ole32/winehq2ros.patch b/reactos/lib/ole32/winehq2ros.patch index 9ee56656109..3f1e3f080f9 100644 --- a/reactos/lib/ole32/winehq2ros.patch +++ b/reactos/lib/ole32/winehq2ros.patch @@ -1,26 +1,63 @@ Index: ifs.h =================================================================== RCS file: /home/wine/wine/dlls/ole32/ifs.h,v -retrieving revision 1.11 -diff -u -r1.11 ifs.h ---- ifs.h 23 Jan 2004 22:51:42 -0000 1.11 -+++ ifs.h 14 Mar 2004 09:24:36 -0000 -@@ -35,6 +35,7 @@ - - typedef struct IMalloc16 IMalloc16, *LPMALLOC16; +retrieving revision 1.12 +diff -u -r1.12 ifs.h +--- ifs.h 12 Aug 2004 03:33:30 -0000 1.12 ++++ ifs.h 14 Aug 2004 20:12:56 -0000 +@@ -33,8 +33,7 @@ + * IMalloc16 interface + */ +-typedef struct IMalloc16 IMalloc16, *LPMALLOC16; +- +#undef INTERFACE #define INTERFACE IMalloc16 #define IMalloc16_METHODS \ IUnknown_METHODS \ +@@ -47,14 +46,14 @@ + DECLARE_INTERFACE_(IMalloc16,IUnknown) { IMalloc16_METHODS }; + #undef INTERFACE + ++typedef struct IMalloc16 *LPMALLOC16; ++ + /**********************************************************************/ + + extern LPMALLOC16 IMalloc16_Constructor(); + + /**********************************************************************/ + +-typedef struct ILockBytes16 *LPLOCKBYTES16, ILockBytes16; +- + #define INTERFACE ILockBytes + #define ILockBytes16_METHODS \ + IUnknown_METHODS \ +@@ -85,8 +84,6 @@ + DWORD reserved; + } STATSTG16; + +-typedef struct IStream16 IStream16, *LPSTREAM16; +- + #define INTERFACE IStream16 + #define IStream16_METHODS \ + ISequentialStream_METHODS \ +@@ -105,8 +102,6 @@ + /**********************************************************************/ + + typedef OLECHAR16 **SNB16; +- +-typedef struct IStorage16 IStorage16, *LPSTORAGE16; + + #define INTERFACE IStorage16 + #define IStorage16_METHODS \ Index: oleproxy.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/oleproxy.c,v -retrieving revision 1.13 -diff -u -r1.13 oleproxy.c ---- oleproxy.c 23 Jan 2004 01:51:34 -0000 1.13 -+++ oleproxy.c 14 Mar 2004 09:24:39 -0000 -@@ -35,6 +35,7 @@ +retrieving revision 1.19 +diff -u -r1.19 oleproxy.c +--- oleproxy.c 12 Aug 2004 23:00:55 -0000 1.19 ++++ oleproxy.c 14 Aug 2004 20:13:00 -0000 +@@ -38,6 +38,7 @@ #include #include