ole32

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- moved 16 bit functions to a seperate file
- first implementation for free threaded marshaller
- fixed handling of REG_EXPAND_STRING registry values in CoCreateObject
- fixed CoLoad/FreeLibrary functions
- fixed use internal dll-list (used only for functions loading a dll 
internally without returning HMODULE)
Index: wine/dlls/ole32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v
retrieving revision 1.21
diff -d -u -r1.21 Makefile.in
--- wine/dlls/ole32/Makefile.in	11 May 2002 23:06:34 -0000	1.21
+++ wine/dlls/ole32/Makefile.in	2 Aug 2002 21:14:57 -0000
@@ -21,12 +21,14 @@
 	defaulthandler.c \
 	errorinfo.c \
 	filemoniker.c \
+	ftm.c \
 	hglobalstream.c \
 	ifs.c \
 	itemmoniker.c \
 	marshal.c \
 	memlockbytes.c \
 	moniker.c \
+	ole16.c \
 	ole2.c \
 	ole2stubs.c \
 	ole2impl.c \
Index: wine/dlls/ole32/compobj.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj.c,v
retrieving revision 1.63
diff -d -u -r1.63 compobj.c
--- wine/dlls/ole32/compobj.c	29 Jul 2002 23:30:20 -0000	1.63
+++ wine/dlls/ole32/compobj.c	2 Aug 2002 21:15:00 -0000
@@ -45,89 +45,62 @@
 #include "wine/obj_marshal.h"
 #include "wine/obj_storage.h"
 #include "wine/obj_channel.h"
-#include "wine/winbase16.h"
 #include "compobj_private.h"
-#include "ifs.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
 /****************************************************************************
- *  COM External Lock structures and methods declaration
- *
- *  This api provides a linked list to managed external references to
- *  COM objects.
+ * This section defines variables internal to the COM module.
  *
- *  The public interface consists of three calls:
- *      COM_ExternalLockAddRef
- *      COM_ExternalLockRelease
- *      COM_ExternalLockFreeList
+ * TODO: Most of these things will have to be made thread-safe.
  */
+HINSTANCE       COMPOBJ_hInstance32 = 0;
 
-#define EL_END_OF_LIST 0
-#define EL_NOT_FOUND   0
+static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN*  ppUnk);
+static void COM_RevokeAllClasses();
+static void COM_ExternalLockFreeList();
 
-/*
- * Declaration of the static structure that manage the
- * external lock to COM  objects.
+/*****************************************************************************
+ * Appartment 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 COM_ExternalLock     COM_ExternalLock;
-typedef struct COM_ExternalLockList COM_ExternalLockList;
 
-struct COM_ExternalLock
-{
-  IUnknown         *pUnk;     /* IUnknown referenced */
-  ULONG            uRefCount; /* external lock counter to IUnknown object*/
-  COM_ExternalLock *next;     /* Pointer to next element in list */
-};
+typedef struct {
+	unsigned char		threadingModell;	// we use the COINIT flags
+        unsigned long		threadID;
+	long			AppartmentLockCount;
+} OleAppartmentData;
 
-struct COM_ExternalLockList
-{
-  COM_ExternalLock *head;     /* head of list */
-};
+typedef struct {
+	OleAppartmentData 	*AppartmentData;
+} OleThreadData;
 
+/* not jet used
+static CRITICAL_SECTION csAppartmentData = CRITICAL_SECTION_INIT("csAppartmentData");
+*/
 /*
- * Declaration and initialization of the static structure that manages
- * the external lock to COM objects.
+ * the first STA created in a process is the main STA
  */
-static COM_ExternalLockList elList = { EL_END_OF_LIST };
 
-/*
- * Public Interface to the external lock list
- */
-static void COM_ExternalLockFreeList();
-static void COM_ExternalLockAddRef(IUnknown *pUnk);
-static void COM_ExternalLockRelease(IUnknown *pUnk, BOOL bRelAll);
-void COM_ExternalLockDump(); /* testing purposes, not static to avoid warning */
+/* not jet used
+static OleAppartmentData * mainSTA;
+*/
 
 /*
- * Private methods used to managed the linked list
+ * a Process can only have one MTA
  */
-static BOOL COM_ExternalLockInsert(
-  IUnknown *pUnk);
 
-static void COM_ExternalLockDelete(
-  COM_ExternalLock *element);
-
-static COM_ExternalLock* COM_ExternalLockFind(
-  IUnknown *pUnk);
-
-static COM_ExternalLock* COM_ExternalLockLocate(
-  COM_ExternalLock *element,
-  IUnknown         *pUnk);
-
-/****************************************************************************
- * This section defines variables internal to the COM module.
- *
- * TODO: Most of these things will have to be made thread-safe.
- */
-HINSTANCE16     COMPOBJ_hInstance = 0;
-HINSTANCE       COMPOBJ_hInstance32 = 0;
-static int      COMPOBJ_Attach = 0;
+/* not jet used
+static OleAppartmentData * processMTA;
+*/
 
-HTASK16 hETask = 0;
-WORD Table_ETask[62];
 
 /*
  * This lock count counts the number of times CoInitialize is called. It is
@@ -155,30 +128,30 @@
   struct tagRegisteredClass* nextClass;
 } RegisteredClass;
 
-static CRITICAL_SECTION csRegisteredClassList;
+static CRITICAL_SECTION csRegisteredClassList = CRITICAL_SECTION_INIT("csRegisteredClassList");
 static RegisteredClass* firstRegisteredClass = NULL;
 
-/* this open DLL table belongs in a per process table, but my guess is that
- * it shouldn't live in the kernel, so I'll put them out here in DLL
- * space assuming that there is one OLE32 per process.
+/*****************************************************************************
+ * This section contains OpenDllList definitions
+ *
+ * The OpenDllList contains only handles of dll loaded by CoGetClassObject or
+ * other functions what do LoadLibrary _without_ giving back a HMODULE.
+ * Without this list these handles would be freed never.
+ *
+ * FIXME: a DLL what says OK whenn asked for unloading is unloaded in the
+ * next unload-call but not before 600 sec.
  */
+
 typedef struct tagOpenDll {
   HINSTANCE hLibrary;
   struct tagOpenDll *next;
 } OpenDll;
 
-static CRITICAL_SECTION csOpenDllList;
+static CRITICAL_SECTION csOpenDllList = CRITICAL_SECTION_INIT("csOpenDllList");
 static OpenDll *openDllList = NULL; /* linked list of open dlls */
 
-/*****************************************************************************
- * This section contains prototypes to internal methods for this
- * module
- */
-static HRESULT COM_GetRegisteredClassObject(REFCLSID    rclsid,
-					    DWORD       dwClsContext,
-					    LPUNKNOWN*  ppUnk);
-
-static void COM_RevokeAllClasses();
+static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
+static void COMPOBJ_DllList_FreeUnused(int Timeout);
 
 
 /******************************************************************************
@@ -186,67 +159,98 @@
  */
 void COMPOBJ_InitProcess( void )
 {
-    InitializeCriticalSection( &csRegisteredClassList );
-    InitializeCriticalSection( &csOpenDllList );
 }
 
 void COMPOBJ_UninitProcess( void )
 {
-    DeleteCriticalSection( &csRegisteredClassList );
-    DeleteCriticalSection( &csOpenDllList );
 }
 
-/******************************************************************************
- *           CoBuildVersion [COMPOBJ.1]
- *           CoBuildVersion [OLE32.4]
- *
- * RETURNS
- *	Current build version, hiword is majornumber, loword is minornumber
+/*****************************************************************************
+ * This section contains OpenDllList implemantation
  */
-DWORD WINAPI CoBuildVersion(void)
+
+static void COMPOBJ_DLLList_Add(HANDLE hLibrary)
 {
-    TRACE("Returning version %d, build %d.\n", rmm, rup);
-    return (rmm<<16)+rup;
-}
+    OpenDll *ptr;
+    OpenDll *tmp;
 
-LPMALLOC16 currentMalloc16=NULL;
+    TRACE("\n");
 
-/***********************************************************************
- *           CoGetMalloc    [COMPOBJ.4]
- * RETURNS
- *	The current win16 IMalloc
- */
-HRESULT WINAPI CoGetMalloc16(
-	DWORD dwMemContext,	/* [in] unknown */
-	LPMALLOC16 * lpMalloc	/* [out] current win16 malloc interface */
-) {
-    if(!currentMalloc16)
-	currentMalloc16 = IMalloc16_Constructor();
-    *lpMalloc = currentMalloc16;
-    return S_OK;
+    EnterCriticalSection( &csOpenDllList );
+
+    if (openDllList == NULL) {
+        /* empty list -- add first node */
+        openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
+	openDllList->hLibrary=hLibrary;
+	openDllList->next = NULL;
+    } else {
+        /* search for this dll */
+        int found = FALSE;
+        for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) {
+  	    if (ptr->hLibrary == hLibrary) {
+	        found = TRUE;
+		break;
+	    }
+        }
+	if (!found) {
+	    /* dll not found, add it */
+ 	    tmp = openDllList;
+	    openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
+	    openDllList->hLibrary = hLibrary;
+	    openDllList->next = tmp;
+	}
+    }
+
+    LeaveCriticalSection( &csOpenDllList );
 }
 
-/***********************************************************************
- *           CoCreateStandardMalloc [COMPOBJ.71]
- */
-HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
-					  LPMALLOC16 *lpMalloc)
+static void COMPOBJ_DllList_FreeUnused(int Timeout)
 {
-    /* FIXME: docu says we shouldn't return the same allocator as in
-     * CoGetMalloc16 */
-    *lpMalloc = IMalloc16_Constructor();
-    return S_OK;
+    OpenDll *curr, *next, *prev = NULL;
+    typedef HRESULT(*DllCanUnloadNowFunc)(void);
+    DllCanUnloadNowFunc DllCanUnloadNow;
+
+    TRACE("\n");
+
+    EnterCriticalSection( &csOpenDllList );
+
+    for (curr = openDllList; curr != NULL; ) {
+	DllCanUnloadNow = (DllCanUnloadNowFunc) GetProcAddress(curr->hLibrary, "DllCanUnloadNow");
+
+	if ( (DllCanUnloadNow != NULL) && (DllCanUnloadNow() == S_OK) ) {
+	    next = curr->next;
+
+	    TRACE("freeing 0x%08x\n", curr->hLibrary);
+	    FreeLibrary(curr->hLibrary);
+
+	    HeapFree(GetProcessHeap(), 0, curr);
+	    if (curr == openDllList) {
+		openDllList = next;
+	    } else {
+	      prev->next = next;
+	    }
+
+	    curr = next;
+	} else {
+	    prev = curr;
+	    curr = curr->next;
+	}
+    }
+
+    LeaveCriticalSection( &csOpenDllList );
 }
 
 /******************************************************************************
- *		CoInitialize	[COMPOBJ.2]
- * Set the win16 IMalloc used for memory management
+ *           CoBuildVersion [COMPOBJ.1]
+ *           CoBuildVersion [OLE32.4]
+ *
+ * RETURNS
+ *	Current build version, hiword is majornumber, loword is minornumber
  */
-HRESULT WINAPI CoInitialize16(
-	LPVOID lpReserved	/* [in] pointer to win16 malloc interface */
-) {
-    currentMalloc16 = (LPMALLOC16)lpReserved;
-    return S_OK;
+DWORD WINAPI CoBuildVersion(void)
+{
+    TRACE("Returning version %d, build %d.\n", rmm, rup);
+    return (rmm<<16)+rup;
 }
 
 /******************************************************************************
@@ -334,18 +338,6 @@
 }
 
 /***********************************************************************
- *           CoUninitialize   [COMPOBJ.3]
- * Don't know what it does.
- * 3-Nov-98 -- this was originally misspelled, I changed it to what I
- *   believe is the correct spelling
- */
-void WINAPI CoUninitialize16(void)
-{
-  TRACE("()\n");
-  CoFreeAllLibraries();
-}
-
-/***********************************************************************
  *           CoUninitialize   [OLE32.47]
  *
  * This method will release the COM libraries.
@@ -403,35 +395,32 @@
     return S_OK;
 }
 
-/***********************************************************************
- *           IsEqualGUID [COMPOBJ.18]
- *
- * Compares two Unique Identifiers.
+/******************************************************************************
+ *		CoCreateGuid[OLE32.6]
  *
- * RETURNS
- *	TRUE if equal
  */
-BOOL16 WINAPI IsEqualGUID16(
-	GUID* g1,	/* [in] unique id 1 */
-	GUID* g2	/* [in] unique id 2 */
+HRESULT WINAPI CoCreateGuid(
+	GUID *pguid /* [out] points to the GUID to initialize */
 ) {
-    return !memcmp( g1, g2, sizeof(GUID) );
+    return UuidCreate(pguid);
 }
 
 /******************************************************************************
- *		CLSIDFromString	[COMPOBJ.20]
+ *		CLSIDFromString	[OLE32.3]
+ *		IIDFromString   [OLE32.74]
  * Converts a unique identifier from its string representation into
  * the GUID struct.
  *
- * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
+ * UNDOCUMENTED
+ *      If idstr is not a valid CLSID string then it gets treated as a ProgID
  *
  * RETURNS
  *	the converted GUID
  */
-HRESULT WINAPI CLSIDFromString16(
-	LPCOLESTR16 idstr,	/* [in] string representation of guid */
-	CLSID *id		/* [out] GUID converted from string */
-) {
+HRESULT WINAPI __CLSIDFromStringA(
+	LPCSTR idstr,	        /* [in] string representation of guid */
+	CLSID *id)		/* [out] GUID converted from string */
+{
   BYTE *s = (BYTE *) idstr;
   int	i;
   BYTE table[256];
@@ -446,13 +435,11 @@
       if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
           return CO_E_CLASSSTRING;
 
-      for (i=1; i<37; i++)
-      {
+      for (i=1; i<37; i++) {
           if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
           if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
                 ((s[i] >= 'a') && (s[i] <= 'f'))  ||
-                ((s[i] >= 'A') && (s[i] <= 'F')))
-             )
+                ((s[i] >= 'A') && (s[i] <= 'F'))))
               return CO_E_CLASSSTRING;
       }
   }
@@ -490,28 +477,6 @@
   return S_OK;
 }
 
-/******************************************************************************
- *		CoCreateGuid[OLE32.6]
- *
- */
-HRESULT WINAPI CoCreateGuid(
-	GUID *pguid /* [out] points to the GUID to initialize */
-) {
-    return UuidCreate(pguid);
-}
-
-/******************************************************************************
- *		CLSIDFromString	[OLE32.3]
- *		IIDFromString   [OLE32.74]
- * Converts a unique identifier from its string representation into
- * the GUID struct.
- *
- * UNDOCUMENTED
- *      If idstr is not a valid CLSID string then it gets treated as a ProgID
- *
- * RETURNS
- *	the converted GUID
- */
 HRESULT WINAPI CLSIDFromString(
 	LPCOLESTR idstr,	/* [in] string representation of GUID */
 	CLSID *id )		/* [out] GUID represented by above string */
@@ -521,7 +486,9 @@
 
     if (!WideCharToMultiByte( CP_ACP, 0, idstr, -1, xid, sizeof(xid), NULL, NULL ))
         return CO_E_CLASSSTRING;
-    ret = CLSIDFromString16(xid,id);
+	
+
+    ret = __CLSIDFromStringA(xid,id);
     if(ret != S_OK) { /* It appears a ProgID is also valid */
         ret = CLSIDFromProgID(idstr, id);
     }
@@ -570,66 +537,6 @@
   return S_OK;
 }
 
-extern BOOL WINAPI K32WOWCallback16Ex(	DWORD vpfn16, DWORD dwFlags,
-					DWORD cbArgs, LPVOID pArgs,
-					LPDWORD pdwRetCode );
-
-/******************************************************************************
- *		_xmalloc16	[internal]
- * Allocates size bytes from the standard ole16 allocator.
- *
- * RETURNS
- *	the allocated segmented pointer and a HRESULT
- */
-HRESULT
-_xmalloc16(DWORD size, SEGPTR *ptr) {
-  LPMALLOC16 mllc;
-  DWORD args[2];
-
-  if (CoGetMalloc16(0,&mllc))
-    return E_OUTOFMEMORY;
-
-  args[0] = (DWORD)mllc;
-  args[1] = size;
-  /* No need for a Callback entry, we have WOWCallback16Ex which does
-   * everything we need.
-   */
-  if (!K32WOWCallback16Ex(
-      (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL(
-	  (SEGPTR)ICOM_VTBL(((LPMALLOC16)MapSL((SEGPTR)mllc))))
-      )->Alloc,
-      WCB16_CDECL,
-      2*sizeof(DWORD),
-      (LPVOID)args,
-      (LPDWORD)ptr
-  )) {
-      ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
-      return E_FAIL;
-  }
-  return S_OK;
-}
-
-/******************************************************************************
- *		StringFromCLSID	[COMPOBJ.19]
- * Converts a GUID into the respective string representation.
- * The target string is allocated using the OLE IMalloc.
- *
- * RETURNS
- *	the string representation and HRESULT
- */
-
-HRESULT WINAPI StringFromCLSID16(
-  REFCLSID id,		/* [in] the GUID to be converted */
-  LPOLESTR16 *idstr	/* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
-
-) {
-  HRESULT ret;
-
-  ret = _xmalloc16(40,(SEGPTR*)idstr);
-  if (ret != S_OK)
-    return ret;
-  return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
-}
 
 /******************************************************************************
  *		StringFromCLSID	[OLE32.151]
@@ -733,82 +640,6 @@
 }
 
 /******************************************************************************
- * ProgIDFromCLSID [COMPOBJ.62]
- * Converts a class id into the respective Program ID. (By using a registry lookup)
- * RETURNS S_OK on success
- * riid associated with the progid
- */
-HRESULT WINAPI ProgIDFromCLSID16(
-  REFCLSID clsid, /* [in] class id as found in registry */
-  LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
-) {
-  char     strCLSID[50], *buf, *buf2;
-  DWORD    buf2len;
-  HKEY     xhkey;
-  HRESULT  ret = S_OK;
-
-  WINE_StringFromCLSID(clsid, strCLSID);
-
-  buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14);
-  sprintf(buf,"CLSID\\%s\\ProgID", strCLSID);
-  if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
-    ret = REGDB_E_CLASSNOTREG;
-
-  HeapFree(GetProcessHeap(), 0, buf);
-
-  if (ret == S_OK)
-  {
-    buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
-    buf2len = 255;
-    if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
-      ret = REGDB_E_CLASSNOTREG;
-
-    if (ret == S_OK)
-    {
-      ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
-      if (ret != S_OK)
-        return ret;
-      strcpy(MapSL((SEGPTR)*lplpszProgID),buf2);
-      ret = S_OK;
-    }
-    HeapFree(GetProcessHeap(), 0, buf2);
-  }
-  RegCloseKey(xhkey);
-  return ret;
-}
-
-/******************************************************************************
- *		CLSIDFromProgID	[COMPOBJ.61]
- * Converts a program id into the respective GUID. (By using a registry lookup)
- * RETURNS
- *	riid associated with the progid
- */
-HRESULT WINAPI CLSIDFromProgID16(
-	LPCOLESTR16 progid,	/* [in] program id as found in registry */
-	LPCLSID riid		/* [out] associated CLSID */
-) {
-	char	*buf,buf2[80];
-	DWORD	buf2len;
-	HRESULT	err;
-	HKEY	xhkey;
-
-	buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
-	sprintf(buf,"%s\\CLSID",progid);
-	if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
-		HeapFree(GetProcessHeap(),0,buf);
-                return CO_E_CLASSSTRING;
-	}
-	HeapFree(GetProcessHeap(),0,buf);
-	buf2len = sizeof(buf2);
-	if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
-		RegCloseKey(xhkey);
-                return CO_E_CLASSSTRING;
-	}
-	RegCloseKey(xhkey);
-	return CLSIDFromString16(buf2,riid);
-}
-
-/******************************************************************************
  *		CLSIDFromProgID	[OLE32.2]
  * Converts a program id into the respective GUID. (By using a registry lookup)
  * RETURNS
@@ -839,7 +670,7 @@
         return CO_E_CLASSSTRING;
     }
     RegCloseKey(xhkey);
-    return CLSIDFromString16(buf2,riid);
+    return __CLSIDFromStringA(buf2,riid);
 }
 
 
@@ -900,8 +731,7 @@
 
     /* We have the CLSid we want back from the registry as a string, so
        lets convert it into a CLSID structure */
-    if ( (CLSIDFromString16(buf2,pclsid)) != NOERROR)
-    {
+    if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR) {
        return E_INVALIDARG;
     }
 
@@ -952,85 +782,6 @@
         return S_OK;
 }
 
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           LookupETask (COMPOBJ.94)
- */
-HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
-	FIXME("(%p,%p),stub!\n",hTask,p);
-	if ((*hTask = GetCurrentTask()) == hETask) {
-		memcpy(p, Table_ETask, sizeof(Table_ETask));
-	}
-	return 0;
-}
-
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           SetETask (COMPOBJ.95)
- */
-HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
-        FIXME("(%04x,%p),stub!\n",hTask,p);
-	hETask = hTask;
-	return 0;
-}
-
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           CALLOBJECTINWOW (COMPOBJ.201)
- */
-HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
-	FIXME("(%p,%p),stub!\n",p1,p2);
-	return 0;
-}
-
-/******************************************************************************
- *		CoRegisterClassObject	[COMPOBJ.5]
- *
- * Don't know where it registers it ...
- */
-HRESULT WINAPI CoRegisterClassObject16(
-	REFCLSID rclsid,
-	LPUNKNOWN pUnk,
-	DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
-	DWORD flags,        /* [in] REGCLS flags indicating how connections are made */
-	LPDWORD lpdwRegister
-) {
-	char	buf[80];
-
-	WINE_StringFromCLSID(rclsid,buf);
-
-	FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
-		buf,pUnk,dwClsContext,flags,lpdwRegister
-	);
-	return 0;
-}
-
-
-/******************************************************************************
- *      CoRevokeClassObject [COMPOBJ.6]
- *
- */
-HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
-{
-    FIXME("(0x%08lx),stub!\n", dwRegister);
-    return 0;
-}
-
-/******************************************************************************
- *      CoFileTimeToDosDateTime [COMPOBJ.30]
- */
-BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
-{
-    return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
-}
-
-/******************************************************************************
- *      CoDosDateTimeToFileTime [COMPOBJ.31]
- */
-BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
-{
-    return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
-}
 
 /***
  * COM_GetRegisteredClassObject
@@ -1319,6 +1070,32 @@
 }
 
 /***********************************************************************
+ *	compobj_RegReadPath	[internal]
+ *
+ *	Reads a registry value and expands it when nessesary
+ */
+HRESULT compobj_RegReadPath(char * keyname, char * valuename, char * dst, int dstlen)
+{
+	HRESULT hres;
+	HKEY key;
+	DWORD keytype;
+	char src[MAX_PATH];
+	DWORD dwLength = dstlen;
+
+	if((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, keyname, 0, KEY_READ, &key)) == ERROR_SUCCESS) {
+          if( (hres = RegQueryValueExA(key, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) {
+            if (keytype == REG_EXPAND_SZ) {
+              if (dstlen <= ExpandEnvironmentStringsA(src, dst, dstlen)) hres = ERROR_MORE_DATA;
+            } else {
+              strncpy(dst, src, dstlen);
+            }
+	  }
+          RegCloseKey (key);
+	}
+	return hres;
+}
+
+/***********************************************************************
  *           CoGetClassObject [COMPOBJ.7]
  *           CoGetClassObject [OLE32.16]
  *
@@ -1334,19 +1111,13 @@
     LPUNKNOWN	regClassObject;
     HRESULT	hres = E_UNEXPECTED;
     char	xclsid[80];
-    WCHAR ProviderName[MAX_PATH+1];
-    DWORD ProviderNameLen = sizeof(ProviderName);
     HINSTANCE hLibrary;
-    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid,
-			     REFIID iid, LPVOID *ppv);
+    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
     DllGetClassObjectFunc DllGetClassObject;
 
     WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
 
-    TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",
-	debugstr_guid(rclsid),
-	debugstr_guid(iid)
-    );
+    TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
 
     if (pServerInfo) {
 	FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
@@ -1374,41 +1145,35 @@
       return hres;
     }
 
-    if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) {
-        HKEY key;
-	char buf[200];
+    /* first try: in-process */
+    if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) {
+	char keyname[MAX_PATH];
+	char dllpath[MAX_PATH+1];
 
-	memset(ProviderName,0,sizeof(ProviderName));
-	sprintf(buf,"CLSID\\%s\\InprocServer32",xclsid);
-        if (((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key)) != ERROR_SUCCESS) ||
-            ((hres = RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)ProviderName,&ProviderNameLen)),
-             RegCloseKey (key),
-             hres != ERROR_SUCCESS))
-        {
+	sprintf(keyname,"CLSID\\%s\\InprocServer32",xclsid);
+	
+	if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) {
+	    /* failure: CLSID is not found in registry */
+	    WARN("class %s not registred\n", xclsid);
             hres = REGDB_E_CLASSNOTREG;
-        }
-        /* Don't ask me.  MSDN says that CoGetClassObject does NOT call CoLoadLibrary */
-        else if ((hLibrary = CoLoadLibrary(ProviderName, TRUE)) == 0)
-        {
-	    FIXME("couldn't load InprocServer32 dll %s\n", debugstr_w(ProviderName));
-	    hres = E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
-	}
-	else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
-        {
-	    /* not sure if this should be called here CoFreeLibrary(hLibrary);*/
-	    FIXME("couldn't find function DllGetClassObject in %s\n", debugstr_w(ProviderName));
-	    hres = E_ACCESSDENIED;
-	}
-        else
-        {
-	    /* Ask the DLL for its class object. (there was a note here about
-	     * class factories but this is good.
-	     */
+	} else {
+	  if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
+	    /* failure: DLL could not be loaded */
+	    ERR("couldn't load InprocServer32 dll %s\n", dllpath);
+	    hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+	  } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
+	    /* failure: the dll did not export DllGetClassObject */
+	    ERR("couldn't find function DllGetClassObject in %s\n", dllpath);
+	    FreeLibrary( hLibrary );
+	    hres = CO_E_DLLNOTFOUND;
+	  } else {
+	    /* OK: get the ClassObject */
+	    COMPOBJ_DLLList_Add( hLibrary );
 	    return DllGetClassObject(rclsid, iid, ppv);
-        }
+	  }
+	}
     }
 
-
     /* Next try out of process */
     if (CLSCTX_LOCAL_SERVER & dwClsContext)
     {
@@ -1525,17 +1290,6 @@
 
     return MK_E_INVALIDEXTENSION;
 }
-/******************************************************************************
- *		CoRegisterMessageFilter	[COMPOBJ.27]
- */
-HRESULT WINAPI CoRegisterMessageFilter16(
-	LPMESSAGEFILTER lpMessageFilter,
-	LPMESSAGEFILTER *lplpMessageFilter
-) {
-	FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
-	return 0;
-}
-
 /***********************************************************************
  *           CoCreateInstance [COMPOBJ.13]
  *           CoCreateInstance [OLE32.7]
@@ -1662,93 +1416,47 @@
 }
 
 /***********************************************************************
- *           CoFreeLibrary [OLE32.13]
+ *           CoLoadLibrary (OLE32.30)
  */
-void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
+HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
 {
-    OpenDll *ptr, *prev;
-    OpenDll *tmp;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    /* lookup library in linked list */
-    prev = NULL;
-    for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
-	if (ptr->hLibrary == hLibrary) {
-	    break;
-	}
-	prev = ptr;
-    }
+    TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
 
-    if (ptr == NULL) {
-	/* shouldn't happen if user passed in a valid hLibrary */
-	goto end;
-    }
-    /* assert: ptr points to the library entry to free */
+    return LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
 
-    /* free library and remove node from list */
-    FreeLibrary(hLibrary);
-    if (ptr == openDllList) {
-	tmp = openDllList->next;
-	HeapFree(GetProcessHeap(), 0, openDllList);
-	openDllList = tmp;
-    } else {
-	tmp = ptr->next;
-	HeapFree(GetProcessHeap(), 0, ptr);
-	prev->next = tmp;
-    }
-end:
-    LeaveCriticalSection( &csOpenDllList );
+/***********************************************************************
+ *           CoFreeLibrary [OLE32.13]
+ *
+ * NOTES: don't belive the docu
+ */
+void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
+{
+	FreeLibrary(hLibrary);
 }
 
 
 /***********************************************************************
  *           CoFreeAllLibraries [OLE32.12]
+ *
+ * NOTES: don't belive the docu
  */
 void WINAPI CoFreeAllLibraries(void)
 {
-    OpenDll *ptr, *tmp;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    for (ptr = openDllList; ptr != NULL; ) {
-	tmp=ptr->next;
-	CoFreeLibrary(ptr->hLibrary);
-	ptr = tmp;
-    }
-
-    LeaveCriticalSection( &csOpenDllList );
+        /* NOP */
 }
 
 
-
 /***********************************************************************
  *           CoFreeUnusedLibraries [COMPOBJ.17]
  *           CoFreeUnusedLibraries [OLE32.14]
+ *
+ * FIXME: Calls to CoFreeUnusedLibraries from any thread always route
+ * through the main apartment's thread to call DllCanUnloadNow
  */
 void WINAPI CoFreeUnusedLibraries(void)
 {
-    OpenDll *ptr, *tmp;
-    typedef HRESULT(*DllCanUnloadNowFunc)(void);
-    DllCanUnloadNowFunc DllCanUnloadNow;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    for (ptr = openDllList; ptr != NULL; ) {
-	DllCanUnloadNow = (DllCanUnloadNowFunc)
-	    GetProcAddress(ptr->hLibrary, "DllCanUnloadNow");
-
-	if ( (DllCanUnloadNow != NULL) &&
-	     (DllCanUnloadNow() == S_OK) ) {
-	    tmp=ptr->next;
-	    CoFreeLibrary(ptr->hLibrary);
-	    ptr = tmp;
-	} else {
-	    ptr=ptr->next;
-	}
-    }
-
-    LeaveCriticalSection( &csOpenDllList );
+    COMPOBJ_DllList_FreeUnused(0);
 }
 
 /***********************************************************************
@@ -1767,157 +1475,149 @@
 /***********************************************************************
  *           CoLoadLibrary (OLE32.30)
  */
-HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
+static void COM_RevokeAllClasses()
 {
-    HINSTANCE hLibrary;
-    OpenDll *ptr;
-    OpenDll *tmp;
+  EnterCriticalSection( &csRegisteredClassList );
 
-    TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
+  while (firstRegisteredClass!=0)
+  {
+    CoRevokeClassObject(firstRegisteredClass->dwCookie);
+  }
 
-    hLibrary = LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+  LeaveCriticalSection( &csRegisteredClassList );
+}
 
-    if (!bAutoFree)
-	return hLibrary;
+/****************************************************************************
+ *  COM External Lock methods implementation
+ *
+ *  This api provides a linked list to managed external references to
+ *  COM objects.
+ *
+ *  The public interface consists of three calls:
+ *      COM_ExternalLockAddRef
+ *      COM_ExternalLockRelease
+ *      COM_ExternalLockFreeList
+ */
 
-    EnterCriticalSection( &csOpenDllList );
+#define EL_END_OF_LIST 0
+#define EL_NOT_FOUND   0
 
-    if (openDllList == NULL) {
-        /* empty list -- add first node */
-        openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
-	openDllList->hLibrary=hLibrary;
-	openDllList->next = NULL;
-    } else {
-        /* search for this dll */
-        int found = FALSE;
-        for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) {
-  	    if (ptr->hLibrary == hLibrary) {
-	        found = TRUE;
-		break;
-	    }
-        }
-	if (!found) {
-	    /* dll not found, add it */
- 	    tmp = openDllList;
-	    openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
-	    openDllList->hLibrary = hLibrary;
-	    openDllList->next = tmp;
-	}
-    }
+/*
+ * Declaration of the static structure that manage the
+ * external lock to COM  objects.
+ */
+typedef struct COM_ExternalLock     COM_ExternalLock;
+typedef struct COM_ExternalLockList COM_ExternalLockList;
 
-    LeaveCriticalSection( &csOpenDllList );
+struct COM_ExternalLock
+{
+  IUnknown         *pUnk;     /* IUnknown referenced */
+  ULONG            uRefCount; /* external lock counter to IUnknown object*/
+  COM_ExternalLock *next;     /* Pointer to next element in list */
+};
 
-    return hLibrary;
-}
+struct COM_ExternalLockList
+{
+  COM_ExternalLock *head;     /* head of list */
+};
 
-/***********************************************************************
- *           CoInitializeWOW (OLE32.27)
+/*
+ * Declaration and initialization of the static structure that manages
+ * the external lock to COM objects.
  */
-HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
-    FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
-    return 0;
-}
+static COM_ExternalLockList elList = { EL_END_OF_LIST };
 
-/******************************************************************************
- *		CoLockObjectExternal	[COMPOBJ.63]
+/*
+ * Private methods used to managed the linked list
  */
-HRESULT WINAPI CoLockObjectExternal16(
-    LPUNKNOWN pUnk,		/* [in] object to be locked */
-    BOOL16 fLock,		/* [in] do lock */
-    BOOL16 fLastUnlockReleases	/* [in] ? */
-) {
-    FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
-    return S_OK;
-}
 
-/******************************************************************************
- *		CoLockObjectExternal	[OLE32.31]
+
+static COM_ExternalLock* COM_ExternalLockLocate(
+  COM_ExternalLock *element,
+  IUnknown         *pUnk);
+
+/****************************************************************************
+ * Internal - Insert a new IUnknown* to the linked list
  */
-HRESULT WINAPI CoLockObjectExternal(
-    LPUNKNOWN pUnk,		/* [in] object to be locked */
-    BOOL fLock,		/* [in] do lock */
-    BOOL fLastUnlockReleases) /* [in] unlock all */
+static BOOL COM_ExternalLockInsert(
+  IUnknown *pUnk)
 {
+  COM_ExternalLock *newLock      = NULL;
+  COM_ExternalLock *previousHead = NULL;
 
-  if (fLock)
-  {
-    /*
-     * Increment the external lock coutner, COM_ExternalLockAddRef also
-     * increment the object's internal lock counter.
-     */
-    COM_ExternalLockAddRef( pUnk);
-  }
-  else
-  {
-    /*
-     * Decrement the external lock coutner, COM_ExternalLockRelease also
-     * decrement the object's internal lock counter.
-     */
-    COM_ExternalLockRelease( pUnk, fLastUnlockReleases);
-  }
+  /*
+   * Allocate space for the new storage object
+   */
+  newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
 
-    return S_OK;
-}
+  if (newLock!=NULL) {
+    if ( elList.head == EL_END_OF_LIST ) {
+      elList.head = newLock;    /* The list is empty */
+    } else {
+      /* insert does it at the head */
+      previousHead  = elList.head;
+      elList.head = newLock;
+    }
 
-/***********************************************************************
- *           CoGetState [COMPOBJ.115]
- */
-HRESULT WINAPI CoGetState16(LPDWORD state)
-{
-    FIXME("(%p),stub!\n", state);
-    *state = 0;
-    return S_OK;
-}
-/***********************************************************************
- *           CoSetState [OLE32.42]
- */
-HRESULT WINAPI CoSetState(LPDWORD state)
-{
-    FIXME("(%p),stub!\n", state);
-    if (state) *state = 0;
-    return S_OK;
-}
-/***********************************************************************
- *          CoCreateFreeThreadedMarshaler [OLE32.5]
- */
-HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal)
-{
-   FIXME ("(%p %p): stub\n", punkOuter, ppunkMarshal);
+    /* Set new list item data member */
+    newLock->pUnk      = pUnk;
+    newLock->uRefCount = 1;
+    newLock->next      = previousHead;
 
-   return S_OK;
+    return TRUE;
+  }
+  return FALSE;
 }
 
-/***
- * COM_RevokeAllClasses
- *
- * This method is called when the COM libraries are uninitialized to
- * release all the references to the class objects registered with
- * the library
+/****************************************************************************
+ * Internal - Method that removes an item from the linked list.
  */
-static void COM_RevokeAllClasses()
+static void COM_ExternalLockDelete(
+  COM_ExternalLock *itemList)
 {
-  EnterCriticalSection( &csRegisteredClassList );
+  COM_ExternalLock *current = elList.head;
 
-  while (firstRegisteredClass!=0)
-  {
-    CoRevokeClassObject(firstRegisteredClass->dwCookie);
-  }
+  if ( current == itemList ) {
+    /* this section handles the deletion of the first node */
+    elList.head = itemList->next;
+    HeapFree( GetProcessHeap(), 0, itemList);
+  } else {
+    do {
+      if ( current->next == itemList ){   /* We found the item to free  */
+        current->next = itemList->next;  /* readjust the list pointers */
+        HeapFree( GetProcessHeap(), 0, itemList);
+        break;
+      }
 
-  LeaveCriticalSection( &csRegisteredClassList );
+      /* Skip to the next item */
+      current = current->next;
+
+    } while ( current != EL_END_OF_LIST );
+  }
 }
 
 /****************************************************************************
- *  COM External Lock methods implementation
+ * Internal - Recursivity agent for IUnknownExternalLockList_Find
+ *
+ * NOTES: how long can the list be ?? (recursive!!!)
  */
+static COM_ExternalLock* COM_ExternalLockLocate( COM_ExternalLock *element, IUnknown *pUnk)
+{
+  if ( element == EL_END_OF_LIST )
+    return EL_NOT_FOUND;
+  else if ( element->pUnk == pUnk )    /* We found it */
+    return element;
+  else                                 /* Not the right guy, keep on looking */
+    return COM_ExternalLockLocate( element->next, pUnk);
+}
 
 /****************************************************************************
  * Public - Method that increments the count for a IUnknown* in the linked
  * list.  The item is inserted if not already in the list.
  */
-static void COM_ExternalLockAddRef(
-  IUnknown *pUnk)
+static void COM_ExternalLockAddRef(IUnknown *pUnk)
 {
-  COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);
+  COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk);
 
   /*
    * Add an external lock to the object. If it was already externally
@@ -1944,17 +1644,14 @@
   IUnknown *pUnk,
   BOOL   bRelAll)
 {
-  COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);
+  COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk);
 
-  if ( externalLock != EL_NOT_FOUND )
-  {
-    do
-    {
+  if ( externalLock != EL_NOT_FOUND ) {
+    do {
       externalLock->uRefCount--;  /* release external locks      */
       IUnknown_Release(pUnk);     /* release local locks as well */
 
-      if ( bRelAll == FALSE )
-        break;  /* perform single release */
+      if ( bRelAll == FALSE ) break;  /* perform single release */
 
     } while ( externalLock->uRefCount > 0 );
 
@@ -1970,10 +1667,8 @@
   COM_ExternalLock *head;
 
   head = elList.head;                 /* grab it by the head             */
-  while ( head != EL_END_OF_LIST )
-  {
+  while ( head != EL_END_OF_LIST ) {
     COM_ExternalLockDelete(head);     /* get rid of the head stuff       */
-
     head = elList.head;               /* get the new head...             */
   }
 }
@@ -1987,144 +1682,98 @@
 
   DPRINTF("\nExternal lock list contains:\n");
 
-  while ( current != EL_END_OF_LIST )
-  {
-      DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount);
+  while ( current != EL_END_OF_LIST ) {
+    DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount);
 
     /* Skip to the next item */
     current = current->next;
   }
-
-}
-
-/****************************************************************************
- * Internal - Find a IUnknown* in the linked list
- */
-static COM_ExternalLock* COM_ExternalLockFind(
-  IUnknown *pUnk)
-{
-  return COM_ExternalLockLocate(elList.head, pUnk);
 }
 
-/****************************************************************************
- * Internal - Recursivity agent for IUnknownExternalLockList_Find
+/******************************************************************************
+ *		CoLockObjectExternal	[OLE32.31]
  */
-static COM_ExternalLock* COM_ExternalLockLocate(
-  COM_ExternalLock *element,
-  IUnknown         *pUnk)
+HRESULT WINAPI CoLockObjectExternal(
+    LPUNKNOWN pUnk,		/* [in] object to be locked */
+    BOOL fLock,		/* [in] do lock */
+    BOOL fLastUnlockReleases) /* [in] unlock all */
 {
-  if ( element == EL_END_OF_LIST )
-    return EL_NOT_FOUND;
 
-  else if ( element->pUnk == pUnk )    /* We found it */
-    return element;
+	if (fLock) {
+            /*
+             * Increment the external lock coutner, COM_ExternalLockAddRef also
+             * increment the object's internal lock counter.
+             */
+	    COM_ExternalLockAddRef( pUnk);
+        } else {
+            /*
+             * Decrement the external lock coutner, COM_ExternalLockRelease also
+             * decrement the object's internal lock counter.
+             */
+            COM_ExternalLockRelease( pUnk, fLastUnlockReleases);
+        }
 
-  else                                 /* Not the right guy, keep on looking */
-    return COM_ExternalLockLocate( element->next, pUnk);
+        return S_OK;
 }
 
-/****************************************************************************
- * Internal - Insert a new IUnknown* to the linked list
+/***********************************************************************
+ *           CoInitializeWOW (OLE32.27)
  */
-static BOOL COM_ExternalLockInsert(
-  IUnknown *pUnk)
-{
-  COM_ExternalLock *newLock      = NULL;
-  COM_ExternalLock *previousHead = NULL;
-
-  /*
-   * Allocate space for the new storage object
-   */
-  newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
-
-  if (newLock!=NULL)
-  {
-    if ( elList.head == EL_END_OF_LIST )
-    {
-      elList.head = newLock;    /* The list is empty */
-    }
-    else
-    {
-      /*
-       * insert does it at the head
-       */
-      previousHead  = elList.head;
-      elList.head = newLock;
-    }
-
-    /*
-     * Set new list item data member
-     */
-    newLock->pUnk      = pUnk;
-    newLock->uRefCount = 1;
-    newLock->next      = previousHead;
-
-    return TRUE;
-  }
-  else
-    return FALSE;
+HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
+    FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
+    return 0;
 }
 
-/****************************************************************************
- * Internal - Method that removes an item from the linked list.
+static IUnknown * pUnkState = 0; /* FIXME: thread local */
+static int nStatCounter = 0;	 /* global */
+static HMODULE hOleAut32 = 0;	 /* global */
+
+/***********************************************************************
+ *           CoGetState [OLE32.@]
+ *
+ * NOTES: might be incomplete
  */
-static void COM_ExternalLockDelete(
-  COM_ExternalLock *itemList)
+HRESULT WINAPI CoGetState(IUnknown ** ppv)
 {
-  COM_ExternalLock *current = elList.head;
-
-  if ( current == itemList )
-  {
-    /*
-     * this section handles the deletion of the first node
-     */
-    elList.head = itemList->next;
-    HeapFree( GetProcessHeap(), 0, itemList);
-  }
-  else
-  {
-    do
-    {
-      if ( current->next == itemList )   /* We found the item to free  */
-      {
-        current->next = itemList->next;  /* readjust the list pointers */
-
-        HeapFree( GetProcessHeap(), 0, itemList);
-        break;
-      }
-
-      /* Skip to the next item */
-      current = current->next;
+	FIXME("\n");
 
-    } while ( current != EL_END_OF_LIST );
-  }
+	if(pUnkState) {
+	    IUnknown_AddRef(pUnkState);
+	    *ppv = pUnkState;
+	    FIXME("-- %p\n", *ppv);
+	    return S_OK;
+	}
+	*ppv = NULL;
+	return E_FAIL;
+	
 }
 
 /***********************************************************************
- *      DllEntryPoint                   [COMPOBJ.116]
- *
- *    Initialization code for the COMPOBJ DLL
+ *           CoSetState [OLE32.42]
  *
- * RETURNS:
+ * NOTES: FIXME: protect this with a crst
  */
-BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
+HRESULT WINAPI CoSetState(IUnknown * pv)
 {
-        TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize,
- res1, res2);
-        switch(Reason)
-        {
-        case DLL_PROCESS_ATTACH:
-                if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
-                break;
+	FIXME("(%p),stub!\n", pv);
 
-        case DLL_PROCESS_DETACH:
-                if(!--COMPOBJ_Attach)
-                        COMPOBJ_hInstance = 0;
-                break;
-        }
-        return TRUE;
+	if (pv) { 
+	    IUnknown_AddRef(pv);
+	    nStatCounter++;
+	    if (nStatCounter == 1) LoadLibraryA("OLEAUT32.DLL");
+	}
+
+	if (pUnkState) {
+	    TRACE("-- release %p now\n", pUnkState);
+	    IUnknown_Release(pUnkState);
+	    nStatCounter--;
+	    if (!nStatCounter) FreeLibrary(hOleAut32);
+	}
+	pUnkState = pv;
+	return S_OK;
 }
 
+
 /******************************************************************************
  *              OleGetAutoConvert        [OLE32.104]
  */
@@ -2153,9 +1802,8 @@
     MultiByteToWideChar( CP_ACP, 0, buf, -1, wbuf, sizeof(wbuf)/sizeof(WCHAR) );
     CLSIDFromString(wbuf,pClsidNew);
 done:
-  if (hkey) RegCloseKey(hkey);
-
-  return res;
+    if (hkey) RegCloseKey(hkey);
+    return res;
 }
 
 /******************************************************************************
Index: wine/dlls/ole32/compobj_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj_private.h,v
retrieving revision 1.4
diff -d -u -r1.4 compobj_private.h
--- wine/dlls/ole32/compobj_private.h	9 Mar 2002 23:39:09 -0000	1.4
+++ wine/dlls/ole32/compobj_private.h	2 Aug 2002 21:15:00 -0000
@@ -116,4 +116,6 @@
 /* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
 int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
 
+HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
+
 #endif /* __WINE_OLE_COMPOBJ_H */
Index: wine/dlls/ole32/ifs.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ifs.c,v
retrieving revision 1.22
diff -d -u -r1.22 ifs.c
--- wine/dlls/ole32/ifs.c	29 Jul 2002 23:30:20 -0000	1.22
+++ wine/dlls/ole32/ifs.c	2 Aug 2002 21:15:01 -0000
@@ -27,155 +27,14 @@
 
 #include "ole2.h"
 #include "windef.h"
+#include "winbase.h"
 #include "winerror.h"
 
 #include "wine/obj_base.h"
-#include "wine/winbase16.h"
-#include "ifs.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-/* --- IMalloc16 implementation */
-
-
-typedef struct
-{
-        /* IUnknown fields */
-        ICOM_VFIELD(IMalloc16);
-        DWORD                   ref;
-        /* IMalloc16 fields */
-} IMalloc16Impl;
-
-/******************************************************************************
- *		IMalloc16_QueryInterface	[COMPOBJ.500]
- */
-HRESULT WINAPI IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
-        ICOM_THIS(IMalloc16Impl,iface);
-
-	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
-	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
-		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
-	) {
-		*obj = This;
-		return 0;
-	}
-	return OLE_E_ENUM_NOMORE;
-}
-
-/******************************************************************************
- *		IMalloc16_AddRef	[COMPOBJ.501]
- */
-ULONG WINAPI IMalloc16_fnAddRef(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->AddRef()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- *		IMalloc16_Release	[COMPOBJ.502]
- */
-ULONG WINAPI IMalloc16_fnRelease(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->Release()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- * IMalloc16_Alloc [COMPOBJ.503]
- */
-SEGPTR WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->Alloc(%ld)\n",This,cb);
-        return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
-}
-
-/******************************************************************************
- * IMalloc16_Realloc [COMPOBJ.504]
- */
-SEGPTR WINAPI IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
-{
-    SEGPTR ret;
-    ICOM_THIS(IMalloc16Impl,iface);
-    TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
-    ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
-    UnMapLS(pv);
-    return ret;
-}
-
-/******************************************************************************
- * IMalloc16_Free [COMPOBJ.505]
- */
-VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
-{
-    void *ptr = MapSL(pv);
-    ICOM_THIS(IMalloc16Impl,iface);
-    TRACE("(%p)->Free(%08lx)\n",This,pv);
-    UnMapLS(pv);
-    HeapFree( GetProcessHeap(), 0, ptr );
-}
-
-/******************************************************************************
- * IMalloc16_GetSize [COMPOBJ.506]
- */
-DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,SEGPTR pv)
-{
-	ICOM_CTHIS(IMalloc16Impl,iface);
-        TRACE("(%p)->GetSize(%08lx)\n",This,pv);
-        return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
-}
-
-/******************************************************************************
- * IMalloc16_DidAlloc [COMPOBJ.507]
- */
-INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
-        ICOM_CTHIS(IMalloc16,iface);
-	TRACE("(%p)->DidAlloc(%p)\n",This,pv);
-	return (INT16)-1;
-}
-
-/******************************************************************************
- * IMalloc16_HeapMinimize [COMPOBJ.508]
- */
-LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->HeapMinimize()\n",This);
-	return NULL;
-}
-
-/******************************************************************************
- * IMalloc16_Constructor [VTABLE]
- */
-LPMALLOC16
-IMalloc16_Constructor()
-{
-    static ICOM_VTABLE(IMalloc16) vt16;
-    static SEGPTR msegvt16;
-    IMalloc16Impl* This;
-    HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
-
-    This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
-    if (!msegvt16)
-    {
-#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
-        VTENT(QueryInterface);
-        VTENT(AddRef);
-        VTENT(Release);
-        VTENT(Alloc);
-        VTENT(Realloc);
-        VTENT(Free);
-        VTENT(GetSize);
-        VTENT(DidAlloc);
-        VTENT(HeapMinimize);
-#undef VTENT
-        msegvt16 = MapLS( &vt16 );
-    }
-    ICOM_VTBL(This) = (ICOM_VTABLE(IMalloc16)*)msegvt16;
-    This->ref = 1;
-    return (LPMALLOC16)MapLS( This );
-}
-
 
 /******************************************************************************
  *	IMalloc32 implementation
Index: wine/include/wtypes.h
===================================================================
RCS file: /home/wine/wine/include/wtypes.h,v
retrieving revision 1.33
diff -d -u -r1.33 wtypes.h
--- wine/include/wtypes.h	25 Jun 2002 03:03:19 -0000	1.33
+++ wine/include/wtypes.h	2 Aug 2002 21:16:06 -0000
@@ -123,7 +123,14 @@
     CLSCTX_INPROC_HANDLER16  = 0x20,
     CLSCTX_INPROC_SERVERX86  = 0x40,
     CLSCTX_INPROC_HANDLERX86 = 0x80,
-    CLSCTX_ESERVER_HANDLER   = 0x100
+    CLSCTX_ESERVER_HANDLER   = 0x100,
+    CLSCTX_NO_CODE_DOWNLOAD  = 0x400,
+    CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
+    CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
+    CLSCTX_NO_FAILURE_LOG   = 0x4000,
+    CLSCTX_DISABLE_AAA      = 0x8000,
+    CLSCTX_ENABLE_AAA       = 0x10000,
+    CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000
 } CLSCTX;
 
 #define CLSCTX_INPROC           (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER)
@@ -143,7 +150,8 @@
     MSHCTX_LOCAL            = 0,
     MSHCTX_NOSHAREDMEM      = 1,
     MSHCTX_DIFFERENTMACHINE = 2,
-    MSHCTX_INPROC           = 3
+    MSHCTX_INPROC           = 3,
+    MSHCTX_CROSSCTX         = 4
 } MSHCTX;
 
 typedef unsigned short VARTYPE;
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/ole32/ftm.c	Tue Jul 30 17:28:26 2002
@@ -0,0 +1,241 @@
+/*
+ *	free threaded marshaler
+ *
+ *  Copyright 2002  Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "winbase.h"
+
+#include "wine/obj_base.h"
+#include "wine/obj_storage.h"
+#include "wine/obj_marshal.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+typedef struct _FTMarshalImpl {
+	ICOM_VFIELD (IUnknown);
+	DWORD ref;
+	ICOM_VTABLE (IMarshal) * lpvtblFTM;
+
+	IUnknown *pUnkOuter;
+} FTMarshalImpl;
+
+#define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
+#define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
+
+#define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM)))
+#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
+
+/* inner IUnknown to handle aggregation */
+HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    *ppv = NULL;
+
+    if (IsEqualIID (&IID_IUnknown, riid))
+	*ppv = _IFTMUnknown_ (This);
+    else if (IsEqualIID (&IID_IMarshal, riid))
+	*ppv = _IFTMarshal_ (This);
+    else {
+	FIXME ("No interface for %s.\n", debugstr_guid (riid));
+	return E_NOINTERFACE;
+    }
+    IUnknown_AddRef ((IUnknown *) * ppv);
+    return S_OK;
+}
+
+ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return InterlockedIncrement (&This->ref);
+}
+
+ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    if (InterlockedDecrement (&This->ref))
+	return This->ref;
+    HeapFree (GetProcessHeap (), 0, This);
+    return 0;
+}
+
+static ICOM_VTABLE (IUnknown) iunkvt =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IiFTMUnknown_fnQueryInterface,
+	IiFTMUnknown_fnAddRef,
+	IiFTMUnknown_fnRelease
+};
+
+HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
+    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
+}
+
+ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
+						void *pvDestContext, DWORD mshlflags, CLSID * pCid)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
+						void *pvDestContext, DWORD mshlflags, DWORD * pSize)
+{
+
+    IMarshal *pMarshal = NULL;
+    HRESULT hres;
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    FIXME ("(), stub!\n");
+
+    /* if the marshaling happends inside the same process the interface pointer is
+       copied between the appartments */
+    if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
+	*pSize = sizeof (This);
+	return S_OK;
+    }
+
+    /* use the standard marshaler to handle all other cases */
+    CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
+    hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
+    IMarshal_Release (pMarshal);
+    return hres;
+
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
+					       DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
+{
+
+    IMarshal *pMarshal = NULL;
+    HRESULT hres;
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    FIXME ("(), stub!\n");
+
+    /* if the marshaling happends inside the same process the interface pointer is
+       copied between the appartments */
+    if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
+	return IStream_Write (pStm, This, sizeof (This), 0);
+    }
+
+    /* use the standard marshaler to handle all other cases */
+    CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
+    hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
+    IMarshal_Release (pMarshal);
+    return hres;
+}
+
+HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+ICOM_VTABLE (IMarshal) ftmvtbl =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	FTMarshalImpl_QueryInterface,
+	FTMarshalImpl_AddRef,
+	FTMarshalImpl_Release,
+	FTMarshalImpl_GetUnmarshalClass,
+	FTMarshalImpl_GetMarshalSizeMax,
+	FTMarshalImpl_MarshalInterface,
+	FTMarshalImpl_UnmarshalInterface,
+	FTMarshalImpl_ReleaseMarshalData,
+	FTMarshalImpl_DisconnectObject
+};
+
+/***********************************************************************
+ *          CoCreateFreeThreadedMarshaler [OLE32.5]
+ *
+ */
+HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
+{
+
+    FTMarshalImpl *ftm;
+
+    TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
+
+    ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
+    if (!ftm)
+	return E_OUTOFMEMORY;
+
+    ICOM_VTBL (ftm) = &iunkvt;
+    ftm->lpvtblFTM = &ftmvtbl;
+    ftm->ref = 1;
+    ftm->pUnkOuter = punkOuter;
+
+    *ppunkMarshal = _IFTMUnknown_ (ftm);
+    return S_OK;
+}
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/ole32/ole16.c	Fri Aug  2 18:50:42 2002
@@ -0,0 +1,552 @@
+/*
+ *	16 bit ole functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "windef.h"
+#include "objbase.h"
+#include "ole2.h"
+#include "ole2ver.h"
+#include "rpc.h"
+#include "winerror.h"
+#include "winreg.h"
+#include "wownt32.h"
+#include "wtypes.h"
+#include "wine/unicode.h"
+#include "wine/obj_base.h"
+#include "wine/obj_clientserver.h"
+#include "wine/obj_misc.h"
+#include "wine/obj_marshal.h"
+#include "wine/obj_storage.h"
+#include "wine/obj_channel.h"
+#include "wine/winbase16.h"
+#include "compobj_private.h"
+#include "ifs.h"
+#include "wine/winbase16.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+HINSTANCE16     COMPOBJ_hInstance = 0;
+static int      COMPOBJ_Attach = 0;
+
+HTASK16 hETask = 0;
+WORD Table_ETask[62];
+
+LPMALLOC16 currentMalloc16=NULL;
+
+/* --- IMalloc16 implementation */
+
+
+typedef struct
+{
+        /* IUnknown fields */
+        ICOM_VFIELD(IMalloc16);
+        DWORD                   ref;
+        /* IMalloc16 fields */
+} IMalloc16Impl;
+
+/******************************************************************************
+ *		IMalloc16_QueryInterface	[COMPOBJ.500]
+ */
+HRESULT WINAPI IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
+        ICOM_THIS(IMalloc16Impl,iface);
+
+	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
+	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
+		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
+	) {
+		*obj = This;
+		return 0;
+	}
+	return OLE_E_ENUM_NOMORE;
+}
+
+/******************************************************************************
+ *		IMalloc16_AddRef	[COMPOBJ.501]
+ */
+ULONG WINAPI IMalloc16_fnAddRef(IMalloc16* iface) {
+        ICOM_THIS(IMalloc16Impl,iface);
+	TRACE("(%p)->AddRef()\n",This);
+	return 1; /* cannot be freed */
+}
+
+/******************************************************************************
+ *		IMalloc16_Release	[COMPOBJ.502]
+ */
+ULONG WINAPI IMalloc16_fnRelease(IMalloc16* iface) {
+        ICOM_THIS(IMalloc16Impl,iface);
+	TRACE("(%p)->Release()\n",This);
+	return 1; /* cannot be freed */
+}
+
+/******************************************************************************
+ * IMalloc16_Alloc [COMPOBJ.503]
+ */
+SEGPTR WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
+        ICOM_THIS(IMalloc16Impl,iface);
+	TRACE("(%p)->Alloc(%ld)\n",This,cb);
+        return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
+}
+
+/******************************************************************************
+ * IMalloc16_Realloc [COMPOBJ.504]
+ */
+SEGPTR WINAPI IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
+{
+    SEGPTR ret;
+    ICOM_THIS(IMalloc16Impl,iface);
+    TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
+    ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
+    UnMapLS(pv);
+    return ret;
+}
+
+/******************************************************************************
+ * IMalloc16_Free [COMPOBJ.505]
+ */
+VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
+{
+    void *ptr = MapSL(pv);
+    ICOM_THIS(IMalloc16Impl,iface);
+    TRACE("(%p)->Free(%08lx)\n",This,pv);
+    UnMapLS(pv);
+    HeapFree( GetProcessHeap(), 0, ptr );
+}
+
+/******************************************************************************
+ * IMalloc16_GetSize [COMPOBJ.506]
+ */
+DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,SEGPTR pv)
+{
+	ICOM_CTHIS(IMalloc16Impl,iface);
+        TRACE("(%p)->GetSize(%08lx)\n",This,pv);
+        return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
+}
+
+/******************************************************************************
+ * IMalloc16_DidAlloc [COMPOBJ.507]
+ */
+INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
+        ICOM_CTHIS(IMalloc16,iface);
+	TRACE("(%p)->DidAlloc(%p)\n",This,pv);
+	return (INT16)-1;
+}
+
+/******************************************************************************
+ * IMalloc16_HeapMinimize [COMPOBJ.508]
+ */
+LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
+        ICOM_THIS(IMalloc16Impl,iface);
+	TRACE("(%p)->HeapMinimize()\n",This);
+	return NULL;
+}
+
+/******************************************************************************
+ * IMalloc16_Constructor [VTABLE]
+ */
+LPMALLOC16
+IMalloc16_Constructor()
+{
+    static ICOM_VTABLE(IMalloc16) vt16;
+    static SEGPTR msegvt16;
+    IMalloc16Impl* This;
+    HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
+
+    This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
+    if (!msegvt16)
+    {
+#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
+        VTENT(QueryInterface);
+        VTENT(AddRef);
+        VTENT(Release);
+        VTENT(Alloc);
+        VTENT(Realloc);
+        VTENT(Free);
+        VTENT(GetSize);
+        VTENT(DidAlloc);
+        VTENT(HeapMinimize);
+#undef VTENT
+        msegvt16 = MapLS( &vt16 );
+    }
+    ICOM_VTBL(This) = (ICOM_VTABLE(IMalloc16)*)msegvt16;
+    This->ref = 1;
+    return (LPMALLOC16)MapLS( This );
+}
+
+
+/***********************************************************************
+ *           CoGetMalloc    [COMPOBJ.4]
+ * RETURNS
+ *	The current win16 IMalloc
+ */
+HRESULT WINAPI CoGetMalloc16(
+	DWORD dwMemContext,	/* [in] unknown */
+	LPMALLOC16 * lpMalloc	/* [out] current win16 malloc interface */
+) {
+    if(!currentMalloc16)
+	currentMalloc16 = IMalloc16_Constructor();
+    *lpMalloc = currentMalloc16;
+    return S_OK;
+}
+
+/***********************************************************************
+ *           CoCreateStandardMalloc [COMPOBJ.71]
+ */
+HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
+					  LPMALLOC16 *lpMalloc)
+{
+    /* FIXME: docu says we shouldn't return the same allocator as in
+     * CoGetMalloc16 */
+    *lpMalloc = IMalloc16_Constructor();
+    return S_OK;
+}
+
+/******************************************************************************
+ *		CoInitialize	[COMPOBJ.2]
+ * Set the win16 IMalloc used for memory management
+ */
+HRESULT WINAPI CoInitialize16(
+	LPVOID lpReserved	/* [in] pointer to win16 malloc interface */
+) {
+    currentMalloc16 = (LPMALLOC16)lpReserved;
+    return S_OK;
+}
+
+/***********************************************************************
+ *           CoUninitialize   [COMPOBJ.3]
+ * Don't know what it does.
+ * 3-Nov-98 -- this was originally misspelled, I changed it to what I
+ *   believe is the correct spelling
+ */
+void WINAPI CoUninitialize16(void)
+{
+  TRACE("()\n");
+  CoFreeAllLibraries();
+}
+
+/***********************************************************************
+ *           IsEqualGUID [COMPOBJ.18]
+ *
+ * Compares two Unique Identifiers.
+ *
+ * RETURNS
+ *	TRUE if equal
+ */
+BOOL16 WINAPI IsEqualGUID16(
+	GUID* g1,	/* [in] unique id 1 */
+	GUID* g2)	/* [in] unique id 2 */
+{
+    return !memcmp( g1, g2, sizeof(GUID) );
+}
+
+/******************************************************************************
+ *		CLSIDFromString	[COMPOBJ.20]
+ * Converts a unique identifier from its string representation into
+ * the GUID struct.
+ *
+ * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
+ *
+ * RETURNS
+ *	the converted GUID
+ */
+HRESULT WINAPI CLSIDFromString16(
+	LPCOLESTR16 idstr,	/* [in] string representation of guid */
+	CLSID *id)		/* [out] GUID converted from string */
+{
+
+  return __CLSIDFromStringA(idstr,id);
+}
+
+extern BOOL WINAPI K32WOWCallback16Ex(	DWORD vpfn16, DWORD dwFlags,
+					DWORD cbArgs, LPVOID pArgs,
+					LPDWORD pdwRetCode );
+
+/******************************************************************************
+ *		_xmalloc16	[internal]
+ * Allocates size bytes from the standard ole16 allocator.
+ *
+ * RETURNS
+ *	the allocated segmented pointer and a HRESULT
+ */
+HRESULT
+_xmalloc16(DWORD size, SEGPTR *ptr) {
+  LPMALLOC16 mllc;
+  DWORD args[2];
+
+  if (CoGetMalloc16(0,&mllc))
+    return E_OUTOFMEMORY;
+
+  args[0] = (DWORD)mllc;
+  args[1] = size;
+  /* No need for a Callback entry, we have WOWCallback16Ex which does
+   * everything we need.
+   */
+  if (!K32WOWCallback16Ex(
+      (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL(
+	  (SEGPTR)ICOM_VTBL(((LPMALLOC16)MapSL((SEGPTR)mllc))))
+      )->Alloc,
+      WCB16_CDECL,
+      2*sizeof(DWORD),
+      (LPVOID)args,
+      (LPDWORD)ptr
+  )) {
+      ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
+      return E_FAIL;
+  }
+  return S_OK;
+}
+
+/******************************************************************************
+ *		StringFromCLSID	[COMPOBJ.19]
+ * Converts a GUID into the respective string representation.
+ * The target string is allocated using the OLE IMalloc.
+ *
+ * RETURNS
+ *	the string representation and HRESULT
+ */
+
+HRESULT WINAPI StringFromCLSID16(
+  REFCLSID id,		/* [in] the GUID to be converted */
+  LPOLESTR16 *idstr	/* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
+
+) {
+  HRESULT ret;
+
+  ret = _xmalloc16(40,(SEGPTR*)idstr);
+  if (ret != S_OK)
+    return ret;
+  return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
+}
+
+/******************************************************************************
+ * ProgIDFromCLSID [COMPOBJ.62]
+ * Converts a class id into the respective Program ID. (By using a registry lookup)
+ * RETURNS S_OK on success
+ * riid associated with the progid
+ */
+HRESULT WINAPI ProgIDFromCLSID16(
+  REFCLSID clsid, /* [in] class id as found in registry */
+  LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
+) {
+  char     strCLSID[50], *buf, *buf2;
+  DWORD    buf2len;
+  HKEY     xhkey;
+  HRESULT  ret = S_OK;
+
+  WINE_StringFromCLSID(clsid, strCLSID);
+
+  buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14);
+  sprintf(buf,"CLSID\\%s\\ProgID", strCLSID);
+  if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
+    ret = REGDB_E_CLASSNOTREG;
+
+  HeapFree(GetProcessHeap(), 0, buf);
+
+  if (ret == S_OK)
+  {
+    buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
+    buf2len = 255;
+    if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
+      ret = REGDB_E_CLASSNOTREG;
+
+    if (ret == S_OK)
+    {
+      ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
+      if (ret != S_OK)
+        return ret;
+      strcpy(MapSL((SEGPTR)*lplpszProgID),buf2);
+      ret = S_OK;
+    }
+    HeapFree(GetProcessHeap(), 0, buf2);
+  }
+  RegCloseKey(xhkey);
+  return ret;
+}
+
+/******************************************************************************
+ *		CLSIDFromProgID	[COMPOBJ.61]
+ * Converts a program id into the respective GUID. (By using a registry lookup)
+ * RETURNS
+ *	riid associated with the progid
+ */
+HRESULT WINAPI CLSIDFromProgID16(
+	LPCOLESTR16 progid,	/* [in] program id as found in registry */
+	LPCLSID riid		/* [out] associated CLSID */
+) {
+	char	*buf,buf2[80];
+	DWORD	buf2len;
+	HRESULT	err;
+	HKEY	xhkey;
+
+	buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
+	sprintf(buf,"%s\\CLSID",progid);
+	if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
+		HeapFree(GetProcessHeap(),0,buf);
+                return CO_E_CLASSSTRING;
+	}
+	HeapFree(GetProcessHeap(),0,buf);
+	buf2len = sizeof(buf2);
+	if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
+		RegCloseKey(xhkey);
+                return CO_E_CLASSSTRING;
+	}
+	RegCloseKey(xhkey);
+	return __CLSIDFromStringA(buf2,riid);
+}
+
+/***********************************************************************
+ *           LookupETask (COMPOBJ.94)
+ */
+HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
+	FIXME("(%p,%p),stub!\n",hTask,p);
+	if ((*hTask = GetCurrentTask()) == hETask) {
+		memcpy(p, Table_ETask, sizeof(Table_ETask));
+	}
+	return 0;
+}
+
+/***********************************************************************
+ *           SetETask (COMPOBJ.95)
+ */
+HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
+        FIXME("(%04x,%p),stub!\n",hTask,p);
+	hETask = hTask;
+	return 0;
+}
+
+/***********************************************************************
+ *           CALLOBJECTINWOW (COMPOBJ.201)
+ */
+HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
+	FIXME("(%p,%p),stub!\n",p1,p2);
+	return 0;
+}
+
+/******************************************************************************
+ *		CoRegisterClassObject	[COMPOBJ.5]
+ *
+ * Don't know where it registers it ...
+ */
+HRESULT WINAPI CoRegisterClassObject16(
+	REFCLSID rclsid,
+	LPUNKNOWN pUnk,
+	DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
+	DWORD flags,        /* [in] REGCLS flags indicating how connections are made */
+	LPDWORD lpdwRegister
+) {
+	char	buf[80];
+
+	WINE_StringFromCLSID(rclsid,buf);
+
+	FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
+		buf,pUnk,dwClsContext,flags,lpdwRegister
+	);
+	return 0;
+}
+
+/******************************************************************************
+ *      CoRevokeClassObject [COMPOBJ.6]
+ *
+ */
+HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
+{
+    FIXME("(0x%08lx),stub!\n", dwRegister);
+    return 0;
+}
+
+/******************************************************************************
+ *      CoFileTimeToDosDateTime [COMPOBJ.30]
+ */
+BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
+{
+    return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
+}
+
+/******************************************************************************
+ *      CoDosDateTimeToFileTime [COMPOBJ.31]
+ */
+BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
+{
+    return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
+}
+
+/******************************************************************************
+ *		CoRegisterMessageFilter	[COMPOBJ.27]
+ */
+HRESULT WINAPI CoRegisterMessageFilter16(
+	LPMESSAGEFILTER lpMessageFilter,
+	LPMESSAGEFILTER *lplpMessageFilter
+) {
+	FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
+	return 0;
+}
+
+/******************************************************************************
+ *		CoLockObjectExternal	[COMPOBJ.63]
+ */
+HRESULT WINAPI CoLockObjectExternal16(
+    LPUNKNOWN pUnk,		/* [in] object to be locked */
+    BOOL16 fLock,		/* [in] do lock */
+    BOOL16 fLastUnlockReleases	/* [in] ? */
+) {
+    FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
+    return S_OK;
+}
+
+/***********************************************************************
+ *           CoGetState [COMPOBJ.115]
+ */
+HRESULT WINAPI CoGetState16(LPDWORD state)
+{
+    FIXME("(%p),stub!\n", state);
+
+    *state = 0;
+    return S_OK;
+}
+
+/***********************************************************************
+ *      DllEntryPoint                   [COMPOBJ.116]
+ *
+ *    Initialization code for the COMPOBJ DLL
+ *
+ * RETURNS:
+ */
+BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
+{
+        TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
+        switch(Reason)
+        {
+        case DLL_PROCESS_ATTACH:
+                if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
+                break;
+
+        case DLL_PROCESS_DETACH:
+                if(!--COMPOBJ_Attach)
+                        COMPOBJ_hInstance = 0;
+                break;
+        }
+        return TRUE;
+}
+

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux