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
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
)
42 if(!LoadStringW(vbscript_hinstance
, id
, buf
, ARRAY_SIZE(buf
))) return NULL
;
43 return SysAllocString(buf
);
46 BSTR
get_vbscript_error_string(HRESULT error
)
49 if(HRESULT_FACILITY(error
) != FACILITY_VBS
|| !(ret
= get_vbscript_string(HRESULT_CODE(error
))))
50 ret
= get_vbscript_string(VBS_UNKNOWN_RUNTIME_ERROR
);
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
)
75 if(!heap
->block_cnt
) {
77 heap
->blocks
= heap_alloc(sizeof(void*));
82 tmp
= heap_alloc(block_size(0));
86 heap
->blocks
[0] = tmp
;
90 if(heap
->offset
+ size
<= block_size(heap
->last_block
)) {
91 tmp
= ((BYTE
*)heap
->blocks
[heap
->last_block
])+heap
->offset
;
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*));
103 heap
->blocks
[heap
->block_cnt
] = heap_alloc(block_size(heap
->block_cnt
));
104 if(!heap
->blocks
[heap
->block_cnt
])
112 return heap
->blocks
[heap
->last_block
];
115 list
= heap_alloc(size
+ sizeof(struct list
));
119 list_add_head(&heap
->custom_blocks
, list
);
123 void *heap_pool_grow(heap_pool_t
*heap
, void *mem
, DWORD size
, DWORD inc
)
127 if(mem
== (BYTE
*)heap
->blocks
[heap
->last_block
] + heap
->offset
-size
128 && heap
->offset
+inc
< block_size(heap
->last_block
)) {
133 ret
= heap_pool_alloc(heap
, size
+inc
);
134 if(ret
) /* FIXME: avoid copying for custom blocks */
135 memcpy(ret
, mem
, size
);
139 void heap_pool_clear(heap_pool_t
*heap
)
146 while((tmp
= list_next(&heap
->custom_blocks
, &heap
->custom_blocks
))) {
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;
162 void heap_pool_free(heap_pool_t
*heap
)
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
)
184 HRESULT
get_dispatch_typeinfo(ITypeInfo
**out
)
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
;
207 static HRESULT WINAPI
ClassFactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
211 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
212 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
214 }else if(IsEqualGUID(&IID_IClassFactory
, riid
)) {
215 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
220 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
234 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
236 TRACE("(%p)\n", iface
);
240 static HRESULT WINAPI
ClassFactory_LockServer(IClassFactory
*iface
, BOOL fLock
)
242 TRACE("(%p)->(%x)\n", iface
, fLock
);
246 static const IClassFactoryVtbl VBScriptFactoryVtbl
= {
247 ClassFactory_QueryInterface
,
249 ClassFactory_Release
,
250 VBScriptFactory_CreateInstance
,
251 ClassFactory_LockServer
254 static IClassFactory VBScriptFactory
= { &VBScriptFactoryVtbl
};
256 static const IClassFactoryVtbl VBScriptRegExpFactoryVtbl
= {
257 ClassFactory_QueryInterface
,
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
);
275 case DLL_WINE_PREATTACH
:
276 return FALSE
; /* prefer native version */
277 case DLL_PROCESS_ATTACH
:
278 DisableThreadLibraryCalls(hInstDLL
);
279 vbscript_hinstance
= hInstDLL
;
281 case DLL_PROCESS_DETACH
:
283 if (dispatch_typeinfo
) ITypeInfo_Release(dispatch_typeinfo
);
284 release_regexp_typelib();
290 /***********************************************************************
291 * DllGetClassObject (vbscript.@)
293 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
295 if(IsEqualGUID(&CLSID_VBScript
, rclsid
)) {
296 TRACE("(CLSID_VBScript %s %p)\n", debugstr_guid(riid
), ppv
);
297 return IClassFactory_QueryInterface(&VBScriptFactory
, riid
, ppv
);
298 }else if(IsEqualGUID(&CLSID_VBScriptRegExp
, rclsid
)) {
299 TRACE("(CLSID_VBScriptRegExp %s %p)\n", debugstr_guid(riid
), ppv
);
300 return IClassFactory_QueryInterface(&VBScriptRegExpFactory
, riid
, ppv
);
303 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
304 return CLASS_E_CLASSNOTAVAILABLE
;
307 /***********************************************************************
308 * DllCanUnloadNow (vbscript.@)
310 HRESULT WINAPI
DllCanUnloadNow(void)
315 /***********************************************************************
316 * DllRegisterServer (vbscript.@)
318 HRESULT WINAPI
DllRegisterServer(void)
321 return __wine_register_resources(vbscript_hinstance
);
324 /***********************************************************************
325 * DllUnregisterServer (vbscript.@)
327 HRESULT WINAPI
DllUnregisterServer(void)
330 return __wine_unregister_resources(vbscript_hinstance
);