Commit in reactos/lib/ole32 on MAIN
compobj.c+49-211.6 -> 1.7
compobj_private.h+91.2 -> 1.3
errorinfo.c+18-71.3 -> 1.4
+76-28
3 modified files
Sync with Wine-20040213:
Robert Shearman <R.J.Shearman@warwick.ac.uk>
- CoSetState info should be thread local.
- SetErrorInfo should allocate an apartment when no apartment present.
Alexandre Julliard
Moved a few remaining 16-bit definitions out of the standard headers.

reactos/lib/ole32
compobj.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- compobj.c	28 Jan 2004 21:27:50 -0000	1.6
+++ compobj.c	17 Feb 2004 23:00:01 -0000	1.7
@@ -184,16 +184,27 @@
     MTA.oxid = 0;
 }
 
-static APARTMENT* COM_CreateApartment(DWORD model)
+/* creates an apartment structure which stores OLE thread-local
+ * information. Call with COINIT_UNINITIALIZED to create an apartment
+ * that will be initialized with a model later. Note: do not call
+ * with COINIT_UNINITIALIZED if the apartment has already been initialized
+ * with a different COINIT value */
+APARTMENT* COM_CreateApartment(DWORD model)
 {
     APARTMENT *apt;
+    BOOL create = (NtCurrentTeb()->ReservedForOle == NULL);
 
-    apt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(APARTMENT));
+    if (create)
+    {
+        apt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(APARTMENT));
+        apt->tid = GetCurrentThreadId();
+        DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &apt->thread,
+                        THREAD_ALL_ACCESS, FALSE, 0);
+    }
+    else
+        apt = NtCurrentTeb()->ReservedForOle;
     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();
@@ -202,14 +213,17 @@
 			       0, 0, OLE32_hInstance, NULL);
       InitializeCriticalSection(&apt->cs);
     }
-    else {
+    else if (!(model & COINIT_UNINITIALIZED)) {
       apt->parent = &MTA;
       apt->oxid = MTA.oxid;
     }
     EnterCriticalSection(&csApartment);
-    if (apts) apts->prev = apt;
-    apt->next = apts;
-    apts = apt;
+    if (create)
+    {
+        if (apts) apts->prev = apt;
+        apt->next = apts;
+        apts = apt;
+    }
     LeaveCriticalSection(&csApartment);
     NtCurrentTeb()->ReservedForOle = apt;
     return apt;
@@ -384,8 +398,17 @@
   }
 
   apt = NtCurrentTeb()->ReservedForOle;
-  if (apt && dwCoInit != apt->model) return RPC_E_CHANGED_MODE;
-  hr = apt ? S_FALSE : S_OK;
+  if (apt && !(apt->model == COINIT_UNINITIALIZED))
+  {
+    if (dwCoInit != apt->model)
+    {
+      WARN("Apartment threading model already initialized with another model\n");
+      return RPC_E_CHANGED_MODE;
+    }
+    hr = S_FALSE;
+  }
+  else
+    hr = S_OK;
 
   /*
    * Check the lock count. If this is the first time going through the initialize
@@ -405,7 +428,7 @@
     RunningObjectTableImpl_Initialize();
   }
 
-  if (!apt) apt = COM_CreateApartment(dwCoInit);
+  if (!apt || apt->model == COINIT_UNINITIALIZED) apt = COM_CreateApartment(dwCoInit);
 
   InterlockedIncrement(&apt->inits);
   if (hr == S_OK) NtCurrentTeb()->ReservedForOle = apt;
@@ -1861,7 +1884,6 @@
     return 0;
 }
 
-static IUnknown * pUnkState = 0; /* FIXME: thread local */
 static int nStatCounter = 0;	 /* global */
 static HMODULE hOleAut32 = 0;	 /* global */
 
@@ -1872,11 +1894,13 @@
  */
 HRESULT WINAPI CoGetState(IUnknown ** ppv)
 {
+	APARTMENT * apt = COM_CurrentInfo();
+
 	FIXME("\n");
 
-	if(pUnkState) {
-	    IUnknown_AddRef(pUnkState);
-	    *ppv = pUnkState;
+	if(apt && apt->state) {
+	    IUnknown_AddRef(apt->state);
+	    *ppv = apt->state;
 	    FIXME("-- %p\n", *ppv);
 	    return S_OK;
 	}
@@ -1892,6 +1916,10 @@
  */
 HRESULT WINAPI CoSetState(IUnknown * pv)
 {
+    APARTMENT * apt = COM_CurrentInfo();
+
+    if (!apt) apt = COM_CreateApartment(COINIT_UNINITIALIZED);
+
 	FIXME("(%p),stub!\n", pv);
 
 	if (pv) {
@@ -1900,13 +1928,13 @@
 	    if (nStatCounter == 1) LoadLibraryA("OLEAUT32.DLL");
 	}
 
-	if (pUnkState) {
-	    TRACE("-- release %p now\n", pUnkState);
-	    IUnknown_Release(pUnkState);
+	if (apt->state) {
+	    TRACE("-- release %p now\n", apt->state);
+	    IUnknown_Release(apt->state);
 	    nStatCounter--;
 	    if (!nStatCounter) FreeLibrary(hOleAut32);
 	}
-	pUnkState = pv;
+	apt->state = pv;
 	return S_OK;
 }
 

reactos/lib/ole32
compobj_private.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- compobj_private.h	2 Jan 2004 19:49:45 -0000	1.2
+++ compobj_private.h	17 Feb 2004 23:00:01 -0000	1.3
@@ -35,6 +35,13 @@
 #include "winreg.h"
 #include "winternl.h"
 
+/* Windows maps COINIT values to 0x80 for apartment threaded, 0x140
+ * for free threaded, and 0 for uninitialized apartments. There is
+ * no real advantage in us doing this and certainly no release version
+ * of an app should be poking around with these flags. So we need a
+ * special value for uninitialized */
+#define COINIT_UNINITIALIZED 0x100
+
 /* exported interface */
 typedef struct tagXIF {
   struct tagXIF *next;
@@ -96,6 +103,7 @@
   LPMESSAGEFILTER filter;  /* message filter */
   XOBJECT *objs;           /* exported objects */
   IOBJECT *proxies;        /* imported objects */
+  LPUNKNOWN state;         /* state object (see Co[Get,Set]State) */
   LPVOID ErrorInfo;        /* thread error info */
 } APARTMENT;
 
@@ -217,6 +225,7 @@
 }
 
 /* compobj.c */
+APARTMENT* COM_CreateApartment(DWORD model);
 HWND COM_GetApartmentWin(OXID oxid);
 
 #endif /* __WINE_OLE_COMPOBJ_H */

reactos/lib/ole32
errorinfo.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- errorinfo.c	22 Jan 2004 20:12:04 -0000	1.3
+++ errorinfo.c	17 Feb 2004 23:00:01 -0000	1.4
@@ -484,13 +484,20 @@
  */
 HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
 {
-	TRACE("(%ld, %p, %p): stub:\n", dwReserved, pperrinfo, COM_CurrentInfo()->ErrorInfo);
+	APARTMENT * apt = COM_CurrentInfo();
 
-	if(! pperrinfo ) return E_INVALIDARG;
-	if(!(*pperrinfo = (IErrorInfo*)(COM_CurrentInfo()->ErrorInfo))) return S_FALSE;
+	TRACE("(%ld, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->ErrorInfo);
 
+	if(!pperrinfo) return E_INVALIDARG;
+	if (!apt || !apt->ErrorInfo)
+	{
+	   *pperrinfo = NULL;
+	   return S_FALSE;
+	}
+
+	*pperrinfo = (IErrorInfo*)(apt->ErrorInfo);
 	/* clear thread error state */
-	COM_CurrentInfo()->ErrorInfo = NULL;
+	apt->ErrorInfo = NULL;
 	return S_OK;
 }
 
@@ -500,14 +507,18 @@
 HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
 {
 	IErrorInfo * pei;
-	TRACE("(%ld, %p): stub:\n", dwReserved, perrinfo);
+	APARTMENT * apt = COM_CurrentInfo();
+
+	TRACE("(%ld, %p)\n", dwReserved, perrinfo);
+	
+	if (!apt) apt = COM_CreateApartment(COINIT_UNINITIALIZED);
 
 	/* release old errorinfo */
-	pei = (IErrorInfo*)COM_CurrentInfo()->ErrorInfo;
+	pei = (IErrorInfo*)apt->ErrorInfo;
 	if(pei) IErrorInfo_Release(pei);
 
 	/* set to new value */
-	COM_CurrentInfo()->ErrorInfo = perrinfo;
+	apt->ErrorInfo = perrinfo;
 	if(perrinfo) IErrorInfo_AddRef(perrinfo);
 	return S_OK;
 }
CVSspam 0.2.8