xref: /reactos/dll/win32/vbscript/vbscript_main.c (revision b5218987)
1 /*
2  * Copyright 2011 Jacek Caban 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 
19 #include "initguid.h"
20 
21 #include "vbscript.h"
22 #include "objsafe.h"
23 #include "mshtmhst.h"
24 #include "rpcproxy.h"
25 #include "vbscript_classes.h"
26 #include "vbsglobal.h"
27 #include "vbsregexp55.h"
28 
29 #include "wine/debug.h"
30 
31 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
32 WINE_DECLARE_DEBUG_CHANNEL(heap);
33 
34 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
35 
36 static HINSTANCE vbscript_hinstance;
37 
38 BSTR get_vbscript_string(int id)
39 {
40     WCHAR buf[512];
41     if(!LoadStringW(vbscript_hinstance, id, buf, ARRAY_SIZE(buf))) return NULL;
42     return SysAllocString(buf);
43 }
44 
45 BSTR get_vbscript_error_string(HRESULT error)
46 {
47     BSTR ret;
48     if(HRESULT_FACILITY(error) != FACILITY_VBS || !(ret = get_vbscript_string(HRESULT_CODE(error))))
49         ret = get_vbscript_string(VBS_UNKNOWN_RUNTIME_ERROR);
50     return ret;
51 }
52 
53 #define MIN_BLOCK_SIZE  128
54 #define ARENA_FREE_FILLER  0xaa
55 
56 static inline DWORD block_size(DWORD block)
57 {
58     return MIN_BLOCK_SIZE << block;
59 }
60 
61 void heap_pool_init(heap_pool_t *heap)
62 {
63     memset(heap, 0, sizeof(*heap));
64     list_init(&heap->custom_blocks);
65 }
66 
67 void *heap_pool_alloc(heap_pool_t *heap, size_t size)
68 {
69     struct list *list;
70     void *tmp;
71 
72     size = (size+3)&~3;
73 
74     if(!heap->block_cnt) {
75         if(!heap->blocks) {
76             heap->blocks = heap_alloc(sizeof(void*));
77             if(!heap->blocks)
78                 return NULL;
79         }
80 
81         tmp = heap_alloc(block_size(0));
82         if(!tmp)
83             return NULL;
84 
85         heap->blocks[0] = tmp;
86         heap->block_cnt = 1;
87     }
88 
89     if(heap->offset + size <= block_size(heap->last_block)) {
90         tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
91         heap->offset += size;
92         return tmp;
93     }
94 
95     if(size <= block_size(heap->last_block+1)) {
96         if(heap->last_block+1 == heap->block_cnt) {
97             tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
98             if(!tmp)
99                 return NULL;
100 
101             heap->blocks = tmp;
102             heap->blocks[heap->block_cnt] = heap_alloc(block_size(heap->block_cnt));
103             if(!heap->blocks[heap->block_cnt])
104                 return NULL;
105 
106             heap->block_cnt++;
107         }
108 
109         heap->last_block++;
110         heap->offset = size;
111         return heap->blocks[heap->last_block];
112     }
113 
114     list = heap_alloc(size + sizeof(struct list));
115     if(!list)
116         return NULL;
117 
118     list_add_head(&heap->custom_blocks, list);
119     return list+1;
120 }
121 
122 void *heap_pool_grow(heap_pool_t *heap, void *mem, DWORD size, DWORD inc)
123 {
124     void *ret;
125 
126     if(mem == (BYTE*)heap->blocks[heap->last_block] + heap->offset-size
127             && heap->offset+inc < block_size(heap->last_block)) {
128         heap->offset += inc;
129         return mem;
130     }
131 
132     ret = heap_pool_alloc(heap, size+inc);
133     if(ret) /* FIXME: avoid copying for custom blocks */
134         memcpy(ret, mem, size);
135     return ret;
136 }
137 
138 void heap_pool_clear(heap_pool_t *heap)
139 {
140     struct list *tmp;
141 
142     if(!heap)
143         return;
144 
145     while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
146         list_remove(tmp);
147         heap_free(tmp);
148     }
149 
150     if(WARN_ON(heap)) {
151         DWORD i;
152 
153         for(i=0; i < heap->block_cnt; i++)
154             memset(heap->blocks[i], ARENA_FREE_FILLER, block_size(i));
155     }
156 
157     heap->last_block = heap->offset = 0;
158     heap->mark = FALSE;
159 }
160 
161 void heap_pool_free(heap_pool_t *heap)
162 {
163     DWORD i;
164 
165     heap_pool_clear(heap);
166 
167     for(i=0; i < heap->block_cnt; i++)
168         heap_free(heap->blocks[i]);
169     heap_free(heap->blocks);
170 
171     heap_pool_init(heap);
172 }
173 
174 heap_pool_t *heap_pool_mark(heap_pool_t *heap)
175 {
176     if(heap->mark)
177         return NULL;
178 
179     heap->mark = TRUE;
180     return heap;
181 }
182 
183 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
184 {
185     *ppv = NULL;
186 
187     if(IsEqualGUID(&IID_IUnknown, riid)) {
188         TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
189         *ppv = iface;
190     }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
191         TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
192         *ppv = iface;
193     }
194 
195     if(*ppv) {
196         IUnknown_AddRef((IUnknown*)*ppv);
197         return S_OK;
198     }
199 
200     FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
201     return E_NOINTERFACE;
202 }
203 
204 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
205 {
206     TRACE("(%p)\n", iface);
207     return 2;
208 }
209 
210 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
211 {
212     TRACE("(%p)\n", iface);
213     return 1;
214 }
215 
216 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
217 {
218     TRACE("(%p)->(%x)\n", iface, fLock);
219     return S_OK;
220 }
221 
222 static const IClassFactoryVtbl VBScriptFactoryVtbl = {
223     ClassFactory_QueryInterface,
224     ClassFactory_AddRef,
225     ClassFactory_Release,
226     VBScriptFactory_CreateInstance,
227     ClassFactory_LockServer
228 };
229 
230 static IClassFactory VBScriptFactory = { &VBScriptFactoryVtbl };
231 
232 static const IClassFactoryVtbl VBScriptRegExpFactoryVtbl = {
233     ClassFactory_QueryInterface,
234     ClassFactory_AddRef,
235     ClassFactory_Release,
236     VBScriptRegExpFactory_CreateInstance,
237     ClassFactory_LockServer
238 };
239 
240 static IClassFactory VBScriptRegExpFactory = { &VBScriptRegExpFactoryVtbl };
241 
242 /******************************************************************
243  *              DllMain (vbscript.@)
244  */
245 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
246 {
247     TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv);
248 
249     switch(fdwReason)
250     {
251     case DLL_WINE_PREATTACH:
252         return FALSE;  /* prefer native version */
253     case DLL_PROCESS_ATTACH:
254         DisableThreadLibraryCalls(hInstDLL);
255         vbscript_hinstance = hInstDLL;
256         break;
257     case DLL_PROCESS_DETACH:
258         if (lpv) break;
259         release_regexp_typelib();
260     }
261 
262     return TRUE;
263 }
264 
265 /***********************************************************************
266  *		DllGetClassObject	(vbscript.@)
267  */
268 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
269 {
270     if(IsEqualGUID(&CLSID_VBScript, rclsid)) {
271         TRACE("(CLSID_VBScript %s %p)\n", debugstr_guid(riid), ppv);
272         return IClassFactory_QueryInterface(&VBScriptFactory, riid, ppv);
273     }else if(IsEqualGUID(&CLSID_VBScriptRegExp, rclsid)) {
274         TRACE("(CLSID_VBScriptRegExp %s %p)\n", debugstr_guid(riid), ppv);
275         return IClassFactory_QueryInterface(&VBScriptRegExpFactory, riid, ppv);
276     }
277 
278     FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
279     return CLASS_E_CLASSNOTAVAILABLE;
280 }
281 
282 /***********************************************************************
283  *          DllCanUnloadNow (vbscript.@)
284  */
285 HRESULT WINAPI DllCanUnloadNow(void)
286 {
287     return S_FALSE;
288 }
289 
290 /***********************************************************************
291  *          DllRegisterServer (vbscript.@)
292  */
293 HRESULT WINAPI DllRegisterServer(void)
294 {
295     TRACE("()\n");
296     return __wine_register_resources(vbscript_hinstance);
297 }
298 
299 /***********************************************************************
300  *          DllUnregisterServer (vbscript.@)
301  */
302 HRESULT WINAPI DllUnregisterServer(void)
303 {
304     TRACE("()\n");
305     return __wine_unregister_resources(vbscript_hinstance);
306 }
307