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
6036a773
Commit
6036a773
authored
Jan 14, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Jan 14, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- The apartment reference should be held while the stub manager
reference is held. - Fix same apartment-unmarshal detection.
parent
3bc93806
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
101 additions
and
65 deletions
+101
-65
compobj_private.h
dlls/ole32/compobj_private.h
+2
-2
marshal.c
dlls/ole32/marshal.c
+51
-14
rpc.c
dlls/ole32/rpc.c
+10
-1
stubmanager.c
dlls/ole32/stubmanager.c
+37
-47
marshal.c
dlls/ole32/tests/marshal.c
+1
-1
No files found.
dlls/ole32/compobj_private.h
View file @
6036a773
...
...
@@ -183,8 +183,8 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);
ULONG
stub_manager_ext_release
(
struct
stub_manager
*
m
,
ULONG
refs
);
IRpcStubBuffer
*
stub_manager_ipid_to_stubbuffer
(
struct
stub_manager
*
m
,
const
IPID
*
iid
);
struct
ifstub
*
stub_manager_new_ifstub
(
struct
stub_manager
*
m
,
IRpcStubBuffer
*
sb
,
IUnknown
*
iptr
,
REFIID
iid
,
BOOL
tablemarshal
);
struct
stub_manager
*
get_stub_manager
(
OXID
oxid
,
OID
oid
);
struct
stub_manager
*
get_stub_manager_from_object
(
OXID
oxid
,
void
*
object
);
struct
stub_manager
*
get_stub_manager
(
APARTMENT
*
apt
,
OID
oid
);
struct
stub_manager
*
get_stub_manager_from_object
(
APARTMENT
*
apt
,
void
*
object
);
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
);
...
...
dlls/ole32/marshal.c
View file @
6036a773
...
...
@@ -79,9 +79,16 @@ get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
)
{
IRpcStubBuffer
*
ret
;
APARTMENT
*
apt
;
struct
stub_manager
*
m
;
if
(
!
(
m
=
get_stub_manager
(
mid
->
oxid
,
mid
->
oid
)))
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
mid
->
oxid
,
TRUE
)))
{
WARN
(
"Could not map OXID %s to apartment object
\n
"
,
wine_dbgstr_longlong
(
mid
->
oxid
));
return
NULL
;
}
if
(
!
(
m
=
get_stub_manager
(
apt
,
mid
->
oid
)))
{
WARN
(
"unknown OID %s
\n
"
,
wine_dbgstr_longlong
(
mid
->
oid
));
return
NULL
;
...
...
@@ -90,6 +97,9 @@ IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid)
ret
=
stub_manager_ipid_to_stubbuffer
(
m
,
&
mid
->
ipid
);
stub_manager_int_release
(
m
);
COM_ApartmentRelease
(
apt
);
return
ret
;
}
...
...
@@ -98,23 +108,30 @@ static HRESULT register_ifstub(wine_marshal_id *mid, REFIID riid, IUnknown *obj,
{
struct
stub_manager
*
manager
=
NULL
;
struct
ifstub
*
ifstub
;
APARTMENT
*
apt
;
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
mid
->
oxid
,
TRUE
)))
{
ERR
(
"Could not map OXID %s to apartment object
\n
"
,
wine_dbgstr_longlong
(
mid
->
oxid
));
return
E_UNEXPECTED
;
}
/* mid->oid of zero means create a new stub manager */
if
(
mid
->
oid
&&
(
manager
=
get_stub_manager
(
mid
->
oxid
,
mid
->
oid
)))
if
(
mid
->
oid
&&
(
manager
=
get_stub_manager
(
apt
,
mid
->
oid
)))
{
TRACE
(
"registering new ifstub on pre-existing manager
\n
"
);
}
else
{
struct
apartment
*
apt
;
TRACE
(
"constructing new stub manager
\n
"
);
apt
=
COM_ApartmentFromOXID
(
mid
->
oxid
,
TRUE
);
manager
=
new_stub_manager
(
apt
,
obj
);
COM_ApartmentRelease
(
apt
);
if
(
!
manager
)
return
E_OUTOFMEMORY
;
if
(
!
manager
)
{
COM_ApartmentRelease
(
apt
);
return
E_OUTOFMEMORY
;
}
mid
->
oid
=
manager
->
oid
;
}
...
...
@@ -125,6 +142,7 @@ static HRESULT register_ifstub(wine_marshal_id *mid, REFIID riid, IUnknown *obj,
stub_manager_int_release
(
manager
);
/* FIXME: should we do another release to completely destroy the
* stub manager? */
COM_ApartmentRelease
(
apt
);
return
E_OUTOFMEMORY
;
}
...
...
@@ -133,6 +151,7 @@ static HRESULT register_ifstub(wine_marshal_id *mid, REFIID riid, IUnknown *obj,
mid
->
ipid
=
ifstub
->
ipid
;
stub_manager_int_release
(
manager
);
COM_ApartmentRelease
(
apt
);
return
S_OK
;
}
...
...
@@ -489,9 +508,16 @@ StdMarshalImpl_MarshalInterface(
IPSFactoryBuffer
*
psfacbuf
;
BOOL
tablemarshal
;
struct
stub_manager
*
manager
;
APARTMENT
*
apt
=
COM_CurrentApt
();
TRACE
(
"(...,%s,...)
\n
"
,
debugstr_guid
(
riid
));
if
(
!
apt
)
{
ERR
(
"Apartment not initialized
\n
"
);
return
CO_E_NOTINITIALIZED
;
}
start_apartment_listener_thread
();
/* just to be sure we have one running. */
hres
=
get_facbuf_for_iid
(
riid
,
&
psfacbuf
);
...
...
@@ -508,11 +534,11 @@ StdMarshalImpl_MarshalInterface(
if
(
tablemarshal
)
FIXME
(
"table marshalling unimplemented
\n
"
);
/* now fill out the MID */
mid
.
oxid
=
COM_CurrentApt
()
->
oxid
;
mid
.
oxid
=
apt
->
oxid
;
IUnknown_QueryInterface
((
LPUNKNOWN
)
pv
,
riid
,
(
LPVOID
*
)
&
pUnk
);
if
((
manager
=
get_stub_manager_from_object
(
mid
.
oxid
,
pUnk
)))
if
((
manager
=
get_stub_manager_from_object
(
apt
,
pUnk
)))
{
mid
.
oid
=
manager
->
oid
;
stub_manager_int_release
(
manager
);
...
...
@@ -551,14 +577,17 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
TRACE
(
"(...,%s,....)
\n
"
,
debugstr_guid
(
riid
));
if
(
!
apt
)
return
CO_E_NOTINITIALIZED
;
if
(
!
apt
)
{
ERR
(
"Apartment not initialized
\n
"
);
return
CO_E_NOTINITIALIZED
;
}
hres
=
IStream_Read
(
pStm
,
&
mid
,
sizeof
(
mid
),
&
res
);
if
(
hres
)
return
hres
;
/* check if we're marshalling back to ourselves */
/* FIXME: commented out until we can get the tests passing with it uncommented. */
if
(
/*(apt->oxid == mid.oxid) &&*/
(
stubmgr
=
get_stub_manager
(
mid
.
oxid
,
mid
.
oid
)))
if
((
apt
->
oxid
==
mid
.
oxid
)
&&
(
stubmgr
=
get_stub_manager
(
apt
,
mid
.
oid
)))
{
TRACE
(
"Unmarshalling object marshalled in same apartment for iid %s, returning original object %p
\n
"
,
debugstr_guid
(
riid
),
stubmgr
->
object
);
...
...
@@ -600,13 +629,20 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
ULONG
res
;
HRESULT
hres
;
struct
stub_manager
*
stubmgr
;
APARTMENT
*
apt
;
TRACE
(
"iface=%p, pStm=%p
\n
"
,
iface
,
pStm
);
hres
=
IStream_Read
(
pStm
,
&
mid
,
sizeof
(
mid
),
&
res
);
if
(
hres
)
return
hres
;
if
(
!
(
stubmgr
=
get_stub_manager
(
mid
.
oxid
,
mid
.
oid
)))
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
mid
.
oxid
,
TRUE
)))
{
WARN
(
"Could not map OXID %s to apartment object
\n
"
,
wine_dbgstr_longlong
(
mid
.
oxid
));
return
RPC_E_INVALID_OBJREF
;
}
if
(
!
(
stubmgr
=
get_stub_manager
(
apt
,
mid
.
oid
)))
{
ERR
(
"could not map MID to stub manager, oxid=%s, oid=%s
\n
"
,
wine_dbgstr_longlong
(
mid
.
oxid
),
wine_dbgstr_longlong
(
mid
.
oid
));
...
...
@@ -616,6 +652,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
stub_manager_ext_release
(
stubmgr
,
1
);
stub_manager_int_release
(
stubmgr
);
COM_ApartmentRelease
(
apt
);
return
S_OK
;
}
...
...
dlls/ole32/rpc.c
View file @
6036a773
...
...
@@ -789,6 +789,7 @@ COM_RpcReceive(wine_pipe *xpipe) {
wine_rpc_disconnect_header
header
;
struct
stub_manager
*
stubmgr
;
DWORD
magic
=
0xcafebabe
;
APARTMENT
*
apt
;
hres
=
read_pipe
(
xhPipe
,
&
header
,
sizeof
(
header
));
if
(
hres
)
{
...
...
@@ -798,15 +799,23 @@ COM_RpcReceive(wine_pipe *xpipe) {
TRACE
(
"read disconnect header
\n
"
);
if
(
!
(
stubmgr
=
get_stub_manager
(
header
.
mid
.
oxid
,
header
.
mid
.
oid
)))
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
header
.
mid
.
oxid
,
TRUE
)))
{
ERR
(
"Could not map OXID %s to apartment object in disconnect
\n
"
,
wine_dbgstr_longlong
(
header
.
mid
.
oxid
));
goto
disconnect_end
;
}
if
(
!
(
stubmgr
=
get_stub_manager
(
apt
,
header
.
mid
.
oid
)))
{
ERR
(
"could not locate stub to disconnect, mid.oid=%s
\n
"
,
wine_dbgstr_longlong
(
header
.
mid
.
oid
));
COM_ApartmentRelease
(
apt
);
goto
disconnect_end
;
}
stub_manager_ext_release
(
stubmgr
,
1
);
stub_manager_int_release
(
stubmgr
);
COM_ApartmentRelease
(
apt
);
disconnect_end:
write_pipe
(
xhPipe
,
&
magic
,
sizeof
(
magic
));
...
...
dlls/ole32/stubmanager.c
View file @
6036a773
...
...
@@ -107,26 +107,50 @@ static void stub_manager_delete(struct stub_manager *m)
HeapFree
(
GetProcessHeap
(),
0
,
m
);
}
/* gets the stub manager associated with an object - caller must call
* release on the stub manager when it is no longer needed */
struct
stub_manager
*
get_stub_manager_from_object
(
OXID
oxid
,
void
*
object
)
/* gets the stub manager associated with an object - caller must have
* a reference to the apartment while a reference to the stub manager is held.
* it must also call release on the stub manager when it is no longer needed */
struct
stub_manager
*
get_stub_manager_from_object
(
APARTMENT
*
apt
,
void
*
object
)
{
struct
stub_manager
*
result
=
NULL
;
struct
list
*
cursor
;
APARTMENT
*
apt
;
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
oxid
,
TRUE
)))
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
apt
->
stubmgrs
)
{
WARN
(
"Could not map OXID %s to apartment object
\n
"
,
wine_dbgstr_longlong
(
oxid
));
return
NULL
;
struct
stub_manager
*
m
=
LIST_ENTRY
(
cursor
,
struct
stub_manager
,
entry
);
if
(
m
->
object
==
object
)
{
result
=
m
;
stub_manager_int_addref
(
result
);
break
;
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
if
(
result
)
TRACE
(
"found %p for object %p
\n
"
,
result
,
object
);
else
TRACE
(
"not found for object %p
\n
"
,
object
);
return
result
;
}
/* gets the stub manager associated with an object id - caller must have
* a reference to the apartment while a reference to the stub manager is held.
* it must also call release on the stub manager when it is no longer needed */
struct
stub_manager
*
get_stub_manager
(
APARTMENT
*
apt
,
OID
oid
)
{
struct
stub_manager
*
result
=
NULL
;
struct
list
*
cursor
;
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
apt
->
stubmgrs
)
{
struct
stub_manager
*
m
=
LIST_ENTRY
(
cursor
,
struct
stub_manager
,
entry
);
if
(
m
->
o
bject
==
object
)
if
(
m
->
o
id
==
oid
)
{
result
=
m
;
stub_manager_int_addref
(
result
);
...
...
@@ -135,11 +159,12 @@ struct stub_manager *get_stub_manager_from_object(OXID oxid, void *object)
}
LeaveCriticalSection
(
&
apt
->
cs
);
COM_ApartmentRelease
(
apt
);
TRACE
(
"found %p from object %p
\n
"
,
result
,
object
);
if
(
result
)
TRACE
(
"found %p for oid %s
\n
"
,
result
,
wine_dbgstr_longlong
(
oid
));
else
TRACE
(
"not found for oid %s
\n
"
,
wine_dbgstr_longlong
(
oid
));
return
result
;
return
result
;
}
/* increments the internal refcount */
...
...
@@ -174,41 +199,6 @@ ULONG stub_manager_int_release(struct stub_manager *This)
return
refs
;
}
/* gets the stub manager associated with an object id - caller must call
* release on the stub manager when it is no longer needed */
struct
stub_manager
*
get_stub_manager
(
OXID
oxid
,
OID
oid
)
{
struct
stub_manager
*
result
=
NULL
;
struct
list
*
cursor
;
APARTMENT
*
apt
;
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
oxid
,
TRUE
)))
{
WARN
(
"Could not map OXID %s to apartment object
\n
"
,
wine_dbgstr_longlong
(
oxid
));
return
NULL
;
}
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH
(
cursor
,
&
apt
->
stubmgrs
)
{
struct
stub_manager
*
m
=
LIST_ENTRY
(
cursor
,
struct
stub_manager
,
entry
);
if
(
m
->
oid
==
oid
)
{
result
=
m
;
stub_manager_int_addref
(
result
);
break
;
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
COM_ApartmentRelease
(
apt
);
TRACE
(
"found %p from oid %s
\n
"
,
result
,
wine_dbgstr_longlong
(
oid
));
return
result
;
}
/* add some external references (ie from a client that unmarshaled an ifptr) */
ULONG
stub_manager_ext_addref
(
struct
stub_manager
*
m
,
ULONG
refs
)
{
...
...
dlls/ole32/tests/marshal.c
View file @
6036a773
...
...
@@ -317,7 +317,7 @@ static void test_marshal_stub_apartment_shutdown()
end_host_object
(
tid
,
thread
);
todo_wine
{
ok_no_locks
();
}
ok_no_locks
();
IUnknown_Release
(
pProxy
);
...
...
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