[VBSCRIPT] Sync with Wine Staging 1.9.11. CORE-11368
[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 *arg, unsigned args_cnt, VARIANT *res)
1024 {
1025 FIXME("\n");
1026 return E_NOTIMPL;
1027 }
1028
1029 static HRESULT Global_LCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1030 {
1031 BSTR str;
1032 HRESULT hres;
1033
1034 TRACE("%s\n", debugstr_variant(arg));
1035
1036 if(V_VT(arg) == VT_NULL) {
1037 if(res)
1038 V_VT(res) = VT_NULL;
1039 return S_OK;
1040 }
1041
1042 hres = to_string(arg, &str);
1043 if(FAILED(hres))
1044 return hres;
1045
1046 if(res) {
1047 WCHAR *ptr;
1048
1049 for(ptr = str; *ptr; ptr++)
1050 *ptr = tolowerW(*ptr);
1051
1052 V_VT(res) = VT_BSTR;
1053 V_BSTR(res) = str;
1054 }else {
1055 SysFreeString(str);
1056 }
1057 return S_OK;
1058 }
1059
1060 static HRESULT Global_UCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1061 {
1062 BSTR str;
1063 HRESULT hres;
1064
1065 TRACE("%s\n", debugstr_variant(arg));
1066
1067 if(V_VT(arg) == VT_NULL) {
1068 if(res)
1069 V_VT(res) = VT_NULL;
1070 return S_OK;
1071 }
1072
1073 hres = to_string(arg, &str);
1074 if(FAILED(hres))
1075 return hres;
1076
1077 if(res) {
1078 WCHAR *ptr;
1079
1080 for(ptr = str; *ptr; ptr++)
1081 *ptr = toupperW(*ptr);
1082
1083 V_VT(res) = VT_BSTR;
1084 V_BSTR(res) = str;
1085 }else {
1086 SysFreeString(str);
1087 }
1088 return S_OK;
1089 }
1090
1091 static HRESULT Global_LTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1092 {
1093 BSTR str, conv_str = NULL;
1094 WCHAR *ptr;
1095 HRESULT hres;
1096
1097 TRACE("%s\n", debugstr_variant(arg));
1098
1099 if(V_VT(arg) == VT_BSTR) {
1100 str = V_BSTR(arg);
1101 }else {
1102 hres = to_string(arg, &conv_str);
1103 if(FAILED(hres))
1104 return hres;
1105 str = conv_str;
1106 }
1107
1108 for(ptr = str; *ptr && isspaceW(*ptr); ptr++);
1109
1110 str = SysAllocString(ptr);
1111 SysFreeString(conv_str);
1112 if(!str)
1113 return E_OUTOFMEMORY;
1114
1115 return return_bstr(res, str);
1116 }
1117
1118 static HRESULT Global_RTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1119 {
1120 BSTR str, conv_str = NULL;
1121 WCHAR *ptr;
1122 HRESULT hres;
1123
1124 TRACE("%s\n", debugstr_variant(arg));
1125
1126 if(V_VT(arg) == VT_BSTR) {
1127 str = V_BSTR(arg);
1128 }else {
1129 hres = to_string(arg, &conv_str);
1130 if(FAILED(hres))
1131 return hres;
1132 str = conv_str;
1133 }
1134
1135 for(ptr = str+SysStringLen(str); ptr-1 > str && isspaceW(*(ptr-1)); ptr--);
1136
1137 str = SysAllocStringLen(str, ptr-str);
1138 SysFreeString(conv_str);
1139 if(!str)
1140 return E_OUTOFMEMORY;
1141
1142 return return_bstr(res, str);
1143 }
1144
1145 static HRESULT Global_Trim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1146 {
1147 BSTR str, conv_str = NULL;
1148 WCHAR *begin_ptr, *end_ptr;
1149 HRESULT hres;
1150
1151 TRACE("%s\n", debugstr_variant(arg));
1152
1153 if(V_VT(arg) == VT_BSTR) {
1154 str = V_BSTR(arg);
1155 }else {
1156 hres = to_string(arg, &conv_str);
1157 if(FAILED(hres))
1158 return hres;
1159 str = conv_str;
1160 }
1161
1162 for(begin_ptr = str; *begin_ptr && isspaceW(*begin_ptr); begin_ptr++);
1163 for(end_ptr = str+SysStringLen(str); end_ptr-1 > begin_ptr && isspaceW(*(end_ptr-1)); end_ptr--);
1164
1165 str = SysAllocStringLen(begin_ptr, end_ptr-begin_ptr);
1166 SysFreeString(conv_str);
1167 if(!str)
1168 return E_OUTOFMEMORY;
1169
1170 return return_bstr(res, str);
1171 }
1172
1173 static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1174 {
1175 BSTR str;
1176 int n, i;
1177 HRESULT hres;
1178
1179 TRACE("%s\n", debugstr_variant(arg));
1180
1181 hres = to_int(arg, &n);
1182 if(FAILED(hres))
1183 return hres;
1184
1185 if(n < 0) {
1186 FIXME("n = %d\n", n);
1187 return E_NOTIMPL;
1188 }
1189
1190 if(!res)
1191 return S_OK;
1192
1193 str = SysAllocStringLen(NULL, n);
1194 if(!str)
1195 return E_OUTOFMEMORY;
1196
1197 for(i=0; i<n; i++)
1198 str[i] = ' ';
1199
1200 V_VT(res) = VT_BSTR;
1201 V_BSTR(res) = str;
1202 return S_OK;
1203 }
1204
1205 static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1206 {
1207 FIXME("\n");
1208 return E_NOTIMPL;
1209 }
1210
1211 static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1212 {
1213 VARIANT *startv, *str1v, *str2v;
1214 BSTR str1, str2;
1215 int start, ret;
1216 HRESULT hres;
1217
1218 TRACE("\n");
1219
1220 assert(2 <= args_cnt && args_cnt <= 4);
1221
1222 switch(args_cnt) {
1223 case 2:
1224 startv = NULL;
1225 str1v = args;
1226 str2v = args+1;
1227 break;
1228 case 3:
1229 startv = args;
1230 str1v = args+1;
1231 str2v = args+2;
1232 break;
1233 case 4:
1234 FIXME("unsupported compare argument %s\n", debugstr_variant(args));
1235 return E_NOTIMPL;
1236 DEFAULT_UNREACHABLE;
1237 }
1238
1239 if(startv) {
1240 hres = to_int(startv, &start);
1241 if(FAILED(hres))
1242 return hres;
1243 if(--start < 0) {
1244 FIXME("start %d\n", start);
1245 return E_FAIL;
1246 }
1247 }else {
1248 start = 0;
1249 }
1250
1251 if(V_VT(str1v) == VT_NULL || V_VT(str2v) == VT_NULL)
1252 return return_null(res);
1253
1254 if(V_VT(str1v) != VT_BSTR) {
1255 FIXME("Unsupported str1 type %s\n", debugstr_variant(str1v));
1256 return E_NOTIMPL;
1257 }
1258 str1 = V_BSTR(str1v);
1259
1260 if(V_VT(str2v) != VT_BSTR) {
1261 FIXME("Unsupported str2 type %s\n", debugstr_variant(str2v));
1262 return E_NOTIMPL;
1263 }
1264 str2 = V_BSTR(str2v);
1265
1266 if(start < SysStringLen(str1)) {
1267 WCHAR *ptr;
1268
1269 ptr = strstrW(str1+start, str2);
1270 ret = ptr ? ptr-str1+1 : 0;
1271 }else {
1272 ret = 0;
1273 }
1274
1275 return return_int(res, ret);
1276 }
1277
1278 static HRESULT Global_InStrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1279 {
1280 FIXME("\n");
1281 return E_NOTIMPL;
1282 }
1283
1284 static HRESULT Global_AscB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1285 {
1286 FIXME("\n");
1287 return E_NOTIMPL;
1288 }
1289
1290 static HRESULT Global_ChrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1291 {
1292 FIXME("\n");
1293 return E_NOTIMPL;
1294 }
1295
1296 static HRESULT Global_Asc(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1297 {
1298 FIXME("\n");
1299 return E_NOTIMPL;
1300 }
1301
1302 /* The function supports only single-byte and double-byte character sets. It
1303 * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
1304 * to be in range of short or unsigned short. */
1305 static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1306 {
1307 int cp, c, len = 0;
1308 CPINFO cpi;
1309 WCHAR ch;
1310 char buf[2];
1311 HRESULT hres;
1312
1313 TRACE("%s\n", debugstr_variant(arg));
1314
1315 hres = to_int(arg, &c);
1316 if(FAILED(hres))
1317 return hres;
1318
1319 cp = GetACP();
1320 if(!GetCPInfo(cp, &cpi))
1321 cpi.MaxCharSize = 1;
1322
1323 if((c!=(short)c && c!=(unsigned short)c) ||
1324 (unsigned short)c>=(cpi.MaxCharSize>1 ? 0x10000 : 0x100)) {
1325 WARN("invalid arg %d\n", c);
1326 return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
1327 }
1328
1329 if(c>>8)
1330 buf[len++] = c>>8;
1331 if(!len || IsDBCSLeadByteEx(cp, buf[0]))
1332 buf[len++] = c;
1333 if(!MultiByteToWideChar(CP_ACP, 0, buf, len, &ch, 1)) {
1334 WARN("invalid arg %d, cp %d\n", c, cp);
1335 return E_FAIL;
1336 }
1337
1338 if(res) {
1339 V_VT(res) = VT_BSTR;
1340 V_BSTR(res) = SysAllocStringLen(&ch, 1);
1341 if(!V_BSTR(res))
1342 return E_OUTOFMEMORY;
1343 }
1344 return S_OK;
1345 }
1346
1347 static HRESULT Global_AscW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1348 {
1349 FIXME("\n");
1350 return E_NOTIMPL;
1351 }
1352
1353 static HRESULT Global_ChrW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1354 {
1355 FIXME("\n");
1356 return E_NOTIMPL;
1357 }
1358
1359 static HRESULT Global_Abs(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1360 {
1361 HRESULT hres;
1362 VARIANT dst;
1363
1364 TRACE("(%s)\n", debugstr_variant(arg));
1365
1366 assert(args_cnt == 1);
1367
1368 hres = VarAbs(arg, &dst);
1369 if(FAILED(hres))
1370 return hres;
1371
1372 if (res)
1373 *res = dst;
1374 else
1375 VariantClear(&dst);
1376
1377 return S_OK;
1378 }
1379
1380 static HRESULT Global_Fix(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1381 {
1382 HRESULT hres;
1383 VARIANT dst;
1384
1385 TRACE("(%s)\n", debugstr_variant(arg));
1386
1387 assert(args_cnt == 1);
1388
1389 hres = VarFix(arg, &dst);
1390 if(FAILED(hres))
1391 return hres;
1392
1393 if (res)
1394 *res = dst;
1395 else
1396 VariantClear(&dst);
1397
1398 return S_OK;
1399 }
1400
1401 static HRESULT Global_Int(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1402 {
1403 HRESULT hres;
1404 VARIANT dst;
1405
1406 TRACE("(%s)\n", debugstr_variant(arg));
1407
1408 assert(args_cnt == 1);
1409
1410 hres = VarInt(arg, &dst);
1411 if(FAILED(hres))
1412 return hres;
1413
1414 if (res)
1415 *res = dst;
1416 else
1417 VariantClear(&dst);
1418
1419 return S_OK;
1420 }
1421
1422 static HRESULT Global_Sgn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1423 {
1424 double v;
1425 short val;
1426 HRESULT hres;
1427
1428 TRACE("(%s)\n", debugstr_variant(arg));
1429
1430 assert(args_cnt == 1);
1431
1432 if(V_VT(arg) == VT_NULL)
1433 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
1434
1435 hres = to_double(arg, &v);
1436 if (FAILED(hres))
1437 return hres;
1438
1439 val = v == 0 ? 0 : (v > 0 ? 1 : -1);
1440 return return_short(res, val);
1441 }
1442
1443 static HRESULT Global_Now(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1444 {
1445 SYSTEMTIME lt;
1446 double date;
1447
1448 TRACE("\n");
1449
1450 GetLocalTime(&lt);
1451 SystemTimeToVariantTime(&lt, &date);
1452 return return_date(res, date);
1453 }
1454
1455 static HRESULT Global_Date(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1456 {
1457 SYSTEMTIME lt;
1458 UDATE ud;
1459 DATE date;
1460 HRESULT hres;
1461
1462 TRACE("\n");
1463
1464 GetLocalTime(&lt);
1465 ud.st = lt;
1466 ud.wDayOfYear = 0;
1467 hres = VarDateFromUdateEx(&ud, 0, VAR_DATEVALUEONLY, &date);
1468 if(FAILED(hres))
1469 return hres;
1470 return return_date(res, date);
1471 }
1472
1473 static HRESULT Global_Time(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1474 {
1475 SYSTEMTIME lt;
1476 UDATE ud;
1477 DATE time;
1478 HRESULT hres;
1479
1480 TRACE("\n");
1481
1482 GetLocalTime(&lt);
1483 ud.st = lt;
1484 ud.wDayOfYear = 0;
1485 hres = VarDateFromUdateEx(&ud, 0, VAR_TIMEVALUEONLY, &time);
1486 if(FAILED(hres))
1487 return hres;
1488 return return_date(res, time);
1489 }
1490
1491 static HRESULT Global_Day(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1492 {
1493 FIXME("\n");
1494 return E_NOTIMPL;
1495 }
1496
1497 static HRESULT Global_Month(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1498 {
1499 FIXME("\n");
1500 return E_NOTIMPL;
1501 }
1502
1503 static HRESULT Global_Weekday(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1504 {
1505 FIXME("\n");
1506 return E_NOTIMPL;
1507 }
1508
1509 static HRESULT Global_Year(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1510 {
1511 FIXME("\n");
1512 return E_NOTIMPL;
1513 }
1514
1515 static HRESULT Global_Hour(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1516 {
1517 FIXME("\n");
1518 return E_NOTIMPL;
1519 }
1520
1521 static HRESULT Global_Minute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1522 {
1523 FIXME("\n");
1524 return E_NOTIMPL;
1525 }
1526
1527 static HRESULT Global_Second(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1528 {
1529 FIXME("\n");
1530 return E_NOTIMPL;
1531 }
1532
1533 static HRESULT Global_DateValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1534 {
1535 FIXME("\n");
1536 return E_NOTIMPL;
1537 }
1538
1539 static HRESULT Global_TimeValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1540 {
1541 FIXME("\n");
1542 return E_NOTIMPL;
1543 }
1544
1545 static HRESULT Global_DateSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1546 {
1547 FIXME("\n");
1548 return E_NOTIMPL;
1549 }
1550
1551 static HRESULT Global_TimeSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1552 {
1553 FIXME("\n");
1554 return E_NOTIMPL;
1555 }
1556
1557 static HRESULT Global_InputBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1558 {
1559 FIXME("\n");
1560 return E_NOTIMPL;
1561 }
1562
1563 static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1564 {
1565 BSTR prompt, title = NULL;
1566 int type = MB_OK;
1567 HRESULT hres;
1568
1569 TRACE("\n");
1570
1571 assert(1 <= args_cnt && args_cnt <= 5);
1572
1573 hres = to_string(args, &prompt);
1574 if(FAILED(hres))
1575 return hres;
1576
1577 if(args_cnt > 1)
1578 hres = to_int(args+1, &type);
1579
1580 if(SUCCEEDED(hres) && args_cnt > 2)
1581 hres = to_string(args+2, &title);
1582
1583 if(SUCCEEDED(hres) && args_cnt > 3) {
1584 FIXME("unsupported arg_cnt %d\n", args_cnt);
1585 hres = E_NOTIMPL;
1586 }
1587
1588 if(SUCCEEDED(hres))
1589 hres = show_msgbox(This->desc->ctx, prompt, type, title, res);
1590
1591 SysFreeString(prompt);
1592 SysFreeString(title);
1593 return hres;
1594 }
1595
1596 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1597 {
1598 IUnknown *obj;
1599 HRESULT hres;
1600
1601 TRACE("(%s)\n", debugstr_variant(arg));
1602
1603 if(V_VT(arg) != VT_BSTR) {
1604 FIXME("non-bstr arg\n");
1605 return E_INVALIDARG;
1606 }
1607
1608 obj = create_object(This->desc->ctx, V_BSTR(arg));
1609 if(!obj)
1610 return VB_E_CANNOT_CREATE_OBJ;
1611
1612 if(res) {
1613 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res));
1614 if(FAILED(hres))
1615 return hres;
1616
1617 V_VT(res) = VT_DISPATCH;
1618 }
1619
1620 IUnknown_Release(obj);
1621 return S_OK;
1622 }
1623
1624 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1625 {
1626 IBindCtx *bind_ctx;
1627 IUnknown *obj_unk;
1628 IDispatch *disp;
1629 ULONG eaten = 0;
1630 IMoniker *mon;
1631 HRESULT hres;
1632
1633 TRACE("%s %s\n", args_cnt ? debugstr_variant(args) : "", args_cnt > 1 ? debugstr_variant(args+1) : "");
1634
1635 if(args_cnt != 1 || V_VT(args) != VT_BSTR) {
1636 FIXME("unsupported args\n");
1637 return E_NOTIMPL;
1638 }
1639
1640 if(This->desc->ctx->safeopt & (INTERFACE_USES_SECURITY_MANAGER|INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
1641 WARN("blocked in current safety mode\n");
1642 return VB_E_CANNOT_CREATE_OBJ;
1643 }
1644
1645 hres = CreateBindCtx(0, &bind_ctx);
1646 if(FAILED(hres))
1647 return hres;
1648
1649 hres = MkParseDisplayName(bind_ctx, V_BSTR(args), &eaten, &mon);
1650 if(SUCCEEDED(hres)) {
1651 hres = IMoniker_BindToObject(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&obj_unk);
1652 IMoniker_Release(mon);
1653 }else {
1654 hres = MK_E_SYNTAX;
1655 }
1656 IBindCtx_Release(bind_ctx);
1657 if(FAILED(hres))
1658 return hres;
1659
1660 hres = set_object_site(This->desc->ctx, obj_unk);
1661 if(FAILED(hres)) {
1662 IUnknown_Release(obj_unk);
1663 return hres;
1664 }
1665
1666 hres = IUnknown_QueryInterface(obj_unk, &IID_IDispatch, (void**)&disp);
1667 if(SUCCEEDED(hres)) {
1668 if(res) {
1669 V_VT(res) = VT_DISPATCH;
1670 V_DISPATCH(res) = disp;
1671 }else {
1672 IDispatch_Release(disp);
1673 }
1674 }else {
1675 FIXME("object does not support IDispatch\n");
1676 }
1677
1678 return hres;
1679 }
1680
1681 static HRESULT Global_DateAdd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1682 {
1683 FIXME("\n");
1684 return E_NOTIMPL;
1685 }
1686
1687 static HRESULT Global_DateDiff(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1688 {
1689 FIXME("\n");
1690 return E_NOTIMPL;
1691 }
1692
1693 static HRESULT Global_DatePart(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1694 {
1695 FIXME("\n");
1696 return E_NOTIMPL;
1697 }
1698
1699 static HRESULT Global_TypeName(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1700 {
1701 static const WCHAR ByteW[] = {'B', 'y', 't', 'e', 0};
1702 static const WCHAR IntegerW[] = {'I', 'n', 't', 'e', 'g', 'e', 'r', 0};
1703 static const WCHAR LongW[] = {'L', 'o', 'n', 'g', 0};
1704 static const WCHAR SingleW[] = {'S', 'i', 'n', 'g', 'l', 'e', 0};
1705 static const WCHAR DoubleW[] = {'D', 'o', 'u', 'b', 'l', 'e', 0};
1706 static const WCHAR CurrencyW[] = {'C', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 0};
1707 static const WCHAR DecimalW[] = {'D', 'e', 'c', 'i', 'm', 'a', 'l', 0};
1708 static const WCHAR DateW[] = {'D', 'a', 't', 'e', 0};
1709 static const WCHAR StringW[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
1710 static const WCHAR BooleanW[] = {'B', 'o', 'o', 'l', 'e', 'a', 'n', 0};
1711 static const WCHAR EmptyW[] = {'E', 'm', 'p', 't', 'y', 0};
1712 static const WCHAR NullW[] = {'N', 'u', 'l', 'l', 0};
1713
1714 TRACE("(%s)\n", debugstr_variant(arg));
1715
1716 assert(args_cnt == 1);
1717
1718 switch(V_VT(arg)) {
1719 case VT_UI1:
1720 return return_string(res, ByteW);
1721 case VT_I2:
1722 return return_string(res, IntegerW);
1723 case VT_I4:
1724 return return_string(res, LongW);
1725 case VT_R4:
1726 return return_string(res, SingleW);
1727 case VT_R8:
1728 return return_string(res, DoubleW);
1729 case VT_CY:
1730 return return_string(res, CurrencyW);
1731 case VT_DECIMAL:
1732 return return_string(res, DecimalW);
1733 case VT_DATE:
1734 return return_string(res, DateW);
1735 case VT_BSTR:
1736 return return_string(res, StringW);
1737 case VT_BOOL:
1738 return return_string(res, BooleanW);
1739 case VT_EMPTY:
1740 return return_string(res, EmptyW);
1741 case VT_NULL:
1742 return return_string(res, NullW);
1743 default:
1744 FIXME("arg %s not supported\n", debugstr_variant(arg));
1745 return E_NOTIMPL;
1746 }
1747 }
1748
1749 static HRESULT Global_Array(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1750 {
1751 FIXME("\n");
1752 return E_NOTIMPL;
1753 }
1754
1755 static HRESULT Global_Erase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1756 {
1757 FIXME("\n");
1758 return E_NOTIMPL;
1759 }
1760
1761 static HRESULT Global_Filter(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1762 {
1763 FIXME("\n");
1764 return E_NOTIMPL;
1765 }
1766
1767 static HRESULT Global_Join(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1768 {
1769 FIXME("\n");
1770 return E_NOTIMPL;
1771 }
1772
1773 static HRESULT Global_Split(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1774 {
1775 FIXME("\n");
1776 return E_NOTIMPL;
1777 }
1778
1779 static HRESULT Global_Replace(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1780 {
1781 FIXME("\n");
1782 return E_NOTIMPL;
1783 }
1784
1785 static HRESULT Global_StrReverse(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1786 {
1787 WCHAR *ptr1, *ptr2, ch;
1788 BSTR ret;
1789 HRESULT hres;
1790
1791 TRACE("%s\n", debugstr_variant(arg));
1792
1793 hres = to_string(arg, &ret);
1794 if(FAILED(hres))
1795 return hres;
1796
1797 ptr1 = ret;
1798 ptr2 = ret + SysStringLen(ret)-1;
1799 while(ptr1 < ptr2) {
1800 ch = *ptr1;
1801 *ptr1++ = *ptr2;
1802 *ptr2-- = ch;
1803 }
1804
1805 return return_bstr(res, ret);
1806 }
1807
1808 static HRESULT Global_InStrRev(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1809 {
1810 int start, ret = 0;
1811 BSTR str1, str2;
1812 HRESULT hres;
1813
1814 TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args), debugstr_variant(args+1), args_cnt);
1815
1816 if(args_cnt > 3) {
1817 FIXME("Unsupported args\n");
1818 return E_NOTIMPL;
1819 }
1820
1821 assert(2 <= args_cnt && args_cnt <= 4);
1822
1823 if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (args_cnt > 2 && V_VT(args+2) == VT_NULL))
1824 return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
1825
1826 hres = to_string(args, &str1);
1827 if(FAILED(hres))
1828 return hres;
1829
1830 hres = to_string(args+1, &str2);
1831 if(SUCCEEDED(hres)) {
1832 if(args_cnt > 2) {
1833 hres = to_int(args+2, &start);
1834 if(SUCCEEDED(hres) && start <= 0) {
1835 FIXME("Unsupported start %d\n", start);
1836 hres = E_NOTIMPL;
1837 }
1838 }else {
1839 start = SysStringLen(str1);
1840 }
1841 } else {
1842 str2 = NULL;
1843 }
1844
1845 if(SUCCEEDED(hres)) {
1846 const WCHAR *ptr;
1847 size_t len;
1848
1849 len = SysStringLen(str2);
1850 if(start >= len && start <= SysStringLen(str1)) {
1851 for(ptr = str1+start-SysStringLen(str2); ptr >= str1; ptr--) {
1852 if(!memcmp(ptr, str2, len*sizeof(WCHAR))) {
1853 ret = ptr-str1+1;
1854 break;
1855 }
1856 }
1857 }
1858 }
1859
1860 SysFreeString(str1);
1861 SysFreeString(str2);
1862 if(FAILED(hres))
1863 return hres;
1864
1865 return return_int(res, ret);
1866 }
1867
1868 static HRESULT Global_LoadPicture(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1869 {
1870 FIXME("\n");
1871 return E_NOTIMPL;
1872 }
1873
1874 static HRESULT Global_ScriptEngine(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1875 {
1876 TRACE("%s\n", debugstr_variant(arg));
1877
1878 assert(args_cnt == 0);
1879
1880 return return_string(res, vbscriptW);
1881 }
1882
1883 static HRESULT Global_ScriptEngineMajorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1884 {
1885 TRACE("%s\n", debugstr_variant(arg));
1886
1887 assert(args_cnt == 0);
1888
1889 return return_int(res, VBSCRIPT_MAJOR_VERSION);
1890 }
1891
1892 static HRESULT Global_ScriptEngineMinorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1893 {
1894 TRACE("%s\n", debugstr_variant(arg));
1895
1896 assert(args_cnt == 0);
1897
1898 return return_int(res, VBSCRIPT_MINOR_VERSION);
1899 }
1900
1901 static HRESULT Global_ScriptEngineBuildVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1902 {
1903 TRACE("%s\n", debugstr_variant(arg));
1904
1905 assert(args_cnt == 0);
1906
1907 return return_int(res, VBSCRIPT_BUILD_VERSION);
1908 }
1909
1910 static HRESULT Global_FormatNumber(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1911 {
1912 FIXME("\n");
1913 return E_NOTIMPL;
1914 }
1915
1916 static HRESULT Global_FormatCurrency(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1917 {
1918 FIXME("\n");
1919 return E_NOTIMPL;
1920 }
1921
1922 static HRESULT Global_FormatPercent(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1923 {
1924 FIXME("\n");
1925 return E_NOTIMPL;
1926 }
1927
1928 static HRESULT Global_FormatDateTime(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1929 {
1930 FIXME("\n");
1931 return E_NOTIMPL;
1932 }
1933
1934 static HRESULT Global_WeekdayName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1935 {
1936 int weekday, first_day = 1, abbrev = 0;
1937 BSTR ret;
1938 HRESULT hres;
1939
1940 TRACE("\n");
1941
1942 assert(1 <= args_cnt && args_cnt <= 3);
1943
1944 hres = to_int(args, &weekday);
1945 if(FAILED(hres))
1946 return hres;
1947
1948 if(args_cnt > 1) {
1949 hres = to_int(args+1, &abbrev);
1950 if(FAILED(hres))
1951 return hres;
1952
1953 if(args_cnt == 3) {
1954 hres = to_int(args+2, &first_day);
1955 if(FAILED(hres))
1956 return hres;
1957 }
1958 }
1959
1960 hres = VarWeekdayName(weekday, abbrev, first_day, 0, &ret);
1961 if(FAILED(hres))
1962 return hres;
1963
1964 return return_bstr(res, ret);
1965 }
1966
1967 static HRESULT Global_MonthName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1968 {
1969 int month, abbrev = 0;
1970 BSTR ret;
1971 HRESULT hres;
1972
1973 TRACE("\n");
1974
1975 assert(args_cnt == 1 || args_cnt == 2);
1976
1977 hres = to_int(args, &month);
1978 if(FAILED(hres))
1979 return hres;
1980
1981 if(args_cnt == 2) {
1982 hres = to_int(args+1, &abbrev);
1983 if(FAILED(hres))
1984 return hres;
1985 }
1986
1987 hres = VarMonthName(month, abbrev, 0, &ret);
1988 if(FAILED(hres))
1989 return hres;
1990
1991 return return_bstr(res, ret);
1992 }
1993
1994 static HRESULT Global_Round(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1995 {
1996 double n;
1997 HRESULT hres;
1998
1999 TRACE("%s\n", debugstr_variant(arg));
2000
2001 if(!res)
2002 return S_OK;
2003
2004 switch(V_VT(arg)) {
2005 case VT_I2:
2006 case VT_I4:
2007 case VT_BOOL:
2008 *res = *arg;
2009 return S_OK;
2010 case VT_R8:
2011 n = V_R8(arg);
2012 break;
2013 default:
2014 hres = to_double(arg, &n);
2015 if(FAILED(hres))
2016 return hres;
2017 }
2018
2019 return return_double(res, round(n));
2020 }
2021
2022 static HRESULT Global_Escape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2023 {
2024 FIXME("\n");
2025 return E_NOTIMPL;
2026 }
2027
2028 static HRESULT Global_Unescape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2029 {
2030 FIXME("\n");
2031 return E_NOTIMPL;
2032 }
2033
2034 static HRESULT Global_Eval(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2035 {
2036 FIXME("\n");
2037 return E_NOTIMPL;
2038 }
2039
2040 static HRESULT Global_Execute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2041 {
2042 FIXME("\n");
2043 return E_NOTIMPL;
2044 }
2045
2046 static HRESULT Global_ExecuteGlobal(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2047 {
2048 FIXME("\n");
2049 return E_NOTIMPL;
2050 }
2051
2052 static HRESULT Global_GetRef(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
2053 {
2054 FIXME("\n");
2055 return E_NOTIMPL;
2056 }
2057
2058 static const string_constant_t vbCr = {1, {'\r'}};
2059 static const string_constant_t vbCrLf = {2, {'\r','\n'}};
2060 static const string_constant_t vbNewLine = {2, {'\r','\n'}};
2061 static const string_constant_t vbFormFeed = {1, {0xc}};
2062 static const string_constant_t vbLf = {1, {'\n'}};
2063 static const string_constant_t vbNullChar = {1};
2064 static const string_constant_t vbNullString = {0};
2065 static const string_constant_t vbTab = {1, {'\t'}};
2066 static const string_constant_t vbVerticalTab = {1, {0xb}};
2067
2068 static const builtin_prop_t global_props[] = {
2069 {DISPID_GLOBAL_VBUSESYSTEM, NULL, BP_GET, VT_I2, 0},
2070 {DISPID_GLOBAL_USESYSTEMDAYOFWEEK, NULL, BP_GET, VT_I2, 0},
2071 {DISPID_GLOBAL_VBSUNDAY, NULL, BP_GET, VT_I2, 1},
2072 {DISPID_GLOBAL_VBMONDAY, NULL, BP_GET, VT_I2, 2},
2073 {DISPID_GLOBAL_VBTUESDAY, NULL, BP_GET, VT_I2, 3},
2074 {DISPID_GLOBAL_VBWEDNESDAY, NULL, BP_GET, VT_I2, 4},
2075 {DISPID_GLOBAL_VBTHURSDAY, NULL, BP_GET, VT_I2, 5},
2076 {DISPID_GLOBAL_VBFRIDAY, NULL, BP_GET, VT_I2, 6},
2077 {DISPID_GLOBAL_VBSATURDAY, NULL, BP_GET, VT_I2, 7},
2078 {DISPID_GLOBAL_VBFIRSTJAN1, NULL, BP_GET, VT_I2, 1},
2079 {DISPID_GLOBAL_VBFIRSTFOURDAYS, NULL, BP_GET, VT_I2, 2},
2080 {DISPID_GLOBAL_VBFIRSTFULLWEEK, NULL, BP_GET, VT_I2, 3},
2081 {DISPID_GLOBAL_VBOKONLY, NULL, BP_GET, VT_I2, MB_OK},
2082 {DISPID_GLOBAL_VBOKCANCEL, NULL, BP_GET, VT_I2, MB_OKCANCEL},
2083 {DISPID_GLOBAL_VBABORTRETRYIGNORE, NULL, BP_GET, VT_I2, MB_ABORTRETRYIGNORE},
2084 {DISPID_GLOBAL_VBYESNOCANCEL, NULL, BP_GET, VT_I2, MB_YESNOCANCEL},
2085 {DISPID_GLOBAL_VBYESNO, NULL, BP_GET, VT_I2, MB_YESNO},
2086 {DISPID_GLOBAL_VBRETRYCANCEL, NULL, BP_GET, VT_I2, MB_RETRYCANCEL},
2087 {DISPID_GLOBAL_VBCRITICAL, NULL, BP_GET, VT_I2, MB_ICONHAND},
2088 {DISPID_GLOBAL_VBQUESTION, NULL, BP_GET, VT_I2, MB_ICONQUESTION},
2089 {DISPID_GLOBAL_VBEXCLAMATION, NULL, BP_GET, VT_I2, MB_ICONEXCLAMATION},
2090 {DISPID_GLOBAL_VBINFORMATION, NULL, BP_GET, VT_I2, MB_ICONASTERISK},
2091 {DISPID_GLOBAL_VBDEFAULTBUTTON1, NULL, BP_GET, VT_I2, MB_DEFBUTTON1},
2092 {DISPID_GLOBAL_VBDEFAULTBUTTON2, NULL, BP_GET, VT_I2, MB_DEFBUTTON2},
2093 {DISPID_GLOBAL_VBDEFAULTBUTTON3, NULL, BP_GET, VT_I2, MB_DEFBUTTON3},
2094 {DISPID_GLOBAL_VBDEFAULTBUTTON4, NULL, BP_GET, VT_I2, MB_DEFBUTTON4},
2095 {DISPID_GLOBAL_VBAPPLICATIONMODAL, NULL, BP_GET, VT_I2, MB_APPLMODAL},
2096 {DISPID_GLOBAL_VBSYSTEMMODAL, NULL, BP_GET, VT_I2, MB_SYSTEMMODAL},
2097 {DISPID_GLOBAL_VBOK, NULL, BP_GET, VT_I2, IDOK},
2098 {DISPID_GLOBAL_VBCANCEL, NULL, BP_GET, VT_I2, IDCANCEL},
2099 {DISPID_GLOBAL_VBABORT, NULL, BP_GET, VT_I2, IDABORT},
2100 {DISPID_GLOBAL_VBRETRY, NULL, BP_GET, VT_I2, IDRETRY},
2101 {DISPID_GLOBAL_VBIGNORE, NULL, BP_GET, VT_I2, IDIGNORE},
2102 {DISPID_GLOBAL_VBYES, NULL, BP_GET, VT_I2, IDYES},
2103 {DISPID_GLOBAL_VBNO, NULL, BP_GET, VT_I2, IDNO},
2104 {DISPID_GLOBAL_VBEMPTY, NULL, BP_GET, VT_I2, VT_EMPTY},
2105 {DISPID_GLOBAL_VBNULL, NULL, BP_GET, VT_I2, VT_NULL},
2106 {DISPID_GLOBAL_VBINTEGER, NULL, BP_GET, VT_I2, VT_I2},
2107 {DISPID_GLOBAL_VBLONG, NULL, BP_GET, VT_I2, VT_I4},
2108 {DISPID_GLOBAL_VBSINGLE, NULL, BP_GET, VT_I2, VT_R4},
2109 {DISPID_GLOBAL_VBDOUBLE, NULL, BP_GET, VT_I2, VT_R8},
2110 {DISPID_GLOBAL_VBCURRENCY, NULL, BP_GET, VT_I2, VT_CY},
2111 {DISPID_GLOBAL_VBDATE, NULL, BP_GET, VT_I2, VT_DATE},
2112 {DISPID_GLOBAL_VBSTRING, NULL, BP_GET, VT_I2, VT_BSTR},
2113 {DISPID_GLOBAL_VBOBJECT, NULL, BP_GET, VT_I2, VT_DISPATCH},
2114 {DISPID_GLOBAL_VBERROR, NULL, BP_GET, VT_I2, VT_ERROR},
2115 {DISPID_GLOBAL_VBBOOLEAN, NULL, BP_GET, VT_I2, VT_BOOL},
2116 {DISPID_GLOBAL_VBVARIANT, NULL, BP_GET, VT_I2, VT_VARIANT},
2117 {DISPID_GLOBAL_VBDATAOBJECT, NULL, BP_GET, VT_I2, VT_UNKNOWN},
2118 {DISPID_GLOBAL_VBDECIMAL, NULL, BP_GET, VT_I2, VT_DECIMAL},
2119 {DISPID_GLOBAL_VBBYTE, NULL, BP_GET, VT_I2, VT_UI1},
2120 {DISPID_GLOBAL_VBARRAY, NULL, BP_GET, VT_I2, VT_ARRAY},
2121 {DISPID_GLOBAL_VBTRUE, NULL, BP_GET, VT_I2, VARIANT_TRUE},
2122 {DISPID_GLOBAL_VBFALSE, NULL, BP_GET, VT_I2, VARIANT_FALSE},
2123 {DISPID_GLOBAL_VBUSEDEFAULT, NULL, BP_GET, VT_I2, -2},
2124 {DISPID_GLOBAL_VBBINARYCOMPARE, NULL, BP_GET, VT_I2, 0},
2125 {DISPID_GLOBAL_VBTEXTCOMPARE, NULL, BP_GET, VT_I2, 1},
2126 {DISPID_GLOBAL_VBDATABASECOMPARE, NULL, BP_GET, VT_I2, 2},
2127 {DISPID_GLOBAL_VBGENERALDATE, NULL, BP_GET, VT_I2, 0},
2128 {DISPID_GLOBAL_VBLONGDATE, NULL, BP_GET, VT_I2, 1},
2129 {DISPID_GLOBAL_VBSHORTDATE, NULL, BP_GET, VT_I2, 2},
2130 {DISPID_GLOBAL_VBLONGTIME, NULL, BP_GET, VT_I2, 3},
2131 {DISPID_GLOBAL_VBSHORTTIME, NULL, BP_GET, VT_I2, 4},
2132 {DISPID_GLOBAL_VBOBJECTERROR, NULL, BP_GET, VT_I4, 0x80040000},
2133 {DISPID_GLOBAL_VBBLACK, NULL, BP_GET, VT_I4, 0x000000},
2134 {DISPID_GLOBAL_VBBLUE, NULL, BP_GET, VT_I4, 0xff0000},
2135 {DISPID_GLOBAL_VBCYAN, NULL, BP_GET, VT_I4, 0xffff00},
2136 {DISPID_GLOBAL_VBGREEN, NULL, BP_GET, VT_I4, 0x00ff00},
2137 {DISPID_GLOBAL_VBMAGENTA, NULL, BP_GET, VT_I4, 0xff00ff},
2138 {DISPID_GLOBAL_VBRED, NULL, BP_GET, VT_I4, 0x0000ff},
2139 {DISPID_GLOBAL_VBWHITE, NULL, BP_GET, VT_I4, 0xffffff},
2140 {DISPID_GLOBAL_VBYELLOW, NULL, BP_GET, VT_I4, 0x00ffff},
2141 {DISPID_GLOBAL_VBCR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCr},
2142 {DISPID_GLOBAL_VBCRLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCrLf},
2143 {DISPID_GLOBAL_VBNEWLINE, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNewLine},
2144 {DISPID_GLOBAL_VBFORMFEED, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbFormFeed},
2145 {DISPID_GLOBAL_VBLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbLf},
2146 {DISPID_GLOBAL_VBNULLCHAR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullChar},
2147 {DISPID_GLOBAL_VBNULLSTRING, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullString},
2148 {DISPID_GLOBAL_VBTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbTab},
2149 {DISPID_GLOBAL_VBVERTICALTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbVerticalTab},
2150 {DISPID_GLOBAL_CCUR, Global_CCur, 0, 1},
2151 {DISPID_GLOBAL_CINT, Global_CInt, 0, 1},
2152 {DISPID_GLOBAL_CLNG, Global_CLng, 0, 1},
2153 {DISPID_GLOBAL_CBOOL, Global_CBool, 0, 1},
2154 {DISPID_GLOBAL_CBYTE, Global_CByte, 0, 1},
2155 {DISPID_GLOBAL_CDATE, Global_CDate, 0, 1},
2156 {DISPID_GLOBAL_CDBL, Global_CDbl, 0, 1},
2157 {DISPID_GLOBAL_CSNG, Global_CSng, 0, 1},
2158 {DISPID_GLOBAL_CSTR, Global_CStr, 0, 1},
2159 {DISPID_GLOBAL_HEX, Global_Hex, 0, 1},
2160 {DISPID_GLOBAL_OCT, Global_Oct, 0, 1},
2161 {DISPID_GLOBAL_VARTYPE, Global_VarType, 0, 1},
2162 {DISPID_GLOBAL_ISDATE, Global_IsDate, 0, 1},
2163 {DISPID_GLOBAL_ISEMPTY, Global_IsEmpty, 0, 1},
2164 {DISPID_GLOBAL_ISNULL, Global_IsNull, 0, 1},
2165 {DISPID_GLOBAL_ISNUMERIC, Global_IsNumeric, 0, 1},
2166 {DISPID_GLOBAL_ISARRAY, Global_IsArray, 0, 1},
2167 {DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1},
2168 {DISPID_GLOBAL_ATN, Global_Atn, 0, 1},
2169 {DISPID_GLOBAL_COS, Global_Cos, 0, 1},
2170 {DISPID_GLOBAL_SIN, Global_Sin, 0, 1},
2171 {DISPID_GLOBAL_TAN, Global_Tan, 0, 1},
2172 {DISPID_GLOBAL_EXP, Global_Exp, 0, 1},
2173 {DISPID_GLOBAL_LOG, Global_Log, 0, 1},
2174 {DISPID_GLOBAL_SQR, Global_Sqr, 0, 1},
2175 {DISPID_GLOBAL_RANDOMIZE, Global_Randomize, 0, 1},
2176 {DISPID_GLOBAL_RND, Global_Rnd, 0, 1},
2177 {DISPID_GLOBAL_TIMER, Global_Timer, 0, 0},
2178 {DISPID_GLOBAL_LBOUND, Global_LBound, 0, 1},
2179 {DISPID_GLOBAL_UBOUND, Global_UBound, 0, 1},
2180 {DISPID_GLOBAL_RGB, Global_RGB, 0, 3},
2181 {DISPID_GLOBAL_LEN, Global_Len, 0, 1},
2182 {DISPID_GLOBAL_LENB, Global_LenB, 0, 1},
2183 {DISPID_GLOBAL_LEFT, Global_Left, 0, 2},
2184 {DISPID_GLOBAL_LEFTB, Global_LeftB, 0, 2},
2185 {DISPID_GLOBAL_RIGHT, Global_Right, 0, 2},
2186 {DISPID_GLOBAL_RIGHTB, Global_RightB, 0, 2},
2187 {DISPID_GLOBAL_MID, Global_Mid, 0, 2, 3},
2188 {DISPID_GLOBAL_MIDB, Global_MidB, 0, 2, 3},
2189 {DISPID_GLOBAL_STRCOMP, Global_StrComp, 0, 2, 3},
2190 {DISPID_GLOBAL_LCASE, Global_LCase, 0, 1},
2191 {DISPID_GLOBAL_UCASE, Global_UCase, 0, 1},
2192 {DISPID_GLOBAL_LTRIM, Global_LTrim, 0, 1},
2193 {DISPID_GLOBAL_RTRIM, Global_RTrim, 0, 1},
2194 {DISPID_GLOBAL_TRIM, Global_Trim, 0, 1},
2195 {DISPID_GLOBAL_SPACE, Global_Space, 0, 1},
2196 {DISPID_GLOBAL_STRING, Global_String, 0, 0, 2},
2197 {DISPID_GLOBAL_INSTR, Global_InStr, 0, 2, 4},
2198 {DISPID_GLOBAL_INSTRB, Global_InStrB, 0, 3, 4},
2199 {DISPID_GLOBAL_ASCB, Global_AscB, 0, 1},
2200 {DISPID_GLOBAL_CHRB, Global_ChrB, 0, 1},
2201 {DISPID_GLOBAL_ASC, Global_Asc, 0, 1},
2202 {DISPID_GLOBAL_CHR, Global_Chr, 0, 1},
2203 {DISPID_GLOBAL_ASCW, Global_AscW, 0, 1},
2204 {DISPID_GLOBAL_CHRW, Global_ChrW, 0, 1},
2205 {DISPID_GLOBAL_ABS, Global_Abs, 0, 1},
2206 {DISPID_GLOBAL_FIX, Global_Fix, 0, 1},
2207 {DISPID_GLOBAL_INT, Global_Int, 0, 1},
2208 {DISPID_GLOBAL_SGN, Global_Sgn, 0, 1},
2209 {DISPID_GLOBAL_NOW, Global_Now, 0, 0},
2210 {DISPID_GLOBAL_DATE, Global_Date, 0, 0},
2211 {DISPID_GLOBAL_TIME, Global_Time, 0, 0},
2212 {DISPID_GLOBAL_DAY, Global_Day, 0, 1},
2213 {DISPID_GLOBAL_MONTH, Global_Month, 0, 1},
2214 {DISPID_GLOBAL_WEEKDAY, Global_Weekday, 0, 1, 2},
2215 {DISPID_GLOBAL_YEAR, Global_Year, 0, 1},
2216 {DISPID_GLOBAL_HOUR, Global_Hour, 0, 1},
2217 {DISPID_GLOBAL_MINUTE, Global_Minute, 0, 1},
2218 {DISPID_GLOBAL_SECOND, Global_Second, 0, 1},
2219 {DISPID_GLOBAL_DATEVALUE, Global_DateValue, 0, 1},
2220 {DISPID_GLOBAL_TIMEVALUE, Global_TimeValue, 0, 1},
2221 {DISPID_GLOBAL_DATESERIAL, Global_DateSerial, 0, 3},
2222 {DISPID_GLOBAL_TIMESERIAL, Global_TimeSerial, 0, 3},
2223 {DISPID_GLOBAL_INPUTBOX, Global_InputBox, 0, 1, 7},
2224 {DISPID_GLOBAL_MSGBOX, Global_MsgBox, 0, 1, 5},
2225 {DISPID_GLOBAL_CREATEOBJECT, Global_CreateObject, 0, 1},
2226 {DISPID_GLOBAL_GETOBJECT, Global_GetObject, 0, 0, 2},
2227 {DISPID_GLOBAL_DATEADD, Global_DateAdd, 0, 3},
2228 {DISPID_GLOBAL_DATEDIFF, Global_DateDiff, 0, 3, 5},
2229 {DISPID_GLOBAL_DATEPART, Global_DatePart, 0, 2, 4},
2230 {DISPID_GLOBAL_TYPENAME, Global_TypeName, 0, 1},
2231 {DISPID_GLOBAL_ARRAY, Global_Array, 0, 1},
2232 {DISPID_GLOBAL_ERASE, Global_Erase, 0, 1},
2233 {DISPID_GLOBAL_FILTER, Global_Filter, 0, 2, 4},
2234 {DISPID_GLOBAL_JOIN, Global_Join, 0, 1, 2},
2235 {DISPID_GLOBAL_SPLIT, Global_Split, 0, 1, 4},
2236 {DISPID_GLOBAL_REPLACE, Global_Replace, 0, 3, 6},
2237 {DISPID_GLOBAL_STRREVERSE, Global_StrReverse, 0, 1},
2238 {DISPID_GLOBAL_INSTRREV, Global_InStrRev, 0, 2, 4},
2239 {DISPID_GLOBAL_LOADPICTURE, Global_LoadPicture, 0, 1},
2240 {DISPID_GLOBAL_SCRIPTENGINE, Global_ScriptEngine, 0, 0},
2241 {DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION, Global_ScriptEngineMajorVersion, 0, 0},
2242 {DISPID_GLOBAL_SCRIPTENGINEMINORVERSION, Global_ScriptEngineMinorVersion, 0, 0},
2243 {DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION, Global_ScriptEngineBuildVersion, 0, 0},
2244 {DISPID_GLOBAL_FORMATNUMBER, Global_FormatNumber, 0, 1, 5},
2245 {DISPID_GLOBAL_FORMATCURRENCY, Global_FormatCurrency, 0, 1, 5},
2246 {DISPID_GLOBAL_FORMATPERCENT, Global_FormatPercent, 0, 1, 5},
2247 {DISPID_GLOBAL_FORMATDATETIME, Global_FormatDateTime, 0, 1, 2},
2248 {DISPID_GLOBAL_WEEKDAYNAME, Global_WeekdayName, 0, 1, 3},
2249 {DISPID_GLOBAL_MONTHNAME, Global_MonthName, 0, 1, 2},
2250 {DISPID_GLOBAL_ROUND, Global_Round, 0, 1, 2},
2251 {DISPID_GLOBAL_ESCAPE, Global_Escape, 0, 1},
2252 {DISPID_GLOBAL_UNESCAPE, Global_Unescape, 0, 1},
2253 {DISPID_GLOBAL_EVAL, Global_Eval, 0, 1},
2254 {DISPID_GLOBAL_EXECUTE, Global_Execute, 0, 1},
2255 {DISPID_GLOBAL_EXECUTEGLOBAL, Global_ExecuteGlobal, 0, 1},
2256 {DISPID_GLOBAL_GETREF, Global_GetRef, 0, 1},
2257 {DISPID_GLOBAL_VBMSGBOXHELPBUTTON, NULL, BP_GET, VT_I4, MB_HELP},
2258 {DISPID_GLOBAL_VBMSGBOXSETFOREGROUND, NULL, BP_GET, VT_I4, MB_SETFOREGROUND},
2259 {DISPID_GLOBAL_VBMSGBOXRIGHT, NULL, BP_GET, VT_I4, MB_RIGHT},
2260 {DISPID_GLOBAL_VBMSGBOXRTLREADING, NULL, BP_GET, VT_I4, MB_RTLREADING}
2261 };
2262
2263 static HRESULT Err_Description(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2264 {
2265 FIXME("\n");
2266 return E_NOTIMPL;
2267 }
2268
2269 static HRESULT Err_HelpContext(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2270 {
2271 FIXME("\n");
2272 return E_NOTIMPL;
2273 }
2274
2275 static HRESULT Err_HelpFile(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2276 {
2277 FIXME("\n");
2278 return E_NOTIMPL;
2279 }
2280
2281 static HRESULT Err_Number(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2282 {
2283 HRESULT hres;
2284
2285 TRACE("\n");
2286
2287 if(!This->desc)
2288 return E_UNEXPECTED;
2289
2290 if(args_cnt) {
2291 FIXME("setter not implemented\n");
2292 return E_NOTIMPL;
2293 }
2294
2295 hres = This->desc->ctx->err_number;
2296 return return_int(res, HRESULT_FACILITY(hres) == FACILITY_VBS ? HRESULT_CODE(hres) : hres);
2297 }
2298
2299 static HRESULT Err_Source(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2300 {
2301 FIXME("\n");
2302 return E_NOTIMPL;
2303 }
2304
2305 static HRESULT Err_Clear(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2306 {
2307 TRACE("\n");
2308
2309 if(!This->desc)
2310 return E_UNEXPECTED;
2311
2312 This->desc->ctx->err_number = S_OK;
2313 return S_OK;
2314 }
2315
2316 static HRESULT Err_Raise(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
2317 {
2318 FIXME("\n");
2319 return E_NOTIMPL;
2320 }
2321
2322 static const builtin_prop_t err_props[] = {
2323 {DISPID_ERR_DESCRIPTION, Err_Description, BP_GETPUT},
2324 {DISPID_ERR_HELPCONTEXT, Err_HelpContext, BP_GETPUT},
2325 {DISPID_ERR_HELPFILE, Err_HelpFile, BP_GETPUT},
2326 {DISPID_ERR_NUMBER, Err_Number, BP_GETPUT},
2327 {DISPID_ERR_SOURCE, Err_Source, BP_GETPUT},
2328 {DISPID_ERR_CLEAR, Err_Clear},
2329 {DISPID_ERR_RAISE, Err_Raise, 0, 5},
2330 };
2331
2332 HRESULT init_global(script_ctx_t *ctx)
2333 {
2334 HRESULT hres;
2335
2336 ctx->global_desc.ctx = ctx;
2337 ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
2338 ctx->global_desc.builtin_props = global_props;
2339
2340 hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
2341 if(FAILED(hres))
2342 return hres;
2343
2344 hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
2345 if(FAILED(hres))
2346 return hres;
2347
2348 hres = create_script_disp(ctx, &ctx->script_obj);
2349 if(FAILED(hres))
2350 return hres;
2351
2352 ctx->err_desc.ctx = ctx;
2353 ctx->err_desc.builtin_prop_cnt = sizeof(err_props)/sizeof(*err_props);
2354 ctx->err_desc.builtin_props = err_props;
2355
2356 hres = get_typeinfo(ErrObj_tid, &ctx->err_desc.typeinfo);
2357 if(FAILED(hres))
2358 return hres;
2359
2360 return create_vbdisp(&ctx->err_desc, &ctx->err_obj);
2361 }