wined3d: Avoid using gl_ViewportIndex unnecessarily.
[wine.git] / dlls / compobj.dll16 / compobj.c
blob4eddacece35712ba2650b082ecc095aff572baed
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 * StringFromIID [COMPOBJ.14]
438 * Converts a GUID into the respective string representation.
439 * The target string is allocated using the OLE IMalloc.
441 * RETURNS
442 * the string representation and HRESULT
445 HRESULT WINAPI StringFromCLSID16(
446 REFCLSID id, /* [in] the GUID to be converted */
447 LPOLESTR16 *idstr ) /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
449 WCHAR buffer[40];
450 HRESULT ret;
452 ret = _xmalloc16(40,(SEGPTR*)idstr);
453 if (ret != S_OK)
454 return ret;
455 StringFromGUID2( id, buffer, 40 );
456 WideCharToMultiByte( CP_ACP, 0, buffer, -1, MapSL((SEGPTR)*idstr), 40, NULL, NULL );
457 return ret;
460 /******************************************************************************
461 * ProgIDFromCLSID [COMPOBJ.62]
463 * Converts a class id into the respective Program ID. (By using a registry lookup)
465 * RETURNS
466 * S_OK on success
467 * riid associated with the progid
469 HRESULT WINAPI ProgIDFromCLSID16(
470 REFCLSID clsid, /* [in] class id as found in registry */
471 LPOLESTR16 *lplpszProgID )/* [out] associated Program ID */
473 LPOLESTR progid;
474 HRESULT ret;
476 ret = ProgIDFromCLSID( clsid, &progid );
477 if (ret == S_OK)
479 INT len = WideCharToMultiByte( CP_ACP, 0, progid, -1, NULL, 0, NULL, NULL );
480 ret = _xmalloc16(len, (SEGPTR*)lplpszProgID);
481 if (ret == S_OK)
482 WideCharToMultiByte( CP_ACP, 0, progid, -1, MapSL((SEGPTR)*lplpszProgID), len, NULL, NULL );
483 CoTaskMemFree( progid );
485 return ret;
488 /***********************************************************************
489 * LookupETask (COMPOBJ.94)
491 HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
492 FIXME("(%p,%p),stub!\n",hTask,p);
493 if ((*hTask = GetCurrentTask()) == hETask) {
494 memcpy(p, Table_ETask, sizeof(Table_ETask));
496 return 0;
499 /***********************************************************************
500 * SetETask (COMPOBJ.95)
502 HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
503 FIXME("(%04x,%p),stub!\n",hTask,p);
504 hETask = hTask;
505 return 0;
508 /***********************************************************************
509 * CALLOBJECTINWOW (COMPOBJ.201)
511 HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
512 FIXME("(%p,%p),stub!\n",p1,p2);
513 return 0;
516 /******************************************************************************
517 * CoRegisterClassObject [COMPOBJ.5]
519 * Don't know where it registers it ...
521 HRESULT WINAPI CoRegisterClassObject16(
522 REFCLSID rclsid,
523 LPUNKNOWN pUnk,
524 DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
525 DWORD flags, /* [in] REGCLS flags indicating how connections are made */
526 LPDWORD lpdwRegister
528 FIXME("(%s,%p,0x%08x,0x%08x,%p),stub\n",
529 debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister
531 return 0;
534 /******************************************************************************
535 * CoRevokeClassObject [COMPOBJ.6]
538 HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
540 FIXME("(0x%08x),stub!\n", dwRegister);
541 return 0;
544 /******************************************************************************
545 * IsValidInterface [COMPOBJ.23]
547 * Determines whether a pointer is a valid interface.
549 * PARAMS
550 * punk [I] Interface to be tested.
552 * RETURNS
553 * TRUE, if the passed pointer is a valid interface, or FALSE otherwise.
555 BOOL WINAPI IsValidInterface16(SEGPTR punk)
557 DWORD **ptr;
559 if (IsBadReadPtr16(punk,4))
560 return FALSE;
561 ptr = MapSL(punk);
562 if (IsBadReadPtr16((SEGPTR)ptr[0],4)) /* check vtable ptr */
563 return FALSE;
564 ptr = MapSL((SEGPTR)ptr[0]); /* ptr to first method */
565 if (IsBadReadPtr16((SEGPTR)ptr[0],2))
566 return FALSE;
567 return TRUE;
570 /******************************************************************************
571 * CoFileTimeToDosDateTime [COMPOBJ.30]
573 BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
575 return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
578 /******************************************************************************
579 * CoDosDateTimeToFileTime [COMPOBJ.31]
581 BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
583 return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
586 /******************************************************************************
587 * CoGetCurrentProcess [COMPOBJ.34]
589 DWORD WINAPI CoGetCurrentProcess16(void)
591 return CoGetCurrentProcess();
594 /******************************************************************************
595 * CoRegisterMessageFilter [COMPOBJ.27]
597 HRESULT WINAPI CoRegisterMessageFilter16(
598 LPMESSAGEFILTER lpMessageFilter,
599 LPMESSAGEFILTER *lplpMessageFilter
601 FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
602 return 0;
605 /******************************************************************************
606 * CoLockObjectExternal [COMPOBJ.63]
608 HRESULT WINAPI CoLockObjectExternal16(
609 LPUNKNOWN pUnk, /* [in] object to be locked */
610 BOOL16 fLock, /* [in] do lock */
611 BOOL16 fLastUnlockReleases /* [in] ? */
613 FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
614 return S_OK;
617 /***********************************************************************
618 * CoGetState [COMPOBJ.115]
620 HRESULT WINAPI CoGetState16(LPDWORD state)
622 FIXME("(%p),stub!\n", state);
624 *state = 0;
625 return S_OK;
628 /***********************************************************************
629 * DllEntryPoint [COMPOBJ.116]
631 * Initialization code for the COMPOBJ DLL
633 * RETURNS:
635 BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
637 TRACE("(%08x, %04x, %04x, %04x, %08x, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
638 return TRUE;
641 /***********************************************************************
642 * CoMemAlloc [COMPOBJ.151]
644 SEGPTR WINAPI CoMemAlloc(DWORD size, DWORD dwMemContext, DWORD x) {
645 HRESULT hres;
646 SEGPTR segptr;
648 /* FIXME: check context handling */
649 TRACE("(%d, 0x%08x, 0x%08x)\n", size, dwMemContext, x);
650 hres = _xmalloc16(size, &segptr);
651 if (hres != S_OK)
652 return 0;
653 return segptr;
656 /******************************************************************************
657 * CLSIDFromProgID [COMPOBJ.61]
659 * Converts a program ID into the respective GUID.
661 * PARAMS
662 * progid [I] program id as found in registry
663 * riid [O] associated CLSID
665 * RETURNS
666 * Success: S_OK
667 * Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
669 HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
671 char *buf,buf2[80];
672 LONG buf2len;
673 HKEY xhkey;
675 buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
676 sprintf(buf,"%s\\CLSID",progid);
677 if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey)) {
678 HeapFree(GetProcessHeap(),0,buf);
679 return CO_E_CLASSSTRING;
681 HeapFree(GetProcessHeap(),0,buf);
682 buf2len = sizeof(buf2);
683 if (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) {
684 RegCloseKey(xhkey);
685 return CO_E_CLASSSTRING;
687 RegCloseKey(xhkey);
688 return CLSIDFromString16(buf2,riid);
691 /******************************************************************************
692 * StringFromGUID2 [COMPOBJ.76]
694 INT16 WINAPI StringFromGUID216(REFGUID id, LPOLESTR16 str, INT16 cmax)
696 static const char format[] = "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}";
697 if (!id || cmax < CHARS_IN_GUID) return 0;
698 sprintf( str, format, id->Data1, id->Data2, id->Data3,
699 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
700 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
701 return CHARS_IN_GUID;
705 /***********************************************************************
706 * CoFileTimeNow [COMPOBJ.82]
708 HRESULT WINAPI CoFileTimeNow16( FILETIME *lpFileTime )
710 return CoFileTimeNow( lpFileTime );
713 /***********************************************************************
714 * CoGetClassObject [COMPOBJ.7]
717 HRESULT WINAPI CoGetClassObject16(
718 SEGPTR rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
719 SEGPTR riid, SEGPTR ppv)
721 LPVOID *ppvl = MapSL(ppv);
723 TRACE("CLSID: %s, IID: %s\n", debugstr_guid(MapSL(rclsid)), debugstr_guid(MapSL(riid)));
725 *ppvl = NULL;
727 if (pServerInfo) {
728 FIXME("pServerInfo->name=%s pAuthInfo=%p\n",
729 debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo);
732 if (CLSCTX_INPROC_SERVER & dwClsContext)
734 char idstr[CHARS_IN_GUID];
735 char buf_key[CHARS_IN_GUID+19], dllpath[MAX_PATH+1];
736 LONG dllpath_len = sizeof(dllpath);
738 HMODULE16 dll;
739 FARPROC16 DllGetClassObject;
741 WORD args[6];
742 DWORD dwRet;
744 StringFromGUID216(MapSL(rclsid), idstr, CHARS_IN_GUID);
745 sprintf(buf_key, "CLSID\\%s\\InprocServer", idstr);
746 if (RegQueryValueA(HKEY_CLASSES_ROOT, buf_key, dllpath, &dllpath_len))
748 ERR("class %s not registered\n", debugstr_guid(MapSL(rclsid)));
749 return REGDB_E_CLASSNOTREG;
752 dll = LoadLibrary16(dllpath);
753 if (!dll)
755 ERR("couldn't load in-process dll %s\n", debugstr_a(dllpath));
756 return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
759 DllGetClassObject = GetProcAddress16(dll, "DllGetClassObject");
760 if (!DllGetClassObject)
762 ERR("couldn't find function DllGetClassObject in %s\n", debugstr_a(dllpath));
763 FreeLibrary16(dll);
764 return CO_E_DLLNOTFOUND;
767 TRACE("calling DllGetClassObject %p\n", DllGetClassObject);
768 args[5] = SELECTOROF(rclsid);
769 args[4] = OFFSETOF(rclsid);
770 args[3] = SELECTOROF(riid);
771 args[2] = OFFSETOF(riid);
772 args[1] = SELECTOROF(ppv);
773 args[0] = OFFSETOF(ppv);
774 WOWCallback16Ex((DWORD) DllGetClassObject, WCB16_PASCAL, sizeof(args), args, &dwRet);
775 if (dwRet != S_OK)
777 ERR("DllGetClassObject returned error 0x%08x\n", dwRet);
778 FreeLibrary16(dll);
779 return dwRet;
782 return S_OK;
785 FIXME("semi-stub\n");
786 return E_NOTIMPL;
789 /******************************************************************************
790 * CoCreateGuid [COMPOBJ.73]
792 HRESULT WINAPI CoCreateGuid16(GUID *pguid)
794 return CoCreateGuid( pguid );
797 /***********************************************************************
798 * CoCreateInstance [COMPOBJ.13]
800 HRESULT WINAPI CoCreateInstance16(
801 REFCLSID rclsid,
802 LPUNKNOWN pUnkOuter,
803 DWORD dwClsContext,
804 REFIID iid,
805 LPVOID *ppv)
807 FIXME("(%s, %p, %x, %s, %p), stub!\n",
808 debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
811 return E_NOTIMPL;
814 /***********************************************************************
815 * CoDisconnectObject [COMPOBJ.15]
817 HRESULT WINAPI CoDisconnectObject16( LPUNKNOWN lpUnk, DWORD reserved )
819 FIXME("(%p, 0x%08x): stub!\n", lpUnk, reserved);
820 return E_NOTIMPL;