#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 "objbase.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
- */
-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.
+ * a Process can only have one MTA
*/
-HINSTANCE16 COMPOBJ_hInstance = 0;
-HINSTANCE COMPOBJ_hInstance32 = 0;
-static int COMPOBJ_Attach = 0;
-LPMALLOC16 currentMalloc16=NULL;
-LPMALLOC currentMalloc32=NULL;
+/* 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
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);
/******************************************************************************
*/
void COMPOBJ_InitProcess( void )
{
- InitializeCriticalSection( &csRegisteredClassList );
- InitializeCriticalSection( &csOpenDllList );
}
void COMPOBJ_UninitProcess( void )
{
- DeleteCriticalSection( &csRegisteredClassList );
- DeleteCriticalSection( &csOpenDllList );
+}
+
+/*****************************************************************************
+ * This section contains OpenDllList implemantation
+ */
+
+static void COMPOBJ_DLLList_Add(HANDLE hLibrary)
+{
+ OpenDll *ptr;
+ OpenDll *tmp;
+
+ TRACE("\n");
+
+ 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 );
+}
+
+static void COMPOBJ_DllList_FreeUnused(int Timeout)
+{
+ 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 %p\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 );
}
/******************************************************************************
return (rmm<<16)+rup;
}
-/******************************************************************************
- * 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;
-}
-
/******************************************************************************
* CoInitialize [OLE32.26]
*
return hr;
}
-/***********************************************************************
- * 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]
*
}
}
-/***********************************************************************
- * 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;
-}
-
-/******************************************************************************
- * CoGetMalloc [OLE32.20]
- *
- * RETURNS
- * The current win32 IMalloc
- */
-HRESULT WINAPI CoGetMalloc(
- DWORD dwMemContext, /* [in] unknown */
- LPMALLOC *lpMalloc /* [out] current win32 malloc interface */
-) {
- if(!currentMalloc32)
- currentMalloc32 = IMalloc_Constructor();
- *lpMalloc = currentMalloc32;
- 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;
-}
-
/******************************************************************************
* CoDisconnectObject [COMPOBJ.15]
* CoDisconnectObject [OLE32.8]
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;
- BYTE *p;
int i;
BYTE table[256];
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;
}
}
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
- p = (BYTE *) id;
-
- s++; /* skip leading brace */
- for (i = 0; i < 4; i++) {
- p[3 - i] = table[*s]<<4 | table[*(s+1)];
- s += 2;
- }
- p += 4;
- s++; /* skip - */
-
- for (i = 0; i < 2; i++) {
- p[1-i] = table[*s]<<4 | table[*(s+1)];
- s += 2;
- }
- p += 2;
- s++; /* skip - */
-
- for (i = 0; i < 2; i++) {
- p[1-i] = table[*s]<<4 | table[*(s+1)];
- s += 2;
- }
- p += 2;
- s++; /* skip - */
+ id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
+ table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] << 4 | table[s[8]]);
+ id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
+ id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
/* these are just sequential bytes */
- for (i = 0; i < 2; i++) {
- *p++ = table[*s]<<4 | table[*(s+1)];
- s += 2;
- }
- s++; /* skip - */
-
- for (i = 0; i < 6; i++) {
- *p++ = table[*s]<<4 | table[*(s+1)];
- s += 2;
- }
+ id->Data4[0] = table[s[20]] << 4 | table[s[21]];
+ id->Data4[1] = table[s[22]] << 4 | table[s[23]];
+ id->Data4[2] = table[s[25]] << 4 | table[s[26]];
+ id->Data4[3] = table[s[27]] << 4 | table[s[28]];
+ id->Data4[4] = table[s[29]] << 4 | table[s[30]];
+ id->Data4[5] = table[s[31]] << 4 | table[s[32]];
+ id->Data4[6] = table[s[33]] << 4 | table[s[34]];
+ id->Data4[7] = table[s[35]] << 4 | table[s[36]];
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 */
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);
}
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 */
-
-) {
- extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
- DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode );
- LPMALLOC16 mllc;
- HRESULT ret;
- DWORD args[2];
-
- ret = CoGetMalloc16(0,&mllc);
- if (ret) return ret;
-
- args[0] = (DWORD)mllc;
- args[1] = 40;
-
- /* 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)idstr
- )) {
- WARN("CallTo16 IMalloc16 failed\n");
- return E_FAIL;
- }
- return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
-}
/******************************************************************************
* StringFromCLSID [OLE32.151]
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)
return CO_E_CLASSSTRING;
}
RegCloseKey(xhkey);
- return CLSIDFromString16(buf2,riid);
+ return __CLSIDFromStringA(buf2,riid);
}
/* 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;
}
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]
+/***
+ * COM_GetRegisteredClassObject
+ *
+ * This internal method is used to scan the registered class list to
+ * find a class object.
*
- * 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
- *
- * This internal method is used to scan the registered class list to
- * find a class object.
- *
- * Params:
- * rclsid Class ID of the class to find.
- * dwClsContext Class context to match.
- * ppv [out] returns a pointer to the class object. Complying
- * to normal COM usage, this method will increase the
- * reference count on this object.
+ * Params:
+ * rclsid Class ID of the class to find.
+ * dwClsContext Class context to match.
+ * ppv [out] returns a pointer to the class object. Complying
+ * to normal COM usage, this method will increase the
+ * reference count on this object.
*/
static HRESULT COM_GetRegisteredClassObject(
REFCLSID rclsid,
return hr;
}
-static HRESULT WINAPI Remote_CoGetClassObject(
- REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
- REFIID iid, LPVOID *ppv
-) {
- HKEY key;
- char buf[200];
- HRESULT hres = E_UNEXPECTED;
- char xclsid[80];
- WCHAR dllName[MAX_PATH+1];
- DWORD dllNameLen = sizeof(dllName);
- STARTUPINFOW sinfo;
- PROCESS_INFORMATION pinfo;
-
- WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
-
- sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
- hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
-
- if (hres != ERROR_SUCCESS)
- return REGDB_E_CLASSNOTREG;
-
- memset(dllName,0,sizeof(dllName));
- hres= RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)dllName,&dllNameLen);
- if (hres)
- return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
- RegCloseKey(key);
-
- TRACE("found LocalServer32 exe %s\n", debugstr_w(dllName));
-
- memset(&sinfo,0,sizeof(sinfo));
- sinfo.cb = sizeof(sinfo);
- if (!CreateProcessW(NULL,dllName,NULL,NULL,FALSE,0,NULL,NULL,&sinfo,&pinfo))
- return E_FAIL;
- return create_marshalled_proxy(rclsid,iid,ppv);
+/***********************************************************************
+ * 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]
*
- * FIXME. If request allows of several options and there is a failure
+ * FIXME. If request allows of several options and there is a failure
* with one (other than not being registered) do we try the
* others or return failure? (E.g. inprocess is registered but
* the DLL is not found but the server version works)
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;
- HKEY key;
- char buf[200];
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));
return hres;
}
- if (((CLSCTX_LOCAL_SERVER) & dwClsContext)
- && !((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext))
- return Remote_CoGetClassObject(rclsid,dwClsContext,pServerInfo,iid,ppv);
+ /* first try: in-process */
+ if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) {
+ char keyname[MAX_PATH];
+ char dllpath[MAX_PATH+1];
- /* remote servers not supported yet */
- if ( ((CLSCTX_REMOTE_SERVER) & dwClsContext)
- && !((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext)
- ){
- FIXME("CLSCTX_REMOTE_SERVER not supported!\n");
- return E_NOINTERFACE;
- }
+ sprintf(keyname,"CLSID\\%s\\InprocServer32",xclsid);
- if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) {
- HKEY key;
- char buf[200];
-
- 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))
- {
+ 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);
- }
+ }
+ }
}
-
- /* Finally try out of process */
- /* out of process and remote servers not supported yet */
+ /* Next try out of process */
if (CLSCTX_LOCAL_SERVER & dwClsContext)
{
- memset(ProviderName,0,sizeof(ProviderName));
- sprintf(buf,"CLSID\\%s\\LocalServer32",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))
- {
- hres = REGDB_E_CLASSNOTREG;
- }
- else
- {
- /* CO_E_APPNOTFOUND if no exe */
- FIXME("CLSCTX_LOCAL_SERVER %s registered but not yet supported!\n",debugstr_w(ProviderName));
- hres = E_ACCESSDENIED;
- }
+ return create_marshalled_proxy(rclsid,iid,ppv);
}
+ /* Finally try remote */
if (CLSCTX_REMOTE_SERVER & dwClsContext)
{
FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
- hres = E_ACCESSDENIED;
+ hres = E_NOINTERFACE;
}
return hres;
{
IStorage *pstg=0;
HRESULT res;
- int nbElm=0,length=0,i=0;
- LONG sizeProgId=20;
+ int nbElm, length, i;
+ LONG sizeProgId;
LPOLESTR *pathDec=0,absFile=0,progId=0;
- WCHAR extention[100]={0};
+ LPWSTR extension;
+ static const WCHAR bkslashW[] = {'\\',0};
+ static const WCHAR dotW[] = {'.',0};
- TRACE("()\n");
+ TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);
/* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/
if((StgIsStorageFile(filePathName))==S_OK){
absFile=pathDec[nbElm-1];
/* failed if the path represente a directory and not an absolute file name*/
- if (lstrcmpW(absFile,(LPOLESTR)"\\"))
+ if (!lstrcmpW(absFile, bkslashW))
return MK_E_INVALIDEXTENSION;
/* get the extension of the file */
+ extension = NULL;
length=lstrlenW(absFile);
- for(i=length-1; ( (i>=0) && (extention[i]=absFile[i]) );i--);
+ for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
+ /* nothing */;
- /* get the progId associated to the extension */
- progId=CoTaskMemAlloc(sizeProgId);
+ if (!extension || !lstrcmpW(extension, dotW))
+ return MK_E_INVALIDEXTENSION;
- res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
+ res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);
- if (res==ERROR_MORE_DATA){
+ /* get the progId associated to the extension */
+ progId = CoTaskMemAlloc(sizeProgId);
+ res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId);
- progId = CoTaskMemRealloc(progId,sizeProgId);
- res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
- }
if (res==ERROR_SUCCESS)
/* return the clsid associated to the progId */
res= CLSIDFromProgID(progId,pclsid);
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]
}
/***********************************************************************
- * 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 );
+ TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
- /* lookup library in linked list */
- prev = NULL;
- for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
- if (ptr->hLibrary == hLibrary) {
- break;
- }
- prev = ptr;
- }
+ return LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
- if (ptr == NULL) {
- /* shouldn't happen if user passed in a valid hLibrary */
- goto end;
- }
- /* assert: ptr points to the library entry to free */
-
- /* 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);
}
/***********************************************************************
}
/***********************************************************************
- * CoTaskMemAlloc (OLE32.43)
- * RETURNS
- * pointer to newly allocated block
+ * CoLoadLibrary (OLE32.30)
*/
-LPVOID WINAPI CoTaskMemAlloc(
- ULONG size /* [in] size of memoryblock to be allocated */
-) {
- LPMALLOC lpmalloc;
- HRESULT ret = CoGetMalloc(0,&lpmalloc);
+static void COM_RevokeAllClasses()
+{
+ EnterCriticalSection( &csRegisteredClassList );
- if (FAILED(ret))
- return NULL;
+ while (firstRegisteredClass!=0)
+ {
+ CoRevokeClassObject(firstRegisteredClass->dwCookie);
+ }
- return IMalloc_Alloc(lpmalloc,size);
+ LeaveCriticalSection( &csRegisteredClassList );
}
-/***********************************************************************
- * CoTaskMemFree (OLE32.44)
- */
-VOID WINAPI CoTaskMemFree(
- LPVOID ptr /* [in] pointer to be freed */
-) {
- LPMALLOC lpmalloc;
- HRESULT ret = CoGetMalloc(0,&lpmalloc);
- if (FAILED(ret))
- return;
+/****************************************************************************
+ * 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
+ */
- IMalloc_Free(lpmalloc, ptr);
-}
+#define EL_END_OF_LIST 0
+#define EL_NOT_FOUND 0
-/***********************************************************************
- * CoTaskMemRealloc (OLE32.45)
- * RETURNS
- * pointer to newly allocated block
+/*
+ * Declaration of the static structure that manage the
+ * external lock to COM objects.
*/
-LPVOID WINAPI CoTaskMemRealloc(
- LPVOID pvOld,
- ULONG size) /* [in] size of memoryblock to be allocated */
+typedef struct COM_ExternalLock COM_ExternalLock;
+typedef struct COM_ExternalLockList COM_ExternalLockList;
+
+struct COM_ExternalLock
{
- LPMALLOC lpmalloc;
- HRESULT ret = CoGetMalloc(0,&lpmalloc);
+ IUnknown *pUnk; /* IUnknown referenced */
+ ULONG uRefCount; /* external lock counter to IUnknown object*/
+ COM_ExternalLock *next; /* Pointer to next element in list */
+};
- if (FAILED(ret))
- return NULL;
+struct COM_ExternalLockList
+{
+ COM_ExternalLock *head; /* head of list */
+};
- return IMalloc_Realloc(lpmalloc, pvOld, size);
-}
+/*
+ * Declaration and initialization of the static structure that manages
+ * the external lock to COM objects.
+ */
+static COM_ExternalLockList elList = { EL_END_OF_LIST };
-/***********************************************************************
- * CoLoadLibrary (OLE32.30)
+/*
+ * Private methods used to managed the linked list
*/
-HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
-{
- HINSTANCE hLibrary;
- OpenDll *ptr;
- OpenDll *tmp;
- TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
- hLibrary = LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+static COM_ExternalLock* COM_ExternalLockLocate(
+ COM_ExternalLock *element,
+ IUnknown *pUnk);
- if (!bAutoFree)
- return hLibrary;
+/****************************************************************************
+ * Internal - Insert a new IUnknown* to the linked list
+ */
+static BOOL COM_ExternalLockInsert(
+ IUnknown *pUnk)
+{
+ COM_ExternalLock *newLock = NULL;
+ COM_ExternalLock *previousHead = NULL;
- EnterCriticalSection( &csOpenDllList );
+ /*
+ * Allocate space for the new storage object
+ */
+ newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
- if (openDllList == NULL) {
- /* empty list -- add first node */
- openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
- openDllList->hLibrary=hLibrary;
- openDllList->next = NULL;
+ if (newLock!=NULL) {
+ if ( elList.head == EL_END_OF_LIST ) {
+ elList.head = newLock; /* The list is empty */
} 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;
- }
+ /* insert does it at the head */
+ previousHead = elList.head;
+ elList.head = newLock;
}
- LeaveCriticalSection( &csOpenDllList );
-
- return hLibrary;
-}
-
-/***********************************************************************
- * CoInitializeWOW (OLE32.27)
- */
-HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
- FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
- 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;
-}
-
-/******************************************************************************
- * CoLockObjectExternal [OLE32.31]
- */
-HRESULT WINAPI CoLockObjectExternal(
- LPUNKNOWN pUnk, /* [in] object to be locked */
- BOOL fLock, /* [in] do lock */
- BOOL fLastUnlockReleases) /* [in] unlock all */
-{
+ /* Set new list item data member */
+ newLock->pUnk = pUnk;
+ newLock->uRefCount = 1;
+ newLock->next = previousHead;
- 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);
+ return TRUE;
}
-
- return S_OK;
+ return FALSE;
}
-/***********************************************************************
- * 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]
+/****************************************************************************
+ * Internal - Method that removes an item from the linked list.
*/
-HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal)
+static void COM_ExternalLockDelete(
+ COM_ExternalLock *itemList)
{
- FIXME ("(%p %p): stub\n", punkOuter, ppunkMarshal);
+ COM_ExternalLock *current = elList.head;
- return S_OK;
-}
+ 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;
+ }
-/***
- * 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
- */
-static void COM_RevokeAllClasses()
-{
- EnterCriticalSection( &csRegisteredClassList );
+ /* Skip to the next item */
+ current = current->next;
- while (firstRegisteredClass!=0)
- {
- CoRevokeClassObject(firstRegisteredClass->dwCookie);
+ } while ( current != EL_END_OF_LIST );
}
-
- LeaveCriticalSection( &csRegisteredClassList );
}
/****************************************************************************
- * 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
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 );
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... */
}
}
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.24]
+ *
+ * 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;
- }
+ FIXME("\n");
- /* Skip to the next item */
- current = current->next;
+ if(pUnkState) {
+ IUnknown_AddRef(pUnkState);
+ *ppv = pUnkState;
+ FIXME("-- %p\n", *ppv);
+ return S_OK;
+ }
+ *ppv = NULL;
+ return E_FAIL;
- } while ( current != EL_END_OF_LIST );
- }
}
/***********************************************************************
- * 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;
-
- case DLL_PROCESS_DETACH:
- if(!--COMPOBJ_Attach)
- COMPOBJ_hInstance = 0;
- break;
- }
- return TRUE;
+ FIXME("(%p),stub!\n", pv);
+
+ 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]
*/
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;
}
/******************************************************************************
{
return !memcmp(rguid1,rguid2,sizeof(GUID));
}
+
+/***********************************************************************
+ * CoInitializeSecurity [OLE32.164]
+ */
+HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
+ SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
+ void* pReserved1, DWORD dwAuthnLevel,
+ DWORD dwImpLevel, void* pReserved2,
+ DWORD dwCapabilities, void* pReserved3)
+{
+ FIXME("(%p,%ld,%p,%p,%ld,%ld,%p,%ld,%p) - stub!\n", pSecDesc, cAuthSvc,
+ asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pReserved2,
+ dwCapabilities, pReserved3);
+ return S_OK;
+}