RFC: Store apartment model in TEB
Robert Shearman
R.J.Shearman at warwick.ac.uk
Fri May 16 10:18:20 CDT 2003
Hi,
I've sent it to wine-devel so I can get some comments on it. This patch will
basically store the apartment model in a structure in the TEB like Windows.
This will allow CoInitializeEx to return the right value, which in itself
has got some apps working better on my machine.
If this patch is ok, then the next question must be: what
functions/interfaces depend on the apartment model?
ChangeLog:
- CoInitializeEx should store apartment model separately for each thread
Rob
-------------- next part --------------
Index: wine/dlls/ole32/compobj.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj.c,v
retrieving revision 1.75
diff -u -r1.75 compobj.c
--- wine/dlls/ole32/compobj.c 13 May 2003 22:14:30 -0000 1.75
+++ wine/dlls/ole32/compobj.c 16 May 2003 14:45:13 -0000
@@ -62,26 +62,10 @@
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");
*/
@@ -296,6 +280,7 @@
)
{
HRESULT hr;
+ OleThreadData * pThreadData;
TRACE("(%p, %x)\n", lpReserved, (int)dwCoInit);
@@ -309,7 +294,7 @@
*/
if (dwCoInit!=COINIT_APARTMENTTHREADED)
{
- FIXME(":(%p,%x): unsupported flag %x\n", lpReserved, (int)dwCoInit, (int)dwCoInit);
+ FIXME(":(%p,%lx): unsupported flag %lx\n", lpReserved, dwCoInit, dwCoInit & ~COINIT_APARTMENTTHREADED);
/* Hope for the best and continue anyway */
}
@@ -328,11 +313,24 @@
RunningObjectTableImpl_Initialize();
+ }
- hr = S_OK;
+ pThreadData = OLE32_GetOleThreadData();
+ if (pThreadData)
+ {
+ if ((pThreadData->ApartmentData.threadingModel & (COINIT_APARTMENTTHREADED | COINIT_MULTITHREADED)) !=
+ (dwCoInit & (COINIT_APARTMENTTHREADED | COINIT_MULTITHREADED)))
+ hr = RPC_E_CHANGED_MODE;
+ else
+ hr = S_FALSE;
}
else
- hr = S_FALSE;
+ {
+ pThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OleThreadData));
+ pThreadData->ApartmentData.threadingModel = (dwCoInit & (COINIT_APARTMENTTHREADED | COINIT_MULTITHREADED));
+ NtCurrentTeb()->ErrorInfo = pThreadData;
+ hr = S_OK;
+ }
return hr;
}
Index: wine/dlls/ole32/compobj_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj_private.h,v
retrieving revision 1.7
diff -u -r1.7 compobj_private.h
--- wine/dlls/ole32/compobj_private.h 13 May 2003 00:41:58 -0000 1.7
+++ wine/dlls/ole32/compobj_private.h 16 May 2003 14:45:15 -0000
@@ -26,6 +26,7 @@
/* All private prototype functions used by OLE will be added to this header file */
#include "wtypes.h"
+#include "thread.h"
extern void* StdGlobalInterfaceTable_Construct();
extern void StdGlobalInterfaceTable_Destroy(void* self);
@@ -120,5 +121,30 @@
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
+
+/*****************************************************************************
+ * 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 threadingModel; /* we use the COINIT flags */
+ long ApartmentLockCount;
+} OleApartmentData;
+
+typedef struct {
+ OleApartmentData ApartmentData;
+ LPVOID pErrorInfo;
+} OleThreadData;
+
+static inline OleThreadData * OLE32_GetOleThreadData()
+{
+ return (OleThreadData *)NtCurrentTeb()->ErrorInfo;
+}
#endif /* __WINE_OLE_COMPOBJ_H */
Index: wine/dlls/ole32/errorinfo.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/errorinfo.c,v
retrieving revision 1.13
diff -u -r1.13 errorinfo.c
--- wine/dlls/ole32/errorinfo.c 5 Dec 2002 20:33:08 -0000 1.13
+++ wine/dlls/ole32/errorinfo.c 16 May 2003 14:45:16 -0000
@@ -32,9 +32,9 @@
#include "objbase.h"
#include "wine/unicode.h"
-#include "thread.h"
#include "wine/debug.h"
+#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -486,10 +486,10 @@
TRACE("(%ld, %p, %p): stub:\n", dwReserved, pperrinfo, NtCurrentTeb()->ErrorInfo);
if(! pperrinfo ) return E_INVALIDARG;
- if(!(*pperrinfo = (IErrorInfo*)(NtCurrentTeb()->ErrorInfo))) return S_FALSE;
+ if(!(*pperrinfo = (IErrorInfo*)(OLE32_GetOleThreadData->pErrorInfo))) return S_FALSE;
/* clear thread error state */
- NtCurrentTeb()->ErrorInfo = NULL;
+ OLE32_GetOleThreadData->pErrorInfo = NULL;
return S_OK;
}
@@ -502,11 +502,11 @@
TRACE("(%ld, %p): stub:\n", dwReserved, perrinfo);
/* release old errorinfo */
- pei = (IErrorInfo*)NtCurrentTeb()->ErrorInfo;
+ pei = OLE32_GetOleThreadData()->pErrorInfo;
if(pei) IErrorInfo_Release(pei);
/* set to new value */
- NtCurrentTeb()->ErrorInfo = perrinfo;
+ OLE32_GetOleThreadData()->pErrorInfo = perrinfo;
if(perrinfo) IErrorInfo_AddRef(perrinfo);
return S_OK;
}
More information about the wine-devel
mailing list