fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / oleaut32 / oleaut.c
1 /*
2  *      OLEAUT32
3  *
4  * Copyright 1999, 2000 Marcus Meissner
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <string.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winerror.h"
28
29 #include "ole2.h"
30 #include "olectl.h"
31 #include "oleauto.h"
32 #include "wine/obj_olefont.h"
33
34 #include "tmarshal.h"
35
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39
40 /******************************************************************************
41  *             SysStringLen  [OLEAUT32.7]
42  *
43  * The Windows documentation states that the length returned by this function
44  * is not necessarely the same as the length returned by the _lstrlenW method.
45  * It is the same number that was passed in as the "len" parameter if the
46  * string was allocated with a SysAllocStringLen method call.
47  */
48 int WINAPI SysStringLen(BSTR str)
49 {
50     DWORD* bufferPointer;
51
52      if (!str) return 0;
53     /*
54      * The length of the string (in bytes) is contained in a DWORD placed
55      * just before the BSTR pointer
56      */
57     bufferPointer = (DWORD*)str;
58
59     bufferPointer--;
60
61     return (int)(*bufferPointer/sizeof(WCHAR));
62 }
63
64 /******************************************************************************
65  *             SysStringByteLen  [OLEAUT32.149]
66  *
67  * The Windows documentation states that the length returned by this function
68  * is not necessarely the same as the length returned by the _lstrlenW method.
69  * It is the same number that was passed in as the "len" parameter if the
70  * string was allocated with a SysAllocStringLen method call.
71  */
72 int WINAPI SysStringByteLen(BSTR str)
73 {
74     DWORD* bufferPointer;
75
76      if (!str) return 0;
77     /*
78      * The length of the string (in bytes) is contained in a DWORD placed
79      * just before the BSTR pointer
80      */
81     bufferPointer = (DWORD*)str;
82
83     bufferPointer--;
84
85     return (int)(*bufferPointer);
86 }
87
88 /******************************************************************************
89  *              SysAllocString  [OLEAUT32.2]
90  *
91  * MSDN (October 2001) states that this returns a NULL value if the argument
92  * is a zero-length string.  This does not appear to be true; certainly it
93  * returns a value under Win98 (Oleaut32.dll Ver 2.40.4515.0)
94  */
95 BSTR WINAPI SysAllocString(LPCOLESTR in)
96 {
97     if (!in) return 0;
98
99     /* Delegate this to the SysAllocStringLen32 method. */
100     return SysAllocStringLen(in, lstrlenW(in));
101 }
102
103 /******************************************************************************
104  *              SysFreeString   [OLEAUT32.6]
105  */
106 void WINAPI SysFreeString(BSTR in)
107 {
108     DWORD* bufferPointer;
109
110     /* NULL is a valid parameter */
111     if(!in) return;
112
113     /*
114      * We have to be careful when we free a BSTR pointer, it points to
115      * the beginning of the string but it skips the byte count contained
116      * before the string.
117      */
118     bufferPointer = (DWORD*)in;
119
120     bufferPointer--;
121
122     /*
123      * Free the memory from its "real" origin.
124      */
125     HeapFree(GetProcessHeap(), 0, bufferPointer);
126 }
127
128 /******************************************************************************
129  *             SysAllocStringLen     [OLEAUT32.4]
130  *
131  * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
132  * section, he describes the DWORD value placed *before* the BSTR data type.
133  * he describes it as a "DWORD count of characters". By experimenting with
134  * a windows application, this count seems to be a DWORD count of bytes in
135  * the string. Meaning that the count is double the number of wide
136  * characters in the string.
137  */
138 BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
139 {
140     DWORD  bufferSize;
141     DWORD* newBuffer;
142     WCHAR* stringBuffer;
143
144     /*
145      * Find the length of the buffer passed-in in bytes.
146      */
147     bufferSize = len * sizeof (WCHAR);
148
149     /*
150      * Allocate a new buffer to hold the string.
151      * dont't forget to keep an empty spot at the beginning of the
152      * buffer for the character count and an extra character at the
153      * end for the NULL.
154      */
155     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
156                                  0,
157                                  bufferSize + sizeof(WCHAR) + sizeof(DWORD));
158
159     /*
160      * If the memory allocation failed, return a null pointer.
161      */
162     if (newBuffer==0)
163       return 0;
164
165     /*
166      * Copy the length of the string in the placeholder.
167      */
168     *newBuffer = bufferSize;
169
170     /*
171      * Skip the byte count.
172      */
173     newBuffer++;
174
175     /*
176      * Copy the information in the buffer.
177      * Since it is valid to pass a NULL pointer here, we'll initialize the
178      * buffer to nul if it is the case.
179      */
180     if (in != 0)
181       memcpy(newBuffer, in, bufferSize);
182     else
183       memset(newBuffer, 0, bufferSize);
184
185     /*
186      * Make sure that there is a nul character at the end of the
187      * string.
188      */
189     stringBuffer = (WCHAR*)newBuffer;
190     stringBuffer[len] = L'\0';
191
192     return (LPWSTR)stringBuffer;
193 }
194
195 /******************************************************************************
196  *             SysReAllocStringLen   [OLEAUT32.5]
197  */
198 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
199 {
200     /*
201      * Sanity check
202      */
203     if (old==NULL)
204       return 0;
205
206     /*
207      * Make sure we free the old string.
208      */
209     if (*old!=NULL)
210       SysFreeString(*old);
211
212     /*
213      * Allocate the new string
214      */
215     *old = SysAllocStringLen(in, len);
216
217     return 1;
218 }
219
220 /******************************************************************************
221  *             SysAllocStringByteLen     [OLEAUT32.150]
222  *
223  */
224 BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len)
225 {
226     DWORD* newBuffer;
227     char* stringBuffer;
228
229     /*
230      * Allocate a new buffer to hold the string.
231      * dont't forget to keep an empty spot at the beginning of the
232      * buffer for the character count and an extra character at the
233      * end for the NULL.
234      */
235     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
236                                  0,
237                                  len + sizeof(WCHAR) + sizeof(DWORD));
238
239     /*
240      * If the memory allocation failed, return a null pointer.
241      */
242     if (newBuffer==0)
243       return 0;
244
245     /*
246      * Copy the length of the string in the placeholder.
247      */
248     *newBuffer = len;
249
250     /*
251      * Skip the byte count.
252      */
253     newBuffer++;
254
255     /*
256      * Copy the information in the buffer.
257      * Since it is valid to pass a NULL pointer here, we'll initialize the
258      * buffer to nul if it is the case.
259      */
260     if (in != 0)
261       memcpy(newBuffer, in, len);
262
263     /*
264      * Make sure that there is a nul character at the end of the
265      * string.
266      */
267     stringBuffer = (char *)newBuffer;
268     stringBuffer[len] = 0;
269     stringBuffer[len+1] = 0;
270
271     return (LPWSTR)stringBuffer;
272 }
273
274 /******************************************************************************
275  *              SysReAllocString        [OLEAUT32.3]
276  */
277 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
278 {
279     /*
280      * Sanity check
281      */
282     if (old==NULL)
283       return 0;
284
285     /*
286      * Make sure we free the old string.
287      */
288     if (*old!=NULL)
289       SysFreeString(*old);
290
291     /*
292      * Allocate the new string
293      */
294     *old = SysAllocString(in);
295
296      return 1;
297 }
298
299 static WCHAR    _delimiter[2] = {'!',0}; /* default delimiter apparently */
300 static WCHAR    *pdelimiter = &_delimiter[0];
301
302 /***********************************************************************
303  *              RegisterActiveObject (OLEAUT32.33)
304  */
305 HRESULT WINAPI RegisterActiveObject(
306         LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
307 ) {
308         WCHAR                   guidbuf[80];
309         HRESULT                 ret;
310         LPRUNNINGOBJECTTABLE    runobtable;
311         LPMONIKER               moniker;
312
313         StringFromGUID2(rcid,guidbuf,39);
314         ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
315         if (FAILED(ret))
316                 return ret;
317         ret = GetRunningObjectTable(0,&runobtable);
318         if (FAILED(ret)) {
319                 IMoniker_Release(moniker);
320                 return ret;
321         }
322         ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister);
323         IRunningObjectTable_Release(runobtable);
324         IMoniker_Release(moniker);
325         return ret;
326 }
327
328 /***********************************************************************
329  *              RevokeActiveObject (OLEAUT32.34)
330  */
331 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
332 {
333         LPRUNNINGOBJECTTABLE    runobtable;
334         HRESULT                 ret;
335
336         ret = GetRunningObjectTable(0,&runobtable);
337         if (FAILED(ret)) return ret;
338         ret = IRunningObjectTable_Revoke(runobtable,xregister);
339         if (SUCCEEDED(ret)) ret = S_OK;
340         IRunningObjectTable_Release(runobtable);
341         return ret;
342 }
343
344 /***********************************************************************
345  *              GetActiveObject (OLEAUT32.35)
346  */
347 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
348 {
349         WCHAR                   guidbuf[80];
350         HRESULT                 ret;
351         LPRUNNINGOBJECTTABLE    runobtable;
352         LPMONIKER               moniker;
353
354         StringFromGUID2(rcid,guidbuf,39);
355         ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
356         if (FAILED(ret))
357                 return ret;
358         ret = GetRunningObjectTable(0,&runobtable);
359         if (FAILED(ret)) {
360                 IMoniker_Release(moniker);
361                 return ret;
362         }
363         ret = IRunningObjectTable_GetObject(runobtable,moniker,ppunk);
364         IRunningObjectTable_Release(runobtable);
365         IMoniker_Release(moniker);
366         return ret;
367 }
368
369
370 /***********************************************************************
371  *           OaBuildVersion           [OLEAUT32.170]
372  *
373  * known OLEAUT32.DLL versions:
374  * OLE 2.1  NT                          1993-95 10     3023
375  * OLE 2.1                                      10     3027
376  * Win32s 1.1e                                  20     4049
377  * OLE 2.20 W95/NT                      1993-96 20     4112
378  * OLE 2.20 W95/NT                      1993-96 20     4118
379  * OLE 2.20 W95/NT                      1993-96 20     4122
380  * OLE 2.30 W95/NT                      1993-98 30     4265
381  * OLE 2.40 NT??                        1993-98 40     4267
382  * OLE 2.40 W98 SE orig. file           1993-98 40     4275
383  * OLE 2.40 W2K orig. file              1993-XX 40     4514
384  *
385  * I just decided to use version 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
386  * and 2.40 for all newer OSs. The build number is maximum, i.e. 0xffff.
387  */
388 UINT WINAPI OaBuildVersion()
389 {
390     switch(GetVersion() & 0x8000ffff)  /* mask off build number */
391     {
392     case 0x80000a03:  /* WIN31 */
393                 return MAKELONG(0xffff, 20);
394     case 0x00003303:  /* NT351 */
395                 return MAKELONG(0xffff, 30);
396     case 0x80000004:  /* WIN95; I'd like to use the "standard" w95 minor
397                          version here (30), but as we still use w95
398                          as default winver (which is good IMHO), I better
399                          play safe and use the latest value for w95 for now.
400                          Change this as soon as default winver gets changed
401                          to something more recent */
402     case 0x80000a04:  /* WIN98 */
403     case 0x00000004:  /* NT40 */
404     case 0x00000005:  /* W2K */
405                 return MAKELONG(0xffff, 40);
406     default:
407                 ERR("Version value not known yet. Please investigate it !\n");
408                 return 0x0;
409     }
410 }
411
412 /******************************************************************************
413  *              OleTranslateColor       [OLEAUT32.421]
414  *
415  * Converts an OLE_COLOR to a COLORREF.
416  * See the documentation for conversion rules.
417  * pColorRef can be NULL. In that case the user only wants to test the
418  * conversion.
419  */
420 HRESULT WINAPI OleTranslateColor(
421   OLE_COLOR clr,
422   HPALETTE  hpal,
423   COLORREF* pColorRef)
424 {
425   COLORREF colorref;
426   BYTE b = HIBYTE(HIWORD(clr));
427
428   TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef);
429
430   /*
431    * In case pColorRef is NULL, provide our own to simplify the code.
432    */
433   if (pColorRef == NULL)
434     pColorRef = &colorref;
435
436   switch (b)
437   {
438     case 0x00:
439     {
440       if (hpal != 0)
441         *pColorRef =  PALETTERGB(GetRValue(clr),
442                                  GetGValue(clr),
443                                  GetBValue(clr));
444       else
445         *pColorRef = clr;
446
447       break;
448     }
449
450     case 0x01:
451     {
452       if (hpal != 0)
453       {
454         PALETTEENTRY pe;
455         /*
456          * Validate the palette index.
457          */
458         if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
459           return E_INVALIDARG;
460       }
461
462       *pColorRef = clr;
463
464       break;
465     }
466
467     case 0x02:
468       *pColorRef = clr;
469       break;
470
471     case 0x80:
472     {
473       int index = LOBYTE(LOWORD(clr));
474
475       /*
476        * Validate GetSysColor index.
477        */
478       if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
479         return E_INVALIDARG;
480
481       *pColorRef =  GetSysColor(index);
482
483       break;
484     }
485
486     default:
487       return E_INVALIDARG;
488   }
489
490   return S_OK;
491 }
492
493 /***********************************************************************
494  *              DllRegisterServer (OLEAUT32.320)
495  */
496 HRESULT WINAPI OLEAUT32_DllRegisterServer() {
497     FIXME("stub!\n");
498     return S_OK;
499 }
500
501 /***********************************************************************
502  *              DllUnregisterServer (OLEAUT32.321)
503  */
504 HRESULT WINAPI OLEAUT32_DllUnregisterServer() {
505     FIXME("stub!\n");
506     return S_OK;
507 }
508
509 extern void _get_STDFONT_CF(LPVOID);
510
511 /***********************************************************************
512  *              DllGetClassObject (OLEAUT32.1)
513  */
514 HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
515 {
516     *ppv = NULL;
517     if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
518         if (IsEqualGUID(iid,&IID_IClassFactory)) {
519             _get_STDFONT_CF(ppv);
520             IClassFactory_AddRef((IClassFactory*)*ppv);
521             return S_OK;
522         }
523     }
524     if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
525         if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
526             return S_OK;
527         /*FALLTHROUGH*/
528     }
529     FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
530     return CLASS_E_CLASSNOTAVAILABLE;
531 }
532
533 /***********************************************************************
534  *              DllCanUnloadNow (OLEAUT32.410)
535  */
536 HRESULT WINAPI OLEAUT32_DllCanUnloadNow() {
537     FIXME("(), stub!\n");
538     return S_FALSE;
539 }