Release 980927
[wine.git] / ole / compobj.c
blobcf85b720b91e8dc499c8a2b0c572e275440ace43
1 /*
2 * COMPOBJ library
4 * Copyright 1995 Martin von Loewis
5 */
7 #define INITGUID
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13 #include "ole.h"
14 #include "ole2.h"
15 #include "winerror.h"
16 #include "debug.h"
17 #include "file.h"
18 #include "compobj.h"
19 #include "heap.h"
20 #include "ldt.h"
21 #include "interfaces.h"
22 #include "shlobj.h"
23 #include "ddraw.h"
24 #include "dsound.h"
25 #include "dinput.h"
26 #include "d3d.h"
27 #include "dplay.h"
30 LPMALLOC16 currentMalloc16=NULL;
31 LPMALLOC32 currentMalloc32=NULL;
33 HTASK16 hETask = 0;
34 WORD Table_ETask[62];
36 /***********************************************************************
37 * CoBuildVersion [COMPOBJ.1]
39 * RETURNS
40 * Current built version, hiword is majornumber, loword is minornumber
42 DWORD WINAPI CoBuildVersion()
44 TRACE(ole,"(void)\n");
45 return (rmm<<16)+rup;
48 /***********************************************************************
49 * CoInitialize [COMPOBJ.2]
50 * Set the win16 IMalloc used for memory management
52 HRESULT WINAPI CoInitialize16(
53 LPMALLOC16 lpReserved /* [in] pointer to win16 malloc interface */
54 ) {
55 currentMalloc16 = lpReserved;
56 return S_OK;
59 /***********************************************************************
60 * CoInitialize (OLE32.26)
61 * Set the win32 IMalloc used for memorymanagement
63 HRESULT WINAPI CoInitialize32(
64 LPMALLOC32 lpReserved /* [in] pointer to win32 malloc interface */
65 ) {
66 currentMalloc32 = lpReserved;
67 return S_OK;
70 /***********************************************************************
71 * CoUnitialize [COMPOBJ.3]
72 * Don't know what it does.
74 void WINAPI CoUnitialize()
76 TRACE(ole,"(void)\n");
79 /***********************************************************************
80 * CoGetMalloc16 [COMPOBJ.4]
81 * RETURNS
82 * The current win16 IMalloc
84 HRESULT WINAPI CoGetMalloc16(
85 DWORD dwMemContext, /* [in] unknown */
86 LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
87 ) {
88 if(!currentMalloc16)
89 currentMalloc16 = IMalloc16_Constructor();
90 *lpMalloc = currentMalloc16;
91 return S_OK;
94 /***********************************************************************
95 * CoGetMalloc32 [OLE32.4]
96 * RETURNS
97 * The current win32 IMalloc
99 HRESULT WINAPI CoGetMalloc32(
100 DWORD dwMemContext, /* [in] unknown */
101 LPMALLOC32 *lpMalloc /* [out] current win32 malloc interface */
103 if(!currentMalloc32)
104 currentMalloc32 = IMalloc32_Constructor();
105 *lpMalloc = currentMalloc32;
106 return S_OK;
109 /***********************************************************************
110 * CoCreateStandardMalloc16 [COMPOBJ.71]
112 OLESTATUS WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
113 LPMALLOC16 *lpMalloc)
115 /* FIXME: docu says we shouldn't return the same allocator as in
116 * CoGetMalloc16 */
117 *lpMalloc = IMalloc16_Constructor();
118 return S_OK;
121 /***********************************************************************
122 * CoDisconnectObject
124 OLESTATUS WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
126 TRACE(ole,"%p %lx\n",lpUnk,reserved);
127 return S_OK;
130 /***********************************************************************
131 * IsEqualGUID [COMPOBJ.18]
132 * Compares two Unique Identifiers
133 * RETURNS
134 * TRUE if equal
136 BOOL16 WINAPI IsEqualGUID(
137 GUID* g1, /* [in] unique id 1 */
138 GUID* g2 /* [in] unique id 2 */
140 return !memcmp( g1, g2, sizeof(GUID) );
143 /***********************************************************************
144 * CLSIDFromString [COMPOBJ.20]
145 * Converts a unique identifier from it's string representation into
146 * the GUID struct.
147 * RETURNS
148 * the converted GUID
151 /* Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6] */
153 OLESTATUS WINAPI CLSIDFromString16(
154 LPCOLESTR16 idstr, /* [in] string representation of guid */
155 CLSID *id /* [out] GUID converted from string */
157 BYTE *s = (BYTE *) idstr;
158 BYTE *p;
159 int i;
160 BYTE table[256];
162 TRACE(ole,"%s -> %p\n", idstr, id);
164 /* quick lookup table */
165 memset(table, 0, 256);
167 for (i = 0; i < 10; i++) {
168 table['0' + i] = i;
170 for (i = 0; i < 6; i++) {
171 table['A' + i] = i+10;
172 table['a' + i] = i+10;
175 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
177 if (strlen(idstr) != 38)
178 return OLE_ERROR_OBJECT;
180 p = (BYTE *) id;
182 s++; /* skip leading brace */
183 for (i = 0; i < 4; i++) {
184 p[3 - i] = table[*s]<<4 | table[*(s+1)];
185 s += 2;
187 p += 4;
188 s++; /* skip - */
190 for (i = 0; i < 2; i++) {
191 p[1-i] = table[*s]<<4 | table[*(s+1)];
192 s += 2;
194 p += 2;
195 s++; /* skip - */
197 for (i = 0; i < 2; i++) {
198 p[1-i] = table[*s]<<4 | table[*(s+1)];
199 s += 2;
201 p += 2;
202 s++; /* skip - */
204 /* these are just sequential bytes */
205 for (i = 0; i < 2; i++) {
206 *p++ = table[*s]<<4 | table[*(s+1)];
207 s += 2;
209 s++; /* skip - */
211 for (i = 0; i < 6; i++) {
212 *p++ = table[*s]<<4 | table[*(s+1)];
213 s += 2;
216 return S_OK;
219 /***********************************************************************
220 * CLSIDFromString (OLE32.3)
221 * Converts a unique identifier from it's string representation into
222 * the GUID struct.
223 * RETURNS
224 * the converted GUID
226 OLESTATUS WINAPI CLSIDFromString32(
227 LPCOLESTR32 idstr, /* [in] string representation of GUID */
228 CLSID *id /* [out] GUID represented by above string */
230 LPOLESTR16 xid = HEAP_strdupWtoA(GetProcessHeap(),0,idstr);
231 OLESTATUS ret = CLSIDFromString16(xid,id);
233 HeapFree(GetProcessHeap(),0,xid);
234 return ret;
237 /***********************************************************************
238 * WINE_StringFromCLSID [internal]
239 * Converts a GUID into the respective string representation.
240 * RETURNS
241 * the string representation and OLESTATUS
243 OLESTATUS WINAPI WINE_StringFromCLSID(
244 const CLSID *id, /* [in] GUID to be converted */
245 LPSTR idstr /* [out] pointer to buffer to contain converted guid */
247 static const char *hex = "0123456789ABCDEF";
248 char *s;
249 int i;
251 if (!id)
252 { ERR(ole,"called with id=Null\n");
253 *idstr = 0x00;
254 return E_FAIL;
257 sprintf(idstr, "{%08lx-%04x-%04x-%02x%02x-",
258 id->Data1, id->Data2, id->Data3,
259 id->Data4[0], id->Data4[1]);
260 s = &idstr[25];
262 /* 6 hex bytes */
263 for (i = 2; i < 8; i++) {
264 *s++ = hex[id->Data4[i]>>4];
265 *s++ = hex[id->Data4[i] & 0xf];
268 *s++ = '}';
269 *s++ = '\0';
271 for (i = strlen(idstr)-1; i >= 0; i--) {
272 idstr[i] = toupper(idstr[i]);
275 TRACE(ole,"%p->%s\n", id, idstr);
277 return OLE_OK;
280 /***********************************************************************
281 * StringFromCLSID [COMPOBJ.19]
282 * Converts a GUID into the respective string representation.
283 * The target string is allocated using the OLE IMalloc.
284 * RETURNS
285 * the string representation and OLESTATUS
287 OLESTATUS WINAPI StringFromCLSID16(
288 const CLSID *id, /* [in] the GUID to be converted */
289 LPOLESTR16 *idstr /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
292 LPMALLOC16 mllc;
293 OLESTATUS ret;
294 DWORD args[2];
296 ret = CoGetMalloc16(0,&mllc);
297 if (ret) return ret;
299 args[0] = (DWORD)mllc;
300 args[1] = 40;
302 /* No need for a Callback entry, we have WOWCallback16Ex which does
303 * everything we need.
305 if (!WOWCallback16Ex(
306 (FARPROC16)((LPMALLOC16_VTABLE)PTR_SEG_TO_LIN(
307 ((LPMALLOC16)PTR_SEG_TO_LIN(mllc))->lpvtbl)
308 )->fnAlloc,
309 WCB16_CDECL,
311 (LPVOID)args,
312 (LPDWORD)idstr
313 )) {
314 WARN(ole,"CallTo16 IMalloc16 failed\n");
315 return E_FAIL;
317 return WINE_StringFromCLSID(id,PTR_SEG_TO_LIN(*idstr));
320 /***********************************************************************
321 * StringFromCLSID [OLE32.151]
322 * Converts a GUID into the respective string representation.
323 * The target string is allocated using the OLE IMalloc.
324 * RETURNS
325 * the string representation and OLESTATUS
327 OLESTATUS WINAPI StringFromCLSID32(
328 const CLSID *id, /* [in] the GUID to be converted */
329 LPOLESTR32 *idstr /* [out] a pointer to a to-be-allocated pointer pointing to the resulting string */
331 char buf[80];
332 OLESTATUS ret;
333 LPMALLOC32 mllc;
335 if ((ret=CoGetMalloc32(0,&mllc)))
336 return ret;
338 ret=WINE_StringFromCLSID(id,buf);
339 if (!ret) {
340 *idstr = mllc->lpvtbl->fnAlloc(mllc,strlen(buf)*2+2);
341 lstrcpyAtoW(*idstr,buf);
343 return ret;
346 /***********************************************************************
347 * StringFromGUID2 (OLE32.152)
349 * Converts a global unique identifier into a string of an API-
350 * specified fixed format. (The usual {.....} stuff.)
352 * RETURNS
353 * The (UNICODE) string representation of the GUID in 'str'
354 * The length of the resulting string, 0 if there was any problem.
356 INT32 WINAPI
357 StringFromGUID2(REFGUID id, LPOLESTR32 str, INT32 cmax)
359 char xguid[80];
361 if (WINE_StringFromCLSID(id,xguid))
362 return 0;
363 if (strlen(xguid)>=cmax)
364 return 0;
365 lstrcpyAtoW(str,xguid);
366 return strlen(xguid);
369 /***********************************************************************
370 * CLSIDFromProgID [COMPOBJ.61]
371 * Converts a program id into the respective GUID. (By using a registry lookup)
372 * RETURNS
373 * riid associated with the progid
375 OLESTATUS WINAPI CLSIDFromProgID16(
376 LPCOLESTR16 progid, /* [in] program id as found in registry */
377 LPCLSID riid /* [out] associated CLSID */
379 char *buf,buf2[80];
380 DWORD buf2len;
381 HRESULT err;
382 HKEY xhkey;
384 buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
385 sprintf(buf,"%s\\CLSID",progid);
386 if ((err=RegOpenKey32A(HKEY_CLASSES_ROOT,buf,&xhkey))) {
387 HeapFree(GetProcessHeap(),0,buf);
388 return OLE_ERROR_GENERIC;
390 HeapFree(GetProcessHeap(),0,buf);
391 buf2len = sizeof(buf2);
392 if ((err=RegQueryValue32A(xhkey,NULL,buf2,&buf2len))) {
393 RegCloseKey(xhkey);
394 return OLE_ERROR_GENERIC;
396 RegCloseKey(xhkey);
397 return CLSIDFromString16(buf2,riid);
400 /***********************************************************************
401 * CLSIDFromProgID (OLE32.2)
402 * Converts a program id into the respective GUID. (By using a registry lookup)
403 * RETURNS
404 * riid associated with the progid
406 OLESTATUS WINAPI CLSIDFromProgID32(
407 LPCOLESTR32 progid, /* [in] program id as found in registry */
408 LPCLSID riid /* [out] associated CLSID */
410 LPOLESTR16 pid = HEAP_strdupWtoA(GetProcessHeap(),0,progid);
411 OLESTATUS ret = CLSIDFromProgID16(pid,riid);
413 HeapFree(GetProcessHeap(),0,pid);
414 return ret;
417 /***********************************************************************
418 * LookupETask (COMPOBJ.94)
420 OLESTATUS WINAPI LookupETask(HTASK16 *hTask,LPVOID p) {
421 FIXME(ole,"(%p,%p),stub!\n",hTask,p);
422 if ((*hTask = GetCurrentTask()) == hETask) {
423 memcpy(p, Table_ETask, sizeof(Table_ETask));
425 return 0;
428 /***********************************************************************
429 * SetETask (COMPOBJ.95)
431 OLESTATUS WINAPI SetETask(HTASK16 hTask, LPVOID p) {
432 FIXME(ole,"(%04x,%p),stub!\n",hTask,p);
433 hETask = hTask;
434 return 0;
437 /***********************************************************************
438 * CallObjectInWOW (COMPOBJ.201)
440 OLESTATUS WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
441 FIXME(ole,"(%p,%p),stub!\n",p1,p2);
442 return 0;
445 /***********************************************************************
446 * CoRegisterClassObject [COMPOBJ.5]
447 * Don't know where it registers it ...
449 OLESTATUS WINAPI CoRegisterClassObject16(
450 REFCLSID rclsid,
451 LPUNKNOWN pUnk,
452 DWORD dwClsContext,
453 DWORD flags,
454 LPDWORD lpdwRegister
456 char buf[80];
458 WINE_StringFromCLSID(rclsid,buf);
460 FIXME(ole,"(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
461 buf,pUnk,dwClsContext,flags,lpdwRegister
463 return 0;
466 /***********************************************************************
467 * CoRegisterClassObject (OLE32.36)
468 * Don't know where it registers it ...
470 OLESTATUS WINAPI CoRegisterClassObject32(
471 REFCLSID rclsid,
472 LPUNKNOWN pUnk,
473 DWORD dwClsContext,
474 DWORD flags,
475 LPDWORD lpdwRegister
477 char buf[80];
479 WINE_StringFromCLSID(rclsid,buf);
481 FIXME(ole,"(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
482 buf,pUnk,dwClsContext,flags,lpdwRegister
484 return 0;
487 /***********************************************************************
488 * CoGetClassObject [COMPOBJ.7]
490 HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext,
491 LPVOID pvReserved, REFIID iid, LPVOID *ppv)
493 char xclsid[50],xiid[50];
494 LPCLASSFACTORY lpclf;
495 HRESULT hres = E_UNEXPECTED;
497 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
498 WINE_StringFromCLSID((LPCLSID)iid,xiid);
499 TRACE(ole,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid);
501 *ppv = NULL;
502 lpclf = IClassFactory_Constructor();
503 if (lpclf)
505 hres = lpclf->lpvtbl->fnQueryInterface(lpclf,iid, ppv);
506 lpclf->lpvtbl->fnRelease(lpclf);
508 return hres;
511 /***********************************************************************
512 * CoRegisterMessageFilter [COMPOBJ.27]
514 OLESTATUS WINAPI CoRegisterMessageFilter16(
515 LPMESSAGEFILTER lpMessageFilter,
516 LPMESSAGEFILTER *lplpMessageFilter
518 FIXME(ole,"(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
519 return 0;
522 /***********************************************************************
523 * CoCreateInstance [COMPOBJ.13, OLE32.7]
525 HRESULT WINAPI CoCreateInstance(
526 REFCLSID rclsid,
527 LPUNKNOWN pUnkOuter,
528 DWORD dwClsContext,
529 REFIID iid,
530 LPVOID *ppv
532 #if 0
533 char buf[80],xbuf[80];
535 if (rclsid)
536 WINE_StringFromCLSID(rclsid,buf);
537 else
538 sprintf(buf,"<rclsid-0x%08lx>",(DWORD)rclsid);
539 if (iid)
540 WINE_StringFromCLSID(iid,xbuf);
541 else
542 sprintf(xbuf,"<iid-0x%08lx>",(DWORD)iid);
544 FIXME(ole,"(%s,%p,0x%08lx,%s,%p): stub !\n",buf,pUnkOuter,dwClsContext,xbuf,ppv);
545 *ppv = NULL;
546 #else
547 HRESULT hres;
548 LPCLASSFACTORY lpclf = 0;
550 CoGetClassObject(rclsid, dwClsContext, NULL, &IID_IClassFactory, (LPVOID)&lpclf);
551 hres = lpclf->lpvtbl->fnCreateInstance(lpclf, pUnkOuter, iid, ppv);
552 lpclf->lpvtbl->fnRelease(lpclf);
553 return hres;
554 #endif
557 /***********************************************************************
558 * CoFreeUnusedLibraries [COMPOBJ.17]
560 void WINAPI CoFreeUnusedLibraries()
562 FIXME(ole,"(), stub !\n");
565 /***********************************************************************
566 * CoFileTimeNow [COMPOBJ.82, OLE32.10]
567 * RETURNS
568 * the current system time in lpFileTime
570 HRESULT WINAPI CoFileTimeNow(
571 FILETIME *lpFileTime /* [out] the current time */
573 DOSFS_UnixTimeToFileTime(time(NULL), lpFileTime, 0);
574 return S_OK;
577 /***********************************************************************
578 * CoTaskMemAlloc (OLE32.43)
579 * RETURNS
580 * pointer to newly allocated block
582 LPVOID WINAPI CoTaskMemAlloc(
583 ULONG size /* [in] size of memoryblock to be allocated */
585 LPMALLOC32 lpmalloc;
586 HRESULT ret = CoGetMalloc32(0,&lpmalloc);
588 if (ret)
589 return NULL;
590 return lpmalloc->lpvtbl->fnAlloc(lpmalloc,size);
593 /***********************************************************************
594 * CoTaskMemFree (OLE32.44)
596 VOID WINAPI CoTaskMemFree(
597 LPVOID ptr /* [in] pointer to be freed */
599 LPMALLOC32 lpmalloc;
600 HRESULT ret = CoGetMalloc32(0,&lpmalloc);
602 if (ret) return;
603 return lpmalloc->lpvtbl->fnFree(lpmalloc,ptr);
606 /***********************************************************************
607 * CoInitializeWOW (OLE32.27)
609 HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
610 FIXME(ole,"(0x%08lx,0x%08lx),stub!\n",x,y);
611 return 0;
614 /***********************************************************************
615 * CoLockObjectExternal (COMPOBJ.63)
617 HRESULT WINAPI CoLockObjectExternal16(
618 LPUNKNOWN pUnk, /* [in] object to be locked */
619 BOOL16 fLock, /* [in] do lock */
620 BOOL16 fLastUnlockReleases /* [in] ? */
622 FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
623 return S_OK;
625 /***********************************************************************
626 * CoLockObjectExternal (OLE32.31)
628 HRESULT WINAPI CoLockObjectExternal32(
629 LPUNKNOWN pUnk, /* [in] object to be locked */
630 BOOL32 fLock, /* [in] do lock */
631 BOOL32 fLastUnlockReleases /* [in] ? */
633 FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
634 return S_OK;
637 /***********************************************************************
638 * CoGetState16 [COMPOBJ.115]
640 HRESULT WINAPI CoGetState16(LPDWORD state)
642 FIXME(ole, "(%p),stub!\n", state);
643 *state = 0;
644 return S_OK;