Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/compobj.dll16/compobj.c
8569 views
1
/*
2
* 16 bit ole functions
3
*
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
9
*
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.
14
*
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.
19
*
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
23
*/
24
25
26
#include <stdlib.h>
27
#include <stdarg.h>
28
#include <stdio.h>
29
#include <string.h>
30
#include <assert.h>
31
32
#include "windef.h"
33
#include "winbase.h"
34
#include "winuser.h"
35
#include "objbase.h"
36
#include "ole2.h"
37
#include "rpc.h"
38
#include "winerror.h"
39
#include "winreg.h"
40
#include "wownt32.h"
41
#include "wtypes.h"
42
#include "wine/winbase16.h"
43
44
#include "wine/debug.h"
45
46
WINE_DEFAULT_DEBUG_CHANNEL(ole);
47
48
typedef LPCSTR LPCOLESTR16;
49
50
#define CHARS_IN_GUID 39
51
52
typedef struct
53
{
54
SEGPTR QueryInterface;
55
SEGPTR AddRef;
56
SEGPTR Release;
57
SEGPTR Alloc;
58
SEGPTR Realloc;
59
SEGPTR Free;
60
SEGPTR GetSize;
61
SEGPTR DidAlloc;
62
SEGPTR HeapMinimize;
63
} IMalloc16Vtbl;
64
65
typedef struct
66
{
67
SEGPTR lpVtbl;
68
} IMalloc16;
69
70
static ULONG call_IMalloc_AddRef(SEGPTR iface)
71
{
72
IMalloc16 *malloc = MapSL(iface);
73
IMalloc16Vtbl *vtbl = MapSL(malloc->lpVtbl);
74
DWORD args[1], ret;
75
76
args[0] = iface;
77
WOWCallback16Ex(vtbl->AddRef, WCB16_CDECL, sizeof(args), args, &ret);
78
return ret;
79
}
80
81
static ULONG call_IMalloc_Release(SEGPTR iface)
82
{
83
IMalloc16 *malloc = MapSL(iface);
84
IMalloc16Vtbl *vtbl = MapSL(malloc->lpVtbl);
85
DWORD args[1], ret;
86
87
args[0] = iface;
88
WOWCallback16Ex(vtbl->Release, WCB16_CDECL, sizeof(args), args, &ret);
89
return ret;
90
}
91
92
static SEGPTR call_IMalloc_Alloc(SEGPTR iface, DWORD size)
93
{
94
IMalloc16 *malloc = MapSL(iface);
95
IMalloc16Vtbl *vtbl = MapSL(malloc->lpVtbl);
96
DWORD args[2], ret;
97
98
args[0] = iface;
99
args[1] = size;
100
WOWCallback16Ex(vtbl->Alloc, WCB16_CDECL, sizeof(args), args, &ret);
101
return ret;
102
}
103
104
static HTASK16 hETask = 0;
105
static WORD Table_ETask[62];
106
107
static SEGPTR compobj_malloc;
108
109
/* --- IMalloc16 implementation */
110
111
112
typedef struct
113
{
114
IMalloc16 IMalloc16_iface;
115
LONG refcount;
116
} IMalloc16Impl;
117
118
static inline IMalloc16Impl *impl_from_IMalloc16(IMalloc16 *iface)
119
{
120
return CONTAINING_RECORD(iface, IMalloc16Impl, IMalloc16_iface);
121
}
122
123
/******************************************************************************
124
* IMalloc16_QueryInterface [COMPOBJ.500]
125
*/
126
HRESULT CDECL IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
127
IMalloc16Impl *This = impl_from_IMalloc16(iface);
128
129
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
130
if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
131
!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
132
) {
133
*obj = This;
134
return 0;
135
}
136
return OLE_E_ENUM_NOMORE;
137
}
138
139
/******************************************************************************
140
* IMalloc16_AddRef [COMPOBJ.501]
141
*/
142
ULONG CDECL IMalloc16_fnAddRef(IMalloc16 *iface)
143
{
144
IMalloc16Impl *malloc = impl_from_IMalloc16(iface);
145
ULONG refcount = InterlockedIncrement(&malloc->refcount);
146
TRACE("%p increasing refcount to %lu.\n", malloc, refcount);
147
return refcount;
148
}
149
150
/******************************************************************************
151
* IMalloc16_Release [COMPOBJ.502]
152
*/
153
ULONG CDECL IMalloc16_fnRelease(SEGPTR iface)
154
{
155
IMalloc16Impl *malloc = impl_from_IMalloc16(MapSL(iface));
156
ULONG refcount = InterlockedDecrement(&malloc->refcount);
157
TRACE("%p decreasing refcount to %lu.\n", malloc, refcount);
158
if (!refcount)
159
{
160
UnMapLS(iface);
161
HeapFree(GetProcessHeap(), 0, malloc);
162
}
163
return refcount;
164
}
165
166
/******************************************************************************
167
* IMalloc16_Alloc [COMPOBJ.503]
168
*/
169
SEGPTR CDECL IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
170
IMalloc16Impl *This = impl_from_IMalloc16(iface);
171
172
TRACE("(%p)->Alloc(%ld)\n",This,cb);
173
return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
174
}
175
176
/******************************************************************************
177
* IMalloc16_Free [COMPOBJ.505]
178
*/
179
VOID CDECL IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
180
{
181
void *ptr = MapSL(pv);
182
IMalloc16Impl *This = impl_from_IMalloc16(iface);
183
TRACE("(%p)->Free(%08lx)\n",This,pv);
184
UnMapLS(pv);
185
HeapFree( GetProcessHeap(), 0, ptr );
186
}
187
188
/******************************************************************************
189
* IMalloc16_Realloc [COMPOBJ.504]
190
*/
191
SEGPTR CDECL IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
192
{
193
SEGPTR ret;
194
IMalloc16Impl *This = impl_from_IMalloc16(iface);
195
196
TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
197
if (!pv)
198
ret = IMalloc16_fnAlloc(iface, cb);
199
else if (cb) {
200
ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
201
UnMapLS(pv);
202
} else {
203
IMalloc16_fnFree(iface, pv);
204
ret = 0;
205
}
206
return ret;
207
}
208
209
/******************************************************************************
210
* IMalloc16_GetSize [COMPOBJ.506]
211
*/
212
DWORD CDECL IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
213
{
214
IMalloc16Impl *This = impl_from_IMalloc16(iface);
215
216
TRACE("(%p)->GetSize(%08lx)\n",This,pv);
217
return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
218
}
219
220
/******************************************************************************
221
* IMalloc16_DidAlloc [COMPOBJ.507]
222
*/
223
INT16 CDECL IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
224
IMalloc16Impl *This = impl_from_IMalloc16(iface);
225
226
TRACE("(%p)->DidAlloc(%p)\n",This,pv);
227
return (INT16)-1;
228
}
229
230
/******************************************************************************
231
* IMalloc16_HeapMinimize [COMPOBJ.508]
232
*/
233
LPVOID CDECL IMalloc16_fnHeapMinimize(IMalloc16* iface) {
234
IMalloc16Impl *This = impl_from_IMalloc16(iface);
235
236
TRACE("(%p)->HeapMinimize()\n",This);
237
return NULL;
238
}
239
240
/******************************************************************************
241
* IMalloc16_Constructor [VTABLE]
242
*/
243
static SEGPTR IMalloc16_Constructor(void)
244
{
245
static IMalloc16Vtbl vt16;
246
static SEGPTR msegvt16;
247
IMalloc16Impl* This;
248
HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
249
250
This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
251
if (!msegvt16)
252
{
253
#define VTENT(x) vt16.x = (SEGPTR)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
254
VTENT(QueryInterface);
255
VTENT(AddRef);
256
VTENT(Release);
257
VTENT(Alloc);
258
VTENT(Realloc);
259
VTENT(Free);
260
VTENT(GetSize);
261
VTENT(DidAlloc);
262
VTENT(HeapMinimize);
263
#undef VTENT
264
msegvt16 = MapLS( &vt16 );
265
}
266
This->IMalloc16_iface.lpVtbl = msegvt16;
267
This->refcount = 1;
268
return MapLS(This);
269
}
270
271
/******************************************************************************
272
* CoBuildVersion [COMPOBJ.1]
273
*/
274
DWORD WINAPI CoBuildVersion16(void)
275
{
276
return CoBuildVersion();
277
}
278
279
/***********************************************************************
280
* CoGetMalloc [COMPOBJ.4]
281
*/
282
HRESULT WINAPI CoGetMalloc16(MEMCTX context, SEGPTR *malloc)
283
{
284
call_IMalloc_AddRef(*malloc = compobj_malloc);
285
return S_OK;
286
}
287
288
/***********************************************************************
289
* CoCreateStandardMalloc [COMPOBJ.71]
290
*/
291
HRESULT WINAPI CoCreateStandardMalloc16(MEMCTX context, SEGPTR *malloc)
292
{
293
/* FIXME: docu says we shouldn't return the same allocator as in
294
* CoGetMalloc16 */
295
*malloc = IMalloc16_Constructor();
296
return S_OK;
297
}
298
299
/***********************************************************************
300
* CoMemAlloc [COMPOBJ.151]
301
*/
302
SEGPTR WINAPI CoMemAlloc(DWORD size, MEMCTX context, DWORD unknown)
303
{
304
TRACE("size %lu, context %d, unknown %#lx.\n", size, context, unknown);
305
if (context != MEMCTX_TASK)
306
FIXME("Ignoring context %d.\n", context);
307
if (unknown)
308
FIXME("Ignoring unknown parameter %#lx.\n", unknown);
309
310
return call_IMalloc_Alloc(compobj_malloc, size);
311
}
312
313
/***********************************************************************
314
* CoInitialize [COMPOBJ.2]
315
*/
316
HRESULT WINAPI CoInitialize16(SEGPTR malloc)
317
{
318
if (!malloc)
319
CoCreateStandardMalloc16(MEMCTX_TASK, &compobj_malloc);
320
else
321
call_IMalloc_AddRef(compobj_malloc = malloc);
322
return S_OK;
323
}
324
325
/***********************************************************************
326
* CoUninitialize [COMPOBJ.3]
327
* Don't know what it does.
328
* 3-Nov-98 -- this was originally misspelled, I changed it to what I
329
* believe is the correct spelling
330
*/
331
void WINAPI CoUninitialize16(void)
332
{
333
TRACE("\n");
334
335
CoFreeAllLibraries();
336
call_IMalloc_Release(compobj_malloc);
337
compobj_malloc = 0;
338
}
339
340
/***********************************************************************
341
* CoFreeUnusedLibraries [COMPOBJ.17]
342
*/
343
void WINAPI CoFreeUnusedLibraries16(void)
344
{
345
CoFreeUnusedLibraries();
346
}
347
348
/***********************************************************************
349
* IsEqualGUID [COMPOBJ.18]
350
*
351
* Compares two Unique Identifiers.
352
*
353
* RETURNS
354
* TRUE if equal
355
*/
356
BOOL16 WINAPI IsEqualGUID16(
357
GUID* g1, /* [in] unique id 1 */
358
GUID* g2) /* [in] unique id 2 */
359
{
360
return !memcmp( g1, g2, sizeof(GUID) );
361
}
362
363
/******************************************************************************
364
* CLSIDFromString [COMPOBJ.20]
365
* Converts a unique identifier from its string representation into
366
* the GUID struct.
367
*
368
* Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
369
*
370
* RETURNS
371
* the converted GUID
372
*/
373
HRESULT WINAPI CLSIDFromString16(
374
LPCOLESTR16 idstr, /* [in] string representation of guid */
375
CLSID *id) /* [out] GUID converted from string */
376
{
377
const BYTE *s;
378
int i;
379
BYTE table[256];
380
381
if (!idstr) {
382
memset( id, 0, sizeof (CLSID) );
383
return S_OK;
384
}
385
386
/* validate the CLSID string */
387
if (strlen(idstr) != 38)
388
return CO_E_CLASSSTRING;
389
390
s = (const BYTE *) idstr;
391
if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
392
return CO_E_CLASSSTRING;
393
394
for (i=1; i<37; i++) {
395
if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
396
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
397
((s[i] >= 'a') && (s[i] <= 'f')) ||
398
((s[i] >= 'A') && (s[i] <= 'F'))))
399
return CO_E_CLASSSTRING;
400
}
401
402
TRACE("%s -> %p\n", s, id);
403
404
/* quick lookup table */
405
memset(table, 0, 256);
406
407
for (i = 0; i < 10; i++) {
408
table['0' + i] = i;
409
}
410
for (i = 0; i < 6; i++) {
411
table['A' + i] = i+10;
412
table['a' + i] = i+10;
413
}
414
415
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
416
417
id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
418
table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] << 4 | table[s[8]]);
419
id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
420
id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
421
422
/* these are just sequential bytes */
423
id->Data4[0] = table[s[20]] << 4 | table[s[21]];
424
id->Data4[1] = table[s[22]] << 4 | table[s[23]];
425
id->Data4[2] = table[s[25]] << 4 | table[s[26]];
426
id->Data4[3] = table[s[27]] << 4 | table[s[28]];
427
id->Data4[4] = table[s[29]] << 4 | table[s[30]];
428
id->Data4[5] = table[s[31]] << 4 | table[s[32]];
429
id->Data4[6] = table[s[33]] << 4 | table[s[34]];
430
id->Data4[7] = table[s[35]] << 4 | table[s[36]];
431
432
return S_OK;
433
}
434
435
/***********************************************************************
436
* StringFromCLSID [COMPOBJ.151]
437
*/
438
HRESULT WINAPI StringFromCLSID16(REFCLSID id, SEGPTR *str)
439
{
440
WCHAR buffer[40];
441
if (!(*str = CoMemAlloc(40, MEMCTX_TASK, 0)))
442
return E_OUTOFMEMORY;
443
StringFromGUID2( id, buffer, 40 );
444
WideCharToMultiByte( CP_ACP, 0, buffer, -1, MapSL(*str), 40, NULL, NULL );
445
return S_OK;
446
}
447
448
/***********************************************************************
449
* ProgIDFromCLSID [COMPOBJ.151]
450
*/
451
HRESULT WINAPI ProgIDFromCLSID16(REFCLSID clsid, SEGPTR *str)
452
{
453
LPOLESTR progid;
454
HRESULT ret;
455
456
ret = ProgIDFromCLSID( clsid, &progid );
457
if (ret == S_OK)
458
{
459
INT len = WideCharToMultiByte( CP_ACP, 0, progid, -1, NULL, 0, NULL, NULL );
460
if ((*str = CoMemAlloc(len, MEMCTX_TASK, 0)))
461
WideCharToMultiByte( CP_ACP, 0, progid, -1, MapSL(*str), len, NULL, NULL );
462
CoTaskMemFree( progid );
463
}
464
return ret;
465
}
466
467
/***********************************************************************
468
* LookupETask (COMPOBJ.94)
469
*/
470
HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
471
FIXME("(%p,%p),stub!\n",hTask,p);
472
if ((*hTask = GetCurrentTask()) == hETask) {
473
memcpy(p, Table_ETask, sizeof(Table_ETask));
474
}
475
return 0;
476
}
477
478
/***********************************************************************
479
* SetETask (COMPOBJ.95)
480
*/
481
HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
482
FIXME("(%04x,%p),stub!\n",hTask,p);
483
hETask = hTask;
484
return 0;
485
}
486
487
/***********************************************************************
488
* CALLOBJECTINWOW (COMPOBJ.201)
489
*/
490
HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
491
FIXME("(%p,%p),stub!\n",p1,p2);
492
return 0;
493
}
494
495
/******************************************************************************
496
* CoRegisterClassObject [COMPOBJ.5]
497
*
498
* Don't know where it registers it ...
499
*/
500
HRESULT WINAPI CoRegisterClassObject16(
501
REFCLSID rclsid,
502
LPUNKNOWN pUnk,
503
DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
504
DWORD flags, /* [in] REGCLS flags indicating how connections are made */
505
LPDWORD lpdwRegister
506
) {
507
FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
508
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister
509
);
510
return 0;
511
}
512
513
/******************************************************************************
514
* CoRevokeClassObject [COMPOBJ.6]
515
*
516
*/
517
HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
518
{
519
FIXME("(0x%08lx),stub!\n", dwRegister);
520
return 0;
521
}
522
523
/******************************************************************************
524
* IsValidInterface [COMPOBJ.23]
525
*
526
* Determines whether a pointer is a valid interface.
527
*
528
* PARAMS
529
* punk [I] Interface to be tested.
530
*
531
* RETURNS
532
* TRUE, if the passed pointer is a valid interface, or FALSE otherwise.
533
*/
534
BOOL WINAPI IsValidInterface16(SEGPTR punk)
535
{
536
DWORD **ptr;
537
538
if (IsBadReadPtr16(punk,4))
539
return FALSE;
540
ptr = MapSL(punk);
541
if (IsBadReadPtr16((SEGPTR)ptr[0],4)) /* check vtable ptr */
542
return FALSE;
543
ptr = MapSL((SEGPTR)ptr[0]); /* ptr to first method */
544
if (IsBadReadPtr16((SEGPTR)ptr[0],2))
545
return FALSE;
546
return TRUE;
547
}
548
549
/******************************************************************************
550
* CoFileTimeToDosDateTime [COMPOBJ.30]
551
*/
552
BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
553
{
554
return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
555
}
556
557
/******************************************************************************
558
* CoDosDateTimeToFileTime [COMPOBJ.31]
559
*/
560
BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
561
{
562
return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
563
}
564
565
/******************************************************************************
566
* CoGetCurrentProcess [COMPOBJ.34]
567
*/
568
DWORD WINAPI CoGetCurrentProcess16(void)
569
{
570
return CoGetCurrentProcess();
571
}
572
573
/******************************************************************************
574
* CoRegisterMessageFilter [COMPOBJ.27]
575
*/
576
HRESULT WINAPI CoRegisterMessageFilter16(
577
LPMESSAGEFILTER lpMessageFilter,
578
LPMESSAGEFILTER *lplpMessageFilter
579
) {
580
FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
581
return 0;
582
}
583
584
/******************************************************************************
585
* CoLockObjectExternal [COMPOBJ.63]
586
*/
587
HRESULT WINAPI CoLockObjectExternal16(
588
LPUNKNOWN pUnk, /* [in] object to be locked */
589
BOOL16 fLock, /* [in] do lock */
590
BOOL16 fLastUnlockReleases /* [in] ? */
591
) {
592
FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
593
return S_OK;
594
}
595
596
/***********************************************************************
597
* CoGetState [COMPOBJ.115]
598
*/
599
HRESULT WINAPI CoGetState16(LPDWORD state)
600
{
601
FIXME("(%p),stub!\n", state);
602
603
*state = 0;
604
return S_OK;
605
}
606
607
/***********************************************************************
608
* DllEntryPoint [COMPOBJ.116]
609
*
610
* Initialization code for the COMPOBJ DLL
611
*
612
* RETURNS:
613
*/
614
BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
615
{
616
TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
617
return TRUE;
618
}
619
620
/******************************************************************************
621
* CLSIDFromProgID [COMPOBJ.61]
622
*
623
* Converts a program ID into the respective GUID.
624
*
625
* PARAMS
626
* progid [I] program id as found in registry
627
* riid [O] associated CLSID
628
*
629
* RETURNS
630
* Success: S_OK
631
* Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
632
*/
633
HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
634
{
635
char *buf,buf2[80];
636
LONG buf2len;
637
HKEY xhkey;
638
639
buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
640
sprintf(buf,"%s\\CLSID",progid);
641
if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey)) {
642
HeapFree(GetProcessHeap(),0,buf);
643
return CO_E_CLASSSTRING;
644
}
645
HeapFree(GetProcessHeap(),0,buf);
646
buf2len = sizeof(buf2);
647
if (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) {
648
RegCloseKey(xhkey);
649
return CO_E_CLASSSTRING;
650
}
651
RegCloseKey(xhkey);
652
return CLSIDFromString16(buf2,riid);
653
}
654
655
/******************************************************************************
656
* StringFromGUID2 [COMPOBJ.76]
657
*/
658
INT16 WINAPI StringFromGUID216(REFGUID id, char *str, INT16 cmax)
659
{
660
static const char format[] = "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}";
661
if (!id || cmax < CHARS_IN_GUID) return 0;
662
sprintf( str, format, id->Data1, id->Data2, id->Data3,
663
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
664
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
665
return CHARS_IN_GUID;
666
}
667
668
669
/***********************************************************************
670
* CoFileTimeNow [COMPOBJ.82]
671
*/
672
HRESULT WINAPI CoFileTimeNow16( FILETIME *lpFileTime )
673
{
674
return CoFileTimeNow( lpFileTime );
675
}
676
677
/***********************************************************************
678
* CoGetClassObject [COMPOBJ.7]
679
*
680
*/
681
HRESULT WINAPI CoGetClassObject16(
682
SEGPTR rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
683
SEGPTR riid, SEGPTR ppv)
684
{
685
LPVOID *ppvl = MapSL(ppv);
686
687
TRACE("CLSID: %s, IID: %s\n", debugstr_guid(MapSL(rclsid)), debugstr_guid(MapSL(riid)));
688
689
*ppvl = NULL;
690
691
if (pServerInfo) {
692
FIXME("pServerInfo->name=%s pAuthInfo=%p\n",
693
debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo);
694
}
695
696
if (CLSCTX_INPROC_SERVER & dwClsContext)
697
{
698
char idstr[CHARS_IN_GUID];
699
char buf_key[CHARS_IN_GUID+19], dllpath[MAX_PATH+1];
700
LONG dllpath_len = sizeof(dllpath);
701
702
HMODULE16 dll;
703
FARPROC16 DllGetClassObject;
704
705
WORD args[6];
706
DWORD dwRet;
707
708
StringFromGUID216(MapSL(rclsid), idstr, CHARS_IN_GUID);
709
sprintf(buf_key, "CLSID\\%s\\InprocServer", idstr);
710
if (RegQueryValueA(HKEY_CLASSES_ROOT, buf_key, dllpath, &dllpath_len))
711
{
712
ERR("class %s not registered\n", debugstr_guid(MapSL(rclsid)));
713
return REGDB_E_CLASSNOTREG;
714
}
715
716
dll = LoadLibrary16(dllpath);
717
if (!dll)
718
{
719
ERR("couldn't load in-process dll %s\n", debugstr_a(dllpath));
720
return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
721
}
722
723
DllGetClassObject = GetProcAddress16(dll, "DllGetClassObject");
724
if (!DllGetClassObject)
725
{
726
ERR("couldn't find function DllGetClassObject in %s\n", debugstr_a(dllpath));
727
FreeLibrary16(dll);
728
return CO_E_DLLNOTFOUND;
729
}
730
731
TRACE("calling DllGetClassObject %p\n", DllGetClassObject);
732
args[5] = SELECTOROF(rclsid);
733
args[4] = OFFSETOF(rclsid);
734
args[3] = SELECTOROF(riid);
735
args[2] = OFFSETOF(riid);
736
args[1] = SELECTOROF(ppv);
737
args[0] = OFFSETOF(ppv);
738
WOWCallback16Ex((DWORD) DllGetClassObject, WCB16_PASCAL, sizeof(args), args, &dwRet);
739
if (dwRet != S_OK)
740
{
741
ERR("DllGetClassObject returned error 0x%08lx\n", dwRet);
742
FreeLibrary16(dll);
743
return dwRet;
744
}
745
746
return S_OK;
747
}
748
749
FIXME("semi-stub\n");
750
return E_NOTIMPL;
751
}
752
753
/******************************************************************************
754
* CoCreateGuid [COMPOBJ.73]
755
*/
756
HRESULT WINAPI CoCreateGuid16(GUID *pguid)
757
{
758
return CoCreateGuid( pguid );
759
}
760
761
/***********************************************************************
762
* CoCreateInstance [COMPOBJ.13]
763
*/
764
HRESULT WINAPI CoCreateInstance16(
765
REFCLSID rclsid,
766
LPUNKNOWN pUnkOuter,
767
DWORD dwClsContext,
768
REFIID iid,
769
LPVOID *ppv)
770
{
771
FIXME("(%s, %p, %lx, %s, %p), stub!\n",
772
debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
773
ppv
774
);
775
return E_NOTIMPL;
776
}
777
778
/***********************************************************************
779
* CoDisconnectObject [COMPOBJ.15]
780
*/
781
HRESULT WINAPI CoDisconnectObject16( LPUNKNOWN lpUnk, DWORD reserved )
782
{
783
FIXME("(%p, 0x%08lx): stub!\n", lpUnk, reserved);
784
return E_NOTIMPL;
785
}
786
787