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
2ff17114
Commit
2ff17114
authored
Feb 14, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Feb 14, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Invoke objects in STA's in the correct thread by sending messages to
the hidden apartment window.
parent
35ae7126
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
57 additions
and
24 deletions
+57
-24
compobj.c
dlls/ole32/compobj.c
+14
-11
compobj_private.h
dlls/ole32/compobj_private.h
+5
-1
rpc.c
dlls/ole32/rpc.c
+30
-7
stubmanager.c
dlls/ole32/stubmanager.c
+8
-5
No files found.
dlls/ole32/compobj.c
View file @
2ff17114
...
...
@@ -34,8 +34,6 @@
* clients and servers to meet up
* - Flip our marshalling on top of the RPC runtime transport API,
* so we no longer use named pipes to communicate
* - Implement RPC thread affinity (should fix InstallShield painting
* problems)
*
* - Make all ole interface marshaling use NDR to be wire compatible with
* native DCOM
...
...
@@ -163,7 +161,7 @@ static CRITICAL_SECTION_DEBUG dll_cs_debug =
};
static
CRITICAL_SECTION
csOpenDllList
=
{
&
dll_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
const
char
aptWinClass
[]
=
"WINE_OLE32_APT_CLASS"
;
static
const
WCHAR
wszAptWinClass
[]
=
{
'W'
,
'I'
,
'N'
,
'E'
,
'_'
,
'O'
,
'L'
,
'E'
,
'3'
,
'2'
,
'_'
,
'A'
,
'P'
,
'T'
,
'_'
,
'C'
,
'L'
,
'A'
,
'S'
,
'S'
,
0
}
;
static
LRESULT
CALLBACK
COM_AptWndProc
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
);
static
void
COMPOBJ_DLLList_Add
(
HANDLE
hLibrary
);
...
...
@@ -171,7 +169,7 @@ static void COMPOBJ_DllList_FreeUnused(int Timeout);
void
COMPOBJ_InitProcess
(
void
)
{
WNDCLASS
A
wclass
;
WNDCLASS
W
wclass
;
/* Dispatching to the correct thread in an apartment is done through
* window messages rather than RPC transports. When an interface is
...
...
@@ -183,15 +181,15 @@ void COMPOBJ_InitProcess( void )
* was unmarshalled.
*/
memset
(
&
wclass
,
0
,
sizeof
(
wclass
));
wclass
.
lpfnWndProc
=
&
COM_AptWndProc
;
wclass
.
lpfnWndProc
=
COM_AptWndProc
;
wclass
.
hInstance
=
OLE32_hInstance
;
wclass
.
lpszClassName
=
a
ptWinClass
;
RegisterClass
A
(
&
wclass
);
wclass
.
lpszClassName
=
wszA
ptWinClass
;
RegisterClass
W
(
&
wclass
);
}
void
COMPOBJ_UninitProcess
(
void
)
{
UnregisterClass
A
(
a
ptWinClass
,
OLE32_hInstance
);
UnregisterClass
W
(
wszA
ptWinClass
,
OLE32_hInstance
);
}
void
COM_TlsDestroy
()
...
...
@@ -239,7 +237,7 @@ static APARTMENT *apartment_construct(DWORD model)
{
/* FIXME: should be randomly generated by in an RPC call to rpcss */
apt
->
oxid
=
((
OXID
)
GetCurrentProcessId
()
<<
32
)
|
GetCurrentThreadId
();
apt
->
win
=
CreateWindow
A
(
a
ptWinClass
,
NULL
,
0
,
apt
->
win
=
CreateWindow
W
(
wszA
ptWinClass
,
NULL
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
OLE32_hInstance
,
NULL
);
}
...
...
@@ -425,10 +423,15 @@ HWND COM_GetApartmentWin(OXID oxid, BOOL ref)
return
apt
->
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
)
{
return
DefWindowProcA
(
hWnd
,
msg
,
wParam
,
lParam
);
switch
(
msg
)
{
case
DM_EXECUTERPC
:
return
RPC_ExecuteCall
((
RPCOLEMESSAGE
*
)
wParam
,
(
IRpcStubBuffer
*
)
lParam
);
default:
return
DefWindowProcW
(
hWnd
,
msg
,
wParam
,
lParam
);
}
}
/*****************************************************************************
...
...
dlls/ole32/compobj_private.h
View file @
2ff17114
...
...
@@ -190,7 +190,7 @@ 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
);
IRpcStubBuffer
*
ipid_to_
apt_and_stubbuffer
(
const
IPID
*
ipid
,
APARTMENT
**
stub_apt
);
HRESULT
start_apartment_remote_unknown
(
void
);
IRpcStubBuffer
*
mid_to_stubbuffer
(
wine_marshal_id
*
mid
);
...
...
@@ -199,6 +199,7 @@ void start_apartment_listener_thread(void);
extern
HRESULT
PIPE_GetNewPipeBuf
(
wine_marshal_id
*
mid
,
IRpcChannelBuffer
**
pipebuf
);
void
RPC_StartLocalServer
(
REFCLSID
clsid
,
IStream
*
stream
);
HRESULT
RPC_ExecuteCall
(
RPCOLEMESSAGE
*
msg
,
IRpcStubBuffer
*
stub
);
/* This function initialize the Running Object Table */
HRESULT
WINAPI
RunningObjectTableImpl_Initialize
(
void
);
...
...
@@ -215,6 +216,9 @@ APARTMENT *COM_ApartmentFromTID(DWORD tid);
DWORD
COM_ApartmentAddRef
(
struct
apartment
*
apt
);
DWORD
COM_ApartmentRelease
(
struct
apartment
*
apt
);
/* messages used by the apartment window (not compatible with native) */
#define DM_EXECUTERPC (WM_USER + 0)
/* WPARAM = (RPCOLEMESSAGE *), LPARAM = (IRpcStubBuffer *) */
/*
* Per-thread values are stored in the TEB on offset 0xF80,
* see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
...
...
dlls/ole32/rpc.c
View file @
2ff17114
...
...
@@ -273,25 +273,48 @@ PipeBuf_GetBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid)
return
S_OK
;
}
HRESULT
RPC_ExecuteCall
(
RPCOLEMESSAGE
*
msg
,
IRpcStubBuffer
*
stub
)
{
return
IRpcStubBuffer_Invoke
(
stub
,
msg
,
NULL
);
}
static
HRESULT
COM_InvokeAndRpcSend
(
struct
rpc
*
req
)
{
IRpcStubBuffer
*
stub
;
APARTMENT
*
apt
;
RPCOLEMESSAGE
msg
;
HRESULT
hres
;
DWORD
reqtype
;
if
(
!
(
stub
=
ipid_to_stubbuffer
(
&
(
req
->
reqh
.
ipid
))))
/* ipid_to_stubbuffer will already have logged the error */
return
RPC_E_DISCONNECTED
;
IUnknown_AddRef
(
stub
);
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
Buffer
=
req
->
Buffer
;
msg
.
iMethod
=
req
->
reqh
.
iMethod
;
msg
.
cbBuffer
=
req
->
reqh
.
cbBuffer
;
msg
.
dataRepresentation
=
NDR_LOCAL_DATA_REPRESENTATION
;
req
->
state
=
REQSTATE_INVOKING
;
req
->
resph
.
retval
=
IRpcStubBuffer_Invoke
(
stub
,
&
msg
,
NULL
);
IUnknown_Release
(
stub
);
stub
=
ipid_to_apt_and_stubbuffer
(
&
req
->
reqh
.
ipid
,
&
apt
);
if
(
!
apt
)
/* ipid_to_apt_and_stubbuffer will already have logged the error */
return
RPC_E_DISCONNECTED
;
if
(
!
stub
)
{
/* ipid_to_apt_and_stubbuffer will already have logged the error */
COM_ApartmentRelease
(
apt
);
return
RPC_E_DISCONNECTED
;
}
/* Note: this is the important difference between STAs and MTAs - we
* always execute RPCs to STAs in the thread that originally created the
* apartment (i.e. the one that pumps messages to the window) */
if
(
apt
->
model
&
COINIT_APARTMENTTHREADED
)
req
->
resph
.
retval
=
SendMessageW
(
apt
->
win
,
DM_EXECUTERPC
,
(
WPARAM
)
&
msg
,
(
LPARAM
)
stub
);
else
req
->
resph
.
retval
=
RPC_ExecuteCall
(
&
msg
,
stub
);
COM_ApartmentRelease
(
apt
);
IRpcStubBuffer_Release
(
stub
);
req
->
Buffer
=
msg
.
Buffer
;
req
->
resph
.
cbBuffer
=
msg
.
cbBuffer
;
reqtype
=
REQTYPE_RESPONSE
;
...
...
dlls/ole32/stubmanager.c
View file @
2ff17114
...
...
@@ -321,24 +321,27 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
return
S_OK
;
}
IRpcStubBuffer
*
ipid_to_stubbuffer
(
const
IPID
*
ipid
)
/* gets the apartment and IRpcStubBuffer from an object. the caller must
* release the references to both objects */
IRpcStubBuffer
*
ipid_to_apt_and_stubbuffer
(
const
IPID
*
ipid
,
APARTMENT
**
stub_apt
)
{
IRpcStubBuffer
*
ret
=
NULL
;
APARTMENT
*
apt
;
struct
stub_manager
*
stubmgr
;
struct
ifstub
*
ifstub
;
HRESULT
hr
;
hr
=
ipid_to_stub_manager
(
ipid
,
&
apt
,
&
stubmgr
);
*
stub_apt
=
NULL
;
hr
=
ipid_to_stub_manager
(
ipid
,
stub_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
);
if
(
ret
)
IRpcStubBuffer_AddRef
(
ret
);
COM_ApartmentRelease
(
apt
);
stub_manager_int_release
(
stubmgr
);
return
ret
;
}
...
...
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