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;