Wine-20050111 vendor drop
Added: vendor/wine/dlls/ole32/Wine-20050111/
Modified: vendor/wine/dlls/ole32/Wine-20050111/Makefile.in
Modified: vendor/wine/dlls/ole32/Wine-20050111/bindctx.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/clipboard.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/compobj.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/compobj_private.h
Modified: vendor/wine/dlls/ole32/Wine-20050111/compositemoniker.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/datacache.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/defaulthandler.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/errorinfo.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/filemoniker.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/ftmarshal.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/hglobalstream.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/ifs.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/ifs.h
Modified: vendor/wine/dlls/ole32/Wine-20050111/itemmoniker.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/marshal.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/memlockbytes.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/moniker.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/ole2.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/oleobj.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/oleproxy.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/rpc.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/stg_bigblockfile.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/stg_stream.c
Modified: vendor/wine/dlls/ole32/Wine-20050111/storage32.c
Added: vendor/wine/dlls/ole32/Wine-20050111/stubmanager.c
Modified: vendor/wine/dlls/ole32/current/Makefile.in
Modified: vendor/wine/dlls/ole32/current/bindctx.c
Modified: vendor/wine/dlls/ole32/current/clipboard.c
Modified: vendor/wine/dlls/ole32/current/compobj.c
Modified: vendor/wine/dlls/ole32/current/compobj_private.h
Modified: vendor/wine/dlls/ole32/current/compositemoniker.c
Modified: vendor/wine/dlls/ole32/current/datacache.c
Modified: vendor/wine/dlls/ole32/current/defaulthandler.c
Modified: vendor/wine/dlls/ole32/current/errorinfo.c
Modified: vendor/wine/dlls/ole32/current/filemoniker.c
Modified: vendor/wine/dlls/ole32/current/ftmarshal.c
Modified: vendor/wine/dlls/ole32/current/hglobalstream.c
Modified: vendor/wine/dlls/ole32/current/ifs.c
Modified: vendor/wine/dlls/ole32/current/ifs.h
Modified: vendor/wine/dlls/ole32/current/itemmoniker.c
Modified: vendor/wine/dlls/ole32/current/marshal.c
Modified: vendor/wine/dlls/ole32/current/memlockbytes.c
Modified: vendor/wine/dlls/ole32/current/moniker.c
Modified: vendor/wine/dlls/ole32/current/ole2.c
Modified: vendor/wine/dlls/ole32/current/oleobj.c
Modified: vendor/wine/dlls/ole32/current/oleproxy.c
Modified: vendor/wine/dlls/ole32/current/rpc.c
Modified: vendor/wine/dlls/ole32/current/stg_bigblockfile.c
Modified: vendor/wine/dlls/ole32/current/stg_stream.c
Modified: vendor/wine/dlls/ole32/current/storage32.c
Added: vendor/wine/dlls/ole32/current/stubmanager.c
_____
Copied: vendor/wine/dlls/ole32/Wine-20050111 (from rev 12927,
vendor/wine/dlls/ole32/current)
_____
Modified: vendor/wine/dlls/ole32/Wine-20050111/Makefile.in
--- vendor/wine/dlls/ole32/current/Makefile.in 2005-01-11 20:23:48 UTC
(rev 12927)
+++ vendor/wine/dlls/ole32/Wine-20050111/Makefile.in 2005-01-12
09:03:31 UTC (rev 12947)
@@ -35,7 +35,8 @@
rpc.c \
stg_bigblockfile.c \
stg_stream.c \
- storage32.c
+ storage32.c \
+ stubmanager.c
C_SRCS16 = \
memlockbytes16.c \
_____
Modified: vendor/wine/dlls/ole32/Wine-20050111/bindctx.c
--- vendor/wine/dlls/ole32/current/bindctx.c 2005-01-11 20:23:48 UTC
(rev 12927)
+++ vendor/wine/dlls/ole32/Wine-20050111/bindctx.c 2005-01-12
09:03:31 UTC (rev 12947)
@@ -275,8 +275,7 @@
if(This->bindCtxTable[index].pObj)
IUnknown_Release(This->bindCtxTable[index].pObj);
- if(This->bindCtxTable[index].pkeyObj)
- HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
+ HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
/* left-shift all elements in the right side of the current revoked
object */
for(j=index; j<This->bindCtxTableLastIndex-1; j++)
@@ -302,8 +301,7 @@
{
if(This->bindCtxTable[i].pObj)
IUnknown_Release(This->bindCtxTable[i].pObj);
- if(This->bindCtxTable[i].pkeyObj)
- HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
+ HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
}
This->bindCtxTableLastIndex = 0;
@@ -472,8 +470,7 @@
/* release the object if it's found */
if(This->bindCtxTable[index].pObj)
IUnknown_Release(This->bindCtxTable[index].pObj);
- if(This->bindCtxTable[index].pkeyObj)
- HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
+ HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
/* remove the object from the table with a left-shifting of all
objects in the right side */
for(j=index; j<This->bindCtxTableLastIndex-1; j++)
_____
Modified: vendor/wine/dlls/ole32/Wine-20050111/clipboard.c
--- vendor/wine/dlls/ole32/current/clipboard.c 2005-01-11 20:23:48 UTC
(rev 12927)
+++ vendor/wine/dlls/ole32/Wine-20050111/clipboard.c 2005-01-12
09:03:31 UTC (rev 12947)
@@ -736,7 +736,7 @@
* We don't bother doing this since the FindClassByAtom code
* would have to be changed to deal with this idiosyncrasy. */
wcex.style = CS_GLOBALCLASS;
- wcex.lpfnWndProc = (WNDPROC)OLEClipbrd_WndProc;
+ wcex.lpfnWndProc = OLEClipbrd_WndProc;
wcex.hInstance = 0;
wcex.lpszClassName = OLEClipbrd_WNDCLASS;
@@ -1489,8 +1489,7 @@
/*
* Free the array of FORMATETC's
*/
- if (afmt)
- HeapFree(GetProcessHeap(), 0, afmt);
+ HeapFree(GetProcessHeap(), 0, afmt);
/*
* Close Windows clipboard
_____
Modified: vendor/wine/dlls/ole32/Wine-20050111/compobj.c
--- vendor/wine/dlls/ole32/current/compobj.c 2005-01-11 20:23:48 UTC
(rev 12927)
+++ vendor/wine/dlls/ole32/Wine-20050111/compobj.c 2005-01-12
09:03:31 UTC (rev 12947)
@@ -21,6 +21,44 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
+ *
+ * Note
+ * 1. COINIT_MULTITHREADED is 0; it is the lack of
COINIT_APARTMENTTHREADED
+ * Therefore do not test against COINIT_MULTITHREADED
+ *
+ * TODO list: (items bunched together depend on each other)
+ *
+ * - Switch wine_marshal_id to use IPIDs not IIDs
+ * - Once that's done, replace wine_marshal_id with STDOBJREF
+ *
+ * - Rewrite the CoLockObjectExternal code, it does totally the wrong
+ * thing currently (should be controlling the stub manager)
+ *
+ * - Make the MTA dynamically allocated and refcounted
+ * - Free the ReservedForOle data in DllMain(THREAD_DETACH)
+ *
+ * - Implement the service control manager (in rpcss) to keep track
+ * of registered class objects: ISCM::ServerRegisterClsid et al
+ * - Implement the OXID resolver so we don't need magic pipe names
for
+ * clients and servers to meet up
+ * - Flip our marshalling on top of the RPC runtime transport API,
+ * so we no longer use named pipes to communicate
+ * - Rework threading so re-entrant calls don't need to be sent on
+ * the incoming pipe
+ * - Implement RPC thread affinity (should fix InstallShield painting
+ * problems)
+ *
+ * - Implement IRemUnknown and marshalling for it, then use that for
+ * reffing/unreffing the stub manager from a proxy instead of our
+ * current hack of simply reffing the stub manager once when it's
+ * registered.
+ * - Implement table marshalling, then use it to let us do the final
+ * rework of the threading
+ *
+ * - Make our custom marshalling use NDR to be wire compatible with
+ * native DCOM
+ *
+ *
*/
#include "config.h"
@@ -61,15 +99,15 @@
*
* TODO: Most of these things will have to be made thread-safe.
*/
-HINSTANCE COMPOBJ_hInstance32 = 0;
static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD
dwClsContext, LPUNKNOWN* ppUnk);
-static void COM_RevokeAllClasses();
-static void COM_ExternalLockFreeList();
+static void COM_RevokeAllClasses(void);
+static void COM_ExternalLockFreeList(void);
const CLSID CLSID_StdGlobalInterfaceTable = { 0x00000323, 0, 0, {0xc0,
0, 0, 0, 0, 0, 0, 0x46} };
-APARTMENT MTA, *apts;
+APARTMENT MTA;
+static struct list apts = LIST_INIT( apts );
static CRITICAL_SECTION csApartment;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -102,7 +140,7 @@
DWORD runContext;
DWORD connectFlags;
DWORD dwCookie;
- HANDLE hThread; /* only for localserver */
+ LPSTREAM pMarshaledData; /* FIXME: only really need to store OXID
and IPID */
struct tagRegisteredClass* nextClass;
} RegisteredClass;
@@ -206,6 +244,7 @@
MTA.oxid = 0;
}
+
/* 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
@@ -213,81 +252,138 @@
* with a different COINIT value */
APARTMENT* COM_CreateApartment(DWORD model)
{
- APARTMENT *apt;
- BOOL create = (NtCurrentTeb()->ReservedForOle == NULL);
+ APARTMENT *apt = COM_CurrentApt();
- if (create)
+ if (!apt)
{
+ if (!(model & COINIT_APARTMENTTHREADED)) /* See note 1 above */
+ {
+ TRACE("thread 0x%lx is entering the multithreaded
apartment\n", GetCurrentThreadId());
+ COM_CurrentInfo()->apt = &MTA;
+ return COM_CurrentInfo()->apt;
+ }
+
+ TRACE("creating new apartment, model=%ld\n", model);
+
apt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(APARTMENT));
apt->tid = GetCurrentThreadId();
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &apt->thread,
THREAD_ALL_ACCESS, FALSE, 0);
+
+ list_init(&apt->proxies);
+ list_init(&apt->stubmgrs);
+ apt->oidc = 1;
+ apt->refs = 1;
+ InitializeCriticalSection(&apt->cs);
+
+ apt->model = model;
+
+ /* we don't ref the apartment as CoInitializeEx will do it for
us */
+
+ if (model & COINIT_APARTMENTTHREADED)
+ {
+ /* FIXME: how does windoze create OXIDs? */
+ apt->oxid = MTA.oxid | GetCurrentThreadId();
+ TRACE("Created apartment on OXID %s\n",
wine_dbgstr_longlong(apt->oxid));
+ apt->win = CreateWindowA(aptWinClass, NULL, 0,
+ 0, 0, 0, 0,
+ 0, 0, OLE32_hInstance, NULL);
+ }
+
+ EnterCriticalSection(&csApartment);
+ list_add_head(&apts, &apt->entry);
+ LeaveCriticalSection(&csApartment);
+
+ COM_CurrentInfo()->apt = apt;
}
- else
- apt = NtCurrentTeb()->ReservedForOle;
- apt->model = model;
- 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 if (!(model & COINIT_UNINITIALIZED)) {
- apt->parent = &MTA;
- apt->oxid = MTA.oxid;
- }
- EnterCriticalSection(&csApartment);
- if (create)
+ return apt;
+}
+
+DWORD COM_ApartmentAddRef(struct apartment *apt)
+{
+ return InterlockedIncrement(&apt->refs);
+}
+
+DWORD COM_ApartmentRelease(struct apartment *apt)
+{
+ DWORD ret;
+
+ ret = InterlockedDecrement(&apt->refs);
+ if (ret == 0)
{
- if (apts) apts->prev = apt;
- apt->next = apts;
- apts = apt;
+ TRACE("destroying apartment %p, oxid %s\n", apt,
wine_dbgstr_longlong(apt->oxid));
+
+ EnterCriticalSection(&csApartment);
+ list_remove(&apt->entry);
+ LeaveCriticalSection(&csApartment);
+
+ MARSHAL_Disconnect_Proxies(apt);
+
+ if (apt->win) DestroyWindow(apt->win);
+
+ if (!list_empty(&apt->stubmgrs))
+ {
+ FIXME("Destroy outstanding stubs\n");
+ }
+
+ if (apt->filter) IUnknown_Release(apt->filter);
+
+
+ DeleteCriticalSection(&apt->cs);
+ CloseHandle(apt->thread);
+ HeapFree(GetProcessHeap(), 0, apt);
+
+ apt = NULL;
}
- LeaveCriticalSection(&csApartment);
- NtCurrentTeb()->ReservedForOle = apt;
- return apt;
+
+ return ret;
}
-static void COM_DestroyApartment(APARTMENT *apt)
+/* The given OXID must be local to this process: you cannot use
+ * apartment windows to send RPCs to other processes. This all needs
+ * to move to rpcrt4.
+ *
+ * The ref parameter is here mostly to ensure people remember that
+ * they get one, you should normally take a ref for thread safety.
+ */
+APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref)
{
+ APARTMENT *result = NULL;
+ struct list *cursor;
+
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;
+ LIST_FOR_EACH( cursor, &apts )
+ {
+ struct apartment *apt = LIST_ENTRY( cursor, struct apartment,
entry );
+ if (apt->oxid == oxid)
+ {
+ result = apt;
+ if (ref) COM_ApartmentAddRef(result);
+ break;
+ }
+ }
LeaveCriticalSection(&csApartment);
- if (apt->model & COINIT_APARTMENTTHREADED) {
- if (apt->win) DestroyWindow(apt->win);
- DeleteCriticalSection(&apt->cs);
- }
- CloseHandle(apt->thread);
- HeapFree(GetProcessHeap(), 0, apt);
+
+ return result;
}
-/* The given OXID must be local to this process: you cannot use
apartment
- windows to send RPCs to other processes. This all needs to move to
rpcrt4 */
-HWND COM_GetApartmentWin(OXID oxid)
+HWND COM_GetApartmentWin(OXID oxid, BOOL ref)
{
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;
+ apt = COM_ApartmentFromOXID(oxid, ref);
+ if (!apt) return NULL;
+
+ return apt->win;
}
/* Currently inter-thread marshalling is not fully implemented, so this
does nothing */
static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM
wParam, LPARAM lParam)
{
return DefWindowProcA(hWnd, msg, wParam, lParam);
-}
+}
/***********************************************************************
******
* This section contains OpenDllList implemantation
@@ -418,8 +514,7 @@
* CoUninitialize
*/
HRESULT WINAPI CoInitializeEx(
- LPVOID lpReserved, /* [in] pointer to win32 malloc
interface
- (obsolete, should be NULL) */
+ LPVOID lpReserved, /* [in] pointer to win32 malloc
interface (obsolete, should be NULL) */
DWORD dwCoInit /* [in] A value from COINIT specifies
the threading model */
)
{
@@ -433,21 +528,6 @@
ERR("(%p, %x) - Bad parameter passed-in %p, must be an old Windows
Application\n", lpReserved, (int)dwCoInit, lpReserved);
}
- apt = NtCurrentTeb()->ReservedForOle;
- if (apt && !(apt->model == COINIT_UNINITIALIZED))
- {
- if (dwCoInit != apt->model)
- {
- /* Changing the threading model after it's been set is illegal.
If this warning is triggered by Wine
- code then we are probably using the wrong threading model to
implement that API. */
- ERR("Attempt to change threading model of this apartment from
0x%lx to 0x%lx\n", apt->model, dwCoInit);
- 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
* process, we have to initialize the libraries.
@@ -463,13 +543,25 @@
COM_InitMTA();
+ /* we may need to defer this until after apartment initialisation
*/
RunningObjectTableImpl_Initialize();
}
- if (!apt || apt->model == COINIT_UNINITIALIZED) apt =
COM_CreateApartment(dwCoInit);
+ if (!(apt = COM_CurrentInfo()->apt))
+ {
+ apt = COM_CreateApartment(dwCoInit);
+ if (!apt) return E_OUTOFMEMORY;
+ }
+ else if (dwCoInit != apt->model)
+ {
+ /* Changing the threading model after it's been set is illegal. If
this warning is triggered by Wine
+ code then we are probably using the wrong threading model to
implement that API. */
+ ERR("Attempt to change threading model of this apartment from 0x%lx
to 0x%lx\n", apt->model, dwCoInit);
+ COM_ApartmentRelease(apt);
+ return RPC_E_CHANGED_MODE;
+ }
- InterlockedIncrement(&apt->inits);
- if (hr == S_OK) NtCurrentTeb()->ReservedForOle = apt;
+ COM_CurrentInfo()->inits++;
return hr;
}
@@ -480,14 +572,20 @@
void COM_FlushMessageQueue(void)
{
MSG message;
- APARTMENT *apt = NtCurrentTeb()->ReservedForOle;
+ APARTMENT *apt = COM_CurrentApt();
if (!apt || !apt->win) return;
TRACE("Flushing STA message queue\n");
- while (PeekMessageA(&message, NULL, 0, 0, PM_REMOVE)) {
- if (message.hwnd != apt->win) continue;
+ while (PeekMessageA(&message, NULL, 0, 0, PM_REMOVE))
+ {
+ if (message.hwnd != apt->win)
+ {
+ WARN("discarding message 0x%x for window %p\n",
message.message, message.hwnd);
+ continue;
+ }
+
TranslateMessage(&message);
DispatchMessageA(&message);
}
@@ -511,19 +609,27 @@
*/
void WINAPI CoUninitialize(void)
{
+ struct oletls * info = COM_CurrentInfo();
LONG lCOMRefCnt;
- APARTMENT *apt;
TRACE("()\n");
- apt = NtCurrentTeb()->ReservedForOle;
- if (!apt) return;
- if (InterlockedDecrement(&apt->inits)==0) {
- NtCurrentTeb()->ReservedForOle = NULL;
- COM_DestroyApartment(apt);
- apt = NULL;
+ /* will only happen on OOM */
+ if (!info) return;
+
+ /* sanity check */
+ if (!info->inits)
+ {
+ ERR("Mismatched CoUninitialize\n");
+ return;
}
+ if (!--info->inits)
+ {
+ COM_ApartmentRelease(info->apt);
+ info->apt = NULL;
+ }
+
/*
* Decrease the reference count.
* If we are back to 0 locks on the COM library, make sure we free
@@ -536,14 +642,6 @@
RunningObjectTableImpl_UnInitialize();
- /* disconnect proxies to release the corresponding stubs.
- * It is confirmed in "Essential COM" in the sub-chapter on
- * "Lifecycle Management and Marshalling" that the native version
also
- * does some kind of proxy cleanup in this function.
- * FIXME: does it just disconnect or completely destroy the
proxies?
- * FIXME: should this be in the apartment destructor? */
- MARSHAL_Disconnect_Proxies();
-
/* Release the references to the registered class objects */
COM_RevokeAllClasses();
@@ -1091,117 +1189,24 @@
return hr;
}
-static DWORD WINAPI
-_LocalServerThread(LPVOID param) {
- HANDLE hPipe;
- char pipefn[200];
- RegisteredClass *newClass = (RegisteredClass*)param;
- HRESULT hres;
- IStream *pStm;
- STATSTG ststg;
- unsigned char *buffer;
- int buflen;
- IClassFactory *classfac;
- LARGE_INTEGER seekto;
- ULARGE_INTEGER newpos;
- ULONG res;
-
- TRACE("Starting threader for
%s.\n",debugstr_guid(&newClass->classIdentifier));
-
- strcpy(pipefn,PIPEPREF);
-
WINE_StringFromCLSID(&newClass->classIdentifier,pipefn+strlen(PIPEPREF))
;
-
- hPipe = CreateNamedPipeA( pipefn, PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
- 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT, NULL );
- if (hPipe == INVALID_HANDLE_VALUE) {
- FIXME("pipe creation failed for %s, le is
%lx\n",pipefn,GetLastError());
- return 1;
- }
- while (1) {
- if (!ConnectNamedPipe(hPipe,NULL)) {
- ERR("Failure during ConnectNamedPipe %lx,
ABORT!\n",GetLastError());
- break;
- }
-
- TRACE("marshalling IClassFactory to client\n");
-
- hres =
IUnknown_QueryInterface(newClass->classObject,&IID_IClassFactory,(LPVOID
*)&classfac);
- if (hres) return hres;
-
- hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
- if (hres) {
- FIXME("Failed to create stream on hglobal.\n");
- return hres;
- }
- hres =
CoMarshalInterface(pStm,&IID_IClassFactory,(LPVOID)classfac,0,NULL,0);
- if (hres) {
- FIXME("CoMarshalInterface failed, %lx!\n",hres);
- return hres;
- }
-
- IUnknown_Release(classfac); /* is this right? */
-
- hres = IStream_Stat(pStm,&ststg,0);
- if (hres) return hres;
-
- buflen = ststg.cbSize.u.LowPart;
- buffer = HeapAlloc(GetProcessHeap(),0,buflen);
- seekto.u.LowPart = 0;
- seekto.u.HighPart = 0;
- hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
- if (hres) {
- FIXME("IStream_Seek failed, %lx\n",hres);
- return hres;
- }
-
- hres = IStream_Read(pStm,buffer,buflen,&res);
- if (hres) {
- FIXME("Stream Read failed, %lx\n",hres);
- return hres;
- }
-
- IStream_Release(pStm);
-
- WriteFile(hPipe,buffer,buflen,&res,NULL);
- FlushFileBuffers(hPipe);
- DisconnectNamedPipe(hPipe);
-
- TRACE("done marshalling IClassFactory\n");
- }
- CloseHandle(hPipe);
- return 0;
-}
-
/***********************************************************************
*******
* CoRegisterClassObject [OLE32.@]
- *
- * This method will register the class object for a given class
- * ID. Servers housed in EXE files use this method instead of
- * exporting DllGetClassObject to allow other code to connect to their
- * objects.
*
- * When a class object (an object which implements IClassFactory) is
- * registered in this way, a new thread is started which listens for
- * connections on a named pipe specific to the registered CLSID. When
- * something else connects to it, it writes out the marshalled
- * IClassFactory interface to the pipe. The code on the other end uses
- * this buffer to unmarshal the class factory, and can then call
- * methods on it.
+ * Registers the class object for a given class ID. Servers housed in
EXE
+ * files use this method instead of exporting DllGetClassObject to
allow
+ * other code to connect to their objects.
*
- * In Windows, such objects are registered with the RPC endpoint
- * mapper, not with a unique named pipe.
- *
- * MSDN claims that multiple interface registrations are legal, but we
- * can't do that with our current implementation.
- *
* RETURNS
- * S_OK on success,
- * E_INVALIDARG if lpdwRegister or pUnk are NULL,
+ * S_OK on success,
+ * E_INVALIDARG if lpdwRegister or pUnk are NULL,
* CO_E_OBJISREG if the object is already registered. We should not
return this.
*
* SEE ALSO
* CoRevokeClassObject, CoGetClassObject
+ *
+ * BUGS
+ * MSDN claims that multiple interface registrations are legal, but we
+ * can't do that with our current implementation.
*/
HRESULT WINAPI CoRegisterClassObject(
REFCLSID rclsid, /* [in] CLSID of the object to register
*/
@@ -1220,6 +1225,12 @@
if ( (lpdwRegister==0) || (pUnk==0) )
return E_INVALIDARG;
+ if (!COM_CurrentApt())
+ {
+ ERR("COM was not initialized\n");
+ return CO_E_NOTINITIALIZED;
+ }
+
*lpdwRegister = 0;
/*
@@ -1243,7 +1254,7 @@
newClass->connectFlags = flags;
/*
* Use the address of the chain node as the cookie since we are sure
it's
- * unique.
+ * unique. FIXME: not on 64-bit platforms.
*/
newClass->dwCookie = (DWORD)newClass;
newClass->nextClass = firstRegisteredClass;
@@ -1261,10 +1272,30 @@
*lpdwRegister = newClass->dwCookie;
if (dwClsContext & CLSCTX_LOCAL_SERVER) {
- DWORD tid;
+ IClassFactory *classfac;
- STUBMGR_Start();
-
newClass->hThread=CreateThread(NULL,0,_LocalServerThread,newClass,0,&tid
);
+ hr = IUnknown_QueryInterface(newClass->classObject,
&IID_IClassFactory,
+ (LPVOID*)&classfac);
+ if (hr) return hr;
+
+ hr = CreateStreamOnHGlobal(0, TRUE, &newClass->pMarshaledData);
+ if (hr) {
+ FIXME("Failed to create stream on hglobal, %lx\n", hr);
+ IUnknown_Release(classfac);
+ return hr;
+ }
+ hr = CoMarshalInterface(newClass->pMarshaledData,
&IID_IClassFactory,
+ (LPVOID)classfac, MSHCTX_LOCAL, NULL,
+ MSHLFLAGS_TABLESTRONG);
+ if (hr) {
+ FIXME("CoMarshalInterface failed, %lx!\n",hr);
+ IUnknown_Release(classfac);
+ return hr;
+ }
+
+ IUnknown_Release(classfac);
+
+ RPC_StartLocalServer(&newClass->classIdentifier,
newClass->pMarshaledData);
}
return S_OK;
}
@@ -1310,6 +1341,15 @@
*/
IUnknown_Release(curClass->classObject);
+ if (curClass->pMarshaledData)
+ {
+ LARGE_INTEGER zero;
+ memset(&zero, 0, sizeof(zero));
+ /* FIXME: stop local server thread */
+ IStream_Seek(curClass->pMarshaledData, zero, SEEK_SET, NULL);
+ CoReleaseMarshalData(curClass->pMarshaledData);
+ }
+
/*
* Free the memory used by the chain node.
*/
@@ -1509,7 +1549,7 @@
pat=ReadPatternFromRegistry(i,j);
hFile=CreateFileW(filePathName,,,,,,hFile);
SetFilePosition(hFile,pat.offset);
- ReadFile(hFile,buf,pat.size,NULL,NULL);
+ ReadFile(hFile,buf,pat.size,&r,NULL);
if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
*pclsid=ReadCLSIDFromRegistry(i);
@@ -1573,7 +1613,7 @@
LPCLASSFACTORY lpclf = 0;
if (!COM_CurrentApt()) return CO_E_NOTINITIALIZED;
-
+
/*
* Sanity check
*/
@@ -1590,15 +1630,15 @@
* Rather than create a class factory, we can just check for it here
*/
if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable)) {
- if (StdGlobalInterfaceTableInstance == NULL)
+ if (StdGlobalInterfaceTableInstance == NULL)
StdGlobalInterfaceTableInstance =
StdGlobalInterfaceTable_Construct();
hres = IGlobalInterfaceTable_QueryInterface(
(IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, iid, ppv);
if (hres) return hres;
-
+
TRACE("Retrieved GIT (%p)\n", *ppv);
return S_OK;
}
-
+
/*
* Get a class factory to construct the object we want.
*/
@@ -1982,6 +2022,8 @@
BOOL fLock, /* [in] do lock */
BOOL fLastUnlockReleases) /* [in] unlock all */
{
+ TRACE("pUnk=%p, fLock=%s, fLastUnlockReleases=%s\n",
+ pUnk, fLock ? "TRUE" : "FALSE", fLastUnlockReleases ?
"TRUE"
: "FALSE");
if (fLock) {
/*
@@ -2015,19 +2057,19 @@
*/
HRESULT WINAPI CoGetState(IUnknown ** ppv)
{
- APARTMENT * apt = COM_CurrentInfo();
+ HRESULT hr = E_FAIL;
- FIXME("\n");
+ *ppv = NULL;
- if(apt && apt->state) {
- IUnknown_AddRef(apt->state);
- *ppv = apt->state;
- FIXME("-- %p\n", *ppv);
- return S_OK;
- }
- *ppv = NULL;
- return E_FAIL;
+ if (COM_CurrentInfo()->state)
+ {
+ IUnknown_AddRef(COM_CurrentInfo()->state);
+ *ppv = COM_CurrentInfo()->state;
+ TRACE("apt->state=%p\n", COM_CurrentInfo()->state);
+ hr = S_OK;
+ }
+ return hr;
}
/***********************************************************************
@@ -2036,22 +2078,17 @@
*/
HRESULT WINAPI CoSetState(IUnknown * pv)
{
- APARTMENT * apt = COM_CurrentInfo();
+ if (pv) IUnknown_AddRef(pv);
- if (!apt) apt = COM_CreateApartment(COINIT_UNINITIALIZED);
+ if (COM_CurrentInfo()->state)
+ {
+ TRACE("-- release %p now\n", COM_CurrentInfo()->state);
+ IUnknown_Release(COM_CurrentInfo()->state);
+ }
- FIXME("(%p),stub!\n", pv);
+ COM_CurrentInfo()->state = pv;
- if (pv) {
- IUnknown_AddRef(pv);
- }
-
- if (apt->state) {
- TRACE("-- release %p now\n", apt->state);
- IUnknown_Release(apt->state);
- }
- apt->state = pv;
- return S_OK;
+ return S_OK;
}
@@ -2206,7 +2243,7 @@
done:
if (hkey) RegCloseKey(hkey);
return res;
-
+
}
/***********************************************************************
_____
Modified: vendor/wine/dlls/ole32/Wine-20050111/compobj_private.h
--- vendor/wine/dlls/ole32/current/compobj_private.h 2005-01-11
20:23:48 UTC (rev 12927)
+++ vendor/wine/dlls/ole32/Wine-20050111/compobj_private.h
2005-01-12 09:03:31 UTC (rev 12947)
@@ -5,6 +5,7 @@
* Copyright 1999 Sylvain St-Germain
* Copyright 2002 Marcus Meissner
* Copyright 2003 Ove Kåven, TransGaming Technologies
+ * Copyright 2004 Mike Hearn, CodeWeavers Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,6 +29,8 @@
#include <stdarg.h>
+#include "wine/list.h"
+
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
@@ -35,13 +38,9 @@
#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
+struct apartment;
+
/* exported interface */
typedef struct tagXIF {
struct tagXIF *next;
@@ -56,7 +55,7 @@
/* exported object */
typedef struct tagXOBJECT {
IRpcStubBufferVtbl *lpVtbl;
- struct tagAPARTMENT *parent;
+ struct apartment *parent;
struct tagXOBJECT *next;
LPUNKNOWN obj; /* object identity (IUnknown) */
OID oid; /* object ID */
@@ -65,51 +64,54 @@
DWORD refs; /* external reference count */
} XOBJECT;
-/* imported interface */
-typedef struct tagIIF {
- struct tagIIF *next;
+/* imported interface proxy */
+struct ifproxy
+{
+ struct list entry;
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 {
- IRemUnknownVtbl *lpVtbl;
- struct tagAPARTMENT *parent;
- struct tagIOBJECT *next;
+/* imported object / proxy manager */
+struct proxy_manager
+{
+ const IInternalUnknownVtbl *lpVtbl;
+ struct apartment *parent;
+ struct list entry;
LPRPCCHANNELBUFFER chan; /* channel to object */
OXID oxid; /* object exported ID */
OID oid; /* object ID */
- IPID ipid; /* first imported interface ID */
- IIF *ifaces; /* imported interfaces */
+ struct list interfaces; /* imported interfaces */
DWORD refs; /* proxy reference count */
-} IOBJECT;
+ CRITICAL_SECTION cs; /* thread safety for this object and
children */
+};
-/* apartment */
-typedef struct tagAPARTMENT {
- struct tagAPARTMENT *next, *prev, *parent;
+/* this needs to become a COM object that implements IRemUnknown */
+struct apartment
+{
+ struct list entry;
+
+ DWORD refs; /* refcount of the apartment */
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 */
+ OID oidc; /* object ID counter, starts at 1, zero is
invalid OID */
HWND win; /* message window */
CRITICAL_SECTION cs; /* thread safety */
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;
+ struct list proxies; /* imported objects */
+ DWORD listenertid; /* id of apartment_listener_thread */
+ struct list stubmgrs; /* stub managers for exported objects */
+};
-extern APARTMENT MTA, *apts;
+typedef struct apartment APARTMENT;
-extern void* StdGlobalInterfaceTable_Construct();
+extern void* StdGlobalInterfaceTable_Construct(void);
extern void StdGlobalInterfaceTable_Destroy(void* self);
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
@@ -118,75 +120,124 @@
extern void* StdGlobalInterfaceTableInstance;
-#define PIPEPREF "\\\\.\\pipe\\"
-#define OLESTUBMGR PIPEPREF"WINE_OLE_StubMgr"
-
/* Standard Marshalling definitions */
typedef struct _wine_marshal_id {
- DWORD processid;
- DWORD objectid; /* unique value corresp. IUnknown of
object */
- IID iid;
+ OXID oxid; /* id of apartment */
+ OID oid; /* id of stub manager */
+ IPID ipid; /* id of interface pointer */
} wine_marshal_id;
inline static BOOL
MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
return
- (mid1->processid == mid2->processid) &&
- (mid1->objectid == mid2->objectid) &&
- IsEqualIID(&(mid1->iid),&(mid2->iid))
+ (mid1->oxid == mid2->oxid) &&
+ (mid1->oid == mid2->oid) &&
+ IsEqualGUID(&(mid1->ipid),&(mid2->ipid))
;
}
-/* compare without interface compare */
-inline static BOOL
-MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id
*mid2) {
- return
- (mid1->processid == mid2->processid) &&
- (mid1->objectid == mid2->objectid)
- ;
-}
+HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt);
+HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
-HRESULT MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer
**stub);
-void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid);
-HRESULT MARSHAL_Disconnect_Proxies();
+/* Thread-safety Annotation Legend:
+ *
+ * RO - The value is read only. It never changes after creation, so
no
+ * locking is required.
+ * LOCK - The value is written to only using Interlocked* functions.
+ * CS - The value is read or written to with a critical section held.
+ * The identifier following "CS" is the specific critical
section that
+ * must be used.
+ */
-HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
+/* an interface stub */
+struct ifstub
+{
+ struct list entry; /* entry in stub_manager->ifstubs
list (CS stub_manager->lock) */
+ IRpcStubBuffer *stubbuffer; /* RO */
+ IID iid; /* RO */
+ IPID ipid; /* RO */
+ IUnknown *iface; /* RO */
+ BOOL table; /* CS stub_manager->lock */
+};
-void STUBMGR_Start();
+/* stub managers hold refs on the object and each interface stub */
+struct stub_manager
+{
+ struct list entry; /* entry in apartment stubmgr list
(CS apt->cs) */
+ struct list ifstubs; /* list of active ifstubs for the
object (CS lock) */
+ CRITICAL_SECTION lock;
+ APARTMENT *apt; /* owning apt (RO) */
+
+ ULONG extrefs; /* number of 'external' references
(LOCK) */
+ ULONG refs; /* internal reference count (CS
apt->cs) */
+ OID oid; /* apartment-scoped unique identifier
(RO) */
+ IUnknown *object; /* the object we are managing the
stub for (RO) */
+ ULONG next_ipid; /* currently unused (LOCK) */
[truncated at 1000 lines; 7593 more skipped]