mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 05:32:55 +00:00
Sync to Wine-20040716:
Mike McCormack <mike@codeweavers.com> - Fix a few serious race conditions in the OLE object pipe server. - Add some explanations to compobj.c, implement flushing message queue on shutdown. Francois Gouget <fgouget@free.fr> - Assorted spelling fixes. Marcus Meissner <marcus@jet.franken.de> - IMalloc vtables are static. - IID_IObjectWithSite is already in libuuid, no need to declare here. Aric Stewart <aric@codeweavers.com> - Return an error in CoMarshalInterface if the IUnknown pointer is NULL and don't crash. Ivan Leo Puoti <puoti@inwind.it> - Removed the winedefault.reg message. Robert Shearman <rob@codeweavers.com> - Add static to non-exported marshal functions. - Remove unused marshal functions. - Rename several RPC functions. svn path=/trunk/; revision=10431
This commit is contained in:
parent
66219a7d31
commit
d0bf3394ea
5 changed files with 120 additions and 69 deletions
|
@ -4,8 +4,9 @@
|
||||||
* Copyright 1995 Martin von Loewis
|
* Copyright 1995 Martin von Loewis
|
||||||
* Copyright 1998 Justin Bradford
|
* Copyright 1998 Justin Bradford
|
||||||
* Copyright 1999 Francis Beaudet
|
* Copyright 1999 Francis Beaudet
|
||||||
* Copyright 1999 Sylvain St-Germain
|
* Copyright 1999 Sylvain St-Germain
|
||||||
* Copyright 2002 Marcus Meissner
|
* Copyright 2002 Marcus Meissner
|
||||||
|
* Copyright 2004 Mike Hearn
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -118,10 +119,10 @@ static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0,
|
||||||
* This section contains OpenDllList definitions
|
* This section contains OpenDllList definitions
|
||||||
*
|
*
|
||||||
* The OpenDllList contains only handles of dll loaded by CoGetClassObject or
|
* The OpenDllList contains only handles of dll loaded by CoGetClassObject or
|
||||||
* other functions what do LoadLibrary _without_ giving back a HMODULE.
|
* other functions that do LoadLibrary _without_ giving back a HMODULE.
|
||||||
* Without this list these handles would be freed never.
|
* Without this list these handles would never be freed.
|
||||||
*
|
*
|
||||||
* FIXME: a DLL what says OK whenn asked for unloading is unloaded in the
|
* FIXME: a DLL that says OK when asked for unloading is unloaded in the
|
||||||
* next unload-call but not before 600 sec.
|
* next unload-call but not before 600 sec.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -147,14 +148,17 @@ static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARA
|
||||||
static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
|
static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
|
||||||
static void COMPOBJ_DllList_FreeUnused(int Timeout);
|
static void COMPOBJ_DllList_FreeUnused(int Timeout);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Initialize/Unitialize threading stuff.
|
|
||||||
*/
|
|
||||||
void COMPOBJ_InitProcess( void )
|
void COMPOBJ_InitProcess( void )
|
||||||
{
|
{
|
||||||
WNDCLASSA wclass;
|
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.
|
||||||
|
*/
|
||||||
memset(&wclass, 0, sizeof(wclass));
|
memset(&wclass, 0, sizeof(wclass));
|
||||||
wclass.lpfnWndProc = &COM_AptWndProc;
|
wclass.lpfnWndProc = &COM_AptWndProc;
|
||||||
wclass.hInstance = OLE32_hInstance;
|
wclass.hInstance = OLE32_hInstance;
|
||||||
|
@ -170,10 +174,22 @@ void COMPOBJ_UninitProcess( void )
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Manage apartments.
|
* Manage apartments.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* The multi-threaded apartment (MTA) contains zero or more threads interacting
|
||||||
|
with free threaded (ie thread safe) COM objects. There is only ever one MTA
|
||||||
|
in a process - you can enter it by calling CoInitializeEx(COINIT_MULTITHREADED)
|
||||||
|
*/
|
||||||
static void COM_InitMTA(void)
|
static void COM_InitMTA(void)
|
||||||
{
|
{
|
||||||
/* FIXME: how does windoze create OXIDs?
|
/* OXIDs are object exporter IDs. Each apartment has an OXID, which is unique
|
||||||
* this method will only work for local RPC */
|
within a network. That is, two different MTAs on different machines will have
|
||||||
|
different OXIDs.
|
||||||
|
|
||||||
|
This method of generating an OXID is therefore wrong as it doesn't work across
|
||||||
|
a network, but for local RPC only it's OK. We can distinguish between MTAs and
|
||||||
|
STAs because STAs use the thread ID as well, and no thread can have an ID of zero.
|
||||||
|
*/
|
||||||
MTA.oxid = ((OXID)GetCurrentProcessId() << 32);
|
MTA.oxid = ((OXID)GetCurrentProcessId() << 32);
|
||||||
InitializeCriticalSection(&MTA.cs);
|
InitializeCriticalSection(&MTA.cs);
|
||||||
}
|
}
|
||||||
|
@ -204,6 +220,7 @@ APARTMENT* COM_CreateApartment(DWORD model)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
apt = NtCurrentTeb()->ReservedForOle;
|
apt = NtCurrentTeb()->ReservedForOle;
|
||||||
|
|
||||||
apt->model = model;
|
apt->model = model;
|
||||||
if (model & COINIT_APARTMENTTHREADED) {
|
if (model & COINIT_APARTMENTTHREADED) {
|
||||||
/* FIXME: how does windoze create OXIDs? */
|
/* FIXME: how does windoze create OXIDs? */
|
||||||
|
@ -245,6 +262,8 @@ static void COM_DestroyApartment(APARTMENT *apt)
|
||||||
HeapFree(GetProcessHeap(), 0, apt);
|
HeapFree(GetProcessHeap(), 0, apt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The given OXID must be local to this process: you cannot use apartment
|
||||||
|
windows to send RPCs to other processes */
|
||||||
HWND COM_GetApartmentWin(OXID oxid)
|
HWND COM_GetApartmentWin(OXID oxid)
|
||||||
{
|
{
|
||||||
APARTMENT *apt;
|
APARTMENT *apt;
|
||||||
|
@ -258,6 +277,7 @@ HWND COM_GetApartmentWin(OXID oxid)
|
||||||
return win;
|
return 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)
|
static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||||
|
@ -378,8 +398,8 @@ HRESULT WINAPI CoInitialize(
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* S_OK if successful,
|
* S_OK if successful,
|
||||||
* S_FALSE if this function was called already.
|
* S_FALSE if this function was called already.
|
||||||
* RPC_E_CHANGED_MODE if a previous call to CoInitialize specified another
|
* RPC_E_CHANGED_MODE if a previous call to CoInitializeEx specified another
|
||||||
* threading model.
|
* threading model.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI CoInitializeEx(
|
HRESULT WINAPI CoInitializeEx(
|
||||||
LPVOID lpReserved, /* [in] pointer to win32 malloc interface
|
LPVOID lpReserved, /* [in] pointer to win32 malloc interface
|
||||||
|
@ -402,7 +422,9 @@ HRESULT WINAPI CoInitializeEx(
|
||||||
{
|
{
|
||||||
if (dwCoInit != apt->model)
|
if (dwCoInit != apt->model)
|
||||||
{
|
{
|
||||||
WARN("Apartment threading model already initialized with another model\n");
|
/* Changing the threading model after it's been set is illegal. If this warning is triggered by Wine
|
||||||
|
code then we are probably using the wrong threading model to implement that API. */
|
||||||
|
WARN("Attempt to change threading model of this apartment from 0x%lx to 0x%lx\n", apt->model, dwCoInit);
|
||||||
return RPC_E_CHANGED_MODE;
|
return RPC_E_CHANGED_MODE;
|
||||||
}
|
}
|
||||||
hr = S_FALSE;
|
hr = S_FALSE;
|
||||||
|
@ -436,6 +458,25 @@ HRESULT WINAPI CoInitializeEx(
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On COM finalization for a STA thread, the message queue is flushed to ensure no
|
||||||
|
pending RPCs are ignored. Non-COM messages are discarded at this point.
|
||||||
|
*/
|
||||||
|
void COM_FlushMessageQueue(void)
|
||||||
|
{
|
||||||
|
MSG message;
|
||||||
|
APARTMENT *apt = NtCurrentTeb()->ReservedForOle;
|
||||||
|
|
||||||
|
if (!apt || !apt->win) return;
|
||||||
|
|
||||||
|
TRACE("Flushing STA message queue\n");
|
||||||
|
|
||||||
|
while (PeekMessageA(&message, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
if (message.hwnd != apt->win) continue;
|
||||||
|
TranslateMessage(&message);
|
||||||
|
DispatchMessageA(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CoUninitialize [OLE32.@]
|
* CoUninitialize [OLE32.@]
|
||||||
*
|
*
|
||||||
|
@ -466,27 +507,22 @@ void WINAPI CoUninitialize(void)
|
||||||
lCOMRefCnt = InterlockedExchangeAdd(&s_COMLockCount,-1);
|
lCOMRefCnt = InterlockedExchangeAdd(&s_COMLockCount,-1);
|
||||||
if (lCOMRefCnt==1)
|
if (lCOMRefCnt==1)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Release the various COM libraries and data structures.
|
|
||||||
*/
|
|
||||||
TRACE("() - Releasing the COM libraries\n");
|
TRACE("() - Releasing the COM libraries\n");
|
||||||
|
|
||||||
RunningObjectTableImpl_UnInitialize();
|
RunningObjectTableImpl_UnInitialize();
|
||||||
/*
|
|
||||||
* Release the references to the registered class objects.
|
/* Release the references to the registered class objects */
|
||||||
*/
|
|
||||||
COM_RevokeAllClasses();
|
COM_RevokeAllClasses();
|
||||||
|
|
||||||
/*
|
/* This will free the loaded COM Dlls */
|
||||||
* This will free the loaded COM Dlls.
|
|
||||||
*/
|
|
||||||
CoFreeAllLibraries();
|
CoFreeAllLibraries();
|
||||||
|
|
||||||
/*
|
/* This will free list of external references to COM objects */
|
||||||
* This will free list of external references to COM objects.
|
|
||||||
*/
|
|
||||||
COM_ExternalLockFreeList();
|
COM_ExternalLockFreeList();
|
||||||
|
|
||||||
|
/* This ensures we deal with any pending RPCs */
|
||||||
|
COM_FlushMessageQueue();
|
||||||
|
|
||||||
COM_UninitMTA();
|
COM_UninitMTA();
|
||||||
}
|
}
|
||||||
else if (lCOMRefCnt<1) {
|
else if (lCOMRefCnt<1) {
|
||||||
|
@ -498,10 +534,17 @@ void WINAPI CoUninitialize(void)
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* CoDisconnectObject [COMPOBJ.15]
|
* CoDisconnectObject [COMPOBJ.15]
|
||||||
* CoDisconnectObject [OLE32.@]
|
* CoDisconnectObject [OLE32.@]
|
||||||
|
*
|
||||||
|
* Disconnects all connections to this object from remote processes. Dispatches
|
||||||
|
* pending RPCs while blocking new RPCs from occurring, and then calls
|
||||||
|
* IMarshal::DisconnectObject on the given object.
|
||||||
|
*
|
||||||
|
* Typically called when the object server is forced to shut down, for instance by
|
||||||
|
* the user.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
||||||
{
|
{
|
||||||
TRACE("(%p, %lx)\n",lpUnk,reserved);
|
FIXME("(%p, %lx): stub - probably harmless\n",lpUnk,reserved);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,10 +864,14 @@ HRESULT WINAPI CLSIDFromProgID(
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* CoGetPSClsid [OLE32.@]
|
* CoGetPSClsid [OLE32.@]
|
||||||
*
|
*
|
||||||
* This function returns the CLSID of the DLL that implements the proxy and stub
|
* This function returns the CLSID of the proxy/stub factory that implements IPSFactoryBuffer
|
||||||
* for the specified interface.
|
* for the specified interface.
|
||||||
*
|
*
|
||||||
* It determines this by searching the
|
* The standard marshaller activates the object with the CLSID returned and uses the
|
||||||
|
* CreateProxy and CreateStub methods on its IPSFactoryBuffer interface to construct
|
||||||
|
* the proxies and stubs for a given object.
|
||||||
|
*
|
||||||
|
* CoGetPSClsid determines this CLSID by searching the
|
||||||
* HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32 in the registry
|
* HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32 in the registry
|
||||||
* and any interface id registered by CoRegisterPSClsid within the current process.
|
* and any interface id registered by CoRegisterPSClsid within the current process.
|
||||||
*
|
*
|
||||||
|
@ -1047,36 +1094,41 @@ _LocalServerThread(LPVOID param) {
|
||||||
}
|
}
|
||||||
IStream_Release(pStm);
|
IStream_Release(pStm);
|
||||||
|
|
||||||
while (1) {
|
hPipe = CreateNamedPipeA( pipefn, PIPE_ACCESS_DUPLEX,
|
||||||
hPipe = CreateNamedPipeA(
|
PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
|
||||||
pipefn,
|
4096, 4096, NMPWAIT_USE_DEFAULT_WAIT, NULL );
|
||||||
PIPE_ACCESS_DUPLEX,
|
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
PIPE_TYPE_BYTE|PIPE_WAIT,
|
FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
|
||||||
PIPE_UNLIMITED_INSTANCES,
|
return 1;
|
||||||
4096,
|
|
||||||
4096,
|
|
||||||
NMPWAIT_USE_DEFAULT_WAIT,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
|
||||||
FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!ConnectNamedPipe(hPipe,NULL)) {
|
|
||||||
ERR("Failure during ConnectNamedPipe %lx, ABORT!\n",GetLastError());
|
|
||||||
CloseHandle(hPipe);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
WriteFile(hPipe,buffer,buflen,&res,NULL);
|
|
||||||
CloseHandle(hPipe);
|
|
||||||
}
|
}
|
||||||
|
while (1) {
|
||||||
|
if (!ConnectNamedPipe(hPipe,NULL)) {
|
||||||
|
ERR("Failure during ConnectNamedPipe %lx, ABORT!\n",GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
WriteFile(hPipe,buffer,buflen,&res,NULL);
|
||||||
|
FlushFileBuffers(hPipe);
|
||||||
|
DisconnectNamedPipe(hPipe);
|
||||||
|
}
|
||||||
|
CloseHandle(hPipe);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* CoRegisterClassObject [OLE32.@]
|
* CoRegisterClassObject [OLE32.@]
|
||||||
*
|
*
|
||||||
* This method will register the class object for a given class ID.
|
* This method will register the class object for a given class ID. Servers housed
|
||||||
|
* in EXE files use this method instead of exporting DllGetClassObject to allow other
|
||||||
|
* code to connect to their objects.
|
||||||
|
*
|
||||||
|
* When a class object (an object which implements IClassFactory) is registered in
|
||||||
|
* this way, a new thread is started which listens for connections on a named pipe
|
||||||
|
* specific to the registered CLSID. When something else connects to it, it writes
|
||||||
|
* out the marshalled IClassFactory interface to the pipe. The code on the other end
|
||||||
|
* uses this buffer to unmarshal the class factory, and can then call methods on it.
|
||||||
|
*
|
||||||
|
* In Windows, such objects are registered with the RPC endpoint mapper, not with
|
||||||
|
* a unique named pipe.
|
||||||
*
|
*
|
||||||
* See the Windows documentation for more details.
|
* See the Windows documentation for more details.
|
||||||
*/
|
*/
|
||||||
|
@ -1103,6 +1155,9 @@ HRESULT WINAPI CoRegisterClassObject(
|
||||||
/*
|
/*
|
||||||
* First, check if the class is already registered.
|
* First, check if the class is already registered.
|
||||||
* If it is, this should cause an error.
|
* If it is, this should cause an error.
|
||||||
|
*
|
||||||
|
* MSDN claims that multiple interface registrations are legal, but we can't do that with
|
||||||
|
* our current implementation.
|
||||||
*/
|
*/
|
||||||
hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
|
hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
|
||||||
if (hr == S_OK) {
|
if (hr == S_OK) {
|
||||||
|
@ -1323,7 +1378,7 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
return create_marshalled_proxy(rclsid,iid,ppv);
|
return create_marshalled_proxy(rclsid,iid,ppv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally try remote */
|
/* Finally try remote: this requires networked DCOM (a lot of work) */
|
||||||
if (CLSCTX_REMOTE_SERVER & dwClsContext)
|
if (CLSCTX_REMOTE_SERVER & dwClsContext)
|
||||||
{
|
{
|
||||||
FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
|
FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
|
||||||
|
@ -1339,7 +1394,7 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI CoResumeClassObjects(void)
|
HRESULT WINAPI CoResumeClassObjects(void)
|
||||||
{
|
{
|
||||||
FIXME("\n");
|
FIXME("stub\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1396,7 +1451,7 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* if the obove strategies fail then search for the extension key in the registry */
|
/* if the above strategies fail then search for the extension key in the registry */
|
||||||
|
|
||||||
/* get the last element (absolute file) in the path name */
|
/* get the last element (absolute file) in the path name */
|
||||||
nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
|
nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
|
||||||
|
|
|
@ -45,7 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(olemalloc);
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/* set the vtable later */
|
/* set the vtable later */
|
||||||
extern ICOM_VTABLE(IMalloc) VT_IMalloc32;
|
static ICOM_VTABLE(IMalloc) VT_IMalloc32;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ICOM_VFIELD(IMalloc);
|
ICOM_VFIELD(IMalloc);
|
||||||
|
@ -361,7 +361,7 @@ static ICOM_VTABLE(IMalloc) VT_IMalloc32 =
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/* set the vtable later */
|
/* set the vtable later */
|
||||||
extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
|
static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ICOM_VFIELD(IMallocSpy);
|
ICOM_VFIELD(IMallocSpy);
|
||||||
|
|
|
@ -453,6 +453,10 @@ CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
|
||||||
TRACE("(%p, %s, %p, %lx, %p, %lx)\n",
|
TRACE("(%p, %s, %p, %lx, %p, %lx)\n",
|
||||||
pStm,debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags
|
pStm,debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (pUnk == NULL)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
STUBMGR_Start(); /* Just to be sure we have one running. */
|
STUBMGR_Start(); /* Just to be sure we have one running. */
|
||||||
mid.processid = GetCurrentProcessId();
|
mid.processid = GetCurrentProcessId();
|
||||||
IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
|
IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
|
||||||
|
@ -482,17 +486,11 @@ CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
|
||||||
}
|
}
|
||||||
hres = IMarshal_MarshalInterface(pMarshal,pStm,riid,pUnk,dwDestContext,pvDestContext,mshlflags);
|
hres = IMarshal_MarshalInterface(pMarshal,pStm,riid,pUnk,dwDestContext,pvDestContext,mshlflags);
|
||||||
if (hres) {
|
if (hres) {
|
||||||
if (IsEqualGUID(riid,&IID_IClassFactory)) {
|
if (IsEqualGUID(riid,&IID_IOleObject)) {
|
||||||
MESSAGE("\nERROR: You need to merge the 'winedefault.reg' file into your\n");
|
ERR("WINE currently cannot marshal IOleObject interfaces. This means you cannot embed/link OLE objects between applications.\n");
|
||||||
MESSAGE(" Wine registry by running: `regedit winedefault.reg'\n\n");
|
|
||||||
} else {
|
} else {
|
||||||
if (IsEqualGUID(riid,&IID_IOleObject)) {
|
FIXME("Failed to marshal the interface %s, %lx?\n",debugstr_guid(riid),hres);
|
||||||
ERR("WINE currently cannot marshal IOleObject interfaces. This means you cannot embed/link OLE objects between applications.\n");
|
|
||||||
} else {
|
|
||||||
FIXME("Failed to marshal the interface %s, %lx?\n",debugstr_guid(riid),hres);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
goto release_marshal;
|
|
||||||
}
|
}
|
||||||
release_marshal:
|
release_marshal:
|
||||||
IMarshal_Release(pMarshal);
|
IMarshal_Release(pMarshal);
|
||||||
|
|
|
@ -466,9 +466,6 @@ static IID const IID_IFontEventsDisp = {
|
||||||
static IID const IID_IProvideMultipleClassInfo = {
|
static IID const IID_IProvideMultipleClassInfo = {
|
||||||
0xA7ABA9C1, 0x8983, 0x11CF, {0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64} };
|
0xA7ABA9C1, 0x8983, 0x11CF, {0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64} };
|
||||||
|
|
||||||
static IID const IID_IObjectWithSite = {
|
|
||||||
0xFC4801A3, 0x2BA9, 0x11CF, {0xA2,0x29,0x00,0xAA,0x00,0x3D,0x73,0x52} };
|
|
||||||
|
|
||||||
static struct regsvr_interface const interface_list[] = {
|
static struct regsvr_interface const interface_list[] = {
|
||||||
{ &IID_IUnknown,
|
{ &IID_IUnknown,
|
||||||
"IUnknown",
|
"IUnknown",
|
||||||
|
|
|
@ -512,6 +512,7 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) {
|
||||||
WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
|
WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
|
||||||
|
|
||||||
while (tries++<MAXTRIES) {
|
while (tries++<MAXTRIES) {
|
||||||
|
WaitNamedPipeA( pipefn, NMPWAIT_WAIT_FOREVER );
|
||||||
hPipe = CreateFileA(
|
hPipe = CreateFileA(
|
||||||
pipefn,
|
pipefn,
|
||||||
GENERIC_READ|GENERIC_WRITE,
|
GENERIC_READ|GENERIC_WRITE,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue