Release 6.15.
[wine.git] / dlls / vbscript / vbscript_main.c
blob087b387e0af7c3a15fb816523ad2a8ad4e55f36f
1 /*
2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "initguid.h"
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"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
32 WINE_DECLARE_DEBUG_CHANNEL(heap);
34 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
36 static HINSTANCE vbscript_hinstance;
37 static ITypeInfo *dispatch_typeinfo;
39 BSTR get_vbscript_string(int id)
41 WCHAR buf[512];
42 if(!LoadStringW(vbscript_hinstance, id, buf, ARRAY_SIZE(buf))) return NULL;
43 return SysAllocString(buf);
46 BSTR get_vbscript_error_string(HRESULT error)
48 BSTR ret;
49 if(HRESULT_FACILITY(error) != FACILITY_VBS || !(ret = get_vbscript_string(HRESULT_CODE(error))))
50 ret = get_vbscript_string(VBS_UNKNOWN_RUNTIME_ERROR);
51 return ret;
54 #define MIN_BLOCK_SIZE 128
55 #define ARENA_FREE_FILLER 0xaa
57 static inline DWORD block_size(DWORD block)
59 return MIN_BLOCK_SIZE << block;
62 void heap_pool_init(heap_pool_t *heap)
64 memset(heap, 0, sizeof(*heap));
65 list_init(&heap->custom_blocks);
68 void *heap_pool_alloc(heap_pool_t *heap, size_t size)
70 struct list *list;
71 void *tmp;
73 size = (size+3)&~3;
75 if(!heap->block_cnt) {
76 if(!heap->blocks) {
77 heap->blocks = heap_alloc(sizeof(void*));
78 if(!heap->blocks)
79 return NULL;
82 tmp = heap_alloc(block_size(0));
83 if(!tmp)
84 return NULL;
86 heap->blocks[0] = tmp;
87 heap->block_cnt = 1;
90 if(heap->offset + size <= block_size(heap->last_block)) {
91 tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
92 heap->offset += size;
93 return tmp;
96 if(size <= block_size(heap->last_block+1)) {
97 if(heap->last_block+1 == heap->block_cnt) {
98 tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
99 if(!tmp)
100 return NULL;
102 heap->blocks = tmp;
103 heap->blocks[heap->block_cnt] = heap_alloc(block_size(heap->block_cnt));
104 if(!heap->blocks[heap->block_cnt])
105 return NULL;
107 heap->block_cnt++;
110 heap->last_block++;
111 heap->offset = size;
112 return heap->blocks[heap->last_block];
115 list = heap_alloc(size + sizeof(struct list));
116 if(!list)
117 return NULL;
119 list_add_head(&heap->custom_blocks, list);
120 return list+1;
123 void *heap_pool_grow(heap_pool_t *heap, void *mem, DWORD size, DWORD inc)
125 void *ret;
127 if(mem == (BYTE*)heap->blocks[heap->last_block] + heap->offset-size
128 && heap->offset+inc < block_size(heap->last_block)) {
129 heap->offset += inc;
130 return mem;
133 ret = heap_pool_alloc(heap, size+inc);
134 if(ret) /* FIXME: avoid copying for custom blocks */
135 memcpy(ret, mem, size);
136 return ret;
139 void heap_pool_clear(heap_pool_t *heap)
141 struct list *tmp;
143 if(!heap)
144 return;
146 while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
147 list_remove(tmp);
148 heap_free(tmp);
151 if(WARN_ON(heap)) {
152 DWORD i;
154 for(i=0; i < heap->block_cnt; i++)
155 memset(heap->blocks[i], ARENA_FREE_FILLER, block_size(i));
158 heap->last_block = heap->offset = 0;
159 heap->mark = FALSE;
162 void heap_pool_free(heap_pool_t *heap)
164 DWORD i;
166 heap_pool_clear(heap);
168 for(i=0; i < heap->block_cnt; i++)
169 heap_free(heap->blocks[i]);
170 heap_free(heap->blocks);
172 heap_pool_init(heap);
175 heap_pool_t *heap_pool_mark(heap_pool_t *heap)
177 if(heap->mark)
178 return NULL;
180 heap->mark = TRUE;
181 return heap;
184 HRESULT get_dispatch_typeinfo(ITypeInfo **out)
186 ITypeInfo *typeinfo;
187 ITypeLib *typelib;
188 HRESULT hr;
190 if (!dispatch_typeinfo)
192 hr = LoadRegTypeLib(&IID_StdOle, STDOLE_MAJORVERNUM, STDOLE_MINORVERNUM, STDOLE_LCID, &typelib);
193 if (FAILED(hr)) return hr;
195 hr = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IDispatch, &typeinfo);
196 ITypeLib_Release(typelib);
197 if (FAILED(hr)) return hr;
199 if (InterlockedCompareExchangePointer((void**)&dispatch_typeinfo, typeinfo, NULL))
200 ITypeInfo_Release(typeinfo);
203 *out = dispatch_typeinfo;
204 return S_OK;
207 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
209 *ppv = NULL;
211 if(IsEqualGUID(&IID_IUnknown, riid)) {
212 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
213 *ppv = iface;
214 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
215 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
216 *ppv = iface;
219 if(*ppv) {
220 IUnknown_AddRef((IUnknown*)*ppv);
221 return S_OK;
224 FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
225 return E_NOINTERFACE;
228 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
230 TRACE("(%p)\n", iface);
231 return 2;
234 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
236 TRACE("(%p)\n", iface);
237 return 1;
240 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
242 TRACE("(%p)->(%x)\n", iface, fLock);
243 return S_OK;
246 static const IClassFactoryVtbl VBScriptFactoryVtbl = {
247 ClassFactory_QueryInterface,
248 ClassFactory_AddRef,
249 ClassFactory_Release,
250 VBScriptFactory_CreateInstance,
251 ClassFactory_LockServer
254 static IClassFactory VBScriptFactory = { &VBScriptFactoryVtbl };
256 static const IClassFactoryVtbl VBScriptRegExpFactoryVtbl = {
257 ClassFactory_QueryInterface,
258 ClassFactory_AddRef,
259 ClassFactory_Release,
260 VBScriptRegExpFactory_CreateInstance,
261 ClassFactory_LockServer
264 static IClassFactory VBScriptRegExpFactory = { &VBScriptRegExpFactoryVtbl };
266 /******************************************************************
267 * DllMain (vbscript.@)
269 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
271 TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv);
273 switch(fdwReason)
275 case DLL_PROCESS_ATTACH:
276 DisableThreadLibraryCalls(hInstDLL);
277 vbscript_hinstance = hInstDLL;
278 break;
279 case DLL_PROCESS_DETACH:
280 if (lpv) break;
281 if (dispatch_typeinfo) ITypeInfo_Release(dispatch_typeinfo);
282 release_regexp_typelib();
285 return TRUE;
288 /***********************************************************************
289 * DllGetClassObject (vbscript.@)
291 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
293 if(IsEqualGUID(&CLSID_VBScript, rclsid)) {
294 TRACE("(CLSID_VBScript %s %p)\n", debugstr_guid(riid), ppv);
295 return IClassFactory_QueryInterface(&VBScriptFactory, riid, ppv);
296 }else if(IsEqualGUID(&CLSID_VBScriptRegExp, rclsid)) {
297 TRACE("(CLSID_VBScriptRegExp %s %p)\n", debugstr_guid(riid), ppv);
298 return IClassFactory_QueryInterface(&VBScriptRegExpFactory, riid, ppv);
301 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
302 return CLASS_E_CLASSNOTAVAILABLE;