[VBSCRIPT] Sync with Wine Staging 1.9.23. CORE-12409
[reactos.git] / reactos / dll / win32 / vbscript / global.c
1 /*
2 * Copyright 2011 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "vbscript.h"
20
21 #include <math.h>
22 #include <wingdi.h>
23 #include <mshtmhst.h>
24
25 #define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
26 #define VB_E_MK_PARSE_ERROR 0x800a01b0
27
28 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
29 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
30 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
31
32 static const WCHAR emptyW[] = {0};
33 static const WCHAR vbscriptW[] = {'V','B','S','c','r','i','p','t',0};
34
35 static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
36 {
37 IInternetHostSecurityManager *secmgr;
38 IServiceProvider *sp;
39 HRESULT hres;
40
41 if(!ctx->site)
42 return NULL;
43
44 if(ctx->secmgr)
45 return ctx->secmgr;
46
47 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
48 if(FAILED(hres))
49 return NULL;
50
51 hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
52 (void**)&secmgr);
53 IServiceProvider_Release(sp);
54 if(FAILED(hres))
55 return NULL;
56
57 return ctx->secmgr = secmgr;
58 }
59
60 static HRESULT return_string(VARIANT *res, const WCHAR *str)
61 {
62 BSTR ret;
63
64 if(!res)
65 return S_OK;
66
67 ret = SysAllocString(str);
68 if(!ret)
69 return E_OUTOFMEMORY;
70
71 V_VT(res) = VT_BSTR;
72 V_BSTR(res) = ret;
73 return S_OK;
74 }
75
76 static HRESULT return_bstr(VARIANT *res, BSTR str)
77 {
78 if(res) {
79 V_VT(res) = VT_BSTR;
80 V_BSTR(res) = str;
81 }else {
82 SysFreeString(str);
83 }
84 return S_OK;
85 }
86
87 static HRESULT return_bool(VARIANT *res, BOOL val)
88 {
89 if(res) {
90 V_VT(res) = VT_BOOL;
91 V_BOOL(res) = val ? VARIANT_TRUE : VARIANT_FALSE;
92 }
93 return S_OK;
94 }
95
96 static HRESULT return_short(VARIANT *res, short val)
97 {
98 if(res) {
99 V_VT(res) = VT_I2;
100 V_I2(res) = val;
101 }
102
103 return S_OK;
104 }
105
106 static HRESULT return_int(VARIANT *res, int val)
107 {
108 if(res) {
109 V_VT(res) = VT_I4;
110 V_I4(res) = val;
111 }
112
113 return S_OK;
114 }
115
116 static inline HRESULT return_double(VARIANT *res, double val)
117 {
118 if(res) {
119 V_VT(res) = VT_R8;
120 V_R8(res) = val;
121 }
122
123 return S_OK;
124 }
125
126 static inline HRESULT return_float(VARIANT *res, float val)
127 {
128 if(res) {
129 V_VT(res) = VT_R4;
130 V_R4(res) = val;
131 }
132
133 return S_OK;
134 }
135
136 static inline HRESULT return_null(VARIANT *res)
137 {
138 if(res)
139 V_VT(res) = VT_NULL;
140 return S_OK;
141 }
142
143 static inline HRESULT return_date(VARIANT *res, double date)
144 {
145 if(res) {
146 V_VT(res) = VT_DATE;
147 V_DATE(res) = date;
148 }
149 return S_OK;
150 }
151
152 HRESULT to_int(VARIANT *v, int *ret)
153 {
154 VARIANT r;
155 HRESULT hres;
156
157 V_VT(&r) = VT_EMPTY;
158 hres = VariantChangeType(&r, v, 0, VT_I4);
159 if(FAILED(hres))
160 return hres;
161
162 *ret = V_I4(&r);
163 return S_OK;
164 }
165
166 static HRESULT to_double(VARIANT *v, double *ret)
167 {
168 VARIANT dst;
169 HRESULT hres;
170
171 V_VT(&dst) = VT_EMPTY;
172 hres = VariantChangeType(&dst, v, 0, VT_R8);
173 if(FAILED(hres))
174 return hres;
175
176 *ret = V_R8(&dst);
177 return S_OK;
178 }
179
180 static HRESULT to_string(VARIANT *v, BSTR *ret)
181 {
182 VARIANT dst;
183 HRESULT hres;
184
185 V_VT(&dst) = VT_EMPTY;
186 hres = VariantChangeType(&dst, v, VARIANT_LOCALBOOL, VT_BSTR);
187 if(FAILED(hres))
188 return hres;
189
190 *ret = V_BSTR(&dst);
191 return S_OK;
192 }
193
194 static HRESULT set_object_site(script_ctx_t *ctx, IUnknown *obj)
195 {
196 IObjectWithSite *obj_site;
197 IUnknown *ax_site;
198 HRESULT hres;
199
200 hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
201 if(FAILED(hres))
202 return S_OK;
203
204 ax_site = create_ax_site(ctx);
205 if(ax_site) {
206 hres = IObjectWithSite_SetSite(obj_site, ax_site);
207 IUnknown_Release(ax_site);
208 }
209 else
210 hres = E_OUTOFMEMORY;
211 IObjectWithSite_Release(obj_site);
212 return hres;
213 }
214
215 static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
216 {
217 IInternetHostSecurityManager *secmgr = NULL;
218 struct CONFIRMSAFETY cs;
219 IClassFactoryEx *cfex;
220 IClassFactory *cf;
221 DWORD policy_size;
222 BYTE *bpolicy;
223 IUnknown *obj;
224 DWORD policy;
225 GUID guid;
226 HRESULT hres;
227
228 hres = CLSIDFromProgID(progid, &guid);
229 if(FAILED(hres))
230 return NULL;
231
232 TRACE("GUID %s\n", debugstr_guid(&guid));
233
234 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
235 secmgr = get_sec_mgr(ctx);
236 if(!secmgr)
237 return NULL;
238
239 policy = 0;
240 hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN,
241 (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0);
242 if(FAILED(hres) || policy != URLPOLICY_ALLOW)
243 return NULL;
244 }
245
246 hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
247 if(FAILED(hres))
248 return NULL;
249
250 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
251 if(SUCCEEDED(hres)) {
252 FIXME("Use IClassFactoryEx\n");
253 IClassFactoryEx_Release(cfex);
254 }
255
256 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
257 if(FAILED(hres))
258 return NULL;
259
260 if(secmgr) {
261 cs.clsid = guid;
262 cs.pUnk = obj;
263 cs.dwFlags = 0;
264 hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
265 &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
266 if(SUCCEEDED(hres)) {
267 policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW;
268 CoTaskMemFree(bpolicy);
269 }
270
271 if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
272 IUnknown_Release(obj);
273 return NULL;
274 }
275 }
276
277 hres = set_object_site(ctx, obj);
278 if(FAILED(hres)) {
279 IUnknown_Release(obj);
280 return NULL;
281 }
282
283 return obj;
284 }
285
286 static HRESULT show_msgbox(script_ctx_t *ctx, BSTR prompt, unsigned type, BSTR orig_title, VARIANT *res)
287 {
288 SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_ALLOW;
289 IActiveScriptSiteUIControl *ui_control;
290 IActiveScriptSiteWindow *acts_window;
291 WCHAR *title_buf = NULL;
292 const WCHAR *title;
293 HWND hwnd = NULL;
294 int ret = 0;
295 HRESULT hres;
296
297 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteUIControl, (void**)&ui_control);
298 if(SUCCEEDED(hres)) {
299 hres = IActiveScriptSiteUIControl_GetUIBehavior(ui_control, SCRIPTUICITEM_MSGBOX, &uic_handling);
300 IActiveScriptSiteUIControl_Release(ui_control);
301 if(FAILED(hres))
302 uic_handling = SCRIPTUICHANDLING_ALLOW;
303 }
304
305 switch(uic_handling) {
306 case SCRIPTUICHANDLING_ALLOW:
307 break;
308 case SCRIPTUICHANDLING_NOUIDEFAULT:
309 return return_short(res, 0);
310 default:
311 FIXME("blocked\n");
312 return E_FAIL;
313 }
314
315 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteWindow, (void**)&acts_window);
316 if(FAILED(hres)) {
317 FIXME("No IActiveScriptSiteWindow\n");
318 return hres;
319 }
320
321 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
322 if(orig_title && *orig_title) {
323 WCHAR *ptr;
324
325 title = title_buf = heap_alloc(sizeof(vbscriptW) + (strlenW(orig_title)+2)*sizeof(WCHAR));
326 if(!title)
327 return E_OUTOFMEMORY;
328
329 memcpy(title_buf, vbscriptW, sizeof(vbscriptW));
330 ptr = title_buf + sizeof(vbscriptW)/sizeof(WCHAR)-1;
331
332 *ptr++ = ':';
333 *ptr++ = ' ';
334 strcpyW(ptr, orig_title);
335 }else {
336 title = vbscriptW;
337 }
338 }else {
339 title = orig_title ? orig_title : emptyW;
340 }
341
342 hres = IActiveScriptSiteWindow_GetWindow(acts_window, &hwnd);
343 if(SUCCEEDED(hres)) {
344 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, FALSE);
345 if(SUCCEEDED(hres)) {
346 ret = MessageBoxW(hwnd, prompt, title, type);
347 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, TRUE);
348 }
349 }
350
351 heap_free(title_buf);
352 IActiveScriptSiteWindow_Release(acts_window);
353 if(FAILED(hres)) {
354 FIXME("failed: %08x\n", hres);
355 return hres;
356 }
357
358 return return_short(res, ret);
359 }
360
361 static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
362 {
363 VARIANT v;
364 HRESULT hres;
365
366 TRACE("%s\n", debugstr_variant(arg));
367
368 assert(args_cnt == 1);
369
370 V_VT(&v) = VT_EMPTY;
371 hres = VariantChangeType(&v, arg, 0, VT_CY);
372 if(FAILED(hres))
373 return hres;
374
375 if(!res) {
376 VariantClear(&v);
377 return DISP_E_BADVARTYPE;
378 }
379
380 *res = v;
381 return S_OK;
382 }
383
384 static HRESULT Global_CInt(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
385 {
386 VARIANT v;
387 HRESULT hres;
388
389 TRACE("%s\n", debugstr_variant(arg));
390
391 assert(args_cnt == 1);
392
393 V_VT(&v) = VT_EMPTY;
394 hres = VariantChangeType(&v, arg, 0, VT_I2);
395 if(FAILED(hres))
396 return hres;
397
398 if(!res)
399 return DISP_E_BADVARTYPE;
400 else {
401 *res = v;
402 return S_OK;
403 }
404 }
405
406 static HRESULT Global_CLng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
407 {
408 int i;
409 HRESULT hres;
410
411 TRACE("%s\n", debugstr_variant(arg));
412
413 assert(args_cnt == 1);
414
415 hres = to_int(arg, &i);
416 if(FAILED(hres))
417 return hres;
418 if(!res)
419 return DISP_E_BADVARTYPE;
420
421 return return_int(res, i);
422 }
423
424 static HRESULT Global_CBool(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
425 {
426 VARIANT v;
427 HRESULT hres;
428
429 TRACE("%s\n", debugstr_variant(arg));
430
431 assert(args_cnt == 1);
432
433 V_VT(&v) = VT_EMPTY;
434 hres = VariantChangeType(&v, arg, VARIANT_LOCALBOOL, VT_BOOL);
435 if(FAILED(hres))
436 return hres;
437
438 if(res)
439 *res = v;
440 else
441 VariantClear(&v);
442 return S_OK;
443 }
444
445 static HRESULT Global_CByte(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
446 {
447 VARIANT v;
448 HRESULT hres;
449
450 TRACE("%s\n", debugstr_variant(arg));
451
452 assert(args_cnt == 1);
453
454 V_VT(&v) = VT_EMPTY;
455 hres = VariantChangeType(&v, arg, VARIANT_LOCALBOOL, VT_UI1);
456 if(FAILED(hres))
457 return hres;
458
459 if(!res) {
460 VariantClear(&v);
461 return DISP_E_BADVARTYPE;
462 }
463
464 *res = v;
465 return S_OK;
466 }
467
468 static HRESULT Global_CDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
469 {
470 FIXME("\n");
471 return E_NOTIMPL;
472 }
473
474 static HRESULT Global_CDbl(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
475 {
476 VARIANT v;
477 HRESULT hres;
478
479 TRACE("%s\n", debugstr_variant(arg));
480
481 assert(args_cnt == 1);
482
483 V_VT(&v) = VT_EMPTY;
484 hres = VariantChangeType(&v, arg, 0, VT_R8);
485 if(FAILED(hres))
486 return hres;
487
488 if(!res)
489 return DISP_E_BADVARTYPE;
490 else {
491 *res = v;
492 return S_OK;
493 }
494 }
495
496 static HRESULT Global_CSng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
497 {
498 VARIANT v;
499 HRESULT hres;
500
501 TRACE("%s\n", debugstr_variant(arg));
502
503 assert(args_cnt == 1);
504
505 V_VT(&v) = VT_EMPTY;
506 hres = VariantChangeType(&v, arg, 0, VT_R4);
507 if(FAILED(hres))
508 return hres;
509
510 if(!res)
511 return DISP_E_BADVARTYPE;
512
513 *res = v;
514 return S_OK;
515 }
516
517 static HRESULT Global_CStr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
518 {
519 BSTR str;
520 HRESULT hres;
521
522 TRACE("%s\n", debugstr_variant(arg));
523
524 hres = to_string(arg, &str);
525 if(FAILED(hres))
526 return hres;
527
528 return return_bstr(res, str);
529 }
530
531 static inline WCHAR hex_char(unsigned n)
532 {
533 return n < 10 ? '0'+n : 'A'+n-10;
534 }
535
536 static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
537 {
538 WCHAR buf[17], *ptr;
539 DWORD n;
540 HRESULT hres;
541 int ret;
542
543 TRACE("%s\n", debugstr_variant(arg));
544
545 switch(V_VT(arg)) {
546 case VT_I2:
547 n = (WORD)V_I2(arg);
548 break;
549 case VT_NULL:
550 if(res)
551 V_VT(res) = VT_NULL;
552 return S_OK;
553 default:
554 hres = to_int(arg, &ret);
555 if(FAILED(hres))
556 return hres;
557 else
558 n = ret;
559 }
560
561 buf[16] = 0;
562 ptr = buf+15;
563
564 if(n) {
565 do {
566 *ptr-- = hex_char(n & 0xf);
567 n >>= 4;
568 }while(n);
569 ptr++;
570 }else {
571 *ptr = '0';
572 }
573
574 return return_string(res, ptr);
575 }
576
577 static HRESULT Global_Oct(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
578 {
579 HRESULT hres;
580 WCHAR buf[23], *ptr;
581 DWORD n;
582 int ret;
583
584 TRACE("%s\n", debugstr_variant(arg));
585
586 switch(V_VT(arg)) {
587 case VT_I2:
588 n = (WORD)V_I2(arg);
589 break;
590 case VT_NULL:
591 if(res)
592 V_VT(res) = VT_NULL;
593 return S_OK;
594 default:
595 hres = to_int(arg, &ret);
596 if(FAILED(hres))
597 return hres;
598 else
599 n = ret;
600 }
601
602 buf[22] = 0;
603 ptr = buf + 21;
604
605 if(n) {
606 do {
607 *ptr-- = '0' + (n & 0x7);
608 n >>= 3;
609 }while(n);
610 ptr++;
611 }else {
612 *ptr = '0';
613 }
614
615 return return_string(res, ptr);
616 }
617
618 static HRESULT Global_VarType(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
619 {
620 TRACE("(%s)\n", debugstr_variant(arg));
621
622 assert(args_cnt == 1);
623
624 if(V_VT(arg) & ~VT_TYPEMASK) {
625 FIXME("not supported %s\n", debugstr_variant(arg));
626 return E_NOTIMPL;
627 }
628
629 return return_short(res, V_VT(arg));
630 }
631
632 static HRESULT Global_IsDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
633 {
634 FIXME("\n");
635 return E_NOTIMPL;
636 }
637
638 static HRESULT Global_IsEmpty(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
639 {
640 TRACE("(%s)\n", debugstr_variant(arg));
641
642 assert(args_cnt == 1);
643
644 if(res) {
645 V_VT(res) = VT_BOOL;
646 V_BOOL(res) = V_VT(arg) == VT_EMPTY ? VARIANT_TRUE : VARIANT_FALSE;
647 }
648 return S_OK;
649 }
650
651 static HRESULT Global_IsNull(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
652 {
653 TRACE("(%s)\n", debugstr_variant(arg));
654
655 assert(args_cnt == 1);
656
657 if(res) {
658 V_VT(res) = VT_BOOL;
659 V_BOOL(res) = V_VT(arg) == VT_NULL ? VARIANT_TRUE : VARIANT_FALSE;
660 }
661 return S_OK;
662 }
663
664 static HRESULT Global_IsNumeric(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
665 {
666 HRESULT hres;
667 double d;
668
669 TRACE("(%s)\n", debugstr_variant(arg));
670
671 assert(args_cnt == 1);
672
673 hres = to_double(arg, &d);
674
675 return return_bool(res, SUCCEEDED(hres));
676 }
677
678 static HRESULT Global_IsArray(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
679 {
680 FIXME("\n");
681 return E_NOTIMPL;
682 }
683
684 static HRESULT Global_IsObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
685 {
686 TRACE("(%s)\n", debugstr_variant(arg));
687
688 assert(args_cnt == 1);
689
690 if(res) {
691 V_VT(res) = VT_BOOL;
692 V_BOOL(res) = V_VT(arg) == VT_DISPATCH ? VARIANT_TRUE : VARIANT_FALSE;
693 }
694 return S_OK;
695 }
696
697 static HRESULT Global_Atn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
698 {
699 HRESULT hres;
700 double d;
701
702 hres = to_double(arg, &d);
703 if(FAILED(hres))
704 return hres;
705
706 return return_double(res, atan(d));
707 }
708
709 static HRESULT Global_Cos(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
710 {
711 HRESULT hres;
712 double d;
713
714 hres = to_double(arg, &d);
715 if(FAILED(hres))
716 return hres;
717
718 return return_double(res, cos(d));
719 }
720
721 static HRESULT Global_Sin(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
722 {
723 HRESULT hres;
724 double d;
725
726 hres = to_double(arg, &d);
727 if(FAILED(hres))
728 return hres;
729
730 return return_double(res, sin(d));
731 }
732
733 static HRESULT Global_Tan(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
734 {
735 HRESULT hres;
736 double d;
737
738 hres = to_double(arg, &d);
739 if(FAILED(hres))
740 return hres;
741
742 return return_double(res, tan(d));
743 }
744
745 static HRESULT Global_Exp(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
746 {
747 HRESULT hres;
748 double d;
749
750 hres = to_double(arg, &d);
751 if(FAILED(hres))
752 return hres;
753
754 return return_double(res, exp(d));
755 }
756
757 static HRESULT Global_Log(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
758 {
759 HRESULT hres;
760 double d;
761
762 hres = to_double(arg, &d);
763 if(FAILED(hres))
764 return hres;
765
766 if(d <= 0)
767 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
768 else
769 return return_double(res, log(d));
770 }
771
772 static HRESULT Global_Sqr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
773 {
774 HRESULT hres;
775 double d;
776
777 hres = to_double(arg, &d);
778 if(FAILED(hres))
779 return hres;
780
781 if(d < 0)
782 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
783 else
784 return return_double(res, sqrt(d));
785 }
786
787 static HRESULT Global_Randomize(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
788 {
789 FIXME("\n");
790 return E_NOTIMPL;
791 }
792
793 static HRESULT Global_Rnd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
794 {
795 FIXME("\n");
796 return E_NOTIMPL;
797 }
798
799 static HRESULT Global_Timer(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
800 {
801 SYSTEMTIME lt;
802 double sec;
803
804 GetLocalTime(&lt);
805 sec = lt.wHour * 3600 + lt.wMinute * 60 + lt.wSecond + lt.wMilliseconds / 1000.0;
806 return return_float(res, sec);
807
808 }
809
810 static HRESULT Global_LBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
811 {
812 FIXME("\n");
813 return E_NOTIMPL;
814 }
815
816 static HRESULT Global_UBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
817 {
818 FIXME("\n");
819 return E_NOTIMPL;
820 }
821
822 static HRESULT Global_RGB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
823 {
824 HRESULT hres;
825 int i, color[3];
826
827 TRACE("%s %s %s\n", debugstr_variant(arg), debugstr_variant(arg + 1), debugstr_variant(arg + 2));
828
829 assert(args_cnt == 3);
830
831 for(i = 0; i < 3; i++) {
832 hres = to_int(arg + i, color + i);
833 if(FAILED(hres))
834 return hres;
835 if(color[i] > 255)
836 color[i] = 255;
837 if(color[i] < 0)
838 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
839 }
840
841 return return_int(res, RGB(color[0], color[1], color[2]));
842 }
843
844 static HRESULT Global_Len(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
845 {
846 DWORD len;
847 HRESULT hres;
848
849 TRACE("%s\n", debugstr_variant(arg));
850
851 if(V_VT(arg) == VT_NULL)
852 return return_null(res);
853
854 if(V_VT(arg) != VT_BSTR) {
855 BSTR str;
856
857 hres = to_string(arg, &str);
858 if(FAILED(hres))
859 return hres;
860
861 len = SysStringLen(str);
862 SysFreeString(str);
863 }else {
864 len = SysStringLen(V_BSTR(arg));
865 }
866
867 return return_int(res, len);
868 }
869
870 static HRESULT Global_LenB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
871 {
872 FIXME("\n");
873 return E_NOTIMPL;
874 }
875
876 static HRESULT Global_Left(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
877 {
878 BSTR str, ret, conv_str = NULL;
879 int len, str_len;
880 HRESULT hres;
881
882 TRACE("(%s %s)\n", debugstr_variant(args+1), debugstr_variant(args));
883
884 if(V_VT(args) == VT_BSTR) {
885 str = V_BSTR(args);
886 }else {
887 hres = to_string(args, &conv_str);
888 if(FAILED(hres))
889 return hres;
890 str = conv_str;
891 }
892
893 hres = to_int(args+1, &len);
894 if(FAILED(hres))
895 return hres;
896
897 if(len < 0) {
898 FIXME("len = %d\n", len);
899 return E_FAIL;
900 }
901
902 str_len = SysStringLen(str);
903 if(len > str_len)
904 len = str_len;
905
906 ret = SysAllocStringLen(str, len);
907 SysFreeString(conv_str);
908 if(!ret)
909 return E_OUTOFMEMORY;
910
911 return return_bstr(res, ret);
912 }
913
914 static HRESULT Global_LeftB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
915 {
916 FIXME("\n");
917 return E_NOTIMPL;
918 }
919
920 static HRESULT Global_Right(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
921 {
922 BSTR str, ret, conv_str = NULL;
923 int len, str_len;
924 HRESULT hres;
925
926 TRACE("(%s %s)\n", debugstr_variant(args), debugstr_variant(args+1));
927
928 if(V_VT(args+1) == VT_BSTR) {
929 str = V_BSTR(args);
930 }else {
931 hres = to_string(args, &conv_str);
932 if(FAILED(hres))
933 return hres;
934 str = conv_str;
935 }
936
937 hres = to_int(args+1, &len);
938 if(FAILED(hres))
939 return hres;
940
941 if(len < 0) {
942 FIXME("len = %d\n", len);
943 return E_FAIL;
944 }
945
946 str_len = SysStringLen(str);
947 if(len > str_len)
948 len = str_len;
949
950 ret = SysAllocStringLen(str+str_len-len, len);
951 SysFreeString(conv_str);
952 if(!ret)
953 return E_OUTOFMEMORY;
954
955 return return_bstr(res, ret);
956 }
957
958 static HRESULT Global_RightB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
959 {
960 FIXME("\n");
961 return E_NOTIMPL;
962 }
963
964 static HRESULT Global_Mid(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
965 {
966 int len = -1, start, str_len;
967 BSTR str;
968 HRESULT hres;
969
970 TRACE("(%s %s ...)\n", debugstr_variant(args), debugstr_variant(args+1));
971
972 assert(args_cnt == 2 || args_cnt == 3);
973
974 if(V_VT(args) != VT_BSTR) {
975 FIXME("args[0] = %s\n", debugstr_variant(args));
976 return E_NOTIMPL;
977 }
978
979 str = V_BSTR(args);
980
981 hres = to_int(args+1, &start);
982 if(FAILED(hres))
983 return hres;
984
985 if(args_cnt == 3) {
986 hres = to_int(args+2, &len);
987 if(FAILED(hres))
988 return hres;
989
990 if(len < 0) {
991 FIXME("len = %d\n", len);
992 return E_FAIL;
993 }
994 }
995
996
997 str_len = SysStringLen(str);
998 start--;
999 if(start > str_len)
1000 start = str_len;
1001
1002 if(len == -1)
1003 len = str_len-start;
1004 else if(len > str_len-start)
1005 len = str_len-start;
1006
1007 if(res) {
1008 V_VT(res) = VT_BSTR;
1009 V_BSTR(res) = SysAllocStringLen(str+start, len);
1010 if(!V_BSTR(res))
1011 return E_OUTOFMEMORY;
1012 }
1013
1014 return S_OK;
1015 }
1016
1017 static HRESULT Global_MidB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1018 {
1019 FIXME("\n");
1020 return E_NOTIMPL;
1021 }
1022
1023 static HRESULT Global_StrComp(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1024 {
1025 BSTR left, right;
1026 int mode, ret;
1027 HRESULT hres;
1028 short val;
1029
1030 TRACE("(%s %s ...)\n", debugstr_variant(args), debugstr_variant(args+1));
1031
1032 assert(args_cnt == 2 || args_cnt == 3);
1033
1034 if (args_cnt == 3) {
1035 hres = to_int(args+2, &mode);
1036 if(FAILED(hres))
1037 return hres;
1038
1039 if (mode != 0 && mode != 1) {
1040 FIXME("unknown compare mode = %d\n", mode);
1041 return E_FAIL;
1042 }
1043 }
1044 else
1045 mode = 0;
1046
1047 hres = to_string(args, &left);
1048 if(FAILED(hres))
1049 return hres;
1050
1051 hres = to_string(args+1, &right);
1052 if(FAILED(hres))
1053 {
1054 SysFreeString(left);
1055 return hres;
1056 }
1057
1058 ret = mode ? strcmpiW(left, right) : strcmpW(left, right);
1059 val = ret < 0 ? -1 : (ret > 0 ? 1 : 0);
1060
1061 SysFreeString(left);
1062 SysFreeString(right);
1063 return return_short(res, val);
1064 }
1065
1066 static HRESULT Global_LCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1067 {
1068 BSTR str;
1069 HRESULT hres;
1070
1071 TRACE("%s\n", debugstr_variant(arg));
1072
1073 if(V_VT(arg) == VT_NULL) {
1074 if(res)
1075 V_VT(res) = VT_NULL;
1076 return S_OK;
1077 }
1078
1079 hres = to_string(arg, &str);
1080 if(FAILED(hres))
1081 return hres;
1082
1083 if(res) {
1084 WCHAR *ptr;
1085
1086 for(ptr = str; *ptr; ptr++)
1087 *ptr = tolowerW(*ptr);
1088
1089 V_VT(res) = VT_BSTR;
1090 V_BSTR(res) = str;
1091 }else {
1092 SysFreeString(str);
1093 }
1094 return S_OK;
1095 }
1096
1097 static HRESULT Global_UCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1098 {
1099 BSTR str;
1100 HRESULT hres;
1101
1102 TRACE("%s\n", debugstr_variant(arg));
1103
1104 if(V_VT(arg) == VT_NULL) {
1105 if(res)
1106 V_VT(res) = VT_NULL;
1107 return S_OK;
1108 }
1109
1110 hres = to_string(arg, &str);
1111 if(FAILED(hres))
1112 return hres;
1113
1114 if(res) {
1115 WCHAR *ptr;
1116
1117 for(ptr = str; *ptr; ptr++)
1118 *ptr = toupperW(*ptr);
1119
1120 V_VT(res) = VT_BSTR;
1121 V_BSTR(res) = str;
1122 }else {
1123 SysFreeString(str);
1124 }
1125 return S_OK;
1126 }
1127
1128 static HRESULT Global_LTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1129 {
1130 BSTR str, conv_str = NULL;
1131 WCHAR *ptr;
1132 HRESULT hres;
1133
1134 TRACE("%s\n", debugstr_variant(arg));
1135
1136 if(V_VT(arg) == VT_BSTR) {
1137 str = V_BSTR(arg);
1138 }else {
1139 hres = to_string(arg, &conv_str);
1140 if(FAILED(hres))
1141 return hres;
1142 str = conv_str;
1143 }
1144
1145 for(ptr = str; *ptr && isspaceW(*ptr); ptr++);
1146
1147 str = SysAllocString(ptr);
1148 SysFreeString(conv_str);
1149 if(!str)
1150 return E_OUTOFMEMORY;
1151
1152 return return_bstr(res, str);
1153 }
1154
1155 static HRESULT Global_RTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1156 {
1157 BSTR str, conv_str = NULL;
1158 WCHAR *ptr;
1159 HRESULT hres;
1160
1161 TRACE("%s\n", debugstr_variant(arg));
1162
1163 if(V_VT(arg) == VT_BSTR) {
1164 str = V_BSTR(arg);
1165 }else {
1166 hres = to_string(arg, &conv_str);
1167 if(FAILED(hres))
1168 return hres;
1169 str = conv_str;
1170 }
1171
1172 for(ptr = str+SysStringLen(str); ptr-1 > str && isspaceW(*(ptr-1)); ptr--);
1173
1174 str = SysAllocStringLen(str, ptr-str);
1175 SysFreeString(conv_str);
1176 if(!str)
1177 return E_OUTOFMEMORY;
1178
1179 return return_bstr(res, str);
1180 }
1181
1182 static HRESULT Global_Trim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1183 {
1184 BSTR str, conv_str = NULL;
1185 WCHAR *begin_ptr, *end_ptr;
1186 HRESULT hres;
1187
1188 TRACE("%s\n", debugstr_variant(arg));
1189
1190 if(V_VT(arg) == VT_BSTR) {
1191 str = V_BSTR(arg);
1192 }else {
1193 hres = to_string(arg, &conv_str);
1194 if(FAILED(hres))
1195 return hres;
1196 str = conv_str;
1197 }
1198
1199 for(begin_ptr = str; *begin_ptr && isspaceW(*begin_ptr); begin_ptr++);
1200 for(end_ptr = str+SysStringLen(str); end_ptr-1 > begin_ptr && isspaceW(*(end_ptr-1)); end_ptr--);
1201
1202 str = SysAllocStringLen(begin_ptr, end_ptr-begin_ptr);
1203 SysFreeString(conv_str);
1204 if(!str)
1205 return E_OUTOFMEMORY;
1206
1207 return return_bstr(res, str);
1208 }
1209
1210 static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1211 {
1212 BSTR str;
1213 int n, i;
1214 HRESULT hres;
1215
1216 TRACE("%s\n", debugstr_variant(arg));
1217
1218 hres = to_int(arg, &n);
1219 if(FAILED(hres))
1220 return hres;
1221
1222 if(n < 0) {
1223 FIXME("n = %d\n", n);
1224 return E_NOTIMPL;
1225 }
1226
1227 if(!res)
1228 return S_OK;
1229
1230 str = SysAllocStringLen(NULL, n);
1231 if(!str)
1232 return E_OUTOFMEMORY;
1233
1234 for(i=0; i<n; i++)
1235 str[i] = ' ';
1236
1237 V_VT(res) = VT_BSTR;
1238 V_BSTR(res) = str;
1239 return S_OK;
1240 }
1241
1242 static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1243 {
1244 FIXME("\n");
1245 return E_NOTIMPL;
1246 }
1247
1248 static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1249 {
1250 VARIANT *startv, *str1v, *str2v;
1251 BSTR str1, str2;
1252 int start, ret;
1253 HRESULT hres;
1254
1255 TRACE("\n");
1256
1257 assert(2 <= args_cnt && args_cnt <= 4);
1258
1259 switch(args_cnt) {
1260 case 2:
1261 startv = NULL;
1262 str1v = args;
1263 str2v = args+1;
1264 break;
1265 case 3:
1266 startv = args;
1267 str1v = args+1;
1268 str2v = args+2;
1269 break;
1270 case 4:
1271 FIXME("unsupported compare argument %s\n", debugstr_variant(args));
1272 return E_NOTIMPL;
1273 DEFAULT_UNREACHABLE;
1274 }
1275
1276 if(startv) {
1277 hres = to_int(startv, &start);
1278 if(FAILED(hres))
1279 return hres;
1280 if(--start < 0) {
1281 FIXME("start %d\n", start);
1282 return E_FAIL;
1283 }
1284 }else {
1285 start = 0;
1286 }
1287
1288 if(V_VT(str1v) == VT_NULL || V_VT(str2v) == VT_NULL)
1289 return return_null(res);
1290
1291 if(V_VT(str1v) != VT_BSTR) {
1292 FIXME("Unsupported str1 type %s\n", debugstr_variant(str1v));
1293 return E_NOTIMPL;
1294 }
1295 str1 = V_BSTR(str1v);
1296
1297 if(V_VT(str2v) != VT_BSTR) {
1298 FIXME("Unsupported str2 type %s\n", debugstr_variant(str2v));
1299 return E_NOTIMPL;
1300 }
1301 str2 = V_BSTR(str2v);
1302
1303 if(start < SysStringLen(str1)) {
1304 WCHAR *ptr;
1305
1306 ptr = strstrW(str1+start, str2);
1307 ret = ptr ? ptr-str1+1 : 0;
1308 }else {
1309 ret = 0;
1310 }
1311
1312 return return_int(res, ret);
1313 }
1314
1315 static HRESULT Global_InStrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1316 {
1317 FIXME("\n");
1318 return E_NOTIMPL;
1319 }
1320
1321 static HRESULT Global_AscB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1322 {
1323 FIXME("\n");
1324 return E_NOTIMPL;
1325 }
1326
1327 static HRESULT Global_ChrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1328 {
1329 FIXME("\n");
1330 return E_NOTIMPL;
1331 }
1332
1333 static HRESULT Global_Asc(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1334 {
1335 FIXME("\n");
1336 return E_NOTIMPL;
1337 }
1338
1339 /* The function supports only single-byte and double-byte character sets. It
1340 * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
1341 * to be in range of short or unsigned short. */
1342 static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1343 {
1344 int cp, c, len = 0;
1345 CPINFO cpi;
1346 WCHAR ch;
1347 char buf[2];
1348 HRESULT hres;
1349
1350 TRACE("%s\n", debugstr_variant(arg));
1351
1352 hres = to_int(arg, &c);
1353 if(FAILED(hres))
1354 return hres;
1355
1356 cp = GetACP();
1357 if(!GetCPInfo(cp, &cpi))
1358 cpi.MaxCharSize = 1;
1359
1360 if((c!=(short)c && c!=(unsigned short)c) ||
1361 (unsigned short)c>=(cpi.MaxCharSize>1 ? 0x10000 : 0x100)) {
1362 WARN("invalid arg %d\n", c);
1363 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
1364 }
1365
1366 if(c>>8)
1367 buf[len++] = c>>8;
1368 if(!len || IsDBCSLeadByteEx(cp, buf[0]))
1369 buf[len++] = c;
1370 if(!MultiByteToWideChar(CP_ACP, 0, buf, len, &ch, 1)) {
1371 WARN("invalid arg %d, cp %d\n", c, cp);
1372 return E_FAIL;
1373 }
1374
1375 if(res) {
1376 V_VT(res) = VT_BSTR;
1377 V_BSTR(res) = SysAllocStringLen(&ch, 1);
1378 if(!V_BSTR(res))
1379 return E_OUTOFMEMORY;
1380 }
1381 return S_OK;
1382 }
1383
1384 static HRESULT Global_AscW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1385 {
1386 FIXME("\n");
1387 return E_NOTIMPL;
1388 }
1389
1390 static HRESULT Global_ChrW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1391 {
1392 FIXME("\n");
1393 return E_NOTIMPL;
1394 }
1395
1396 static HRESULT Global_Abs(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1397 {
1398 HRESULT hres;
1399 VARIANT dst;
1400
1401 TRACE("(%s)\n", debugstr_variant(arg));
1402
1403 assert(args_cnt == 1);
1404
1405 hres = VarAbs(arg, &dst);
1406 if(FAILED(hres))
1407 return hres;
1408
1409 if (res)
1410 *res = dst;
1411 else
1412 VariantClear(&dst);
1413
1414 return S_OK;
1415 }
1416
1417 static HRESULT Global_Fix(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1418 {
1419 HRESULT hres;
1420 VARIANT dst;
1421
1422 TRACE("(%s)\n", debugstr_variant(arg));
1423
1424 assert(args_cnt == 1);
1425
1426 hres = VarFix(arg, &dst);
1427 if(FAILED(hres))
1428 return hres;
1429
1430 if (res)
1431 *res = dst;
1432 else
1433 VariantClear(&dst);
1434
1435 return S_OK;
1436 }
1437
1438 static HRESULT Global_Int(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1439 {
1440 HRESULT hres;
1441 VARIANT dst;
1442
1443 TRACE("(%s)\n", debugstr_variant(arg));
1444
1445 assert(args_cnt == 1);
1446
1447 hres = VarInt(arg, &dst);
1448 if(FAILED(hres))
1449 return hres;
1450
1451 if (res)
1452 *res = dst;
1453 else
1454 VariantClear(&dst);
1455
1456 return S_OK;
1457 }
1458
1459 static HRESULT Global_Sgn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1460 {
1461 double v;
1462 short val;
1463 HRESULT hres;
1464
1465 TRACE("(%s)\n", debugstr_variant(arg));
1466
1467 assert(args_cnt == 1);
1468
1469 if(V_VT(arg) == VT_NULL)
1470 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
1471
1472 hres = to_double(arg, &v);
1473 if (FAILED(hres))
1474 return hres;
1475
1476 val = v == 0 ? 0 : (v > 0 ? 1 : -1);
1477 return return_short(res, val);
1478 }
1479
1480 static HRESULT Global_Now(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1481 {
1482 SYSTEMTIME lt;
1483 double date;
1484
1485 TRACE("\n");
1486
1487 GetLocalTime(&lt);
1488 SystemTimeToVariantTime(&lt, &date);
1489 return return_date(res, date);
1490 }
1491
1492 static HRESULT Global_Date(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1493 {
1494 SYSTEMTIME lt;
1495 UDATE ud;
1496 DATE date;
1497 HRESULT hres;
1498
1499 TRACE("\n");
1500
1501 GetLocalTime(&lt);
1502 ud.st = lt;
1503 ud.wDayOfYear = 0;
1504 hres = VarDateFromUdateEx(&ud, 0, VAR_DATEVALUEONLY, &date);
1505 if(FAILED(hres))
1506 return hres;
1507 return return_date(res, date);
1508 }
1509
1510 static HRESULT Global_Time(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1511 {
1512 SYSTEMTIME lt;
1513 UDATE ud;
1514 DATE time;
1515 HRESULT hres;
1516
1517 TRACE("\n");
1518
1519 GetLocalTime(&lt);
1520 ud.st = lt;
1521 ud.wDayOfYear = 0;
1522 hres = VarDateFromUdateEx(&ud, 0, VAR_TIMEVALUEONLY, &time);
1523 if(FAILED(hres))
1524 return hres;
1525 return return_date(res, time);
1526 }
1527
1528 static HRESULT Global_Day(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1529 {
1530 FIXME("\n");
1531 return E_NOTIMPL;
1532 }
1533
1534 static HRESULT Global_Month(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1535 {
1536 FIXME("\n");
1537 return E_NOTIMPL;
1538 }
1539
1540 static HRESULT Global_Weekday(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1541 {
1542 FIXME("\n");
1543 return E_NOTIMPL;
1544 }
1545
1546 static HRESULT Global_Year(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1547 {
1548 FIXME("\n");
1549 return E_NOTIMPL;
1550 }
1551
1552 static HRESULT Global_Hour(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1553 {
1554 FIXME("\n");
1555 return E_NOTIMPL;
1556 }
1557
1558 static HRESULT Global_Minute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1559 {
1560 FIXME("\n");
1561 return E_NOTIMPL;
1562 }
1563
1564 static HRESULT Global_Second(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1565 {
1566 FIXME("\n");
1567 return E_NOTIMPL;
1568 }
1569
1570 static HRESULT Global_DateValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1571 {
1572 FIXME("\n");
1573 return E_NOTIMPL;
1574 }
1575
1576 static HRESULT Global_TimeValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1577 {
1578 FIXME("\n");
1579 return E_NOTIMPL;
1580 }
1581
1582 static HRESULT Global_DateSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1583 {
1584 FIXME("\n");
1585 return E_NOTIMPL;
1586 }
1587
1588 static HRESULT Global_TimeSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1589 {
1590 FIXME("\n");
1591 return E_NOTIMPL;
1592 }
1593
1594 static HRESULT Global_InputBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1595 {
1596 FIXME("\n");
1597 return E_NOTIMPL;
1598 }
1599
1600 static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1601 {
1602 BSTR prompt, title = NULL;
1603 int type = MB_OK;
1604 HRESULT hres;
1605
1606 TRACE("\n");
1607
1608 assert(1 <= args_cnt && args_cnt <= 5);
1609
1610 hres = to_string(args, &prompt);
1611 if(FAILED(hres))
1612 return hres;
1613
1614 if(args_cnt > 1)
1615 hres = to_int(args+1, &type);
1616
1617 if(SUCCEEDED(hres) && args_cnt > 2)
1618 hres = to_string(args+2, &title);
1619
1620 if(SUCCEEDED(hres) && args_cnt > 3) {
1621 FIXME("unsupported arg_cnt %d\n", args_cnt);
1622 hres = E_NOTIMPL;
1623 }
1624
1625 if(SUCCEEDED(hres))
1626 hres = show_msgbox(This->desc->ctx, prompt, type, title, res);
1627
1628 SysFreeString(prompt);
1629 SysFreeString(title);
1630 return hres;
1631 }
1632
1633 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1634 {
1635 IUnknown *obj;
1636 HRESULT hres;
1637
1638 TRACE("(%s)\n", debugstr_variant(arg));
1639
1640 if(V_VT(arg) != VT_BSTR) {
1641 FIXME("non-bstr arg\n");
1642 return E_INVALIDARG;
1643 }
1644
1645 obj = create_object(This->desc->ctx, V_BSTR(arg));
1646 if(!obj)
1647 return VB_E_CANNOT_CREATE_OBJ;
1648
1649 if(res) {
1650 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res));
1651 if(FAILED(hres))
1652 return hres;
1653
1654 V_VT(res) = VT_DISPATCH;
1655 }
1656
1657 IUnknown_Release(obj);
1658 return S_OK;
1659 }
1660
1661 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1662 {
1663 IBindCtx *bind_ctx;
1664 IUnknown *obj_unk;
1665 IDispatch *disp;
1666 ULONG eaten = 0;
1667 IMoniker *mon;
1668 HRESULT hres;
1669
1670 TRACE("%s %s\n", args_cnt ? debugstr_variant(args) : "", args_cnt > 1 ? debugstr_variant(args+1) : "");
1671
1672 if(args_cnt != 1 || V_VT(args) != VT_BSTR) {
1673 FIXME("unsupported args\n");
1674 return E_NOTIMPL;
1675 }
1676
1677 if(This->desc->ctx->safeopt & (INTERFACE_USES_SECURITY_MANAGER|INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
1678 WARN("blocked in current safety mode\n");
1679 return VB_E_CANNOT_CREATE_OBJ;
1680 }
1681
1682 hres = CreateBindCtx(0, &bind_ctx);
1683 if(FAILED(hres))
1684 return hres;
1685
1686 hres = MkParseDisplayName(bind_ctx, V_BSTR(args), &eaten, &mon);
1687 if(SUCCEEDED(hres)) {
1688 hres = IMoniker_BindToObject(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&obj_unk);
1689 IMoniker_Release(mon);
1690 }else {
1691 hres = MK_E_SYNTAX;
1692 }
1693 IBindCtx_Release(bind_ctx);
1694 if(FAILED(hres))
1695 return hres;
1696
1697 hres = set_object_site(This->desc->ctx, obj_unk);
1698 if(FAILED(hres)) {
1699 IUnknown_Release(obj_unk);
1700 return hres;
1701 }
1702
1703 hres = IUnknown_QueryInterface(obj_unk, &IID_IDispatch, (void**)&disp);
1704 if(SUCCEEDED(hres)) {
1705 if(res) {
1706 V_VT(res) = VT_DISPATCH;
1707 V_DISPATCH(res) = disp;
1708 }else {
1709 IDispatch_Release(disp);
1710 }
1711 }else {
1712 FIXME("object does not support IDispatch\n");
1713 }
1714
1715 return hres;
1716 }
1717
1718 static HRESULT Global_DateAdd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1719 {
1720 FIXME("\n");
1721 return E_NOTIMPL;
1722 }
1723
1724 static HRESULT Global_DateDiff(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1725 {
1726 FIXME("\n");
1727 return E_NOTIMPL;
1728 }
1729
1730 static HRESULT Global_DatePart(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1731 {
1732 FIXME("\n");
1733 return E_NOTIMPL;
1734 }
1735
1736 static HRESULT Global_TypeName(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1737 {
1738 static const WCHAR ByteW[] = {'B', 'y', 't', 'e', 0};
1739 static const WCHAR IntegerW[] = {'I', 'n', 't', 'e', 'g', 'e', 'r', 0};
1740 static const WCHAR LongW[] = {'L', 'o', 'n', 'g', 0};
1741 static const WCHAR SingleW[] = {'S', 'i', 'n', 'g', 'l', 'e', 0};
1742 static const WCHAR DoubleW[] = {'D', 'o', 'u', 'b', 'l', 'e', 0};
1743 static const WCHAR CurrencyW[] = {'C', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 0};
1744 static const WCHAR DecimalW[] = {'D', 'e', 'c', 'i', 'm', 'a', 'l', 0};
1745 static const WCHAR DateW[] = {'D', 'a', 't', 'e', 0};
1746 static const WCHAR StringW[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
1747 static const WCHAR BooleanW[] = {'B', 'o', 'o', 'l', 'e', 'a', 'n', 0};
1748 static const WCHAR EmptyW[] = {'E', 'm', 'p', 't', 'y', 0};
1749 static const WCHAR NullW[] = {'N', 'u', 'l', 'l', 0};
1750
1751 TRACE("(%s)\n", debugstr_variant(arg));
1752
1753 assert(args_cnt == 1);
1754
1755 switch(V_VT(arg)) {
1756 case VT_UI1:
1757 return return_string(res, ByteW);
1758 case VT_I2:
1759 return return_string(res, IntegerW);
1760 case VT_I4:
1761 return return_string(res, LongW);
1762 case VT_R4:
1763 return return_string(res, SingleW);
1764 case VT_R8:
1765 return return_string(res, DoubleW);
1766 case VT_CY:
1767 return return_string(res, CurrencyW);
1768 case VT_DECIMAL:
1769 return return_string(res, DecimalW);
1770 case VT_DATE:
1771 return return_string(res, DateW);
1772 case VT_BSTR:
1773 return return_string(res, StringW);
1774 case VT_BOOL:
1775 return return_string(res, BooleanW);
1776 case VT_EMPTY:
1777 return return_string(res, EmptyW);
1778 case VT_NULL:
1779 return return_string(res, NullW);
1780 default:
1781 FIXME("arg %s not supported\n", debugstr_variant(arg));
1782 return E_NOTIMPL;
1783 }
1784 }
1785
1786 static HRESULT Global_Array(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1787 {
1788 FIXME("\n");
1789 return E_NOTIMPL;
1790 }
1791
1792 static HRESULT Global_Erase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1793 {
1794 FIXME("\n");
1795 return E_NOTIMPL;
1796 }
1797
1798 static HRESULT Global_Filter(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1799 {
1800 FIXME("\n");
1801 return E_NOTIMPL;
1802 }
1803
1804 static HRESULT Global_Join(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1805 {
1806 FIXME("\n");
1807 return E_NOTIMPL;
1808 }
1809
1810 static HRESULT Global_Split(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1811 {
1812 FIXME("\n");
1813 return E_NOTIMPL;
1814 }
1815
1816 static HRESULT Global_Replace(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1817 {
1818 FIXME("\n");
1819 return E_NOTIMPL;
1820 }
1821
1822 static HRESULT Global_StrReverse(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1823 {
1824 WCHAR *ptr1, *ptr2, ch;
1825 BSTR ret;
1826 HRESULT hres;
1827
1828 TRACE("%s\n", debugstr_variant(arg));
1829
1830 hres = to_string(arg, &ret);
1831 if(FAILED(hres))
1832 return hres;
1833
1834 ptr1 = ret;
1835 ptr2 = ret + SysStringLen(ret)-1;
1836 while(ptr1 < ptr2) {
1837 ch = *ptr1;
1838 *ptr1++ = *ptr2;
1839 *ptr2-- = ch;
1840 }
1841
1842 return return_bstr(res, ret);
1843 }
1844
1845 static HRESULT Global_InStrRev(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1846 {
1847 int start, ret = 0;
1848 BSTR str1, str2;
1849 HRESULT hres;
1850
1851 TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args), debugstr_variant(args+1), args_cnt);
1852
1853 if(args_cnt > 3) {
1854 FIXME("Unsupported args\n");
1855 return E_NOTIMPL;
1856 }
1857
1858 assert(2 <= args_cnt && args_cnt <= 4);
1859
1860 if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (args_cnt > 2 && V_VT(args+2) == VT_NULL))
1861 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
1862
1863 hres = to_string(args, &str1);
1864 if(FAILED(hres))
1865 return hres;
1866
1867 hres = to_string(args+1, &str2);
1868 if(SUCCEEDED(hres)) {
1869 if(args_cnt > 2) {
1870 hres = to_int(args+2, &start);
1871 if(SUCCEEDED(hres) && start <= 0) {
1872 FIXME("Unsupported start %d\n", start);
1873 hres = E_NOTIMPL;
1874 }
1875 }else {
1876 start = SysStringLen(str1);
1877 }
1878 } else {
1879 str2 = NULL;
1880 }
1881
1882 if(SUCCEEDED(hres)) {
1883 const WCHAR *ptr;
1884 size_t len;
1885
1886 len = SysStringLen(str2);
1887 if(start >= len && start <= SysStringLen(str1)) {
1888 for(ptr = str1+start-SysStringLen(str2); ptr >= str1; ptr--) {
1889 if(!memcmp(ptr, str2, len*sizeof(WCHAR))) {
1890 ret = ptr-str1+1;
1891 break;
1892 }
1893 }
1894 }
1895 }
1896
1897 SysFreeString(str1);
1898 SysFreeString(str2);
1899 if(FAILED(hres))
1900 return hres;
1901
1902 return return_int(res, ret);
1903 }
1904
1905 static HRESULT Global_LoadPicture(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1906 {
1907 FIXME("\n");
1908 return E_NOTIMPL;
1909 }
1910
1911 static HRESULT Global_ScriptEngine(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1912 {
1913 TRACE("%s\n", debugstr_variant(arg));
1914
1915 assert(args_cnt == 0);
1916
1917 return return_string(res, vbscriptW);
1918 }
1919
1920 static HRESULT Global_ScriptEngineMajorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1921 {
1922 TRACE("%s\n", debugstr_variant(arg));
1923
1924 assert(args_cnt == 0);
1925
1926 return return_int(res, VBSCRIPT_MAJOR_VERSION);
1927 }
1928
1929 static HRESULT Global_ScriptEngineMinorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1930 {
1931 TRACE("%s\n", debugstr_variant(arg));
1932
1933 assert(args_cnt == 0);
1934
1935 return return_int(res, VBSCRIPT_MINOR_VERSION);
1936 }
1937
1938 static HRESULT Global_ScriptEngineBuildVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1939 {
1940 TRACE("%s\n", debugstr_variant(arg));
1941
1942 assert(args_cnt == 0);
1943
1944 return return_int(res, VBSCRIPT_BUILD_VERSION);
1945 }
1946
1947 static HRESULT Global_FormatNumber(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1948 {
1949 FIXME("\n");
1950 return E_NOTIMPL;
1951 }
1952
1953 static HRESULT Global_FormatCurrency(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1954 {
1955 FIXME("\n");
1956 return E_NOTIMPL;
1957 }
1958
1959 static HRESULT Global_FormatPercent(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1960 {
1961 FIXME("\n");
1962 return E_NOTIMPL;
1963 }
1964
1965 static HRESULT Global_FormatDateTime(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1966 {
1967 FIXME("\n");
1968 return E_NOTIMPL;
1969 }
1970
1971 static HRESULT Global_WeekdayName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1972 {
1973 int weekday, first_day = 1, abbrev = 0;
1974 BSTR ret;
1975 HRESULT hres;
1976
1977 TRACE("\n");
1978
1979 assert(1 <= args_cnt && args_cnt <= 3);
1980
1981 hres = to_int(args, &weekday);
1982 if(FAILED(hres))
1983 return hres;
1984
1985 if(args_cnt > 1) {
1986 hres = to_int(args+1, &abbrev);
1987 if(FAILED(hres))
1988 return hres;
1989
1990 if(args_cnt == 3) {
1991 hres = to_int(args+2, &first_day);
1992 if(FAILED(hres))
1993 return hres;
1994 }
1995 }
1996
1997 hres = VarWeekdayName(weekday, abbrev, first_day, 0, &ret);
1998 if(FAILED(hres))
1999 return hres;
2000
2001 return return_bstr(res, ret);
2002 }
2003
2004 static HRESULT Global_MonthName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2005 {
2006 int month, abbrev = 0;
2007 BSTR ret;
2008 HRESULT hres;
2009
2010 TRACE("\n");
2011
2012 assert(args_cnt == 1 || args_cnt == 2);
2013
2014 hres = to_int(args, &month);
2015 if(FAILED(hres))
2016 return hres;
2017
2018 if(args_cnt == 2) {
2019 hres = to_int(args+1, &abbrev);
2020 if(FAILED(hres))
2021 return hres;
2022 }
2023
2024 hres = VarMonthName(month, abbrev, 0, &ret);
2025 if(FAILED(hres))
2026 return hres;
2027
2028 return return_bstr(res, ret);
2029 }
2030
2031 static HRESULT Global_Round(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2032 {
2033 double n;
2034 HRESULT hres;
2035
2036 TRACE("%s\n", debugstr_variant(arg));
2037
2038 if(!res)
2039 return S_OK;
2040
2041 switch(V_VT(arg)) {
2042 case VT_I2:
2043 case VT_I4:
2044 case VT_BOOL:
2045 *res = *arg;
2046 return S_OK;
2047 case VT_R8:
2048 n = V_R8(arg);
2049 break;
2050 default:
2051 hres = to_double(arg, &n);
2052 if(FAILED(hres))
2053 return hres;
2054 }
2055
2056 return return_double(res, round(n));
2057 }
2058
2059 static HRESULT Global_Escape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2060 {
2061 FIXME("\n");
2062 return E_NOTIMPL;
2063 }
2064
2065 static HRESULT Global_Unescape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2066 {
2067 FIXME("\n");
2068 return E_NOTIMPL;
2069 }
2070
2071 static HRESULT Global_Eval(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2072 {
2073 FIXME("\n");
2074 return E_NOTIMPL;
2075 }
2076
2077 static HRESULT Global_Execute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2078 {
2079 FIXME("\n");
2080 return E_NOTIMPL;
2081 }
2082
2083 static HRESULT Global_ExecuteGlobal(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2084 {
2085 FIXME("\n");
2086 return E_NOTIMPL;
2087 }
2088
2089 static HRESULT Global_GetRef(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2090 {
2091 FIXME("\n");
2092 return E_NOTIMPL;
2093 }
2094
2095 static const string_constant_t vbCr = {1, {'\r'}};
2096 static const string_constant_t vbCrLf = {2, {'\r','\n'}};
2097 static const string_constant_t vbNewLine = {2, {'\r','\n'}};
2098 static const string_constant_t vbFormFeed = {1, {0xc}};
2099 static const string_constant_t vbLf = {1, {'\n'}};
2100 static const string_constant_t vbNullChar = {1};
2101 static const string_constant_t vbNullString = {0};
2102 static const string_constant_t vbTab = {1, {'\t'}};
2103 static const string_constant_t vbVerticalTab = {1, {0xb}};
2104
2105 static const builtin_prop_t global_props[] = {
2106 {DISPID_GLOBAL_VBUSESYSTEM, NULL, BP_GET, VT_I2, 0},
2107 {DISPID_GLOBAL_USESYSTEMDAYOFWEEK, NULL, BP_GET, VT_I2, 0},
2108 {DISPID_GLOBAL_VBSUNDAY, NULL, BP_GET, VT_I2, 1},
2109 {DISPID_GLOBAL_VBMONDAY, NULL, BP_GET, VT_I2, 2},
2110 {DISPID_GLOBAL_VBTUESDAY, NULL, BP_GET, VT_I2, 3},
2111 {DISPID_GLOBAL_VBWEDNESDAY, NULL, BP_GET, VT_I2, 4},
2112 {DISPID_GLOBAL_VBTHURSDAY, NULL, BP_GET, VT_I2, 5},
2113 {DISPID_GLOBAL_VBFRIDAY, NULL, BP_GET, VT_I2, 6},
2114 {DISPID_GLOBAL_VBSATURDAY, NULL, BP_GET, VT_I2, 7},
2115 {DISPID_GLOBAL_VBFIRSTJAN1, NULL, BP_GET, VT_I2, 1},
2116 {DISPID_GLOBAL_VBFIRSTFOURDAYS, NULL, BP_GET, VT_I2, 2},
2117 {DISPID_GLOBAL_VBFIRSTFULLWEEK, NULL, BP_GET, VT_I2, 3},
2118 {DISPID_GLOBAL_VBOKONLY, NULL, BP_GET, VT_I2, MB_OK},
2119 {DISPID_GLOBAL_VBOKCANCEL, NULL, BP_GET, VT_I2, MB_OKCANCEL},
2120 {DISPID_GLOBAL_VBABORTRETRYIGNORE, NULL, BP_GET, VT_I2, MB_ABORTRETRYIGNORE},
2121 {DISPID_GLOBAL_VBYESNOCANCEL, NULL, BP_GET, VT_I2, MB_YESNOCANCEL},
2122 {DISPID_GLOBAL_VBYESNO, NULL, BP_GET, VT_I2, MB_YESNO},
2123 {DISPID_GLOBAL_VBRETRYCANCEL, NULL, BP_GET, VT_I2, MB_RETRYCANCEL},
2124 {DISPID_GLOBAL_VBCRITICAL, NULL, BP_GET, VT_I2, MB_ICONHAND},
2125 {DISPID_GLOBAL_VBQUESTION, NULL, BP_GET, VT_I2, MB_ICONQUESTION},
2126 {DISPID_GLOBAL_VBEXCLAMATION, NULL, BP_GET, VT_I2, MB_ICONEXCLAMATION},
2127 {DISPID_GLOBAL_VBINFORMATION, NULL, BP_GET, VT_I2, MB_ICONASTERISK},
2128 {DISPID_GLOBAL_VBDEFAULTBUTTON1, NULL, BP_GET, VT_I2, MB_DEFBUTTON1},
2129 {DISPID_GLOBAL_VBDEFAULTBUTTON2, NULL, BP_GET, VT_I2, MB_DEFBUTTON2},
2130 {DISPID_GLOBAL_VBDEFAULTBUTTON3, NULL, BP_GET, VT_I2, MB_DEFBUTTON3},
2131 {DISPID_GLOBAL_VBDEFAULTBUTTON4, NULL, BP_GET, VT_I2, MB_DEFBUTTON4},
2132 {DISPID_GLOBAL_VBAPPLICATIONMODAL, NULL, BP_GET, VT_I2, MB_APPLMODAL},
2133 {DISPID_GLOBAL_VBSYSTEMMODAL, NULL, BP_GET, VT_I2, MB_SYSTEMMODAL},
2134 {DISPID_GLOBAL_VBOK, NULL, BP_GET, VT_I2, IDOK},
2135 {DISPID_GLOBAL_VBCANCEL, NULL, BP_GET, VT_I2, IDCANCEL},
2136 {DISPID_GLOBAL_VBABORT, NULL, BP_GET, VT_I2, IDABORT},
2137 {DISPID_GLOBAL_VBRETRY, NULL, BP_GET, VT_I2, IDRETRY},
2138 {DISPID_GLOBAL_VBIGNORE, NULL, BP_GET, VT_I2, IDIGNORE},
2139 {DISPID_GLOBAL_VBYES, NULL, BP_GET, VT_I2, IDYES},
2140 {DISPID_GLOBAL_VBNO, NULL, BP_GET, VT_I2, IDNO},
2141 {DISPID_GLOBAL_VBEMPTY, NULL, BP_GET, VT_I2, VT_EMPTY},
2142 {DISPID_GLOBAL_VBNULL, NULL, BP_GET, VT_I2, VT_NULL},
2143 {DISPID_GLOBAL_VBINTEGER, NULL, BP_GET, VT_I2, VT_I2},
2144 {DISPID_GLOBAL_VBLONG, NULL, BP_GET, VT_I2, VT_I4},
2145 {DISPID_GLOBAL_VBSINGLE, NULL, BP_GET, VT_I2, VT_R4},
2146 {DISPID_GLOBAL_VBDOUBLE, NULL, BP_GET, VT_I2, VT_R8},
2147 {DISPID_GLOBAL_VBCURRENCY, NULL, BP_GET, VT_I2, VT_CY},
2148 {DISPID_GLOBAL_VBDATE, NULL, BP_GET, VT_I2, VT_DATE},
2149 {DISPID_GLOBAL_VBSTRING, NULL, BP_GET, VT_I2, VT_BSTR},
2150 {DISPID_GLOBAL_VBOBJECT, NULL, BP_GET, VT_I2, VT_DISPATCH},
2151 {DISPID_GLOBAL_VBERROR, NULL, BP_GET, VT_I2, VT_ERROR},
2152 {DISPID_GLOBAL_VBBOOLEAN, NULL, BP_GET, VT_I2, VT_BOOL},
2153 {DISPID_GLOBAL_VBVARIANT, NULL, BP_GET, VT_I2, VT_VARIANT},
2154 {DISPID_GLOBAL_VBDATAOBJECT, NULL, BP_GET, VT_I2, VT_UNKNOWN},
2155 {DISPID_GLOBAL_VBDECIMAL, NULL, BP_GET, VT_I2, VT_DECIMAL},
2156 {DISPID_GLOBAL_VBBYTE, NULL, BP_GET, VT_I2, VT_UI1},
2157 {DISPID_GLOBAL_VBARRAY, NULL, BP_GET, VT_I2, VT_ARRAY},
2158 {DISPID_GLOBAL_VBTRUE, NULL, BP_GET, VT_I2, VARIANT_TRUE},
2159 {DISPID_GLOBAL_VBFALSE, NULL, BP_GET, VT_I2, VARIANT_FALSE},
2160 {DISPID_GLOBAL_VBUSEDEFAULT, NULL, BP_GET, VT_I2, -2},
2161 {DISPID_GLOBAL_VBBINARYCOMPARE, NULL, BP_GET, VT_I2, 0},
2162 {DISPID_GLOBAL_VBTEXTCOMPARE, NULL, BP_GET, VT_I2, 1},
2163 {DISPID_GLOBAL_VBDATABASECOMPARE, NULL, BP_GET, VT_I2, 2},
2164 {DISPID_GLOBAL_VBGENERALDATE, NULL, BP_GET, VT_I2, 0},
2165 {DISPID_GLOBAL_VBLONGDATE, NULL, BP_GET, VT_I2, 1},
2166 {DISPID_GLOBAL_VBSHORTDATE, NULL, BP_GET, VT_I2, 2},
2167 {DISPID_GLOBAL_VBLONGTIME, NULL, BP_GET, VT_I2, 3},
2168 {DISPID_GLOBAL_VBSHORTTIME, NULL, BP_GET, VT_I2, 4},
2169 {DISPID_GLOBAL_VBOBJECTERROR, NULL, BP_GET, VT_I4, 0x80040000},
2170 {DISPID_GLOBAL_VBBLACK, NULL, BP_GET, VT_I4, 0x000000},
2171 {DISPID_GLOBAL_VBBLUE, NULL, BP_GET, VT_I4, 0xff0000},
2172 {DISPID_GLOBAL_VBCYAN, NULL, BP_GET, VT_I4, 0xffff00},
2173 {DISPID_GLOBAL_VBGREEN, NULL, BP_GET, VT_I4, 0x00ff00},
2174 {DISPID_GLOBAL_VBMAGENTA, NULL, BP_GET, VT_I4, 0xff00ff},
2175 {DISPID_GLOBAL_VBRED, NULL, BP_GET, VT_I4, 0x0000ff},
2176 {DISPID_GLOBAL_VBWHITE, NULL, BP_GET, VT_I4, 0xffffff},
2177 {DISPID_GLOBAL_VBYELLOW, NULL, BP_GET, VT_I4, 0x00ffff},
2178 {DISPID_GLOBAL_VBCR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCr},
2179 {DISPID_GLOBAL_VBCRLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCrLf},
2180 {DISPID_GLOBAL_VBNEWLINE, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNewLine},
2181 {DISPID_GLOBAL_VBFORMFEED, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbFormFeed},
2182 {DISPID_GLOBAL_VBLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbLf},
2183 {DISPID_GLOBAL_VBNULLCHAR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullChar},
2184 {DISPID_GLOBAL_VBNULLSTRING, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullString},
2185 {DISPID_GLOBAL_VBTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbTab},
2186 {DISPID_GLOBAL_VBVERTICALTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbVerticalTab},
2187 {DISPID_GLOBAL_CCUR, Global_CCur, 0, 1},
2188 {DISPID_GLOBAL_CINT, Global_CInt, 0, 1},
2189 {DISPID_GLOBAL_CLNG, Global_CLng, 0, 1},
2190 {DISPID_GLOBAL_CBOOL, Global_CBool, 0, 1},
2191 {DISPID_GLOBAL_CBYTE, Global_CByte, 0, 1},
2192 {DISPID_GLOBAL_CDATE, Global_CDate, 0, 1},
2193 {DISPID_GLOBAL_CDBL, Global_CDbl, 0, 1},
2194 {DISPID_GLOBAL_CSNG, Global_CSng, 0, 1},
2195 {DISPID_GLOBAL_CSTR, Global_CStr, 0, 1},
2196 {DISPID_GLOBAL_HEX, Global_Hex, 0, 1},
2197 {DISPID_GLOBAL_OCT, Global_Oct, 0, 1},
2198 {DISPID_GLOBAL_VARTYPE, Global_VarType, 0, 1},
2199 {DISPID_GLOBAL_ISDATE, Global_IsDate, 0, 1},
2200 {DISPID_GLOBAL_ISEMPTY, Global_IsEmpty, 0, 1},
2201 {DISPID_GLOBAL_ISNULL, Global_IsNull, 0, 1},
2202 {DISPID_GLOBAL_ISNUMERIC, Global_IsNumeric, 0, 1},
2203 {DISPID_GLOBAL_ISARRAY, Global_IsArray, 0, 1},
2204 {DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1},
2205 {DISPID_GLOBAL_ATN, Global_Atn, 0, 1},
2206 {DISPID_GLOBAL_COS, Global_Cos, 0, 1},
2207 {DISPID_GLOBAL_SIN, Global_Sin, 0, 1},
2208 {DISPID_GLOBAL_TAN, Global_Tan, 0, 1},
2209 {DISPID_GLOBAL_EXP, Global_Exp, 0, 1},
2210 {DISPID_GLOBAL_LOG, Global_Log, 0, 1},
2211 {DISPID_GLOBAL_SQR, Global_Sqr, 0, 1},
2212 {DISPID_GLOBAL_RANDOMIZE, Global_Randomize, 0, 1},
2213 {DISPID_GLOBAL_RND, Global_Rnd, 0, 1},
2214 {DISPID_GLOBAL_TIMER, Global_Timer, 0, 0},
2215 {DISPID_GLOBAL_LBOUND, Global_LBound, 0, 1},
2216 {DISPID_GLOBAL_UBOUND, Global_UBound, 0, 1},
2217 {DISPID_GLOBAL_RGB, Global_RGB, 0, 3},
2218 {DISPID_GLOBAL_LEN, Global_Len, 0, 1},
2219 {DISPID_GLOBAL_LENB, Global_LenB, 0, 1},
2220 {DISPID_GLOBAL_LEFT, Global_Left, 0, 2},
2221 {DISPID_GLOBAL_LEFTB, Global_LeftB, 0, 2},
2222 {DISPID_GLOBAL_RIGHT, Global_Right, 0, 2},
2223 {DISPID_GLOBAL_RIGHTB, Global_RightB, 0, 2},
2224 {DISPID_GLOBAL_MID, Global_Mid, 0, 2, 3},
2225 {DISPID_GLOBAL_MIDB, Global_MidB, 0, 2, 3},
2226 {DISPID_GLOBAL_STRCOMP, Global_StrComp, 0, 2, 3},
2227 {DISPID_GLOBAL_LCASE, Global_LCase, 0, 1},
2228 {DISPID_GLOBAL_UCASE, Global_UCase, 0, 1},
2229 {DISPID_GLOBAL_LTRIM, Global_LTrim, 0, 1},
2230 {DISPID_GLOBAL_RTRIM, Global_RTrim, 0, 1},
2231 {DISPID_GLOBAL_TRIM, Global_Trim, 0, 1},
2232 {DISPID_GLOBAL_SPACE, Global_Space, 0, 1},
2233 {DISPID_GLOBAL_STRING, Global_String, 0, 0, 2},
2234 {DISPID_GLOBAL_INSTR, Global_InStr, 0, 2, 4},
2235 {DISPID_GLOBAL_INSTRB, Global_InStrB, 0, 3, 4},
2236 {DISPID_GLOBAL_ASCB, Global_AscB, 0, 1},
2237 {DISPID_GLOBAL_CHRB, Global_ChrB, 0, 1},
2238 {DISPID_GLOBAL_ASC, Global_Asc, 0, 1},
2239 {DISPID_GLOBAL_CHR, Global_Chr, 0, 1},
2240 {DISPID_GLOBAL_ASCW, Global_AscW, 0, 1},
2241 {DISPID_GLOBAL_CHRW, Global_ChrW, 0, 1},
2242 {DISPID_GLOBAL_ABS, Global_Abs, 0, 1},
2243 {DISPID_GLOBAL_FIX, Global_Fix, 0, 1},
2244 {DISPID_GLOBAL_INT, Global_Int, 0, 1},
2245 {DISPID_GLOBAL_SGN, Global_Sgn, 0, 1},
2246 {DISPID_GLOBAL_NOW, Global_Now, 0, 0},
2247 {DISPID_GLOBAL_DATE, Global_Date, 0, 0},
2248 {DISPID_GLOBAL_TIME, Global_Time, 0, 0},
2249 {DISPID_GLOBAL_DAY, Global_Day, 0, 1},
2250 {DISPID_GLOBAL_MONTH, Global_Month, 0, 1},
2251 {DISPID_GLOBAL_WEEKDAY, Global_Weekday, 0, 1, 2},
2252 {DISPID_GLOBAL_YEAR, Global_Year, 0, 1},
2253 {DISPID_GLOBAL_HOUR, Global_Hour, 0, 1},
2254 {DISPID_GLOBAL_MINUTE, Global_Minute, 0, 1},
2255 {DISPID_GLOBAL_SECOND, Global_Second, 0, 1},
2256 {DISPID_GLOBAL_DATEVALUE, Global_DateValue, 0, 1},
2257 {DISPID_GLOBAL_TIMEVALUE, Global_TimeValue, 0, 1},
2258 {DISPID_GLOBAL_DATESERIAL, Global_DateSerial, 0, 3},
2259 {DISPID_GLOBAL_TIMESERIAL, Global_TimeSerial, 0, 3},
2260 {DISPID_GLOBAL_INPUTBOX, Global_InputBox, 0, 1, 7},
2261 {DISPID_GLOBAL_MSGBOX, Global_MsgBox, 0, 1, 5},
2262 {DISPID_GLOBAL_CREATEOBJECT, Global_CreateObject, 0, 1},
2263 {DISPID_GLOBAL_GETOBJECT, Global_GetObject, 0, 0, 2},
2264 {DISPID_GLOBAL_DATEADD, Global_DateAdd, 0, 3},
2265 {DISPID_GLOBAL_DATEDIFF, Global_DateDiff, 0, 3, 5},
2266 {DISPID_GLOBAL_DATEPART, Global_DatePart, 0, 2, 4},
2267 {DISPID_GLOBAL_TYPENAME, Global_TypeName, 0, 1},
2268 {DISPID_GLOBAL_ARRAY, Global_Array, 0, 1},
2269 {DISPID_GLOBAL_ERASE, Global_Erase, 0, 1},
2270 {DISPID_GLOBAL_FILTER, Global_Filter, 0, 2, 4},
2271 {DISPID_GLOBAL_JOIN, Global_Join, 0, 1, 2},
2272 {DISPID_GLOBAL_SPLIT, Global_Split, 0, 1, 4},
2273 {DISPID_GLOBAL_REPLACE, Global_Replace, 0, 3, 6},
2274 {DISPID_GLOBAL_STRREVERSE, Global_StrReverse, 0, 1},
2275 {DISPID_GLOBAL_INSTRREV, Global_InStrRev, 0, 2, 4},
2276 {DISPID_GLOBAL_LOADPICTURE, Global_LoadPicture, 0, 1},
2277 {DISPID_GLOBAL_SCRIPTENGINE, Global_ScriptEngine, 0, 0},
2278 {DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION, Global_ScriptEngineMajorVersion, 0, 0},
2279 {DISPID_GLOBAL_SCRIPTENGINEMINORVERSION, Global_ScriptEngineMinorVersion, 0, 0},
2280 {DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION, Global_ScriptEngineBuildVersion, 0, 0},
2281 {DISPID_GLOBAL_FORMATNUMBER, Global_FormatNumber, 0, 1, 5},
2282 {DISPID_GLOBAL_FORMATCURRENCY, Global_FormatCurrency, 0, 1, 5},
2283 {DISPID_GLOBAL_FORMATPERCENT, Global_FormatPercent, 0, 1, 5},
2284 {DISPID_GLOBAL_FORMATDATETIME, Global_FormatDateTime, 0, 1, 2},
2285 {DISPID_GLOBAL_WEEKDAYNAME, Global_WeekdayName, 0, 1, 3},
2286 {DISPID_GLOBAL_MONTHNAME, Global_MonthName, 0, 1, 2},
2287 {DISPID_GLOBAL_ROUND, Global_Round, 0, 1, 2},
2288 {DISPID_GLOBAL_ESCAPE, Global_Escape, 0, 1},
2289 {DISPID_GLOBAL_UNESCAPE, Global_Unescape, 0, 1},
2290 {DISPID_GLOBAL_EVAL, Global_Eval, 0, 1},
2291 {DISPID_GLOBAL_EXECUTE, Global_Execute, 0, 1},
2292 {DISPID_GLOBAL_EXECUTEGLOBAL, Global_ExecuteGlobal, 0, 1},
2293 {DISPID_GLOBAL_GETREF, Global_GetRef, 0, 1},
2294 {DISPID_GLOBAL_VBMSGBOXHELPBUTTON, NULL, BP_GET, VT_I4, MB_HELP},
2295 {DISPID_GLOBAL_VBMSGBOXSETFOREGROUND, NULL, BP_GET, VT_I4, MB_SETFOREGROUND},
2296 {DISPID_GLOBAL_VBMSGBOXRIGHT, NULL, BP_GET, VT_I4, MB_RIGHT},
2297 {DISPID_GLOBAL_VBMSGBOXRTLREADING, NULL, BP_GET, VT_I4, MB_RTLREADING}
2298 };
2299
2300 static HRESULT Err_Description(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2301 {
2302 FIXME("\n");
2303 return E_NOTIMPL;
2304 }
2305
2306 static HRESULT Err_HelpContext(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2307 {
2308 FIXME("\n");
2309 return E_NOTIMPL;
2310 }
2311
2312 static HRESULT Err_HelpFile(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2313 {
2314 FIXME("\n");
2315 return E_NOTIMPL;
2316 }
2317
2318 static HRESULT Err_Number(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2319 {
2320 HRESULT hres;
2321
2322 TRACE("\n");
2323
2324 if(!This->desc)
2325 return E_UNEXPECTED;
2326
2327 if(args_cnt) {
2328 FIXME("setter not implemented\n");
2329 return E_NOTIMPL;
2330 }
2331
2332 hres = This->desc->ctx->err_number;
2333 return return_int(res, HRESULT_FACILITY(hres) == FACILITY_VBS ? HRESULT_CODE(hres) : hres);
2334 }
2335
2336 static HRESULT Err_Source(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2337 {
2338 FIXME("\n");
2339 return E_NOTIMPL;
2340 }
2341
2342 static HRESULT Err_Clear(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2343 {
2344 TRACE("\n");
2345
2346 if(!This->desc)
2347 return E_UNEXPECTED;
2348
2349 This->desc->ctx->err_number = S_OK;
2350 return S_OK;
2351 }
2352
2353 static HRESULT Err_Raise(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2354 {
2355 FIXME("\n");
2356 return E_NOTIMPL;
2357 }
2358
2359 static const builtin_prop_t err_props[] = {
2360 {DISPID_ERR_DESCRIPTION, Err_Description, BP_GETPUT},
2361 {DISPID_ERR_HELPCONTEXT, Err_HelpContext, BP_GETPUT},
2362 {DISPID_ERR_HELPFILE, Err_HelpFile, BP_GETPUT},
2363 {DISPID_ERR_NUMBER, Err_Number, BP_GETPUT},
2364 {DISPID_ERR_SOURCE, Err_Source, BP_GETPUT},
2365 {DISPID_ERR_CLEAR, Err_Clear},
2366 {DISPID_ERR_RAISE, Err_Raise, 0, 5},
2367 };
2368
2369 HRESULT init_global(script_ctx_t *ctx)
2370 {
2371 HRESULT hres;
2372
2373 ctx->global_desc.ctx = ctx;
2374 ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
2375 ctx->global_desc.builtin_props = global_props;
2376
2377 hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
2378 if(FAILED(hres))
2379 return hres;
2380
2381 hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
2382 if(FAILED(hres))
2383 return hres;
2384
2385 hres = create_script_disp(ctx, &ctx->script_obj);
2386 if(FAILED(hres))
2387 return hres;
2388
2389 ctx->err_desc.ctx = ctx;
2390 ctx->err_desc.builtin_prop_cnt = sizeof(err_props)/sizeof(*err_props);
2391 ctx->err_desc.builtin_props = err_props;
2392
2393 hres = get_typeinfo(ErrObj_tid, &ctx->err_desc.typeinfo);
2394 if(FAILED(hres))
2395 return hres;
2396
2397 return create_vbdisp(&ctx->err_desc, &ctx->err_obj);
2398 }