Reactos
at master 308 lines 7.9 kB view raw
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 31WINE_DEFAULT_DEBUG_CHANNEL(vbscript); 32WINE_DECLARE_DEBUG_CHANNEL(heap); 33 34DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 35 36static HINSTANCE vbscript_hinstance; 37 38BSTR 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 45BSTR 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 56static inline DWORD block_size(DWORD block) 57{ 58 return MIN_BLOCK_SIZE << block; 59} 60 61void heap_pool_init(heap_pool_t *heap) 62{ 63 memset(heap, 0, sizeof(*heap)); 64 list_init(&heap->custom_blocks); 65} 66 67void *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 122void *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 138void 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 161void 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 174heap_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 183static 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 204static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) 205{ 206 TRACE("(%p)\n", iface); 207 return 2; 208} 209 210static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) 211{ 212 TRACE("(%p)\n", iface); 213 return 1; 214} 215 216static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) 217{ 218 TRACE("(%p)->(%x)\n", iface, fLock); 219 return S_OK; 220} 221 222static const IClassFactoryVtbl VBScriptFactoryVtbl = { 223 ClassFactory_QueryInterface, 224 ClassFactory_AddRef, 225 ClassFactory_Release, 226 VBScriptFactory_CreateInstance, 227 ClassFactory_LockServer 228}; 229 230static IClassFactory VBScriptFactory = { &VBScriptFactoryVtbl }; 231 232static const IClassFactoryVtbl VBScriptRegExpFactoryVtbl = { 233 ClassFactory_QueryInterface, 234 ClassFactory_AddRef, 235 ClassFactory_Release, 236 VBScriptRegExpFactory_CreateInstance, 237 ClassFactory_LockServer 238}; 239 240static IClassFactory VBScriptRegExpFactory = { &VBScriptRegExpFactoryVtbl }; 241 242/****************************************************************** 243 * DllMain (vbscript.@) 244 */ 245BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) 246{ 247 TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv); 248 249 switch(fdwReason) 250 { 251#ifndef __REACTOS__ 252 case DLL_WINE_PREATTACH: 253 return FALSE; /* prefer native version */ 254#endif 255 case DLL_PROCESS_ATTACH: 256 DisableThreadLibraryCalls(hInstDLL); 257 vbscript_hinstance = hInstDLL; 258 break; 259 case DLL_PROCESS_DETACH: 260 if (lpv) break; 261 release_regexp_typelib(); 262 } 263 264 return TRUE; 265} 266 267/*********************************************************************** 268 * DllGetClassObject (vbscript.@) 269 */ 270HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 271{ 272 if(IsEqualGUID(&CLSID_VBScript, rclsid)) { 273 TRACE("(CLSID_VBScript %s %p)\n", debugstr_guid(riid), ppv); 274 return IClassFactory_QueryInterface(&VBScriptFactory, riid, ppv); 275 }else if(IsEqualGUID(&CLSID_VBScriptRegExp, rclsid)) { 276 TRACE("(CLSID_VBScriptRegExp %s %p)\n", debugstr_guid(riid), ppv); 277 return IClassFactory_QueryInterface(&VBScriptRegExpFactory, riid, ppv); 278 } 279 280 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 281 return CLASS_E_CLASSNOTAVAILABLE; 282} 283 284/*********************************************************************** 285 * DllCanUnloadNow (vbscript.@) 286 */ 287HRESULT WINAPI DllCanUnloadNow(void) 288{ 289 return S_FALSE; 290} 291 292/*********************************************************************** 293 * DllRegisterServer (vbscript.@) 294 */ 295HRESULT WINAPI DllRegisterServer(void) 296{ 297 TRACE("()\n"); 298 return __wine_register_resources(vbscript_hinstance); 299} 300 301/*********************************************************************** 302 * DllUnregisterServer (vbscript.@) 303 */ 304HRESULT WINAPI DllUnregisterServer(void) 305{ 306 TRACE("()\n"); 307 return __wine_unregister_resources(vbscript_hinstance); 308}