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