Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
28356337
Commit
28356337
authored
Jan 04, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Jan 04, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement proxy manager.
parent
ffc55dad
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
314 additions
and
81 deletions
+314
-81
compobj.c
dlls/ole32/compobj.c
+9
-8
compobj_private.h
dlls/ole32/compobj_private.h
+15
-14
marshal.c
dlls/ole32/marshal.c
+290
-59
No files found.
dlls/ole32/compobj.c
View file @
28356337
...
@@ -226,6 +226,7 @@ APARTMENT* COM_CreateApartment(DWORD model)
...
@@ -226,6 +226,7 @@ APARTMENT* COM_CreateApartment(DWORD model)
else
else
apt
=
NtCurrentTeb
()
->
ReservedForOle
;
apt
=
NtCurrentTeb
()
->
ReservedForOle
;
list_init
(
&
apt
->
proxies
);
list_init
(
&
apt
->
stubmgrs
);
list_init
(
&
apt
->
stubmgrs
);
apt
->
oidc
=
1
;
apt
->
oidc
=
1
;
...
@@ -263,6 +264,14 @@ static void COM_DestroyApartment(APARTMENT *apt)
...
@@ -263,6 +264,14 @@ static void COM_DestroyApartment(APARTMENT *apt)
apt
->
prev
=
NULL
;
apt
->
next
=
NULL
;
apt
->
prev
=
NULL
;
apt
->
next
=
NULL
;
LeaveCriticalSection
(
&
csApartment
);
LeaveCriticalSection
(
&
csApartment
);
if
(
apt
->
model
&
COINIT_APARTMENTTHREADED
)
{
if
(
apt
->
model
&
COINIT_APARTMENTTHREADED
)
{
/* disconnect proxies to release the corresponding stubs.
* It is confirmed in "Essential COM" in the sub-chapter on
* "Lifecycle Management and Marshalling" that the native version also
* disconnects proxies in this function. */
/* FIXME: this should also be called for MTA destruction, but that
* requires restructuring how apartments work slightly. */
MARSHAL_Disconnect_Proxies
(
apt
);
if
(
apt
->
win
)
DestroyWindow
(
apt
->
win
);
if
(
apt
->
win
)
DestroyWindow
(
apt
->
win
);
DeleteCriticalSection
(
&
apt
->
cs
);
DeleteCriticalSection
(
&
apt
->
cs
);
}
}
...
@@ -545,14 +554,6 @@ void WINAPI CoUninitialize(void)
...
@@ -545,14 +554,6 @@ void WINAPI CoUninitialize(void)
RunningObjectTableImpl_UnInitialize
();
RunningObjectTableImpl_UnInitialize
();
/* disconnect proxies to release the corresponding stubs.
* It is confirmed in "Essential COM" in the sub-chapter on
* "Lifecycle Management and Marshalling" that the native version also
* does some kind of proxy cleanup in this function.
* FIXME: does it just disconnect or completely destroy the proxies?
* FIXME: should this be in the apartment destructor? */
MARSHAL_Disconnect_Proxies
();
/* Release the references to the registered class objects */
/* Release the references to the registered class objects */
COM_RevokeAllClasses
();
COM_RevokeAllClasses
();
...
...
dlls/ole32/compobj_private.h
View file @
28356337
...
@@ -68,29 +68,30 @@ typedef struct tagXOBJECT {
...
@@ -68,29 +68,30 @@ typedef struct tagXOBJECT {
DWORD
refs
;
/* external reference count */
DWORD
refs
;
/* external reference count */
}
XOBJECT
;
}
XOBJECT
;
/* imported interface */
/* imported interface proxy */
typedef
struct
tagIIF
{
struct
ifproxy
struct
tagIIF
*
next
;
{
struct
list
entry
;
LPVOID
iface
;
/* interface pointer */
LPVOID
iface
;
/* interface pointer */
IID
iid
;
/* interface ID */
IID
iid
;
/* interface ID */
IPID
ipid
;
/* imported interface ID */
IPID
ipid
;
/* imported interface ID */
LPRPCPROXYBUFFER
proxy
;
/* interface proxy */
LPRPCPROXYBUFFER
proxy
;
/* interface proxy */
DWORD
refs
;
/* imported (public) references */
DWORD
refs
;
/* imported (public) references */
HRESULT
hres
;
/* result of proxy creation attempt */
};
}
IIF
;
/* imported object */
/* imported object / proxy manager */
typedef
struct
tagIOBJECT
{
struct
proxy_manager
IRemUnknownVtbl
*
lpVtbl
;
{
const
IInternalUnknownVtbl
*
lpVtbl
;
struct
tagAPARTMENT
*
parent
;
struct
tagAPARTMENT
*
parent
;
struct
tagIOBJECT
*
next
;
struct
list
entry
;
LPRPCCHANNELBUFFER
chan
;
/* channel to object */
LPRPCCHANNELBUFFER
chan
;
/* channel to object */
OXID
oxid
;
/* object exported ID */
OXID
oxid
;
/* object exported ID */
OID
oid
;
/* object ID */
OID
oid
;
/* object ID */
IPID
ipid
;
/* first imported interface ID */
struct
list
interfaces
;
/* imported interfaces */
IIF
*
ifaces
;
/* imported interfaces */
DWORD
refs
;
/* proxy reference count */
DWORD
refs
;
/* proxy reference count */
}
IOBJECT
;
CRITICAL_SECTION
cs
;
/* thread safety for this object and children */
};
/* apartment */
/* apartment */
typedef
struct
tagAPARTMENT
{
typedef
struct
tagAPARTMENT
{
...
@@ -105,7 +106,7 @@ typedef struct tagAPARTMENT {
...
@@ -105,7 +106,7 @@ typedef struct tagAPARTMENT {
CRITICAL_SECTION
cs
;
/* thread safety */
CRITICAL_SECTION
cs
;
/* thread safety */
LPMESSAGEFILTER
filter
;
/* message filter */
LPMESSAGEFILTER
filter
;
/* message filter */
XOBJECT
*
objs
;
/* exported objects */
XOBJECT
*
objs
;
/* exported objects */
IOBJECT
*
proxies
;
/* imported objects */
struct
list
proxies
;
/* imported objects */
LPUNKNOWN
state
;
/* state object (see Co[Get,Set]State) */
LPUNKNOWN
state
;
/* state object (see Co[Get,Set]State) */
LPVOID
ErrorInfo
;
/* thread error info */
LPVOID
ErrorInfo
;
/* thread error info */
DWORD
listenertid
;
/* id of apartment_listener_thread */
DWORD
listenertid
;
/* id of apartment_listener_thread */
...
@@ -139,7 +140,7 @@ MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
...
@@ -139,7 +140,7 @@ MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
;
;
}
}
HRESULT
MARSHAL_Disconnect_Proxies
(
void
);
HRESULT
MARSHAL_Disconnect_Proxies
(
APARTMENT
*
apt
);
HRESULT
MARSHAL_GetStandardMarshalCF
(
LPVOID
*
ppv
);
HRESULT
MARSHAL_GetStandardMarshalCF
(
LPVOID
*
ppv
);
/* an interface stub */
/* an interface stub */
...
...
dlls/ole32/marshal.c
View file @
28356337
...
@@ -81,14 +81,6 @@ typedef struct _wine_marshal_data {
...
@@ -81,14 +81,6 @@ typedef struct _wine_marshal_data {
DWORD
mshlflags
;
DWORD
mshlflags
;
}
wine_marshal_data
;
}
wine_marshal_data
;
typedef
struct
_mid2unknown
{
wine_marshal_id
mid
;
LPUNKNOWN
pUnk
;
}
mid2unknown
;
static
mid2unknown
*
proxies
=
NULL
;
static
int
nrofproxies
=
0
;
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
)
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
)
{
{
struct
stub_manager
*
m
;
struct
stub_manager
*
m
;
...
@@ -132,40 +124,285 @@ static HRESULT register_ifstub(wine_marshal_id *mid, IUnknown *obj, IRpcStubBuff
...
@@ -132,40 +124,285 @@ static HRESULT register_ifstub(wine_marshal_id *mid, IUnknown *obj, IRpcStubBuff
return
ifstub
?
S_OK
:
E_OUTOFMEMORY
;
return
ifstub
?
S_OK
:
E_OUTOFMEMORY
;
}
}
HRESULT
MARSHAL_Disconnect_Proxies
()
{
int
i
;
TRACE
(
"Disconnecting %d proxies
\n
"
,
nrofproxies
);
for
(
i
=
0
;
i
<
nrofproxies
;
i
++
)
/* Client-side identity of the server object */
IRpcProxyBuffer_Disconnect
((
IRpcProxyBuffer
*
)
proxies
[
i
].
pUnk
);
static
void
proxy_manager_destroy
(
struct
proxy_manager
*
This
);
static
HRESULT
proxy_manager_find_ifproxy
(
struct
proxy_manager
*
This
,
REFIID
riid
,
struct
ifproxy
**
ifproxy_found
);
static
HRESULT
WINAPI
ClientIdentity_QueryInterface
(
IInternalUnknown
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
struct
proxy_manager
*
This
=
(
struct
proxy_manager
*
)
iface
;
HRESULT
hr
;
struct
ifproxy
*
ifproxy
;
TRACE
(
"%s
\n
"
,
debugstr_guid
(
riid
));
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IInternalUnknown
))
{
*
ppv
=
(
void
*
)
iface
;
IInternalUnknown_AddRef
(
iface
);
return
S_OK
;
}
hr
=
proxy_manager_find_ifproxy
(
This
,
riid
,
&
ifproxy
);
if
(
hr
==
S_OK
)
{
*
ppv
=
ifproxy
->
iface
;
IUnknown_AddRef
((
IUnknown
*
)
*
ppv
);
return
S_OK
;
return
S_OK
;
}
FIXME
(
"interface not found %s
\n
"
,
debugstr_guid
(
riid
));
/* FIXME: call IRemUnknown::RemQueryInterface */
return
E_NOINTERFACE
;
}
}
static
HRESULT
static
ULONG
WINAPI
ClientIdentity_AddRef
(
IInternalUnknown
*
iface
)
MARSHAL_Register_Proxy
(
wine_marshal_id
*
mid
,
LPUNKNOWN
punk
)
{
{
int
i
;
struct
proxy_manager
*
This
=
(
struct
proxy_manager
*
)
iface
;
TRACE
(
"%p
\n
"
,
iface
);
return
InterlockedIncrement
(
&
This
->
refs
);
}
for
(
i
=
0
;
i
<
nrofproxies
;
i
++
)
{
static
ULONG
WINAPI
ClientIdentity_Release
(
IInternalUnknown
*
iface
)
if
(
MARSHAL_Compare_Mids
(
mid
,
&
(
proxies
[
i
].
mid
)))
{
{
/* this will happen if the program attempts to marshal two
struct
proxy_manager
*
This
=
(
struct
proxy_manager
*
)
iface
;
* objects that implement the same interface */
ULONG
refs
=
InterlockedDecrement
(
&
This
->
refs
);
TRACE
(
"%p
\n
"
,
iface
);
if
(
!
refs
)
proxy_manager_destroy
(
This
);
return
refs
;
}
FIXME
(
"need to use IPIDs, already have mid oxid=%s, oid=%s, iid=%s
\n
"
,
static
HRESULT
WINAPI
ClientIdentity_QueryInternalInterface
(
IInternalUnknown
*
iface
,
REFIID
riid
,
void
**
ppv
)
wine_dbgstr_longlong
(
mid
->
oxid
),
wine_dbgstr_longlong
(
mid
->
oid
),
debugstr_guid
(
&
mid
->
iid
));
{
return
E_FAIL
;
FIXME
(
"(%s, %p): stub!
\n
"
,
debugstr_guid
(
riid
),
ppv
);
return
E_NOINTERFACE
;
}
static
const
IInternalUnknownVtbl
ClientIdentity_Vtbl
=
{
ClientIdentity_QueryInterface
,
ClientIdentity_AddRef
,
ClientIdentity_Release
,
ClientIdentity_QueryInternalInterface
};
static
HRESULT
ifproxy_get_public_ref
(
struct
ifproxy
*
This
)
{
/* FIXME: call IRemUnknown::RemAddRef if necessary */
return
S_OK
;
}
static
HRESULT
ifproxy_release_public_refs
(
struct
ifproxy
*
This
)
{
/* FIXME: call IRemUnknown::RemRelease */
return
S_OK
;
}
static
void
ifproxy_disconnect
(
struct
ifproxy
*
This
)
{
IRpcProxyBuffer_Disconnect
(
This
->
proxy
);
}
static
void
ifproxy_destroy
(
struct
ifproxy
*
This
)
{
/* release public references to this object so that the stub can know
* when to destroy itself */
ifproxy_release_public_refs
(
This
);
list_remove
(
&
This
->
entry
);
if
(
This
->
proxy
)
IRpcProxyBuffer_Release
(
This
->
proxy
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
static
HRESULT
proxy_manager_construct
(
APARTMENT
*
apt
,
OXID
oxid
,
OID
oid
,
IRpcChannelBuffer
*
channel
,
struct
proxy_manager
**
proxy_manager
)
{
struct
proxy_manager
*
This
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
This
));
if
(
!
This
)
return
E_OUTOFMEMORY
;
This
->
lpVtbl
=
&
ClientIdentity_Vtbl
;
list_init
(
&
This
->
entry
);
list_init
(
&
This
->
interfaces
);
InitializeCriticalSection
(
&
This
->
cs
);
/* the apartment the object was unmarshaled into */
This
->
parent
=
apt
;
/* the source apartment and id of the object */
This
->
oxid
=
oxid
;
This
->
oid
=
oid
;
This
->
refs
=
0
;
/* will be incremented on creation of first proxy */
This
->
chan
=
channel
;
/* FIXME: we should take the binding strings and construct the channel in this function */
EnterCriticalSection
(
&
apt
->
cs
);
list_add_head
(
&
apt
->
proxies
,
&
This
->
entry
);
LeaveCriticalSection
(
&
apt
->
cs
);
*
proxy_manager
=
This
;
return
S_OK
;
}
static
HRESULT
proxy_manager_create_ifproxy
(
struct
proxy_manager
*
This
,
IPID
ipid
,
REFIID
riid
,
ULONG
cPublicRefs
,
struct
ifproxy
**
iif_out
)
{
HRESULT
hr
;
IPSFactoryBuffer
*
psfb
;
struct
ifproxy
*
ifproxy
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
ifproxy
));
if
(
!
ifproxy
)
return
E_OUTOFMEMORY
;
list_init
(
&
ifproxy
->
entry
);
ifproxy
->
ipid
=
ipid
;
ifproxy
->
iid
=
*
riid
;
ifproxy
->
refs
=
cPublicRefs
;
ifproxy
->
proxy
=
NULL
;
hr
=
get_facbuf_for_iid
(
riid
,
&
psfb
);
if
(
hr
==
S_OK
)
{
/* important note: the outer unknown is set to the proxy manager.
* This ensures the COM identity rules are not violated, by having a
* one-to-one mapping of objects on the proxy side to objects on the
* stub side, no matter which interface you view the object through */
hr
=
IPSFactoryBuffer_CreateProxy
(
psfb
,
(
IUnknown
*
)
&
This
->
lpVtbl
,
riid
,
&
ifproxy
->
proxy
,
&
ifproxy
->
iface
);
IPSFactoryBuffer_Release
(
psfb
);
}
}
if
(
hr
==
S_OK
)
hr
=
IRpcProxyBuffer_Connect
(
ifproxy
->
proxy
,
This
->
chan
);
/* get at least one external reference to the object to keep it alive */
if
(
hr
==
S_OK
)
hr
=
ifproxy_get_public_ref
(
ifproxy
);
if
(
hr
==
S_OK
)
{
EnterCriticalSection
(
&
This
->
cs
);
list_add_tail
(
&
This
->
interfaces
,
&
ifproxy
->
entry
);
LeaveCriticalSection
(
&
This
->
cs
);
*
iif_out
=
ifproxy
;
}
}
if
(
nrofproxies
)
proxies
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
proxies
,
sizeof
(
proxies
[
0
])
*
(
nrofproxies
+
1
));
else
else
proxies
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
proxies
[
0
]));
ifproxy_destroy
(
ifproxy
);
memcpy
(
&
(
proxies
[
nrofproxies
].
mid
),
mid
,
sizeof
(
*
mid
));
proxies
[
nrofproxies
].
pUnk
=
punk
;
return
hr
;
nrofproxies
++
;
}
IUnknown_AddRef
(
punk
);
static
HRESULT
proxy_manager_find_ifproxy
(
struct
proxy_manager
*
This
,
REFIID
riid
,
struct
ifproxy
**
ifproxy_found
)
{
HRESULT
hr
=
E_NOINTERFACE
;
/* assume not found */
struct
list
*
cursor
;
EnterCriticalSection
(
&
This
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
This
->
interfaces
)
{
struct
ifproxy
*
ifproxy
=
LIST_ENTRY
(
cursor
,
struct
ifproxy
,
entry
);
if
(
IsEqualIID
(
riid
,
&
ifproxy
->
iid
))
{
*
ifproxy_found
=
ifproxy
;
hr
=
S_OK
;
break
;
}
}
LeaveCriticalSection
(
&
This
->
cs
);
return
hr
;
}
static
void
proxy_manager_disconnect
(
struct
proxy_manager
*
This
)
{
struct
list
*
cursor
;
EnterCriticalSection
(
&
This
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
This
->
interfaces
)
{
struct
ifproxy
*
ifproxy
=
LIST_ENTRY
(
cursor
,
struct
ifproxy
,
entry
);
ifproxy_disconnect
(
ifproxy
);
}
/* apartment is being destroyed so don't keep a pointer around to it */
This
->
parent
=
NULL
;
LeaveCriticalSection
(
&
This
->
cs
);
}
static
void
proxy_manager_destroy
(
struct
proxy_manager
*
This
)
{
struct
list
*
cursor
;
if
(
This
->
parent
)
{
EnterCriticalSection
(
&
This
->
parent
->
cs
);
/* remove ourself from the list of proxy objects in the apartment */
LIST_FOR_EACH
(
cursor
,
&
This
->
parent
->
proxies
)
{
if
(
cursor
==
&
This
->
entry
)
{
list_remove
(
&
This
->
entry
);
break
;
}
}
LeaveCriticalSection
(
&
This
->
parent
->
cs
);
}
/* destroy all of the interface proxies */
while
(
!
(
cursor
=
list_head
(
&
This
->
interfaces
)))
{
struct
ifproxy
*
ifproxy
=
LIST_ENTRY
(
cursor
,
struct
ifproxy
,
entry
);
ifproxy_destroy
(
ifproxy
);
}
DeleteCriticalSection
(
&
This
->
cs
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
static
BOOL
find_proxy_manager
(
APARTMENT
*
apt
,
OXID
oxid
,
OID
oid
,
struct
proxy_manager
**
proxy_found
)
{
BOOL
found
=
FALSE
;
struct
list
*
cursor
;
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
apt
->
proxies
)
{
struct
proxy_manager
*
proxy
=
LIST_ENTRY
(
cursor
,
struct
proxy_manager
,
entry
);
if
((
oxid
==
proxy
->
oxid
)
&&
(
oid
==
proxy
->
oid
))
{
*
proxy_found
=
proxy
;
found
=
TRUE
;
break
;
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
return
found
;
}
HRESULT
MARSHAL_Disconnect_Proxies
(
APARTMENT
*
apt
)
{
struct
list
*
cursor
;
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
apt
->
proxies
)
{
struct
proxy_manager
*
proxy
=
LIST_ENTRY
(
cursor
,
struct
proxy_manager
,
entry
);
proxy_manager_disconnect
(
proxy
);
}
LeaveCriticalSection
(
&
apt
->
cs
);
return
S_OK
;
return
S_OK
;
}
}
...
@@ -302,11 +539,14 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
...
@@ -302,11 +539,14 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
wine_marshal_data
md
;
wine_marshal_data
md
;
ULONG
res
;
ULONG
res
;
HRESULT
hres
;
HRESULT
hres
;
IPSFactoryBuffer
*
psfacbuf
;
IRpcProxyBuffer
*
rpcproxy
;
IRpcChannelBuffer
*
chanbuf
;
IRpcChannelBuffer
*
chanbuf
;
struct
proxy_manager
*
proxy_manager
;
APARTMENT
*
apt
=
COM_CurrentApt
();
TRACE
(
"(...,%s,....)
\n
"
,
debugstr_guid
(
riid
));
TRACE
(
"(...,%s,....)
\n
"
,
debugstr_guid
(
riid
));
if
(
!
apt
)
return
CO_E_NOTINITIALIZED
;
hres
=
IStream_Read
(
pStm
,
&
mid
,
sizeof
(
mid
),
&
res
);
hres
=
IStream_Read
(
pStm
,
&
mid
,
sizeof
(
mid
),
&
res
);
if
(
hres
)
return
hres
;
if
(
hres
)
return
hres
;
hres
=
IStream_Read
(
pStm
,
&
md
,
sizeof
(
md
),
&
res
);
hres
=
IStream_Read
(
pStm
,
&
md
,
sizeof
(
md
),
&
res
);
...
@@ -327,35 +567,26 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
...
@@ -327,35 +567,26 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
return
hres
;
return
hres
;
}
}
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_NULL
))
{
if
(
!
find_proxy_manager
(
apt
,
mid
.
oxid
,
mid
.
oid
,
&
proxy_manager
))
/* should return proxy manager IUnknown object */
{
FIXME
(
"Special treatment required for IID of %s
\n
"
,
debugstr_guid
(
riid
));
hres
=
PIPE_GetNewPipeBuf
(
&
mid
,
&
chanbuf
);
}
if
(
hres
==
S_OK
)
hres
=
get_facbuf_for_iid
(
riid
,
&
psfacbuf
);
hres
=
proxy_manager_construct
(
apt
,
mid
.
oxid
,
mid
.
oid
,
chanbuf
,
&
proxy_manager
);
if
(
hres
)
return
hres
;
hres
=
IPSFactoryBuffer_CreateProxy
(
psfacbuf
,
NULL
,
riid
,
&
rpcproxy
,
ppv
);
if
(
hres
)
{
FIXME
(
"Failed to create a proxy for %s
\n
"
,
debugstr_guid
(
riid
));
return
hres
;
}
}
MARSHAL_Register_Proxy
(
&
mid
,
(
LPUNKNOWN
)
rpcproxy
);
if
(
hres
==
S_OK
)
{
hres
=
PIPE_GetNewPipeBuf
(
&
mid
,
&
chanbuf
);
struct
ifproxy
*
ifproxy
;
IPSFactoryBuffer_Release
(
psfacbuf
);
hres
=
proxy_manager_find_ifproxy
(
proxy_manager
,
riid
,
&
ifproxy
);
if
(
hres
)
{
if
(
hres
==
S_OK
)
ERR
(
"Failed to get an rpc channel buffer for %s
\n
"
,
debugstr_guid
(
riid
));
IUnknown_AddRef
((
IUnknown
*
)
ifproxy
->
iface
);
}
else
{
else
if
(
hres
==
E_NOINTERFACE
)
/* Connect the channel buffer to the proxy and release the no longer
hres
=
proxy_manager_create_ifproxy
(
proxy_manager
,
mid
.
iid
/* FIXME: ipid */
,
riid
,
1
,
&
ifproxy
);
* needed proxy.
* NOTE: The proxy should have taken an extra reference because it also
if
(
hres
==
S_OK
)
* aggregates the object, so we can safely release our reference to it. */
*
ppv
=
ifproxy
->
iface
;
/* AddRef'd above */
IRpcProxyBuffer_Connect
(
rpcproxy
,
chanbuf
);
IRpcProxyBuffer_Release
(
rpcproxy
);
/* IRpcProxyBuffer takes a reference on the channel buffer and
* we no longer need it, so release it */
IRpcChannelBuffer_Release
(
chanbuf
);
}
}
return
hres
;
return
hres
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment