Implementation of CoLoadLibrary, CoFreeAllLibraries,

CoFreeUnusedLibraries, CoFreeLibrary.
Fixed misspelling of CoUninitialize.
This commit is contained in:
John Richardson 1998-11-07 12:19:26 +00:00 committed by Alexandre Julliard
parent 50af6022c7
commit 2660e6a06c
4 changed files with 205 additions and 65 deletions

View File

@ -3,7 +3,7 @@ type win16
1 pascal CoBuildVersion() CoBuildVersion 1 pascal CoBuildVersion() CoBuildVersion
2 pascal CoInitialize(long) CoInitialize16 2 pascal CoInitialize(long) CoInitialize16
3 pascal CoUninitialize() CoUnitialize 3 pascal CoUninitialize() CoUninitialize
4 pascal CoGetMalloc(long ptr) CoGetMalloc16 4 pascal CoGetMalloc(long ptr) CoGetMalloc16
5 pascal CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject16 5 pascal CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject16
6 stub COREVOKECLASSOBJECT 6 stub COREVOKECLASSOBJECT

View File

@ -290,6 +290,12 @@ OLESTATUS WINAPI OleRevokeServerDoc(LHSERVERDOC);
OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC); OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC);
OLESTATUS WINAPI OleRevokeServer(LHSERVER); OLESTATUS WINAPI OleRevokeServer(LHSERVER);
/* com functions */
void WINAPI CoFreeUnusedLibraries(void);
HINSTANCE32 WINAPI CoLoadLibrary(LPSTR lpszLibName, BOOL32 bAutoFree);
void WINAPI CoFreeUnusedLibraries(void);
void WINAPI CoFreeAllLibraries(void);
typedef enum tagCALLCONV { typedef enum tagCALLCONV {
CC_CDECL = 1, CC_CDECL = 1,
CC_MSCPASCAL = CC_CDECL + 1, CC_MSCPASCAL = CC_CDECL + 1,

View File

@ -25,6 +25,7 @@
#include "dinput.h" #include "dinput.h"
#include "d3d.h" #include "d3d.h"
#include "dplay.h" #include "dplay.h"
#include "windows.h"
LPMALLOC16 currentMalloc16=NULL; LPMALLOC16 currentMalloc16=NULL;
@ -33,13 +34,27 @@ LPMALLOC32 currentMalloc32=NULL;
HTASK16 hETask = 0; HTASK16 hETask = 0;
WORD Table_ETask[62]; WORD Table_ETask[62];
/* 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.
*/
typedef struct tagOpenDll {
char *DllName; /* really only needed for debugging */
HINSTANCE32 hLibrary;
struct tagOpenDll *next;
} OpenDll;
static OpenDll *openDllList = NULL; /* linked list of open dlls */
/****************************************************************************** /******************************************************************************
* CoBuildVersion [COMPOBJ.1] * CoBuildVersion [COMPOBJ.1]
* *
* RETURNS * RETURNS
* Current built version, hiword is majornumber, loword is minornumber * Current built version, hiword is majornumber, loword is minornumber
*/ */
DWORD WINAPI CoBuildVersion() DWORD WINAPI CoBuildVersion(void)
{ {
TRACE(ole,"(void)\n"); TRACE(ole,"(void)\n");
return (rmm<<16)+rup; return (rmm<<16)+rup;
@ -63,17 +78,23 @@ HRESULT WINAPI CoInitialize16(
HRESULT WINAPI CoInitialize32( HRESULT WINAPI CoInitialize32(
LPMALLOC32 lpReserved /* [in] pointer to win32 malloc interface */ LPMALLOC32 lpReserved /* [in] pointer to win32 malloc interface */
) { ) {
/* FIXME: there really should be something here that incrememts a refcount
* but I'm supposing that it is a real COM object, so I won't bother
* creating one here. (Decrement done in CoUnitialize()) */
currentMalloc32 = lpReserved; currentMalloc32 = lpReserved;
return S_OK; return S_OK;
} }
/*********************************************************************** /***********************************************************************
* CoUnitialize [COMPOBJ.3] * CoUnitialize [COMPOBJ.3]
* Don't know what it does. * 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 CoUnitialize() void WINAPI CoUninitialize(void)
{ {
TRACE(ole,"(void)\n"); TRACE(ole,"(void)\n");
CoFreeAllLibraries();
} }
/*********************************************************************** /***********************************************************************
@ -511,8 +532,8 @@ HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext,
char dllName[MAX_PATH+1]; char dllName[MAX_PATH+1];
LONG dllNameLen = MAX_PATH+1; LONG dllNameLen = MAX_PATH+1;
HINSTANCE32 hLibrary; HINSTANCE32 hLibrary;
typedef HRESULT (*DllGetClassObjectFunc)(REFCLSID clsid, typedef HRESULT (*DllGetClassObjectFunc)(REFCLSID clsid,
REFIID iid, LPVOID *ppv); REFIID iid, LPVOID *ppv);
DllGetClassObjectFunc DllGetClassObject; DllGetClassObjectFunc DllGetClassObject;
HKEY CLSIDkey; HKEY CLSIDkey;
@ -527,71 +548,74 @@ HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext,
/* out of process and remote servers not supported yet */ /* out of process and remote servers not supported yet */
if ((CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER) & dwClsContext) { if ((CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER) & dwClsContext) {
FIXME(ole, "CLSCTX_LOCAL_SERVER and CLSCTX_REMOTE_SERVER not supported!\n"); FIXME(ole, "CLSCTX_LOCAL_SERVER and CLSCTX_REMOTE_SERVER not supported!\n");
return E_ACCESSDENIED; return E_ACCESSDENIED;
} }
if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) { if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) {
/* lookup CLSID in registry key HKCR/CLSID */ /* lookup CLSID in registry key HKCR/CLSID */
hres = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, "CLSID", 0, hres = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, "CLSID", 0,
KEY_ENUMERATE_SUB_KEYS, &CLSIDkey); KEY_ENUMERATE_SUB_KEYS, &CLSIDkey);
if (hres != ERROR_SUCCESS) { if (hres != ERROR_SUCCESS) {
return REGDB_E_READREGDB; return REGDB_E_READREGDB;
} }
/* search all the subkeys for a match to xclsid */ /* search all the subkeys for a match to xclsid */
found=FALSE; found=FALSE;
for (i=0; i<100000; i++) { for (i=0; i<100000; i++) {
char clsidKeyPath[MAX_PATH + 1];
HKEY key;
LONG res;
char clsidKeyPath[MAX_PATH + 1]; res = RegEnumKey32A(CLSIDkey, i, buf, MAX_PATH);
HKEY key; if (res == ERROR_NO_MORE_ITEMS)
LONG res; break;
if (res != ERROR_SUCCESS)
continue;
res = RegEnumKey32A(CLSIDkey, i, buf, MAX_PATH); sprintf(clsidKeyPath, "CLSID\\%s", buf);
if (res == ERROR_NO_MORE_ITEMS)
break; if (lstrcmpi32A(buf, xclsid) != 0)
if (res != ERROR_SUCCESS) continue;
continue;
sprintf(clsidKeyPath, "CLSID\\%s", buf); res = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, clsidKeyPath, 0,
KEY_QUERY_VALUE, &key);
if (res != ERROR_SUCCESS) {
return REGDB_E_READREGDB;
}
hres = RegQueryValue32A(key, "InprocServer32", dllName, &dllNameLen);
if (res != ERROR_SUCCESS) {
return REGDB_E_READREGDB;
}
TRACE(ole,"found InprocServer32 dll %s\n", dllName);
found = TRUE;
break;
}
if (lstrcmpi32A(buf, xclsid) != 0) if (!found) {
continue; return REGDB_E_CLASSNOTREG;
}
res = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, clsidKeyPath, 0,
KEY_QUERY_VALUE, &key); /* open dll, call DllGetClassFactory */
if (res != ERROR_SUCCESS) { hLibrary = CoLoadLibrary(dllName, TRUE);
return REGDB_E_READREGDB;
}
hres = RegQueryValue32A(key, "InprocServer32", dllName, &dllNameLen); if (hLibrary == 0) {
if (res != ERROR_SUCCESS) { TRACE(ole,"couldn't load InprocServer32 dll %s\n", dllName);
return REGDB_E_READREGDB; return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
} }
TRACE(ole,"found InprocServer32 dll %s\n", dllName);
found = TRUE;
break;
}
if (!found) { DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress32(hLibrary, "DllGetClassObject");
return REGDB_E_CLASSNOTREG; if (DllGetClassObject == NULL) {
} /* not sure if this should be called here CoFreeLibrary(hLibrary);*/
TRACE(ole,"couldn't find function DllGetClassObject in %s\n", dllName);
/* open dll, call DllGetClassFactory */ return E_ACCESSDENIED;
hLibrary = LoadLibrary32A(dllName); }
if (hLibrary == 0) { return DllGetClassObject(rclsid, iid, ppv);
TRACE(ole,"couldn't load InprocServer32 dll %s\n", dllName);
return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
}
DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress32(hLibrary, "DllGetClassObject");
if (DllGetClassObject == NULL) {
TRACE(ole,"couldn't find function DllGetClassObject in %s\n", dllName);
return E_ACCESSDENIED;
}
return DllGetClassObject(rclsid, iid, ppv);
} }
return hres; return hres;
@ -644,20 +668,85 @@ HRESULT WINAPI CoCreateInstance(
#endif #endif
} }
/*********************************************************************** /***********************************************************************
* CoFreeLibrary [COMPOBJ.13] * CoFreeLibrary [COMPOBJ.13]
*/ */
void WINAPI CoFreeLibrary(HINSTANCE32 hInst) void WINAPI CoFreeLibrary(HINSTANCE32 hLibrary)
{ {
FIXME(ole,"(), stub !\n"); OpenDll *ptr, *prev;
OpenDll *tmp;
/* lookup library in linked list */
prev = NULL;
for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
if (ptr->hLibrary == hLibrary) {
break;
}
prev = ptr;
}
if (ptr == NULL) {
/* shouldn't happen if user passed in a valid hLibrary */
return;
}
/* assert: ptr points to the library entry to free */
/* free library and remove node from list */
FreeLibrary32(hLibrary);
if (ptr == openDllList) {
tmp = openDllList->next;
HeapFree(GetProcessHeap(), 0, openDllList->DllName);
HeapFree(GetProcessHeap(), 0, openDllList);
openDllList = tmp;
} else {
tmp = ptr->next;
HeapFree(GetProcessHeap(), 0, ptr->DllName);
HeapFree(GetProcessHeap(), 0, ptr);
prev->next = tmp;
}
} }
/***********************************************************************
* CoFreeAllLibraries [COMPOBJ.12]
*/
void WINAPI CoFreeAllLibraries(void)
{
OpenDll *ptr, *tmp;
for (ptr = openDllList; ptr != NULL; ) {
tmp=ptr->next;
CoFreeLibrary(ptr->hLibrary);
ptr = tmp;
}
}
/*********************************************************************** /***********************************************************************
* CoFreeUnusedLibraries [COMPOBJ.17] * CoFreeUnusedLibraries [COMPOBJ.17]
*/ */
void WINAPI CoFreeUnusedLibraries() void WINAPI CoFreeUnusedLibraries(void)
{ {
FIXME(ole,"(), stub !\n"); OpenDll *ptr, *tmp;
typedef HRESULT(*DllCanUnloadNowFunc)(void);
DllCanUnloadNowFunc DllCanUnloadNow;
for (ptr = openDllList; ptr != NULL; ) {
DllCanUnloadNow = (DllCanUnloadNowFunc)
GetProcAddress32(ptr->hLibrary, "DllCanUnloadNow");
if (DllCanUnloadNow() == S_OK) {
tmp=ptr->next;
CoFreeLibrary(ptr->hLibrary);
ptr = tmp;
} else {
ptr=ptr->next;
}
}
} }
/*********************************************************************** /***********************************************************************
@ -701,6 +790,51 @@ VOID WINAPI CoTaskMemFree(
return lpmalloc->lpvtbl->fnFree(lpmalloc,ptr); return lpmalloc->lpvtbl->fnFree(lpmalloc,ptr);
} }
/***********************************************************************
* CoLoadLibrary (OLE32.30)
*/
HINSTANCE32 WINAPI CoLoadLibrary(LPSTR lpszLibName, BOOL32 bAutoFree)
{
HINSTANCE32 hLibrary;
OpenDll *ptr;
OpenDll *tmp;
TRACE(ole,"CoLoadLibrary(%p, %d\n", lpszLibName, bAutoFree);
hLibrary = LoadLibrary32A(lpszLibName);
if (!bAutoFree)
return hLibrary;
if (openDllList == NULL) {
/* empty list -- add first node */
openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
openDllList->DllName = HEAP_strdupA(GetProcessHeap(), 0, lpszLibName);
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->next =
(OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
openDllList->DllName = HEAP_strdupA(GetProcessHeap(), 0, lpszLibName);
openDllList->hLibrary = hLibrary;
openDllList->next = tmp;
}
}
return hLibrary;
}
/*********************************************************************** /***********************************************************************
* CoInitializeWOW (OLE32.27) * CoInitializeWOW (OLE32.27)
*/ */

View File

@ -12,7 +12,7 @@ type win32
9 stdcall CoDosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime 9 stdcall CoDosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
10 stdcall CoFileTimeNow(ptr) CoFileTimeNow 10 stdcall CoFileTimeNow(ptr) CoFileTimeNow
11 stdcall CoFileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime 11 stdcall CoFileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
12 stub CoFreeAllLibraries 12 stdcall CoFreeAllLibraries() CoFreeAllLibraries
13 stdcall CoFreeLibrary(long) CoFreeLibrary 13 stdcall CoFreeLibrary(long) CoFreeLibrary
14 stdcall CoFreeUnusedLibraries() CoFreeUnusedLibraries 14 stdcall CoFreeUnusedLibraries() CoFreeUnusedLibraries
15 stub CoGetCallerTID 15 stub CoGetCallerTID
@ -30,7 +30,7 @@ type win32
27 stdcall CoInitializeWOW(long long) CoInitializeWOW 27 stdcall CoInitializeWOW(long long) CoInitializeWOW
28 stub CoIsHandlerConnected 28 stub CoIsHandlerConnected
29 stub CoIsOle1Class 29 stub CoIsOle1Class
30 stub CoLoadLibrary 30 stdcall CoLoadLibrary(ptr long) CoLoadLibrary
31 stdcall CoLockObjectExternal(ptr long long) CoLockObjectExternal32 31 stdcall CoLockObjectExternal(ptr long long) CoLockObjectExternal32
32 stub CoMarshalHresult 32 stub CoMarshalHresult
33 stub CoMarshalInterThreadInterfaceInStream 33 stub CoMarshalInterThreadInterfaceInStream
@ -47,7 +47,7 @@ type win32
44 stdcall CoTaskMemFree(ptr) CoTaskMemFree 44 stdcall CoTaskMemFree(ptr) CoTaskMemFree
45 stub CoTaskMemRealloc 45 stub CoTaskMemRealloc
46 stub CoTreatAsClass 46 stub CoTreatAsClass
47 stdcall CoUninitialize() CoUnitialize 47 stdcall CoUninitialize() CoUninitialize
48 stub CoUnloadingWOW 48 stub CoUnloadingWOW
49 stub CoUnmarshalHresult 49 stub CoUnmarshalHresult
50 stub CoUnmarshalInterface 50 stub CoUnmarshalInterface