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