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