reactos/lib/ole32
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
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
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;
}