msvcrt: Return child exit code in _pclose function.
[wine] / dlls / scrrun / scrrun.c
1 /*
2  * Copyright 2011 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 #define COBJMACROS
19
20 #include "config.h"
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "ole2.h"
26 #include "rpcproxy.h"
27
28 #include <initguid.h>
29 #include "scrrun.h"
30 #include "scrrun_private.h"
31
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
35
36 static HINSTANCE scrrun_instance;
37
38 typedef HRESULT (*fnCreateInstance)(LPVOID *ppObj);
39
40 static HRESULT WINAPI scrruncf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv )
41 {
42     *ppv = NULL;
43
44     if(IsEqualGUID(&IID_IUnknown, riid)) {
45         TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
46         *ppv = iface;
47     }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
48         TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
49         *ppv = iface;
50     }
51
52     if(*ppv) {
53         IUnknown_AddRef((IUnknown*)*ppv);
54         return S_OK;
55     }
56
57     WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
58     return E_NOINTERFACE;
59 }
60
61 static ULONG WINAPI scrruncf_AddRef(IClassFactory *iface )
62 {
63     TRACE("(%p)\n", iface);
64     return 2;
65 }
66
67 static ULONG WINAPI scrruncf_Release(IClassFactory *iface )
68 {
69     TRACE("(%p)\n", iface);
70     return 1;
71 }
72
73 static HRESULT WINAPI scrruncf_LockServer(IClassFactory *iface, BOOL fLock)
74 {
75     TRACE("(%p)->(%x)\n", iface, fLock);
76     return S_OK;
77 }
78
79 static const struct IClassFactoryVtbl scrruncf_vtbl =
80 {
81     scrruncf_QueryInterface,
82     scrruncf_AddRef,
83     scrruncf_Release,
84     FileSystem_CreateInstance,
85     scrruncf_LockServer
86 };
87
88 static const struct IClassFactoryVtbl dictcf_vtbl =
89 {
90     scrruncf_QueryInterface,
91     scrruncf_AddRef,
92     scrruncf_Release,
93     Dictionary_CreateInstance,
94     scrruncf_LockServer
95 };
96
97 static IClassFactory FileSystemFactory = { &scrruncf_vtbl };
98 static IClassFactory DictionaryFactory = { &dictcf_vtbl };
99
100 static ITypeLib *typelib;
101 static ITypeInfo *typeinfos[LAST_tid];
102
103 static REFIID tid_ids[] = {
104     &IID_NULL,
105     &IID_IDictionary,
106     &IID_IFileSystem3,
107     &IID_IFolder
108 };
109
110 static HRESULT load_typelib(void)
111 {
112     HRESULT hres;
113     ITypeLib *tl;
114
115     hres = LoadRegTypeLib(&LIBID_Scripting, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
116     if(FAILED(hres)) {
117         ERR("LoadRegTypeLib failed: %08x\n", hres);
118         return hres;
119     }
120
121     if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
122         ITypeLib_Release(tl);
123     return hres;
124 }
125
126 HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
127 {
128     HRESULT hres;
129
130     if (!typelib)
131         hres = load_typelib();
132     if (!typelib)
133         return hres;
134
135     if(!typeinfos[tid]) {
136         ITypeInfo *ti;
137
138         hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
139         if(FAILED(hres)) {
140             ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
141             return hres;
142         }
143
144         if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
145             ITypeInfo_Release(ti);
146     }
147
148     *typeinfo = typeinfos[tid];
149     return S_OK;
150 }
151
152 static void release_typelib(void)
153 {
154     unsigned i;
155
156     if(!typelib)
157         return;
158
159     for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
160         if(typeinfos[i])
161             ITypeInfo_Release(typeinfos[i]);
162
163     ITypeLib_Release(typelib);
164 }
165
166 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
167 {
168     TRACE("%p, %u, %p\n", hinst, reason, reserved);
169
170     switch (reason)
171     {
172         case DLL_WINE_PREATTACH:
173             return FALSE;    /* prefer native version */
174         case DLL_PROCESS_ATTACH:
175             DisableThreadLibraryCalls( hinst );
176             scrrun_instance = hinst;
177             break;
178         case DLL_PROCESS_DETACH:
179             release_typelib();
180             break;
181     }
182     return TRUE;
183 }
184
185 /***********************************************************************
186  *      DllRegisterServer (scrrun.@)
187  */
188 HRESULT WINAPI DllRegisterServer(void)
189 {
190     TRACE("()\n");
191     return __wine_register_resources(scrrun_instance);
192 }
193
194 /***********************************************************************
195  *      DllUnregisterServer (scrrun.@)
196  */
197 HRESULT WINAPI DllUnregisterServer(void)
198 {
199     TRACE("()\n");
200     return __wine_unregister_resources(scrrun_instance);
201 }
202
203 /***********************************************************************
204  *      DllGetClassObject (scrrun.@)
205  */
206
207 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
208 {
209     if(IsEqualGUID(&CLSID_FileSystemObject, rclsid)) {
210         TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv);
211         return IClassFactory_QueryInterface(&FileSystemFactory, riid, ppv);
212     }
213     else if(IsEqualGUID(&CLSID_Dictionary, rclsid)) {
214         TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv);
215         return IClassFactory_QueryInterface(&DictionaryFactory, riid, ppv);
216     }
217
218     FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
219     return CLASS_E_CLASSNOTAVAILABLE;
220 }
221
222 /***********************************************************************
223  *      DllCanUnloadNow (scrrun.@)
224  */
225 HRESULT WINAPI DllCanUnloadNow(void)
226 {
227     return S_FALSE;
228 }