4 * Copyright 1995 Martin von Loewis
21 #include "interfaces.h"
31 LPMALLOC16 currentMalloc16=NULL;
32 LPMALLOC32 currentMalloc32=NULL;
38 /* this open DLL table belongs in a per process table, but my guess is that
39 * it shouldn't live in the kernel, so I'll put them out here in DLL
40 * space assuming that there is one OLE32 per process.
42 typedef struct tagOpenDll {
43 char *DllName; /* really only needed for debugging */
45 struct tagOpenDll *next;
48 static OpenDll *openDllList = NULL; /* linked list of open dlls */
51 /******************************************************************************
52 * CoBuildVersion [COMPOBJ.1]
55 * Current built version, hiword is majornumber, loword is minornumber
57 DWORD WINAPI CoBuildVersion(void)
59 TRACE(ole,"(void)\n");
63 /******************************************************************************
64 * CoInitialize16 [COMPOBJ.2]
65 * Set the win16 IMalloc used for memory management
67 HRESULT WINAPI CoInitialize16(
68 LPMALLOC16 lpReserved /* [in] pointer to win16 malloc interface */
70 currentMalloc16 = lpReserved;
74 /******************************************************************************
75 * CoInitialize32 [OLE32.26]
76 * Set the win32 IMalloc used for memorymanagement
78 HRESULT WINAPI CoInitialize32(
79 LPMALLOC32 lpReserved /* [in] pointer to win32 malloc interface */
81 /* FIXME: there really should be something here that incrememts a refcount
82 * but I'm supposing that it is a real COM object, so I won't bother
83 * creating one here. (Decrement done in CoUnitialize()) */
84 currentMalloc32 = lpReserved;
88 /***********************************************************************
89 * CoUnitialize [COMPOBJ.3]
90 * Don't know what it does.
91 * 3-Nov-98 -- this was originally misspelled, I changed it to what I
92 * believe is the correct spelling
94 void WINAPI CoUninitialize(void)
96 TRACE(ole,"(void)\n");
100 /***********************************************************************
101 * CoGetMalloc16 [COMPOBJ.4]
103 * The current win16 IMalloc
105 HRESULT WINAPI CoGetMalloc16(
106 DWORD dwMemContext, /* [in] unknown */
107 LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
110 currentMalloc16 = IMalloc16_Constructor();
111 *lpMalloc = currentMalloc16;
115 /******************************************************************************
116 * CoGetMalloc32 [OLE32.20]
119 * The current win32 IMalloc
121 HRESULT WINAPI CoGetMalloc32(
122 DWORD dwMemContext, /* [in] unknown */
123 LPMALLOC32 *lpMalloc /* [out] current win32 malloc interface */
126 currentMalloc32 = IMalloc32_Constructor();
127 *lpMalloc = currentMalloc32;
131 /***********************************************************************
132 * CoCreateStandardMalloc16 [COMPOBJ.71]
134 OLESTATUS WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
135 LPMALLOC16 *lpMalloc)
137 /* FIXME: docu says we shouldn't return the same allocator as in
139 *lpMalloc = IMalloc16_Constructor();
143 /******************************************************************************
144 * CoDisconnectObject [COMPOBJ.15]
146 OLESTATUS WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
148 TRACE(ole,"%p %lx\n",lpUnk,reserved);
152 /***********************************************************************
153 * IsEqualGUID [COMPOBJ.18]
154 * Compares two Unique Identifiers
158 BOOL16 WINAPI IsEqualGUID(
159 GUID* g1, /* [in] unique id 1 */
160 GUID* g2 /* [in] unique id 2 */
162 return !memcmp( g1, g2, sizeof(GUID) );
165 /******************************************************************************
166 * CLSIDFromString16 [COMPOBJ.20]
167 * Converts a unique identifier from it's string representation into
170 * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
175 OLESTATUS WINAPI CLSIDFromString16(
176 LPCOLESTR16 idstr, /* [in] string representation of guid */
177 CLSID *id /* [out] GUID converted from string */
179 BYTE *s = (BYTE *) idstr;
184 TRACE(ole,"%s -> %p\n", idstr, id);
186 /* quick lookup table */
187 memset(table, 0, 256);
189 for (i = 0; i < 10; i++) {
192 for (i = 0; i < 6; i++) {
193 table['A' + i] = i+10;
194 table['a' + i] = i+10;
197 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
199 if (strlen(idstr) != 38)
200 return OLE_ERROR_OBJECT;
204 s++; /* skip leading brace */
205 for (i = 0; i < 4; i++) {
206 p[3 - i] = table[*s]<<4 | table[*(s+1)];
212 for (i = 0; i < 2; i++) {
213 p[1-i] = table[*s]<<4 | table[*(s+1)];
219 for (i = 0; i < 2; i++) {
220 p[1-i] = table[*s]<<4 | table[*(s+1)];
226 /* these are just sequential bytes */
227 for (i = 0; i < 2; i++) {
228 *p++ = table[*s]<<4 | table[*(s+1)];
233 for (i = 0; i < 6; i++) {
234 *p++ = table[*s]<<4 | table[*(s+1)];
241 /******************************************************************************
242 * CoCreateGuid[OLE32.6]
243 * Just a random 128-bit number?
245 HRESULT WINAPI CoCreateGuid(GUID *pguid) {
246 FIXME(ole,"stub!\n");
250 /******************************************************************************
251 * CLSIDFromString32 [OLE32.3]
252 * Converts a unique identifier from it's string representation into
257 OLESTATUS WINAPI CLSIDFromString32(
258 LPCOLESTR32 idstr, /* [in] string representation of GUID */
259 CLSID *id /* [out] GUID represented by above string */
261 LPOLESTR16 xid = HEAP_strdupWtoA(GetProcessHeap(),0,idstr);
262 OLESTATUS ret = CLSIDFromString16(xid,id);
264 HeapFree(GetProcessHeap(),0,xid);
268 /******************************************************************************
269 * WINE_StringFromCLSID [???]
270 * Converts a GUID into the respective string representation.
273 * Why is this WINAPI?
276 * the string representation and OLESTATUS
278 OLESTATUS WINAPI WINE_StringFromCLSID(
279 const CLSID *id, /* [in] GUID to be converted */
280 LPSTR idstr /* [out] pointer to buffer to contain converted guid */
282 static const char *hex = "0123456789ABCDEF";
287 { ERR(ole,"called with id=Null\n");
292 sprintf(idstr, "{%08lx-%04x-%04x-%02x%02x-",
293 id->Data1, id->Data2, id->Data3,
294 id->Data4[0], id->Data4[1]);
298 for (i = 2; i < 8; i++) {
299 *s++ = hex[id->Data4[i]>>4];
300 *s++ = hex[id->Data4[i] & 0xf];
306 for (i = strlen(idstr)-1; i >= 0; i--) {
307 idstr[i] = toupper(idstr[i]);
310 TRACE(ole,"%p->%s\n", id, idstr);
315 /******************************************************************************
316 * StringFromCLSID16 [COMPOBJ.19]
317 * Converts a GUID into the respective string representation.
318 * The target string is allocated using the OLE IMalloc.
320 * the string representation and OLESTATUS
322 OLESTATUS WINAPI StringFromCLSID16(
323 const CLSID *id, /* [in] the GUID to be converted */
324 LPOLESTR16 *idstr /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
331 ret = CoGetMalloc16(0,&mllc);
334 args[0] = (DWORD)mllc;
337 /* No need for a Callback entry, we have WOWCallback16Ex which does
338 * everything we need.
340 if (!WOWCallback16Ex(
341 (FARPROC16)((LPMALLOC16_VTABLE)PTR_SEG_TO_LIN(
342 ((LPMALLOC16)PTR_SEG_TO_LIN(mllc))->lpvtbl)
349 WARN(ole,"CallTo16 IMalloc16 failed\n");
352 return WINE_StringFromCLSID(id,PTR_SEG_TO_LIN(*idstr));
355 /******************************************************************************
356 * StringFromCLSID32 [OLE32.151]
357 * Converts a GUID into the respective string representation.
358 * The target string is allocated using the OLE IMalloc.
360 * the string representation and OLESTATUS
362 OLESTATUS WINAPI StringFromCLSID32(
363 const CLSID *id, /* [in] the GUID to be converted */
364 LPOLESTR32 *idstr /* [out] a pointer to a to-be-allocated pointer pointing to the resulting string */
370 if ((ret=CoGetMalloc32(0,&mllc)))
373 ret=WINE_StringFromCLSID(id,buf);
375 *idstr = mllc->lpvtbl->fnAlloc(mllc,strlen(buf)*2+2);
376 lstrcpyAtoW(*idstr,buf);
381 /******************************************************************************
382 * StringFromGUID2 [COMPOBJ.76] [OLE32.152]
384 * Converts a global unique identifier into a string of an API-
385 * specified fixed format. (The usual {.....} stuff.)
388 * The (UNICODE) string representation of the GUID in 'str'
389 * The length of the resulting string, 0 if there was any problem.
392 StringFromGUID2(REFGUID id, LPOLESTR32 str, INT32 cmax)
396 if (WINE_StringFromCLSID(id,xguid))
398 if (strlen(xguid)>=cmax)
400 lstrcpyAtoW(str,xguid);
401 return strlen(xguid);
404 /******************************************************************************
405 * CLSIDFromProgID16 [COMPOBJ.61]
406 * Converts a program id into the respective GUID. (By using a registry lookup)
408 * riid associated with the progid
410 OLESTATUS WINAPI CLSIDFromProgID16(
411 LPCOLESTR16 progid, /* [in] program id as found in registry */
412 LPCLSID riid /* [out] associated CLSID */
419 buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
420 sprintf(buf,"%s\\CLSID",progid);
421 if ((err=RegOpenKey32A(HKEY_CLASSES_ROOT,buf,&xhkey))) {
422 HeapFree(GetProcessHeap(),0,buf);
423 return OLE_ERROR_GENERIC;
425 HeapFree(GetProcessHeap(),0,buf);
426 buf2len = sizeof(buf2);
427 if ((err=RegQueryValue32A(xhkey,NULL,buf2,&buf2len))) {
429 return OLE_ERROR_GENERIC;
432 return CLSIDFromString16(buf2,riid);
435 /******************************************************************************
436 * CLSIDFromProgID32 [OLE32.2]
437 * Converts a program id into the respective GUID. (By using a registry lookup)
439 * riid associated with the progid
441 OLESTATUS WINAPI CLSIDFromProgID32(
442 LPCOLESTR32 progid, /* [in] program id as found in registry */
443 LPCLSID riid /* [out] associated CLSID */
445 LPOLESTR16 pid = HEAP_strdupWtoA(GetProcessHeap(),0,progid);
446 OLESTATUS ret = CLSIDFromProgID16(pid,riid);
448 HeapFree(GetProcessHeap(),0,pid);
452 /***********************************************************************
453 * LookupETask (COMPOBJ.94)
455 OLESTATUS WINAPI LookupETask(HTASK16 *hTask,LPVOID p) {
456 FIXME(ole,"(%p,%p),stub!\n",hTask,p);
457 if ((*hTask = GetCurrentTask()) == hETask) {
458 memcpy(p, Table_ETask, sizeof(Table_ETask));
463 /***********************************************************************
464 * SetETask (COMPOBJ.95)
466 OLESTATUS WINAPI SetETask(HTASK16 hTask, LPVOID p) {
467 FIXME(ole,"(%04x,%p),stub!\n",hTask,p);
472 /***********************************************************************
473 * CallObjectInWOW (COMPOBJ.201)
475 OLESTATUS WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
476 FIXME(ole,"(%p,%p),stub!\n",p1,p2);
480 /******************************************************************************
481 * CoRegisterClassObject16 [COMPOBJ.5]
483 * Don't know where it registers it ...
485 OLESTATUS WINAPI CoRegisterClassObject16(
494 WINE_StringFromCLSID(rclsid,buf);
496 FIXME(ole,"(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
497 buf,pUnk,dwClsContext,flags,lpdwRegister
502 /******************************************************************************
503 * CoRegisterClassObject32 [OLE32.36]
505 * Don't know where it registers it ...
507 OLESTATUS WINAPI CoRegisterClassObject32(
516 WINE_StringFromCLSID(rclsid,buf);
518 FIXME(ole,"(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
519 buf,pUnk,dwClsContext,flags,lpdwRegister
524 /***********************************************************************
525 * CoGetClassObject [COMPOBJ.7]
527 HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext,
528 LPVOID pvReserved, REFIID iid, LPVOID *ppv)
530 char xclsid[50],xiid[50];
531 HRESULT hres = E_UNEXPECTED;
532 char dllName[MAX_PATH+1];
533 LONG dllNameLen = MAX_PATH+1;
534 HINSTANCE32 hLibrary;
535 typedef HRESULT (*DllGetClassObjectFunc)(REFCLSID clsid,
536 REFIID iid, LPVOID *ppv);
537 DllGetClassObjectFunc DllGetClassObject;
540 char buf[MAX_PATH + 1];
544 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
545 WINE_StringFromCLSID((LPCLSID)iid,xiid);
546 TRACE(ole,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid);
548 /* out of process and remote servers not supported yet */
549 if ((CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER) & dwClsContext) {
550 FIXME(ole, "CLSCTX_LOCAL_SERVER and CLSCTX_REMOTE_SERVER not supported!\n");
551 return E_ACCESSDENIED;
554 if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) {
556 /* lookup CLSID in registry key HKCR/CLSID */
557 hres = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, "CLSID", 0,
558 KEY_ENUMERATE_SUB_KEYS, &CLSIDkey);
560 if (hres != ERROR_SUCCESS) {
561 return REGDB_E_READREGDB;
564 /* search all the subkeys for a match to xclsid */
566 for (i=0; i<100000; i++) {
568 char clsidKeyPath[MAX_PATH + 1];
572 res = RegEnumKey32A(CLSIDkey, i, buf, MAX_PATH);
573 if (res == ERROR_NO_MORE_ITEMS)
575 if (res != ERROR_SUCCESS)
578 sprintf(clsidKeyPath, "CLSID\\%s", buf);
580 if (lstrcmpi32A(buf, xclsid) != 0)
583 res = RegOpenKeyEx32A(HKEY_CLASSES_ROOT, clsidKeyPath, 0,
584 KEY_QUERY_VALUE, &key);
585 if (res != ERROR_SUCCESS) {
586 return REGDB_E_READREGDB;
588 hres = RegQueryValue32A(key, "InprocServer32", dllName, &dllNameLen);
589 if (res != ERROR_SUCCESS) {
590 return REGDB_E_READREGDB;
592 TRACE(ole,"found InprocServer32 dll %s\n", dllName);
598 return REGDB_E_CLASSNOTREG;
602 /* open dll, call DllGetClassFactory */
603 hLibrary = CoLoadLibrary(dllName, TRUE);
607 TRACE(ole,"couldn't load InprocServer32 dll %s\n", dllName);
608 return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
611 DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress32(hLibrary, "DllGetClassObject");
612 if (DllGetClassObject == NULL) {
613 /* not sure if this should be called here CoFreeLibrary(hLibrary);*/
614 TRACE(ole,"couldn't find function DllGetClassObject in %s\n", dllName);
615 return E_ACCESSDENIED;
618 return DllGetClassObject(rclsid, iid, ppv);
624 /******************************************************************************
625 * CoRegisterMessageFilter16 [COMPOBJ.27]
627 OLESTATUS WINAPI CoRegisterMessageFilter16(
628 LPMESSAGEFILTER lpMessageFilter,
629 LPMESSAGEFILTER *lplpMessageFilter
631 FIXME(ole,"(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
635 /***********************************************************************
636 * CoCreateInstance [COMPOBJ.13, OLE32.7]
638 HRESULT WINAPI CoCreateInstance(
646 char buf[80],xbuf[80];
649 WINE_StringFromCLSID(rclsid,buf);
651 sprintf(buf,"<rclsid-0x%08lx>",(DWORD)rclsid);
653 WINE_StringFromCLSID(iid,xbuf);
655 sprintf(xbuf,"<iid-0x%08lx>",(DWORD)iid);
657 FIXME(ole,"(%s,%p,0x%08lx,%s,%p): stub !\n",buf,pUnkOuter,dwClsContext,xbuf,ppv);
661 LPCLASSFACTORY lpclf = 0;
663 hres = CoGetClassObject(rclsid, dwClsContext, NULL, &IID_IClassFactory, (LPVOID)&lpclf);
664 if (!SUCCEEDED(hres)) return hres;
665 hres = lpclf->lpvtbl->fnCreateInstance(lpclf, pUnkOuter, iid, ppv);
666 lpclf->lpvtbl->fnRelease(lpclf);
673 /***********************************************************************
674 * CoFreeLibrary [COMPOBJ.13]
676 void WINAPI CoFreeLibrary(HINSTANCE32 hLibrary)
681 /* lookup library in linked list */
683 for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
684 if (ptr->hLibrary == hLibrary) {
691 /* shouldn't happen if user passed in a valid hLibrary */
694 /* assert: ptr points to the library entry to free */
696 /* free library and remove node from list */
697 FreeLibrary32(hLibrary);
698 if (ptr == openDllList) {
699 tmp = openDllList->next;
700 HeapFree(GetProcessHeap(), 0, openDllList->DllName);
701 HeapFree(GetProcessHeap(), 0, openDllList);
705 HeapFree(GetProcessHeap(), 0, ptr->DllName);
706 HeapFree(GetProcessHeap(), 0, ptr);
713 /***********************************************************************
714 * CoFreeAllLibraries [COMPOBJ.12]
716 void WINAPI CoFreeAllLibraries(void)
720 for (ptr = openDllList; ptr != NULL; ) {
722 CoFreeLibrary(ptr->hLibrary);
729 /***********************************************************************
730 * CoFreeUnusedLibraries [COMPOBJ.17]
732 void WINAPI CoFreeUnusedLibraries(void)
735 typedef HRESULT(*DllCanUnloadNowFunc)(void);
736 DllCanUnloadNowFunc DllCanUnloadNow;
738 for (ptr = openDllList; ptr != NULL; ) {
739 DllCanUnloadNow = (DllCanUnloadNowFunc)
740 GetProcAddress32(ptr->hLibrary, "DllCanUnloadNow");
742 if (DllCanUnloadNow() == S_OK) {
744 CoFreeLibrary(ptr->hLibrary);
752 /***********************************************************************
753 * CoFileTimeNow [COMPOBJ.82, OLE32.10]
755 * the current system time in lpFileTime
757 HRESULT WINAPI CoFileTimeNow(
758 FILETIME *lpFileTime /* [out] the current time */
760 DOSFS_UnixTimeToFileTime(time(NULL), lpFileTime, 0);
764 /***********************************************************************
765 * CoTaskMemAlloc (OLE32.43)
767 * pointer to newly allocated block
769 LPVOID WINAPI CoTaskMemAlloc(
770 ULONG size /* [in] size of memoryblock to be allocated */
773 HRESULT ret = CoGetMalloc32(0,&lpmalloc);
777 return lpmalloc->lpvtbl->fnAlloc(lpmalloc,size);
780 /***********************************************************************
781 * CoTaskMemFree (OLE32.44)
783 VOID WINAPI CoTaskMemFree(
784 LPVOID ptr /* [in] pointer to be freed */
787 HRESULT ret = CoGetMalloc32(0,&lpmalloc);
790 return lpmalloc->lpvtbl->fnFree(lpmalloc,ptr);
793 /***********************************************************************
794 * CoLoadLibrary (OLE32.30)
796 HINSTANCE32 WINAPI CoLoadLibrary(LPSTR lpszLibName, BOOL32 bAutoFree)
798 HINSTANCE32 hLibrary;
802 TRACE(ole,"CoLoadLibrary(%p, %d\n", lpszLibName, bAutoFree);
804 hLibrary = LoadLibrary32A(lpszLibName);
809 if (openDllList == NULL) {
810 /* empty list -- add first node */
811 openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
812 openDllList->DllName = HEAP_strdupA(GetProcessHeap(), 0, lpszLibName);
813 openDllList->hLibrary = hLibrary;
814 openDllList->next = NULL;
816 /* search for this dll */
818 for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) {
819 if (ptr->hLibrary == hLibrary) {
825 /* dll not found, add it */
828 (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
829 openDllList->DllName = HEAP_strdupA(GetProcessHeap(), 0, lpszLibName);
830 openDllList->hLibrary = hLibrary;
831 openDllList->next = tmp;
838 /***********************************************************************
839 * CoInitializeWOW (OLE32.27)
841 HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
842 FIXME(ole,"(0x%08lx,0x%08lx),stub!\n",x,y);
846 /******************************************************************************
847 * CoLockObjectExternal16 [COMPOBJ.63]
849 HRESULT WINAPI CoLockObjectExternal16(
850 LPUNKNOWN pUnk, /* [in] object to be locked */
851 BOOL16 fLock, /* [in] do lock */
852 BOOL16 fLastUnlockReleases /* [in] ? */
854 FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
858 /******************************************************************************
859 * CoLockObjectExternal32 [OLE32.31]
861 HRESULT WINAPI CoLockObjectExternal32(
862 LPUNKNOWN pUnk, /* [in] object to be locked */
863 BOOL32 fLock, /* [in] do lock */
864 BOOL32 fLastUnlockReleases /* [in] ? */
866 FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
870 /***********************************************************************
871 * CoGetState16 [COMPOBJ.115]
873 HRESULT WINAPI CoGetState16(LPDWORD state)
875 FIXME(ole, "(%p),stub!\n", state);
879 /***********************************************************************
880 * CoSetState32 [COM32.42]
882 HRESULT WINAPI CoSetState32(LPDWORD state)
884 FIXME(ole, "(%p),stub!\n", state);