Sync to Wine-20050310: Jon Griffiths jon_p_griffiths@yahoo.com - Documentation spelling fixes. Mike McCormack mike@codeweavers.com - Implement and test IPropertySetStorage. - Fix more incorrect uses of STGM_ enumerations. - Add struct StorageBaseImpl at the start of derived structures instead of trying to keep the first members the same. - StgOpenStorage shouldn't open zero length storage files. - Shared reading of storage files requires STGM_TRANSACTED. - Test and fix grfMode handling in StgOpenDocfile. - Implement StgSetTimes. Robert Shearman rob@codeweavers.com - Better tracing. - Small cleanup of creation functions. - Rename apartment functions to become more object-oriented. - Rename register_ifstub to marshal_object to more accurately describe what it does. - Add new function, apartment_getoxid, to prepare for a possible future patch where remoting is started on demand. - Move marshaling state machine into stub manager from ifstub. - Add additional needed states for table-weak marshaling, as shown by tests. - Protect external reference count from underflows/overflows. - Make COM use the RPC runtime as the backend for RPC calls. Based on a patch by Ove Ksven. - Invoke objects in STA's in the correct thread by sending messages to the hidden apartment window. - Use I_RpcGetBuffer, instead of our own buffer routines to fix an occasional test crash caused by heap corruption. - Zero the memory block passed to RpcServerRegisterIfEx so we don't pass garbage in some of the fields we don't fill in. - Return the correct error code from create_server and fix two handle leaks. - TODO update. - Remove cruft left over from previous RPC backend implementation in the apartment structure. - Don't pass an IPID by value for proxy_manager_create_ifproxy. - Disable more of RPC_UnregisterInterface to prevent the RPC runtime using freed memory. - Rename various external RPC backend functions so that they all have the same "RPC_" prefix. - Reduce the timeout of the function that connects to a local server to 30s, like native. - Make each ifproxy have its own channel buffer to fix a bug where a proxy with multiple interfaces could invoke the wrong stub buffer on the server. - The Global Interface Table should do table-strong marshaling instead of normal marshaling so that an interface can be retrieved more than one time. Mike Hearn mh@codeweavers.com - Avoid infinite loop when doing a typelib marshalled IUnknown::QueryInterface by only doing an extra QI if requested IID is not equal to marshalled IID. Rob Shearman rob@codeweavers.com Mike Hearn mh@codeweavers.com - Add re-entrancy tests to the test suite. - Run RPCs on a new thread client side so we can pump the message loop. Juan Lang juan_lang@yahoo.com - Fix the calling convention of DllCanUnloadNow. - Move vtbl to end of file and get rid of unnecessary prototypes. - Implement StgCreatePropSetStg. Joris Huizer jorishuizer@planet.nl - A few memory checks avoiding memory leaks. Francois Gouget fgouget@free.fr - Assorted spelling fixes. Paul Vriens Paul.Vriens@xs4all.nl - Added some TRACE statements. Modified: trunk/reactos/lib/ole32/Makefile.in Modified: trunk/reactos/lib/ole32/clipboard.c Modified: trunk/reactos/lib/ole32/compobj.c Modified: trunk/reactos/lib/ole32/compobj_private.h Modified: trunk/reactos/lib/ole32/errorinfo.c Modified: trunk/reactos/lib/ole32/filemoniker.c Modified: trunk/reactos/lib/ole32/git.c Modified: trunk/reactos/lib/ole32/itemmoniker.c Modified: trunk/reactos/lib/ole32/marshal.c Modified: trunk/reactos/lib/ole32/ole2.c Modified: trunk/reactos/lib/ole32/ole32.spec Modified: trunk/reactos/lib/ole32/oleproxy.c Modified: trunk/reactos/lib/ole32/rpc.c Modified: trunk/reactos/lib/ole32/stg_bigblockfile.c Added: trunk/reactos/lib/ole32/stg_prop.c Modified: trunk/reactos/lib/ole32/stg_stream.c Modified: trunk/reactos/lib/ole32/storage32.c Modified: trunk/reactos/lib/ole32/storage32.h Modified: trunk/reactos/lib/ole32/stubmanager.c _____
Modified: trunk/reactos/lib/ole32/Makefile.in --- trunk/reactos/lib/ole32/Makefile.in 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/Makefile.in 2005-03-14 23:17:44 UTC (rev 14083) @@ -34,6 +34,7 @@
regsvr.c \ rpc.c \ stg_bigblockfile.c \ + stg_prop.c \ stg_stream.c \ storage32.c \ stubmanager.c _____
Modified: trunk/reactos/lib/ole32/clipboard.c --- trunk/reactos/lib/ole32/clipboard.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/clipboard.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -82,7 +82,7 @@
/* For CoGetMalloc (MEMCTX_TASK is currently ignored) */ #ifndef MEMCTX_TASK - #define MEMCTX_TASK -1 +# define MEMCTX_TASK -1 #endif
WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -799,7 +799,7 @@ * (Recall that in OleSetClipboard, we used SetClipboardData to * make all HGLOBAL formats supported by the source IDataObject * available using delayed rendering) - * On receiving this mesage we must actually render the data in the + * On receiving this message we must actually render the data in the * specified format and place it on the clipboard by calling the * SetClipboardData function. */ _____
Modified: trunk/reactos/lib/ole32/compobj.c --- trunk/reactos/lib/ole32/compobj.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/compobj.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -30,13 +30,12 @@
* * - Implement the service control manager (in rpcss) to keep track * of registered class objects: ISCM::ServerRegisterClsid et al - * - Implement the OXID resolver so we don't need magic pipe names for + * - Implement the OXID resolver so we don't need magic endpoint names for * clients and servers to meet up - * - Flip our marshalling on top of the RPC runtime transport API, - * so we no longer use named pipes to communicate - * - Implement RPC thread affinity (should fix InstallShield painting - * problems) * + * - Pump the message loop during RPC calls. + * - Call IMessageFilter functions. + * * - Make all ole interface marshaling use NDR to be wire compatible with * native DCOM * - Use & interpret ORPCTHIS & ORPCTHAT. @@ -163,7 +162,7 @@ }; static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };
-static const char aptWinClass[] = "WINE_OLE32_APT_CLASS"; +static const WCHAR wszAptWinClass[] = {'W','I','N','E','_','O','L','E','3','2','_','A','P','T','_','C','L','A' ,'S','S',0}; static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void COMPOBJ_DLLList_Add(HANDLE hLibrary); @@ -171,7 +170,7 @@
void COMPOBJ_InitProcess( void ) { - WNDCLASSA wclass; + WNDCLASSW wclass;
/* Dispatching to the correct thread in an apartment is done through * window messages rather than RPC transports. When an interface is @@ -183,15 +182,15 @@ * was unmarshalled. */ memset(&wclass, 0, sizeof(wclass)); - wclass.lpfnWndProc = &COM_AptWndProc; + wclass.lpfnWndProc = COM_AptWndProc; wclass.hInstance = OLE32_hInstance; - wclass.lpszClassName = aptWinClass; - RegisterClassA(&wclass); + wclass.lpszClassName = wszAptWinClass; + RegisterClassW(&wclass); }
void COMPOBJ_UninitProcess( void ) { - UnregisterClassA(aptWinClass, OLE32_hInstance); + UnregisterClassW(wszAptWinClass, OLE32_hInstance); }
void COM_TlsDestroy() @@ -239,7 +238,7 @@ { /* FIXME: should be randomly generated by in an RPC call to rpcss */ apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId(); - apt->win = CreateWindowA(aptWinClass, NULL, 0, + apt->win = CreateWindowW(wszAptWinClass, NULL, 0, 0, 0, 0, 0, 0, 0, OLE32_hInstance, NULL); } @@ -249,8 +248,6 @@ apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe; }
- apt->shutdown_event = CreateEventW(NULL, TRUE, FALSE, NULL); - TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));
/* the locking here is not currently needed for the MTA case, but it @@ -354,8 +351,6 @@ if (apt->filter) IUnknown_Release(apt->filter);
DeleteCriticalSection(&apt->cs); - SetEvent(apt->shutdown_event); - CloseHandle(apt->shutdown_event); CloseHandle(apt->thread); HeapFree(GetProcessHeap(), 0, apt); } @@ -425,10 +420,15 @@ return apt->win; }
-/* Currently inter-thread marshalling is not fully implemented, so this does nothing */ static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - return DefWindowProcA(hWnd, msg, wParam, lParam); + switch (msg) + { + case DM_EXECUTERPC: + return RPC_ExecuteCall((RPCOLEMESSAGE *)wParam, (IRpcStubBuffer *)lParam); + default: + return DefWindowProcW(hWnd, msg, wParam, lParam); + } }
/*********************************************************************** ****** @@ -473,7 +473,7 @@ static void COMPOBJ_DllList_FreeUnused(int Timeout) { OpenDll *curr, *next, *prev = NULL; - typedef HRESULT(*DllCanUnloadNowFunc)(void); + typedef HRESULT (WINAPI *DllCanUnloadNowFunc)(void); DllCanUnloadNowFunc DllCanUnloadNow;
TRACE("\n"); @@ -1629,7 +1629,7 @@ /* Next try out of process */ if (CLSCTX_LOCAL_SERVER & dwClsContext) { - return create_marshalled_proxy(rclsid,iid,ppv); + return RPC_GetLocalClassObject(rclsid,iid,ppv); }
/* Finally try remote: this requires networked DCOM (a lot of work) */ _____
Modified: trunk/reactos/lib/ole32/compobj_private.h --- trunk/reactos/lib/ole32/compobj_private.h 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/compobj_private.h 2005-03-14 23:17:44 UTC (rev 14083) @@ -53,10 +53,12 @@
typedef enum ifstub_state { - IFSTUB_STATE_NORMAL_MARSHALED, - IFSTUB_STATE_NORMAL_UNMARSHALED, - IFSTUB_STATE_TABLE_MARSHALED -} IFSTUB_STATE; + STUBSTATE_NORMAL_MARSHALED, + STUBSTATE_NORMAL_UNMARSHALED, + STUBSTATE_TABLE_WEAK_MARSHALED, + STUBSTATE_TABLE_WEAK_UNMARSHALED, + STUBSTATE_TABLE_STRONG, +} STUB_STATE;
/* an interface stub */ struct ifstub @@ -66,7 +68,6 @@ IID iid; /* RO */ IPID ipid; /* RO */ IUnknown *iface; /* RO */ - IFSTUB_STATE state; /* CS stub_manager->lock */ };
@@ -78,11 +79,12 @@ CRITICAL_SECTION lock; APARTMENT *apt; /* owning apt (RO) */
- ULONG extrefs; /* number of 'external' references (LOCK) */ + ULONG extrefs; /* number of 'external' references (CS lock) */ ULONG refs; /* internal reference count (CS apt->cs) */ OID oid; /* apartment-scoped unique identifier (RO) */ IUnknown *object; /* the object we are managing the stub for (RO) */ ULONG next_ipid; /* currently unused (LOCK) */ + STUB_STATE state; /* state machine (CS lock) */ };
/* imported interface proxy */ @@ -95,6 +97,7 @@ IPID ipid; /* imported interface ID (RO) */ LPRPCPROXYBUFFER proxy; /* interface proxy (RO) */ DWORD refs; /* imported (public) references (CS parent->cs) */ + IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */ };
/* imported object / proxy manager */ @@ -103,7 +106,6 @@ const IMultiQIVtbl *lpVtbl; struct apartment *parent; /* owning apartment (RO) */ struct list entry; /* entry in apartment (CS parent->cs) */ - LPRPCCHANNELBUFFER chan; /* channel to object (CS cs) */ OXID oxid; /* object exported ID (RO) */ OID oid; /* object ID (RO) */ struct list interfaces; /* imported interfaces (CS cs) */ @@ -130,11 +132,10 @@ struct list proxies; /* imported objects (CS cs) */ struct list stubmgrs; /* stub managers for exported objects (CS cs) */ BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */ + LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
- /* FIXME: These should all be removed long term as they leak information that should be encapsulated */ + /* FIXME: OID's should be given out by RPCSS */ OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */ - DWORD listenertid; /* id of apartment_listener_thread */ - HANDLE shutdown_event; /* event used to tell the client_dispatch_thread to shut down */ };
/* this is what is stored in TEB->ReservedForOle */ @@ -146,60 +147,50 @@ DWORD inits; /* number of times CoInitializeEx called */ };
+ +/* Global Interface Table Functions */ + extern void* StdGlobalInterfaceTable_Construct(void); extern void StdGlobalInterfaceTable_Destroy(void* self); extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv); +extern void* StdGlobalInterfaceTableInstance;
/* FIXME: these shouldn't be needed, except for 16-bit functions */ extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr); HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
-extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv); - -extern void* StdGlobalInterfaceTableInstance; - -/* Standard Marshalling definitions */ -typedef struct _wine_marshal_id { - OXID oxid; /* id of apartment */ - OID oid; /* id of stub manager */ - IPID ipid; /* id of interface pointer */ -} wine_marshal_id; - -inline static BOOL -MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) { - return - (mid1->oxid == mid2->oxid) && - (mid1->oid == mid2->oid) && - IsEqualGUID(&(mid1->ipid),&(mid2->ipid)) - ; -} - HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt); HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
+/* Stub Manager */ + ULONG stub_manager_int_addref(struct stub_manager *This); ULONG stub_manager_int_release(struct stub_manager *This); -struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object); +struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags); ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs); ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs); -struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, BOOL tablemarshal); +struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid); struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid); struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object); void apartment_disconnect_object(APARTMENT *apt, void *object); -BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid); -BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid); +BOOL stub_manager_notify_unmarshal(struct stub_manager *m); +BOOL stub_manager_is_table_marshaled(struct stub_manager *m); +void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs); HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags); HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret); -IRpcStubBuffer *ipid_to_stubbuffer(const IPID *ipid); +IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt); HRESULT start_apartment_remote_unknown(void);
-IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid); +/* RPC Backend */
-void start_apartment_listener_thread(void); +void RPC_StartRemoting(struct apartment *apt); +HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf); +HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub); +HRESULT RPC_RegisterInterface(REFIID riid); +void RPC_UnregisterInterface(REFIID riid); +void RPC_StartLocalServer(REFCLSID clsid, IStream *stream); +HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
-extern HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf); -void RPC_StartLocalServer(REFCLSID clsid, IStream *stream); - /* This function initialize the Running Object Table */ HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
@@ -209,12 +200,17 @@ /* This function decomposes a String path to a String Table containing all the elements ("" or "subDirectory" or "Directory" or "FileName") of the path */ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
-/* compobj.c */ + +/* Apartment Functions */ + APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref); APARTMENT *COM_ApartmentFromTID(DWORD tid); DWORD COM_ApartmentAddRef(struct apartment *apt); DWORD COM_ApartmentRelease(struct apartment *apt);
+/* messages used by the apartment window (not compatible with native) */ +#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = (RPCOLEMESSAGE *), LPARAM = (IRpcStubBuffer *) */ + /* * Per-thread values are stored in the TEB on offset 0xF80, * see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm _____
Modified: trunk/reactos/lib/ole32/errorinfo.c --- trunk/reactos/lib/ole32/errorinfo.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/errorinfo.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -386,11 +386,10 @@
LPOLESTR szHelpFile) { _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface); - TRACE("(%p)\n",This); + TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile)); if (This->bstrHelpFile != NULL) ERRORINFO_SysFreeString(This->bstrHelpFile); This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile); - return S_OK; }
@@ -399,9 +398,8 @@ DWORD dwHelpContext) { _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface); - TRACE("(%p)\n",This); + TRACE("(%p,%ld)\n",This,dwHelpContext); This->m_dwHelpContext = dwHelpContext; - return S_OK; }
_____
Modified: trunk/reactos/lib/ole32/filemoniker.c --- trunk/reactos/lib/ole32/filemoniker.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/filemoniker.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -157,7 +157,7 @@
{ FileMonikerImpl *This = (FileMonikerImpl *)iface;
- TRACE("(%p,%p,%p)\n",This,riid,ppvObject); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
/* Perform a sanity check on the parameters.*/ if ( (This==0) || (ppvObject==0) ) @@ -223,7 +223,7 @@ HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID)/* Pointer to CLSID of object */ { - TRACE("(%p,%p),stub!\n",iface,pClassID); + TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL) return E_POINTER; @@ -473,7 +473,7 @@ static const WCHAR bkSlash[]={'\',0}; BYTE addBkSlash;
- TRACE("(%p,%p)\n",This,lpszPathName); + TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
/* Initialize the virtual fgunction table. */ This->lpvtbl1 = &VT_FileMonikerImpl; @@ -566,7 +566,7 @@
*ppvResult=0;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult); + TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvRe sult);
if(pmkToLeft==NULL){
@@ -673,7 +673,7 @@ IStorage *pstg=0; HRESULT res;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject); + TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvOb ject);
if (pmkToLeft==NULL){
@@ -708,7 +708,7 @@ } else {
- FIXME("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject); + FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvOb ject);
return E_NOTIMPL; } @@ -1243,6 +1243,8 @@
strcpyW(*ppszDisplayName,This->filePathName);
+ TRACE("-- %s\n", debugstr_w(*ppszDisplayName)); + return S_OK; }
@@ -1283,7 +1285,7 @@
ICOM_THIS_From_IROTData(IMoniker, iface);
- TRACE("(%p,%p,%p)\n",This,riid,ppvObject); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
return FileMonikerImpl_QueryInterface(This, riid, ppvObject); } @@ -1329,29 +1331,28 @@
************************************************************************ ******/ HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk) { - FileMonikerImpl* newFileMoniker = 0; - HRESULT hr = E_FAIL; - IID riid=IID_IMoniker; + FileMonikerImpl* newFileMoniker; + HRESULT hr;
- TRACE("(%p,%p)\n",lpszPathName,ppmk); + TRACE("(%s,%p)\n",debugstr_w(lpszPathName),ppmk);
- if (ppmk==NULL) + if (!ppmk) return E_POINTER;
- if(lpszPathName==NULL) + if(!lpszPathName) return MK_E_SYNTAX;
- *ppmk=0; + *ppmk=NULL;
newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
- if (newFileMoniker == 0) + if (!newFileMoniker) return E_OUTOFMEMORY;
hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);
if (SUCCEEDED(hr)) - hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)p pmk); + hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&IID_IMoniker,( void**)ppmk); else HeapFree(GetProcessHeap(),0,newFileMoniker);
_____
Modified: trunk/reactos/lib/ole32/git.c --- trunk/reactos/lib/ole32/git.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/git.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -223,6 +223,7 @@
IStream* stream = NULL; HRESULT hres; StdGITEntry* entry; + static const LARGE_INTEGER zero;
TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
@@ -230,8 +231,18 @@
/* marshal the interface */ TRACE("About to marshal the interface\n"); - hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream); + + hres = CreateStreamOnHGlobal(0, TRUE, &stream); if (hres) return hres; + hres = CoMarshalInterface(stream, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG); + if (hres) + { + IStream_Release(stream); + return hres; + } + + IStream_Seek(stream, zero, SEEK_SET, NULL); + entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry)); if (entry == NULL) return E_OUTOFMEMORY;
@@ -261,6 +272,7 @@ HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) { StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface; StdGITEntry* entry; + HRESULT hr;
TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
@@ -271,6 +283,12 @@ }
/* Free the stream */ + hr = CoReleaseMarshalData(entry->stream); + if (hr != S_OK) + { + WARN("Failed to release marshal data, hr = 0x%08lx\n", hr); + return hr; + } IStream_Release(entry->stream); /* chop entry out of the list, and free the memory */ _____
Modified: trunk/reactos/lib/ole32/itemmoniker.c --- trunk/reactos/lib/ole32/itemmoniker.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/itemmoniker.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -156,7 +156,7 @@
{ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
- TRACE("(%p,%p,%p)\n",This,riid,ppvObject); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
/* Perform a sanity check on the parameters.*/ if ( (This==0) || (ppvObject==0) ) @@ -221,7 +221,7 @@
************************************************************************ ******/ HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) { - TRACE("(%p,%p),stub!\n",iface,pClassID); + TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL) return E_POINTER; @@ -257,6 +257,8 @@ CHAR *itemNameA,*itemDelimiterA; ULONG bread;
+ TRACE("\n"); + /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
/* read item delimiter string length + 1 */ @@ -335,6 +337,8 @@ WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL); WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
+ TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE"); + res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL); res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL); res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL); @@ -381,7 +385,7 @@ static const OLECHAR emptystr[1]; LPCOLESTR delim;
- TRACE("(%p,%p)\n",This,lpszItem); + TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
/* Initialize the virtual fgunction table. */ This->lpvtbl1 = &VT_ItemMonikerImpl; @@ -437,7 +441,7 @@ IID refid=IID_IOleItemContainer; IOleItemContainer *poic=0;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult); + TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvRe sult);
if(ppvResult ==NULL) return E_POINTER; @@ -473,7 +477,7 @@ HRESULT res; IOleItemContainer *poic=0;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult); + TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvRe sult);
*ppvResult=0;
@@ -781,6 +785,9 @@ HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { DWORD mkSys; + + TRACE("(%p,%p)\n", pmkOther, ppmkPrefix); + IMoniker_IsSystemMoniker(pmkOther,&mkSys); /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */ /* to this moniker and returns MK_S_US */ @@ -841,6 +848,8 @@ lstrcpyW(*ppszDisplayName,This->itemDelimiter); lstrcatW(*ppszDisplayName,This->itemName);
+ TRACE("-- %s\n", debugstr_w(*ppszDisplayName)); + return S_OK; }
@@ -860,6 +869,8 @@ HRESULT res; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+ TRACE("%s\n", debugstr_w(pszDisplayName)); + /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */ if (pmkToLeft==NULL)
@@ -955,15 +966,14 @@
************************************************************************ ******/ HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk) { - ItemMonikerImpl* newItemMoniker = 0; - HRESULT hr = S_OK; - IID riid=IID_IMoniker; + ItemMonikerImpl* newItemMoniker; + HRESULT hr;
- TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk); + TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);
newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
- if (newItemMoniker == 0) + if (!newItemMoniker) return STG_E_INSUFFICIENTMEMORY;
hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem); @@ -974,5 +984,5 @@ return hr; }
- return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)p pmk); + return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,( void**)ppmk); } _____
Modified: trunk/reactos/lib/ole32/marshal.c --- trunk/reactos/lib/ole32/marshal.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/marshal.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -117,13 +117,15 @@
stdobjref->oxid = apt->oxid;
+ /* FIXME: what happens if we register an interface twice with different + * marshaling flags? */ if ((manager = get_stub_manager_from_object(apt, obj))) TRACE("registering new ifstub on pre-existing manager\n"); else { TRACE("constructing new stub manager\n");
- manager = new_stub_manager(apt, obj); + manager = new_stub_manager(apt, obj, mshlflags); if (!manager) return E_OUTOFMEMORY; } @@ -131,7 +133,7 @@
tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
- ifstub = stub_manager_new_ifstub(manager, stub, obj, riid, tablemarshal); + ifstub = stub_manager_new_ifstub(manager, stub, obj, riid); if (!ifstub) { IRpcStubBuffer_Release(stub); @@ -153,6 +155,9 @@ stub_manager_ext_addref(manager, 1); }
+ /* FIXME: check return value */ + RPC_RegisterInterface(riid); + stdobjref->ipid = ifstub->ipid;
stub_manager_int_release(manager); @@ -372,12 +377,17 @@ return hr; }
+/* should be called inside This->parent->cs critical section */ static void ifproxy_disconnect(struct ifproxy * This) { ifproxy_release_public_refs(This); if (This->proxy) IRpcProxyBuffer_Disconnect(This->proxy); + + IRpcChannelBuffer_Release(This->chan); + This->chan = NULL; }
+/* should be called in This->parent->cs critical section if it is an entry in parent's list */ static void ifproxy_destroy(struct ifproxy * This) { TRACE("%p\n", This); @@ -388,6 +398,12 @@
list_remove(&This->entry);
+ if (This->chan) + { + IRpcChannelBuffer_Release(This->chan); + This->chan = NULL; + } + /* note: we don't call Release for This->proxy because its lifetime is * controlled by the return value from ClientIdentity_Release, which this * function is always called from */ @@ -397,7 +413,7 @@
static HRESULT proxy_manager_construct( APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid, - IRpcChannelBuffer * channel, struct proxy_manager ** proxy_manager) + struct proxy_manager ** proxy_manager) { struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) return E_OUTOFMEMORY; @@ -423,9 +439,6 @@ * should store the STDOBJREF flags in the proxy manager. */ This->sorflags = sorflags;
- assert(channel); - This->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */ - /* we create the IRemUnknown proxy on demand */ This->remunk = NULL;
@@ -473,8 +486,8 @@ }
static HRESULT proxy_manager_create_ifproxy( - struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs, - struct ifproxy ** iif_out) + struct proxy_manager * This, const IPID *ipid, REFIID riid, ULONG cPublicRefs, + IRpcChannelBuffer * channel, struct ifproxy ** iif_out) { HRESULT hr; IPSFactoryBuffer * psfb; @@ -484,11 +497,14 @@ list_init(&ifproxy->entry);
ifproxy->parent = This; - ifproxy->ipid = ipid; + ifproxy->ipid = *ipid; ifproxy->iid = *riid; ifproxy->refs = cPublicRefs; ifproxy->proxy = NULL;
+ assert(channel); + ifproxy->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */ + /* the IUnknown interface is special because it does not have a * proxy associated with the ifproxy as we handle IUnknown ourselves */ if (IsEqualIID(riid, &IID_IUnknown)) @@ -517,7 +533,7 @@ debugstr_guid(riid), hr);
if (hr == S_OK) - hr = IRpcProxyBuffer_Connect(ifproxy->proxy, This->chan); + hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan); }
/* get at least one external reference to the object to keep it alive */ @@ -532,7 +548,7 @@
*iif_out = ifproxy; TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n", - ifproxy, debugstr_guid(&ipid), debugstr_guid(riid), cPublicRefs); + ifproxy, debugstr_guid(ipid), debugstr_guid(riid), cPublicRefs); } else ifproxy_destroy(ifproxy); @@ -579,11 +595,6 @@ /* apartment is being destroyed so don't keep a pointer around to it */ This->parent = NULL;
- /* FIXME: will this still be necessary if/when we use a real RPC - * channel? */ - IRpcChannelBuffer_Release(This->chan); - This->chan = NULL; - LeaveCriticalSection(&This->cs); }
@@ -671,7 +682,6 @@ }
if (This->remunk) IRemUnknown_Release(This->remunk); - if (This->chan) IRpcChannelBuffer_Release(This->chan);
DeleteCriticalSection(&This->cs);
@@ -792,8 +802,8 @@ return CO_E_NOTINITIALIZED; }
- start_apartment_listener_thread(); /* just to be sure we have one running. */ - start_apartment_remote_unknown(); + /* make sure this apartment can be reached from other threads / processes */ + RPC_StartRemoting(apt);
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk); if (hres != S_OK) @@ -839,18 +849,9 @@ * object */ if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager)) { - IRpcChannelBuffer *chanbuf; - wine_marshal_id mid; - - mid.oxid = stdobjref->oxid; - mid.oid = stdobjref->oid; - mid.ipid = stdobjref->ipid; - - hr = PIPE_GetNewPipeBuf(&mid,&chanbuf); - if (hr == S_OK) - hr = proxy_manager_construct(apt, stdobjref->flags, - stdobjref->oxid, stdobjref->oid, - chanbuf, &proxy_manager); + hr = proxy_manager_construct(apt, stdobjref->flags, + stdobjref->oxid, stdobjref->oid, + &proxy_manager); } else TRACE("proxy manager already created, using\n"); @@ -860,9 +861,14 @@ struct ifproxy * ifproxy; hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy); if (hr == E_NOINTERFACE) - hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref->ipid, - riid, stdobjref->cPublicRefs, - &ifproxy); + { + IRpcChannelBuffer *chanbuf; + hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf); + if (hr == S_OK) + hr = proxy_manager_create_ifproxy(proxy_manager, &stdobjref->ipid, + riid, stdobjref->cPublicRefs, + chanbuf, &ifproxy); + }
if (hr == S_OK) { @@ -911,7 +917,7 @@ hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
/* unref the ifstub. FIXME: only do this on success? */ - if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid)) + if (!stub_manager_is_table_marshaled(stubmgr)) stub_manager_ext_release(stubmgr, 1);
stub_manager_int_release(stubmgr); @@ -927,7 +933,7 @@ { if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid))) { - if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid)) + if (!stub_manager_notify_unmarshal(stubmgr)) hres = CO_E_OBJNOTCONNECTED;
stub_manager_int_release(stubmgr); @@ -982,9 +988,7 @@ return RPC_E_INVALID_OBJREF; }
- /* FIXME: don't release if table-weak and already unmarshaled an object */ - /* FIXME: this should also depend on stdobjref.cPublicRefs */ - stub_manager_ext_release(stubmgr, 1); + stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs);
stub_manager_int_release(stubmgr); COM_ApartmentRelease(apt); @@ -1418,11 +1422,19 @@
if (hr == S_OK) { - hr = IUnknown_QueryInterface(object, &iid, ppv); - if (hr) - ERR("Couldn't query for interface %s, hr = 0x%08lx\n", - debugstr_guid(riid), hr); - IUnknown_Release(object); + if (!IsEqualIID(riid, &iid)) + { + TRACE("requested interface != marshalled interface, additional QI needed\n"); + hr = IUnknown_QueryInterface(object, &iid, ppv); + if (hr) + ERR("Couldn't query for interface %s, hr = 0x%08lx\n", + debugstr_guid(riid), hr); + IUnknown_Release(object); + } + else + { + *ppv = object; + } }
IMarshal_Release(pMarshal); _____
Modified: trunk/reactos/lib/ole32/ole2.c --- trunk/reactos/lib/ole32/ole2.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/ole2.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -1036,7 +1036,7 @@
* All menu messages from these groups should be routed to the server. * * RETURNS: TRUE if the popup menu is part of a server owned group - * FASE if the popup menu is part of a container owned group + * FALSE if the popup menu is part of a container owned group */ BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDescriptor ) { _____
Modified: trunk/reactos/lib/ole32/ole32.spec --- trunk/reactos/lib/ole32/ole32.spec 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/ole32.spec 2005-03-14 23:17:44 UTC (rev 14083) @@ -233,6 +233,7 @@
@ stub SNB_UserUnmarshal @ stdcall StgCreateDocfile(wstr long long ptr) @ stdcall StgCreateDocfileOnILockBytes(ptr long long ptr) +@ stdcall StgCreatePropSetStg(ptr long ptr) @ stdcall StgCreateStorageEx(wstr long long long ptr ptr ptr ptr) @ stub StgGetIFillLockBytesOnFile @ stub StgGetIFillLockBytesOnILockBytes _____
Modified: trunk/reactos/lib/ole32/oleproxy.c --- trunk/reactos/lib/ole32/oleproxy.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/oleproxy.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -191,10 +191,8 @@
msg->cbBuffer = ststg.cbSize.u.LowPart;
- if (msg->Buffer) - msg->Buffer = HeapReAlloc(GetProcessHeap(),0,msg->Buffer,ststg.cbSize.u.LowPart); - else - msg->Buffer = HeapAlloc(GetProcessHeap(),0,ststg.cbSize.u.LowPart); + I_RpcGetBuffer((RPC_MESSAGE *)msg); + if (hres) return hres;
seekto.u.LowPart = 0;seekto.u.HighPart = 0; hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); @@ -547,10 +545,10 @@
/* out */ pMsg->cbBuffer = cIids * sizeof(REMQIRESULT); - if (pMsg->Buffer) - pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer); - else - pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer); + + I_RpcGetBuffer((RPC_MESSAGE *)pMsg); + if (hr) return hr; + buf = pMsg->Buffer; /* FIXME: pQIResults is a unique pointer so pQIResults can be NULL! */ memcpy(buf, pQIResults, cIids * sizeof(REMQIRESULT)); @@ -574,13 +572,14 @@
/* out */ pMsg->cbBuffer = cIids * sizeof(HRESULT); - if (pMsg->Buffer) - pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer); - else - pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer); - buf = pMsg->Buffer; - memcpy(buf, pResults, cIids * sizeof(HRESULT));
+ I_RpcGetBuffer((RPC_MESSAGE *)pMsg); + if (!hr) + { + buf = pMsg->Buffer; + memcpy(buf, pResults, cIids * sizeof(HRESULT)); + } + CoTaskMemFree(pResults);
break; _____
Modified: trunk/reactos/lib/ole32/rpc.c --- trunk/reactos/lib/ole32/rpc.c 2005-03-14 22:56:02 UTC (rev 14082) +++ trunk/reactos/lib/ole32/rpc.c 2005-03-14 23:17:44 UTC (rev 14083) @@ -1,6 +1,7 @@
/* * (Local) RPC Stuff * + * Copyright 2001 Ove KÕven, TransGaming Technologies * Copyright 2002 Marcus Meissner * Copyright 2005 Mike Hearn, Rob Shearman for CodeWeavers * @@ -49,425 +50,530 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole); [truncated at 1000 lines; 2487 more skipped]