comctl32/tests: Make test_combo_WS_VSCROLL() static.
[wine.git] / dlls / compobj.dll16 / compobj.c
blobaf69bf8bc4836e5ccf3896533869a827ff562493
1 /*
2 * 16 bit ole functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1998 Justin Bradford
6 * Copyright 1999 Francis Beaudet
7 * Copyright 1999 Sylvain St-Germain
8 * Copyright 2002 Marcus Meissner
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "config.h"
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "objbase.h"
37 #include "ole2.h"
38 #include "rpc.h"
39 #include "winerror.h"
40 #include "winreg.h"
41 #include "wownt32.h"
42 #include "wtypes.h"
43 #include "wine/unicode.h"
44 #include "wine/winbase16.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 typedef LPSTR LPOLESTR16;
51 typedef LPCSTR LPCOLESTR16;
53 #define STDMETHOD16CALLTYPE __cdecl
54 #define STDMETHOD16(m) HRESULT (STDMETHOD16CALLTYPE *m)
55 #define STDMETHOD16_(t,m) t (STDMETHOD16CALLTYPE *m)
57 #define CHARS_IN_GUID 39
59 /***********************************************************************
60 * IMalloc16 interface
63 typedef struct IMalloc16 *LPMALLOC16;
65 #define INTERFACE IMalloc16
66 DECLARE_INTERFACE_(IMalloc16,IUnknown)
68 /*** IUnknown methods ***/
69 STDMETHOD16_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
70 STDMETHOD16_(ULONG,AddRef)(THIS) PURE;
71 STDMETHOD16_(ULONG,Release)(THIS) PURE;
72 /*** IMalloc16 methods ***/
73 STDMETHOD16_(LPVOID,Alloc)(THIS_ DWORD cb) PURE;
74 STDMETHOD16_(LPVOID,Realloc)(THIS_ LPVOID pv, DWORD cb) PURE;
75 STDMETHOD16_(void,Free)(THIS_ LPVOID pv) PURE;
76 STDMETHOD16_(DWORD,GetSize)(THIS_ LPVOID pv) PURE;
77 STDMETHOD16_(INT16,DidAlloc)(THIS_ LPVOID pv) PURE;
78 STDMETHOD16_(LPVOID,HeapMinimize)(THIS) PURE;
80 #undef INTERFACE
82 static HTASK16 hETask = 0;
83 static WORD Table_ETask[62];
85 static LPMALLOC16 currentMalloc16=NULL;
87 /* --- IMalloc16 implementation */
90 typedef struct
92 IMalloc16 IMalloc16_iface;
93 DWORD ref;
94 } IMalloc16Impl;
96 static inline IMalloc16Impl *impl_from_IMalloc16(IMalloc16 *iface)
98 return CONTAINING_RECORD(iface, IMalloc16Impl, IMalloc16_iface);
101 /******************************************************************************
102 * IMalloc16_QueryInterface [COMPOBJ.500]
104 HRESULT CDECL IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
105 IMalloc16Impl *This = impl_from_IMalloc16(iface);
107 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
108 if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
109 !memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
111 *obj = This;
112 return 0;
114 return OLE_E_ENUM_NOMORE;
117 /******************************************************************************
118 * IMalloc16_AddRef [COMPOBJ.501]
120 ULONG CDECL IMalloc16_fnAddRef(IMalloc16* iface) {
121 IMalloc16Impl *This = impl_from_IMalloc16(iface);
123 TRACE("(%p)->AddRef()\n",This);
124 return 1; /* cannot be freed */
127 /******************************************************************************
128 * IMalloc16_Release [COMPOBJ.502]
130 ULONG CDECL IMalloc16_fnRelease(IMalloc16* iface) {
131 IMalloc16Impl *This = impl_from_IMalloc16(iface);
133 TRACE("(%p)->Release()\n",This);
134 return 1; /* cannot be freed */
137 /******************************************************************************
138 * IMalloc16_Alloc [COMPOBJ.503]
140 SEGPTR CDECL IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
141 IMalloc16Impl *This = impl_from_IMalloc16(iface);
143 TRACE("(%p)->Alloc(%d)\n",This,cb);
144 return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
147 /******************************************************************************
148 * IMalloc16_Free [COMPOBJ.505]
150 VOID CDECL IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
152 void *ptr = MapSL(pv);
153 IMalloc16Impl *This = impl_from_IMalloc16(iface);
154 TRACE("(%p)->Free(%08x)\n",This,pv);
155 UnMapLS(pv);
156 HeapFree( GetProcessHeap(), 0, ptr );
159 /******************************************************************************
160 * IMalloc16_Realloc [COMPOBJ.504]
162 SEGPTR CDECL IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
164 SEGPTR ret;
165 IMalloc16Impl *This = impl_from_IMalloc16(iface);
167 TRACE("(%p)->Realloc(%08x,%d)\n",This,pv,cb);
168 if (!pv)
169 ret = IMalloc16_fnAlloc(iface, cb);
170 else if (cb) {
171 ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
172 UnMapLS(pv);
173 } else {
174 IMalloc16_fnFree(iface, pv);
175 ret = 0;
177 return ret;
180 /******************************************************************************
181 * IMalloc16_GetSize [COMPOBJ.506]
183 DWORD CDECL IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
185 IMalloc16Impl *This = impl_from_IMalloc16(iface);
187 TRACE("(%p)->GetSize(%08x)\n",This,pv);
188 return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
191 /******************************************************************************
192 * IMalloc16_DidAlloc [COMPOBJ.507]
194 INT16 CDECL IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
195 IMalloc16Impl *This = impl_from_IMalloc16(iface);
197 TRACE("(%p)->DidAlloc(%p)\n",This,pv);
198 return (INT16)-1;
201 /******************************************************************************
202 * IMalloc16_HeapMinimize [COMPOBJ.508]
204 LPVOID CDECL IMalloc16_fnHeapMinimize(IMalloc16* iface) {
205 IMalloc16Impl *This = impl_from_IMalloc16(iface);
207 TRACE("(%p)->HeapMinimize()\n",This);
208 return NULL;
211 /******************************************************************************
212 * IMalloc16_Constructor [VTABLE]
214 static LPMALLOC16
215 IMalloc16_Constructor(void)
217 static IMalloc16Vtbl vt16;
218 static SEGPTR msegvt16;
219 IMalloc16Impl* This;
220 HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
222 This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
223 if (!msegvt16)
225 #define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
226 VTENT(QueryInterface);
227 VTENT(AddRef);
228 VTENT(Release);
229 VTENT(Alloc);
230 VTENT(Realloc);
231 VTENT(Free);
232 VTENT(GetSize);
233 VTENT(DidAlloc);
234 VTENT(HeapMinimize);
235 #undef VTENT
236 msegvt16 = MapLS( &vt16 );
238 This->IMalloc16_iface.lpVtbl = (const IMalloc16Vtbl*)msegvt16;
239 This->ref = 1;
240 return (LPMALLOC16)MapLS( This );
244 /******************************************************************************
245 * CoBuildVersion [COMPOBJ.1]
247 DWORD WINAPI CoBuildVersion16(void)
249 return CoBuildVersion();
252 /***********************************************************************
253 * CoGetMalloc [COMPOBJ.4]
255 * Retrieve the current win16 IMalloc interface.
257 * RETURNS
258 * The current win16 IMalloc
260 HRESULT WINAPI CoGetMalloc16(
261 DWORD dwMemContext, /* [in] unknown */
262 LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
264 if(!currentMalloc16)
265 currentMalloc16 = IMalloc16_Constructor();
266 *lpMalloc = currentMalloc16;
267 return S_OK;
270 /***********************************************************************
271 * CoCreateStandardMalloc [COMPOBJ.71]
273 HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
274 LPMALLOC16 *lpMalloc)
276 /* FIXME: docu says we shouldn't return the same allocator as in
277 * CoGetMalloc16 */
278 *lpMalloc = IMalloc16_Constructor();
279 return S_OK;
282 /******************************************************************************
283 * CoInitialize [COMPOBJ.2]
284 * Set the win16 IMalloc used for memory management
286 HRESULT WINAPI CoInitialize16(
287 LPVOID lpReserved /* [in] pointer to win16 malloc interface */
289 currentMalloc16 = (LPMALLOC16)lpReserved;
290 return S_OK;
293 /***********************************************************************
294 * CoUninitialize [COMPOBJ.3]
295 * Don't know what it does.
296 * 3-Nov-98 -- this was originally misspelled, I changed it to what I
297 * believe is the correct spelling
299 void WINAPI CoUninitialize16(void)
301 TRACE("()\n");
302 CoFreeAllLibraries();
305 /***********************************************************************
306 * CoFreeUnusedLibraries [COMPOBJ.17]
308 void WINAPI CoFreeUnusedLibraries16(void)
310 CoFreeUnusedLibraries();
313 /***********************************************************************
314 * IsEqualGUID [COMPOBJ.18]
316 * Compares two Unique Identifiers.
318 * RETURNS
319 * TRUE if equal
321 BOOL16 WINAPI IsEqualGUID16(
322 GUID* g1, /* [in] unique id 1 */
323 GUID* g2) /* [in] unique id 2 */
325 return !memcmp( g1, g2, sizeof(GUID) );
328 /******************************************************************************
329 * CLSIDFromString [COMPOBJ.20]
330 * Converts a unique identifier from its string representation into
331 * the GUID struct.
333 * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
335 * RETURNS
336 * the converted GUID
338 HRESULT WINAPI CLSIDFromString16(
339 LPCOLESTR16 idstr, /* [in] string representation of guid */
340 CLSID *id) /* [out] GUID converted from string */
342 const BYTE *s;
343 int i;
344 BYTE table[256];
346 if (!idstr) {
347 memset( id, 0, sizeof (CLSID) );
348 return S_OK;
351 /* validate the CLSID string */
352 if (strlen(idstr) != 38)
353 return CO_E_CLASSSTRING;
355 s = (const BYTE *) idstr;
356 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
357 return CO_E_CLASSSTRING;
359 for (i=1; i<37; i++) {
360 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
361 if (!(((s[i] >= '0') && (s[i] <= '9')) ||
362 ((s[i] >= 'a') && (s[i] <= 'f')) ||
363 ((s[i] >= 'A') && (s[i] <= 'F'))))
364 return CO_E_CLASSSTRING;
367 TRACE("%s -> %p\n", s, id);
369 /* quick lookup table */
370 memset(table, 0, 256);
372 for (i = 0; i < 10; i++) {
373 table['0' + i] = i;
375 for (i = 0; i < 6; i++) {
376 table['A' + i] = i+10;
377 table['a' + i] = i+10;
380 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
382 id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
383 table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] << 4 | table[s[8]]);
384 id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
385 id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
387 /* these are just sequential bytes */
388 id->Data4[0] = table[s[20]] << 4 | table[s[21]];
389 id->Data4[1] = table[s[22]] << 4 | table[s[23]];
390 id->Data4[2] = table[s[25]] << 4 | table[s[26]];
391 id->Data4[3] = table[s[27]] << 4 | table[s[28]];
392 id->Data4[4] = table[s[29]] << 4 | table[s[30]];
393 id->Data4[5] = table[s[31]] << 4 | table[s[32]];
394 id->Data4[6] = table[s[33]] << 4 | table[s[34]];
395 id->Data4[7] = table[s[35]] << 4 | table[s[36]];
397 return S_OK;
400 /******************************************************************************
401 * _xmalloc16 [internal]
402 * Allocates size bytes from the standard ole16 allocator.
404 * RETURNS
405 * the allocated segmented pointer and a HRESULT
407 static HRESULT
408 _xmalloc16(DWORD size, SEGPTR *ptr) {
409 LPMALLOC16 mllc;
410 DWORD args[2];
412 if (CoGetMalloc16(0,&mllc))
413 return E_OUTOFMEMORY;
415 args[0] = (DWORD)mllc;
416 args[1] = size;
417 /* No need for a Callback entry, we have WOWCallback16Ex which does
418 * everything we need.
420 if (!WOWCallback16Ex(
421 (DWORD)((const IMalloc16Vtbl*)MapSL(
422 (SEGPTR)((LPMALLOC16)MapSL((SEGPTR)mllc))->lpVtbl )
423 )->Alloc,
424 WCB16_CDECL,
425 2*sizeof(DWORD),
426 (LPVOID)args,
427 (LPDWORD)ptr
428 )) {
429 ERR("CallTo16 IMalloc16 (%d) failed\n",size);
430 return E_FAIL;
432 return S_OK;
435 /******************************************************************************
436 * StringFromCLSID [COMPOBJ.19]
437 * Converts a GUID into the respective string representation.
438 * The target string is allocated using the OLE IMalloc.
440 * RETURNS
441 * the string representation and HRESULT
444 HRESULT WINAPI StringFromCLSID16(
445 REFCLSID id, /* [in] the GUID to be converted */
446 LPOLESTR16 *idstr ) /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
448 WCHAR buffer[40];
449 HRESULT ret;
451 ret = _xmalloc16(40,(SEGPTR*)idstr);
452 if (ret != S_OK)
453 return ret;
454 StringFromGUID2( id, buffer, 40 );
455 WideCharToMultiByte( CP_ACP, 0, buffer, -1, MapSL((SEGPTR)*idstr), 40, NULL, NULL );
456 return ret;
459 /******************************************************************************
460 * ProgIDFromCLSID [COMPOBJ.62]
462 * Converts a class id into the respective Program ID. (By using a registry lookup)
464 * RETURNS
465 * S_OK on success
466 * riid associated with the progid
468 HRESULT WINAPI ProgIDFromCLSID16(
469 REFCLSID clsid, /* [in] class id as found in registry */
470 LPOLESTR16 *lplpszProgID )/* [out] associated Program ID */
472 LPOLESTR progid;
473 HRESULT ret;
475 ret = ProgIDFromCLSID( clsid, &progid );
476 if (ret == S_OK)
478 INT len = WideCharToMultiByte( CP_ACP, 0, progid, -1, NULL, 0, NULL, NULL );
479 ret = _xmalloc16(len, (SEGPTR*)lplpszProgID);
480 if (ret == S_OK)
481 WideCharToMultiByte( CP_ACP, 0, progid, -1, MapSL((SEGPTR)*lplpszProgID), len, NULL, NULL );
482 CoTaskMemFree( progid );
484 return ret;
487 /***********************************************************************
488 * LookupETask (COMPOBJ.94)
490 HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
491 FIXME("(%p,%p),stub!\n",hTask,p);
492 if ((*hTask = GetCurrentTask()) == hETask) {
493 memcpy(p, Table_ETask, sizeof(Table_ETask));
495 return 0;
498 /***********************************************************************
499 * SetETask (COMPOBJ.95)
501 HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
502 FIXME("(%04x,%p),stub!\n",hTask,p);
503 hETask = hTask;
504 return 0;
507 /***********************************************************************
508 * CALLOBJECTINWOW (COMPOBJ.201)
510 HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
511 FIXME("(%p,%p),stub!\n",p1,p2);
512 return 0;
515 /******************************************************************************
516 * CoRegisterClassObject [COMPOBJ.5]
518 * Don't know where it registers it ...
520 HRESULT WINAPI CoRegisterClassObject16(
521 REFCLSID rclsid,
522 LPUNKNOWN pUnk,
523 DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
524 DWORD flags, /* [in] REGCLS flags indicating how connections are made */
525 LPDWORD lpdwRegister
527 FIXME("(%s,%p,0x%08x,0x%08x,%p),stub\n",
528 debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister
530 return 0;
533 /******************************************************************************
534 * CoRevokeClassObject [COMPOBJ.6]
537 HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
539 FIXME("(0x%08x),stub!\n", dwRegister);
540 return 0;
543 /******************************************************************************
544 * IsValidInterface [COMPOBJ.23]
546 * Determines whether a pointer is a valid interface.
548 * PARAMS
549 * punk [I] Interface to be tested.
551 * RETURNS
552 * TRUE, if the passed pointer is a valid interface, or FALSE otherwise.
554 BOOL WINAPI IsValidInterface16(SEGPTR punk)
556 DWORD **ptr;
558 if (IsBadReadPtr16(punk,4))
559 return FALSE;
560 ptr = MapSL(punk);
561 if (IsBadReadPtr16((SEGPTR)ptr[0],4)) /* check vtable ptr */
562 return FALSE;
563 ptr = MapSL((SEGPTR)ptr[0]); /* ptr to first method */
564 if (IsBadReadPtr16((SEGPTR)ptr[0],2))
565 return FALSE;
566 return TRUE;
569 /******************************************************************************
570 * CoFileTimeToDosDateTime [COMPOBJ.30]
572 BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
574 return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
577 /******************************************************************************
578 * CoDosDateTimeToFileTime [COMPOBJ.31]
580 BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
582 return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
585 /******************************************************************************
586 * CoGetCurrentProcess [COMPOBJ.34]
588 DWORD WINAPI CoGetCurrentProcess16(void)
590 return CoGetCurrentProcess();
593 /******************************************************************************
594 * CoRegisterMessageFilter [COMPOBJ.27]
596 HRESULT WINAPI CoRegisterMessageFilter16(
597 LPMESSAGEFILTER lpMessageFilter,
598 LPMESSAGEFILTER *lplpMessageFilter
600 FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
601 return 0;
604 /******************************************************************************
605 * CoLockObjectExternal [COMPOBJ.63]
607 HRESULT WINAPI CoLockObjectExternal16(
608 LPUNKNOWN pUnk, /* [in] object to be locked */
609 BOOL16 fLock, /* [in] do lock */
610 BOOL16 fLastUnlockReleases /* [in] ? */
612 FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
613 return S_OK;
616 /***********************************************************************
617 * CoGetState [COMPOBJ.115]
619 HRESULT WINAPI CoGetState16(LPDWORD state)
621 FIXME("(%p),stub!\n", state);
623 *state = 0;
624 return S_OK;
627 /***********************************************************************
628 * DllEntryPoint [COMPOBJ.116]
630 * Initialization code for the COMPOBJ DLL
632 * RETURNS:
634 BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
636 TRACE("(%08x, %04x, %04x, %04x, %08x, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
637 return TRUE;
640 /***********************************************************************
641 * CoMemAlloc [COMPOBJ.151]
643 SEGPTR WINAPI CoMemAlloc(DWORD size, DWORD dwMemContext, DWORD x) {
644 HRESULT hres;
645 SEGPTR segptr;
647 /* FIXME: check context handling */
648 TRACE("(%d, 0x%08x, 0x%08x)\n", size, dwMemContext, x);
649 hres = _xmalloc16(size, &segptr);
650 if (hres != S_OK)
651 return 0;
652 return segptr;
655 /******************************************************************************
656 * CLSIDFromProgID [COMPOBJ.61]
658 * Converts a program ID into the respective GUID.
660 * PARAMS
661 * progid [I] program id as found in registry
662 * riid [O] associated CLSID
664 * RETURNS
665 * Success: S_OK
666 * Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
668 HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
670 char *buf,buf2[80];
671 LONG buf2len;
672 HKEY xhkey;
674 buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
675 sprintf(buf,"%s\\CLSID",progid);
676 if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey)) {
677 HeapFree(GetProcessHeap(),0,buf);
678 return CO_E_CLASSSTRING;
680 HeapFree(GetProcessHeap(),0,buf);
681 buf2len = sizeof(buf2);
682 if (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) {
683 RegCloseKey(xhkey);
684 return CO_E_CLASSSTRING;
686 RegCloseKey(xhkey);
687 return CLSIDFromString16(buf2,riid);
690 /******************************************************************************
691 * StringFromGUID2 [COMPOBJ.76]
693 INT16 WINAPI StringFromGUID216(REFGUID id, LPOLESTR16 str, INT16 cmax)
695 static const char format[] = "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}";
696 if (!id || cmax < CHARS_IN_GUID) return 0;
697 sprintf( str, format, id->Data1, id->Data2, id->Data3,
698 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
699 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
700 return CHARS_IN_GUID;
704 /***********************************************************************
705 * CoFileTimeNow [COMPOBJ.82]
707 HRESULT WINAPI CoFileTimeNow16( FILETIME *lpFileTime )
709 return CoFileTimeNow( lpFileTime );
712 /***********************************************************************
713 * CoGetClassObject [COMPOBJ.7]
716 HRESULT WINAPI CoGetClassObject16(
717 SEGPTR rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
718 SEGPTR riid, SEGPTR ppv)
720 LPVOID *ppvl = MapSL(ppv);
722 TRACE("CLSID: %s, IID: %s\n", debugstr_guid(MapSL(rclsid)), debugstr_guid(MapSL(riid)));
724 *ppvl = NULL;
726 if (pServerInfo) {
727 FIXME("pServerInfo->name=%s pAuthInfo=%p\n",
728 debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo);
731 if (CLSCTX_INPROC_SERVER & dwClsContext)
733 char idstr[CHARS_IN_GUID];
734 char buf_key[CHARS_IN_GUID+19], dllpath[MAX_PATH+1];
735 LONG dllpath_len = sizeof(dllpath);
737 HMODULE16 dll;
738 FARPROC16 DllGetClassObject;
740 WORD args[6];
741 DWORD dwRet;
743 StringFromGUID216(MapSL(rclsid), idstr, CHARS_IN_GUID);
744 sprintf(buf_key, "CLSID\\%s\\InprocServer", idstr);
745 if (RegQueryValueA(HKEY_CLASSES_ROOT, buf_key, dllpath, &dllpath_len))
747 ERR("class %s not registered\n", debugstr_guid(MapSL(rclsid)));
748 return REGDB_E_CLASSNOTREG;
751 dll = LoadLibrary16(dllpath);
752 if (!dll)
754 ERR("couldn't load in-process dll %s\n", debugstr_a(dllpath));
755 return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
758 DllGetClassObject = GetProcAddress16(dll, "DllGetClassObject");
759 if (!DllGetClassObject)
761 ERR("couldn't find function DllGetClassObject in %s\n", debugstr_a(dllpath));
762 FreeLibrary16(dll);
763 return CO_E_DLLNOTFOUND;
766 TRACE("calling DllGetClassObject %p\n", DllGetClassObject);
767 args[5] = SELECTOROF(rclsid);
768 args[4] = OFFSETOF(rclsid);
769 args[3] = SELECTOROF(riid);
770 args[2] = OFFSETOF(riid);
771 args[1] = SELECTOROF(ppv);
772 args[0] = OFFSETOF(ppv);
773 WOWCallback16Ex((DWORD) DllGetClassObject, WCB16_PASCAL, sizeof(args), args, &dwRet);
774 if (dwRet != S_OK)
776 ERR("DllGetClassObject returned error 0x%08x\n", dwRet);
777 FreeLibrary16(dll);
778 return dwRet;
781 return S_OK;
784 FIXME("semi-stub\n");
785 return E_NOTIMPL;
788 /******************************************************************************
789 * CoCreateGuid [COMPOBJ.73]
791 HRESULT WINAPI CoCreateGuid16(GUID *pguid)
793 return CoCreateGuid( pguid );
796 /***********************************************************************
797 * CoCreateInstance [COMPOBJ.13]
799 HRESULT WINAPI CoCreateInstance16(
800 REFCLSID rclsid,
801 LPUNKNOWN pUnkOuter,
802 DWORD dwClsContext,
803 REFIID iid,
804 LPVOID *ppv)
806 FIXME("(%s, %p, %x, %s, %p), stub!\n",
807 debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
810 return E_NOTIMPL;
813 /***********************************************************************
814 * CoDisconnectObject [COMPOBJ.15]
816 HRESULT WINAPI CoDisconnectObject16( LPUNKNOWN lpUnk, DWORD reserved )
818 FIXME("(%p, 0x%08x): stub!\n", lpUnk, reserved);
819 return E_NOTIMPL;