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
23 #include "vbscript_defs.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(vbscript
);
33 #define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
34 #define VB_E_MK_PARSE_ERROR 0x800a01b0
36 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
37 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY
=
38 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
40 static const WCHAR emptyW
[] = {0};
41 static const WCHAR vbscriptW
[] = {'V','B','S','c','r','i','p','t',0};
51 struct _builtin_prop_t
{
53 HRESULT (*proc
)(BuiltinDisp
*,VARIANT
*,unsigned,VARIANT
*);
59 static inline BuiltinDisp
*impl_from_IDispatch(IDispatch
*iface
)
61 return CONTAINING_RECORD(iface
, BuiltinDisp
, IDispatch_iface
);
64 static HRESULT WINAPI
Builtin_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppv
)
66 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
68 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
69 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
70 *ppv
= &This
->IDispatch_iface
;
71 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
72 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
73 *ppv
= &This
->IDispatch_iface
;
75 if(!IsEqualGUID(riid
, &IID_IDispatchEx
))
76 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
81 IUnknown_AddRef((IUnknown
*)*ppv
);
85 static ULONG WINAPI
Builtin_AddRef(IDispatch
*iface
)
87 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
88 LONG ref
= InterlockedIncrement(&This
->ref
);
90 TRACE("(%p) ref=%d\n", This
, ref
);
95 static ULONG WINAPI
Builtin_Release(IDispatch
*iface
)
97 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
98 LONG ref
= InterlockedDecrement(&This
->ref
);
100 TRACE("(%p) ref=%d\n", This
, ref
);
110 static HRESULT WINAPI
Builtin_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
112 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
113 TRACE("(%p)->(%p)\n", This
, pctinfo
);
118 static HRESULT WINAPI
Builtin_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
120 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
121 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
122 return DISP_E_BADINDEX
;
125 HRESULT
get_builtin_id(BuiltinDisp
*disp
, const WCHAR
*name
, DISPID
*id
)
127 size_t min
= 1, max
= disp
->member_cnt
- 1, i
;
132 r
= wcsicmp(disp
->members
[i
].name
, name
);
143 return DISP_E_MEMBERNOTFOUND
;
147 static HRESULT WINAPI
Builtin_GetIDsOfNames(IDispatch
*iface
, REFIID riid
, LPOLESTR
*names
, UINT name_cnt
,
148 LCID lcid
, DISPID
*ids
)
150 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
154 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), names
, name_cnt
, lcid
, ids
);
157 FIXME("NULL context\n");
161 for(i
= 0; i
< name_cnt
; i
++) {
162 hres
= get_builtin_id(This
, names
[i
], &ids
[i
]);
170 static HRESULT WINAPI
Builtin_Invoke(IDispatch
*iface
, DISPID id
, REFIID riid
, LCID lcid
, WORD flags
,
171 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, UINT
*err
)
173 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
174 const builtin_prop_t
*prop
;
175 VARIANT args_buf
[8], *args
;
179 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, id
, debugstr_guid(riid
), lcid
, flags
, dp
, res
, ei
, err
);
182 FIXME("NULL context\n");
186 if(id
>= This
->member_cnt
|| (!This
->members
[id
].proc
&& !This
->members
[id
].flags
))
187 return DISP_E_MEMBERNOTFOUND
;
188 prop
= This
->members
+ id
;
191 case DISPATCH_PROPERTYGET
:
192 if(!(prop
->flags
& (BP_GET
|BP_GETPUT
))) {
193 FIXME("property does not support DISPATCH_PROPERTYGET\n");
197 case DISPATCH_PROPERTYGET
|DISPATCH_METHOD
:
198 if(!prop
->proc
&& prop
->flags
== BP_GET
) {
199 const int vt
= prop
->min_args
, val
= prop
->max_args
;
210 const string_constant_t
*str
= (const string_constant_t
*)prop
->max_args
;
213 ret
= SysAllocStringLen(str
->buf
, str
->len
);
215 return E_OUTOFMEMORY
;
226 case DISPATCH_METHOD
:
227 if(prop
->flags
& (BP_GET
|BP_GETPUT
)) {
228 FIXME("Call on property\n");
232 case DISPATCH_PROPERTYPUT
:
233 if(!(prop
->flags
& BP_GETPUT
)) {
234 FIXME("property does not support DISPATCH_PROPERTYPUT\n");
241 FIXME("unsupported flags %x\n", flags
);
247 if(argn
< prop
->min_args
|| argn
> (prop
->max_args
? prop
->max_args
: prop
->min_args
)) {
248 WARN("invalid number of arguments\n");
249 return MAKE_VBSERROR(VBSE_FUNC_ARITY_MISMATCH
);
252 if(argn
<= ARRAY_SIZE(args_buf
)) {
255 args
= heap_alloc(argn
* sizeof(*args
));
257 return E_OUTOFMEMORY
;
260 for(i
=0; i
< argn
; i
++) {
261 if(V_VT(dp
->rgvarg
+dp
->cArgs
-i
-1) == (VT_BYREF
|VT_VARIANT
))
262 args
[i
] = *V_VARIANTREF(dp
->rgvarg
+dp
->cArgs
-i
-1);
264 args
[i
] = dp
->rgvarg
[dp
->cArgs
-i
-1];
267 hres
= prop
->proc(This
, args
, dp
->cArgs
, res
);
273 static const IDispatchVtbl BuiltinDispVtbl
= {
274 Builtin_QueryInterface
,
277 Builtin_GetTypeInfoCount
,
279 Builtin_GetIDsOfNames
,
283 static HRESULT
create_builtin_dispatch(script_ctx_t
*ctx
, const builtin_prop_t
*members
, size_t member_cnt
, BuiltinDisp
**ret
)
287 if(!(disp
= heap_alloc(sizeof(*disp
))))
288 return E_OUTOFMEMORY
;
290 disp
->IDispatch_iface
.lpVtbl
= &BuiltinDispVtbl
;
292 disp
->members
= members
;
293 disp
->member_cnt
= member_cnt
;
300 static IInternetHostSecurityManager
*get_sec_mgr(script_ctx_t
*ctx
)
302 IInternetHostSecurityManager
*secmgr
;
303 IServiceProvider
*sp
;
312 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IServiceProvider
, (void**)&sp
);
316 hres
= IServiceProvider_QueryService(sp
, &SID_SInternetHostSecurityManager
, &IID_IInternetHostSecurityManager
,
318 IServiceProvider_Release(sp
);
322 return ctx
->secmgr
= secmgr
;
325 static HRESULT
return_string(VARIANT
*res
, const WCHAR
*str
)
332 ret
= SysAllocString(str
);
334 return E_OUTOFMEMORY
;
341 static HRESULT
return_bstr(VARIANT
*res
, BSTR str
)
352 static HRESULT
return_bool(VARIANT
*res
, BOOL val
)
356 V_BOOL(res
) = val
? VARIANT_TRUE
: VARIANT_FALSE
;
361 static HRESULT
return_short(VARIANT
*res
, short val
)
371 static HRESULT
return_int(VARIANT
*res
, int val
)
381 static inline HRESULT
return_double(VARIANT
*res
, double val
)
391 static inline HRESULT
return_float(VARIANT
*res
, float val
)
401 static inline HRESULT
return_null(VARIANT
*res
)
408 static inline HRESULT
return_date(VARIANT
*res
, double date
)
417 HRESULT
to_int(VARIANT
*v
, int *ret
)
423 hres
= VariantChangeType(&r
, v
, 0, VT_I4
);
431 static HRESULT
to_double(VARIANT
*v
, double *ret
)
436 V_VT(&dst
) = VT_EMPTY
;
437 hres
= VariantChangeType(&dst
, v
, 0, VT_R8
);
445 static HRESULT
to_string(VARIANT
*v
, BSTR
*ret
)
450 V_VT(&dst
) = VT_EMPTY
;
451 hres
= VariantChangeType(&dst
, v
, VARIANT_LOCALBOOL
, VT_BSTR
);
459 static HRESULT
to_system_time(VARIANT
*v
, SYSTEMTIME
*st
)
464 V_VT(&date
) = VT_EMPTY
;
465 hres
= VariantChangeType(&date
, v
, 0, VT_DATE
);
469 return VariantTimeToSystemTime(V_DATE(&date
), st
);
472 static HRESULT
set_object_site(script_ctx_t
*ctx
, IUnknown
*obj
)
474 IObjectWithSite
*obj_site
;
478 hres
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (void**)&obj_site
);
482 ax_site
= create_ax_site(ctx
);
484 hres
= IObjectWithSite_SetSite(obj_site
, ax_site
);
485 IUnknown_Release(ax_site
);
488 hres
= E_OUTOFMEMORY
;
489 IObjectWithSite_Release(obj_site
);
493 static IUnknown
*create_object(script_ctx_t
*ctx
, const WCHAR
*progid
)
495 IInternetHostSecurityManager
*secmgr
= NULL
;
496 struct CONFIRMSAFETY cs
;
497 IClassFactoryEx
*cfex
;
506 hres
= CLSIDFromProgID(progid
, &guid
);
510 TRACE("GUID %s\n", debugstr_guid(&guid
));
512 if(ctx
->safeopt
& INTERFACE_USES_SECURITY_MANAGER
) {
513 secmgr
= get_sec_mgr(ctx
);
518 hres
= IInternetHostSecurityManager_ProcessUrlAction(secmgr
, URLACTION_ACTIVEX_RUN
,
519 (BYTE
*)&policy
, sizeof(policy
), (BYTE
*)&guid
, sizeof(GUID
), 0, 0);
520 if(FAILED(hres
) || policy
!= URLPOLICY_ALLOW
)
524 hres
= CoGetClassObject(&guid
, CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
, NULL
, &IID_IClassFactory
, (void**)&cf
);
528 hres
= IClassFactory_QueryInterface(cf
, &IID_IClassFactoryEx
, (void**)&cfex
);
529 if(SUCCEEDED(hres
)) {
530 FIXME("Use IClassFactoryEx\n");
531 IClassFactoryEx_Release(cfex
);
534 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)&obj
);
542 hres
= IInternetHostSecurityManager_QueryCustomPolicy(secmgr
, &GUID_CUSTOM_CONFIRMOBJECTSAFETY
,
543 &bpolicy
, &policy_size
, (BYTE
*)&cs
, sizeof(cs
), 0);
544 if(SUCCEEDED(hres
)) {
545 policy
= policy_size
>= sizeof(DWORD
) ? *(DWORD
*)bpolicy
: URLPOLICY_DISALLOW
;
546 CoTaskMemFree(bpolicy
);
549 if(FAILED(hres
) || policy
!= URLPOLICY_ALLOW
) {
550 IUnknown_Release(obj
);
555 hres
= set_object_site(ctx
, obj
);
557 IUnknown_Release(obj
);
564 static HRESULT
show_msgbox(script_ctx_t
*ctx
, BSTR prompt
, unsigned type
, BSTR orig_title
, VARIANT
*res
)
566 SCRIPTUICHANDLING uic_handling
= SCRIPTUICHANDLING_ALLOW
;
567 IActiveScriptSiteUIControl
*ui_control
;
568 IActiveScriptSiteWindow
*acts_window
;
569 WCHAR
*title_buf
= NULL
;
575 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IActiveScriptSiteUIControl
, (void**)&ui_control
);
576 if(SUCCEEDED(hres
)) {
577 hres
= IActiveScriptSiteUIControl_GetUIBehavior(ui_control
, SCRIPTUICITEM_MSGBOX
, &uic_handling
);
578 IActiveScriptSiteUIControl_Release(ui_control
);
580 uic_handling
= SCRIPTUICHANDLING_ALLOW
;
583 switch(uic_handling
) {
584 case SCRIPTUICHANDLING_ALLOW
:
586 case SCRIPTUICHANDLING_NOUIDEFAULT
:
587 return return_short(res
, 0);
593 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IActiveScriptSiteWindow
, (void**)&acts_window
);
595 FIXME("No IActiveScriptSiteWindow\n");
599 if(ctx
->safeopt
& INTERFACE_USES_SECURITY_MANAGER
) {
600 if(orig_title
&& *orig_title
) {
603 title
= title_buf
= heap_alloc(sizeof(vbscriptW
) + (lstrlenW(orig_title
)+2)*sizeof(WCHAR
));
605 return E_OUTOFMEMORY
;
607 memcpy(title_buf
, vbscriptW
, sizeof(vbscriptW
));
608 ptr
= title_buf
+ ARRAY_SIZE(vbscriptW
)-1;
612 lstrcpyW(ptr
, orig_title
);
617 title
= orig_title
? orig_title
: emptyW
;
620 hres
= IActiveScriptSiteWindow_GetWindow(acts_window
, &hwnd
);
621 if(SUCCEEDED(hres
)) {
622 hres
= IActiveScriptSiteWindow_EnableModeless(acts_window
, FALSE
);
623 if(SUCCEEDED(hres
)) {
624 ret
= MessageBoxW(hwnd
, prompt
, title
, type
);
625 hres
= IActiveScriptSiteWindow_EnableModeless(acts_window
, TRUE
);
629 heap_free(title_buf
);
630 IActiveScriptSiteWindow_Release(acts_window
);
632 FIXME("failed: %08x\n", hres
);
636 return return_short(res
, ret
);
639 static HRESULT
Global_CCur(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
644 TRACE("%s\n", debugstr_variant(arg
));
646 assert(args_cnt
== 1);
649 hres
= VariantChangeType(&v
, arg
, 0, VT_CY
);
655 return DISP_E_BADVARTYPE
;
662 static HRESULT
Global_CInt(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
667 TRACE("%s\n", debugstr_variant(arg
));
669 assert(args_cnt
== 1);
672 hres
= VariantChangeType(&v
, arg
, 0, VT_I2
);
677 return DISP_E_BADVARTYPE
;
684 static HRESULT
Global_CLng(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
689 TRACE("%s\n", debugstr_variant(arg
));
691 assert(args_cnt
== 1);
693 hres
= to_int(arg
, &i
);
697 return DISP_E_BADVARTYPE
;
699 return return_int(res
, i
);
702 static HRESULT
Global_CBool(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
707 TRACE("%s\n", debugstr_variant(arg
));
709 assert(args_cnt
== 1);
712 hres
= VariantChangeType(&v
, arg
, VARIANT_LOCALBOOL
, VT_BOOL
);
723 static HRESULT
Global_CByte(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
728 TRACE("%s\n", debugstr_variant(arg
));
730 assert(args_cnt
== 1);
733 hres
= VariantChangeType(&v
, arg
, VARIANT_LOCALBOOL
, VT_UI1
);
739 return DISP_E_BADVARTYPE
;
746 static HRESULT
Global_CDate(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
752 static HRESULT
Global_CDbl(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
757 TRACE("%s\n", debugstr_variant(arg
));
759 assert(args_cnt
== 1);
762 hres
= VariantChangeType(&v
, arg
, 0, VT_R8
);
767 return DISP_E_BADVARTYPE
;
774 static HRESULT
Global_CSng(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
779 TRACE("%s\n", debugstr_variant(arg
));
781 assert(args_cnt
== 1);
784 hres
= VariantChangeType(&v
, arg
, 0, VT_R4
);
789 return DISP_E_BADVARTYPE
;
795 static HRESULT
Global_CStr(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
800 TRACE("%s\n", debugstr_variant(arg
));
802 if(V_VT(arg
) == VT_NULL
)
803 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
805 hres
= to_string(arg
, &str
);
809 return return_bstr(res
, str
);
812 static inline WCHAR
hex_char(unsigned n
)
814 return n
< 10 ? '0'+n
: 'A'+n
-10;
817 static HRESULT
Global_Hex(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
824 TRACE("%s\n", debugstr_variant(arg
));
835 hres
= to_int(arg
, &ret
);
847 *ptr
-- = hex_char(n
& 0xf);
855 return return_string(res
, ptr
);
858 static HRESULT
Global_Oct(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
865 TRACE("%s\n", debugstr_variant(arg
));
876 hres
= to_int(arg
, &ret
);
888 *ptr
-- = '0' + (n
& 0x7);
896 return return_string(res
, ptr
);
899 static HRESULT
Global_VarType(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
903 TRACE("(%s)\n", debugstr_variant(arg
));
905 assert(args_cnt
== 1);
907 vt
= V_VT(arg
) & ~VT_BYREF
;
908 if(vt
& ~(VT_TYPEMASK
| VT_ARRAY
)) {
909 FIXME("not supported %s\n", debugstr_variant(arg
));
913 return return_short(res
, vt
);
916 static HRESULT
Global_IsDate(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
922 static HRESULT
Global_IsEmpty(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
924 TRACE("(%s)\n", debugstr_variant(arg
));
926 assert(args_cnt
== 1);
930 V_BOOL(res
) = V_VT(arg
) == VT_EMPTY
? VARIANT_TRUE
: VARIANT_FALSE
;
935 static HRESULT
Global_IsNull(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
937 TRACE("(%s)\n", debugstr_variant(arg
));
939 assert(args_cnt
== 1);
943 V_BOOL(res
) = V_VT(arg
) == VT_NULL
? VARIANT_TRUE
: VARIANT_FALSE
;
948 static HRESULT
Global_IsNumeric(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
953 TRACE("(%s)\n", debugstr_variant(arg
));
955 assert(args_cnt
== 1);
957 hres
= to_double(arg
, &d
);
959 return return_bool(res
, SUCCEEDED(hres
));
962 static HRESULT
Global_IsArray(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
968 static HRESULT
Global_IsObject(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
970 TRACE("(%s)\n", debugstr_variant(arg
));
972 assert(args_cnt
== 1);
976 V_BOOL(res
) = V_VT(arg
) == VT_DISPATCH
? VARIANT_TRUE
: VARIANT_FALSE
;
981 static HRESULT
Global_Atn(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
986 hres
= to_double(arg
, &d
);
990 return return_double(res
, atan(d
));
993 static HRESULT
Global_Cos(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
998 hres
= to_double(arg
, &d
);
1002 return return_double(res
, cos(d
));
1005 static HRESULT
Global_Sin(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1010 hres
= to_double(arg
, &d
);
1014 return return_double(res
, sin(d
));
1017 static HRESULT
Global_Tan(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1022 hres
= to_double(arg
, &d
);
1026 return return_double(res
, tan(d
));
1029 static HRESULT
Global_Exp(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1034 hres
= to_double(arg
, &d
);
1038 return return_double(res
, exp(d
));
1041 static HRESULT
Global_Log(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1046 hres
= to_double(arg
, &d
);
1051 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1053 return return_double(res
, log(d
));
1056 static HRESULT
Global_Sqr(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1061 hres
= to_double(arg
, &d
);
1066 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1068 return return_double(res
, sqrt(d
));
1071 static HRESULT
Global_Randomize(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1077 static HRESULT
Global_Rnd(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1083 static HRESULT
Global_Timer(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1089 sec
= lt
.wHour
* 3600 + lt
.wMinute
* 60 + lt
.wSecond
+ lt
.wMilliseconds
/ 1000.0;
1090 return return_float(res
, sec
);
1094 static HRESULT
Global_LBound(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1101 assert(args_cnt
== 1 || args_cnt
== 2);
1103 TRACE("%s %s\n", debugstr_variant(arg
), args_cnt
== 2 ? debugstr_variant(arg
+ 1) : "1");
1106 case VT_VARIANT
|VT_ARRAY
:
1109 case VT_VARIANT
|VT_ARRAY
|VT_BYREF
:
1110 sa
= *V_ARRAYREF(arg
);
1113 FIXME("arg %s not supported\n", debugstr_variant(arg
));
1118 hres
= to_int(arg
+ 1, &dim
);
1125 hres
= SafeArrayGetLBound(sa
, dim
, &ubound
);
1129 return return_int(res
, ubound
);
1132 static HRESULT
Global_UBound(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1139 assert(args_cnt
== 1 || args_cnt
== 2);
1141 TRACE("%s %s\n", debugstr_variant(arg
), args_cnt
== 2 ? debugstr_variant(arg
+ 1) : "1");
1144 case VT_VARIANT
|VT_ARRAY
:
1147 case VT_VARIANT
|VT_ARRAY
|VT_BYREF
:
1148 sa
= *V_ARRAYREF(arg
);
1151 FIXME("arg %s not supported\n", debugstr_variant(arg
));
1156 hres
= to_int(arg
+ 1, &dim
);
1163 hres
= SafeArrayGetUBound(sa
, dim
, &ubound
);
1167 return return_int(res
, ubound
);
1170 static HRESULT
Global_RGB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1175 TRACE("%s %s %s\n", debugstr_variant(arg
), debugstr_variant(arg
+ 1), debugstr_variant(arg
+ 2));
1177 assert(args_cnt
== 3);
1179 for(i
= 0; i
< 3; i
++) {
1180 hres
= to_int(arg
+ i
, color
+ i
);
1186 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1189 return return_int(res
, RGB(color
[0], color
[1], color
[2]));
1192 static HRESULT
Global_Len(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1197 TRACE("%s\n", debugstr_variant(arg
));
1199 if(V_VT(arg
) == VT_NULL
)
1200 return return_null(res
);
1202 if(V_VT(arg
) != VT_BSTR
) {
1205 hres
= to_string(arg
, &str
);
1209 len
= SysStringLen(str
);
1212 len
= SysStringLen(V_BSTR(arg
));
1215 return return_int(res
, len
);
1218 static HRESULT
Global_LenB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1224 static HRESULT
Global_Left(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1226 BSTR str
, ret
, conv_str
= NULL
;
1230 TRACE("(%s %s)\n", debugstr_variant(args
+1), debugstr_variant(args
));
1232 if(V_VT(args
) == VT_BSTR
) {
1235 hres
= to_string(args
, &conv_str
);
1241 hres
= to_int(args
+1, &len
);
1246 FIXME("len = %d\n", len
);
1250 str_len
= SysStringLen(str
);
1254 ret
= SysAllocStringLen(str
, len
);
1255 SysFreeString(conv_str
);
1257 return E_OUTOFMEMORY
;
1259 return return_bstr(res
, ret
);
1262 static HRESULT
Global_LeftB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1268 static HRESULT
Global_Right(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1270 BSTR str
, ret
, conv_str
= NULL
;
1274 TRACE("(%s %s)\n", debugstr_variant(args
), debugstr_variant(args
+1));
1276 if(V_VT(args
+1) == VT_BSTR
) {
1279 hres
= to_string(args
, &conv_str
);
1285 hres
= to_int(args
+1, &len
);
1290 FIXME("len = %d\n", len
);
1294 str_len
= SysStringLen(str
);
1298 ret
= SysAllocStringLen(str
+str_len
-len
, len
);
1299 SysFreeString(conv_str
);
1301 return E_OUTOFMEMORY
;
1303 return return_bstr(res
, ret
);
1306 static HRESULT
Global_RightB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1312 static HRESULT
Global_Mid(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1314 int len
= -1, start
, str_len
;
1318 TRACE("(%s %s ...)\n", debugstr_variant(args
), debugstr_variant(args
+1));
1320 assert(args_cnt
== 2 || args_cnt
== 3);
1322 if(V_VT(args
) != VT_BSTR
) {
1323 FIXME("args[0] = %s\n", debugstr_variant(args
));
1329 hres
= to_int(args
+1, &start
);
1334 hres
= to_int(args
+2, &len
);
1339 FIXME("len = %d\n", len
);
1345 str_len
= SysStringLen(str
);
1351 len
= str_len
-start
;
1352 else if(len
> str_len
-start
)
1353 len
= str_len
-start
;
1356 V_VT(res
) = VT_BSTR
;
1357 V_BSTR(res
) = SysAllocStringLen(str
+start
, len
);
1359 return E_OUTOFMEMORY
;
1365 static HRESULT
Global_MidB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1371 static HRESULT
Global_StrComp(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1378 TRACE("(%s %s ...)\n", debugstr_variant(args
), debugstr_variant(args
+1));
1380 assert(args_cnt
== 2 || args_cnt
== 3);
1382 if (args_cnt
== 3) {
1383 hres
= to_int(args
+2, &mode
);
1387 if (mode
!= 0 && mode
!= 1) {
1388 FIXME("unknown compare mode = %d\n", mode
);
1395 hres
= to_string(args
, &left
);
1399 hres
= to_string(args
+1, &right
);
1402 SysFreeString(left
);
1406 ret
= mode
? wcsicmp(left
, right
) : wcscmp(left
, right
);
1407 val
= ret
< 0 ? -1 : (ret
> 0 ? 1 : 0);
1409 SysFreeString(left
);
1410 SysFreeString(right
);
1411 return return_short(res
, val
);
1414 static HRESULT
Global_LCase(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1419 TRACE("%s\n", debugstr_variant(arg
));
1421 if(V_VT(arg
) == VT_NULL
) {
1423 V_VT(res
) = VT_NULL
;
1427 hres
= to_string(arg
, &str
);
1434 for(ptr
= str
; *ptr
; ptr
++)
1435 *ptr
= towlower(*ptr
);
1437 V_VT(res
) = VT_BSTR
;
1445 static HRESULT
Global_UCase(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1450 TRACE("%s\n", debugstr_variant(arg
));
1452 if(V_VT(arg
) == VT_NULL
) {
1454 V_VT(res
) = VT_NULL
;
1458 hres
= to_string(arg
, &str
);
1465 for(ptr
= str
; *ptr
; ptr
++)
1466 *ptr
= towupper(*ptr
);
1468 V_VT(res
) = VT_BSTR
;
1476 static HRESULT
Global_LTrim(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1478 BSTR str
, conv_str
= NULL
;
1482 TRACE("%s\n", debugstr_variant(arg
));
1484 if(V_VT(arg
) == VT_BSTR
) {
1487 hres
= to_string(arg
, &conv_str
);
1493 for(ptr
= str
; *ptr
&& iswspace(*ptr
); ptr
++);
1495 str
= SysAllocString(ptr
);
1496 SysFreeString(conv_str
);
1498 return E_OUTOFMEMORY
;
1500 return return_bstr(res
, str
);
1503 static HRESULT
Global_RTrim(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1505 BSTR str
, conv_str
= NULL
;
1509 TRACE("%s\n", debugstr_variant(arg
));
1511 if(V_VT(arg
) == VT_BSTR
) {
1514 hres
= to_string(arg
, &conv_str
);
1520 for(ptr
= str
+SysStringLen(str
); ptr
-1 > str
&& iswspace(*(ptr
-1)); ptr
--);
1522 str
= SysAllocStringLen(str
, ptr
-str
);
1523 SysFreeString(conv_str
);
1525 return E_OUTOFMEMORY
;
1527 return return_bstr(res
, str
);
1530 static HRESULT
Global_Trim(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1532 BSTR str
, conv_str
= NULL
;
1533 WCHAR
*begin_ptr
, *end_ptr
;
1536 TRACE("%s\n", debugstr_variant(arg
));
1538 if(V_VT(arg
) == VT_BSTR
) {
1541 hres
= to_string(arg
, &conv_str
);
1547 for(begin_ptr
= str
; *begin_ptr
&& iswspace(*begin_ptr
); begin_ptr
++);
1548 for(end_ptr
= str
+SysStringLen(str
); end_ptr
-1 > begin_ptr
&& iswspace(*(end_ptr
-1)); end_ptr
--);
1550 str
= SysAllocStringLen(begin_ptr
, end_ptr
-begin_ptr
);
1551 SysFreeString(conv_str
);
1553 return E_OUTOFMEMORY
;
1555 return return_bstr(res
, str
);
1558 static HRESULT
Global_Space(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1564 TRACE("%s\n", debugstr_variant(arg
));
1566 hres
= to_int(arg
, &n
);
1571 FIXME("n = %d\n", n
);
1578 str
= SysAllocStringLen(NULL
, n
);
1580 return E_OUTOFMEMORY
;
1585 V_VT(res
) = VT_BSTR
;
1590 static HRESULT
Global_String(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1596 TRACE("%s %s\n", debugstr_variant(args
), debugstr_variant(args
+ 1));
1598 hres
= to_int(args
, &cnt
);
1602 return E_INVALIDARG
;
1604 if(V_VT(args
+ 1) != VT_BSTR
) {
1605 FIXME("Unsupported argument %s\n", debugstr_variant(args
+1));
1608 if(!SysStringLen(V_BSTR(args
+ 1)))
1609 return E_INVALIDARG
;
1610 ch
= V_BSTR(args
+ 1)[0];
1613 BSTR str
= SysAllocStringLen(NULL
, cnt
);
1615 return E_OUTOFMEMORY
;
1616 wmemset(str
, ch
, cnt
);
1617 V_VT(res
) = VT_BSTR
;
1623 static HRESULT
Global_InStr(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
1625 VARIANT
*startv
, *str1v
, *str2v
;
1632 assert(2 <= args_cnt
&& args_cnt
<= 4);
1646 FIXME("unsupported compare argument %s\n", debugstr_variant(args
));
1648 DEFAULT_UNREACHABLE
;
1652 hres
= to_int(startv
, &start
);
1656 FIXME("start %d\n", start
);
1663 if(V_VT(str1v
) == VT_NULL
|| V_VT(str2v
) == VT_NULL
)
1664 return return_null(res
);
1666 if(V_VT(str1v
) != VT_BSTR
) {
1667 FIXME("Unsupported str1 type %s\n", debugstr_variant(str1v
));
1670 str1
= V_BSTR(str1v
);
1672 if(V_VT(str2v
) != VT_BSTR
) {
1673 FIXME("Unsupported str2 type %s\n", debugstr_variant(str2v
));
1676 str2
= V_BSTR(str2v
);
1678 if(start
< SysStringLen(str1
)) {
1681 ptr
= wcsstr(str1
+start
, str2
);
1682 ret
= ptr
? ptr
-str1
+1 : 0;
1687 return return_int(res
, ret
);
1690 static HRESULT
Global_InStrB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1696 static HRESULT
Global_AscB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1702 static HRESULT
Global_ChrB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1708 static HRESULT
Global_Asc(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1710 BSTR conv_str
= NULL
, str
;
1711 HRESULT hres
= S_OK
;
1713 TRACE("(%s)\n", debugstr_variant(arg
));
1717 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1719 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1724 hres
= to_string(arg
, &conv_str
);
1730 if(!SysStringLen(str
) || *str
>= 0x100)
1731 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1733 hres
= return_short(res
, *str
);
1734 SysFreeString(conv_str
);
1738 /* The function supports only single-byte and double-byte character sets. It
1739 * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
1740 * to be in range of short or unsigned short. */
1741 static HRESULT
Global_Chr(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1749 TRACE("%s\n", debugstr_variant(arg
));
1751 hres
= to_int(arg
, &c
);
1756 if(!GetCPInfo(cp
, &cpi
))
1757 cpi
.MaxCharSize
= 1;
1759 if((c
!=(short)c
&& c
!=(unsigned short)c
) ||
1760 (unsigned short)c
>=(cpi
.MaxCharSize
>1 ? 0x10000 : 0x100)) {
1761 WARN("invalid arg %d\n", c
);
1762 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1767 if(!len
|| IsDBCSLeadByteEx(cp
, buf
[0]))
1769 if(!MultiByteToWideChar(CP_ACP
, 0, buf
, len
, &ch
, 1)) {
1770 WARN("invalid arg %d, cp %d\n", c
, cp
);
1775 V_VT(res
) = VT_BSTR
;
1776 V_BSTR(res
) = SysAllocStringLen(&ch
, 1);
1778 return E_OUTOFMEMORY
;
1783 static HRESULT
Global_AscW(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1789 static HRESULT
Global_ChrW(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1795 static HRESULT
Global_Abs(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1800 TRACE("(%s)\n", debugstr_variant(arg
));
1802 assert(args_cnt
== 1);
1804 hres
= VarAbs(arg
, &dst
);
1816 static HRESULT
Global_Fix(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1821 TRACE("(%s)\n", debugstr_variant(arg
));
1823 assert(args_cnt
== 1);
1825 hres
= VarFix(arg
, &dst
);
1837 static HRESULT
Global_Int(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1842 TRACE("(%s)\n", debugstr_variant(arg
));
1844 assert(args_cnt
== 1);
1846 hres
= VarInt(arg
, &dst
);
1858 static HRESULT
Global_Sgn(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1864 TRACE("(%s)\n", debugstr_variant(arg
));
1866 assert(args_cnt
== 1);
1868 if(V_VT(arg
) == VT_NULL
)
1869 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1871 hres
= to_double(arg
, &v
);
1875 val
= v
== 0 ? 0 : (v
> 0 ? 1 : -1);
1876 return return_short(res
, val
);
1879 static HRESULT
Global_Now(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1887 SystemTimeToVariantTime(<
, &date
);
1888 return return_date(res
, date
);
1891 static HRESULT
Global_Date(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1903 hres
= VarDateFromUdateEx(&ud
, 0, VAR_DATEVALUEONLY
, &date
);
1906 return return_date(res
, date
);
1909 static HRESULT
Global_Time(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1921 hres
= VarDateFromUdateEx(&ud
, 0, VAR_TIMEVALUEONLY
, &time
);
1924 return return_date(res
, time
);
1927 static HRESULT
Global_Day(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1932 TRACE("(%s)\n", debugstr_variant(arg
));
1934 hres
= to_system_time(arg
, &st
);
1935 return FAILED(hres
) ? hres
: return_short(res
, st
.wDay
);
1938 static HRESULT
Global_Month(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1943 TRACE("(%s)\n", debugstr_variant(arg
));
1945 hres
= to_system_time(arg
, &st
);
1946 return FAILED(hres
) ? hres
: return_short(res
, st
.wMonth
);
1949 static HRESULT
Global_Weekday(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1955 static HRESULT
Global_Year(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1960 TRACE("(%s)\n", debugstr_variant(arg
));
1962 hres
= to_system_time(arg
, &st
);
1963 return FAILED(hres
) ? hres
: return_short(res
, st
.wYear
);
1966 static HRESULT
Global_Hour(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1971 TRACE("(%s)\n", debugstr_variant(arg
));
1973 hres
= to_system_time(arg
, &st
);
1974 return FAILED(hres
) ? hres
: return_short(res
, st
.wHour
);
1977 static HRESULT
Global_Minute(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1982 TRACE("(%s)\n", debugstr_variant(arg
));
1984 hres
= to_system_time(arg
, &st
);
1985 return FAILED(hres
) ? hres
: return_short(res
, st
.wMinute
);
1988 static HRESULT
Global_Second(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1993 TRACE("(%s)\n", debugstr_variant(arg
));
1995 hres
= to_system_time(arg
, &st
);
1996 return FAILED(hres
) ? hres
: return_short(res
, st
.wSecond
);
1999 static HRESULT
Global_DateValue(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2005 static HRESULT
Global_TimeValue(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2011 static HRESULT
Global_DateSerial(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2017 static HRESULT
Global_TimeSerial(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2023 static HRESULT
Global_InputBox(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2029 static HRESULT
Global_MsgBox(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2031 BSTR prompt
, title
= NULL
;
2037 assert(1 <= args_cnt
&& args_cnt
<= 5);
2039 hres
= to_string(args
, &prompt
);
2044 hres
= to_int(args
+1, &type
);
2046 if(SUCCEEDED(hres
) && args_cnt
> 2)
2047 hres
= to_string(args
+2, &title
);
2049 if(SUCCEEDED(hres
) && args_cnt
> 3) {
2050 FIXME("unsupported arg_cnt %d\n", args_cnt
);
2055 hres
= show_msgbox(This
->ctx
, prompt
, type
, title
, res
);
2057 SysFreeString(prompt
);
2058 SysFreeString(title
);
2062 static HRESULT
Global_CreateObject(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2067 TRACE("(%s)\n", debugstr_variant(arg
));
2069 if(V_VT(arg
) != VT_BSTR
) {
2070 FIXME("non-bstr arg\n");
2071 return E_INVALIDARG
;
2074 obj
= create_object(This
->ctx
, V_BSTR(arg
));
2076 return VB_E_CANNOT_CREATE_OBJ
;
2079 hres
= IUnknown_QueryInterface(obj
, &IID_IDispatch
, (void**)&V_DISPATCH(res
));
2083 V_VT(res
) = VT_DISPATCH
;
2086 IUnknown_Release(obj
);
2090 static HRESULT
Global_GetObject(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2099 TRACE("%s %s\n", args_cnt
? debugstr_variant(args
) : "", args_cnt
> 1 ? debugstr_variant(args
+1) : "");
2101 if(args_cnt
!= 1 || V_VT(args
) != VT_BSTR
) {
2102 FIXME("unsupported args\n");
2106 if(This
->ctx
->safeopt
& (INTERFACE_USES_SECURITY_MANAGER
|INTERFACESAFE_FOR_UNTRUSTED_DATA
)) {
2107 WARN("blocked in current safety mode\n");
2108 return VB_E_CANNOT_CREATE_OBJ
;
2111 hres
= CreateBindCtx(0, &bind_ctx
);
2115 hres
= MkParseDisplayName(bind_ctx
, V_BSTR(args
), &eaten
, &mon
);
2116 if(SUCCEEDED(hres
)) {
2117 hres
= IMoniker_BindToObject(mon
, bind_ctx
, NULL
, &IID_IUnknown
, (void**)&obj_unk
);
2118 IMoniker_Release(mon
);
2122 IBindCtx_Release(bind_ctx
);
2126 hres
= set_object_site(This
->ctx
, obj_unk
);
2128 IUnknown_Release(obj_unk
);
2132 hres
= IUnknown_QueryInterface(obj_unk
, &IID_IDispatch
, (void**)&disp
);
2133 if(SUCCEEDED(hres
)) {
2135 V_VT(res
) = VT_DISPATCH
;
2136 V_DISPATCH(res
) = disp
;
2138 IDispatch_Release(disp
);
2141 FIXME("object does not support IDispatch\n");
2147 static HRESULT
Global_DateAdd(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2153 static HRESULT
Global_DateDiff(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2159 static HRESULT
Global_DatePart(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2165 static HRESULT
Global_TypeName(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2167 static const WCHAR ByteW
[] = {'B', 'y', 't', 'e', 0};
2168 static const WCHAR IntegerW
[] = {'I', 'n', 't', 'e', 'g', 'e', 'r', 0};
2169 static const WCHAR LongW
[] = {'L', 'o', 'n', 'g', 0};
2170 static const WCHAR SingleW
[] = {'S', 'i', 'n', 'g', 'l', 'e', 0};
2171 static const WCHAR DoubleW
[] = {'D', 'o', 'u', 'b', 'l', 'e', 0};
2172 static const WCHAR CurrencyW
[] = {'C', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 0};
2173 static const WCHAR DecimalW
[] = {'D', 'e', 'c', 'i', 'm', 'a', 'l', 0};
2174 static const WCHAR DateW
[] = {'D', 'a', 't', 'e', 0};
2175 static const WCHAR StringW
[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
2176 static const WCHAR BooleanW
[] = {'B', 'o', 'o', 'l', 'e', 'a', 'n', 0};
2177 static const WCHAR EmptyW
[] = {'E', 'm', 'p', 't', 'y', 0};
2178 static const WCHAR NullW
[] = {'N', 'u', 'l', 'l', 0};
2180 TRACE("(%s)\n", debugstr_variant(arg
));
2182 assert(args_cnt
== 1);
2186 return return_string(res
, ByteW
);
2188 return return_string(res
, IntegerW
);
2190 return return_string(res
, LongW
);
2192 return return_string(res
, SingleW
);
2194 return return_string(res
, DoubleW
);
2196 return return_string(res
, CurrencyW
);
2198 return return_string(res
, DecimalW
);
2200 return return_string(res
, DateW
);
2202 return return_string(res
, StringW
);
2204 return return_string(res
, BooleanW
);
2206 return return_string(res
, EmptyW
);
2208 return return_string(res
, NullW
);
2210 FIXME("arg %s not supported\n", debugstr_variant(arg
));
2215 static HRESULT
Global_Array(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2217 SAFEARRAYBOUND bounds
;
2223 TRACE("arg_cnt=%u\n", args_cnt
);
2226 bounds
.cElements
= args_cnt
;
2227 sa
= SafeArrayCreate(VT_VARIANT
, 1, &bounds
);
2229 return E_OUTOFMEMORY
;
2231 hres
= SafeArrayAccessData(sa
, (void**)&data
);
2233 SafeArrayDestroy(sa
);
2237 for(i
=0; i
<args_cnt
; i
++) {
2238 hres
= VariantCopyInd(data
+i
, arg
+i
);
2240 SafeArrayUnaccessData(sa
);
2241 SafeArrayDestroy(sa
);
2245 SafeArrayUnaccessData(sa
);
2248 V_VT(res
) = VT_ARRAY
|VT_VARIANT
;
2251 SafeArrayDestroy(sa
);
2257 static HRESULT
Global_Erase(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2263 static HRESULT
Global_Filter(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2269 static HRESULT
Global_Join(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2275 static HRESULT
Global_Split(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2281 static HRESULT
Global_Replace(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2283 BSTR string
, find
= NULL
, replace
= NULL
, ret
;
2284 int from
= 1, cnt
= -1;
2285 HRESULT hres
= S_OK
;
2287 TRACE("%s %s %s %u...\n", debugstr_variant(args
), debugstr_variant(args
+1), debugstr_variant(args
+2), args_cnt
);
2289 assert(3 <= args_cnt
&& args_cnt
<= 6);
2290 if(V_VT(args
) != VT_BSTR
) {
2291 hres
= to_string(args
, &string
);
2295 string
= V_BSTR(args
);
2298 if(V_VT(args
+1) != VT_BSTR
) {
2299 hres
= to_string(args
+1, &find
);
2303 find
= V_BSTR(args
+1);
2306 if(V_VT(args
+2) != VT_BSTR
) {
2307 hres
= to_string(args
+2, &replace
);
2311 replace
= V_BSTR(args
+2);
2315 hres
= to_int(args
+3, &from
);
2319 hres
= E_INVALIDARG
;
2325 hres
= to_int(args
+4, &cnt
);
2329 hres
= E_INVALIDARG
;
2335 FIXME("copare argument not supported\n");
2337 ret
= string_replace(string
, find
, replace
, from
- 1, cnt
);
2339 hres
= E_OUTOFMEMORY
;
2341 V_VT(res
) = VT_BSTR
;
2348 if(V_VT(args
) != VT_BSTR
)
2349 SysFreeString(string
);
2350 if(V_VT(args
+1) != VT_BSTR
)
2351 SysFreeString(find
);
2352 if(V_VT(args
+2) != VT_BSTR
)
2353 SysFreeString(replace
);
2357 static HRESULT
Global_StrReverse(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2359 WCHAR
*ptr1
, *ptr2
, ch
;
2363 TRACE("%s\n", debugstr_variant(arg
));
2365 hres
= to_string(arg
, &ret
);
2370 ptr2
= ret
+ SysStringLen(ret
)-1;
2371 while(ptr1
< ptr2
) {
2377 return return_bstr(res
, ret
);
2380 static HRESULT
Global_InStrRev(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2386 TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args
), debugstr_variant(args
+1), args_cnt
);
2389 FIXME("Unsupported args\n");
2393 assert(2 <= args_cnt
&& args_cnt
<= 4);
2395 if(V_VT(args
) == VT_NULL
|| V_VT(args
+1) == VT_NULL
|| (args_cnt
> 2 && V_VT(args
+2) == VT_NULL
))
2396 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
2398 hres
= to_string(args
, &str1
);
2402 hres
= to_string(args
+1, &str2
);
2403 if(SUCCEEDED(hres
)) {
2405 hres
= to_int(args
+2, &start
);
2406 if(SUCCEEDED(hres
) && start
<= 0) {
2407 FIXME("Unsupported start %d\n", start
);
2411 start
= SysStringLen(str1
);
2417 if(SUCCEEDED(hres
)) {
2421 len
= SysStringLen(str2
);
2422 if(start
>= len
&& start
<= SysStringLen(str1
)) {
2423 for(ptr
= str1
+start
-SysStringLen(str2
); ptr
>= str1
; ptr
--) {
2424 if(!memcmp(ptr
, str2
, len
*sizeof(WCHAR
))) {
2432 SysFreeString(str1
);
2433 SysFreeString(str2
);
2437 return return_int(res
, ret
);
2440 static HRESULT
Global_LoadPicture(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2446 static HRESULT
Global_ScriptEngine(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2448 TRACE("%s\n", debugstr_variant(arg
));
2450 assert(args_cnt
== 0);
2452 return return_string(res
, vbscriptW
);
2455 static HRESULT
Global_ScriptEngineMajorVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2457 TRACE("%s\n", debugstr_variant(arg
));
2459 assert(args_cnt
== 0);
2461 return return_int(res
, VBSCRIPT_MAJOR_VERSION
);
2464 static HRESULT
Global_ScriptEngineMinorVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2466 TRACE("%s\n", debugstr_variant(arg
));
2468 assert(args_cnt
== 0);
2470 return return_int(res
, VBSCRIPT_MINOR_VERSION
);
2473 static HRESULT
Global_ScriptEngineBuildVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2475 TRACE("%s\n", debugstr_variant(arg
));
2477 assert(args_cnt
== 0);
2479 return return_int(res
, VBSCRIPT_BUILD_VERSION
);
2482 static HRESULT
Global_FormatNumber(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2488 static HRESULT
Global_FormatCurrency(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2494 static HRESULT
Global_FormatPercent(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2500 static HRESULT
Global_FormatDateTime(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2506 static HRESULT
Global_WeekdayName(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2508 int weekday
, first_day
= 1, abbrev
= 0;
2514 assert(1 <= args_cnt
&& args_cnt
<= 3);
2516 hres
= to_int(args
, &weekday
);
2521 hres
= to_int(args
+1, &abbrev
);
2526 hres
= to_int(args
+2, &first_day
);
2532 hres
= VarWeekdayName(weekday
, abbrev
, first_day
, 0, &ret
);
2536 return return_bstr(res
, ret
);
2539 static HRESULT
Global_MonthName(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2541 int month
, abbrev
= 0;
2547 assert(args_cnt
== 1 || args_cnt
== 2);
2549 hres
= to_int(args
, &month
);
2554 hres
= to_int(args
+1, &abbrev
);
2559 hres
= VarMonthName(month
, abbrev
, 0, &ret
);
2563 return return_bstr(res
, ret
);
2566 static HRESULT
Global_Round(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2571 TRACE("%s\n", debugstr_variant(arg
));
2586 hres
= to_double(arg
, &n
);
2591 return return_double(res
, round(n
));
2594 static HRESULT
Global_Escape(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2600 static HRESULT
Global_Unescape(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2606 static HRESULT
Global_Eval(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2612 static HRESULT
Global_Execute(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2618 static HRESULT
Global_ExecuteGlobal(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2624 static HRESULT
Global_GetRef(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2630 static HRESULT
Global_Err(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2635 FIXME("Setter not supported\n");
2639 V_VT(res
) = VT_DISPATCH
;
2640 V_DISPATCH(res
) = &This
->ctx
->err_obj
->IDispatch_iface
;
2641 IDispatch_AddRef(V_DISPATCH(res
));
2645 static const string_constant_t vbCr
= {1, {'\r'}};
2646 static const string_constant_t vbCrLf
= {2, {'\r','\n'}};
2647 static const string_constant_t vbNewLine
= {2, {'\r','\n'}};
2648 static const string_constant_t vbFormFeed
= {1, {0xc}};
2649 static const string_constant_t vbLf
= {1, {'\n'}};
2650 static const string_constant_t vbNullChar
= {1};
2651 static const string_constant_t vbNullString
= {0};
2652 static const string_constant_t vbTab
= {1, {'\t'}};
2653 static const string_constant_t vbVerticalTab
= {1, {0xb}};
2655 static const builtin_prop_t global_props
[] = {
2656 {NULL
}, /* no default value */
2657 {L
"Abs", Global_Abs
, 0, 1},
2658 {L
"Array", Global_Array
, 0, 0, MAXDWORD
},
2659 {L
"Asc", Global_Asc
, 0, 1},
2660 {L
"AscB", Global_AscB
, 0, 1},
2661 {L
"AscW", Global_AscW
, 0, 1},
2662 {L
"Atn", Global_Atn
, 0, 1},
2663 {L
"CBool", Global_CBool
, 0, 1},
2664 {L
"CByte", Global_CByte
, 0, 1},
2665 {L
"CCur", Global_CCur
, 0, 1},
2666 {L
"CDate", Global_CDate
, 0, 1},
2667 {L
"CDbl", Global_CDbl
, 0, 1},
2668 {L
"Chr", Global_Chr
, 0, 1},
2669 {L
"ChrB", Global_ChrB
, 0, 1},
2670 {L
"ChrW", Global_ChrW
, 0, 1},
2671 {L
"CInt", Global_CInt
, 0, 1},
2672 {L
"CLng", Global_CLng
, 0, 1},
2673 {L
"Cos", Global_Cos
, 0, 1},
2674 {L
"CreateObject", Global_CreateObject
, 0, 1},
2675 {L
"CSng", Global_CSng
, 0, 1},
2676 {L
"CStr", Global_CStr
, 0, 1},
2677 {L
"Date", Global_Date
, 0, 0},
2678 {L
"DateAdd", Global_DateAdd
, 0, 3},
2679 {L
"DateDiff", Global_DateDiff
, 0, 3, 5},
2680 {L
"DatePart", Global_DatePart
, 0, 2, 4},
2681 {L
"DateSerial", Global_DateSerial
, 0, 3},
2682 {L
"DateValue", Global_DateValue
, 0, 1},
2683 {L
"Day", Global_Day
, 0, 1},
2684 {L
"Erase", Global_Erase
, 0, 1},
2685 {L
"Err", Global_Err
, BP_GETPUT
},
2686 {L
"Escape", Global_Escape
, 0, 1},
2687 {L
"Eval", Global_Eval
, 0, 1},
2688 {L
"Execute", Global_Execute
, 0, 1},
2689 {L
"ExecuteGlobal", Global_ExecuteGlobal
, 0, 1},
2690 {L
"Exp", Global_Exp
, 0, 1},
2691 {L
"Filter", Global_Filter
, 0, 2, 4},
2692 {L
"Fix", Global_Fix
, 0, 1},
2693 {L
"FormatCurrency", Global_FormatCurrency
, 0, 1, 5},
2694 {L
"FormatDateTime", Global_FormatDateTime
, 0, 1, 2},
2695 {L
"FormatNumber", Global_FormatNumber
, 0, 1, 5},
2696 {L
"FormatPercent", Global_FormatPercent
, 0, 1, 5},
2697 {L
"GetObject", Global_GetObject
, 0, 0, 2},
2698 {L
"GetRef", Global_GetRef
, 0, 1},
2699 {L
"Hex", Global_Hex
, 0, 1},
2700 {L
"Hour", Global_Hour
, 0, 1},
2701 {L
"InputBox", Global_InputBox
, 0, 1, 7},
2702 {L
"InStr", Global_InStr
, 0, 2, 4},
2703 {L
"InStrB", Global_InStrB
, 0, 3, 4},
2704 {L
"InStrRev", Global_InStrRev
, 0, 2, 4},
2705 {L
"Int", Global_Int
, 0, 1},
2706 {L
"IsArray", Global_IsArray
, 0, 1},
2707 {L
"IsDate", Global_IsDate
, 0, 1},
2708 {L
"IsEmpty", Global_IsEmpty
, 0, 1},
2709 {L
"IsNull", Global_IsNull
, 0, 1},
2710 {L
"IsNumeric", Global_IsNumeric
, 0, 1},
2711 {L
"IsObject", Global_IsObject
, 0, 1},
2712 {L
"Join", Global_Join
, 0, 1, 2},
2713 {L
"LBound", Global_LBound
, 0, 1, 2},
2714 {L
"LCase", Global_LCase
, 0, 1},
2715 {L
"Left", Global_Left
, 0, 2},
2716 {L
"LeftB", Global_LeftB
, 0, 2},
2717 {L
"Len", Global_Len
, 0, 1},
2718 {L
"LenB", Global_LenB
, 0, 1},
2719 {L
"LoadPicture", Global_LoadPicture
, 0, 1},
2720 {L
"Log", Global_Log
, 0, 1},
2721 {L
"LTrim", Global_LTrim
, 0, 1},
2722 {L
"Mid", Global_Mid
, 0, 2, 3},
2723 {L
"MidB", Global_MidB
, 0, 2, 3},
2724 {L
"Minute", Global_Minute
, 0, 1},
2725 {L
"Month", Global_Month
, 0, 1},
2726 {L
"MonthName", Global_MonthName
, 0, 1, 2},
2727 {L
"MsgBox", Global_MsgBox
, 0, 1, 5},
2728 {L
"Now", Global_Now
, 0, 0},
2729 {L
"Oct", Global_Oct
, 0, 1},
2730 {L
"Randomize", Global_Randomize
, 0, 1},
2731 {L
"Replace", Global_Replace
, 0, 3, 6},
2732 {L
"RGB", Global_RGB
, 0, 3},
2733 {L
"Right", Global_Right
, 0, 2},
2734 {L
"RightB", Global_RightB
, 0, 2},
2735 {L
"Rnd", Global_Rnd
, 0, 1},
2736 {L
"Round", Global_Round
, 0, 1, 2},
2737 {L
"RTrim", Global_RTrim
, 0, 1},
2738 {L
"ScriptEngine", Global_ScriptEngine
, 0, 0},
2739 {L
"ScriptEngineBuildVersion", Global_ScriptEngineBuildVersion
, 0, 0},
2740 {L
"ScriptEngineMajorVersion", Global_ScriptEngineMajorVersion
, 0, 0},
2741 {L
"ScriptEngineMinorVersion", Global_ScriptEngineMinorVersion
, 0, 0},
2742 {L
"Second", Global_Second
, 0, 1},
2743 {L
"Sgn", Global_Sgn
, 0, 1},
2744 {L
"Sin", Global_Sin
, 0, 1},
2745 {L
"Space", Global_Space
, 0, 1},
2746 {L
"Split", Global_Split
, 0, 1, 4},
2747 {L
"Sqr", Global_Sqr
, 0, 1},
2748 {L
"StrComp", Global_StrComp
, 0, 2, 3},
2749 {L
"String", Global_String
, 0, 0, 2},
2750 {L
"StrReverse", Global_StrReverse
, 0, 1},
2751 {L
"Tan", Global_Tan
, 0, 1},
2752 {L
"Time", Global_Time
, 0, 0},
2753 {L
"Timer", Global_Timer
, 0, 0},
2754 {L
"TimeSerial", Global_TimeSerial
, 0, 3},
2755 {L
"TimeValue", Global_TimeValue
, 0, 1},
2756 {L
"Trim", Global_Trim
, 0, 1},
2757 {L
"TypeName", Global_TypeName
, 0, 1},
2758 {L
"UBound", Global_UBound
, 0, 1, 2},
2759 {L
"UCase", Global_UCase
, 0, 1},
2760 {L
"Unescape", Global_Unescape
, 0, 1},
2761 {L
"VarType", Global_VarType
, 0, 1},
2762 {L
"vbAbort", NULL
, BP_GET
, VT_I2
, IDABORT
},
2763 {L
"vbAbortRetryIgnore", NULL
, BP_GET
, VT_I2
, MB_ABORTRETRYIGNORE
},
2764 {L
"vbApplicationModal", NULL
, BP_GET
, VT_I2
, MB_APPLMODAL
},
2765 {L
"vbArray", NULL
, BP_GET
, VT_I2
, VT_ARRAY
},
2766 {L
"vbBinaryCompare", NULL
, BP_GET
, VT_I2
, 0},
2767 {L
"vbBlack", NULL
, BP_GET
, VT_I4
, 0x000000},
2768 {L
"vbBlue", NULL
, BP_GET
, VT_I4
, 0xff0000},
2769 {L
"vbBoolean", NULL
, BP_GET
, VT_I2
, VT_BOOL
},
2770 {L
"vbByte", NULL
, BP_GET
, VT_I2
, VT_UI1
},
2771 {L
"vbCancel", NULL
, BP_GET
, VT_I2
, IDCANCEL
},
2772 {L
"vbCr", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbCr
},
2773 {L
"vbCritical", NULL
, BP_GET
, VT_I2
, MB_ICONHAND
},
2774 {L
"vbCrLf", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbCrLf
},
2775 {L
"vbCurrency", NULL
, BP_GET
, VT_I2
, VT_CY
},
2776 {L
"vbCyan", NULL
, BP_GET
, VT_I4
, 0xffff00},
2777 {L
"vbDatabaseCompare", NULL
, BP_GET
, VT_I2
, 2},
2778 {L
"vbDataObject", NULL
, BP_GET
, VT_I2
, VT_UNKNOWN
},
2779 {L
"vbDate", NULL
, BP_GET
, VT_I2
, VT_DATE
},
2780 {L
"vbDecimal", NULL
, BP_GET
, VT_I2
, VT_DECIMAL
},
2781 {L
"vbDefaultButton1", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON1
},
2782 {L
"vbDefaultButton2", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON2
},
2783 {L
"vbDefaultButton3", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON3
},
2784 {L
"vbDefaultButton4", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON4
},
2785 {L
"vbDouble", NULL
, BP_GET
, VT_I2
, VT_R8
},
2786 {L
"vbEmpty", NULL
, BP_GET
, VT_I2
, VT_EMPTY
},
2787 {L
"vbError", NULL
, BP_GET
, VT_I2
, VT_ERROR
},
2788 {L
"vbExclamation", NULL
, BP_GET
, VT_I2
, MB_ICONEXCLAMATION
},
2789 {L
"vbFalse", NULL
, BP_GET
, VT_I2
, VARIANT_FALSE
},
2790 {L
"vbFirstFourDays", NULL
, BP_GET
, VT_I2
, 2},
2791 {L
"vbFirstFullWeek", NULL
, BP_GET
, VT_I2
, 3},
2792 {L
"vbFirstJan1", NULL
, BP_GET
, VT_I2
, 1},
2793 {L
"vbFormFeed", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbFormFeed
},
2794 {L
"vbFriday", NULL
, BP_GET
, VT_I2
, 6},
2795 {L
"vbGeneralDate", NULL
, BP_GET
, VT_I2
, 0},
2796 {L
"vbGreen", NULL
, BP_GET
, VT_I4
, 0x00ff00},
2797 {L
"vbIgnore", NULL
, BP_GET
, VT_I2
, IDIGNORE
},
2798 {L
"vbInformation", NULL
, BP_GET
, VT_I2
, MB_ICONASTERISK
},
2799 {L
"vbInteger", NULL
, BP_GET
, VT_I2
, VT_I2
},
2800 {L
"vbLf", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbLf
},
2801 {L
"vbLong", NULL
, BP_GET
, VT_I2
, VT_I4
},
2802 {L
"vbLongDate", NULL
, BP_GET
, VT_I2
, 1},
2803 {L
"vbLongTime", NULL
, BP_GET
, VT_I2
, 3},
2804 {L
"vbMagenta", NULL
, BP_GET
, VT_I4
, 0xff00ff},
2805 {L
"vbMonday", NULL
, BP_GET
, VT_I2
, 2},
2806 {L
"vbMsgBoxHelpButton", NULL
, BP_GET
, VT_I4
, MB_HELP
},
2807 {L
"vbMsgBoxRight", NULL
, BP_GET
, VT_I4
, MB_RIGHT
},
2808 {L
"vbMsgBoxRtlReading", NULL
, BP_GET
, VT_I4
, MB_RTLREADING
},
2809 {L
"vbMsgBoxSetForeground", NULL
, BP_GET
, VT_I4
, MB_SETFOREGROUND
},
2810 {L
"vbNewLine", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNewLine
},
2811 {L
"vbNo", NULL
, BP_GET
, VT_I2
, IDNO
},
2812 {L
"vbNull", NULL
, BP_GET
, VT_I2
, VT_NULL
},
2813 {L
"vbNullChar", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNullChar
},
2814 {L
"vbNullString", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNullString
},
2815 {L
"vbObject", NULL
, BP_GET
, VT_I2
, VT_DISPATCH
},
2816 {L
"vbObjectError", NULL
, BP_GET
, VT_I4
, 0x80040000},
2817 {L
"vbOK", NULL
, BP_GET
, VT_I2
, IDOK
},
2818 {L
"vbOKCancel", NULL
, BP_GET
, VT_I2
, MB_OKCANCEL
},
2819 {L
"vbOKOnly", NULL
, BP_GET
, VT_I2
, MB_OK
},
2820 {L
"vbQuestion", NULL
, BP_GET
, VT_I2
, MB_ICONQUESTION
},
2821 {L
"vbRed", NULL
, BP_GET
, VT_I4
, 0x0000ff},
2822 {L
"vbRetry", NULL
, BP_GET
, VT_I2
, IDRETRY
},
2823 {L
"vbRetryCancel", NULL
, BP_GET
, VT_I2
, MB_RETRYCANCEL
},
2824 {L
"vbSaturday", NULL
, BP_GET
, VT_I2
, 7},
2825 {L
"vbShortDate", NULL
, BP_GET
, VT_I2
, 2},
2826 {L
"vbShortTime", NULL
, BP_GET
, VT_I2
, 4},
2827 {L
"vbSingle", NULL
, BP_GET
, VT_I2
, VT_R4
},
2828 {L
"vbString", NULL
, BP_GET
, VT_I2
, VT_BSTR
},
2829 {L
"vbSunday", NULL
, BP_GET
, VT_I2
, 1},
2830 {L
"vbSystemModal", NULL
, BP_GET
, VT_I2
, MB_SYSTEMMODAL
},
2831 {L
"vbTab", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbTab
},
2832 {L
"vbTextCompare", NULL
, BP_GET
, VT_I2
, 1},
2833 {L
"vbThursday", NULL
, BP_GET
, VT_I2
, 5},
2834 {L
"vbTrue", NULL
, BP_GET
, VT_I2
, VARIANT_TRUE
},
2835 {L
"vbTuesday", NULL
, BP_GET
, VT_I2
, 3},
2836 {L
"vbUseDefault", NULL
, BP_GET
, VT_I2
, -2},
2837 {L
"vbUseSystem", NULL
, BP_GET
, VT_I2
, 0},
2838 {L
"vbUseSystemDayOfWeek", NULL
, BP_GET
, VT_I2
, 0},
2839 {L
"vbVariant", NULL
, BP_GET
, VT_I2
, VT_VARIANT
},
2840 {L
"vbVerticalTab", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbVerticalTab
},
2841 {L
"vbWednesday", NULL
, BP_GET
, VT_I2
, 4},
2842 {L
"vbWhite", NULL
, BP_GET
, VT_I4
, 0xffffff},
2843 {L
"vbYellow", NULL
, BP_GET
, VT_I4
, 0x00ffff},
2844 {L
"vbYes", NULL
, BP_GET
, VT_I2
, IDYES
},
2845 {L
"vbYesNo", NULL
, BP_GET
, VT_I2
, MB_YESNO
},
2846 {L
"vbYesNoCancel", NULL
, BP_GET
, VT_I2
, MB_YESNOCANCEL
},
2847 {L
"Weekday", Global_Weekday
, 0, 1, 2},
2848 {L
"WeekdayName", Global_WeekdayName
, 0, 1, 3},
2849 {L
"Year", Global_Year
, 0, 1}
2852 static HRESULT
err_string_prop(BSTR
*prop
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2858 return return_string(res
, *prop
? *prop
: L
"");
2860 hres
= to_string(args
, &str
);
2864 SysFreeString(*prop
);
2869 static HRESULT
Err_Description(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2872 return err_string_prop(&This
->ctx
->ei
.bstrDescription
, args
, args_cnt
, res
);
2875 static HRESULT
Err_HelpContext(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2880 FIXME("setter not implemented\n");
2884 return return_int(res
, This
->ctx
->ei
.dwHelpContext
);
2887 static HRESULT
Err_HelpFile(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2890 return err_string_prop(&This
->ctx
->ei
.bstrHelpFile
, args
, args_cnt
, res
);
2893 static HRESULT
Err_Number(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2900 FIXME("setter not implemented\n");
2904 hres
= This
->ctx
->ei
.scode
;
2905 return return_int(res
, HRESULT_FACILITY(hres
) == FACILITY_VBS
? HRESULT_CODE(hres
) : hres
);
2908 static HRESULT
Err_Source(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2911 return err_string_prop(&This
->ctx
->ei
.bstrSource
, args
, args_cnt
, res
);
2914 static HRESULT
Err_Clear(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2918 clear_ei(&This
->ctx
->ei
);
2922 static HRESULT
Err_Raise(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2924 BSTR source
= NULL
, description
= NULL
, helpfile
= NULL
;
2925 int code
, helpcontext
= 0;
2926 HRESULT hres
, error
;
2928 TRACE("%s %u...\n", debugstr_variant(args
), args_cnt
);
2930 hres
= to_int(args
, &code
);
2933 if(code
> 0 && code
> 0xffff)
2934 return E_INVALIDARG
;
2937 hres
= to_string(args
+ 1, &source
);
2938 if(args_cnt
>= 3 && SUCCEEDED(hres
))
2939 hres
= to_string(args
+ 2, &description
);
2940 if(args_cnt
>= 4 && SUCCEEDED(hres
))
2941 hres
= to_string(args
+ 3, &helpfile
);
2942 if(args_cnt
>= 5 && SUCCEEDED(hres
))
2943 hres
= to_int(args
+ 4, &helpcontext
);
2945 if(SUCCEEDED(hres
)) {
2946 script_ctx_t
*ctx
= This
->ctx
;
2948 error
= (code
& ~0xffff) ? map_hres(code
) : MAKE_VBSERROR(code
);
2951 SysFreeString(ctx
->ei
.bstrSource
);
2952 ctx
->ei
.bstrSource
= source
;
2954 if(!ctx
->ei
.bstrSource
)
2955 ctx
->ei
.bstrSource
= get_vbscript_string(VBS_RUNTIME_ERROR
);
2957 SysFreeString(ctx
->ei
.bstrDescription
);
2958 ctx
->ei
.bstrDescription
= description
;
2960 if(!ctx
->ei
.bstrDescription
)
2961 ctx
->ei
.bstrDescription
= get_vbscript_error_string(error
);
2963 SysFreeString(ctx
->ei
.bstrHelpFile
);
2964 ctx
->ei
.bstrHelpFile
= helpfile
;
2967 ctx
->ei
.dwHelpContext
= helpcontext
;
2969 ctx
->ei
.scode
= error
;
2970 hres
= SCRIPT_E_RECORDED
;
2972 SysFreeString(source
);
2973 SysFreeString(description
);
2974 SysFreeString(helpfile
);
2980 static const builtin_prop_t err_props
[] = {
2981 {NULL
, Err_Number
, BP_GETPUT
},
2982 {L
"Clear", Err_Clear
},
2983 {L
"Description", Err_Description
, BP_GETPUT
},
2984 {L
"HelpContext", Err_HelpContext
, BP_GETPUT
},
2985 {L
"HelpFile", Err_HelpFile
, BP_GETPUT
},
2986 {L
"Number", Err_Number
, BP_GETPUT
},
2987 {L
"Raise", Err_Raise
, 0, 1, 5},
2988 {L
"Source", Err_Source
, BP_GETPUT
}
2991 void detach_global_objects(script_ctx_t
*ctx
)
2994 ctx
->err_obj
->ctx
= NULL
;
2995 IDispatch_Release(&ctx
->err_obj
->IDispatch_iface
);
2996 ctx
->err_obj
= NULL
;
2999 if(ctx
->global_obj
) {
3000 ctx
->global_obj
->ctx
= NULL
;
3001 IDispatch_Release(&ctx
->global_obj
->IDispatch_iface
);
3002 ctx
->global_obj
= NULL
;
3006 HRESULT
init_global(script_ctx_t
*ctx
)
3010 hres
= create_builtin_dispatch(ctx
, global_props
, ARRAY_SIZE(global_props
), &ctx
->global_obj
);
3014 return create_builtin_dispatch(ctx
, err_props
, ARRAY_SIZE(err_props
), &ctx
->err_obj
);