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
4c8d59dd
Commit
4c8d59dd
authored
Jan 17, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Jan 17, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement table marshaling.
parent
049e75a3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
166 additions
and
23 deletions
+166
-23
compobj.c
dlls/ole32/compobj.c
+2
-4
compobj_private.h
dlls/ole32/compobj_private.h
+14
-4
marshal.c
dlls/ole32/marshal.c
+83
-9
stubmanager.c
dlls/ole32/stubmanager.c
+64
-1
marshal.c
dlls/ole32/tests/marshal.c
+3
-5
No files found.
dlls/ole32/compobj.c
View file @
4c8d59dd
...
...
@@ -48,10 +48,8 @@
*
* - Implement IRemUnknown and marshalling for it, then use that for
* reffing/unreffing the stub manager from a proxy instead of our
* current hack of simply reffing the stub manager once when it's
* registered.
* - Implement table marshalling, then use it to let us do the final
* rework of the threading
* current hack of simply reaching into local process memory to do it,
* which obviously doesn't work inter-process.
*
* - Make our custom marshalling use NDR to be wire compatible with
* native DCOM
...
...
dlls/ole32/compobj_private.h
View file @
4c8d59dd
...
...
@@ -51,6 +51,13 @@ typedef struct apartment APARTMENT;
* must be used.
*/
typedef
enum
ifstub_state
{
IFSTUB_STATE_NORMAL_MARSHALED
,
IFSTUB_STATE_NORMAL_UNMARSHALED
,
IFSTUB_STATE_TABLE_MARSHALED
}
IFSTUB_STATE
;
/* an interface stub */
struct
ifstub
{
...
...
@@ -59,7 +66,7 @@ struct ifstub
IID
iid
;
/* RO */
IPID
ipid
;
/* RO */
IUnknown
*
iface
;
/* RO */
BOOL
tabl
e
;
/* CS stub_manager->lock */
IFSTUB_STATE
stat
e
;
/* CS stub_manager->lock */
};
...
...
@@ -81,12 +88,13 @@ struct stub_manager
/* imported interface proxy */
struct
ifproxy
{
struct
list
entry
;
struct
list
entry
;
/* entry in proxy_manager list (CS parent->cs) */
struct
proxy_manager
*
parent
;
/* owning proxy_manager (RO) */
LPVOID
iface
;
/* interface pointer (RO) */
IID
iid
;
/* interface ID (RO) */
IPID
ipid
;
/* imported interface ID (RO) */
LPRPCPROXYBUFFER
proxy
;
/* interface proxy (RO) */
DWORD
refs
;
/* imported (public) references (CS
?
) */
DWORD
refs
;
/* imported (public) references (CS
parent->cs
) */
};
/* imported object / proxy manager */
...
...
@@ -168,10 +176,12 @@ ULONG stub_manager_int_release(struct stub_manager *This);
struct
stub_manager
*
new_stub_manager
(
APARTMENT
*
apt
,
IUnknown
*
object
);
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
);
IRpcStubBuffer
*
stub_manager_ipid_to_stubbuffer
(
struct
stub_manager
*
m
,
const
IPID
*
i
p
id
);
struct
ifstub
*
stub_manager_new_ifstub
(
struct
stub_manager
*
m
,
IRpcStubBuffer
*
sb
,
IUnknown
*
iptr
,
REFIID
iid
,
BOOL
tablemarshal
);
struct
stub_manager
*
get_stub_manager
(
APARTMENT
*
apt
,
OID
oid
);
struct
stub_manager
*
get_stub_manager_from_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
);
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
);
...
...
dlls/ole32/marshal.c
View file @
4c8d59dd
...
...
@@ -104,11 +104,12 @@ IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid)
}
/* creates a new stub manager and sets mid->oid when mid->oid == 0 */
static
HRESULT
register_ifstub
(
wine_marshal_id
*
mid
,
REFIID
riid
,
IUnknown
*
obj
,
IRpcStubBuffer
*
stub
,
BOOL
tablemarshal
)
static
HRESULT
register_ifstub
(
wine_marshal_id
*
mid
,
REFIID
riid
,
IUnknown
*
obj
,
IRpcStubBuffer
*
stub
,
MSHLFLAGS
mshlflags
)
{
struct
stub_manager
*
manager
=
NULL
;
struct
ifstub
*
ifstub
;
APARTMENT
*
apt
;
BOOL
tablemarshal
;
if
(
!
(
apt
=
COM_ApartmentFromOXID
(
mid
->
oxid
,
TRUE
)))
{
...
...
@@ -136,6 +137,8 @@ static HRESULT register_ifstub(wine_marshal_id *mid, REFIID riid, IUnknown *obj,
mid
->
oid
=
manager
->
oid
;
}
tablemarshal
=
((
mshlflags
&
MSHLFLAGS_TABLESTRONG
)
||
(
mshlflags
&
MSHLFLAGS_TABLEWEAK
));
ifstub
=
stub_manager_new_ifstub
(
manager
,
stub
,
obj
,
riid
,
tablemarshal
);
if
(
!
ifstub
)
{
...
...
@@ -146,7 +149,10 @@ static HRESULT register_ifstub(wine_marshal_id *mid, REFIID riid, IUnknown *obj,
return
E_OUTOFMEMORY
;
}
if
(
!
tablemarshal
)
stub_manager_ext_addref
(
manager
,
1
);
if
(
!
tablemarshal
)
stub_manager_ext_addref
(
manager
,
1
);
else
if
(
mshlflags
&
MSHLFLAGS_TABLESTRONG
)
stub_manager_ext_addref
(
manager
,
1
);
mid
->
ipid
=
ifstub
->
ipid
;
...
...
@@ -225,13 +231,48 @@ static const IInternalUnknownVtbl ClientIdentity_Vtbl =
static
HRESULT
ifproxy_get_public_ref
(
struct
ifproxy
*
This
)
{
EnterCriticalSection
(
&
This
->
parent
->
cs
);
if
(
This
->
refs
==
0
)
{
APARTMENT
*
apt
;
TRACE
(
"getting public ref for ifproxy %p
\n
"
,
This
);
/* FIXME: call IRemUnknown::RemAddRef if necessary */
/* FIXME: this is a hack around not yet implemented IRemUnknown */
if
((
apt
=
COM_ApartmentFromOXID
(
This
->
parent
->
oxid
,
TRUE
)))
{
struct
stub_manager
*
stubmgr
;
if
((
stubmgr
=
get_stub_manager
(
apt
,
This
->
parent
->
oid
)))
{
stub_manager_ext_addref
(
stubmgr
,
1
);
This
->
refs
+=
1
;
stub_manager_int_release
(
stubmgr
);
}
COM_ApartmentRelease
(
apt
);
}
else
FIXME
(
"Need to implement IRemUnknown for inter-process table marshaling
\n
"
);
}
LeaveCriticalSection
(
&
This
->
parent
->
cs
);
return
S_OK
;
}
static
HRESULT
ifproxy_release_public_refs
(
struct
ifproxy
*
This
)
{
/* FIXME: call IRemUnknown::RemRelease */
EnterCriticalSection
(
&
This
->
parent
->
cs
);
/*
if (This->refs > 0)
{
// FIXME: call IRemUnknown::RemRelease
This->refs = 0;
}
*/
LeaveCriticalSection
(
&
This
->
parent
->
cs
);
return
S_OK
;
}
...
...
@@ -292,6 +333,7 @@ static HRESULT proxy_manager_create_ifproxy(struct proxy_manager * This, IPID ip
list_init
(
&
ifproxy
->
entry
);
ifproxy
->
parent
=
This
;
ifproxy
->
ipid
=
ipid
;
ifproxy
->
iid
=
*
riid
;
ifproxy
->
refs
=
cPublicRefs
;
...
...
@@ -513,7 +555,6 @@ StdMarshalImpl_MarshalInterface(
HRESULT
hres
;
IRpcStubBuffer
*
stubbuffer
;
IPSFactoryBuffer
*
psfacbuf
;
BOOL
tablemarshal
;
struct
stub_manager
*
manager
;
APARTMENT
*
apt
=
COM_CurrentApt
();
...
...
@@ -537,9 +578,6 @@ StdMarshalImpl_MarshalInterface(
return
hres
;
}
tablemarshal
=
((
mshlflags
&
MSHLFLAGS_TABLESTRONG
)
||
(
mshlflags
&
MSHLFLAGS_TABLEWEAK
));
if
(
tablemarshal
)
FIXME
(
"table marshalling unimplemented
\n
"
);
/* now fill out the MID */
mid
.
oxid
=
apt
->
oxid
;
...
...
@@ -555,7 +593,7 @@ StdMarshalImpl_MarshalInterface(
mid
.
oid
=
0
;
/* will be set by register_ifstub */
}
hres
=
register_ifstub
(
&
mid
,
riid
,
pUnk
,
stubbuffer
,
tablemarshal
);
hres
=
register_ifstub
(
&
mid
,
riid
,
pUnk
,
stubbuffer
,
mshlflags
);
IUnknown_Release
(
pUnk
);
...
...
@@ -581,6 +619,8 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
IRpcChannelBuffer
*
chanbuf
;
struct
proxy_manager
*
proxy_manager
;
APARTMENT
*
apt
=
COM_CurrentApt
();
APARTMENT
*
stub_apt
;
ULONG
cPublicRefs
=
1
;
TRACE
(
"(...,%s,....)
\n
"
,
debugstr_guid
(
riid
));
...
...
@@ -601,12 +641,46 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
hres
=
IUnknown_QueryInterface
(
stubmgr
->
object
,
riid
,
ppv
);
/* unref the ifstub. FIXME: only do this on success? */
if
(
!
stub_manager_is_table_marshaled
(
stubmgr
,
&
mid
.
ipid
))
stub_manager_ext_release
(
stubmgr
,
1
);
stub_manager_int_release
(
stubmgr
);
return
hres
;
}
/* notify stub manager about unmarshal if process-local object.
* note: if the oxid is not found then we and native will quite happily
* ignore table marshaling and normal marshaling rules regarding number of
* unmarshals, etc, but if you abuse these rules then your proxy could end
* up returning RPC_E_DISCONNECTED. */
if
((
stub_apt
=
COM_ApartmentFromOXID
(
mid
.
oxid
,
TRUE
)))
{
if
((
stubmgr
=
get_stub_manager
(
stub_apt
,
mid
.
oid
)))
{
if
(
!
stub_manager_notify_unmarshal
(
stubmgr
,
&
mid
.
ipid
))
hres
=
CO_E_OBJNOTCONNECTED
;
/* FIXME: hack around not using STDOBJREF yet */
if
(
stub_manager_is_table_marshaled
(
stubmgr
,
&
mid
.
ipid
))
cPublicRefs
=
0
;
stub_manager_int_release
(
stubmgr
);
}
else
{
WARN
(
"Couldn't find object for OXID %s, OID %s, assuming disconnected
\n
"
,
wine_dbgstr_longlong
(
mid
.
oxid
),
wine_dbgstr_longlong
(
mid
.
oid
));
hres
=
CO_E_OBJNOTCONNECTED
;
}
COM_ApartmentRelease
(
stub_apt
);
}
else
TRACE
(
"Treating unmarshal from OXID %s as inter-process
\n
"
,
wine_dbgstr_longlong
(
mid
.
oxid
));
if
(
hres
)
return
hres
;
if
(
!
find_proxy_manager
(
apt
,
mid
.
oxid
,
mid
.
oid
,
&
proxy_manager
))
{
hres
=
PIPE_GetNewPipeBuf
(
&
mid
,
&
chanbuf
);
...
...
@@ -621,7 +695,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
if
(
hres
==
S_OK
)
IUnknown_AddRef
((
IUnknown
*
)
ifproxy
->
iface
);
else
if
(
hres
==
E_NOINTERFACE
)
hres
=
proxy_manager_create_ifproxy
(
proxy_manager
,
mid
.
ipid
,
riid
,
1
,
&
ifproxy
);
hres
=
proxy_manager_create_ifproxy
(
proxy_manager
,
mid
.
ipid
,
riid
,
cPublicRefs
,
&
ifproxy
);
if
(
hres
==
S_OK
)
*
ppv
=
ifproxy
->
iface
;
/* AddRef'd above */
...
...
dlls/ole32/stubmanager.c
View file @
4c8d59dd
...
...
@@ -266,7 +266,12 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
/* no need to ref this, same object as sb */
stub
->
iface
=
iptr
;
stub
->
table
=
tablemarshal
;
if
(
tablemarshal
)
stub
->
state
=
IFSTUB_STATE_TABLE_MARSHALED
;
else
stub
->
state
=
IFSTUB_STATE_NORMAL_MARSHALED
;
stub
->
iid
=
*
iid
;
stub
->
ipid
=
*
iid
;
/* FIXME: should be globally unique */
...
...
@@ -288,3 +293,61 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
HeapFree
(
GetProcessHeap
(),
0
,
ifstub
);
}
/* returns TRUE if it is possible to unmarshal, FALSE otherwise. */
BOOL
stub_manager_notify_unmarshal
(
struct
stub_manager
*
m
,
const
IPID
*
ipid
)
{
struct
ifstub
*
ifstub
;
BOOL
ret
;
ifstub
=
stub_manager_ipid_to_ifstub
(
m
,
ipid
);
if
(
!
ifstub
)
{
WARN
(
"Can't find ifstub for OID %s, IPID %s
\n
"
,
wine_dbgstr_longlong
(
m
->
oid
),
wine_dbgstr_guid
(
ipid
));
return
FALSE
;
}
EnterCriticalSection
(
&
m
->
lock
);
switch
(
ifstub
->
state
)
{
case
IFSTUB_STATE_TABLE_MARSHALED
:
ret
=
TRUE
;
break
;
case
IFSTUB_STATE_NORMAL_MARSHALED
:
ifstub
->
state
=
IFSTUB_STATE_NORMAL_UNMARSHALED
;
ret
=
TRUE
;
break
;
default:
WARN
(
"object OID %s, IPID %s already unmarshaled
\n
"
,
wine_dbgstr_longlong
(
m
->
oid
),
wine_dbgstr_guid
(
ipid
));
ret
=
FALSE
;
break
;
}
LeaveCriticalSection
(
&
m
->
lock
);
return
ret
;
}
/* is an ifstub table marshaled? */
BOOL
stub_manager_is_table_marshaled
(
struct
stub_manager
*
m
,
const
IPID
*
ipid
)
{
struct
ifstub
*
ifstub
;
BOOL
ret
;
ifstub
=
stub_manager_ipid_to_ifstub
(
m
,
ipid
);
if
(
!
ifstub
)
{
WARN
(
"Can't find ifstub for OID %s, IPID %s
\n
"
,
wine_dbgstr_longlong
(
m
->
oid
),
wine_dbgstr_guid
(
ipid
));
return
FALSE
;
}
EnterCriticalSection
(
&
m
->
lock
);
ret
=
(
ifstub
->
state
==
IFSTUB_STATE_TABLE_MARSHALED
);
LeaveCriticalSection
(
&
m
->
lock
);
return
ret
;
}
dlls/ole32/tests/marshal.c
View file @
4c8d59dd
...
...
@@ -279,7 +279,7 @@ static void test_interthread_marshal_and_unmarshal()
IStream_Seek
(
pStream
,
ullZero
,
STREAM_SEEK_SET
,
NULL
);
hr
=
CoUnmarshalInterface
(
pStream
,
&
IID_IClassFactory
,
(
void
**
)
&
pProxy
);
ok_ole_success
(
hr
,
Co
ReleaseMarshalData
);
ok_ole_success
(
hr
,
Co
UnmarshalInterface
);
IStream_Release
(
pStream
);
ok_more_than_one_lock
();
...
...
@@ -397,7 +397,7 @@ static void test_tableweak_marshal_and_unmarshal_twice()
/* this line is shows the difference between weak and strong table marshaling:
* weak has cLocks == 0
* strong has cLocks > 0 */
todo_wine
{
ok_no_locks
();
}
ok_no_locks
();
end_host_object
(
tid
,
thread
);
}
...
...
@@ -446,7 +446,7 @@ static void test_tablestrong_marshal_and_unmarshal_twice()
release_host_object
(
tid
);
IStream_Release
(
pStream
);
todo_wine
{
ok_no_locks
();
}
ok_no_locks
();
end_host_object
(
tid
,
thread
);
}
...
...
@@ -534,10 +534,8 @@ static void test_normal_marshal_and_unmarshal_twice()
IStream_Seek
(
pStream
,
ullZero
,
STREAM_SEEK_SET
,
NULL
);
hr
=
CoUnmarshalInterface
(
pStream
,
&
IID_IClassFactory
,
(
void
**
)
&
pProxy2
);
todo_wine
{
ok
(
hr
==
CO_E_OBJNOTCONNECTED
,
"CoUnmarshalInterface should have failed with error CO_E_OBJNOTCONNECTED for double unmarshal, instead of 0x%08lx
\n
"
,
hr
);
}
IStream_Release
(
pStream
);
...
...
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