Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
ef57c4d9
Commit
ef57c4d9
authored
Jun 04, 2003
by
Ove Kaaven
Committed by
Alexandre Julliard
Jun 04, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preliminary support for COM apartments.
parent
350aa2dc
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
217 additions
and
66 deletions
+217
-66
compobj.c
dlls/ole32/compobj.c
+121
-60
compobj_private.h
dlls/ole32/compobj_private.h
+90
-0
errorinfo.c
dlls/ole32/errorinfo.c
+6
-6
No files found.
dlls/ole32/compobj.c
View file @
ef57c4d9
...
...
@@ -31,7 +31,8 @@
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "ole2ver.h"
...
...
@@ -41,6 +42,7 @@
#include "wownt32.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "ole32_main.h"
#include "compobj_private.h"
#include "wine/debug.h"
...
...
@@ -62,45 +64,8 @@ const CLSID CLSID_StdGlobalInterfaceTable = { 0x00000323, 0, 0, {0xc0, 0, 0, 0,
static
void
*
StdGlobalInterfaceTableInstance
;
/*****************************************************************************
* Apartment management stuff
*
* NOTE:
* per Thread values are stored in the TEB on offset 0xF80
*
* see www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
*
*/
typedef
struct
{
unsigned
char
threadingModell
;
/* we use the COINIT flags */
unsigned
long
threadID
;
long
ApartmentLockCount
;
}
OleApartmentData
;
typedef
struct
{
OleApartmentData
*
ApartmentData
;
}
OleThreadData
;
/* not jet used
static CRITICAL_SECTION csApartmentData = CRITICAL_SECTION_INIT("csApartmentData");
*/
/*
* the first STA created in a process is the main STA
*/
/* not jet used
static OleApartmentData * mainSTA;
*/
/*
* a Process can only have one MTA
*/
/* not jet used
static OleApartmentData * processMTA;
*/
APARTMENT
MTA
,
*
apts
;
static
CRITICAL_SECTION
csApartment
=
CRITICAL_SECTION_INIT
(
"csApartment"
);
/*
* This lock count counts the number of times CoInitialize is called. It is
...
...
@@ -150,19 +115,112 @@ typedef struct tagOpenDll {
static
CRITICAL_SECTION
csOpenDllList
=
CRITICAL_SECTION_INIT
(
"csOpenDllList"
);
static
OpenDll
*
openDllList
=
NULL
;
/* linked list of open dlls */
static
const
char
aptWinClass
[]
=
"WINE_OLE32_APT_CLASS"
;
static
LRESULT
CALLBACK
COM_AptWndProc
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
);
static
void
COMPOBJ_DLLList_Add
(
HANDLE
hLibrary
);
static
void
COMPOBJ_DllList_FreeUnused
(
int
Timeout
);
/******************************************************************************
* Initialize/Uni
nitialize critical sections
.
* Initialize/Uni
tialize threading stuff
.
*/
void
COMPOBJ_InitProcess
(
void
)
{
WNDCLASSA
wclass
;
memset
(
&
wclass
,
0
,
sizeof
(
wclass
));
wclass
.
lpfnWndProc
=
&
COM_AptWndProc
;
wclass
.
hInstance
=
OLE32_hInstance
;
wclass
.
lpszClassName
=
aptWinClass
;
RegisterClassA
(
&
wclass
);
}
void
COMPOBJ_UninitProcess
(
void
)
{
UnregisterClassA
(
aptWinClass
,
OLE32_hInstance
);
}
/******************************************************************************
* Manage apartments.
*/
static
void
COM_InitMTA
(
void
)
{
/* FIXME: how does windoze create OXIDs?
* this method will only work for local RPC */
MTA
.
oxid
=
((
OXID
)
GetCurrentProcessId
()
<<
32
);
InitializeCriticalSection
(
&
MTA
.
cs
);
}
static
void
COM_UninitMTA
(
void
)
{
DeleteCriticalSection
(
&
MTA
.
cs
);
MTA
.
oxid
=
0
;
}
static
APARTMENT
*
COM_CreateApartment
(
DWORD
model
)
{
APARTMENT
*
apt
;
apt
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
APARTMENT
));
apt
->
model
=
model
;
apt
->
tid
=
GetCurrentThreadId
();
DuplicateHandle
(
GetCurrentProcess
(),
GetCurrentThread
(),
GetCurrentProcess
(),
&
apt
->
thread
,
THREAD_ALL_ACCESS
,
FALSE
,
0
);
if
(
model
&
COINIT_APARTMENTTHREADED
)
{
/* FIXME: how does windoze create OXIDs? */
apt
->
oxid
=
MTA
.
oxid
|
GetCurrentThreadId
();
apt
->
win
=
CreateWindowA
(
aptWinClass
,
NULL
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
OLE32_hInstance
,
NULL
);
InitializeCriticalSection
(
&
apt
->
cs
);
}
else
{
apt
->
parent
=
&
MTA
;
apt
->
oxid
=
MTA
.
oxid
;
}
EnterCriticalSection
(
&
csApartment
);
if
(
apts
)
apts
->
prev
=
apt
;
apt
->
next
=
apts
;
apts
=
apt
;
LeaveCriticalSection
(
&
csApartment
);
NtCurrentTeb
()
->
ErrorInfo
=
apt
;
return
apt
;
}
static
void
COM_DestroyApartment
(
APARTMENT
*
apt
)
{
EnterCriticalSection
(
&
csApartment
);
if
(
apt
->
prev
)
apt
->
prev
->
next
=
apt
->
next
;
if
(
apt
->
next
)
apt
->
next
->
prev
=
apt
->
prev
;
if
(
apts
==
apt
)
apts
=
apt
->
next
;
apt
->
prev
=
NULL
;
apt
->
next
=
NULL
;
LeaveCriticalSection
(
&
csApartment
);
if
(
apt
->
model
&
COINIT_APARTMENTTHREADED
)
{
if
(
apt
->
win
)
DestroyWindow
(
apt
->
win
);
DeleteCriticalSection
(
&
apt
->
cs
);
}
CloseHandle
(
apt
->
thread
);
HeapFree
(
GetProcessHeap
(),
0
,
apt
);
}
HWND
COM_GetApartmentWin
(
OXID
oxid
)
{
APARTMENT
*
apt
;
HWND
win
=
0
;
EnterCriticalSection
(
&
csApartment
);
apt
=
apts
;
while
(
apt
&&
apt
->
oxid
!=
oxid
)
apt
=
apt
->
next
;
if
(
apt
)
win
=
apt
->
win
;
LeaveCriticalSection
(
&
csApartment
);
return
win
;
}
static
LRESULT
CALLBACK
COM_AptWndProc
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
return
DefWindowProcA
(
hWnd
,
msg
,
wParam
,
lParam
);
}
/*****************************************************************************
...
...
@@ -282,12 +340,6 @@ HRESULT WINAPI CoInitialize(
* S_FALSE if this function was called already.
* RPC_E_CHANGED_MODE if a previous call to CoInitialize specified another
* threading model.
*
* BUGS
* Only the single threaded model is supported. As a result RPC_E_CHANGED_MODE
* is never returned.
*
* See the windows documentation for more details.
*/
HRESULT
WINAPI
CoInitializeEx
(
LPVOID
lpReserved
,
/* [in] pointer to win32 malloc interface
...
...
@@ -295,7 +347,8 @@ HRESULT WINAPI CoInitializeEx(
DWORD
dwCoInit
/* [in] A value from COINIT specifies the threading model */
)
{
HRESULT
hr
;
HRESULT
hr
=
S_OK
;
APARTMENT
*
apt
;
TRACE
(
"(%p, %x)
\n
"
,
lpReserved
,
(
int
)
dwCoInit
);
...
...
@@ -304,14 +357,9 @@ HRESULT WINAPI CoInitializeEx(
ERR
(
"(%p, %x) - Bad parameter passed-in %p, must be an old Windows Application
\n
"
,
lpReserved
,
(
int
)
dwCoInit
,
lpReserved
);
}
/*
* Check for unsupported features.
*/
if
(
dwCoInit
!=
COINIT_APARTMENTTHREADED
)
{
FIXME
(
":(%p,%x): unsupported flag %x
\n
"
,
lpReserved
,
(
int
)
dwCoInit
,
(
int
)
dwCoInit
);
/* Hope for the best and continue anyway */
}
apt
=
NtCurrentTeb
()
->
ErrorInfo
;
if
(
apt
&&
dwCoInit
!=
apt
->
model
)
return
RPC_E_CHANGED_MODE
;
hr
=
apt
?
S_FALSE
:
S_OK
;
/*
* Check the lock count. If this is the first time going through the initialize
...
...
@@ -326,13 +374,15 @@ HRESULT WINAPI CoInitializeEx(
*/
TRACE
(
"() - Initializing the COM libraries
\n
"
);
COM_InitMTA
();
RunningObjectTableImpl_Initialize
();
hr
=
S_OK
;
}
else
hr
=
S_FALSE
;
if
(
!
apt
)
apt
=
COM_CreateApartment
(
dwCoInit
);
InterlockedIncrement
(
&
apt
->
inits
);
if
(
hr
==
S_OK
)
NtCurrentTeb
()
->
ErrorInfo
=
apt
;
return
hr
;
}
...
...
@@ -347,8 +397,18 @@ HRESULT WINAPI CoInitializeEx(
void
WINAPI
CoUninitialize
(
void
)
{
LONG
lCOMRefCnt
;
APARTMENT
*
apt
;
TRACE
(
"()
\n
"
);
apt
=
NtCurrentTeb
()
->
ErrorInfo
;
if
(
!
apt
)
return
;
if
(
InterlockedDecrement
(
&
apt
->
inits
)
==
0
)
{
NtCurrentTeb
()
->
ErrorInfo
=
NULL
;
COM_DestroyApartment
(
apt
);
apt
=
NULL
;
}
/*
* Decrease the reference count.
* If we are back to 0 locks on the COM library, make sure we free
...
...
@@ -378,6 +438,7 @@ void WINAPI CoUninitialize(void)
*/
COM_ExternalLockFreeList
();
COM_UninitMTA
();
}
else
if
(
lCOMRefCnt
<
1
)
{
ERR
(
"CoUninitialize() - not CoInitialized.
\n
"
);
...
...
dlls/ole32/compobj_private.h
View file @
ef57c4d9
...
...
@@ -4,6 +4,7 @@
* Copyright 1999 Francis Beaudet
* Copyright 1999 Sylvain St-Germain
* Copyright 2002 Marcus Meissner
* Copyright 2003 Ove Kven, TransGaming Technologies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -26,6 +27,74 @@
/* All private prototype functions used by OLE will be added to this header file */
#include "wtypes.h"
#include "dcom.h"
#include "thread.h"
/* exported interface */
typedef
struct
tagXIF
{
struct
tagXIF
*
next
;
LPVOID
iface
;
/* interface pointer */
IID
iid
;
/* interface ID */
IPID
ipid
;
/* exported interface ID */
LPRPCSTUBBUFFER
stub
;
/* interface stub */
DWORD
refs
;
/* external reference count */
HRESULT
hres
;
/* result of stub creation attempt */
}
XIF
;
/* exported object */
typedef
struct
tagXOBJECT
{
ICOM_VTABLE
(
IRpcStubBuffer
)
*
lpVtbl
;
struct
tagAPARTMENT
*
parent
;
struct
tagXOBJECT
*
next
;
LPUNKNOWN
obj
;
/* object identity (IUnknown) */
OID
oid
;
/* object ID */
DWORD
ifc
;
/* interface ID counter */
XIF
*
ifaces
;
/* exported interfaces */
DWORD
refs
;
/* external reference count */
}
XOBJECT
;
/* imported interface */
typedef
struct
tagIIF
{
struct
tagIIF
*
next
;
LPVOID
iface
;
/* interface pointer */
IID
iid
;
/* interface ID */
IPID
ipid
;
/* imported interface ID */
LPRPCPROXYBUFFER
proxy
;
/* interface proxy */
DWORD
refs
;
/* imported (public) references */
HRESULT
hres
;
/* result of proxy creation attempt */
}
IIF
;
/* imported object */
typedef
struct
tagIOBJECT
{
ICOM_VTABLE
(
IRemUnknown
)
*
lpVtbl
;
struct
tagAPARTMENT
*
parent
;
struct
tagIOBJECT
*
next
;
LPRPCCHANNELBUFFER
chan
;
/* channel to object */
OXID
oxid
;
/* object exported ID */
OID
oid
;
/* object ID */
IPID
ipid
;
/* first imported interface ID */
IIF
*
ifaces
;
/* imported interfaces */
DWORD
refs
;
/* proxy reference count */
}
IOBJECT
;
/* apartment */
typedef
struct
tagAPARTMENT
{
struct
tagAPARTMENT
*
next
,
*
prev
,
*
parent
;
DWORD
model
;
/* threading model */
DWORD
inits
;
/* CoInitialize count */
DWORD
tid
;
/* thread id */
HANDLE
thread
;
/* thread handle */
OXID
oxid
;
/* object exporter ID */
OID
oidc
;
/* object ID counter */
HWND
win
;
/* message window */
CRITICAL_SECTION
cs
;
/* thread safety */
LPMESSAGEFILTER
filter
;
/* message filter */
XOBJECT
*
objs
;
/* exported objects */
IOBJECT
*
proxies
;
/* imported objects */
LPVOID
ErrorInfo
;
/* thread error info */
}
APARTMENT
;
extern
APARTMENT
MTA
,
*
apts
;
extern
void
*
StdGlobalInterfaceTable_Construct
();
extern
void
StdGlobalInterfaceTable_Destroy
(
void
*
self
);
...
...
@@ -121,4 +190,25 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
HRESULT
WINAPI
__CLSIDFromStringA
(
LPCSTR
idstr
,
CLSID
*
id
);
/*
* Per-thread values are stored in the TEB on offset 0xF80,
* see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
*/
static
inline
APARTMENT
*
COM_CurrentInfo
(
void
)
WINE_UNUSED
;
static
inline
APARTMENT
*
COM_CurrentInfo
(
void
)
{
APARTMENT
*
apt
=
NtCurrentTeb
()
->
ErrorInfo
;
return
apt
;
}
static
inline
APARTMENT
*
COM_CurrentApt
(
void
)
WINE_UNUSED
;
static
inline
APARTMENT
*
COM_CurrentApt
(
void
)
{
APARTMENT
*
apt
=
COM_CurrentInfo
();
if
(
apt
&&
apt
->
parent
)
apt
=
apt
->
parent
;
return
apt
;
}
/* compobj.c */
HWND
COM_GetApartmentWin
(
OXID
oxid
);
#endif
/* __WINE_OLE_COMPOBJ_H */
dlls/ole32/errorinfo.c
View file @
ef57c4d9
...
...
@@ -32,7 +32,7 @@
#include "objbase.h"
#include "wine/unicode.h"
#include "
thread
.h"
#include "
compobj_private
.h"
#include "wine/debug.h"
...
...
@@ -483,13 +483,13 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
*/
HRESULT
WINAPI
GetErrorInfo
(
ULONG
dwReserved
,
IErrorInfo
**
pperrinfo
)
{
TRACE
(
"(%ld, %p, %p): stub:
\n
"
,
dwReserved
,
pperrinfo
,
NtCurrentTeb
()
->
ErrorInfo
);
TRACE
(
"(%ld, %p, %p): stub:
\n
"
,
dwReserved
,
pperrinfo
,
COM_CurrentInfo
()
->
ErrorInfo
);
if
(
!
pperrinfo
)
return
E_INVALIDARG
;
if
(
!
(
*
pperrinfo
=
(
IErrorInfo
*
)(
NtCurrentTeb
()
->
ErrorInfo
)))
return
S_FALSE
;
if
(
!
(
*
pperrinfo
=
(
IErrorInfo
*
)(
COM_CurrentInfo
()
->
ErrorInfo
)))
return
S_FALSE
;
/* clear thread error state */
NtCurrentTeb
()
->
ErrorInfo
=
NULL
;
COM_CurrentInfo
()
->
ErrorInfo
=
NULL
;
return
S_OK
;
}
...
...
@@ -502,11 +502,11 @@ HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
TRACE
(
"(%ld, %p): stub:
\n
"
,
dwReserved
,
perrinfo
);
/* release old errorinfo */
pei
=
(
IErrorInfo
*
)
NtCurrentTeb
()
->
ErrorInfo
;
pei
=
(
IErrorInfo
*
)
COM_CurrentInfo
()
->
ErrorInfo
;
if
(
pei
)
IErrorInfo_Release
(
pei
);
/* set to new value */
NtCurrentTeb
()
->
ErrorInfo
=
perrinfo
;
COM_CurrentInfo
()
->
ErrorInfo
=
perrinfo
;
if
(
perrinfo
)
IErrorInfo_AddRef
(
perrinfo
);
return
S_OK
;
}
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