vbscript: Implemented Log.
[wine.git] / dlls / vbscript / global.c
blob666334346fe54c59602f59781e680b74a230c91a
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 <assert.h>
20 #include <math.h>
22 #include "vbscript.h"
23 #include "vbscript_defs.h"
25 #include "mshtmhst.h"
26 #include "objsafe.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
32 #define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
33 #define VB_E_MK_PARSE_ERROR 0x800a01b0
35 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
36 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
37 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
39 static const WCHAR emptyW[] = {0};
40 static const WCHAR vbscriptW[] = {'V','B','S','c','r','i','p','t',0};
42 static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
44 IInternetHostSecurityManager *secmgr;
45 IServiceProvider *sp;
46 HRESULT hres;
48 if(!ctx->site)
49 return NULL;
51 if(ctx->secmgr)
52 return ctx->secmgr;
54 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
55 if(FAILED(hres))
56 return NULL;
58 hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
59 (void**)&secmgr);
60 IServiceProvider_Release(sp);
61 if(FAILED(hres))
62 return NULL;
64 return ctx->secmgr = secmgr;
67 static HRESULT return_string(VARIANT *res, const WCHAR *str)
69 BSTR ret;
71 if(!res)
72 return S_OK;
74 ret = SysAllocString(str);
75 if(!ret)
76 return E_OUTOFMEMORY;
78 V_VT(res) = VT_BSTR;
79 V_BSTR(res) = ret;
80 return S_OK;
83 static HRESULT return_bstr(VARIANT *res, BSTR str)
85 if(res) {
86 V_VT(res) = VT_BSTR;
87 V_BSTR(res) = str;
88 }else {
89 SysFreeString(str);
91 return S_OK;
94 static HRESULT return_bool(VARIANT *res, BOOL val)
96 if(res) {
97 V_VT(res) = VT_BOOL;
98 V_BOOL(res) = val ? VARIANT_TRUE : VARIANT_FALSE;
100 return S_OK;
103 static HRESULT return_short(VARIANT *res, short val)
105 if(res) {
106 V_VT(res) = VT_I2;
107 V_I2(res) = val;
110 return S_OK;
113 static HRESULT return_int(VARIANT *res, int val)
115 if((short)val == val)
116 return return_short(res, val);
118 if(res) {
119 V_VT(res) = VT_I4;
120 V_I4(res) = val;
123 return S_OK;
126 static inline HRESULT return_double(VARIANT *res, double val)
128 if(res) {
129 V_VT(res) = VT_R8;
130 V_R8(res) = val;
133 return S_OK;
136 static inline HRESULT return_null(VARIANT *res)
138 if(res)
139 V_VT(res) = VT_NULL;
140 return S_OK;
143 static inline HRESULT return_date(VARIANT *res, double date)
145 if(res) {
146 V_VT(res) = VT_DATE;
147 V_DATE(res) = date;
149 return S_OK;
152 HRESULT to_int(VARIANT *v, int *ret)
154 VARIANT r;
155 HRESULT hres;
157 V_VT(&r) = VT_EMPTY;
158 hres = VariantChangeType(&r, v, 0, VT_I4);
159 if(FAILED(hres))
160 return hres;
162 *ret = V_I4(&r);
163 return S_OK;
166 static HRESULT to_double(VARIANT *v, double *ret)
168 VARIANT dst;
169 HRESULT hres;
171 V_VT(&dst) = VT_EMPTY;
172 hres = VariantChangeType(&dst, v, 0, VT_R8);
173 if(FAILED(hres))
174 return hres;
176 *ret = V_R8(&dst);
177 return S_OK;
180 static HRESULT to_string(VARIANT *v, BSTR *ret)
182 VARIANT dst;
183 HRESULT hres;
185 V_VT(&dst) = VT_EMPTY;
186 hres = VariantChangeType(&dst, v, VARIANT_LOCALBOOL, VT_BSTR);
187 if(FAILED(hres))
188 return hres;
190 *ret = V_BSTR(&dst);
191 return S_OK;
194 static HRESULT set_object_site(script_ctx_t *ctx, IUnknown *obj)
196 IObjectWithSite *obj_site;
197 IUnknown *ax_site;
198 HRESULT hres;
200 hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
201 if(FAILED(hres))
202 return S_OK;
204 ax_site = create_ax_site(ctx);
205 if(ax_site)
206 hres = IObjectWithSite_SetSite(obj_site, ax_site);
207 else
208 hres = E_OUTOFMEMORY;
209 IUnknown_Release(ax_site);
210 IObjectWithSite_Release(obj_site);
211 return hres;
214 static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
216 IInternetHostSecurityManager *secmgr = NULL;
217 struct CONFIRMSAFETY cs;
218 IClassFactoryEx *cfex;
219 IClassFactory *cf;
220 DWORD policy_size;
221 BYTE *bpolicy;
222 IUnknown *obj;
223 DWORD policy;
224 GUID guid;
225 HRESULT hres;
227 hres = CLSIDFromProgID(progid, &guid);
228 if(FAILED(hres))
229 return NULL;
231 TRACE("GUID %s\n", debugstr_guid(&guid));
233 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
234 secmgr = get_sec_mgr(ctx);
235 if(!secmgr)
236 return NULL;
238 policy = 0;
239 hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN,
240 (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0);
241 if(FAILED(hres) || policy != URLPOLICY_ALLOW)
242 return NULL;
245 hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
246 if(FAILED(hres))
247 return NULL;
249 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
250 if(SUCCEEDED(hres)) {
251 FIXME("Use IClassFactoryEx\n");
252 IClassFactoryEx_Release(cfex);
255 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
256 if(FAILED(hres))
257 return NULL;
259 if(secmgr) {
260 cs.clsid = guid;
261 cs.pUnk = obj;
262 cs.dwFlags = 0;
263 hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
264 &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
265 if(SUCCEEDED(hres)) {
266 policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW;
267 CoTaskMemFree(bpolicy);
270 if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
271 IUnknown_Release(obj);
272 return NULL;
276 hres = set_object_site(ctx, obj);
277 if(FAILED(hres)) {
278 IUnknown_Release(obj);
279 return NULL;
282 return obj;
285 static HRESULT show_msgbox(script_ctx_t *ctx, BSTR prompt, unsigned type, BSTR orig_title, VARIANT *res)
287 SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_ALLOW;
288 IActiveScriptSiteUIControl *ui_control;
289 IActiveScriptSiteWindow *acts_window;
290 WCHAR *title_buf = NULL;
291 const WCHAR *title;
292 HWND hwnd = NULL;
293 int ret = 0;
294 HRESULT hres;
296 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteUIControl, (void**)&ui_control);
297 if(SUCCEEDED(hres)) {
298 hres = IActiveScriptSiteUIControl_GetUIBehavior(ui_control, SCRIPTUICITEM_MSGBOX, &uic_handling);
299 IActiveScriptSiteUIControl_Release(ui_control);
300 if(FAILED(hres))
301 uic_handling = SCRIPTUICHANDLING_ALLOW;
304 switch(uic_handling) {
305 case SCRIPTUICHANDLING_ALLOW:
306 break;
307 case SCRIPTUICHANDLING_NOUIDEFAULT:
308 return return_short(res, 0);
309 default:
310 FIXME("blocked\n");
311 return E_FAIL;
314 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteWindow, (void**)&acts_window);
315 if(FAILED(hres)) {
316 FIXME("No IActiveScriptSiteWindow\n");
317 return hres;
320 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
321 if(orig_title && *orig_title) {
322 WCHAR *ptr;
324 title = title_buf = heap_alloc(sizeof(vbscriptW) + (strlenW(orig_title)+2)*sizeof(WCHAR));
325 if(!title)
326 return E_OUTOFMEMORY;
328 memcpy(title_buf, vbscriptW, sizeof(vbscriptW));
329 ptr = title_buf + sizeof(vbscriptW)/sizeof(WCHAR)-1;
331 *ptr++ = ':';
332 *ptr++ = ' ';
333 strcpyW(ptr, orig_title);
334 }else {
335 title = vbscriptW;
337 }else {
338 title = orig_title ? orig_title : emptyW;
341 hres = IActiveScriptSiteWindow_GetWindow(acts_window, &hwnd);
342 if(SUCCEEDED(hres)) {
343 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, FALSE);
344 if(SUCCEEDED(hres)) {
345 ret = MessageBoxW(hwnd, prompt, title, type);
346 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, TRUE);
350 heap_free(title_buf);
351 IActiveScriptSiteWindow_Release(acts_window);
352 if(FAILED(hres)) {
353 FIXME("failed: %08x\n", hres);
354 return hres;
357 return return_short(res, ret);
360 static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
362 VARIANT v;
363 HRESULT hres;
365 TRACE("%s\n", debugstr_variant(arg));
367 assert(args_cnt == 1);
369 V_VT(&v) = VT_EMPTY;
370 hres = VariantChangeType(&v, arg, 0, VT_CY);
371 if(FAILED(hres))
372 return hres;
374 if(!res) {
375 VariantClear(&v);
376 return DISP_E_BADVARTYPE;
379 *res = v;
380 return S_OK;
383 static HRESULT Global_CInt(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
385 VARIANT v;
386 HRESULT hres;
388 TRACE("%s\n", debugstr_variant(arg));
390 assert(args_cnt == 1);
392 V_VT(&v) = VT_EMPTY;
393 hres = VariantChangeType(&v, arg, 0, VT_I2);
394 if(FAILED(hres))
395 return hres;
397 if(!res)
398 return DISP_E_BADVARTYPE;
399 else {
400 *res = v;
401 return S_OK;
405 static HRESULT Global_CLng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
407 int i;
408 HRESULT hres;
410 TRACE("%s\n", debugstr_variant(arg));
412 assert(args_cnt == 1);
414 hres = to_int(arg, &i);
415 if(FAILED(hres))
416 return hres;
417 if(!res)
418 return DISP_E_BADVARTYPE;
420 V_VT(res) = VT_I4;
421 V_I4(res) = i;
422 return S_OK;
425 static HRESULT Global_CBool(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
427 VARIANT v;
428 HRESULT hres;
430 TRACE("%s\n", debugstr_variant(arg));
432 assert(args_cnt == 1);
434 V_VT(&v) = VT_EMPTY;
435 hres = VariantChangeType(&v, arg, VARIANT_LOCALBOOL, VT_BOOL);
436 if(FAILED(hres))
437 return hres;
439 if(res)
440 *res = v;
441 else
442 VariantClear(&v);
443 return S_OK;
446 static HRESULT Global_CByte(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
448 VARIANT v;
449 HRESULT hres;
451 TRACE("%s\n", debugstr_variant(arg));
453 assert(args_cnt == 1);
455 V_VT(&v) = VT_EMPTY;
456 hres = VariantChangeType(&v, arg, VARIANT_LOCALBOOL, VT_UI1);
457 if(FAILED(hres))
458 return hres;
460 if(!res) {
461 VariantClear(&v);
462 return DISP_E_BADVARTYPE;
465 *res = v;
466 return S_OK;
469 static HRESULT Global_CDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
471 FIXME("\n");
472 return E_NOTIMPL;
475 static HRESULT Global_CDbl(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
477 VARIANT v;
478 HRESULT hres;
480 TRACE("%s\n", debugstr_variant(arg));
482 assert(args_cnt == 1);
484 V_VT(&v) = VT_EMPTY;
485 hres = VariantChangeType(&v, arg, 0, VT_R8);
486 if(FAILED(hres))
487 return hres;
489 if(!res)
490 return DISP_E_BADVARTYPE;
491 else {
492 *res = v;
493 return S_OK;
497 static HRESULT Global_CSng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
499 VARIANT v;
500 HRESULT hres;
502 TRACE("%s\n", debugstr_variant(arg));
504 assert(args_cnt == 1);
506 V_VT(&v) = VT_EMPTY;
507 hres = VariantChangeType(&v, arg, 0, VT_R4);
508 if(FAILED(hres))
509 return hres;
511 if(!res)
512 return DISP_E_BADVARTYPE;
514 *res = v;
515 return S_OK;
518 static HRESULT Global_CStr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
520 BSTR str;
521 HRESULT hres;
523 TRACE("%s\n", debugstr_variant(arg));
525 hres = to_string(arg, &str);
526 if(FAILED(hres))
527 return hres;
529 return return_bstr(res, str);
532 static inline WCHAR hex_char(unsigned n)
534 return n < 10 ? '0'+n : 'A'+n-10;
537 static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
539 WCHAR buf[17], *ptr;
540 DWORD n;
542 TRACE("%s\n", debugstr_variant(arg));
544 switch(V_VT(arg)) {
545 case VT_I2:
546 n = (WORD)V_I2(arg);
547 break;
548 case VT_I4:
549 n = V_I4(arg);
550 break;
551 case VT_EMPTY:
552 n = 0;
553 break;
554 case VT_NULL:
555 if(res)
556 V_VT(res) = VT_NULL;
557 return S_OK;
558 default:
559 FIXME("unsupported type %s\n", debugstr_variant(arg));
560 return E_NOTIMPL;
563 buf[16] = 0;
564 ptr = buf+15;
566 if(n) {
567 do {
568 *ptr-- = hex_char(n & 0xf);
569 n >>= 4;
570 }while(n);
571 ptr++;
572 }else {
573 *ptr = '0';
576 return return_string(res, ptr);
579 static HRESULT Global_Oct(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
581 FIXME("\n");
582 return E_NOTIMPL;
585 static HRESULT Global_VarType(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
587 TRACE("(%s)\n", debugstr_variant(arg));
589 assert(args_cnt == 1);
591 if(V_VT(arg) & ~VT_TYPEMASK) {
592 FIXME("not supported %s\n", debugstr_variant(arg));
593 return E_NOTIMPL;
596 return return_short(res, V_VT(arg));
599 static HRESULT Global_IsDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
601 FIXME("\n");
602 return E_NOTIMPL;
605 static HRESULT Global_IsEmpty(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
607 TRACE("(%s)\n", debugstr_variant(arg));
609 assert(args_cnt == 1);
611 if(res) {
612 V_VT(res) = VT_BOOL;
613 V_BOOL(res) = V_VT(arg) == VT_EMPTY ? VARIANT_TRUE : VARIANT_FALSE;
615 return S_OK;
618 static HRESULT Global_IsNull(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
620 TRACE("(%s)\n", debugstr_variant(arg));
622 assert(args_cnt == 1);
624 if(res) {
625 V_VT(res) = VT_BOOL;
626 V_BOOL(res) = V_VT(arg) == VT_NULL ? VARIANT_TRUE : VARIANT_FALSE;
628 return S_OK;
631 static HRESULT Global_IsNumeric(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
633 HRESULT hres;
634 double d;
636 TRACE("(%s)\n", debugstr_variant(arg));
638 assert(args_cnt == 1);
640 hres = to_double(arg, &d);
642 return return_bool(res, SUCCEEDED(hres));
645 static HRESULT Global_IsArray(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
647 FIXME("\n");
648 return E_NOTIMPL;
651 static HRESULT Global_IsObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
653 TRACE("(%s)\n", debugstr_variant(arg));
655 assert(args_cnt == 1);
657 if(res) {
658 V_VT(res) = VT_BOOL;
659 V_BOOL(res) = V_VT(arg) == VT_DISPATCH ? VARIANT_TRUE : VARIANT_FALSE;
661 return S_OK;
664 static HRESULT Global_Atn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
666 HRESULT hres;
667 double d;
669 hres = to_double(arg, &d);
670 if(FAILED(hres))
671 return hres;
673 return return_double(res, atan(d));
676 static HRESULT Global_Cos(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
678 HRESULT hres;
679 double d;
681 hres = to_double(arg, &d);
682 if(FAILED(hres))
683 return hres;
685 return return_double(res, cos(d));
688 static HRESULT Global_Sin(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
690 HRESULT hres;
691 double d;
693 hres = to_double(arg, &d);
694 if(FAILED(hres))
695 return hres;
697 return return_double(res, sin(d));
700 static HRESULT Global_Tan(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
702 HRESULT hres;
703 double d;
705 hres = to_double(arg, &d);
706 if(FAILED(hres))
707 return hres;
709 return return_double(res, tan(d));
712 static HRESULT Global_Exp(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
714 HRESULT hres;
715 double d;
717 hres = to_double(arg, &d);
718 if(FAILED(hres))
719 return hres;
721 return return_double(res, exp(d));
724 static HRESULT Global_Log(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
726 HRESULT hres;
727 double d;
729 hres = to_double(arg, &d);
730 if(FAILED(hres))
731 return hres;
733 if(d <= 0)
734 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
735 else
736 return return_double(res, log(d));
739 static HRESULT Global_Sqr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
741 HRESULT hres;
742 double d;
744 hres = to_double(arg, &d);
745 if(FAILED(hres))
746 return hres;
748 if(d < 0)
749 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
750 else
751 return return_double(res, sqrt(d));
754 static HRESULT Global_Randomize(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
756 FIXME("\n");
757 return E_NOTIMPL;
760 static HRESULT Global_Rnd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
762 FIXME("\n");
763 return E_NOTIMPL;
766 static HRESULT Global_Timer(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
768 FIXME("\n");
769 return E_NOTIMPL;
772 static HRESULT Global_LBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
774 FIXME("\n");
775 return E_NOTIMPL;
778 static HRESULT Global_UBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
780 FIXME("\n");
781 return E_NOTIMPL;
784 static HRESULT Global_RGB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
786 FIXME("\n");
787 return E_NOTIMPL;
790 static HRESULT Global_Len(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
792 DWORD len;
793 HRESULT hres;
795 TRACE("%s\n", debugstr_variant(arg));
797 if(V_VT(arg) == VT_NULL)
798 return return_null(res);
800 if(V_VT(arg) != VT_BSTR) {
801 BSTR str;
803 hres = to_string(arg, &str);
804 if(FAILED(hres))
805 return hres;
807 len = SysStringLen(str);
808 SysFreeString(str);
809 }else {
810 len = SysStringLen(V_BSTR(arg));
813 return return_int(res, len);
816 static HRESULT Global_LenB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
818 FIXME("\n");
819 return E_NOTIMPL;
822 static HRESULT Global_Left(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
824 BSTR str, ret, conv_str = NULL;
825 int len, str_len;
826 HRESULT hres;
828 TRACE("(%s %s)\n", debugstr_variant(args+1), debugstr_variant(args));
830 if(V_VT(args) == VT_BSTR) {
831 str = V_BSTR(args);
832 }else {
833 hres = to_string(args, &conv_str);
834 if(FAILED(hres))
835 return hres;
836 str = conv_str;
839 hres = to_int(args+1, &len);
840 if(FAILED(hres))
841 return hres;
843 if(len < 0) {
844 FIXME("len = %d\n", len);
845 return E_FAIL;
848 str_len = SysStringLen(str);
849 if(len > str_len)
850 len = str_len;
852 ret = SysAllocStringLen(str, len);
853 SysFreeString(conv_str);
854 if(!ret)
855 return E_OUTOFMEMORY;
857 return return_bstr(res, ret);
860 static HRESULT Global_LeftB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
862 FIXME("\n");
863 return E_NOTIMPL;
866 static HRESULT Global_Right(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
868 BSTR str, ret, conv_str = NULL;
869 int len, str_len;
870 HRESULT hres;
872 TRACE("(%s %s)\n", debugstr_variant(args), debugstr_variant(args+1));
874 if(V_VT(args+1) == VT_BSTR) {
875 str = V_BSTR(args);
876 }else {
877 hres = to_string(args, &conv_str);
878 if(FAILED(hres))
879 return hres;
880 str = conv_str;
883 hres = to_int(args+1, &len);
884 if(FAILED(hres))
885 return hres;
887 if(len < 0) {
888 FIXME("len = %d\n", len);
889 return E_FAIL;
892 str_len = SysStringLen(str);
893 if(len > str_len)
894 len = str_len;
896 ret = SysAllocStringLen(str+str_len-len, len);
897 SysFreeString(conv_str);
898 if(!ret)
899 return E_OUTOFMEMORY;
901 return return_bstr(res, ret);
904 static HRESULT Global_RightB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
906 FIXME("\n");
907 return E_NOTIMPL;
910 static HRESULT Global_Mid(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
912 int len = -1, start, str_len;
913 BSTR str;
914 HRESULT hres;
916 TRACE("(%s %s ...)\n", debugstr_variant(args), debugstr_variant(args+1));
918 assert(args_cnt == 2 || args_cnt == 3);
920 if(V_VT(args) != VT_BSTR) {
921 FIXME("args[0] = %s\n", debugstr_variant(args));
922 return E_NOTIMPL;
925 str = V_BSTR(args);
927 hres = to_int(args+1, &start);
928 if(FAILED(hres))
929 return hres;
931 if(args_cnt == 3) {
932 hres = to_int(args+2, &len);
933 if(FAILED(hres))
934 return hres;
936 if(len < 0) {
937 FIXME("len = %d\n", len);
938 return E_FAIL;
943 str_len = SysStringLen(str);
944 start--;
945 if(start > str_len)
946 start = str_len;
948 if(len == -1)
949 len = str_len-start;
950 else if(len > str_len-start)
951 len = str_len-start;
953 if(res) {
954 V_VT(res) = VT_BSTR;
955 V_BSTR(res) = SysAllocStringLen(str+start, len);
956 if(!V_BSTR(res))
957 return E_OUTOFMEMORY;
960 return S_OK;
963 static HRESULT Global_MidB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
965 FIXME("\n");
966 return E_NOTIMPL;
969 static HRESULT Global_StrComp(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
971 FIXME("\n");
972 return E_NOTIMPL;
975 static HRESULT Global_LCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
977 BSTR str;
978 HRESULT hres;
980 TRACE("%s\n", debugstr_variant(arg));
982 if(V_VT(arg) == VT_NULL) {
983 if(res)
984 V_VT(res) = VT_NULL;
985 return S_OK;
988 hres = to_string(arg, &str);
989 if(FAILED(hres))
990 return hres;
992 if(res) {
993 WCHAR *ptr;
995 for(ptr = str; *ptr; ptr++)
996 *ptr = tolowerW(*ptr);
998 V_VT(res) = VT_BSTR;
999 V_BSTR(res) = str;
1000 }else {
1001 SysFreeString(str);
1003 return S_OK;
1006 static HRESULT Global_UCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1008 BSTR str;
1009 HRESULT hres;
1011 TRACE("%s\n", debugstr_variant(arg));
1013 if(V_VT(arg) == VT_NULL) {
1014 if(res)
1015 V_VT(res) = VT_NULL;
1016 return S_OK;
1019 hres = to_string(arg, &str);
1020 if(FAILED(hres))
1021 return hres;
1023 if(res) {
1024 WCHAR *ptr;
1026 for(ptr = str; *ptr; ptr++)
1027 *ptr = toupperW(*ptr);
1029 V_VT(res) = VT_BSTR;
1030 V_BSTR(res) = str;
1031 }else {
1032 SysFreeString(str);
1034 return S_OK;
1037 static HRESULT Global_LTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1039 BSTR str, conv_str = NULL;
1040 WCHAR *ptr;
1041 HRESULT hres;
1043 TRACE("%s\n", debugstr_variant(arg));
1045 if(V_VT(arg) == VT_BSTR) {
1046 str = V_BSTR(arg);
1047 }else {
1048 hres = to_string(arg, &conv_str);
1049 if(FAILED(hres))
1050 return hres;
1051 str = conv_str;
1054 for(ptr = str; *ptr && isspaceW(*ptr); ptr++);
1056 str = SysAllocString(ptr);
1057 SysFreeString(conv_str);
1058 if(!str)
1059 return E_OUTOFMEMORY;
1061 return return_bstr(res, str);
1064 static HRESULT Global_RTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1066 BSTR str, conv_str = NULL;
1067 WCHAR *ptr;
1068 HRESULT hres;
1070 TRACE("%s\n", debugstr_variant(arg));
1072 if(V_VT(arg) == VT_BSTR) {
1073 str = V_BSTR(arg);
1074 }else {
1075 hres = to_string(arg, &conv_str);
1076 if(FAILED(hres))
1077 return hres;
1078 str = conv_str;
1081 for(ptr = str+SysStringLen(str); ptr-1 > str && isspaceW(*(ptr-1)); ptr--);
1083 str = SysAllocStringLen(str, ptr-str);
1084 SysFreeString(conv_str);
1085 if(!str)
1086 return E_OUTOFMEMORY;
1088 return return_bstr(res, str);
1091 static HRESULT Global_Trim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1093 BSTR str, conv_str = NULL;
1094 WCHAR *begin_ptr, *end_ptr;
1095 HRESULT hres;
1097 TRACE("%s\n", debugstr_variant(arg));
1099 if(V_VT(arg) == VT_BSTR) {
1100 str = V_BSTR(arg);
1101 }else {
1102 hres = to_string(arg, &conv_str);
1103 if(FAILED(hres))
1104 return hres;
1105 str = conv_str;
1108 for(begin_ptr = str; *begin_ptr && isspaceW(*begin_ptr); begin_ptr++);
1109 for(end_ptr = str+SysStringLen(str); end_ptr-1 > begin_ptr && isspaceW(*(end_ptr-1)); end_ptr--);
1111 str = SysAllocStringLen(begin_ptr, end_ptr-begin_ptr);
1112 SysFreeString(conv_str);
1113 if(!str)
1114 return E_OUTOFMEMORY;
1116 return return_bstr(res, str);
1119 static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1121 BSTR str;
1122 int n, i;
1123 HRESULT hres;
1125 TRACE("%s\n", debugstr_variant(arg));
1127 hres = to_int(arg, &n);
1128 if(FAILED(hres))
1129 return hres;
1131 if(n < 0) {
1132 FIXME("n = %d\n", n);
1133 return E_NOTIMPL;
1136 if(!res)
1137 return S_OK;
1139 str = SysAllocStringLen(NULL, n);
1140 if(!str)
1141 return E_OUTOFMEMORY;
1143 for(i=0; i<n; i++)
1144 str[i] = ' ';
1146 V_VT(res) = VT_BSTR;
1147 V_BSTR(res) = str;
1148 return S_OK;
1151 static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1153 FIXME("\n");
1154 return E_NOTIMPL;
1157 static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1159 VARIANT *startv, *str1v, *str2v;
1160 BSTR str1, str2;
1161 int start, ret;
1162 HRESULT hres;
1164 TRACE("\n");
1166 assert(2 <= args_cnt && args_cnt <= 4);
1168 switch(args_cnt) {
1169 case 2:
1170 startv = NULL;
1171 str1v = args;
1172 str2v = args+1;
1173 break;
1174 case 3:
1175 startv = args;
1176 str1v = args+1;
1177 str2v = args+2;
1178 break;
1179 case 4:
1180 FIXME("unsupported compare argument %s\n", debugstr_variant(args));
1181 return E_NOTIMPL;
1182 DEFAULT_UNREACHABLE;
1185 if(startv) {
1186 hres = to_int(startv, &start);
1187 if(FAILED(hres))
1188 return hres;
1189 if(--start < 0) {
1190 FIXME("start %d\n", start);
1191 return E_FAIL;
1193 }else {
1194 start = 0;
1197 if(V_VT(str1v) == VT_NULL || V_VT(str2v) == VT_NULL)
1198 return return_null(res);
1200 if(V_VT(str1v) != VT_BSTR) {
1201 FIXME("Unsupported str1 type %s\n", debugstr_variant(str1v));
1202 return E_NOTIMPL;
1204 str1 = V_BSTR(str1v);
1206 if(V_VT(str2v) != VT_BSTR) {
1207 FIXME("Unsupported str2 type %s\n", debugstr_variant(str2v));
1208 return E_NOTIMPL;
1210 str2 = V_BSTR(str2v);
1212 if(start < SysStringLen(str1)) {
1213 WCHAR *ptr;
1215 ptr = strstrW(str1+start, str2);
1216 ret = ptr ? ptr-str1+1 : 0;
1217 }else {
1218 ret = 0;
1221 return return_int(res, ret);
1224 static HRESULT Global_InStrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1226 FIXME("\n");
1227 return E_NOTIMPL;
1230 static HRESULT Global_AscB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1232 FIXME("\n");
1233 return E_NOTIMPL;
1236 static HRESULT Global_ChrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1238 FIXME("\n");
1239 return E_NOTIMPL;
1242 static HRESULT Global_Asc(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1244 FIXME("\n");
1245 return E_NOTIMPL;
1248 /* The function supports only single-byte and double-byte character sets. It
1249 * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
1250 * to be in range of short or unsigned short. */
1251 static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1253 int cp, c, len = 0;
1254 CPINFO cpi;
1255 WCHAR ch;
1256 char buf[2];
1257 HRESULT hres;
1259 TRACE("%s\n", debugstr_variant(arg));
1261 hres = to_int(arg, &c);
1262 if(FAILED(hres))
1263 return hres;
1265 cp = GetACP();
1266 if(!GetCPInfo(cp, &cpi))
1267 cpi.MaxCharSize = 1;
1269 if((c!=(short)c && c!=(unsigned short)c) ||
1270 (unsigned short)c>=(cpi.MaxCharSize>1 ? 0x10000 : 0x100)) {
1271 WARN("invalid arg %d\n", c);
1272 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
1275 if(c>>8)
1276 buf[len++] = c>>8;
1277 if(!len || IsDBCSLeadByteEx(cp, buf[0]))
1278 buf[len++] = c;
1279 if(!MultiByteToWideChar(0, 0, buf, len, &ch, 1)) {
1280 WARN("invalid arg %d, cp %d\n", c, cp);
1281 return E_FAIL;
1284 if(res) {
1285 V_VT(res) = VT_BSTR;
1286 V_BSTR(res) = SysAllocStringLen(&ch, 1);
1287 if(!V_BSTR(res))
1288 return E_OUTOFMEMORY;
1290 return S_OK;
1293 static HRESULT Global_AscW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1295 FIXME("\n");
1296 return E_NOTIMPL;
1299 static HRESULT Global_ChrW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1301 FIXME("\n");
1302 return E_NOTIMPL;
1305 static HRESULT Global_Abs(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1307 HRESULT hres;
1308 VARIANT dst;
1310 TRACE("(%s)\n", debugstr_variant(arg));
1312 assert(args_cnt == 1);
1314 hres = VarAbs(arg, &dst);
1315 if(FAILED(hres))
1316 return hres;
1318 if (res)
1319 *res = dst;
1320 else
1321 VariantClear(&dst);
1323 return S_OK;
1326 static HRESULT Global_Fix(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1328 HRESULT hres;
1329 VARIANT dst;
1331 TRACE("(%s)\n", debugstr_variant(arg));
1333 assert(args_cnt == 1);
1335 hres = VarFix(arg, &dst);
1336 if(FAILED(hres))
1337 return hres;
1339 if (res)
1340 *res = dst;
1341 else
1342 VariantClear(&dst);
1344 return S_OK;
1347 static HRESULT Global_Int(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1349 HRESULT hres;
1350 VARIANT dst;
1352 TRACE("(%s)\n", debugstr_variant(arg));
1354 assert(args_cnt == 1);
1356 hres = VarInt(arg, &dst);
1357 if(FAILED(hres))
1358 return hres;
1360 if (res)
1361 *res = dst;
1362 else
1363 VariantClear(&dst);
1365 return S_OK;
1368 static HRESULT Global_Sgn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1370 double v;
1371 short val;
1372 HRESULT hres;
1374 TRACE("(%s)\n", debugstr_variant(arg));
1376 assert(args_cnt == 1);
1378 if(V_VT(arg) == VT_NULL)
1379 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
1381 hres = to_double(arg, &v);
1382 if (FAILED(hres))
1383 return hres;
1385 val = v == 0 ? 0 : (v > 0 ? 1 : -1);
1386 return return_short(res, val);
1389 static HRESULT Global_Now(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1391 SYSTEMTIME lt;
1392 double date;
1394 TRACE("\n");
1396 GetLocalTime(&lt);
1397 SystemTimeToVariantTime(&lt, &date);
1398 return return_date(res, date);
1401 static HRESULT Global_Date(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1403 FIXME("\n");
1404 return E_NOTIMPL;
1407 static HRESULT Global_Time(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1409 FIXME("\n");
1410 return E_NOTIMPL;
1413 static HRESULT Global_Day(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1415 FIXME("\n");
1416 return E_NOTIMPL;
1419 static HRESULT Global_Month(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1421 FIXME("\n");
1422 return E_NOTIMPL;
1425 static HRESULT Global_Weekday(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1427 FIXME("\n");
1428 return E_NOTIMPL;
1431 static HRESULT Global_Year(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1433 FIXME("\n");
1434 return E_NOTIMPL;
1437 static HRESULT Global_Hour(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1439 FIXME("\n");
1440 return E_NOTIMPL;
1443 static HRESULT Global_Minute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1445 FIXME("\n");
1446 return E_NOTIMPL;
1449 static HRESULT Global_Second(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1451 FIXME("\n");
1452 return E_NOTIMPL;
1455 static HRESULT Global_DateValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1457 FIXME("\n");
1458 return E_NOTIMPL;
1461 static HRESULT Global_TimeValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1463 FIXME("\n");
1464 return E_NOTIMPL;
1467 static HRESULT Global_DateSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1469 FIXME("\n");
1470 return E_NOTIMPL;
1473 static HRESULT Global_TimeSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1475 FIXME("\n");
1476 return E_NOTIMPL;
1479 static HRESULT Global_InputBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1481 FIXME("\n");
1482 return E_NOTIMPL;
1485 static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1487 BSTR prompt, title = NULL;
1488 int type = MB_OK;
1489 HRESULT hres;
1491 TRACE("\n");
1493 assert(1 <= args_cnt && args_cnt <= 5);
1495 hres = to_string(args, &prompt);
1496 if(FAILED(hres))
1497 return hres;
1499 if(args_cnt > 1)
1500 hres = to_int(args+1, &type);
1502 if(SUCCEEDED(hres) && args_cnt > 2)
1503 hres = to_string(args+2, &title);
1505 if(SUCCEEDED(hres) && args_cnt > 3) {
1506 FIXME("unsupported arg_cnt %d\n", args_cnt);
1507 hres = E_NOTIMPL;
1510 if(SUCCEEDED(hres))
1511 hres = show_msgbox(This->desc->ctx, prompt, type, title, res);
1513 SysFreeString(prompt);
1514 SysFreeString(title);
1515 return hres;
1518 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1520 IUnknown *obj;
1521 HRESULT hres;
1523 TRACE("(%s)\n", debugstr_variant(arg));
1525 if(V_VT(arg) != VT_BSTR) {
1526 FIXME("non-bstr arg\n");
1527 return E_INVALIDARG;
1530 obj = create_object(This->desc->ctx, V_BSTR(arg));
1531 if(!obj)
1532 return VB_E_CANNOT_CREATE_OBJ;
1534 if(res) {
1535 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res));
1536 if(FAILED(hres))
1537 return hres;
1539 V_VT(res) = VT_DISPATCH;
1542 IUnknown_Release(obj);
1543 return S_OK;
1546 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1548 IBindCtx *bind_ctx;
1549 IUnknown *obj_unk;
1550 IDispatch *disp;
1551 ULONG eaten = 0;
1552 IMoniker *mon;
1553 HRESULT hres;
1555 TRACE("%s %s\n", args_cnt ? debugstr_variant(args) : "", args_cnt > 1 ? debugstr_variant(args+1) : "");
1557 if(args_cnt != 1 || V_VT(args) != VT_BSTR) {
1558 FIXME("unsupported args\n");
1559 return E_NOTIMPL;
1562 if(This->desc->ctx->safeopt & (INTERFACE_USES_SECURITY_MANAGER|INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
1563 WARN("blocked in current safety mode\n");
1564 return VB_E_CANNOT_CREATE_OBJ;
1567 hres = CreateBindCtx(0, &bind_ctx);
1568 if(FAILED(hres))
1569 return hres;
1571 hres = MkParseDisplayName(bind_ctx, V_BSTR(args), &eaten, &mon);
1572 if(SUCCEEDED(hres)) {
1573 hres = IMoniker_BindToObject(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&obj_unk);
1574 IMoniker_Release(mon);
1575 }else {
1576 hres = MK_E_SYNTAX;
1578 IBindCtx_Release(bind_ctx);
1579 if(FAILED(hres))
1580 return hres;
1582 hres = set_object_site(This->desc->ctx, obj_unk);
1583 if(FAILED(hres)) {
1584 IUnknown_Release(obj_unk);
1585 return hres;
1588 hres = IUnknown_QueryInterface(obj_unk, &IID_IDispatch, (void**)&disp);
1589 if(SUCCEEDED(hres)) {
1590 if(res) {
1591 V_VT(res) = VT_DISPATCH;
1592 V_DISPATCH(res) = disp;
1593 }else {
1594 IDispatch_Release(disp);
1596 }else {
1597 FIXME("object does not support IDispatch\n");
1600 return hres;
1603 static HRESULT Global_DateAdd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1605 FIXME("\n");
1606 return E_NOTIMPL;
1609 static HRESULT Global_DateDiff(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1611 FIXME("\n");
1612 return E_NOTIMPL;
1615 static HRESULT Global_DatePart(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1617 FIXME("\n");
1618 return E_NOTIMPL;
1621 static HRESULT Global_TypeName(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1623 static const WCHAR ByteW[] = {'B', 'y', 't', 'e', 0};
1624 static const WCHAR IntegerW[] = {'I', 'n', 't', 'e', 'g', 'e', 'r', 0};
1625 static const WCHAR LongW[] = {'L', 'o', 'n', 'g', 0};
1626 static const WCHAR SingleW[] = {'S', 'i', 'n', 'g', 'l', 'e', 0};
1627 static const WCHAR DoubleW[] = {'D', 'o', 'u', 'b', 'l', 'e', 0};
1628 static const WCHAR CurrencyW[] = {'C', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 0};
1629 static const WCHAR DecimalW[] = {'D', 'e', 'c', 'i', 'm', 'a', 'l', 0};
1630 static const WCHAR DateW[] = {'D', 'a', 't', 'e', 0};
1631 static const WCHAR StringW[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
1632 static const WCHAR BooleanW[] = {'B', 'o', 'o', 'l', 'e', 'a', 'n', 0};
1633 static const WCHAR EmptyW[] = {'E', 'm', 'p', 't', 'y', 0};
1634 static const WCHAR NullW[] = {'N', 'u', 'l', 'l', 0};
1636 TRACE("(%s)\n", debugstr_variant(arg));
1638 assert(args_cnt == 1);
1640 switch(V_VT(arg)) {
1641 case VT_UI1:
1642 return return_string(res, ByteW);
1643 case VT_I2:
1644 return return_string(res, IntegerW);
1645 case VT_I4:
1646 return return_string(res, LongW);
1647 case VT_R4:
1648 return return_string(res, SingleW);
1649 case VT_R8:
1650 return return_string(res, DoubleW);
1651 case VT_CY:
1652 return return_string(res, CurrencyW);
1653 case VT_DECIMAL:
1654 return return_string(res, DecimalW);
1655 case VT_DATE:
1656 return return_string(res, DateW);
1657 case VT_BSTR:
1658 return return_string(res, StringW);
1659 case VT_BOOL:
1660 return return_string(res, BooleanW);
1661 case VT_EMPTY:
1662 return return_string(res, EmptyW);
1663 case VT_NULL:
1664 return return_string(res, NullW);
1665 default:
1666 FIXME("arg %s not supported\n", debugstr_variant(arg));
1667 return E_NOTIMPL;
1671 static HRESULT Global_Array(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1673 FIXME("\n");
1674 return E_NOTIMPL;
1677 static HRESULT Global_Erase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1679 FIXME("\n");
1680 return E_NOTIMPL;
1683 static HRESULT Global_Filter(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1685 FIXME("\n");
1686 return E_NOTIMPL;
1689 static HRESULT Global_Join(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1691 FIXME("\n");
1692 return E_NOTIMPL;
1695 static HRESULT Global_Split(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1697 FIXME("\n");
1698 return E_NOTIMPL;
1701 static HRESULT Global_Replace(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1703 FIXME("\n");
1704 return E_NOTIMPL;
1707 static HRESULT Global_StrReverse(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1709 WCHAR *ptr1, *ptr2, ch;
1710 BSTR ret;
1711 HRESULT hres;
1713 TRACE("%s\n", debugstr_variant(arg));
1715 hres = to_string(arg, &ret);
1716 if(FAILED(hres))
1717 return hres;
1719 ptr1 = ret;
1720 ptr2 = ret + SysStringLen(ret)-1;
1721 while(ptr1 < ptr2) {
1722 ch = *ptr1;
1723 *ptr1++ = *ptr2;
1724 *ptr2-- = ch;
1727 return return_bstr(res, ret);
1730 static HRESULT Global_InStrRev(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1732 FIXME("\n");
1733 return E_NOTIMPL;
1736 static HRESULT Global_LoadPicture(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1738 FIXME("\n");
1739 return E_NOTIMPL;
1742 static HRESULT Global_ScriptEngine(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1744 TRACE("%s\n", debugstr_variant(arg));
1746 assert(args_cnt == 0);
1748 return return_string(res, vbscriptW);
1751 static HRESULT Global_ScriptEngineMajorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1753 TRACE("%s\n", debugstr_variant(arg));
1755 assert(args_cnt == 0);
1757 if(res) {
1758 V_VT(res) = VT_I4;
1759 V_I4(res) = VBSCRIPT_MAJOR_VERSION;
1762 return S_OK;
1765 static HRESULT Global_ScriptEngineMinorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1767 TRACE("%s\n", debugstr_variant(arg));
1769 assert(args_cnt == 0);
1771 if(res) {
1772 V_VT(res) = VT_I4;
1773 V_I4(res) = VBSCRIPT_MINOR_VERSION;
1776 return S_OK;
1779 static HRESULT Global_ScriptEngineBuildVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1781 TRACE("%s\n", debugstr_variant(arg));
1783 assert(args_cnt == 0);
1785 if(res) {
1786 V_VT(res) = VT_I4;
1787 V_I4(res) = VBSCRIPT_BUILD_VERSION;
1790 return S_OK;
1793 static HRESULT Global_FormatNumber(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1795 FIXME("\n");
1796 return E_NOTIMPL;
1799 static HRESULT Global_FormatCurrency(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1801 FIXME("\n");
1802 return E_NOTIMPL;
1805 static HRESULT Global_FormatPercent(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1807 FIXME("\n");
1808 return E_NOTIMPL;
1811 static HRESULT Global_FormatDateTime(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1813 FIXME("\n");
1814 return E_NOTIMPL;
1817 static HRESULT Global_WeekdayName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1819 int weekday, first_day = 1, abbrev = 0;
1820 BSTR ret;
1821 HRESULT hres;
1823 TRACE("\n");
1825 assert(1 <= args_cnt && args_cnt <= 3);
1827 hres = to_int(args, &weekday);
1828 if(FAILED(hres))
1829 return hres;
1831 if(args_cnt > 1) {
1832 hres = to_int(args+1, &abbrev);
1833 if(FAILED(hres))
1834 return hres;
1836 if(args_cnt == 3) {
1837 hres = to_int(args+2, &first_day);
1838 if(FAILED(hres))
1839 return hres;
1843 hres = VarWeekdayName(weekday, abbrev, first_day, 0, &ret);
1844 if(FAILED(hres))
1845 return hres;
1847 return return_bstr(res, ret);
1850 static HRESULT Global_MonthName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1852 int month, abbrev = 0;
1853 BSTR ret;
1854 HRESULT hres;
1856 TRACE("\n");
1858 assert(args_cnt == 1 || args_cnt == 2);
1860 hres = to_int(args, &month);
1861 if(FAILED(hres))
1862 return hres;
1864 if(args_cnt == 2) {
1865 hres = to_int(args+1, &abbrev);
1866 if(FAILED(hres))
1867 return hres;
1870 hres = VarMonthName(month, abbrev, 0, &ret);
1871 if(FAILED(hres))
1872 return hres;
1874 return return_bstr(res, ret);
1877 static HRESULT Global_Round(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1879 double n;
1880 HRESULT hres;
1882 TRACE("%s\n", debugstr_variant(arg));
1884 if(!res)
1885 return S_OK;
1887 switch(V_VT(arg)) {
1888 case VT_I2:
1889 case VT_I4:
1890 case VT_BOOL:
1891 *res = *arg;
1892 return S_OK;
1893 case VT_R8:
1894 n = V_R8(arg);
1895 break;
1896 default:
1897 hres = to_double(arg, &n);
1898 if(FAILED(hres))
1899 return hres;
1902 return return_double(res, round(n));
1905 static HRESULT Global_Escape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1907 FIXME("\n");
1908 return E_NOTIMPL;
1911 static HRESULT Global_Unescape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1913 FIXME("\n");
1914 return E_NOTIMPL;
1917 static HRESULT Global_Eval(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1919 FIXME("\n");
1920 return E_NOTIMPL;
1923 static HRESULT Global_Execute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1925 FIXME("\n");
1926 return E_NOTIMPL;
1929 static HRESULT Global_ExecuteGlobal(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1931 FIXME("\n");
1932 return E_NOTIMPL;
1935 static HRESULT Global_GetRef(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1937 FIXME("\n");
1938 return E_NOTIMPL;
1941 static const string_constant_t vbCr = {1, {'\r'}};
1942 static const string_constant_t vbCrLf = {2, {'\r','\n'}};
1943 static const string_constant_t vbNewLine = {2, {'\r','\n'}};
1944 static const string_constant_t vbFormFeed = {1, {0xc}};
1945 static const string_constant_t vbLf = {1, {'\n'}};
1946 static const string_constant_t vbNullChar = {1};
1947 static const string_constant_t vbNullString = {0};
1948 static const string_constant_t vbTab = {1, {'\t'}};
1949 static const string_constant_t vbVerticalTab = {1, {0xb}};
1951 static const builtin_prop_t global_props[] = {
1952 {DISPID_GLOBAL_VBUSESYSTEM, NULL, BP_GET, VT_I2, 0},
1953 {DISPID_GLOBAL_USESYSTEMDAYOFWEEK, NULL, BP_GET, VT_I2, 0},
1954 {DISPID_GLOBAL_VBSUNDAY, NULL, BP_GET, VT_I2, 1},
1955 {DISPID_GLOBAL_VBMONDAY, NULL, BP_GET, VT_I2, 2},
1956 {DISPID_GLOBAL_VBTUESDAY, NULL, BP_GET, VT_I2, 3},
1957 {DISPID_GLOBAL_VBWEDNESDAY, NULL, BP_GET, VT_I2, 4},
1958 {DISPID_GLOBAL_VBTHURSDAY, NULL, BP_GET, VT_I2, 5},
1959 {DISPID_GLOBAL_VBFRIDAY, NULL, BP_GET, VT_I2, 6},
1960 {DISPID_GLOBAL_VBSATURDAY, NULL, BP_GET, VT_I2, 7},
1961 {DISPID_GLOBAL_VBFIRSTJAN1, NULL, BP_GET, VT_I2, 1},
1962 {DISPID_GLOBAL_VBFIRSTFOURDAYS, NULL, BP_GET, VT_I2, 2},
1963 {DISPID_GLOBAL_VBFIRSTFULLWEEK, NULL, BP_GET, VT_I2, 3},
1964 {DISPID_GLOBAL_VBOKONLY, NULL, BP_GET, VT_I2, MB_OK},
1965 {DISPID_GLOBAL_VBOKCANCEL, NULL, BP_GET, VT_I2, MB_OKCANCEL},
1966 {DISPID_GLOBAL_VBABORTRETRYIGNORE, NULL, BP_GET, VT_I2, MB_ABORTRETRYIGNORE},
1967 {DISPID_GLOBAL_VBYESNOCANCEL, NULL, BP_GET, VT_I2, MB_YESNOCANCEL},
1968 {DISPID_GLOBAL_VBYESNO, NULL, BP_GET, VT_I2, MB_YESNO},
1969 {DISPID_GLOBAL_VBRETRYCANCEL, NULL, BP_GET, VT_I2, MB_RETRYCANCEL},
1970 {DISPID_GLOBAL_VBCRITICAL, NULL, BP_GET, VT_I2, MB_ICONHAND},
1971 {DISPID_GLOBAL_VBQUESTION, NULL, BP_GET, VT_I2, MB_ICONQUESTION},
1972 {DISPID_GLOBAL_VBEXCLAMATION, NULL, BP_GET, VT_I2, MB_ICONEXCLAMATION},
1973 {DISPID_GLOBAL_VBINFORMATION, NULL, BP_GET, VT_I2, MB_ICONASTERISK},
1974 {DISPID_GLOBAL_VBDEFAULTBUTTON1, NULL, BP_GET, VT_I2, MB_DEFBUTTON1},
1975 {DISPID_GLOBAL_VBDEFAULTBUTTON2, NULL, BP_GET, VT_I2, MB_DEFBUTTON2},
1976 {DISPID_GLOBAL_VBDEFAULTBUTTON3, NULL, BP_GET, VT_I2, MB_DEFBUTTON3},
1977 {DISPID_GLOBAL_VBDEFAULTBUTTON4, NULL, BP_GET, VT_I2, MB_DEFBUTTON4},
1978 {DISPID_GLOBAL_VBAPPLICATIONMODAL, NULL, BP_GET, VT_I2, MB_APPLMODAL},
1979 {DISPID_GLOBAL_VBSYSTEMMODAL, NULL, BP_GET, VT_I2, MB_SYSTEMMODAL},
1980 {DISPID_GLOBAL_VBOK, NULL, BP_GET, VT_I2, IDOK},
1981 {DISPID_GLOBAL_VBCANCEL, NULL, BP_GET, VT_I2, IDCANCEL},
1982 {DISPID_GLOBAL_VBABORT, NULL, BP_GET, VT_I2, IDABORT},
1983 {DISPID_GLOBAL_VBRETRY, NULL, BP_GET, VT_I2, IDRETRY},
1984 {DISPID_GLOBAL_VBIGNORE, NULL, BP_GET, VT_I2, IDIGNORE},
1985 {DISPID_GLOBAL_VBYES, NULL, BP_GET, VT_I2, IDYES},
1986 {DISPID_GLOBAL_VBNO, NULL, BP_GET, VT_I2, IDNO},
1987 {DISPID_GLOBAL_VBEMPTY, NULL, BP_GET, VT_I2, VT_EMPTY},
1988 {DISPID_GLOBAL_VBNULL, NULL, BP_GET, VT_I2, VT_NULL},
1989 {DISPID_GLOBAL_VBINTEGER, NULL, BP_GET, VT_I2, VT_I2},
1990 {DISPID_GLOBAL_VBLONG, NULL, BP_GET, VT_I2, VT_I4},
1991 {DISPID_GLOBAL_VBSINGLE, NULL, BP_GET, VT_I2, VT_R4},
1992 {DISPID_GLOBAL_VBDOUBLE, NULL, BP_GET, VT_I2, VT_R8},
1993 {DISPID_GLOBAL_VBCURRENCY, NULL, BP_GET, VT_I2, VT_CY},
1994 {DISPID_GLOBAL_VBDATE, NULL, BP_GET, VT_I2, VT_DATE},
1995 {DISPID_GLOBAL_VBSTRING, NULL, BP_GET, VT_I2, VT_BSTR},
1996 {DISPID_GLOBAL_VBOBJECT, NULL, BP_GET, VT_I2, VT_DISPATCH},
1997 {DISPID_GLOBAL_VBERROR, NULL, BP_GET, VT_I2, VT_ERROR},
1998 {DISPID_GLOBAL_VBBOOLEAN, NULL, BP_GET, VT_I2, VT_BOOL},
1999 {DISPID_GLOBAL_VBVARIANT, NULL, BP_GET, VT_I2, VT_VARIANT},
2000 {DISPID_GLOBAL_VBDATAOBJECT, NULL, BP_GET, VT_I2, VT_UNKNOWN},
2001 {DISPID_GLOBAL_VBDECIMAL, NULL, BP_GET, VT_I2, VT_DECIMAL},
2002 {DISPID_GLOBAL_VBBYTE, NULL, BP_GET, VT_I2, VT_UI1},
2003 {DISPID_GLOBAL_VBARRAY, NULL, BP_GET, VT_I2, VT_ARRAY},
2004 {DISPID_GLOBAL_VBTRUE, NULL, BP_GET, VT_I2, VARIANT_TRUE},
2005 {DISPID_GLOBAL_VBFALSE, NULL, BP_GET, VT_I2, VARIANT_FALSE},
2006 {DISPID_GLOBAL_VBUSEDEFAULT, NULL, BP_GET, VT_I2, -2},
2007 {DISPID_GLOBAL_VBBINARYCOMPARE, NULL, BP_GET, VT_I2, 0},
2008 {DISPID_GLOBAL_VBTEXTCOMPARE, NULL, BP_GET, VT_I2, 1},
2009 {DISPID_GLOBAL_VBDATABASECOMPARE, NULL, BP_GET, VT_I2, 2},
2010 {DISPID_GLOBAL_VBGENERALDATE, NULL, BP_GET, VT_I2, 0},
2011 {DISPID_GLOBAL_VBLONGDATE, NULL, BP_GET, VT_I2, 1},
2012 {DISPID_GLOBAL_VBSHORTDATE, NULL, BP_GET, VT_I2, 2},
2013 {DISPID_GLOBAL_VBLONGTIME, NULL, BP_GET, VT_I2, 3},
2014 {DISPID_GLOBAL_VBSHORTTIME, NULL, BP_GET, VT_I2, 4},
2015 {DISPID_GLOBAL_VBOBJECTERROR, NULL, BP_GET, VT_I4, 0x80040000},
2016 {DISPID_GLOBAL_VBBLACK, NULL, BP_GET, VT_I4, 0x000000},
2017 {DISPID_GLOBAL_VBBLUE, NULL, BP_GET, VT_I4, 0xff0000},
2018 {DISPID_GLOBAL_VBCYAN, NULL, BP_GET, VT_I4, 0xffff00},
2019 {DISPID_GLOBAL_VBGREEN, NULL, BP_GET, VT_I4, 0x00ff00},
2020 {DISPID_GLOBAL_VBMAGENTA, NULL, BP_GET, VT_I4, 0xff00ff},
2021 {DISPID_GLOBAL_VBRED, NULL, BP_GET, VT_I4, 0x0000ff},
2022 {DISPID_GLOBAL_VBWHITE, NULL, BP_GET, VT_I4, 0xffffff},
2023 {DISPID_GLOBAL_VBYELLOW, NULL, BP_GET, VT_I4, 0x00ffff},
2024 {DISPID_GLOBAL_VBCR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCr},
2025 {DISPID_GLOBAL_VBCRLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCrLf},
2026 {DISPID_GLOBAL_VBNEWLINE, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNewLine},
2027 {DISPID_GLOBAL_VBFORMFEED, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbFormFeed},
2028 {DISPID_GLOBAL_VBLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbLf},
2029 {DISPID_GLOBAL_VBNULLCHAR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullChar},
2030 {DISPID_GLOBAL_VBNULLSTRING, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullString},
2031 {DISPID_GLOBAL_VBTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbTab},
2032 {DISPID_GLOBAL_VBVERTICALTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbVerticalTab},
2033 {DISPID_GLOBAL_CCUR, Global_CCur, 0, 1},
2034 {DISPID_GLOBAL_CINT, Global_CInt, 0, 1},
2035 {DISPID_GLOBAL_CLNG, Global_CLng, 0, 1},
2036 {DISPID_GLOBAL_CBOOL, Global_CBool, 0, 1},
2037 {DISPID_GLOBAL_CBYTE, Global_CByte, 0, 1},
2038 {DISPID_GLOBAL_CDATE, Global_CDate, 0, 1},
2039 {DISPID_GLOBAL_CDBL, Global_CDbl, 0, 1},
2040 {DISPID_GLOBAL_CSNG, Global_CSng, 0, 1},
2041 {DISPID_GLOBAL_CSTR, Global_CStr, 0, 1},
2042 {DISPID_GLOBAL_HEX, Global_Hex, 0, 1},
2043 {DISPID_GLOBAL_OCT, Global_Oct, 0, 1},
2044 {DISPID_GLOBAL_VARTYPE, Global_VarType, 0, 1},
2045 {DISPID_GLOBAL_ISDATE, Global_IsDate, 0, 1},
2046 {DISPID_GLOBAL_ISEMPTY, Global_IsEmpty, 0, 1},
2047 {DISPID_GLOBAL_ISNULL, Global_IsNull, 0, 1},
2048 {DISPID_GLOBAL_ISNUMERIC, Global_IsNumeric, 0, 1},
2049 {DISPID_GLOBAL_ISARRAY, Global_IsArray, 0, 1},
2050 {DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1},
2051 {DISPID_GLOBAL_ATN, Global_Atn, 0, 1},
2052 {DISPID_GLOBAL_COS, Global_Cos, 0, 1},
2053 {DISPID_GLOBAL_SIN, Global_Sin, 0, 1},
2054 {DISPID_GLOBAL_TAN, Global_Tan, 0, 1},
2055 {DISPID_GLOBAL_EXP, Global_Exp, 0, 1},
2056 {DISPID_GLOBAL_LOG, Global_Log, 0, 1},
2057 {DISPID_GLOBAL_SQR, Global_Sqr, 0, 1},
2058 {DISPID_GLOBAL_RANDOMIZE, Global_Randomize, 0, 1},
2059 {DISPID_GLOBAL_RND, Global_Rnd, 0, 1},
2060 {DISPID_GLOBAL_TIMER, Global_Timer, 0, 0},
2061 {DISPID_GLOBAL_LBOUND, Global_LBound, 0, 1},
2062 {DISPID_GLOBAL_UBOUND, Global_UBound, 0, 1},
2063 {DISPID_GLOBAL_RGB, Global_RGB, 0, 3},
2064 {DISPID_GLOBAL_LEN, Global_Len, 0, 1},
2065 {DISPID_GLOBAL_LENB, Global_LenB, 0, 1},
2066 {DISPID_GLOBAL_LEFT, Global_Left, 0, 2},
2067 {DISPID_GLOBAL_LEFTB, Global_LeftB, 0, 2},
2068 {DISPID_GLOBAL_RIGHT, Global_Right, 0, 2},
2069 {DISPID_GLOBAL_RIGHTB, Global_RightB, 0, 2},
2070 {DISPID_GLOBAL_MID, Global_Mid, 0, 2, 3},
2071 {DISPID_GLOBAL_MIDB, Global_MidB, 0, 2, 3},
2072 {DISPID_GLOBAL_STRCOMP, Global_StrComp, 0, 2, 3},
2073 {DISPID_GLOBAL_LCASE, Global_LCase, 0, 1},
2074 {DISPID_GLOBAL_UCASE, Global_UCase, 0, 1},
2075 {DISPID_GLOBAL_LTRIM, Global_LTrim, 0, 1},
2076 {DISPID_GLOBAL_RTRIM, Global_RTrim, 0, 1},
2077 {DISPID_GLOBAL_TRIM, Global_Trim, 0, 1},
2078 {DISPID_GLOBAL_SPACE, Global_Space, 0, 1},
2079 {DISPID_GLOBAL_STRING, Global_String, 0, 0, 2},
2080 {DISPID_GLOBAL_INSTR, Global_InStr, 0, 2, 4},
2081 {DISPID_GLOBAL_INSTRB, Global_InStrB, 0, 3, 4},
2082 {DISPID_GLOBAL_ASCB, Global_AscB, 0, 1},
2083 {DISPID_GLOBAL_CHRB, Global_ChrB, 0, 1},
2084 {DISPID_GLOBAL_ASC, Global_Asc, 0, 1},
2085 {DISPID_GLOBAL_CHR, Global_Chr, 0, 1},
2086 {DISPID_GLOBAL_ASCW, Global_AscW, 0, 1},
2087 {DISPID_GLOBAL_CHRW, Global_ChrW, 0, 1},
2088 {DISPID_GLOBAL_ABS, Global_Abs, 0, 1},
2089 {DISPID_GLOBAL_FIX, Global_Fix, 0, 1},
2090 {DISPID_GLOBAL_INT, Global_Int, 0, 1},
2091 {DISPID_GLOBAL_SGN, Global_Sgn, 0, 1},
2092 {DISPID_GLOBAL_NOW, Global_Now, 0, 0},
2093 {DISPID_GLOBAL_DATE, Global_Date, 0, 0},
2094 {DISPID_GLOBAL_TIME, Global_Time, 0, 0},
2095 {DISPID_GLOBAL_DAY, Global_Day, 0, 1},
2096 {DISPID_GLOBAL_MONTH, Global_Month, 0, 1},
2097 {DISPID_GLOBAL_WEEKDAY, Global_Weekday, 0, 1, 2},
2098 {DISPID_GLOBAL_YEAR, Global_Year, 0, 1},
2099 {DISPID_GLOBAL_HOUR, Global_Hour, 0, 1},
2100 {DISPID_GLOBAL_MINUTE, Global_Minute, 0, 1},
2101 {DISPID_GLOBAL_SECOND, Global_Second, 0, 1},
2102 {DISPID_GLOBAL_DATEVALUE, Global_DateValue, 0, 1},
2103 {DISPID_GLOBAL_TIMEVALUE, Global_TimeValue, 0, 1},
2104 {DISPID_GLOBAL_DATESERIAL, Global_DateSerial, 0, 3},
2105 {DISPID_GLOBAL_TIMESERIAL, Global_TimeSerial, 0, 3},
2106 {DISPID_GLOBAL_INPUTBOX, Global_InputBox, 0, 1, 7},
2107 {DISPID_GLOBAL_MSGBOX, Global_MsgBox, 0, 1, 5},
2108 {DISPID_GLOBAL_CREATEOBJECT, Global_CreateObject, 0, 1},
2109 {DISPID_GLOBAL_GETOBJECT, Global_GetObject, 0, 0, 2},
2110 {DISPID_GLOBAL_DATEADD, Global_DateAdd, 0, 3},
2111 {DISPID_GLOBAL_DATEDIFF, Global_DateDiff, 0, 3, 5},
2112 {DISPID_GLOBAL_DATEPART, Global_DatePart, 0, 2, 4},
2113 {DISPID_GLOBAL_TYPENAME, Global_TypeName, 0, 1},
2114 {DISPID_GLOBAL_ARRAY, Global_Array, 0, 1},
2115 {DISPID_GLOBAL_ERASE, Global_Erase, 0, 1},
2116 {DISPID_GLOBAL_FILTER, Global_Filter, 0, 2, 4},
2117 {DISPID_GLOBAL_JOIN, Global_Join, 0, 1, 2},
2118 {DISPID_GLOBAL_SPLIT, Global_Split, 0, 1, 4},
2119 {DISPID_GLOBAL_REPLACE, Global_Replace, 0, 3, 6},
2120 {DISPID_GLOBAL_STRREVERSE, Global_StrReverse, 0, 1},
2121 {DISPID_GLOBAL_INSTRREV, Global_InStrRev, 0, 2, 4},
2122 {DISPID_GLOBAL_LOADPICTURE, Global_LoadPicture, 0, 1},
2123 {DISPID_GLOBAL_SCRIPTENGINE, Global_ScriptEngine, 0, 0},
2124 {DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION, Global_ScriptEngineMajorVersion, 0, 0},
2125 {DISPID_GLOBAL_SCRIPTENGINEMINORVERSION, Global_ScriptEngineMinorVersion, 0, 0},
2126 {DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION, Global_ScriptEngineBuildVersion, 0, 0},
2127 {DISPID_GLOBAL_FORMATNUMBER, Global_FormatNumber, 0, 1, 5},
2128 {DISPID_GLOBAL_FORMATCURRENCY, Global_FormatCurrency, 0, 1, 5},
2129 {DISPID_GLOBAL_FORMATPERCENT, Global_FormatPercent, 0, 1, 5},
2130 {DISPID_GLOBAL_FORMATDATETIME, Global_FormatDateTime, 0, 1, 2},
2131 {DISPID_GLOBAL_WEEKDAYNAME, Global_WeekdayName, 0, 1, 3},
2132 {DISPID_GLOBAL_MONTHNAME, Global_MonthName, 0, 1, 2},
2133 {DISPID_GLOBAL_ROUND, Global_Round, 0, 1, 2},
2134 {DISPID_GLOBAL_ESCAPE, Global_Escape, 0, 1},
2135 {DISPID_GLOBAL_UNESCAPE, Global_Unescape, 0, 1},
2136 {DISPID_GLOBAL_EVAL, Global_Eval, 0, 1},
2137 {DISPID_GLOBAL_EXECUTE, Global_Execute, 0, 1},
2138 {DISPID_GLOBAL_EXECUTEGLOBAL, Global_ExecuteGlobal, 0, 1},
2139 {DISPID_GLOBAL_GETREF, Global_GetRef, 0, 1},
2140 {DISPID_GLOBAL_VBMSGBOXHELPBUTTON, NULL, BP_GET, VT_I4, MB_HELP},
2141 {DISPID_GLOBAL_VBMSGBOXSETFOREGROUND, NULL, BP_GET, VT_I4, MB_SETFOREGROUND},
2142 {DISPID_GLOBAL_VBMSGBOXRIGHT, NULL, BP_GET, VT_I4, MB_RIGHT},
2143 {DISPID_GLOBAL_VBMSGBOXRTLREADING, NULL, BP_GET, VT_I4, MB_RTLREADING}
2146 static HRESULT Err_Description(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2148 FIXME("\n");
2149 return E_NOTIMPL;
2152 static HRESULT Err_HelpContext(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2154 FIXME("\n");
2155 return E_NOTIMPL;
2158 static HRESULT Err_HelpFile(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2160 FIXME("\n");
2161 return E_NOTIMPL;
2164 static HRESULT Err_Number(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2166 HRESULT hres;
2168 TRACE("\n");
2170 if(!This->desc)
2171 return E_UNEXPECTED;
2173 if(args_cnt) {
2174 FIXME("setter not implemented\n");
2175 return E_NOTIMPL;
2178 hres = This->desc->ctx->err_number;
2179 return return_int(res, HRESULT_FACILITY(hres) == FACILITY_VBS ? HRESULT_CODE(hres) : hres);
2182 static HRESULT Err_Source(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2184 FIXME("\n");
2185 return E_NOTIMPL;
2188 static HRESULT Err_Clear(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2190 TRACE("\n");
2192 if(!This->desc)
2193 return E_UNEXPECTED;
2195 This->desc->ctx->err_number = S_OK;
2196 return S_OK;
2199 static HRESULT Err_Raise(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2201 FIXME("\n");
2202 return E_NOTIMPL;
2205 static const builtin_prop_t err_props[] = {
2206 {DISPID_ERR_DESCRIPTION, Err_Description, BP_GETPUT},
2207 {DISPID_ERR_HELPCONTEXT, Err_HelpContext, BP_GETPUT},
2208 {DISPID_ERR_HELPFILE, Err_HelpFile, BP_GETPUT},
2209 {DISPID_ERR_NUMBER, Err_Number, BP_GETPUT},
2210 {DISPID_ERR_SOURCE, Err_Source, BP_GETPUT},
2211 {DISPID_ERR_CLEAR, Err_Clear},
2212 {DISPID_ERR_RAISE, Err_Raise, 0, 5},
2215 HRESULT init_global(script_ctx_t *ctx)
2217 HRESULT hres;
2219 ctx->global_desc.ctx = ctx;
2220 ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
2221 ctx->global_desc.builtin_props = global_props;
2223 hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
2224 if(FAILED(hres))
2225 return hres;
2227 hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
2228 if(FAILED(hres))
2229 return hres;
2231 hres = create_script_disp(ctx, &ctx->script_obj);
2232 if(FAILED(hres))
2233 return hres;
2235 ctx->err_desc.ctx = ctx;
2236 ctx->err_desc.builtin_prop_cnt = sizeof(err_props)/sizeof(*err_props);
2237 ctx->err_desc.builtin_props = err_props;
2239 hres = get_typeinfo(ErrObj_tid, &ctx->err_desc.typeinfo);
2240 if(FAILED(hres))
2241 return hres;
2243 return create_vbdisp(&ctx->err_desc, &ctx->err_obj);