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}};
48 struct _builtin_prop_t
{
50 HRESULT (*proc
)(BuiltinDisp
*,VARIANT
*,unsigned,VARIANT
*);
56 static inline BuiltinDisp
*impl_from_IDispatch(IDispatch
*iface
)
58 return CONTAINING_RECORD(iface
, BuiltinDisp
, IDispatch_iface
);
61 static HRESULT WINAPI
Builtin_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppv
)
63 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
65 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
66 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
67 *ppv
= &This
->IDispatch_iface
;
68 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
69 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
70 *ppv
= &This
->IDispatch_iface
;
72 if(!IsEqualGUID(riid
, &IID_IDispatchEx
))
73 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
78 IUnknown_AddRef((IUnknown
*)*ppv
);
82 static ULONG WINAPI
Builtin_AddRef(IDispatch
*iface
)
84 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
85 LONG ref
= InterlockedIncrement(&This
->ref
);
87 TRACE("(%p) ref=%d\n", This
, ref
);
92 static ULONG WINAPI
Builtin_Release(IDispatch
*iface
)
94 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
95 LONG ref
= InterlockedDecrement(&This
->ref
);
97 TRACE("(%p) ref=%d\n", This
, ref
);
107 static HRESULT WINAPI
Builtin_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
109 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
110 TRACE("(%p)->(%p)\n", This
, pctinfo
);
115 static HRESULT WINAPI
Builtin_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
117 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
118 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
119 return DISP_E_BADINDEX
;
122 HRESULT
get_builtin_id(BuiltinDisp
*disp
, const WCHAR
*name
, DISPID
*id
)
124 size_t min
= 1, max
= disp
->member_cnt
- 1, i
;
129 r
= wcsicmp(disp
->members
[i
].name
, name
);
140 return DISP_E_MEMBERNOTFOUND
;
144 static HRESULT WINAPI
Builtin_GetIDsOfNames(IDispatch
*iface
, REFIID riid
, LPOLESTR
*names
, UINT name_cnt
,
145 LCID lcid
, DISPID
*ids
)
147 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
151 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), names
, name_cnt
, lcid
, ids
);
154 FIXME("NULL context\n");
158 for(i
= 0; i
< name_cnt
; i
++) {
159 hres
= get_builtin_id(This
, names
[i
], &ids
[i
]);
167 static HRESULT WINAPI
Builtin_Invoke(IDispatch
*iface
, DISPID id
, REFIID riid
, LCID lcid
, WORD flags
,
168 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, UINT
*err
)
170 BuiltinDisp
*This
= impl_from_IDispatch(iface
);
171 const builtin_prop_t
*prop
;
172 VARIANT args_buf
[8], *args
;
176 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, id
, debugstr_guid(riid
), lcid
, flags
, dp
, res
, ei
, err
);
179 FIXME("NULL context\n");
183 if(id
>= This
->member_cnt
|| (!This
->members
[id
].proc
&& !This
->members
[id
].flags
))
184 return DISP_E_MEMBERNOTFOUND
;
185 prop
= This
->members
+ id
;
188 case DISPATCH_PROPERTYGET
:
189 if(!(prop
->flags
& (BP_GET
|BP_GETPUT
))) {
190 FIXME("property does not support DISPATCH_PROPERTYGET\n");
194 case DISPATCH_PROPERTYGET
|DISPATCH_METHOD
:
195 if(!prop
->proc
&& prop
->flags
== BP_GET
) {
196 const int vt
= prop
->min_args
, val
= prop
->max_args
;
207 const string_constant_t
*str
= (const string_constant_t
*)prop
->max_args
;
210 ret
= SysAllocStringLen(str
->buf
, str
->len
);
212 return E_OUTOFMEMORY
;
223 case DISPATCH_METHOD
:
224 if(prop
->flags
& (BP_GET
|BP_GETPUT
)) {
225 FIXME("Call on property\n");
229 case DISPATCH_PROPERTYPUT
:
230 if(!(prop
->flags
& BP_GETPUT
)) {
231 FIXME("property does not support DISPATCH_PROPERTYPUT\n");
238 FIXME("unsupported flags %x\n", flags
);
244 if(argn
< prop
->min_args
|| argn
> (prop
->max_args
? prop
->max_args
: prop
->min_args
)) {
245 WARN("invalid number of arguments\n");
246 return MAKE_VBSERROR(VBSE_FUNC_ARITY_MISMATCH
);
249 if(argn
<= ARRAY_SIZE(args_buf
)) {
252 args
= heap_alloc(argn
* sizeof(*args
));
254 return E_OUTOFMEMORY
;
257 for(i
=0; i
< argn
; i
++) {
258 if(V_VT(dp
->rgvarg
+dp
->cArgs
-i
-1) == (VT_BYREF
|VT_VARIANT
))
259 args
[i
] = *V_VARIANTREF(dp
->rgvarg
+dp
->cArgs
-i
-1);
261 args
[i
] = dp
->rgvarg
[dp
->cArgs
-i
-1];
264 hres
= prop
->proc(This
, args
, dp
->cArgs
, res
);
270 static const IDispatchVtbl BuiltinDispVtbl
= {
271 Builtin_QueryInterface
,
274 Builtin_GetTypeInfoCount
,
276 Builtin_GetIDsOfNames
,
280 static HRESULT
create_builtin_dispatch(script_ctx_t
*ctx
, const builtin_prop_t
*members
, size_t member_cnt
, BuiltinDisp
**ret
)
284 if(!(disp
= heap_alloc(sizeof(*disp
))))
285 return E_OUTOFMEMORY
;
287 disp
->IDispatch_iface
.lpVtbl
= &BuiltinDispVtbl
;
289 disp
->members
= members
;
290 disp
->member_cnt
= member_cnt
;
297 static IInternetHostSecurityManager
*get_sec_mgr(script_ctx_t
*ctx
)
299 IInternetHostSecurityManager
*secmgr
;
300 IServiceProvider
*sp
;
309 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IServiceProvider
, (void**)&sp
);
313 hres
= IServiceProvider_QueryService(sp
, &SID_SInternetHostSecurityManager
, &IID_IInternetHostSecurityManager
,
315 IServiceProvider_Release(sp
);
319 return ctx
->secmgr
= secmgr
;
322 static HRESULT
return_string(VARIANT
*res
, const WCHAR
*str
)
329 ret
= SysAllocString(str
);
331 return E_OUTOFMEMORY
;
338 static HRESULT
return_bstr(VARIANT
*res
, BSTR str
)
349 static HRESULT
return_bool(VARIANT
*res
, BOOL val
)
353 V_BOOL(res
) = val
? VARIANT_TRUE
: VARIANT_FALSE
;
358 static HRESULT
return_short(VARIANT
*res
, short val
)
368 static HRESULT
return_int(VARIANT
*res
, int val
)
378 static inline HRESULT
return_double(VARIANT
*res
, double val
)
388 static inline HRESULT
return_float(VARIANT
*res
, float val
)
398 static inline HRESULT
return_null(VARIANT
*res
)
405 static inline HRESULT
return_date(VARIANT
*res
, double date
)
414 HRESULT
to_int(VARIANT
*v
, int *ret
)
420 hres
= VariantChangeType(&r
, v
, 0, VT_I4
);
428 static HRESULT
to_double(VARIANT
*v
, double *ret
)
433 V_VT(&dst
) = VT_EMPTY
;
434 hres
= VariantChangeType(&dst
, v
, 0, VT_R8
);
442 static HRESULT
to_string(VARIANT
*v
, BSTR
*ret
)
447 V_VT(&dst
) = VT_EMPTY
;
448 hres
= VariantChangeType(&dst
, v
, VARIANT_LOCALBOOL
, VT_BSTR
);
456 static HRESULT
to_system_time(VARIANT
*v
, SYSTEMTIME
*st
)
461 V_VT(&date
) = VT_EMPTY
;
462 hres
= VariantChangeType(&date
, v
, 0, VT_DATE
);
466 return VariantTimeToSystemTime(V_DATE(&date
), st
);
469 static HRESULT
set_object_site(script_ctx_t
*ctx
, IUnknown
*obj
)
471 IObjectWithSite
*obj_site
;
475 hres
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (void**)&obj_site
);
479 ax_site
= create_ax_site(ctx
);
481 hres
= IObjectWithSite_SetSite(obj_site
, ax_site
);
482 IUnknown_Release(ax_site
);
485 hres
= E_OUTOFMEMORY
;
486 IObjectWithSite_Release(obj_site
);
490 static IUnknown
*create_object(script_ctx_t
*ctx
, const WCHAR
*progid
)
492 IInternetHostSecurityManager
*secmgr
= NULL
;
493 struct CONFIRMSAFETY cs
;
494 IClassFactoryEx
*cfex
;
503 hres
= CLSIDFromProgID(progid
, &guid
);
507 TRACE("GUID %s\n", debugstr_guid(&guid
));
509 if(ctx
->safeopt
& INTERFACE_USES_SECURITY_MANAGER
) {
510 secmgr
= get_sec_mgr(ctx
);
515 hres
= IInternetHostSecurityManager_ProcessUrlAction(secmgr
, URLACTION_ACTIVEX_RUN
,
516 (BYTE
*)&policy
, sizeof(policy
), (BYTE
*)&guid
, sizeof(GUID
), 0, 0);
517 if(FAILED(hres
) || policy
!= URLPOLICY_ALLOW
)
521 hres
= CoGetClassObject(&guid
, CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
, NULL
, &IID_IClassFactory
, (void**)&cf
);
525 hres
= IClassFactory_QueryInterface(cf
, &IID_IClassFactoryEx
, (void**)&cfex
);
526 if(SUCCEEDED(hres
)) {
527 FIXME("Use IClassFactoryEx\n");
528 IClassFactoryEx_Release(cfex
);
531 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)&obj
);
539 hres
= IInternetHostSecurityManager_QueryCustomPolicy(secmgr
, &GUID_CUSTOM_CONFIRMOBJECTSAFETY
,
540 &bpolicy
, &policy_size
, (BYTE
*)&cs
, sizeof(cs
), 0);
541 if(SUCCEEDED(hres
)) {
542 policy
= policy_size
>= sizeof(DWORD
) ? *(DWORD
*)bpolicy
: URLPOLICY_DISALLOW
;
543 CoTaskMemFree(bpolicy
);
546 if(FAILED(hres
) || policy
!= URLPOLICY_ALLOW
) {
547 IUnknown_Release(obj
);
552 hres
= set_object_site(ctx
, obj
);
554 IUnknown_Release(obj
);
561 static HRESULT
show_msgbox(script_ctx_t
*ctx
, BSTR prompt
, unsigned type
, BSTR orig_title
, VARIANT
*res
)
563 SCRIPTUICHANDLING uic_handling
= SCRIPTUICHANDLING_ALLOW
;
564 IActiveScriptSiteUIControl
*ui_control
;
565 IActiveScriptSiteWindow
*acts_window
;
566 WCHAR
*title_buf
= NULL
;
572 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IActiveScriptSiteUIControl
, (void**)&ui_control
);
573 if(SUCCEEDED(hres
)) {
574 hres
= IActiveScriptSiteUIControl_GetUIBehavior(ui_control
, SCRIPTUICITEM_MSGBOX
, &uic_handling
);
575 IActiveScriptSiteUIControl_Release(ui_control
);
577 uic_handling
= SCRIPTUICHANDLING_ALLOW
;
580 switch(uic_handling
) {
581 case SCRIPTUICHANDLING_ALLOW
:
583 case SCRIPTUICHANDLING_NOUIDEFAULT
:
584 return return_short(res
, 0);
590 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IActiveScriptSiteWindow
, (void**)&acts_window
);
592 FIXME("No IActiveScriptSiteWindow\n");
596 if(ctx
->safeopt
& INTERFACE_USES_SECURITY_MANAGER
) {
597 if(orig_title
&& *orig_title
) {
600 title
= title_buf
= heap_alloc(sizeof(L
"VBScript") + (lstrlenW(orig_title
)+2)*sizeof(WCHAR
));
602 return E_OUTOFMEMORY
;
604 memcpy(title_buf
, L
"VBScript", sizeof(L
"VBScript"));
605 ptr
= title_buf
+ ARRAY_SIZE(L
"VBScript")-1;
609 lstrcpyW(ptr
, orig_title
);
614 title
= orig_title
? orig_title
: L
"";
617 hres
= IActiveScriptSiteWindow_GetWindow(acts_window
, &hwnd
);
618 if(SUCCEEDED(hres
)) {
619 hres
= IActiveScriptSiteWindow_EnableModeless(acts_window
, FALSE
);
620 if(SUCCEEDED(hres
)) {
621 ret
= MessageBoxW(hwnd
, prompt
, title
, type
);
622 hres
= IActiveScriptSiteWindow_EnableModeless(acts_window
, TRUE
);
626 heap_free(title_buf
);
627 IActiveScriptSiteWindow_Release(acts_window
);
629 FIXME("failed: %08x\n", hres
);
633 return return_short(res
, ret
);
636 static HRESULT
Global_CCur(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
641 TRACE("%s\n", debugstr_variant(arg
));
643 assert(args_cnt
== 1);
646 hres
= VariantChangeType(&v
, arg
, 0, VT_CY
);
652 return DISP_E_BADVARTYPE
;
659 static HRESULT
Global_CInt(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
664 TRACE("%s\n", debugstr_variant(arg
));
666 assert(args_cnt
== 1);
669 hres
= VariantChangeType(&v
, arg
, 0, VT_I2
);
674 return DISP_E_BADVARTYPE
;
681 static HRESULT
Global_CLng(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
686 TRACE("%s\n", debugstr_variant(arg
));
688 assert(args_cnt
== 1);
690 hres
= to_int(arg
, &i
);
694 return DISP_E_BADVARTYPE
;
696 return return_int(res
, i
);
699 static HRESULT
Global_CBool(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
704 TRACE("%s\n", debugstr_variant(arg
));
706 assert(args_cnt
== 1);
709 hres
= VariantChangeType(&v
, arg
, VARIANT_LOCALBOOL
, VT_BOOL
);
720 static HRESULT
Global_CByte(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
725 TRACE("%s\n", debugstr_variant(arg
));
727 assert(args_cnt
== 1);
730 hres
= VariantChangeType(&v
, arg
, VARIANT_LOCALBOOL
, VT_UI1
);
736 return DISP_E_BADVARTYPE
;
743 static HRESULT
Global_CDate(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
749 static HRESULT
Global_CDbl(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
754 TRACE("%s\n", debugstr_variant(arg
));
756 assert(args_cnt
== 1);
759 hres
= VariantChangeType(&v
, arg
, 0, VT_R8
);
764 return DISP_E_BADVARTYPE
;
771 static HRESULT
Global_CSng(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
776 TRACE("%s\n", debugstr_variant(arg
));
778 assert(args_cnt
== 1);
781 hres
= VariantChangeType(&v
, arg
, 0, VT_R4
);
786 return DISP_E_BADVARTYPE
;
792 static HRESULT
Global_CStr(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
797 TRACE("%s\n", debugstr_variant(arg
));
799 if(V_VT(arg
) == VT_NULL
)
800 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
802 hres
= to_string(arg
, &str
);
806 return return_bstr(res
, str
);
809 static inline WCHAR
hex_char(unsigned n
)
811 return n
< 10 ? '0'+n
: 'A'+n
-10;
814 static HRESULT
Global_Hex(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
821 TRACE("%s\n", debugstr_variant(arg
));
832 hres
= to_int(arg
, &ret
);
844 *ptr
-- = hex_char(n
& 0xf);
852 return return_string(res
, ptr
);
855 static HRESULT
Global_Oct(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
862 TRACE("%s\n", debugstr_variant(arg
));
873 hres
= to_int(arg
, &ret
);
885 *ptr
-- = '0' + (n
& 0x7);
893 return return_string(res
, ptr
);
896 static HRESULT
Global_VarType(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
900 TRACE("(%s)\n", debugstr_variant(arg
));
902 assert(args_cnt
== 1);
904 vt
= V_VT(arg
) & ~VT_BYREF
;
905 if(vt
& ~(VT_TYPEMASK
| VT_ARRAY
)) {
906 FIXME("not supported %s\n", debugstr_variant(arg
));
910 return return_short(res
, vt
);
913 static HRESULT
Global_IsDate(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
919 static HRESULT
Global_IsEmpty(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
921 TRACE("(%s)\n", debugstr_variant(arg
));
923 assert(args_cnt
== 1);
927 V_BOOL(res
) = V_VT(arg
) == VT_EMPTY
? VARIANT_TRUE
: VARIANT_FALSE
;
932 static HRESULT
Global_IsNull(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
934 TRACE("(%s)\n", debugstr_variant(arg
));
936 assert(args_cnt
== 1);
940 V_BOOL(res
) = V_VT(arg
) == VT_NULL
? VARIANT_TRUE
: VARIANT_FALSE
;
945 static HRESULT
Global_IsNumeric(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
950 TRACE("(%s)\n", debugstr_variant(arg
));
952 assert(args_cnt
== 1);
954 hres
= to_double(arg
, &d
);
956 return return_bool(res
, SUCCEEDED(hres
));
959 static HRESULT
Global_IsArray(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
961 TRACE("(%s)\n", debugstr_variant(arg
));
963 assert(args_cnt
== 1);
965 return return_bool(res
, V_ISARRAY(arg
));
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
;
1627 int ret
= -1, start
= 0, mode
= 0;
1630 TRACE("args_cnt=%u\n", args_cnt
);
1632 assert(2 <= args_cnt
&& args_cnt
<= 4);
1650 if(V_VT(args
+3) == VT_NULL
)
1651 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1653 hres
= to_int(args
+3, &mode
);
1657 if (mode
!= 0 && mode
!= 1)
1658 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1661 DEFAULT_UNREACHABLE
;
1665 if(V_VT(startv
) == VT_NULL
)
1666 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1668 hres
= to_int(startv
, &start
);
1672 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1675 if(V_VT(str1v
) == VT_NULL
|| V_VT(str2v
) == VT_NULL
)
1676 return return_null(res
);
1678 if(V_VT(str1v
) != VT_BSTR
) {
1679 hres
= to_string(str1v
, &str1
);
1684 str1
= V_BSTR(str1v
);
1686 if(V_VT(str2v
) != VT_BSTR
) {
1687 hres
= to_string(str2v
, &str2
);
1689 if(V_VT(str1v
) != VT_BSTR
)
1690 SysFreeString(str1
);
1695 str2
= V_BSTR(str2v
);
1697 if(start
< SysStringLen(str1
)) {
1698 ret
= FindStringOrdinal(FIND_FROMSTART
, str1
+ start
, SysStringLen(str1
)-start
,
1699 str2
, SysStringLen(str2
), mode
);
1702 if(V_VT(str1v
) != VT_BSTR
)
1703 SysFreeString(str1
);
1704 if(V_VT(str2v
) != VT_BSTR
)
1705 SysFreeString(str2
);
1706 return return_int(res
, ++ret
? ret
+start
: 0);
1709 static HRESULT
Global_InStrB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1715 static HRESULT
Global_AscB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1721 static HRESULT
Global_ChrB(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1727 static HRESULT
Global_Asc(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1729 BSTR conv_str
= NULL
, str
;
1730 HRESULT hres
= S_OK
;
1732 TRACE("(%s)\n", debugstr_variant(arg
));
1736 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1738 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1743 hres
= to_string(arg
, &conv_str
);
1749 if(!SysStringLen(str
))
1750 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1752 unsigned char buf
[2];
1754 int n
= WideCharToMultiByte(CP_ACP
, 0, str
, 1, (char*)buf
, sizeof(buf
), NULL
, NULL
);
1760 val
= (buf
[0] << 8) | buf
[1];
1763 WARN("Failed to convert %x\n", *str
);
1764 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1767 hres
= return_short(res
, val
);
1770 SysFreeString(conv_str
);
1774 /* The function supports only single-byte and double-byte character sets. It
1775 * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
1776 * to be in range of short or unsigned short. */
1777 static HRESULT
Global_Chr(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1785 TRACE("%s\n", debugstr_variant(arg
));
1787 hres
= to_int(arg
, &c
);
1792 if(!GetCPInfo(cp
, &cpi
))
1793 cpi
.MaxCharSize
= 1;
1795 if((c
!=(short)c
&& c
!=(unsigned short)c
) ||
1796 (unsigned short)c
>=(cpi
.MaxCharSize
>1 ? 0x10000 : 0x100)) {
1797 WARN("invalid arg %d\n", c
);
1798 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
1803 if(!len
|| IsDBCSLeadByteEx(cp
, buf
[0]))
1805 if(!MultiByteToWideChar(CP_ACP
, 0, buf
, len
, &ch
, 1)) {
1806 WARN("invalid arg %d, cp %d\n", c
, cp
);
1811 V_VT(res
) = VT_BSTR
;
1812 V_BSTR(res
) = SysAllocStringLen(&ch
, 1);
1814 return E_OUTOFMEMORY
;
1819 static HRESULT
Global_AscW(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1825 static HRESULT
Global_ChrW(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1831 static HRESULT
Global_Abs(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1836 TRACE("(%s)\n", debugstr_variant(arg
));
1838 assert(args_cnt
== 1);
1840 hres
= VarAbs(arg
, &dst
);
1852 static HRESULT
Global_Fix(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1857 TRACE("(%s)\n", debugstr_variant(arg
));
1859 assert(args_cnt
== 1);
1861 hres
= VarFix(arg
, &dst
);
1873 static HRESULT
Global_Int(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1878 TRACE("(%s)\n", debugstr_variant(arg
));
1880 assert(args_cnt
== 1);
1882 hres
= VarInt(arg
, &dst
);
1894 static HRESULT
Global_Sgn(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1900 TRACE("(%s)\n", debugstr_variant(arg
));
1902 assert(args_cnt
== 1);
1904 if(V_VT(arg
) == VT_NULL
)
1905 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
1907 hres
= to_double(arg
, &v
);
1911 val
= v
== 0 ? 0 : (v
> 0 ? 1 : -1);
1912 return return_short(res
, val
);
1915 static HRESULT
Global_Now(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1923 SystemTimeToVariantTime(<
, &date
);
1924 return return_date(res
, date
);
1927 static HRESULT
Global_Date(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1939 hres
= VarDateFromUdateEx(&ud
, 0, VAR_DATEVALUEONLY
, &date
);
1942 return return_date(res
, date
);
1945 static HRESULT
Global_Time(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1957 hres
= VarDateFromUdateEx(&ud
, 0, VAR_TIMEVALUEONLY
, &time
);
1960 return return_date(res
, time
);
1963 static HRESULT
Global_Day(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1968 TRACE("(%s)\n", debugstr_variant(arg
));
1970 hres
= to_system_time(arg
, &st
);
1971 return FAILED(hres
) ? hres
: return_short(res
, st
.wDay
);
1974 static HRESULT
Global_Month(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1979 TRACE("(%s)\n", debugstr_variant(arg
));
1981 hres
= to_system_time(arg
, &st
);
1982 return FAILED(hres
) ? hres
: return_short(res
, st
.wMonth
);
1985 static HRESULT
Global_Weekday(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1991 static HRESULT
Global_Year(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
1996 TRACE("(%s)\n", debugstr_variant(arg
));
1998 hres
= to_system_time(arg
, &st
);
1999 return FAILED(hres
) ? hres
: return_short(res
, st
.wYear
);
2002 static HRESULT
Global_Hour(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2007 TRACE("(%s)\n", debugstr_variant(arg
));
2009 hres
= to_system_time(arg
, &st
);
2010 return FAILED(hres
) ? hres
: return_short(res
, st
.wHour
);
2013 static HRESULT
Global_Minute(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2018 TRACE("(%s)\n", debugstr_variant(arg
));
2020 hres
= to_system_time(arg
, &st
);
2021 return FAILED(hres
) ? hres
: return_short(res
, st
.wMinute
);
2024 static HRESULT
Global_Second(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2029 TRACE("(%s)\n", debugstr_variant(arg
));
2031 hres
= to_system_time(arg
, &st
);
2032 return FAILED(hres
) ? hres
: return_short(res
, st
.wSecond
);
2035 static HRESULT
Global_DateValue(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2041 static HRESULT
Global_TimeValue(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2047 static HRESULT
Global_DateSerial(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2053 static HRESULT
Global_TimeSerial(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2059 static HRESULT
Global_InputBox(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2065 static HRESULT
Global_MsgBox(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2067 BSTR prompt
, title
= NULL
;
2073 assert(1 <= args_cnt
&& args_cnt
<= 5);
2075 hres
= to_string(args
, &prompt
);
2080 hres
= to_int(args
+1, &type
);
2082 if(SUCCEEDED(hres
) && args_cnt
> 2)
2083 hres
= to_string(args
+2, &title
);
2085 if(SUCCEEDED(hres
) && args_cnt
> 3) {
2086 FIXME("unsupported arg_cnt %d\n", args_cnt
);
2091 hres
= show_msgbox(This
->ctx
, prompt
, type
, title
, res
);
2093 SysFreeString(prompt
);
2094 SysFreeString(title
);
2098 static HRESULT
Global_CreateObject(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2103 TRACE("(%s)\n", debugstr_variant(arg
));
2105 if(V_VT(arg
) != VT_BSTR
) {
2106 FIXME("non-bstr arg\n");
2107 return E_INVALIDARG
;
2110 obj
= create_object(This
->ctx
, V_BSTR(arg
));
2112 return VB_E_CANNOT_CREATE_OBJ
;
2115 hres
= IUnknown_QueryInterface(obj
, &IID_IDispatch
, (void**)&V_DISPATCH(res
));
2119 V_VT(res
) = VT_DISPATCH
;
2122 IUnknown_Release(obj
);
2126 static HRESULT
Global_GetObject(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2135 TRACE("%s %s\n", args_cnt
? debugstr_variant(args
) : "", args_cnt
> 1 ? debugstr_variant(args
+1) : "");
2137 if(args_cnt
!= 1 || V_VT(args
) != VT_BSTR
) {
2138 FIXME("unsupported args\n");
2142 if(This
->ctx
->safeopt
& (INTERFACE_USES_SECURITY_MANAGER
|INTERFACESAFE_FOR_UNTRUSTED_DATA
)) {
2143 WARN("blocked in current safety mode\n");
2144 return VB_E_CANNOT_CREATE_OBJ
;
2147 hres
= CreateBindCtx(0, &bind_ctx
);
2151 hres
= MkParseDisplayName(bind_ctx
, V_BSTR(args
), &eaten
, &mon
);
2152 if(SUCCEEDED(hres
)) {
2153 hres
= IMoniker_BindToObject(mon
, bind_ctx
, NULL
, &IID_IUnknown
, (void**)&obj_unk
);
2154 IMoniker_Release(mon
);
2158 IBindCtx_Release(bind_ctx
);
2162 hres
= set_object_site(This
->ctx
, obj_unk
);
2164 IUnknown_Release(obj_unk
);
2168 hres
= IUnknown_QueryInterface(obj_unk
, &IID_IDispatch
, (void**)&disp
);
2169 if(SUCCEEDED(hres
)) {
2171 V_VT(res
) = VT_DISPATCH
;
2172 V_DISPATCH(res
) = disp
;
2174 IDispatch_Release(disp
);
2177 FIXME("object does not support IDispatch\n");
2183 static HRESULT
Global_DateAdd(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2189 static HRESULT
Global_DateDiff(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2195 static HRESULT
Global_DatePart(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2201 static HRESULT
Global_TypeName(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2203 TRACE("(%s)\n", debugstr_variant(arg
));
2205 assert(args_cnt
== 1);
2208 return return_string(res
, L
"Variant()");
2212 return return_string(res
, L
"Byte");
2214 return return_string(res
, L
"Integer");
2216 return return_string(res
, L
"Long");
2218 return return_string(res
, L
"Single");
2220 return return_string(res
, L
"Double");
2222 return return_string(res
, L
"Currency");
2224 return return_string(res
, L
"Decimal");
2226 return return_string(res
, L
"Date");
2228 return return_string(res
, L
"String");
2230 return return_string(res
, L
"Boolean");
2232 return return_string(res
, L
"Empty");
2234 return return_string(res
, L
"Null");
2236 FIXME("arg %s not supported\n", debugstr_variant(arg
));
2241 static HRESULT
Global_Array(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2243 SAFEARRAYBOUND bounds
;
2249 TRACE("arg_cnt=%u\n", args_cnt
);
2252 bounds
.cElements
= args_cnt
;
2253 sa
= SafeArrayCreate(VT_VARIANT
, 1, &bounds
);
2255 return E_OUTOFMEMORY
;
2257 hres
= SafeArrayAccessData(sa
, (void**)&data
);
2259 SafeArrayDestroy(sa
);
2263 for(i
=0; i
<args_cnt
; i
++) {
2264 hres
= VariantCopyInd(data
+i
, arg
+i
);
2266 SafeArrayUnaccessData(sa
);
2267 SafeArrayDestroy(sa
);
2271 SafeArrayUnaccessData(sa
);
2274 V_VT(res
) = VT_ARRAY
|VT_VARIANT
;
2277 SafeArrayDestroy(sa
);
2283 static HRESULT
Global_Erase(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2289 static HRESULT
Global_Filter(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2295 static HRESULT
Global_Join(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2301 static HRESULT
Global_Split(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2303 BSTR str
, string
, delimiter
= NULL
;
2304 int count
, max
, mode
, len
, start
, end
, ret
, delimiterlen
= 1;
2305 int i
,*indices
= NULL
, indices_max
= 8;
2306 SAFEARRAYBOUND bounds
;
2307 SAFEARRAY
*sa
= NULL
;
2309 HRESULT hres
= S_OK
;
2311 TRACE("%s %u...\n", debugstr_variant(args
), args_cnt
);
2313 assert(1 <= args_cnt
&& args_cnt
<= 4);
2315 if(V_VT(args
) == VT_NULL
|| (args_cnt
> 1 && V_VT(args
+1) == VT_NULL
) || (args_cnt
> 2 && V_VT(args
+2) == VT_NULL
)
2316 || (args_cnt
== 4 && V_VT(args
+3) == VT_NULL
))
2317 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
2319 if(V_VT(args
) != VT_BSTR
) {
2320 hres
= to_string(args
, &string
);
2324 string
= V_BSTR(args
);
2328 if(V_VT(args
+1) != VT_BSTR
) {
2329 hres
= to_string(args
+1, &delimiter
);
2333 delimiter
= V_BSTR(args
+1);
2335 delimiterlen
= SysStringLen(delimiter
);
2339 hres
= to_int(args
+2, &max
);
2343 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
2351 hres
= to_int(args
+3, &mode
);
2354 if (mode
!= 0 && mode
!= 1) {
2355 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
2364 len
= SysStringLen(string
);
2367 indices
= heap_alloc( indices_max
* sizeof(int));
2369 hres
= E_OUTOFMEMORY
;
2376 ret
= FindStringOrdinal(FIND_FROMSTART
, string
+ start
, len
- start
,
2377 delimiter
? delimiter
: L
" ", delimiterlen
, mode
);
2386 if (count
== indices_max
) {
2388 indices
= heap_realloc( indices
, indices_max
* sizeof(int));
2390 hres
= E_OUTOFMEMORY
;
2394 indices
[count
++] = end
;
2396 if (ret
== -1 || count
== max
) break;
2397 start
= start
+ ret
+ delimiterlen
;
2398 if (start
> len
) break;
2402 bounds
.cElements
= count
;
2403 sa
= SafeArrayCreate( VT_VARIANT
, 1, &bounds
);
2405 hres
= E_OUTOFMEMORY
;
2408 hres
= SafeArrayAccessData(sa
, (void**)&data
);
2414 for (i
= 0; i
< count
; i
++) {
2415 str
= SysAllocStringLen(string
+ start
, indices
[i
] - start
);
2417 hres
= E_OUTOFMEMORY
;
2420 V_VT(&var
) = VT_BSTR
;
2423 hres
= VariantCopyInd(data
+i
, &var
);
2425 SafeArrayUnaccessData(sa
);
2428 start
= indices
[i
]+delimiterlen
;
2430 SafeArrayUnaccessData(sa
);
2433 if(SUCCEEDED(hres
) && res
) {
2434 V_VT(res
) = VT_ARRAY
|VT_VARIANT
;
2437 SafeArrayDestroy(sa
);
2441 if(V_VT(args
) != VT_BSTR
)
2442 SysFreeString(string
);
2443 if(args_cnt
> 1 && V_VT(args
+1) != VT_BSTR
)
2444 SysFreeString(delimiter
);
2448 static HRESULT
Global_Replace(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2450 BSTR string
, find
= NULL
, replace
= NULL
, ret
;
2451 int from
= 1, cnt
= -1, mode
= 0;
2452 HRESULT hres
= S_OK
;
2454 TRACE("%s %s %s %u...\n", debugstr_variant(args
), debugstr_variant(args
+1), debugstr_variant(args
+2), args_cnt
);
2456 assert(3 <= args_cnt
&& args_cnt
<= 6);
2458 if(V_VT(args
) == VT_NULL
|| V_VT(args
+1) == VT_NULL
|| (V_VT(args
+2) == VT_NULL
)
2459 || (args_cnt
>= 4 && V_VT(args
+3) == VT_NULL
) || (args_cnt
>= 5 && V_VT(args
+4) == VT_NULL
)
2460 || (args_cnt
== 6 && V_VT(args
+5) == VT_NULL
))
2461 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
2464 if(V_VT(args
) != VT_BSTR
) {
2465 hres
= to_string(args
, &string
);
2469 string
= V_BSTR(args
);
2472 if(V_VT(args
+1) != VT_BSTR
) {
2473 hres
= to_string(args
+1, &find
);
2477 find
= V_BSTR(args
+1);
2480 if(V_VT(args
+2) != VT_BSTR
) {
2481 hres
= to_string(args
+2, &replace
);
2485 replace
= V_BSTR(args
+2);
2489 hres
= to_int(args
+3, &from
);
2493 hres
= E_INVALIDARG
;
2499 hres
= to_int(args
+4, &cnt
);
2503 hres
= E_INVALIDARG
;
2509 hres
= to_int(args
+5, &mode
);
2512 if (mode
!= 0 && mode
!= 1) {
2513 hres
= MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
2518 ret
= string_replace(string
, find
, replace
, from
- 1, cnt
, mode
);
2520 hres
= E_OUTOFMEMORY
;
2522 V_VT(res
) = VT_BSTR
;
2529 if(V_VT(args
) != VT_BSTR
)
2530 SysFreeString(string
);
2531 if(V_VT(args
+1) != VT_BSTR
)
2532 SysFreeString(find
);
2533 if(V_VT(args
+2) != VT_BSTR
)
2534 SysFreeString(replace
);
2538 static HRESULT
Global_StrReverse(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2540 WCHAR
*ptr1
, *ptr2
, ch
;
2544 TRACE("%s\n", debugstr_variant(arg
));
2546 hres
= to_string(arg
, &ret
);
2551 ptr2
= ret
+ SysStringLen(ret
)-1;
2552 while(ptr1
< ptr2
) {
2558 return return_bstr(res
, ret
);
2561 static HRESULT
Global_InStrRev(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2563 int start
= -1, ret
= -1, mode
= 0;
2568 TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args
), debugstr_variant(args
+1), args_cnt
);
2570 assert(2 <= args_cnt
&& args_cnt
<= 4);
2572 if(V_VT(args
) == VT_NULL
|| V_VT(args
+1) == VT_NULL
|| (args_cnt
> 2 && V_VT(args
+2) == VT_NULL
)
2573 || (args_cnt
== 4 && V_VT(args
+3) == VT_NULL
))
2574 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE
);
2577 hres
= to_int(args
+3, &mode
);
2580 if (mode
!= 0 && mode
!= 1)
2581 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
2585 hres
= to_int(args
+2, &start
);
2588 if(!start
|| start
< -1)
2589 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL
);
2592 if(V_VT(args
) != VT_BSTR
) {
2593 hres
= to_string(args
, &str1
);
2598 str1
= V_BSTR(args
);
2600 if(V_VT(args
+1) != VT_BSTR
) {
2601 hres
= to_string(args
+1, &str2
);
2603 if(V_VT(args
) != VT_BSTR
)
2604 SysFreeString(str1
);
2609 str2
= V_BSTR(args
+1);
2611 len1
= SysStringLen(str1
);
2620 len2
= SysStringLen(str2
);
2626 if(start
>= len2
&& start
<= len1
) {
2627 ret
= FindStringOrdinal(FIND_FROMEND
, str1
, start
,
2633 if(V_VT(args
) != VT_BSTR
)
2634 SysFreeString(str1
);
2635 if(V_VT(args
+1) != VT_BSTR
)
2636 SysFreeString(str2
);
2637 return return_int(res
, ret
);
2640 static HRESULT
Global_LoadPicture(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2646 static HRESULT
Global_ScriptEngine(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2648 TRACE("%s\n", debugstr_variant(arg
));
2650 assert(args_cnt
== 0);
2652 return return_string(res
, L
"VBScript");
2655 static HRESULT
Global_ScriptEngineMajorVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2657 TRACE("%s\n", debugstr_variant(arg
));
2659 assert(args_cnt
== 0);
2661 return return_int(res
, VBSCRIPT_MAJOR_VERSION
);
2664 static HRESULT
Global_ScriptEngineMinorVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2666 TRACE("%s\n", debugstr_variant(arg
));
2668 assert(args_cnt
== 0);
2670 return return_int(res
, VBSCRIPT_MINOR_VERSION
);
2673 static HRESULT
Global_ScriptEngineBuildVersion(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2675 TRACE("%s\n", debugstr_variant(arg
));
2677 assert(args_cnt
== 0);
2679 return return_int(res
, VBSCRIPT_BUILD_VERSION
);
2682 static HRESULT
Global_FormatNumber(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2688 static HRESULT
Global_FormatCurrency(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2694 static HRESULT
Global_FormatPercent(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2700 static HRESULT
Global_FormatDateTime(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2706 static HRESULT
Global_WeekdayName(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2708 int weekday
, first_day
= 1, abbrev
= 0;
2714 assert(1 <= args_cnt
&& args_cnt
<= 3);
2716 hres
= to_int(args
, &weekday
);
2721 hres
= to_int(args
+1, &abbrev
);
2726 hres
= to_int(args
+2, &first_day
);
2732 hres
= VarWeekdayName(weekday
, abbrev
, first_day
, 0, &ret
);
2736 return return_bstr(res
, ret
);
2739 static HRESULT
Global_MonthName(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
2741 int month
, abbrev
= 0;
2747 assert(args_cnt
== 1 || args_cnt
== 2);
2749 hres
= to_int(args
, &month
);
2754 hres
= to_int(args
+1, &abbrev
);
2759 hres
= VarMonthName(month
, abbrev
, 0, &ret
);
2763 return return_bstr(res
, ret
);
2766 static HRESULT
Global_Round(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2771 TRACE("%s\n", debugstr_variant(arg
));
2786 hres
= to_double(arg
, &n
);
2791 return return_double(res
, round(n
));
2794 static HRESULT
Global_Escape(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2800 static HRESULT
Global_Unescape(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2806 static HRESULT
Global_Eval(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2812 static HRESULT
Global_Execute(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2818 static HRESULT
Global_ExecuteGlobal(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2824 static HRESULT
Global_GetRef(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2830 static HRESULT
Global_Err(BuiltinDisp
*This
, VARIANT
*arg
, unsigned args_cnt
, VARIANT
*res
)
2835 FIXME("Setter not supported\n");
2839 V_VT(res
) = VT_DISPATCH
;
2840 V_DISPATCH(res
) = &This
->ctx
->err_obj
->IDispatch_iface
;
2841 IDispatch_AddRef(V_DISPATCH(res
));
2845 static const string_constant_t vbCr
= {1, {'\r'}};
2846 static const string_constant_t vbCrLf
= {2, {'\r','\n'}};
2847 static const string_constant_t vbNewLine
= {2, {'\r','\n'}};
2848 static const string_constant_t vbFormFeed
= {1, {0xc}};
2849 static const string_constant_t vbLf
= {1, {'\n'}};
2850 static const string_constant_t vbNullChar
= {1};
2851 static const string_constant_t vbNullString
= {0};
2852 static const string_constant_t vbTab
= {1, {'\t'}};
2853 static const string_constant_t vbVerticalTab
= {1, {0xb}};
2855 static const builtin_prop_t global_props
[] = {
2856 {NULL
}, /* no default value */
2857 {L
"Abs", Global_Abs
, 0, 1},
2858 {L
"Array", Global_Array
, 0, 0, MAXDWORD
},
2859 {L
"Asc", Global_Asc
, 0, 1},
2860 {L
"AscB", Global_AscB
, 0, 1},
2861 {L
"AscW", Global_AscW
, 0, 1},
2862 {L
"Atn", Global_Atn
, 0, 1},
2863 {L
"CBool", Global_CBool
, 0, 1},
2864 {L
"CByte", Global_CByte
, 0, 1},
2865 {L
"CCur", Global_CCur
, 0, 1},
2866 {L
"CDate", Global_CDate
, 0, 1},
2867 {L
"CDbl", Global_CDbl
, 0, 1},
2868 {L
"Chr", Global_Chr
, 0, 1},
2869 {L
"ChrB", Global_ChrB
, 0, 1},
2870 {L
"ChrW", Global_ChrW
, 0, 1},
2871 {L
"CInt", Global_CInt
, 0, 1},
2872 {L
"CLng", Global_CLng
, 0, 1},
2873 {L
"Cos", Global_Cos
, 0, 1},
2874 {L
"CreateObject", Global_CreateObject
, 0, 1},
2875 {L
"CSng", Global_CSng
, 0, 1},
2876 {L
"CStr", Global_CStr
, 0, 1},
2877 {L
"Date", Global_Date
, 0, 0},
2878 {L
"DateAdd", Global_DateAdd
, 0, 3},
2879 {L
"DateDiff", Global_DateDiff
, 0, 3, 5},
2880 {L
"DatePart", Global_DatePart
, 0, 2, 4},
2881 {L
"DateSerial", Global_DateSerial
, 0, 3},
2882 {L
"DateValue", Global_DateValue
, 0, 1},
2883 {L
"Day", Global_Day
, 0, 1},
2884 {L
"Erase", Global_Erase
, 0, 1},
2885 {L
"Err", Global_Err
, BP_GETPUT
},
2886 {L
"Escape", Global_Escape
, 0, 1},
2887 {L
"Eval", Global_Eval
, 0, 1},
2888 {L
"Execute", Global_Execute
, 0, 1},
2889 {L
"ExecuteGlobal", Global_ExecuteGlobal
, 0, 1},
2890 {L
"Exp", Global_Exp
, 0, 1},
2891 {L
"Filter", Global_Filter
, 0, 2, 4},
2892 {L
"Fix", Global_Fix
, 0, 1},
2893 {L
"FormatCurrency", Global_FormatCurrency
, 0, 1, 5},
2894 {L
"FormatDateTime", Global_FormatDateTime
, 0, 1, 2},
2895 {L
"FormatNumber", Global_FormatNumber
, 0, 1, 5},
2896 {L
"FormatPercent", Global_FormatPercent
, 0, 1, 5},
2897 {L
"GetObject", Global_GetObject
, 0, 0, 2},
2898 {L
"GetRef", Global_GetRef
, 0, 1},
2899 {L
"Hex", Global_Hex
, 0, 1},
2900 {L
"Hour", Global_Hour
, 0, 1},
2901 {L
"InputBox", Global_InputBox
, 0, 1, 7},
2902 {L
"InStr", Global_InStr
, 0, 2, 4},
2903 {L
"InStrB", Global_InStrB
, 0, 3, 4},
2904 {L
"InStrRev", Global_InStrRev
, 0, 2, 4},
2905 {L
"Int", Global_Int
, 0, 1},
2906 {L
"IsArray", Global_IsArray
, 0, 1},
2907 {L
"IsDate", Global_IsDate
, 0, 1},
2908 {L
"IsEmpty", Global_IsEmpty
, 0, 1},
2909 {L
"IsNull", Global_IsNull
, 0, 1},
2910 {L
"IsNumeric", Global_IsNumeric
, 0, 1},
2911 {L
"IsObject", Global_IsObject
, 0, 1},
2912 {L
"Join", Global_Join
, 0, 1, 2},
2913 {L
"LBound", Global_LBound
, 0, 1, 2},
2914 {L
"LCase", Global_LCase
, 0, 1},
2915 {L
"Left", Global_Left
, 0, 2},
2916 {L
"LeftB", Global_LeftB
, 0, 2},
2917 {L
"Len", Global_Len
, 0, 1},
2918 {L
"LenB", Global_LenB
, 0, 1},
2919 {L
"LoadPicture", Global_LoadPicture
, 0, 1},
2920 {L
"Log", Global_Log
, 0, 1},
2921 {L
"LTrim", Global_LTrim
, 0, 1},
2922 {L
"Mid", Global_Mid
, 0, 2, 3},
2923 {L
"MidB", Global_MidB
, 0, 2, 3},
2924 {L
"Minute", Global_Minute
, 0, 1},
2925 {L
"Month", Global_Month
, 0, 1},
2926 {L
"MonthName", Global_MonthName
, 0, 1, 2},
2927 {L
"MsgBox", Global_MsgBox
, 0, 1, 5},
2928 {L
"Now", Global_Now
, 0, 0},
2929 {L
"Oct", Global_Oct
, 0, 1},
2930 {L
"Randomize", Global_Randomize
, 0, 1},
2931 {L
"Replace", Global_Replace
, 0, 3, 6},
2932 {L
"RGB", Global_RGB
, 0, 3},
2933 {L
"Right", Global_Right
, 0, 2},
2934 {L
"RightB", Global_RightB
, 0, 2},
2935 {L
"Rnd", Global_Rnd
, 0, 1},
2936 {L
"Round", Global_Round
, 0, 1, 2},
2937 {L
"RTrim", Global_RTrim
, 0, 1},
2938 {L
"ScriptEngine", Global_ScriptEngine
, 0, 0},
2939 {L
"ScriptEngineBuildVersion", Global_ScriptEngineBuildVersion
, 0, 0},
2940 {L
"ScriptEngineMajorVersion", Global_ScriptEngineMajorVersion
, 0, 0},
2941 {L
"ScriptEngineMinorVersion", Global_ScriptEngineMinorVersion
, 0, 0},
2942 {L
"Second", Global_Second
, 0, 1},
2943 {L
"Sgn", Global_Sgn
, 0, 1},
2944 {L
"Sin", Global_Sin
, 0, 1},
2945 {L
"Space", Global_Space
, 0, 1},
2946 {L
"Split", Global_Split
, 0, 1, 4},
2947 {L
"Sqr", Global_Sqr
, 0, 1},
2948 {L
"StrComp", Global_StrComp
, 0, 2, 3},
2949 {L
"String", Global_String
, 0, 0, 2},
2950 {L
"StrReverse", Global_StrReverse
, 0, 1},
2951 {L
"Tan", Global_Tan
, 0, 1},
2952 {L
"Time", Global_Time
, 0, 0},
2953 {L
"Timer", Global_Timer
, 0, 0},
2954 {L
"TimeSerial", Global_TimeSerial
, 0, 3},
2955 {L
"TimeValue", Global_TimeValue
, 0, 1},
2956 {L
"Trim", Global_Trim
, 0, 1},
2957 {L
"TypeName", Global_TypeName
, 0, 1},
2958 {L
"UBound", Global_UBound
, 0, 1, 2},
2959 {L
"UCase", Global_UCase
, 0, 1},
2960 {L
"Unescape", Global_Unescape
, 0, 1},
2961 {L
"VarType", Global_VarType
, 0, 1},
2962 {L
"vbAbort", NULL
, BP_GET
, VT_I2
, IDABORT
},
2963 {L
"vbAbortRetryIgnore", NULL
, BP_GET
, VT_I2
, MB_ABORTRETRYIGNORE
},
2964 {L
"vbApplicationModal", NULL
, BP_GET
, VT_I2
, MB_APPLMODAL
},
2965 {L
"vbArray", NULL
, BP_GET
, VT_I2
, VT_ARRAY
},
2966 {L
"vbBinaryCompare", NULL
, BP_GET
, VT_I2
, 0},
2967 {L
"vbBlack", NULL
, BP_GET
, VT_I4
, 0x000000},
2968 {L
"vbBlue", NULL
, BP_GET
, VT_I4
, 0xff0000},
2969 {L
"vbBoolean", NULL
, BP_GET
, VT_I2
, VT_BOOL
},
2970 {L
"vbByte", NULL
, BP_GET
, VT_I2
, VT_UI1
},
2971 {L
"vbCancel", NULL
, BP_GET
, VT_I2
, IDCANCEL
},
2972 {L
"vbCr", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbCr
},
2973 {L
"vbCritical", NULL
, BP_GET
, VT_I2
, MB_ICONHAND
},
2974 {L
"vbCrLf", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbCrLf
},
2975 {L
"vbCurrency", NULL
, BP_GET
, VT_I2
, VT_CY
},
2976 {L
"vbCyan", NULL
, BP_GET
, VT_I4
, 0xffff00},
2977 {L
"vbDatabaseCompare", NULL
, BP_GET
, VT_I2
, 2},
2978 {L
"vbDataObject", NULL
, BP_GET
, VT_I2
, VT_UNKNOWN
},
2979 {L
"vbDate", NULL
, BP_GET
, VT_I2
, VT_DATE
},
2980 {L
"vbDecimal", NULL
, BP_GET
, VT_I2
, VT_DECIMAL
},
2981 {L
"vbDefaultButton1", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON1
},
2982 {L
"vbDefaultButton2", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON2
},
2983 {L
"vbDefaultButton3", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON3
},
2984 {L
"vbDefaultButton4", NULL
, BP_GET
, VT_I2
, MB_DEFBUTTON4
},
2985 {L
"vbDouble", NULL
, BP_GET
, VT_I2
, VT_R8
},
2986 {L
"vbEmpty", NULL
, BP_GET
, VT_I2
, VT_EMPTY
},
2987 {L
"vbError", NULL
, BP_GET
, VT_I2
, VT_ERROR
},
2988 {L
"vbExclamation", NULL
, BP_GET
, VT_I2
, MB_ICONEXCLAMATION
},
2989 {L
"vbFalse", NULL
, BP_GET
, VT_I2
, VARIANT_FALSE
},
2990 {L
"vbFirstFourDays", NULL
, BP_GET
, VT_I2
, 2},
2991 {L
"vbFirstFullWeek", NULL
, BP_GET
, VT_I2
, 3},
2992 {L
"vbFirstJan1", NULL
, BP_GET
, VT_I2
, 1},
2993 {L
"vbFormFeed", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbFormFeed
},
2994 {L
"vbFriday", NULL
, BP_GET
, VT_I2
, 6},
2995 {L
"vbGeneralDate", NULL
, BP_GET
, VT_I2
, 0},
2996 {L
"vbGreen", NULL
, BP_GET
, VT_I4
, 0x00ff00},
2997 {L
"vbIgnore", NULL
, BP_GET
, VT_I2
, IDIGNORE
},
2998 {L
"vbInformation", NULL
, BP_GET
, VT_I2
, MB_ICONASTERISK
},
2999 {L
"vbInteger", NULL
, BP_GET
, VT_I2
, VT_I2
},
3000 {L
"vbLf", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbLf
},
3001 {L
"vbLong", NULL
, BP_GET
, VT_I2
, VT_I4
},
3002 {L
"vbLongDate", NULL
, BP_GET
, VT_I2
, 1},
3003 {L
"vbLongTime", NULL
, BP_GET
, VT_I2
, 3},
3004 {L
"vbMagenta", NULL
, BP_GET
, VT_I4
, 0xff00ff},
3005 {L
"vbMonday", NULL
, BP_GET
, VT_I2
, 2},
3006 {L
"vbMsgBoxHelpButton", NULL
, BP_GET
, VT_I4
, MB_HELP
},
3007 {L
"vbMsgBoxRight", NULL
, BP_GET
, VT_I4
, MB_RIGHT
},
3008 {L
"vbMsgBoxRtlReading", NULL
, BP_GET
, VT_I4
, MB_RTLREADING
},
3009 {L
"vbMsgBoxSetForeground", NULL
, BP_GET
, VT_I4
, MB_SETFOREGROUND
},
3010 {L
"vbNewLine", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNewLine
},
3011 {L
"vbNo", NULL
, BP_GET
, VT_I2
, IDNO
},
3012 {L
"vbNull", NULL
, BP_GET
, VT_I2
, VT_NULL
},
3013 {L
"vbNullChar", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNullChar
},
3014 {L
"vbNullString", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbNullString
},
3015 {L
"vbObject", NULL
, BP_GET
, VT_I2
, VT_DISPATCH
},
3016 {L
"vbObjectError", NULL
, BP_GET
, VT_I4
, 0x80040000},
3017 {L
"vbOK", NULL
, BP_GET
, VT_I2
, IDOK
},
3018 {L
"vbOKCancel", NULL
, BP_GET
, VT_I2
, MB_OKCANCEL
},
3019 {L
"vbOKOnly", NULL
, BP_GET
, VT_I2
, MB_OK
},
3020 {L
"vbQuestion", NULL
, BP_GET
, VT_I2
, MB_ICONQUESTION
},
3021 {L
"vbRed", NULL
, BP_GET
, VT_I4
, 0x0000ff},
3022 {L
"vbRetry", NULL
, BP_GET
, VT_I2
, IDRETRY
},
3023 {L
"vbRetryCancel", NULL
, BP_GET
, VT_I2
, MB_RETRYCANCEL
},
3024 {L
"vbSaturday", NULL
, BP_GET
, VT_I2
, 7},
3025 {L
"vbShortDate", NULL
, BP_GET
, VT_I2
, 2},
3026 {L
"vbShortTime", NULL
, BP_GET
, VT_I2
, 4},
3027 {L
"vbSingle", NULL
, BP_GET
, VT_I2
, VT_R4
},
3028 {L
"vbString", NULL
, BP_GET
, VT_I2
, VT_BSTR
},
3029 {L
"vbSunday", NULL
, BP_GET
, VT_I2
, 1},
3030 {L
"vbSystemModal", NULL
, BP_GET
, VT_I2
, MB_SYSTEMMODAL
},
3031 {L
"vbTab", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbTab
},
3032 {L
"vbTextCompare", NULL
, BP_GET
, VT_I2
, 1},
3033 {L
"vbThursday", NULL
, BP_GET
, VT_I2
, 5},
3034 {L
"vbTrue", NULL
, BP_GET
, VT_I2
, VARIANT_TRUE
},
3035 {L
"vbTuesday", NULL
, BP_GET
, VT_I2
, 3},
3036 {L
"vbUseDefault", NULL
, BP_GET
, VT_I2
, -2},
3037 {L
"vbUseSystem", NULL
, BP_GET
, VT_I2
, 0},
3038 {L
"vbUseSystemDayOfWeek", NULL
, BP_GET
, VT_I2
, 0},
3039 {L
"vbVariant", NULL
, BP_GET
, VT_I2
, VT_VARIANT
},
3040 {L
"vbVerticalTab", NULL
, BP_GET
, VT_BSTR
, (UINT_PTR
)&vbVerticalTab
},
3041 {L
"vbWednesday", NULL
, BP_GET
, VT_I2
, 4},
3042 {L
"vbWhite", NULL
, BP_GET
, VT_I4
, 0xffffff},
3043 {L
"vbYellow", NULL
, BP_GET
, VT_I4
, 0x00ffff},
3044 {L
"vbYes", NULL
, BP_GET
, VT_I2
, IDYES
},
3045 {L
"vbYesNo", NULL
, BP_GET
, VT_I2
, MB_YESNO
},
3046 {L
"vbYesNoCancel", NULL
, BP_GET
, VT_I2
, MB_YESNOCANCEL
},
3047 {L
"Weekday", Global_Weekday
, 0, 1, 2},
3048 {L
"WeekdayName", Global_WeekdayName
, 0, 1, 3},
3049 {L
"Year", Global_Year
, 0, 1}
3052 static HRESULT
err_string_prop(BSTR
*prop
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3058 return return_string(res
, *prop
? *prop
: L
"");
3060 hres
= to_string(args
, &str
);
3064 SysFreeString(*prop
);
3069 static HRESULT
Err_Description(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3072 return err_string_prop(&This
->ctx
->ei
.bstrDescription
, args
, args_cnt
, res
);
3075 static HRESULT
Err_HelpContext(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3080 FIXME("setter not implemented\n");
3084 return return_int(res
, This
->ctx
->ei
.dwHelpContext
);
3087 static HRESULT
Err_HelpFile(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3090 return err_string_prop(&This
->ctx
->ei
.bstrHelpFile
, args
, args_cnt
, res
);
3093 static HRESULT
Err_Number(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3100 FIXME("setter not implemented\n");
3104 hres
= This
->ctx
->ei
.scode
;
3105 return return_int(res
, HRESULT_FACILITY(hres
) == FACILITY_VBS
? HRESULT_CODE(hres
) : hres
);
3108 static HRESULT
Err_Source(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3111 return err_string_prop(&This
->ctx
->ei
.bstrSource
, args
, args_cnt
, res
);
3114 static HRESULT
Err_Clear(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3118 clear_ei(&This
->ctx
->ei
);
3122 static HRESULT
Err_Raise(BuiltinDisp
*This
, VARIANT
*args
, unsigned args_cnt
, VARIANT
*res
)
3124 BSTR source
= NULL
, description
= NULL
, helpfile
= NULL
;
3125 int code
, helpcontext
= 0;
3126 HRESULT hres
, error
;
3128 TRACE("%s %u...\n", debugstr_variant(args
), args_cnt
);
3130 hres
= to_int(args
, &code
);
3133 if(code
== 0 || code
> 0xffff)
3134 return E_INVALIDARG
;
3137 hres
= to_string(args
+ 1, &source
);
3138 if(args_cnt
>= 3 && SUCCEEDED(hres
))
3139 hres
= to_string(args
+ 2, &description
);
3140 if(args_cnt
>= 4 && SUCCEEDED(hres
))
3141 hres
= to_string(args
+ 3, &helpfile
);
3142 if(args_cnt
>= 5 && SUCCEEDED(hres
))
3143 hres
= to_int(args
+ 4, &helpcontext
);
3145 if(SUCCEEDED(hres
)) {
3146 script_ctx_t
*ctx
= This
->ctx
;
3148 error
= (code
& ~0xffff) ? map_hres(code
) : MAKE_VBSERROR(code
);
3151 SysFreeString(ctx
->ei
.bstrSource
);
3152 ctx
->ei
.bstrSource
= source
;
3154 if(!ctx
->ei
.bstrSource
)
3155 ctx
->ei
.bstrSource
= get_vbscript_string(VBS_RUNTIME_ERROR
);
3157 SysFreeString(ctx
->ei
.bstrDescription
);
3158 ctx
->ei
.bstrDescription
= description
;
3160 if(!ctx
->ei
.bstrDescription
)
3161 ctx
->ei
.bstrDescription
= get_vbscript_error_string(error
);
3163 SysFreeString(ctx
->ei
.bstrHelpFile
);
3164 ctx
->ei
.bstrHelpFile
= helpfile
;
3167 ctx
->ei
.dwHelpContext
= helpcontext
;
3169 ctx
->ei
.scode
= error
;
3170 hres
= SCRIPT_E_RECORDED
;
3172 SysFreeString(source
);
3173 SysFreeString(description
);
3174 SysFreeString(helpfile
);
3180 static const builtin_prop_t err_props
[] = {
3181 {NULL
, Err_Number
, BP_GETPUT
},
3182 {L
"Clear", Err_Clear
},
3183 {L
"Description", Err_Description
, BP_GETPUT
},
3184 {L
"HelpContext", Err_HelpContext
, BP_GETPUT
},
3185 {L
"HelpFile", Err_HelpFile
, BP_GETPUT
},
3186 {L
"Number", Err_Number
, BP_GETPUT
},
3187 {L
"Raise", Err_Raise
, 0, 1, 5},
3188 {L
"Source", Err_Source
, BP_GETPUT
}
3191 void detach_global_objects(script_ctx_t
*ctx
)
3194 ctx
->err_obj
->ctx
= NULL
;
3195 IDispatch_Release(&ctx
->err_obj
->IDispatch_iface
);
3196 ctx
->err_obj
= NULL
;
3199 if(ctx
->global_obj
) {
3200 ctx
->global_obj
->ctx
= NULL
;
3201 IDispatch_Release(&ctx
->global_obj
->IDispatch_iface
);
3202 ctx
->global_obj
= NULL
;
3206 HRESULT
init_global(script_ctx_t
*ctx
)
3210 hres
= create_builtin_dispatch(ctx
, global_props
, ARRAY_SIZE(global_props
), &ctx
->global_obj
);
3214 return create_builtin_dispatch(ctx
, err_props
, ARRAY_SIZE(err_props
), &ctx
->err_obj
);