vbscript: Added global object's isObject function stub implementation.
diff --git a/.gitignore b/.gitignore
index b1d82eb..b9a7636 100644
--- a/.gitignore
+++ b/.gitignore
@@ -125,6 +125,7 @@
dlls/vbscript/parser.tab.c
dlls/vbscript/parser.tab.h
dlls/vbscript/vbscript_classes.h
+dlls/vbscript/vbsglobal.h
dlls/windowscodecs/windowscodecs_wincodec.h
dlls/windowscodecs/windowscodecs_wincodec_p.c
include/activaut.h
diff --git a/dlls/vbscript/Makefile.in b/dlls/vbscript/Makefile.in
index bfc07b5..e1a8382 100644
--- a/dlls/vbscript/Makefile.in
+++ b/dlls/vbscript/Makefile.in
@@ -3,6 +3,7 @@
C_SRCS = \
compile.c \
+ global.c \
interp.c \
lex.c \
vbdisp.c \
@@ -14,8 +15,12 @@
RC_SRCS = vbscript.rc
+IDL_H_SRCS = \
+ vbscript_classes.idl \
+ vbsglobal.idl
+
IDL_TLB_SRCS = vbsglobal.idl
-IDL_H_SRCS = vbscript_classes.idl
+
IDL_R_SRCS = vbscript_classes.idl
@MAKE_DLL_RULES@
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index df08c24..1102378 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -107,6 +107,16 @@
return vbsheap_alloc(&vbscode->heap, size);
}
+static inline void *compiler_alloc_zero(vbscode_t *vbscode, size_t size)
+{
+ void *ret;
+
+ ret = vbsheap_alloc(&vbscode->heap, size);
+ if(ret)
+ memset(ret, 0, size);
+ return ret;
+}
+
static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
{
size_t size;
@@ -1006,7 +1016,7 @@
return E_FAIL;
}
- class_desc = compiler_alloc(ctx->code, sizeof(*class_desc));
+ class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
if(!class_desc)
return E_OUTOFMEMORY;
@@ -1015,9 +1025,6 @@
return E_OUTOFMEMORY;
class_desc->func_cnt = 1; /* always allocate slot for default getter */
- class_desc->prop_cnt = 0;
- class_desc->class_initialize_id = 0;
- class_desc->class_terminate_id = 0;
for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
new file mode 100644
index 0000000..87aef8f
--- /dev/null
+++ b/dlls/vbscript/global.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "vbscript.h"
+#include "vbscript_defs.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+
+static HRESULT Global_IsObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static const builtin_prop_t global_props[] = {
+ {DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1}
+};
+
+HRESULT init_global(script_ctx_t *ctx)
+{
+ HRESULT hres;
+
+ ctx->global_desc.ctx = ctx;
+ ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
+ ctx->global_desc.builtin_props = global_props;
+
+ hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
+ if(FAILED(hres))
+ return hres;
+
+ hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
+ if(FAILED(hres))
+ return hres;
+
+ ctx->script_desc.ctx = ctx;
+ hres = create_vbdisp(&ctx->script_desc, &ctx->script_obj);
+ if(FAILED(hres))
+ return hres;
+
+ return S_OK;
+}
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 472d23c..7c3df7d 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -147,6 +147,14 @@
}
}
+ hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, &id);
+ if(SUCCEEDED(hres)) {
+ ref->type = REF_DISP;
+ ref->u.d.disp = (IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
+ ref->u.d.id = id;
+ return S_OK;
+ }
+
if(!ctx->func->code_ctx->option_explicit)
FIXME("create an attempt to set\n");
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 19a511e..96df71a 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -69,6 +69,14 @@
}
}
+ if(This->desc->typeinfo) {
+ HRESULT hres;
+
+ hres = ITypeInfo_GetIDsOfNames(This->desc->typeinfo, &name, 1, id);
+ if(SUCCEEDED(hres))
+ return S_OK;
+ }
+
*id = -1;
return DISP_E_UNKNOWNNAME;
}
@@ -123,6 +131,36 @@
return hres;
}
+static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD flags, DISPPARAMS *dp, VARIANT *res)
+{
+ switch(flags) {
+ case DISPATCH_PROPERTYGET:
+ if(!(prop->flags & (BP_GET|BP_GETPUT))) {
+ FIXME("property does not support DISPATCH_PROPERTYGET\n");
+ return E_FAIL;
+ }
+ /* FALLTHROUGH */
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? prop->max_args : prop->min_args)) {
+ FIXME("invalid number of arguments\n");
+ return E_FAIL;
+ }
+
+ return prop->proc(This, dp->rgvarg, dp->cArgs, res);
+ case DISPATCH_PROPERTYPUT:
+ if(!(prop->flags & (BP_GET|BP_GETPUT))) {
+ FIXME("property does not support DISPATCH_PROPERTYPUT\n");
+ return E_FAIL;
+ }
+
+ FIXME("call put\n");
+ return E_NOTIMPL;
+ default:
+ FIXME("unsupported flags %x\n", flags);
+ return E_NOTIMPL;
+ }
+}
+
static BOOL run_terminator(vbdisp_t *This)
{
DISPPARAMS dp = {0};
@@ -322,6 +360,20 @@
if(id < This->desc->prop_cnt + This->desc->func_cnt)
return invoke_variant_prop(This, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
+ if(This->desc->builtin_prop_cnt) {
+ unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
+
+ while(min <= max) {
+ i = (min+max)/2;
+ if(This->desc->builtin_props[i].id == id)
+ return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes);
+ if(This->desc->builtin_props[i].id < id)
+ min = i+1;
+ else
+ max = i-1;
+ }
+ }
+
return DISP_E_MEMBERNOTFOUND;
}
@@ -436,12 +488,6 @@
}
}
-HRESULT init_global(script_ctx_t *ctx)
-{
- ctx->script_desc.ctx = ctx;
- return create_vbdisp(&ctx->script_desc, &ctx->script_obj);
-}
-
HRESULT disp_get_id(IDispatch *disp, BSTR name, vbdisp_invoke_type_t invoke_type, BOOL search_private, DISPID *id)
{
IDispatchEx *dispex;
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 8074799..9b61b93 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -131,6 +131,8 @@
IDispatch_Release(ctx->host_global);
if(ctx->site)
IActiveScriptSite_Release(ctx->site);
+ if(ctx->global_obj)
+ IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
if(ctx->script_obj)
IDispatchEx_Release(&ctx->script_obj->IDispatchEx_iface);
heap_free(ctx);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 6083511..5bd7ff9 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -46,6 +46,7 @@
typedef struct _function_t function_t;
typedef struct _vbscode_t vbscode_t;
typedef struct _script_ctx_t script_ctx_t;
+typedef struct _vbdisp_t vbdisp_t;
typedef struct named_item_t {
IDispatch *disp;
@@ -73,19 +74,37 @@
function_t *entries[VBDISP_ANY];
} vbdisp_funcprop_desc_t;
+#define BP_GET 1
+#define BP_GETPUT 2
+
+typedef struct {
+ DISPID id;
+ HRESULT (*proc)(vbdisp_t*,VARIANT*,unsigned,VARIANT*);
+ DWORD flags;
+ unsigned min_args;
+ unsigned max_args;
+} builtin_prop_t;
+
typedef struct _class_desc_t {
const WCHAR *name;
script_ctx_t *ctx;
+
unsigned class_initialize_id;
unsigned class_terminate_id;
unsigned func_cnt;
vbdisp_funcprop_desc_t *funcs;
+
unsigned prop_cnt;
vbdisp_prop_desc_t *props;
+
+ unsigned builtin_prop_cnt;
+ const builtin_prop_t *builtin_props;
+ ITypeInfo *typeinfo;
+
struct _class_desc_t *next;
} class_desc_t;
-typedef struct {
+struct _vbdisp_t {
IDispatchEx IDispatchEx_iface;
LONG ref;
@@ -94,10 +113,11 @@
const class_desc_t *desc;
VARIANT props[1];
-} vbdisp_t;
+};
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
+HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
void collect_objects(script_ctx_t*);
@@ -127,6 +147,9 @@
class_desc_t script_desc;
vbdisp_t *script_obj;
+ class_desc_t global_desc;
+ vbdisp_t *global_obj;
+
dynamic_var_t *global_vars;
function_t *global_funcs;
class_desc_t *classes;
@@ -268,6 +291,19 @@
HRESULT compile_script(script_ctx_t*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
HRESULT exec_script(script_ctx_t*,function_t*,IDispatch*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
+#define TID_LIST \
+ XDIID(ErrObj) \
+ XDIID(GlobalObj)
+
+typedef enum {
+#define XDIID(iface) iface ## _tid,
+TID_LIST
+#undef XDIID
+ LAST_tid
+} tid_t;
+
+HRESULT get_typeinfo(tid_t,ITypeInfo**);
+
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN;
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c
index 43ab484..4054d35 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -22,6 +22,7 @@
#include "objsafe.h"
#include "rpcproxy.h"
#include "vbscript_classes.h"
+#include "vbsglobal.h"
#include "wine/debug.h"
@@ -31,6 +32,66 @@
static HINSTANCE vbscript_hinstance;
+static ITypeLib *typelib;
+static ITypeInfo *typeinfos[LAST_tid];
+
+static REFIID tid_ids[] = {
+#define XDIID(iface) &DIID_ ## iface,
+TID_LIST
+#undef XDIID
+};
+
+HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
+{
+ HRESULT hres;
+
+ if (!typelib) {
+ ITypeLib *tl;
+
+ static const WCHAR vbscript_dll1W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','1',0};
+
+ hres = LoadTypeLib(vbscript_dll1W, &tl);
+ if(FAILED(hres)) {
+ ERR("LoadRegTypeLib failed: %08x\n", hres);
+ return hres;
+ }
+
+ if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
+ ITypeLib_Release(tl);
+ }
+
+ if(!typeinfos[tid]) {
+ ITypeInfo *ti;
+
+ hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
+ if(FAILED(hres)) {
+ ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
+ return hres;
+ }
+
+ if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
+ ITypeInfo_Release(ti);
+ }
+
+ *typeinfo = typeinfos[tid];
+ return S_OK;
+}
+
+static void release_typelib(void)
+{
+ unsigned i;
+
+ if(!typelib)
+ return;
+
+ for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) {
+ if(typeinfos[i])
+ ITypeInfo_Release(typeinfos[i]);
+ }
+
+ ITypeLib_Release(typelib);
+}
+
const char *debugstr_variant(const VARIANT *v)
{
if(!v)
@@ -210,6 +271,8 @@
DisableThreadLibraryCalls(hInstDLL);
vbscript_hinstance = hInstDLL;
break;
+ case DLL_PROCESS_DETACH:
+ release_typelib();
}
return TRUE;