Use theming for the ListView non-client area.
[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 <stdarg.h>
22 #include <string.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winerror.h"
31
32 #include "ole2.h"
33 #include "olectl.h"
34 #include "oleauto.h"
35
36 #include "tmarshal.h"
37
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(ole);
41
42 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
43 extern const GUID CLSID_PSOAInterface;
44
45 extern const GUID CLSID_PSDispatch;
46 extern const GUID CLSID_PSEnumVariant;
47 extern const GUID CLSID_PSTypeInfo;
48 extern const GUID CLSID_PSTypeLib;
49 extern const GUID CLSID_PSTypeComp;
50
51 static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
52
53 HMODULE OLEAUT32_hModule = NULL;
54
55 /******************************************************************************
56  * BSTR  {OLEAUT32}
57  *
58  * NOTES
59  *  BSTR is a simple typedef for a wide-character string used as the principle
60  *  string type in ole automation. When encapsulated in a Variant type they are
61  *  automatically copied and destroyed as the variant is processed.
62  *
63  *  The low level BSTR Api allows manipulation of these strings and is used by
64  *  higher level Api calls to manage the strings transparently to the caller.
65  *
66  *  Internally the BSTR type is allocated with space for a DWORD byte count before
67  *  the string data begins. This is undocumented and non-system code should not
68  *  access the count directly. Use SysStringLen() or SysStringByteLen()
69  *  instead. Note that the byte count does not include the terminating NUL.
70  *
71  *  To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
72  *  SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
73  *  or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
74  *
75  *  BSTR's are cached by Ole Automation by default. To override this behaviour
76  *  either set the environment variable 'OANOCACHE', or call SetOaNoCache().
77  *
78  * SEE ALSO
79  *  'Inside OLE, second edition' by Kraig Brockshmidt.
80  */
81
82 /******************************************************************************
83  *             SysStringLen  [OLEAUT32.7]
84  *
85  * Get the allocated length of a BSTR in wide characters.
86  *
87  * PARAMS
88  *  str [I] BSTR to find the length of
89  *
90  * RETURNS
91  *  The allocated length of str, or 0 if str is NULL.
92  *
93  * NOTES
94  *  See BSTR.
95  *  The returned length may be different from the length of the string as
96  *  calculated by lstrlenW(), since it returns the length that was used to
97  *  allocate the string by SysAllocStringLen().
98  */
99 UINT WINAPI SysStringLen(BSTR str)
100 {
101     DWORD* bufferPointer;
102
103      if (!str) return 0;
104     /*
105      * The length of the string (in bytes) is contained in a DWORD placed
106      * just before the BSTR pointer
107      */
108     bufferPointer = (DWORD*)str;
109
110     bufferPointer--;
111
112     return (int)(*bufferPointer/sizeof(WCHAR));
113 }
114
115 /******************************************************************************
116  *             SysStringByteLen  [OLEAUT32.149]
117  *
118  * Get the allocated length of a BSTR in bytes.
119  *
120  * PARAMS
121  *  str [I] BSTR to find the length of
122  *
123  * RETURNS
124  *  The allocated length of str, or 0 if str is NULL.
125  *
126  * NOTES
127  *  See SysStringLen(), BSTR().
128  */
129 UINT WINAPI SysStringByteLen(BSTR str)
130 {
131     DWORD* bufferPointer;
132
133      if (!str) return 0;
134     /*
135      * The length of the string (in bytes) is contained in a DWORD placed
136      * just before the BSTR pointer
137      */
138     bufferPointer = (DWORD*)str;
139
140     bufferPointer--;
141
142     return (int)(*bufferPointer);
143 }
144
145 /******************************************************************************
146  *              SysAllocString  [OLEAUT32.2]
147  *
148  * Create a BSTR from an OLESTR.
149  *
150  * PARAMS
151  *  str [I] Source to create BSTR from
152  *
153  * RETURNS
154  *  Success: A BSTR allocated with SysAllocStringLen().
155  *  Failure: NULL, if oleStr is NULL.
156  *
157  * NOTES
158  *  See BSTR.
159  *  MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
160  *  a length of 0. Native Win32 and this implementation both return a valid
161  *  empty BSTR in this case.
162  */
163 BSTR WINAPI SysAllocString(LPCOLESTR str)
164 {
165     if (!str) return 0;
166
167     /* Delegate this to the SysAllocStringLen32 method. */
168     return SysAllocStringLen(str, lstrlenW(str));
169 }
170
171 /******************************************************************************
172  *              SysFreeString   [OLEAUT32.6]
173  *
174  * Free a BSTR.
175  *
176  * PARAMS
177  *  str [I] BSTR to free.
178  *
179  * RETURNS
180  *  Nothing.
181  *
182  * NOTES
183  *  See BSTR.
184  *  str may be NULL, in which case this function does nothing.
185  */
186 void WINAPI SysFreeString(BSTR str)
187 {
188     DWORD* bufferPointer;
189
190     /* NULL is a valid parameter */
191     if(!str) return;
192
193     /*
194      * We have to be careful when we free a BSTR pointer, it points to
195      * the beginning of the string but it skips the byte count contained
196      * before the string.
197      */
198     bufferPointer = (DWORD*)str;
199
200     bufferPointer--;
201
202     /*
203      * Free the memory from its "real" origin.
204      */
205     HeapFree(GetProcessHeap(), 0, bufferPointer);
206 }
207
208 /******************************************************************************
209  *             SysAllocStringLen     [OLEAUT32.4]
210  *
211  * Create a BSTR from an OLESTR of a given wide character length.
212  *
213  * PARAMS
214  *  str [I] Source to create BSTR from
215  *  len [I] Length of oleStr in wide characters
216  *
217  * RETURNS
218  *  Success: A newly allocated BSTR from SysAllocStringByteLen()
219  *  Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
220  *
221  * NOTES
222  *  See BSTR(), SysAllocStringByteLen().
223  */
224 BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
225 {
226     DWORD  bufferSize;
227     DWORD* newBuffer;
228     WCHAR* stringBuffer;
229
230     /*
231      * Find the length of the buffer passed-in in bytes.
232      */
233     bufferSize = len * sizeof (WCHAR);
234
235     /*
236      * Allocate a new buffer to hold the string.
237      * don't forget to keep an empty spot at the beginning of the
238      * buffer for the character count and an extra character at the
239      * end for the NULL.
240      */
241     newBuffer = HeapAlloc(GetProcessHeap(), 0,
242                           bufferSize + sizeof(WCHAR) + sizeof(DWORD));
243
244     /*
245      * If the memory allocation failed, return a null pointer.
246      */
247     if (newBuffer==0)
248       return 0;
249
250     /*
251      * Copy the length of the string in the placeholder.
252      */
253     *newBuffer = bufferSize;
254
255     /*
256      * Skip the byte count.
257      */
258     newBuffer++;
259
260     /*
261      * Copy the information in the buffer.
262      * Since it is valid to pass a NULL pointer here, we'll initialize the
263      * buffer to nul if it is the case.
264      */
265     if (str != 0)
266       memcpy(newBuffer, str, bufferSize);
267     else
268       memset(newBuffer, 0, bufferSize);
269
270     /*
271      * Make sure that there is a nul character at the end of the
272      * string.
273      */
274     stringBuffer = (WCHAR*)newBuffer;
275     stringBuffer[len] = L'\0';
276
277     return (LPWSTR)stringBuffer;
278 }
279
280 /******************************************************************************
281  *             SysReAllocStringLen   [OLEAUT32.5]
282  *
283  * Change the length of a previously created BSTR.
284  *
285  * PARAMS
286  *  old [O] BSTR to change the length of
287  *  str [I] New source for pbstr
288  *  len [I] Length of oleStr in wide characters
289  *
290  * RETURNS
291  *  Success: 1. The size of pbstr is updated.
292  *  Failure: 0, if len >= 0x80000000 or memory allocation fails.
293  *
294  * NOTES
295  *  See BSTR(), SysAllocStringByteLen().
296  *  *pbstr may be changed by this function.
297  */
298 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
299 {
300     if (*old!=NULL) {
301       DWORD newbytelen = len*sizeof(WCHAR);
302       DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
303       *old = (BSTR)(ptr+1);
304       *ptr = newbytelen;
305       if (str) {
306         memcpy(*old, str, newbytelen);
307         (*old)[len] = 0;
308       } else {
309         /* Subtle hidden feature: The old string data is still there
310          * when 'in' is NULL!
311          * Some Microsoft program needs it.
312          */
313       }
314     } else {
315       /*
316        * Allocate the new string
317        */
318       *old = SysAllocStringLen(str, len);
319     }
320
321     return 1;
322 }
323
324 /******************************************************************************
325  *             SysAllocStringByteLen     [OLEAUT32.150]
326  *
327  * Create a BSTR from an OLESTR of a given byte length.
328  *
329  * PARAMS
330  *  str [I] Source to create BSTR from
331  *  len [I] Length of oleStr in bytes
332  *
333  * RETURNS
334  *  Success: A newly allocated BSTR
335  *  Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
336  *
337  * NOTES
338  *  -If len is 0 or oleStr is NULL the resulting string is empty ("").
339  *  -This function always NUL terminates the resulting BSTR.
340  *  -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
341  *  without checking for a terminating NUL.
342  *  See BSTR.
343  */
344 BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
345 {
346     DWORD* newBuffer;
347     char* stringBuffer;
348
349     /*
350      * Allocate a new buffer to hold the string.
351      * don't forget to keep an empty spot at the beginning of the
352      * buffer for the character count and an extra character at the
353      * end for the NULL.
354      */
355     newBuffer = HeapAlloc(GetProcessHeap(), 0,
356                           len + sizeof(WCHAR) + sizeof(DWORD));
357
358     /*
359      * If the memory allocation failed, return a null pointer.
360      */
361     if (newBuffer==0)
362       return 0;
363
364     /*
365      * Copy the length of the string in the placeholder.
366      */
367     *newBuffer = len;
368
369     /*
370      * Skip the byte count.
371      */
372     newBuffer++;
373
374     /*
375      * Copy the information in the buffer.
376      * Since it is valid to pass a NULL pointer here, we'll initialize the
377      * buffer to nul if it is the case.
378      */
379     if (str != 0)
380       memcpy(newBuffer, str, len);
381
382     /*
383      * Make sure that there is a nul character at the end of the
384      * string.
385      */
386     stringBuffer = (char *)newBuffer;
387     stringBuffer[len] = 0;
388     stringBuffer[len+1] = 0;
389
390     return (LPWSTR)stringBuffer;
391 }
392
393 /******************************************************************************
394  *              SysReAllocString        [OLEAUT32.3]
395  *
396  * Change the length of a previously created BSTR.
397  *
398  * PARAMS
399  *  old [I/O] BSTR to change the length of
400  *  str [I]   New source for pbstr
401  *
402  * RETURNS
403  *  Success: 1
404  *  Failure: 0.
405  *
406  * NOTES
407  *  See BSTR(), SysAllocStringStringLen().
408  */
409 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str)
410 {
411     /*
412      * Sanity check
413      */
414     if (old==NULL)
415       return 0;
416
417     /*
418      * Make sure we free the old string.
419      */
420     if (*old!=NULL)
421       SysFreeString(*old);
422
423     /*
424      * Allocate the new string
425      */
426     *old = SysAllocString(str);
427
428      return 1;
429 }
430
431 /******************************************************************************
432  *              SetOaNoCache (OLEAUT32.327)
433  *
434  * Instruct Ole Automation not to cache BSTR allocations.
435  *
436  * PARAMS
437  *  None.
438  *
439  * RETURNS
440  *  Nothing.
441  *
442  * NOTES
443  *  See BSTR.
444  */
445 void WINAPI SetOaNoCache(void)
446 {
447   BSTR_bCache = FALSE;
448 }
449
450 static WCHAR    _delimiter[2] = {'!',0}; /* default delimiter apparently */
451 static WCHAR    *pdelimiter = &_delimiter[0];
452
453 /***********************************************************************
454  *              RegisterActiveObject (OLEAUT32.33)
455  *
456  * Registers an object in the global item table.
457  *
458  * PARAMS
459  *  punk        [I] Object to register.
460  *  rcid        [I] CLSID of the object.
461  *  dwFlags     [I] Flags.
462  *  pdwRegister [O] Address to store cookie of object registration in.
463  *
464  * RETURNS
465  *  Success: S_OK.
466  *  Failure: HRESULT code.
467  */
468 HRESULT WINAPI RegisterActiveObject(
469         LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
470 ) {
471         WCHAR                   guidbuf[80];
472         HRESULT                 ret;
473         LPRUNNINGOBJECTTABLE    runobtable;
474         LPMONIKER               moniker;
475
476         StringFromGUID2(rcid,guidbuf,39);
477         ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
478         if (FAILED(ret))
479                 return ret;
480         ret = GetRunningObjectTable(0,&runobtable);
481         if (FAILED(ret)) {
482                 IMoniker_Release(moniker);
483                 return ret;
484         }
485         ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister);
486         IRunningObjectTable_Release(runobtable);
487         IMoniker_Release(moniker);
488         return ret;
489 }
490
491 /***********************************************************************
492  *              RevokeActiveObject (OLEAUT32.34)
493  *
494  * Revokes an object from the global item table.
495  *
496  * PARAMS
497  *  xregister [I] Registration cookie.
498  *  reserved  [I] Reserved. Set to NULL.
499  *
500  * RETURNS
501  *  Success: S_OK.
502  *  Failure: HRESULT code.
503  */
504 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
505 {
506         LPRUNNINGOBJECTTABLE    runobtable;
507         HRESULT                 ret;
508
509         ret = GetRunningObjectTable(0,&runobtable);
510         if (FAILED(ret)) return ret;
511         ret = IRunningObjectTable_Revoke(runobtable,xregister);
512         if (SUCCEEDED(ret)) ret = S_OK;
513         IRunningObjectTable_Release(runobtable);
514         return ret;
515 }
516
517 /***********************************************************************
518  *              GetActiveObject (OLEAUT32.35)
519  *
520  * Gets an object from the global item table.
521  *
522  * PARAMS
523  *  rcid        [I] CLSID of the object.
524  *  preserved   [I] Reserved. Set to NULL.
525  *  ppunk       [O] Address to store object into.
526  *
527  * RETURNS
528  *  Success: S_OK.
529  *  Failure: HRESULT code.
530  */
531 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
532 {
533         WCHAR                   guidbuf[80];
534         HRESULT                 ret;
535         LPRUNNINGOBJECTTABLE    runobtable;
536         LPMONIKER               moniker;
537
538         StringFromGUID2(rcid,guidbuf,39);
539         ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
540         if (FAILED(ret))
541                 return ret;
542         ret = GetRunningObjectTable(0,&runobtable);
543         if (FAILED(ret)) {
544                 IMoniker_Release(moniker);
545                 return ret;
546         }
547         ret = IRunningObjectTable_GetObject(runobtable,moniker,ppunk);
548         IRunningObjectTable_Release(runobtable);
549         IMoniker_Release(moniker);
550         return ret;
551 }
552
553
554 /***********************************************************************
555  *           OaBuildVersion           [OLEAUT32.170]
556  *
557  * Get the Ole Automation build version.
558  *
559  * PARAMS
560  *  None
561  *
562  * RETURNS
563  *  The build version.
564  *
565  * NOTES
566  *  Known oleaut32.dll versions:
567  *| OLE Ver.  Comments                   Date     Build Ver.
568  *| --------  -------------------------  ----     ---------
569  *| OLE 2.1   NT                         1993-95  10 3023
570  *| OLE 2.1                                       10 3027
571  *| Win32s    Ver 1.1e                            20 4049
572  *| OLE 2.20  W95/NT                     1993-96  20 4112
573  *| OLE 2.20  W95/NT                     1993-96  20 4118
574  *| OLE 2.20  W95/NT                     1993-96  20 4122
575  *| OLE 2.30  W95/NT                     1993-98  30 4265
576  *| OLE 2.40  NT??                       1993-98  40 4267
577  *| OLE 2.40  W98 SE orig. file          1993-98  40 4275
578  *| OLE 2.40  W2K orig. file             1993-XX  40 4514
579  *
580  * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
581  * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
582  */
583 ULONG WINAPI OaBuildVersion()
584 {
585     switch(GetVersion() & 0x8000ffff)  /* mask off build number */
586     {
587     case 0x80000a03:  /* WIN31 */
588                 return MAKELONG(0xffff, 20);
589     case 0x00003303:  /* NT351 */
590                 return MAKELONG(0xffff, 30);
591     case 0x80000004:  /* WIN95; I'd like to use the "standard" w95 minor
592                          version here (30), but as we still use w95
593                          as default winver (which is good IMHO), I better
594                          play safe and use the latest value for w95 for now.
595                          Change this as soon as default winver gets changed
596                          to something more recent */
597     case 0x80000a04:  /* WIN98 */
598     case 0x00000004:  /* NT40 */
599     case 0x00000005:  /* W2K */
600     case 0x00000105:  /* WinXP */
601                 return MAKELONG(0xffff, 40);
602     default:
603                 FIXME("Version value not known yet. Please investigate it !\n");
604                 return MAKELONG(0xffff, 40);  /* for now return the same value as for w2k */
605     }
606 }
607
608 /******************************************************************************
609  *              OleTranslateColor       [OLEAUT32.421]
610  *
611  * Convert an OLE_COLOR to a COLORREF.
612  *
613  * PARAMS
614  *  clr       [I] Color to convert
615  *  hpal      [I] Handle to a palette for the conversion
616  *  pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
617  *
618  * RETURNS
619  *  Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
620  *  Failure: E_INVALIDARG, if any argument is invalid.
621  *
622  * FIXME
623  *  Document the conversion rules.
624  */
625 HRESULT WINAPI OleTranslateColor(
626   OLE_COLOR clr,
627   HPALETTE  hpal,
628   COLORREF* pColorRef)
629 {
630   COLORREF colorref;
631   BYTE b = HIBYTE(HIWORD(clr));
632
633   TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef);
634
635   /*
636    * In case pColorRef is NULL, provide our own to simplify the code.
637    */
638   if (pColorRef == NULL)
639     pColorRef = &colorref;
640
641   switch (b)
642   {
643     case 0x00:
644     {
645       if (hpal != 0)
646         *pColorRef =  PALETTERGB(GetRValue(clr),
647                                  GetGValue(clr),
648                                  GetBValue(clr));
649       else
650         *pColorRef = clr;
651
652       break;
653     }
654
655     case 0x01:
656     {
657       if (hpal != 0)
658       {
659         PALETTEENTRY pe;
660         /*
661          * Validate the palette index.
662          */
663         if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
664           return E_INVALIDARG;
665       }
666
667       *pColorRef = clr;
668
669       break;
670     }
671
672     case 0x02:
673       *pColorRef = clr;
674       break;
675
676     case 0x80:
677     {
678       int index = LOBYTE(LOWORD(clr));
679
680       /*
681        * Validate GetSysColor index.
682        */
683       if ((index < COLOR_SCROLLBAR) || (index > COLOR_MENUBAR))
684         return E_INVALIDARG;
685
686       *pColorRef =  GetSysColor(index);
687
688       break;
689     }
690
691     default:
692       return E_INVALIDARG;
693   }
694
695   return S_OK;
696 }
697
698 extern HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
699
700 extern void _get_STDFONT_CF(LPVOID);
701 extern void _get_STDPIC_CF(LPVOID);
702
703 /***********************************************************************
704  *              DllGetClassObject (OLEAUT32.1)
705  */
706 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
707 {
708     *ppv = NULL;
709     if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
710         if (IsEqualGUID(iid,&IID_IClassFactory)) {
711             _get_STDFONT_CF(ppv);
712             IClassFactory_AddRef((IClassFactory*)*ppv);
713             return S_OK;
714         }
715     }
716     if (IsEqualGUID(rclsid,&CLSID_StdPicture)) {
717         if (IsEqualGUID(iid,&IID_IClassFactory)) {
718             _get_STDPIC_CF(ppv);
719             IClassFactory_AddRef((IClassFactory*)*ppv);
720             return S_OK;
721         }
722     }
723     if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
724         IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
725         IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
726         IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) {
727         return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv);
728     }
729     if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
730         if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
731             return S_OK;
732         /*FALLTHROUGH*/
733     }
734     FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
735     return CLASS_E_CLASSNOTAVAILABLE;
736 }
737
738 /***********************************************************************
739  *              DllCanUnloadNow (OLEAUT32.410)
740  *
741  * Determine if this dll can be unloaded from the callers address space.
742  *
743  * PARAMS
744  *  None.
745  *
746  * RETURNS
747  *  Always returns S_FALSE. This dll cannot be unloaded.
748  */
749 HRESULT WINAPI DllCanUnloadNow(void)
750 {
751     return S_FALSE;
752 }
753
754 /*****************************************************************************
755  *              DllMain         [OLEAUT32.@]
756  */
757 BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
758 {
759   TRACE("(%p,%lu,%p)\n", hInstDll, fdwReason, lpvReserved);
760
761   switch (fdwReason) {
762   case DLL_PROCESS_ATTACH:
763     DisableThreadLibraryCalls(hInstDll);
764     OLEAUT32_hModule = (HMODULE)hInstDll;
765     break;
766   case DLL_PROCESS_DETACH:
767     break;
768   };
769
770   return TRUE;
771 }