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
ad34f3dc
Commit
ad34f3dc
authored
Jan 25, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Jan 25, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Generate machine-local IPIDs.
- Make pipes be uniquely identified only by their IPID.
parent
c1db191d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
171 additions
and
50 deletions
+171
-50
compobj.c
dlls/ole32/compobj.c
+27
-1
compobj_private.h
dlls/ole32/compobj_private.h
+9
-2
marshal.c
dlls/ole32/marshal.c
+3
-28
rpc.c
dlls/ole32/rpc.c
+19
-14
stubmanager.c
dlls/ole32/stubmanager.c
+113
-5
No files found.
dlls/ole32/compobj.c
View file @
ad34f3dc
...
...
@@ -246,8 +246,10 @@ APARTMENT* COM_CreateApartment(DWORD model)
list_init
(
&
apt
->
proxies
);
list_init
(
&
apt
->
stubmgrs
);
apt
->
o
idc
=
1
;
apt
->
ip
idc
=
1
;
apt
->
refs
=
1
;
apt
->
remunk_exported
=
FALSE
;
apt
->
oidc
=
1
;
InitializeCriticalSection
(
&
apt
->
cs
);
apt
->
model
=
model
;
...
...
@@ -363,6 +365,30 @@ APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref)
return
result
;
}
/* gets the apartment which has a given creator thread ID. The caller must
* release the reference from the apartment as soon as the apartment pointer
* is no longer required. */
APARTMENT
*
COM_ApartmentFromTID
(
DWORD
tid
)
{
APARTMENT
*
result
=
NULL
;
struct
list
*
cursor
;
EnterCriticalSection
(
&
csApartment
);
LIST_FOR_EACH
(
cursor
,
&
apts
)
{
struct
apartment
*
apt
=
LIST_ENTRY
(
cursor
,
struct
apartment
,
entry
);
if
(
apt
->
tid
==
tid
)
{
result
=
apt
;
COM_ApartmentAddRef
(
result
);
break
;
}
}
LeaveCriticalSection
(
&
csApartment
);
return
result
;
}
HWND
COM_GetApartmentWin
(
OXID
oxid
,
BOOL
ref
)
{
APARTMENT
*
apt
;
...
...
dlls/ole32/compobj_private.h
View file @
ad34f3dc
...
...
@@ -110,6 +110,7 @@ struct proxy_manager
DWORD
refs
;
/* proxy reference count (LOCK) */
CRITICAL_SECTION
cs
;
/* thread safety for this object and children */
ULONG
sorflags
;
/* STDOBJREF flags (RO) */
IRemUnknown
*
remunk
;
/* proxy to IRemUnknown used for lifecycle management (CS cs) */
};
/* this needs to become a COM object that implements IRemUnknown */
...
...
@@ -122,13 +123,15 @@ struct apartment
DWORD
tid
;
/* thread id (RO) */
HANDLE
thread
;
/* thread handle (RO) */
OXID
oxid
;
/* object exporter ID (RO) */
OID
oidc
;
/* object ID counter, starts at 1, zero is invalid OID
(CS cs) */
DWORD
ipidc
;
/* interface pointer ID counter, starts at 1
(CS cs) */
HWND
win
;
/* message window (RO) */
CRITICAL_SECTION
cs
;
/* thread safety */
LPMESSAGEFILTER
filter
;
/* message filter (CS cs) */
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) */
OID
oidc
;
/* object ID counter, starts at 1, zero is invalid OID (CS cs). FIXME: remove me */
DWORD
listenertid
;
/* id of apartment_listener_thread. FIXME: remove me */
};
...
...
@@ -177,12 +180,15 @@ 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
*
ipid
);
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
);
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
);
HRESULT
start_apartment_remote_unknown
(
void
);
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
);
...
...
@@ -203,6 +209,7 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* compobj.c */
APARTMENT
*
COM_CreateApartment
(
DWORD
model
);
APARTMENT
*
COM_ApartmentFromOXID
(
OXID
oxid
,
BOOL
ref
);
APARTMENT
*
COM_ApartmentFromTID
(
DWORD
tid
);
DWORD
COM_ApartmentAddRef
(
struct
apartment
*
apt
);
DWORD
COM_ApartmentRelease
(
struct
apartment
*
apt
);
...
...
dlls/ole32/marshal.c
View file @
ad34f3dc
...
...
@@ -56,6 +56,8 @@ extern const CLSID CLSID_DfMarshal;
* when the proxy disconnects or is destroyed */
#define SORFP_NOLIFETIMEMGMT SORF_OXRES1
static
HRESULT
unmarshal_object
(
const
STDOBJREF
*
stdobjref
,
APARTMENT
*
apt
,
REFIID
riid
,
void
**
object
);
/* Marshalling just passes a unique identifier to the remote client,
* that makes it possible to find the passed interface again.
*
...
...
@@ -83,35 +85,8 @@ get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
return
CoGetClassObject
(
&
pxclsid
,
CLSCTX_INPROC_SERVER
,
NULL
,
&
IID_IPSFactoryBuffer
,(
LPVOID
*
)
facbuf
);
}
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
)
{
IRpcStubBuffer
*
ret
;
APARTMENT
*
apt
;
struct
stub_manager
*
m
;
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
;
}
ret
=
stub_manager_ipid_to_stubbuffer
(
m
,
&
mid
->
ipid
);
stub_manager_int_release
(
m
);
COM_ApartmentRelease
(
apt
);
return
ret
;
}
/* creates a new stub manager and sets stdobjref->oid when stdobjref->oid == 0 */
static
HRESULT
register_ifstub
(
APARTMENT
*
apt
,
STDOBJREF
*
stdobjref
,
REFIID
riid
,
IUnknown
*
obj
,
MSHLFLAGS
mshlflags
)
HRESULT
register_ifstub
(
APARTMENT
*
apt
,
STDOBJREF
*
stdobjref
,
REFIID
riid
,
IUnknown
*
obj
,
MSHLFLAGS
mshlflags
)
{
struct
stub_manager
*
manager
=
NULL
;
struct
ifstub
*
ifstub
;
...
...
dlls/ole32/rpc.c
View file @
ad34f3dc
...
...
@@ -59,7 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
struct
request_header
{
DWORD
reqid
;
wine_marshal_id
m
id
;
IPID
ip
id
;
DWORD
iMethod
;
DWORD
cbBuffer
;
};
...
...
@@ -162,7 +162,6 @@ static DWORD WINAPI stub_dispatch_thread(LPVOID);
static
HRESULT
PIPE_RegisterPipe
(
wine_marshal_id
*
mid
,
HANDLE
hPipe
,
BOOL
startreader
)
{
/* FIXME: this pipe caching code is commented out because it is breaks the
* tests, causing them hang due to writing to or reading from the wrong pipe.
*/
...
...
@@ -205,15 +204,21 @@ PIPE_FindByMID(wine_marshal_id *mid) {
}
static
struct
pipe
*
PIPE_GetFromMID
(
wine_marshal_id
*
mid
)
{
int
i
;
for
(
i
=
0
;
i
<
nrofpipes
;
i
++
)
{
if
((
pipes
[
i
].
mid
.
oxid
==
mid
->
oxid
)
&&
(
GetCurrentThreadId
()
==
pipes
[
i
].
tid
)
)
return
pipes
+
i
;
}
return
NULL
;
PIPE_GetFromIPID
(
const
IPID
*
ipid
)
{
int
i
;
for
(
i
=
0
;
i
<
nrofpipes
;
i
++
)
{
/* compare TID and PID fields */
if
((
pipes
[
i
].
mid
.
ipid
.
Data2
==
ipid
->
Data2
)
&&
(
pipes
[
i
].
mid
.
ipid
.
Data3
==
ipid
->
Data3
)
&&
(
GetCurrentThreadId
()
==
pipes
[
i
].
tid
))
return
pipes
+
i
;
/* special case for IRemUnknown IPID */
else
if
((
pipes
[
i
].
mid
.
oxid
==
*
(
OXID
*
)
ipid
->
Data4
)
&&
(
GetCurrentThreadId
()
==
pipes
[
i
].
tid
))
return
pipes
+
i
;
}
return
NULL
;
}
static
HRESULT
...
...
@@ -331,7 +336,7 @@ COM_InvokeAndRpcSend(struct rpc *req) {
HRESULT
hres
;
DWORD
reqtype
;
if
(
!
(
stub
=
mid_to_stubbuffer
(
&
(
req
->
reqh
.
m
id
))))
if
(
!
(
stub
=
ipid_to_stubbuffer
(
&
(
req
->
reqh
.
ip
id
))))
{
ERR
(
"Stub not found?
\n
"
);
return
E_FAIL
;
...
...
@@ -366,7 +371,7 @@ RPC_QueueRequestAndWait(struct rpc *req) {
struct
rpc
*
xreq
;
HRESULT
hres
;
DWORD
reqtype
;
struct
pipe
*
xpipe
=
PIPE_GetFrom
MID
(
&
(
req
->
reqh
.
m
id
));
struct
pipe
*
xpipe
=
PIPE_GetFrom
IPID
(
&
(
req
->
reqh
.
ip
id
));
if
(
!
xpipe
)
{
FIXME
(
"no pipe found.
\n
"
);
...
...
@@ -421,7 +426,7 @@ PipeBuf_SendReceive(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status)
if
(
hres
)
return
hres
;
req
->
reqh
.
iMethod
=
msg
->
iMethod
;
req
->
reqh
.
cbBuffer
=
msg
->
cbBuffer
;
memcpy
(
&
(
req
->
reqh
.
mid
),
&
(
This
->
mid
),
sizeof
(
This
->
mid
))
;
req
->
reqh
.
ipid
=
This
->
mid
.
ipid
;
req
->
Buffer
=
msg
->
Buffer
;
hres
=
RPC_QueueRequestAndWait
(
req
);
if
(
hres
)
{
...
...
dlls/ole32/stubmanager.c
View file @
ad34f3dc
...
...
@@ -243,11 +243,103 @@ static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const
return
result
;
}
IRpcStubBuffer
*
stub_manager_ipid_to_stubbuffer
(
struct
stub_manager
*
m
,
const
IPID
*
ipid
)
/* gets the stub manager associated with an ipid - 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 */
static
struct
stub_manager
*
get_stub_manager_from_ipid
(
APARTMENT
*
apt
,
const
IPID
*
ipid
)
{
struct
ifstub
*
ifstub
=
stub_manager_ipid_to_ifstub
(
m
,
ipid
);
return
ifstub
?
ifstub
->
stubbuffer
:
NULL
;
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
(
stub_manager_ipid_to_ifstub
(
m
,
ipid
))
{
result
=
m
;
stub_manager_int_addref
(
result
);
break
;
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
if
(
result
)
TRACE
(
"found %p for ipid %s
\n
"
,
result
,
debugstr_guid
(
ipid
));
else
ERR
(
"not found for ipid %s
\n
"
,
debugstr_guid
(
ipid
));
return
result
;
}
HRESULT
ipid_to_stub_manager
(
const
IPID
*
ipid
,
APARTMENT
**
stub_apt
,
struct
stub_manager
**
stubmgr_ret
)
{
/* FIXME: hack for IRemUnknown */
if
(
ipid
->
Data2
==
0xffff
)
*
stub_apt
=
COM_ApartmentFromOXID
(
*
(
OXID
*
)
ipid
->
Data4
,
TRUE
);
else
*
stub_apt
=
COM_ApartmentFromTID
(
ipid
->
Data2
);
if
(
!*
stub_apt
)
{
ERR
(
"Couldn't find apartment corresponding to TID 0x%04x
\n
"
,
ipid
->
Data2
);
return
RPC_E_INVALID_OBJECT
;
}
*
stubmgr_ret
=
get_stub_manager_from_ipid
(
*
stub_apt
,
ipid
);
if
(
!*
stubmgr_ret
)
{
COM_ApartmentRelease
(
*
stub_apt
);
*
stub_apt
=
NULL
;
return
RPC_E_INVALID_OBJECT
;
}
return
S_OK
;
}
IRpcStubBuffer
*
ipid_to_stubbuffer
(
const
IPID
*
ipid
)
{
IRpcStubBuffer
*
ret
=
NULL
;
APARTMENT
*
apt
;
struct
stub_manager
*
stubmgr
;
struct
ifstub
*
ifstub
;
HRESULT
hr
;
hr
=
ipid_to_stub_manager
(
ipid
,
&
apt
,
&
stubmgr
);
if
(
hr
!=
S_OK
)
return
NULL
;
ifstub
=
stub_manager_ipid_to_ifstub
(
stubmgr
,
ipid
);
if
(
ifstub
)
ret
=
ifstub
->
stubbuffer
;
stub_manager_int_release
(
stubmgr
);
COM_ApartmentRelease
(
apt
);
return
ret
;
}
/* generates an ipid in the following format (similar to native version):
* Data1 = apartment-local ipid counter
* Data2 = apartment creator thread ID
* Data3 = process ID
* Data4 = random value
*/
static
inline
HRESULT
generate_ipid
(
struct
stub_manager
*
m
,
IPID
*
ipid
)
{
HRESULT
hr
;
hr
=
UuidCreate
(
ipid
);
if
(
FAILED
(
hr
))
{
ERR
(
"couldn't create IPID for stub manager %p
\n
"
,
m
);
UuidCreateNil
(
ipid
);
return
hr
;
}
EnterCriticalSection
(
&
m
->
apt
->
cs
);
ipid
->
Data1
=
m
->
apt
->
ipidc
++
;
LeaveCriticalSection
(
&
m
->
apt
->
cs
);
ipid
->
Data2
=
(
USHORT
)
m
->
apt
->
tid
;
ipid
->
Data3
=
(
USHORT
)
GetCurrentProcessId
();
return
S_OK
;
}
/* registers a new interface stub COM object with the stub manager and returns registration record */
...
...
@@ -273,12 +365,26 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub
->
state
=
IFSTUB_STATE_NORMAL_MARSHALED
;
stub
->
iid
=
*
iid
;
stub
->
ipid
=
*
iid
;
/* FIXME: should be globally unique */
/* FIXME: hack for IRemUnknown because we don't notify SCM of our IPID
* yet, so we need to use a well-known one */
if
(
IsEqualIID
(
iid
,
&
IID_IRemUnknown
))
{
stub
->
ipid
.
Data1
=
0xffffffff
;
stub
->
ipid
.
Data2
=
0xffff
;
stub
->
ipid
.
Data3
=
0xffff
;
assert
(
sizeof
(
stub
->
ipid
.
Data4
)
==
sizeof
(
m
->
apt
->
oxid
));
memcpy
(
&
stub
->
ipid
.
Data4
,
&
m
->
apt
->
oxid
,
sizeof
(
OXID
));
}
else
generate_ipid
(
m
,
&
stub
->
ipid
);
EnterCriticalSection
(
&
m
->
lock
);
list_add_head
(
&
m
->
ifstubs
,
&
stub
->
entry
);
LeaveCriticalSection
(
&
m
->
lock
);
TRACE
(
"ifstub %p created with ipid %s
\n
"
,
stub
,
debugstr_guid
(
&
stub
->
ipid
));
return
stub
;
}
...
...
@@ -351,3 +457,5 @@ BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
return
ret
;
}
const
IID
IID_IRemUnknown
=
{
0x00000131
,
0
,
0
,
{
0xc0
,
0
,
0
,
0
,
0
,
0
,
0
,
0x46
}
};
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