Fix the case of product and company names.
[wine] / dlls / ole32 / ole16.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24
25 #include "config.h"
26
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "objbase.h"
36 #include "ole2.h"
37 #include "ole2ver.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"
45 #include "compobj_private.h"
46 #include "ifs.h"
47
48 #include "wine/debug.h"
49
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51
52 HINSTANCE16     COMPOBJ_hInstance = 0;
53 static int      COMPOBJ_Attach = 0;
54
55 HTASK16 hETask = 0;
56 WORD Table_ETask[62];
57
58 LPMALLOC16 currentMalloc16=NULL;
59
60 /* --- IMalloc16 implementation */
61
62
63 typedef struct
64 {
65         /* IUnknown fields */
66         ICOM_VFIELD(IMalloc16);
67         DWORD                   ref;
68         /* IMalloc16 fields */
69 } IMalloc16Impl;
70
71 /******************************************************************************
72  *              IMalloc16_QueryInterface        [COMPOBJ.500]
73  */
74 HRESULT WINAPI IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
75         ICOM_THIS(IMalloc16Impl,iface);
76
77         TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
78         if (    !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
79                 !memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
80         ) {
81                 *obj = This;
82                 return 0;
83         }
84         return OLE_E_ENUM_NOMORE;
85 }
86
87 /******************************************************************************
88  *              IMalloc16_AddRef        [COMPOBJ.501]
89  */
90 ULONG WINAPI IMalloc16_fnAddRef(IMalloc16* iface) {
91         ICOM_THIS(IMalloc16Impl,iface);
92         TRACE("(%p)->AddRef()\n",This);
93         return 1; /* cannot be freed */
94 }
95
96 /******************************************************************************
97  *              IMalloc16_Release       [COMPOBJ.502]
98  */
99 ULONG WINAPI IMalloc16_fnRelease(IMalloc16* iface) {
100         ICOM_THIS(IMalloc16Impl,iface);
101         TRACE("(%p)->Release()\n",This);
102         return 1; /* cannot be freed */
103 }
104
105 /******************************************************************************
106  * IMalloc16_Alloc [COMPOBJ.503]
107  */
108 SEGPTR WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
109         ICOM_THIS(IMalloc16Impl,iface);
110         TRACE("(%p)->Alloc(%ld)\n",This,cb);
111         return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
112 }
113
114 /******************************************************************************
115  * IMalloc16_Realloc [COMPOBJ.504]
116  */
117 SEGPTR WINAPI IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
118 {
119     SEGPTR ret;
120     ICOM_THIS(IMalloc16Impl,iface);
121     TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
122     ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
123     UnMapLS(pv);
124     return ret;
125 }
126
127 /******************************************************************************
128  * IMalloc16_Free [COMPOBJ.505]
129  */
130 VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
131 {
132     void *ptr = MapSL(pv);
133     ICOM_THIS(IMalloc16Impl,iface);
134     TRACE("(%p)->Free(%08lx)\n",This,pv);
135     UnMapLS(pv);
136     HeapFree( GetProcessHeap(), 0, ptr );
137 }
138
139 /******************************************************************************
140  * IMalloc16_GetSize [COMPOBJ.506]
141  */
142 DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,SEGPTR pv)
143 {
144         ICOM_THIS(IMalloc16Impl,iface);
145         TRACE("(%p)->GetSize(%08lx)\n",This,pv);
146         return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
147 }
148
149 /******************************************************************************
150  * IMalloc16_DidAlloc [COMPOBJ.507]
151  */
152 INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
153         ICOM_THIS(IMalloc16,iface);
154         TRACE("(%p)->DidAlloc(%p)\n",This,pv);
155         return (INT16)-1;
156 }
157
158 /******************************************************************************
159  * IMalloc16_HeapMinimize [COMPOBJ.508]
160  */
161 LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
162         ICOM_THIS(IMalloc16Impl,iface);
163         TRACE("(%p)->HeapMinimize()\n",This);
164         return NULL;
165 }
166
167 /******************************************************************************
168  * IMalloc16_Constructor [VTABLE]
169  */
170 LPMALLOC16
171 IMalloc16_Constructor()
172 {
173     static ICOM_VTABLE(IMalloc16) vt16;
174     static SEGPTR msegvt16;
175     IMalloc16Impl* This;
176     HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
177
178     This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
179     if (!msegvt16)
180     {
181 #define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
182         VTENT(QueryInterface);
183         VTENT(AddRef);
184         VTENT(Release);
185         VTENT(Alloc);
186         VTENT(Realloc);
187         VTENT(Free);
188         VTENT(GetSize);
189         VTENT(DidAlloc);
190         VTENT(HeapMinimize);
191 #undef VTENT
192         msegvt16 = MapLS( &vt16 );
193     }
194     This->lpVtbl = (ICOM_VTABLE(IMalloc16)*)msegvt16;
195     This->ref = 1;
196     return (LPMALLOC16)MapLS( This );
197 }
198
199
200 /***********************************************************************
201  *           CoGetMalloc    [COMPOBJ.4]
202  * RETURNS
203  *      The current win16 IMalloc
204  */
205 HRESULT WINAPI CoGetMalloc16(
206         DWORD dwMemContext,     /* [in] unknown */
207         LPMALLOC16 * lpMalloc   /* [out] current win16 malloc interface */
208 ) {
209     if(!currentMalloc16)
210         currentMalloc16 = IMalloc16_Constructor();
211     *lpMalloc = currentMalloc16;
212     return S_OK;
213 }
214
215 /***********************************************************************
216  *           CoCreateStandardMalloc [COMPOBJ.71]
217  */
218 HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
219                                           LPMALLOC16 *lpMalloc)
220 {
221     /* FIXME: docu says we shouldn't return the same allocator as in
222      * CoGetMalloc16 */
223     *lpMalloc = IMalloc16_Constructor();
224     return S_OK;
225 }
226
227 /******************************************************************************
228  *              CoInitialize    [COMPOBJ.2]
229  * Set the win16 IMalloc used for memory management
230  */
231 HRESULT WINAPI CoInitialize16(
232         LPVOID lpReserved       /* [in] pointer to win16 malloc interface */
233 ) {
234     currentMalloc16 = (LPMALLOC16)lpReserved;
235     return S_OK;
236 }
237
238 /***********************************************************************
239  *           CoUninitialize   [COMPOBJ.3]
240  * Don't know what it does.
241  * 3-Nov-98 -- this was originally misspelled, I changed it to what I
242  *   believe is the correct spelling
243  */
244 void WINAPI CoUninitialize16(void)
245 {
246   TRACE("()\n");
247   CoFreeAllLibraries();
248 }
249
250 /***********************************************************************
251  *           IsEqualGUID [COMPOBJ.18]
252  *
253  * Compares two Unique Identifiers.
254  *
255  * RETURNS
256  *      TRUE if equal
257  */
258 BOOL16 WINAPI IsEqualGUID16(
259         GUID* g1,       /* [in] unique id 1 */
260         GUID* g2)       /* [in] unique id 2 */
261 {
262     return !memcmp( g1, g2, sizeof(GUID) );
263 }
264
265 /******************************************************************************
266  *              CLSIDFromString [COMPOBJ.20]
267  * Converts a unique identifier from its string representation into
268  * the GUID struct.
269  *
270  * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
271  *
272  * RETURNS
273  *      the converted GUID
274  */
275 HRESULT WINAPI CLSIDFromString16(
276         LPCOLESTR16 idstr,      /* [in] string representation of guid */
277         CLSID *id)              /* [out] GUID converted from string */
278 {
279
280   return __CLSIDFromStringA(idstr,id);
281 }
282
283 extern BOOL WINAPI K32WOWCallback16Ex(  DWORD vpfn16, DWORD dwFlags,
284                                         DWORD cbArgs, LPVOID pArgs,
285                                         LPDWORD pdwRetCode );
286
287 /******************************************************************************
288  *              _xmalloc16      [internal]
289  * Allocates size bytes from the standard ole16 allocator.
290  *
291  * RETURNS
292  *      the allocated segmented pointer and a HRESULT
293  */
294 HRESULT
295 _xmalloc16(DWORD size, SEGPTR *ptr) {
296   LPMALLOC16 mllc;
297   DWORD args[2];
298
299   if (CoGetMalloc16(0,&mllc))
300     return E_OUTOFMEMORY;
301
302   args[0] = (DWORD)mllc;
303   args[1] = size;
304   /* No need for a Callback entry, we have WOWCallback16Ex which does
305    * everything we need.
306    */
307   if (!K32WOWCallback16Ex(
308       (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL(
309           (SEGPTR)((LPMALLOC16)MapSL((SEGPTR)mllc))->lpVtbl  )
310       )->Alloc,
311       WCB16_CDECL,
312       2*sizeof(DWORD),
313       (LPVOID)args,
314       (LPDWORD)ptr
315   )) {
316       ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
317       return E_FAIL;
318   }
319   return S_OK;
320 }
321
322 /******************************************************************************
323  *              StringFromCLSID [COMPOBJ.19]
324  * Converts a GUID into the respective string representation.
325  * The target string is allocated using the OLE IMalloc.
326  *
327  * RETURNS
328  *      the string representation and HRESULT
329  */
330
331 HRESULT WINAPI StringFromCLSID16(
332   REFCLSID id,          /* [in] the GUID to be converted */
333   LPOLESTR16 *idstr     /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
334
335 ) {
336   HRESULT ret;
337
338   ret = _xmalloc16(40,(SEGPTR*)idstr);
339   if (ret != S_OK)
340     return ret;
341   return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
342 }
343
344 /******************************************************************************
345  * ProgIDFromCLSID [COMPOBJ.62]
346  * Converts a class id into the respective Program ID. (By using a registry lookup)
347  * RETURNS S_OK on success
348  * riid associated with the progid
349  */
350 HRESULT WINAPI ProgIDFromCLSID16(
351   REFCLSID clsid, /* [in] class id as found in registry */
352   LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
353 ) {
354   char     strCLSID[50], *buf, *buf2;
355   DWORD    buf2len;
356   HKEY     xhkey;
357   HRESULT  ret = S_OK;
358
359   WINE_StringFromCLSID(clsid, strCLSID);
360
361   buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14);
362   sprintf(buf,"CLSID\\%s\\ProgID", strCLSID);
363   if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
364     ret = REGDB_E_CLASSNOTREG;
365
366   HeapFree(GetProcessHeap(), 0, buf);
367
368   if (ret == S_OK)
369   {
370     buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
371     buf2len = 255;
372     if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
373       ret = REGDB_E_CLASSNOTREG;
374
375     if (ret == S_OK)
376     {
377       ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
378       if (ret != S_OK)
379         return ret;
380       strcpy(MapSL((SEGPTR)*lplpszProgID),buf2);
381       ret = S_OK;
382     }
383     HeapFree(GetProcessHeap(), 0, buf2);
384   }
385   RegCloseKey(xhkey);
386   return ret;
387 }
388
389 /***********************************************************************
390  *           LookupETask (COMPOBJ.94)
391  */
392 HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
393         FIXME("(%p,%p),stub!\n",hTask,p);
394         if ((*hTask = GetCurrentTask()) == hETask) {
395                 memcpy(p, Table_ETask, sizeof(Table_ETask));
396         }
397         return 0;
398 }
399
400 /***********************************************************************
401  *           SetETask (COMPOBJ.95)
402  */
403 HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
404         FIXME("(%04x,%p),stub!\n",hTask,p);
405         hETask = hTask;
406         return 0;
407 }
408
409 /***********************************************************************
410  *           CALLOBJECTINWOW (COMPOBJ.201)
411  */
412 HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
413         FIXME("(%p,%p),stub!\n",p1,p2);
414         return 0;
415 }
416
417 /******************************************************************************
418  *              CoRegisterClassObject   [COMPOBJ.5]
419  *
420  * Don't know where it registers it ...
421  */
422 HRESULT WINAPI CoRegisterClassObject16(
423         REFCLSID rclsid,
424         LPUNKNOWN pUnk,
425         DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
426         DWORD flags,        /* [in] REGCLS flags indicating how connections are made */
427         LPDWORD lpdwRegister
428 ) {
429         char    buf[80];
430
431         WINE_StringFromCLSID(rclsid,buf);
432
433         FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
434                 buf,pUnk,dwClsContext,flags,lpdwRegister
435         );
436         return 0;
437 }
438
439 /******************************************************************************
440  *      CoRevokeClassObject [COMPOBJ.6]
441  *
442  */
443 HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
444 {
445     FIXME("(0x%08lx),stub!\n", dwRegister);
446     return 0;
447 }
448
449 /******************************************************************************
450  *      CoFileTimeToDosDateTime [COMPOBJ.30]
451  */
452 BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
453 {
454     return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
455 }
456
457 /******************************************************************************
458  *      CoDosDateTimeToFileTime [COMPOBJ.31]
459  */
460 BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
461 {
462     return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
463 }
464
465 /******************************************************************************
466  *              CoRegisterMessageFilter [COMPOBJ.27]
467  */
468 HRESULT WINAPI CoRegisterMessageFilter16(
469         LPMESSAGEFILTER lpMessageFilter,
470         LPMESSAGEFILTER *lplpMessageFilter
471 ) {
472         FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
473         return 0;
474 }
475
476 /******************************************************************************
477  *              CoLockObjectExternal    [COMPOBJ.63]
478  */
479 HRESULT WINAPI CoLockObjectExternal16(
480     LPUNKNOWN pUnk,             /* [in] object to be locked */
481     BOOL16 fLock,               /* [in] do lock */
482     BOOL16 fLastUnlockReleases  /* [in] ? */
483 ) {
484     FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
485     return S_OK;
486 }
487
488 /***********************************************************************
489  *           CoGetState [COMPOBJ.115]
490  */
491 HRESULT WINAPI CoGetState16(LPDWORD state)
492 {
493     FIXME("(%p),stub!\n", state);
494
495     *state = 0;
496     return S_OK;
497 }
498
499 /***********************************************************************
500  *      DllEntryPoint                   [COMPOBJ.116]
501  *
502  *    Initialization code for the COMPOBJ DLL
503  *
504  * RETURNS:
505  */
506 BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
507 {
508         TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
509         switch(Reason)
510         {
511         case DLL_PROCESS_ATTACH:
512                 if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
513                 break;
514
515         case DLL_PROCESS_DETACH:
516                 if(!--COMPOBJ_Attach)
517                         COMPOBJ_hInstance = 0;
518                 break;
519         }
520         return TRUE;
521 }