Sync with trunk rev.61910 to get latest improvements and bugfixes.
[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 "vbscript.h"
20
21 #include <math.h>
22 #include <mshtmhst.h>
23
24 #define round(x) (((x) < 0) ? (int)((x) - 0.5) : (int)((x) + 0.5))
25
26 #define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
27 #define VB_E_MK_PARSE_ERROR 0x800a01b0
28
29 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
30 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
31 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
32
33 static const WCHAR emptyW[] = {0};
34 static const WCHAR vbscriptW[] = {'V','B','S','c','r','i','p','t',0};
35
36 static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
37 {
38 IInternetHostSecurityManager *secmgr;
39 IServiceProvider *sp;
40 HRESULT hres;
41
42 if(!ctx->site)
43 return NULL;
44
45 if(ctx->secmgr)
46 return ctx->secmgr;
47
48 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
49 if(FAILED(hres))
50 return NULL;
51
52 hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
53 (void**)&secmgr);
54 IServiceProvider_Release(sp);
55 if(FAILED(hres))
56 return NULL;
57
58 return ctx->secmgr = secmgr;
59 }
60
61 static HRESULT return_string(VARIANT *res, const WCHAR *str)
62 {
63 BSTR ret;
64
65 if(!res)
66 return S_OK;
67
68 ret = SysAllocString(str);
69 if(!ret)
70 return E_OUTOFMEMORY;
71
72 V_VT(res) = VT_BSTR;
73 V_BSTR(res) = ret;
74 return S_OK;
75 }
76
77 static HRESULT return_bstr(VARIANT *res, BSTR str)
78 {
79 if(res) {
80 V_VT(res) = VT_BSTR;
81 V_BSTR(res) = str;
82 }else {
83 SysFreeString(str);
84 }
85 return S_OK;
86 }
87
88 static HRESULT return_short(VARIANT *res, short val)
89 {
90 if(res) {
91 V_VT(res) = VT_I2;
92 V_I2(res) = val;
93 }
94
95 return S_OK;
96 }
97
98 static HRESULT return_int(VARIANT *res, int val)
99 {
100 if((short)val == val)
101 return return_short(res, val);
102
103 if(res) {
104 V_VT(res) = VT_I4;
105 V_I4(res) = val;
106 }
107
108 return S_OK;
109 }
110
111 static HRESULT return_bool(VARIANT *res, int val)
112 {
113 if(res) {
114 V_VT(res) = VT_BOOL;
115 V_BOOL(res) = val != 0 ? VARIANT_TRUE : VARIANT_FALSE;
116 }
117
118 return S_OK;
119 }
120
121 static inline HRESULT return_double(VARIANT *res, double val)
122 {
123 if(res) {
124 V_VT(res) = VT_R8;
125 V_R8(res) = val;
126 }
127
128 return S_OK;
129 }
130
131 static inline HRESULT return_null(VARIANT *res)
132 {
133 if(res)
134 V_VT(res) = VT_NULL;
135 return S_OK;
136 }
137
138 static inline HRESULT return_date(VARIANT *res, double date)
139 {
140 if(res) {
141 V_VT(res) = VT_DATE;
142 V_DATE(res) = date;
143 }
144 return S_OK;
145 }
146
147 static HRESULT to_int(VARIANT *v, int *ret)
148 {
149 switch(V_VT(v)) {
150 case VT_I2:
151 *ret = V_I2(v);
152 break;
153 case VT_I4:
154 *ret = V_I4(v);
155 break;
156 case VT_R8: {
157 double n = floor(V_R8(v)+0.5);
158 INT32 i;
159
160 if(!is_int32(n)) {
161 FIXME("%lf is out of int range\n", n);
162 return E_FAIL;
163 }
164
165 /* Round half to even */
166 i = n;
167 if(i%2 && n-V_R8(v) == 0.5)
168 i--;
169
170 *ret = i;
171 break;
172 }
173 case VT_BOOL:
174 *ret = V_BOOL(v) ? -1 : 0;
175 break;
176 default:
177 FIXME("not supported %s\n", debugstr_variant(v));
178 return E_NOTIMPL;
179 }
180
181 return S_OK;
182 }
183
184 static HRESULT to_double(VARIANT *v, double *ret)
185 {
186 switch(V_VT(v)) {
187 case VT_I2:
188 *ret = V_I2(v);
189 break;
190 case VT_I4:
191 *ret = V_I4(v);
192 break;
193 case VT_R4:
194 *ret = V_R4(v);
195 break;
196 case VT_R8:
197 *ret = V_R8(v);
198 break;
199 case VT_BSTR: {
200 VARIANT dst;
201 HRESULT hres;
202
203 V_VT(&dst) = VT_EMPTY;
204 hres = VariantChangeType(&dst, v, VARIANT_LOCALBOOL, VT_R8);
205 if(FAILED(hres))
206 return hres;
207 *ret = V_R8(&dst);
208 break;
209 }
210 default:
211 FIXME("arg %s not supported\n", debugstr_variant(v));
212 return E_NOTIMPL;
213 }
214
215 return S_OK;
216 }
217
218 static HRESULT to_string(VARIANT *v, BSTR *ret)
219 {
220 VARIANT dst;
221 HRESULT hres;
222
223 V_VT(&dst) = VT_EMPTY;
224 hres = VariantChangeType(&dst, v, VARIANT_LOCALBOOL, VT_BSTR);
225 if(FAILED(hres))
226 return hres;
227
228 *ret = V_BSTR(&dst);
229 return S_OK;
230 }
231
232 static HRESULT set_object_site(script_ctx_t *ctx, IUnknown *obj)
233 {
234 IObjectWithSite *obj_site;
235 IUnknown *ax_site;
236 HRESULT hres;
237
238 hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
239 if(FAILED(hres))
240 return S_OK;
241
242 ax_site = create_ax_site(ctx);
243 if(ax_site)
244 hres = IObjectWithSite_SetSite(obj_site, ax_site);
245 else
246 hres = E_OUTOFMEMORY;
247 IUnknown_Release(ax_site);
248 IObjectWithSite_Release(obj_site);
249 return hres;
250 }
251
252 static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
253 {
254 IInternetHostSecurityManager *secmgr = NULL;
255 struct CONFIRMSAFETY cs;
256 IClassFactoryEx *cfex;
257 IClassFactory *cf;
258 DWORD policy_size;
259 BYTE *bpolicy;
260 IUnknown *obj;
261 DWORD policy;
262 GUID guid;
263 HRESULT hres;
264
265 hres = CLSIDFromProgID(progid, &guid);
266 if(FAILED(hres))
267 return NULL;
268
269 TRACE("GUID %s\n", debugstr_guid(&guid));
270
271 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
272 secmgr = get_sec_mgr(ctx);
273 if(!secmgr)
274 return NULL;
275
276 policy = 0;
277 hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN,
278 (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0);
279 if(FAILED(hres) || policy != URLPOLICY_ALLOW)
280 return NULL;
281 }
282
283 hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
284 if(FAILED(hres))
285 return NULL;
286
287 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
288 if(SUCCEEDED(hres)) {
289 FIXME("Use IClassFactoryEx\n");
290 IClassFactoryEx_Release(cfex);
291 }
292
293 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
294 if(FAILED(hres))
295 return NULL;
296
297 if(secmgr) {
298 cs.clsid = guid;
299 cs.pUnk = obj;
300 cs.dwFlags = 0;
301 hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
302 &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
303 if(SUCCEEDED(hres)) {
304 policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW;
305 CoTaskMemFree(bpolicy);
306 }
307
308 if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
309 IUnknown_Release(obj);
310 return NULL;
311 }
312 }
313
314 hres = set_object_site(ctx, obj);
315 if(FAILED(hres)) {
316 IUnknown_Release(obj);
317 return NULL;
318 }
319
320 return obj;
321 }
322
323 static HRESULT show_msgbox(script_ctx_t *ctx, BSTR prompt, VARIANT *res)
324 {
325 SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_ALLOW;
326 IActiveScriptSiteUIControl *ui_control;
327 IActiveScriptSiteWindow *acts_window;
328 const WCHAR *title;
329 HWND hwnd = NULL;
330 int ret;
331 HRESULT hres;
332
333 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteUIControl, (void**)&ui_control);
334 if(SUCCEEDED(hres)) {
335 hres = IActiveScriptSiteUIControl_GetUIBehavior(ui_control, SCRIPTUICITEM_MSGBOX, &uic_handling);
336 IActiveScriptSiteUIControl_Release(ui_control);
337 if(FAILED(hres))
338 uic_handling = SCRIPTUICHANDLING_ALLOW;
339 }
340
341 switch(uic_handling) {
342 case SCRIPTUICHANDLING_ALLOW:
343 break;
344 case SCRIPTUICHANDLING_NOUIDEFAULT:
345 return return_short(res, 0);
346 default:
347 FIXME("blocked\n");
348 return E_FAIL;
349 }
350
351 title = (ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) ? vbscriptW : emptyW;
352
353 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IActiveScriptSiteWindow, (void**)&acts_window);
354 if(FAILED(hres)) {
355 FIXME("No IActiveScriptSiteWindow\n");
356 return hres;
357 }
358
359 hres = IActiveScriptSiteWindow_GetWindow(acts_window, &hwnd);
360 if(SUCCEEDED(hres)) {
361 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, FALSE);
362 if(SUCCEEDED(hres)) {
363 ret = MessageBoxW(hwnd, prompt, title, MB_OK);
364 hres = IActiveScriptSiteWindow_EnableModeless(acts_window, TRUE);
365 }
366 }
367
368 IActiveScriptSiteWindow_Release(acts_window);
369 if(FAILED(hres)) {
370 FIXME("failed: %08x\n", hres);
371 return hres;
372 }
373
374 return return_short(res, ret);
375 }
376
377 static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
378 {
379 FIXME("\n");
380 return E_NOTIMPL;
381 }
382
383 static HRESULT Global_CInt(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
384 {
385 int val;
386 HRESULT hres;
387
388 TRACE("%s\n", debugstr_variant(arg));
389
390 assert(args_cnt == 1);
391
392 hres = to_int(arg, &val);
393 if(FAILED(hres))
394 return hres;
395
396 return return_int(res, val);
397 }
398
399 static HRESULT Global_CLng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
400 {
401 FIXME("\n");
402 return E_NOTIMPL;
403 }
404
405 static HRESULT Global_CBool(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
406 {
407 int val;
408 TRACE("%s\n", debugstr_variant(arg));
409
410 assert(args_cnt == 1);
411
412 switch(V_VT(arg)) {
413 case VT_I2:
414 val = V_I2(arg);
415 break;
416 case VT_I4:
417 val = V_I4(arg);
418 break;
419 case VT_R4:
420 val = V_R4(arg) > 0.0 || V_R4(arg) < 0.0;
421 break;
422 case VT_R8:
423 val = V_R8(arg) > 0.0 || V_R8(arg) < 0.0;
424 break;
425 default:
426 ERR("Not a numeric value: %s\n", debugstr_variant(arg));
427 return E_FAIL;
428 }
429
430 return return_bool(res, val);
431 }
432
433 static HRESULT Global_CByte(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
434 {
435 FIXME("\n");
436 return E_NOTIMPL;
437 }
438
439 static HRESULT Global_CDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
440 {
441 FIXME("\n");
442 return E_NOTIMPL;
443 }
444
445 static HRESULT Global_CDbl(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
446 {
447 FIXME("\n");
448 return E_NOTIMPL;
449 }
450
451 static HRESULT Global_CSng(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
452 {
453 FIXME("\n");
454 return E_NOTIMPL;
455 }
456
457 static HRESULT Global_CStr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
458 {
459 BSTR str;
460 HRESULT hres;
461
462 TRACE("%s\n", debugstr_variant(arg));
463
464 hres = to_string(arg, &str);
465 if(FAILED(hres))
466 return hres;
467
468 return return_bstr(res, str);
469 }
470
471 static inline WCHAR hex_char(unsigned n)
472 {
473 return n < 10 ? '0'+n : 'A'+n-10;
474 }
475
476 static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
477 {
478 WCHAR buf[17], *ptr;
479 DWORD n;
480
481 TRACE("%s\n", debugstr_variant(arg));
482
483 switch(V_VT(arg)) {
484 case VT_I2:
485 n = (WORD)V_I2(arg);
486 break;
487 case VT_I4:
488 n = V_I4(arg);
489 break;
490 case VT_EMPTY:
491 n = 0;
492 break;
493 case VT_NULL:
494 if(res)
495 V_VT(res) = VT_NULL;
496 return S_OK;
497 default:
498 FIXME("unsupported type %s\n", debugstr_variant(arg));
499 return E_NOTIMPL;
500 }
501
502 buf[16] = 0;
503 ptr = buf+15;
504
505 if(n) {
506 do {
507 *ptr-- = hex_char(n & 0xf);
508 n >>= 4;
509 }while(n);
510 ptr++;
511 }else {
512 *ptr = '0';
513 }
514
515 return return_string(res, ptr);
516 }
517
518 static HRESULT Global_Oct(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
519 {
520 FIXME("\n");
521 return E_NOTIMPL;
522 }
523
524 static HRESULT Global_VarType(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
525 {
526 FIXME("\n");
527 return E_NOTIMPL;
528 }
529
530 static HRESULT Global_IsDate(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
531 {
532 FIXME("\n");
533 return E_NOTIMPL;
534 }
535
536 static HRESULT Global_IsEmpty(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
537 {
538 TRACE("(%s)\n", debugstr_variant(arg));
539
540 assert(args_cnt == 1);
541
542 if(res) {
543 V_VT(res) = VT_BOOL;
544 V_BOOL(res) = V_VT(arg) == VT_EMPTY ? VARIANT_TRUE : VARIANT_FALSE;
545 }
546 return S_OK;
547 }
548
549 static HRESULT Global_IsNull(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
550 {
551 TRACE("(%s)\n", debugstr_variant(arg));
552
553 assert(args_cnt == 1);
554
555 if(res) {
556 V_VT(res) = VT_BOOL;
557 V_BOOL(res) = V_VT(arg) == VT_NULL ? VARIANT_TRUE : VARIANT_FALSE;
558 }
559 return S_OK;
560 }
561
562 static HRESULT Global_IsNumeric(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
563 {
564 FIXME("\n");
565 return E_NOTIMPL;
566 }
567
568 static HRESULT Global_IsArray(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
569 {
570 FIXME("\n");
571 return E_NOTIMPL;
572 }
573
574 static HRESULT Global_IsObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
575 {
576 TRACE("(%s)\n", debugstr_variant(arg));
577
578 assert(args_cnt == 1);
579
580 if(res) {
581 V_VT(res) = VT_BOOL;
582 V_BOOL(res) = V_VT(arg) == VT_DISPATCH ? VARIANT_TRUE : VARIANT_FALSE;
583 }
584 return S_OK;
585 }
586
587 static HRESULT Global_Ant(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
588 {
589 FIXME("\n");
590 return E_NOTIMPL;
591 }
592
593 static HRESULT Global_Cos(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
594 {
595 FIXME("\n");
596 return E_NOTIMPL;
597 }
598
599 static HRESULT Global_Sin(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
600 {
601 FIXME("\n");
602 return E_NOTIMPL;
603 }
604
605 static HRESULT Global_Tan(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
606 {
607 FIXME("\n");
608 return E_NOTIMPL;
609 }
610
611 static HRESULT Global_Exp(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
612 {
613 FIXME("\n");
614 return E_NOTIMPL;
615 }
616
617 static HRESULT Global_Log(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
618 {
619 FIXME("\n");
620 return E_NOTIMPL;
621 }
622
623 static HRESULT Global_Sqr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
624 {
625 FIXME("\n");
626 return E_NOTIMPL;
627 }
628
629 static HRESULT Global_Randomize(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
630 {
631 FIXME("\n");
632 return E_NOTIMPL;
633 }
634
635 static HRESULT Global_Rnd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
636 {
637 FIXME("\n");
638 return E_NOTIMPL;
639 }
640
641 static HRESULT Global_Timer(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
642 {
643 FIXME("\n");
644 return E_NOTIMPL;
645 }
646
647 static HRESULT Global_LBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
648 {
649 FIXME("\n");
650 return E_NOTIMPL;
651 }
652
653 static HRESULT Global_UBound(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
654 {
655 FIXME("\n");
656 return E_NOTIMPL;
657 }
658
659 static HRESULT Global_RGB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
660 {
661 FIXME("\n");
662 return E_NOTIMPL;
663 }
664
665 static HRESULT Global_Len(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
666 {
667 DWORD len;
668 HRESULT hres;
669
670 TRACE("%s\n", debugstr_variant(arg));
671
672 if(V_VT(arg) == VT_NULL)
673 return return_null(res);
674
675 if(V_VT(arg) != VT_BSTR) {
676 BSTR str;
677
678 hres = to_string(arg, &str);
679 if(FAILED(hres))
680 return hres;
681
682 len = SysStringLen(str);
683 SysFreeString(str);
684 }else {
685 len = SysStringLen(V_BSTR(arg));
686 }
687
688 return return_int(res, len);
689 }
690
691 static HRESULT Global_LenB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
692 {
693 FIXME("\n");
694 return E_NOTIMPL;
695 }
696
697 static HRESULT Global_Left(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
698 {
699 BSTR str, ret, conv_str = NULL;
700 int len, str_len;
701 HRESULT hres;
702
703 TRACE("(%s %s)\n", debugstr_variant(args+1), debugstr_variant(args));
704
705 if(V_VT(args) == VT_BSTR) {
706 str = V_BSTR(args);
707 }else {
708 hres = to_string(args, &conv_str);
709 if(FAILED(hres))
710 return hres;
711 str = conv_str;
712 }
713
714 hres = to_int(args+1, &len);
715 if(FAILED(hres))
716 return hres;
717
718 if(len < 0) {
719 FIXME("len = %d\n", len);
720 return E_FAIL;
721 }
722
723 str_len = SysStringLen(str);
724 if(len > str_len)
725 len = str_len;
726
727 ret = SysAllocStringLen(str, len);
728 SysFreeString(conv_str);
729 if(!ret)
730 return E_OUTOFMEMORY;
731
732 return return_bstr(res, ret);
733 }
734
735 static HRESULT Global_LeftB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
736 {
737 FIXME("\n");
738 return E_NOTIMPL;
739 }
740
741 static HRESULT Global_Right(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
742 {
743 BSTR str, ret, conv_str = NULL;
744 int len, str_len;
745 HRESULT hres;
746
747 TRACE("(%s %s)\n", debugstr_variant(args), debugstr_variant(args+1));
748
749 if(V_VT(args+1) == VT_BSTR) {
750 str = V_BSTR(args);
751 }else {
752 hres = to_string(args, &conv_str);
753 if(FAILED(hres))
754 return hres;
755 str = conv_str;
756 }
757
758 hres = to_int(args+1, &len);
759 if(FAILED(hres))
760 return hres;
761
762 if(len < 0) {
763 FIXME("len = %d\n", len);
764 return E_FAIL;
765 }
766
767 str_len = SysStringLen(str);
768 if(len > str_len)
769 len = str_len;
770
771 ret = SysAllocStringLen(str+str_len-len, len);
772 SysFreeString(conv_str);
773 if(!ret)
774 return E_OUTOFMEMORY;
775
776 return return_bstr(res, ret);
777 }
778
779 static HRESULT Global_RightB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
780 {
781 FIXME("\n");
782 return E_NOTIMPL;
783 }
784
785 static HRESULT Global_Mid(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
786 {
787 int len = -1, start, str_len;
788 BSTR str;
789 HRESULT hres;
790
791 TRACE("(%s %s ...)\n", debugstr_variant(args), debugstr_variant(args+1));
792
793 assert(args_cnt == 2 || args_cnt == 3);
794
795 if(V_VT(args) != VT_BSTR) {
796 FIXME("args[0] = %s\n", debugstr_variant(args));
797 return E_NOTIMPL;
798 }
799
800 str = V_BSTR(args);
801
802 hres = to_int(args+1, &start);
803 if(FAILED(hres))
804 return hres;
805
806 if(args_cnt == 3) {
807 hres = to_int(args+2, &len);
808 if(FAILED(hres))
809 return hres;
810
811 if(len < 0) {
812 FIXME("len = %d\n", len);
813 return E_FAIL;
814 }
815 }
816
817
818 str_len = SysStringLen(str);
819 start--;
820 if(start > str_len)
821 start = str_len;
822
823 if(len == -1)
824 len = str_len-start;
825 else if(len > str_len-start)
826 len = str_len-start;
827
828 if(res) {
829 V_VT(res) = VT_BSTR;
830 V_BSTR(res) = SysAllocStringLen(str+start, len);
831 if(!V_BSTR(res))
832 return E_OUTOFMEMORY;
833 }
834
835 return S_OK;
836 }
837
838 static HRESULT Global_MidB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
839 {
840 FIXME("\n");
841 return E_NOTIMPL;
842 }
843
844 static HRESULT Global_StrComp(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
845 {
846 FIXME("\n");
847 return E_NOTIMPL;
848 }
849
850 static HRESULT Global_LCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
851 {
852 BSTR str;
853 HRESULT hres;
854
855 TRACE("%s\n", debugstr_variant(arg));
856
857 if(V_VT(arg) == VT_NULL) {
858 if(res)
859 V_VT(res) = VT_NULL;
860 return S_OK;
861 }
862
863 hres = to_string(arg, &str);
864 if(FAILED(hres))
865 return hres;
866
867 if(res) {
868 WCHAR *ptr;
869
870 for(ptr = str; *ptr; ptr++)
871 *ptr = tolowerW(*ptr);
872
873 V_VT(res) = VT_BSTR;
874 V_BSTR(res) = str;
875 }else {
876 SysFreeString(str);
877 }
878 return S_OK;
879 }
880
881 static HRESULT Global_UCase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
882 {
883 BSTR str;
884 HRESULT hres;
885
886 TRACE("%s\n", debugstr_variant(arg));
887
888 if(V_VT(arg) == VT_NULL) {
889 if(res)
890 V_VT(res) = VT_NULL;
891 return S_OK;
892 }
893
894 hres = to_string(arg, &str);
895 if(FAILED(hres))
896 return hres;
897
898 if(res) {
899 WCHAR *ptr;
900
901 for(ptr = str; *ptr; ptr++)
902 *ptr = toupperW(*ptr);
903
904 V_VT(res) = VT_BSTR;
905 V_BSTR(res) = str;
906 }else {
907 SysFreeString(str);
908 }
909 return S_OK;
910 }
911
912 static HRESULT Global_LTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
913 {
914 BSTR str, conv_str = NULL;
915 WCHAR *ptr;
916 HRESULT hres;
917
918 TRACE("%s\n", debugstr_variant(arg));
919
920 if(V_VT(arg) == VT_BSTR) {
921 str = V_BSTR(arg);
922 }else {
923 hres = to_string(arg, &conv_str);
924 if(FAILED(hres))
925 return hres;
926 str = conv_str;
927 }
928
929 for(ptr = str; *ptr && isspaceW(*ptr); ptr++);
930
931 str = SysAllocString(ptr);
932 SysFreeString(conv_str);
933 if(!str)
934 return E_OUTOFMEMORY;
935
936 return return_bstr(res, str);
937 }
938
939 static HRESULT Global_RTrim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
940 {
941 BSTR str, conv_str = NULL;
942 WCHAR *ptr;
943 HRESULT hres;
944
945 TRACE("%s\n", debugstr_variant(arg));
946
947 if(V_VT(arg) == VT_BSTR) {
948 str = V_BSTR(arg);
949 }else {
950 hres = to_string(arg, &conv_str);
951 if(FAILED(hres))
952 return hres;
953 str = conv_str;
954 }
955
956 for(ptr = str+SysStringLen(str); ptr-1 > str && isspaceW(*(ptr-1)); ptr--);
957
958 str = SysAllocStringLen(str, ptr-str);
959 SysFreeString(conv_str);
960 if(!str)
961 return E_OUTOFMEMORY;
962
963 return return_bstr(res, str);
964 }
965
966 static HRESULT Global_Trim(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
967 {
968 BSTR str, conv_str = NULL;
969 WCHAR *begin_ptr, *end_ptr;
970 HRESULT hres;
971
972 TRACE("%s\n", debugstr_variant(arg));
973
974 if(V_VT(arg) == VT_BSTR) {
975 str = V_BSTR(arg);
976 }else {
977 hres = to_string(arg, &conv_str);
978 if(FAILED(hres))
979 return hres;
980 str = conv_str;
981 }
982
983 for(begin_ptr = str; *begin_ptr && isspaceW(*begin_ptr); begin_ptr++);
984 for(end_ptr = str+SysStringLen(str); end_ptr-1 > begin_ptr && isspaceW(*(end_ptr-1)); end_ptr--);
985
986 str = SysAllocStringLen(begin_ptr, end_ptr-begin_ptr);
987 SysFreeString(conv_str);
988 if(!str)
989 return E_OUTOFMEMORY;
990
991 return return_bstr(res, str);
992 }
993
994 static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
995 {
996 BSTR str;
997 int n, i;
998 HRESULT hres;
999
1000 TRACE("%s\n", debugstr_variant(arg));
1001
1002 hres = to_int(arg, &n);
1003 if(FAILED(hres))
1004 return hres;
1005
1006 if(n < 0) {
1007 FIXME("n = %d\n", n);
1008 return E_NOTIMPL;
1009 }
1010
1011 if(!res)
1012 return S_OK;
1013
1014 str = SysAllocStringLen(NULL, n);
1015 if(!str)
1016 return E_OUTOFMEMORY;
1017
1018 for(i=0; i<n; i++)
1019 str[i] = ' ';
1020
1021 V_VT(res) = VT_BSTR;
1022 V_BSTR(res) = str;
1023 return S_OK;
1024 }
1025
1026 static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1027 {
1028 FIXME("\n");
1029 return E_NOTIMPL;
1030 }
1031
1032 static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1033 {
1034 VARIANT *startv, *str1v, *str2v;
1035 BSTR str1, str2;
1036 int start, ret;
1037 HRESULT hres;
1038
1039 TRACE("\n");
1040
1041 assert(2 <= args_cnt && args_cnt <= 4);
1042
1043 switch(args_cnt) {
1044 case 2:
1045 startv = NULL;
1046 str1v = args;
1047 str2v = args+1;
1048 break;
1049 case 3:
1050 startv = args;
1051 str1v = args+1;
1052 str2v = args+2;
1053 break;
1054 case 4:
1055 FIXME("unsupported compare argument %s\n", debugstr_variant(args));
1056 return E_NOTIMPL;
1057 DEFAULT_UNREACHABLE;
1058 }
1059
1060 if(startv) {
1061 hres = to_int(startv, &start);
1062 if(FAILED(hres))
1063 return hres;
1064 if(--start < 0) {
1065 FIXME("start %d\n", start);
1066 return E_FAIL;
1067 }
1068 }else {
1069 start = 0;
1070 }
1071
1072 if(V_VT(str1v) == VT_NULL || V_VT(str2v) == VT_NULL)
1073 return return_null(res);
1074
1075 if(V_VT(str1v) != VT_BSTR) {
1076 FIXME("Unsupported str1 type %s\n", debugstr_variant(str1v));
1077 return E_NOTIMPL;
1078 }
1079 str1 = V_BSTR(str1v);
1080
1081 if(V_VT(str2v) != VT_BSTR) {
1082 FIXME("Unsupported str2 type %s\n", debugstr_variant(str2v));
1083 return E_NOTIMPL;
1084 }
1085 str2 = V_BSTR(str2v);
1086
1087 if(start < SysStringLen(str1)) {
1088 WCHAR *ptr;
1089
1090 ptr = strstrW(str1+start, str2);
1091 ret = ptr ? ptr-str1+1 : 0;
1092 }else {
1093 ret = 0;
1094 }
1095
1096 return return_int(res, ret);
1097 }
1098
1099 static HRESULT Global_InStrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1100 {
1101 FIXME("\n");
1102 return E_NOTIMPL;
1103 }
1104
1105 static HRESULT Global_AscB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1106 {
1107 FIXME("\n");
1108 return E_NOTIMPL;
1109 }
1110
1111 static HRESULT Global_ChrB(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1112 {
1113 FIXME("\n");
1114 return E_NOTIMPL;
1115 }
1116
1117 static HRESULT Global_Asc(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1118 {
1119 FIXME("\n");
1120 return E_NOTIMPL;
1121 }
1122
1123 static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1124 {
1125 int c;
1126 HRESULT hres;
1127
1128 TRACE("%s\n", debugstr_variant(arg));
1129
1130 hres = to_int(arg, &c);
1131 if(FAILED(hres))
1132 return hres;
1133
1134 if(c < 0 || c >= 0x100) {
1135 FIXME("invalid arg\n");
1136 return E_FAIL;
1137 }
1138
1139 if(res) {
1140 WCHAR ch = c;
1141
1142 V_VT(res) = VT_BSTR;
1143 V_BSTR(res) = SysAllocStringLen(&ch, 1);
1144 if(!V_BSTR(res))
1145 return E_OUTOFMEMORY;
1146 }
1147 return S_OK;
1148 }
1149
1150 static HRESULT Global_AscW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1151 {
1152 FIXME("\n");
1153 return E_NOTIMPL;
1154 }
1155
1156 static HRESULT Global_ChrW(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1157 {
1158 FIXME("\n");
1159 return E_NOTIMPL;
1160 }
1161
1162 static HRESULT Global_Abs(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1163 {
1164 FIXME("\n");
1165 return E_NOTIMPL;
1166 }
1167
1168 static HRESULT Global_Fix(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1169 {
1170 FIXME("\n");
1171 return E_NOTIMPL;
1172 }
1173
1174 static HRESULT Global_Int(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1175 {
1176 FIXME("\n");
1177 return E_NOTIMPL;
1178 }
1179
1180 static HRESULT Global_Sgn(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1181 {
1182 FIXME("\n");
1183 return E_NOTIMPL;
1184 }
1185
1186 static HRESULT Global_Now(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1187 {
1188 SYSTEMTIME lt;
1189 double date;
1190
1191 TRACE("\n");
1192
1193 GetLocalTime(&lt);
1194 SystemTimeToVariantTime(&lt, &date);
1195 return return_date(res, date);
1196 }
1197
1198 static HRESULT Global_Date(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1199 {
1200 FIXME("\n");
1201 return E_NOTIMPL;
1202 }
1203
1204 static HRESULT Global_Time(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1205 {
1206 FIXME("\n");
1207 return E_NOTIMPL;
1208 }
1209
1210 static HRESULT Global_Day(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1211 {
1212 FIXME("\n");
1213 return E_NOTIMPL;
1214 }
1215
1216 static HRESULT Global_Month(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1217 {
1218 FIXME("\n");
1219 return E_NOTIMPL;
1220 }
1221
1222 static HRESULT Global_Weekday(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1223 {
1224 FIXME("\n");
1225 return E_NOTIMPL;
1226 }
1227
1228 static HRESULT Global_Year(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1229 {
1230 FIXME("\n");
1231 return E_NOTIMPL;
1232 }
1233
1234 static HRESULT Global_Hour(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1235 {
1236 FIXME("\n");
1237 return E_NOTIMPL;
1238 }
1239
1240 static HRESULT Global_Minute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1241 {
1242 FIXME("\n");
1243 return E_NOTIMPL;
1244 }
1245
1246 static HRESULT Global_Second(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1247 {
1248 FIXME("\n");
1249 return E_NOTIMPL;
1250 }
1251
1252 static HRESULT Global_DateValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1253 {
1254 FIXME("\n");
1255 return E_NOTIMPL;
1256 }
1257
1258 static HRESULT Global_TimeValue(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1259 {
1260 FIXME("\n");
1261 return E_NOTIMPL;
1262 }
1263
1264 static HRESULT Global_DateSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1265 {
1266 FIXME("\n");
1267 return E_NOTIMPL;
1268 }
1269
1270 static HRESULT Global_TimeSerial(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1271 {
1272 FIXME("\n");
1273 return E_NOTIMPL;
1274 }
1275
1276 static HRESULT Global_InputBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1277 {
1278 FIXME("\n");
1279 return E_NOTIMPL;
1280 }
1281
1282 static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1283 {
1284 BSTR prompt;
1285 HRESULT hres;
1286
1287 TRACE("\n");
1288
1289 if(args_cnt != 1) {
1290 FIXME("unsupported arg_cnt %d\n", args_cnt);
1291 return E_NOTIMPL;
1292 }
1293
1294 hres = to_string(args, &prompt);
1295 if(FAILED(hres))
1296 return hres;
1297
1298 hres = show_msgbox(This->desc->ctx, prompt, res);
1299 SysFreeString(prompt);
1300 return hres;
1301 }
1302
1303 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1304 {
1305 IUnknown *obj;
1306 HRESULT hres;
1307
1308 TRACE("(%s)\n", debugstr_variant(arg));
1309
1310 if(V_VT(arg) != VT_BSTR) {
1311 FIXME("non-bstr arg\n");
1312 return E_INVALIDARG;
1313 }
1314
1315 obj = create_object(This->desc->ctx, V_BSTR(arg));
1316 if(!obj)
1317 return VB_E_CANNOT_CREATE_OBJ;
1318
1319 if(res) {
1320 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res));
1321 if(FAILED(hres))
1322 return hres;
1323
1324 V_VT(res) = VT_DISPATCH;
1325 }
1326
1327 IUnknown_Release(obj);
1328 return S_OK;
1329 }
1330
1331 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1332 {
1333 IBindCtx *bind_ctx;
1334 IUnknown *obj_unk;
1335 IDispatch *disp;
1336 ULONG eaten = 0;
1337 IMoniker *mon;
1338 HRESULT hres;
1339
1340 TRACE("%s %s\n", args_cnt ? debugstr_variant(args) : "", args_cnt > 1 ? debugstr_variant(args+1) : "");
1341
1342 if(args_cnt != 1 || V_VT(args) != VT_BSTR) {
1343 FIXME("unsupported args\n");
1344 return E_NOTIMPL;
1345 }
1346
1347 if(This->desc->ctx->safeopt & (INTERFACE_USES_SECURITY_MANAGER|INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
1348 WARN("blocked in current safety mode\n");
1349 return VB_E_CANNOT_CREATE_OBJ;
1350 }
1351
1352 hres = CreateBindCtx(0, &bind_ctx);
1353 if(FAILED(hres))
1354 return hres;
1355
1356 hres = MkParseDisplayName(bind_ctx, V_BSTR(args), &eaten, &mon);
1357 if(SUCCEEDED(hres)) {
1358 hres = IMoniker_BindToObject(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&obj_unk);
1359 IMoniker_Release(mon);
1360 }else {
1361 hres = MK_E_SYNTAX;
1362 }
1363 IBindCtx_Release(bind_ctx);
1364 if(FAILED(hres))
1365 return hres;
1366
1367 hres = set_object_site(This->desc->ctx, obj_unk);
1368 if(FAILED(hres)) {
1369 IUnknown_Release(obj_unk);
1370 return hres;
1371 }
1372
1373 hres = IUnknown_QueryInterface(obj_unk, &IID_IDispatch, (void**)&disp);
1374 if(SUCCEEDED(hres)) {
1375 if(res) {
1376 V_VT(res) = VT_DISPATCH;
1377 V_DISPATCH(res) = disp;
1378 }else {
1379 IDispatch_Release(disp);
1380 }
1381 }else {
1382 FIXME("object does not support IDispatch\n");
1383 }
1384
1385 return hres;
1386 }
1387
1388 static HRESULT Global_DateAdd(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1389 {
1390 FIXME("\n");
1391 return E_NOTIMPL;
1392 }
1393
1394 static HRESULT Global_DateDiff(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1395 {
1396 FIXME("\n");
1397 return E_NOTIMPL;
1398 }
1399
1400 static HRESULT Global_DatePart(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1401 {
1402 FIXME("\n");
1403 return E_NOTIMPL;
1404 }
1405
1406 static HRESULT Global_TypeName(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1407 {
1408 FIXME("\n");
1409 return E_NOTIMPL;
1410 }
1411
1412 static HRESULT Global_Array(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1413 {
1414 FIXME("\n");
1415 return E_NOTIMPL;
1416 }
1417
1418 static HRESULT Global_Erase(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1419 {
1420 FIXME("\n");
1421 return E_NOTIMPL;
1422 }
1423
1424 static HRESULT Global_Filter(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1425 {
1426 FIXME("\n");
1427 return E_NOTIMPL;
1428 }
1429
1430 static HRESULT Global_Join(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1431 {
1432 FIXME("\n");
1433 return E_NOTIMPL;
1434 }
1435
1436 static HRESULT Global_Split(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1437 {
1438 FIXME("\n");
1439 return E_NOTIMPL;
1440 }
1441
1442 static HRESULT Global_Replace(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1443 {
1444 FIXME("\n");
1445 return E_NOTIMPL;
1446 }
1447
1448 static HRESULT Global_StrReverse(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1449 {
1450 WCHAR *ptr1, *ptr2, ch;
1451 BSTR ret;
1452 HRESULT hres;
1453
1454 TRACE("%s\n", debugstr_variant(arg));
1455
1456 hres = to_string(arg, &ret);
1457 if(FAILED(hres))
1458 return hres;
1459
1460 ptr1 = ret;
1461 ptr2 = ret + SysStringLen(ret)-1;
1462 while(ptr1 < ptr2) {
1463 ch = *ptr1;
1464 *ptr1++ = *ptr2;
1465 *ptr2-- = ch;
1466 }
1467
1468 return return_bstr(res, ret);
1469 }
1470
1471 static HRESULT Global_InStrRev(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1472 {
1473 FIXME("\n");
1474 return E_NOTIMPL;
1475 }
1476
1477 static HRESULT Global_LoadPicture(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1478 {
1479 FIXME("\n");
1480 return E_NOTIMPL;
1481 }
1482
1483 static HRESULT Global_ScriptEngine(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1484 {
1485 FIXME("\n");
1486 return E_NOTIMPL;
1487 }
1488
1489 static HRESULT Global_ScriptEngineMajorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1490 {
1491 FIXME("\n");
1492 return E_NOTIMPL;
1493 }
1494
1495 static HRESULT Global_ScriptEngineMinorVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1496 {
1497 FIXME("\n");
1498 return E_NOTIMPL;
1499 }
1500
1501 static HRESULT Global_ScriptEngineBuildVersion(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1502 {
1503 FIXME("\n");
1504 return E_NOTIMPL;
1505 }
1506
1507 static HRESULT Global_FormatNumber(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1508 {
1509 FIXME("\n");
1510 return E_NOTIMPL;
1511 }
1512
1513 static HRESULT Global_FormatCurrency(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1514 {
1515 FIXME("\n");
1516 return E_NOTIMPL;
1517 }
1518
1519 static HRESULT Global_FormatPercent(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1520 {
1521 FIXME("\n");
1522 return E_NOTIMPL;
1523 }
1524
1525 static HRESULT Global_FormatDateTime(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1526 {
1527 FIXME("\n");
1528 return E_NOTIMPL;
1529 }
1530
1531 static HRESULT Global_WeekdayName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1532 {
1533 int weekday, first_day = 1, abbrev = 0;
1534 BSTR ret;
1535 HRESULT hres;
1536
1537 TRACE("\n");
1538
1539 assert(1 <= args_cnt && args_cnt <= 3);
1540
1541 hres = to_int(args, &weekday);
1542 if(FAILED(hres))
1543 return hres;
1544
1545 if(args_cnt > 1) {
1546 hres = to_int(args+1, &abbrev);
1547 if(FAILED(hres))
1548 return hres;
1549
1550 if(args_cnt == 3) {
1551 hres = to_int(args+2, &first_day);
1552 if(FAILED(hres))
1553 return hres;
1554 }
1555 }
1556
1557 hres = VarWeekdayName(weekday, abbrev, first_day, 0, &ret);
1558 if(FAILED(hres))
1559 return hres;
1560
1561 return return_bstr(res, ret);
1562 }
1563
1564 static HRESULT Global_MonthName(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
1565 {
1566 int month, abbrev = 0;
1567 BSTR ret;
1568 HRESULT hres;
1569
1570 TRACE("\n");
1571
1572 assert(args_cnt == 1 || args_cnt == 2);
1573
1574 hres = to_int(args, &month);
1575 if(FAILED(hres))
1576 return hres;
1577
1578 if(args_cnt == 2) {
1579 hres = to_int(args+1, &abbrev);
1580 if(FAILED(hres))
1581 return hres;
1582 }
1583
1584 hres = VarMonthName(month, abbrev, 0, &ret);
1585 if(FAILED(hres))
1586 return hres;
1587
1588 return return_bstr(res, ret);
1589 }
1590
1591 static HRESULT Global_Round(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1592 {
1593 double n;
1594 HRESULT hres;
1595
1596 TRACE("%s\n", debugstr_variant(arg));
1597
1598 if(!res)
1599 return S_OK;
1600
1601 switch(V_VT(arg)) {
1602 case VT_I2:
1603 case VT_I4:
1604 case VT_BOOL:
1605 *res = *arg;
1606 return S_OK;
1607 case VT_R8:
1608 n = V_R8(arg);
1609 break;
1610 default:
1611 hres = to_double(arg, &n);
1612 if(FAILED(hres))
1613 return hres;
1614 }
1615
1616 return return_double(res, round(n));
1617 }
1618
1619 static HRESULT Global_Escape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1620 {
1621 FIXME("\n");
1622 return E_NOTIMPL;
1623 }
1624
1625 static HRESULT Global_Unescape(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1626 {
1627 FIXME("\n");
1628 return E_NOTIMPL;
1629 }
1630
1631 static HRESULT Global_Eval(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1632 {
1633 FIXME("\n");
1634 return E_NOTIMPL;
1635 }
1636
1637 static HRESULT Global_Execute(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1638 {
1639 FIXME("\n");
1640 return E_NOTIMPL;
1641 }
1642
1643 static HRESULT Global_ExecuteGlobal(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1644 {
1645 FIXME("\n");
1646 return E_NOTIMPL;
1647 }
1648
1649 static HRESULT Global_GetRef(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
1650 {
1651 FIXME("\n");
1652 return E_NOTIMPL;
1653 }
1654
1655 static const string_constant_t vbCr = {1, {'\r'}};
1656 static const string_constant_t vbCrLf = {2, {'\r','\n'}};
1657 static const string_constant_t vbNewLine = {2, {'\r','\n'}};
1658 static const string_constant_t vbFormFeed = {1, {0xc}};
1659 static const string_constant_t vbLf = {1, {'\n'}};
1660 static const string_constant_t vbNullChar = {1};
1661 static const string_constant_t vbNullString = {0};
1662 static const string_constant_t vbTab = {1, {'\t'}};
1663 static const string_constant_t vbVerticalTab = {1, {0xb}};
1664
1665 static const builtin_prop_t global_props[] = {
1666 {DISPID_GLOBAL_VBUSESYSTEM, NULL, BP_GET, VT_I2, 0},
1667 {DISPID_GLOBAL_USESYSTEMDAYOFWEEK, NULL, BP_GET, VT_I2, 0},
1668 {DISPID_GLOBAL_VBSUNDAY, NULL, BP_GET, VT_I2, 1},
1669 {DISPID_GLOBAL_VBMONDAY, NULL, BP_GET, VT_I2, 2},
1670 {DISPID_GLOBAL_VBTUESDAY, NULL, BP_GET, VT_I2, 3},
1671 {DISPID_GLOBAL_VBWEDNESDAY, NULL, BP_GET, VT_I2, 4},
1672 {DISPID_GLOBAL_VBTHURSDAY, NULL, BP_GET, VT_I2, 5},
1673 {DISPID_GLOBAL_VBFRIDAY, NULL, BP_GET, VT_I2, 6},
1674 {DISPID_GLOBAL_VBSATURDAY, NULL, BP_GET, VT_I2, 7},
1675 {DISPID_GLOBAL_VBFIRSTJAN1, NULL, BP_GET, VT_I2, 1},
1676 {DISPID_GLOBAL_VBFIRSTFOURDAYS, NULL, BP_GET, VT_I2, 2},
1677 {DISPID_GLOBAL_VBFIRSTFULLWEEK, NULL, BP_GET, VT_I2, 3},
1678 {DISPID_GLOBAL_VBOKONLY, NULL, BP_GET, VT_I2, MB_OK},
1679 {DISPID_GLOBAL_VBOKCANCEL, NULL, BP_GET, VT_I2, MB_OKCANCEL},
1680 {DISPID_GLOBAL_VBABORTRETRYIGNORE, NULL, BP_GET, VT_I2, MB_ABORTRETRYIGNORE},
1681 {DISPID_GLOBAL_VBYESNOCANCEL, NULL, BP_GET, VT_I2, MB_YESNOCANCEL},
1682 {DISPID_GLOBAL_VBYESNO, NULL, BP_GET, VT_I2, MB_YESNO},
1683 {DISPID_GLOBAL_VBRETRYCANCEL, NULL, BP_GET, VT_I2, MB_RETRYCANCEL},
1684 {DISPID_GLOBAL_VBCRITICAL, NULL, BP_GET, VT_I2, MB_ICONHAND},
1685 {DISPID_GLOBAL_VBQUESTION, NULL, BP_GET, VT_I2, MB_ICONQUESTION},
1686 {DISPID_GLOBAL_VBEXCLAMATION, NULL, BP_GET, VT_I2, MB_ICONEXCLAMATION},
1687 {DISPID_GLOBAL_VBINFORMATION, NULL, BP_GET, VT_I2, MB_ICONASTERISK},
1688 {DISPID_GLOBAL_VBDEFAULTBUTTON1, NULL, BP_GET, VT_I2, MB_DEFBUTTON1},
1689 {DISPID_GLOBAL_VBDEFAULTBUTTON2, NULL, BP_GET, VT_I2, MB_DEFBUTTON2},
1690 {DISPID_GLOBAL_VBDEFAULTBUTTON3, NULL, BP_GET, VT_I2, MB_DEFBUTTON3},
1691 {DISPID_GLOBAL_VBDEFAULTBUTTON4, NULL, BP_GET, VT_I2, MB_DEFBUTTON4},
1692 {DISPID_GLOBAL_VBAPPLICATIONMODAL, NULL, BP_GET, VT_I2, MB_APPLMODAL},
1693 {DISPID_GLOBAL_VBSYSTEMMODAL, NULL, BP_GET, VT_I2, MB_SYSTEMMODAL},
1694 {DISPID_GLOBAL_VBOK, NULL, BP_GET, VT_I2, IDOK},
1695 {DISPID_GLOBAL_VBCANCEL, NULL, BP_GET, VT_I2, IDCANCEL},
1696 {DISPID_GLOBAL_VBABORT, NULL, BP_GET, VT_I2, IDABORT},
1697 {DISPID_GLOBAL_VBRETRY, NULL, BP_GET, VT_I2, IDRETRY},
1698 {DISPID_GLOBAL_VBIGNORE, NULL, BP_GET, VT_I2, IDIGNORE},
1699 {DISPID_GLOBAL_VBYES, NULL, BP_GET, VT_I2, IDYES},
1700 {DISPID_GLOBAL_VBNO, NULL, BP_GET, VT_I2, IDNO},
1701 {DISPID_GLOBAL_VBEMPTY, NULL, BP_GET, VT_I2, VT_EMPTY},
1702 {DISPID_GLOBAL_VBNULL, NULL, BP_GET, VT_I2, VT_NULL},
1703 {DISPID_GLOBAL_VBINTEGER, NULL, BP_GET, VT_I2, VT_I2},
1704 {DISPID_GLOBAL_VBLONG, NULL, BP_GET, VT_I2, VT_I4},
1705 {DISPID_GLOBAL_VBSINGLE, NULL, BP_GET, VT_I2, VT_R4},
1706 {DISPID_GLOBAL_VBDOUBLE, NULL, BP_GET, VT_I2, VT_R8},
1707 {DISPID_GLOBAL_VBCURRENCY, NULL, BP_GET, VT_I2, VT_CY},
1708 {DISPID_GLOBAL_VBDATE, NULL, BP_GET, VT_I2, VT_DATE},
1709 {DISPID_GLOBAL_VBSTRING, NULL, BP_GET, VT_I2, VT_BSTR},
1710 {DISPID_GLOBAL_VBOBJECT, NULL, BP_GET, VT_I2, VT_DISPATCH},
1711 {DISPID_GLOBAL_VBERROR, NULL, BP_GET, VT_I2, VT_ERROR},
1712 {DISPID_GLOBAL_VBBOOLEAN, NULL, BP_GET, VT_I2, VT_BOOL},
1713 {DISPID_GLOBAL_VBVARIANT, NULL, BP_GET, VT_I2, VT_VARIANT},
1714 {DISPID_GLOBAL_VBDATAOBJECT, NULL, BP_GET, VT_I2, VT_UNKNOWN},
1715 {DISPID_GLOBAL_VBDECIMAL, NULL, BP_GET, VT_I2, VT_DECIMAL},
1716 {DISPID_GLOBAL_VBBYTE, NULL, BP_GET, VT_I2, VT_UI1},
1717 {DISPID_GLOBAL_VBARRAY, NULL, BP_GET, VT_I2, VT_ARRAY},
1718 {DISPID_GLOBAL_VBTRUE, NULL, BP_GET, VT_I2, VARIANT_TRUE},
1719 {DISPID_GLOBAL_VBFALSE, NULL, BP_GET, VT_I2, VARIANT_FALSE},
1720 {DISPID_GLOBAL_VBUSEDEFAULT, NULL, BP_GET, VT_I2, -2},
1721 {DISPID_GLOBAL_VBBINARYCOMPARE, NULL, BP_GET, VT_I2, 0},
1722 {DISPID_GLOBAL_VBTEXTCOMPARE, NULL, BP_GET, VT_I2, 1},
1723 {DISPID_GLOBAL_VBDATABASECOMPARE, NULL, BP_GET, VT_I2, 2},
1724 {DISPID_GLOBAL_VBGENERALDATE, NULL, BP_GET, VT_I2, 0},
1725 {DISPID_GLOBAL_VBLONGDATE, NULL, BP_GET, VT_I2, 1},
1726 {DISPID_GLOBAL_VBSHORTDATE, NULL, BP_GET, VT_I2, 2},
1727 {DISPID_GLOBAL_VBLONGTIME, NULL, BP_GET, VT_I2, 3},
1728 {DISPID_GLOBAL_VBSHORTTIME, NULL, BP_GET, VT_I2, 4},
1729 {DISPID_GLOBAL_VBOBJECTERROR, NULL, BP_GET, VT_I4, 0x80040000},
1730 {DISPID_GLOBAL_VBBLACK, NULL, BP_GET, VT_I4, 0x000000},
1731 {DISPID_GLOBAL_VBBLUE, NULL, BP_GET, VT_I4, 0xff0000},
1732 {DISPID_GLOBAL_VBCYAN, NULL, BP_GET, VT_I4, 0xffff00},
1733 {DISPID_GLOBAL_VBGREEN, NULL, BP_GET, VT_I4, 0x00ff00},
1734 {DISPID_GLOBAL_VBMAGENTA, NULL, BP_GET, VT_I4, 0xff00ff},
1735 {DISPID_GLOBAL_VBRED, NULL, BP_GET, VT_I4, 0x0000ff},
1736 {DISPID_GLOBAL_VBWHITE, NULL, BP_GET, VT_I4, 0xffffff},
1737 {DISPID_GLOBAL_VBYELLOW, NULL, BP_GET, VT_I4, 0x00ffff},
1738 {DISPID_GLOBAL_VBCR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCr},
1739 {DISPID_GLOBAL_VBCRLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbCrLf},
1740 {DISPID_GLOBAL_VBNEWLINE, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNewLine},
1741 {DISPID_GLOBAL_VBFORMFEED, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbFormFeed},
1742 {DISPID_GLOBAL_VBLF, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbLf},
1743 {DISPID_GLOBAL_VBNULLCHAR, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullChar},
1744 {DISPID_GLOBAL_VBNULLSTRING, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbNullString},
1745 {DISPID_GLOBAL_VBTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbTab},
1746 {DISPID_GLOBAL_VBVERTICALTAB, NULL, BP_GET, VT_BSTR, (UINT_PTR)&vbVerticalTab},
1747 {DISPID_GLOBAL_CCUR, Global_CCur, 0, 1},
1748 {DISPID_GLOBAL_CINT, Global_CInt, 0, 1},
1749 {DISPID_GLOBAL_CLNG, Global_CLng, 0, 1},
1750 {DISPID_GLOBAL_CBOOL, Global_CBool, 0, 1},
1751 {DISPID_GLOBAL_CBYTE, Global_CByte, 0, 1},
1752 {DISPID_GLOBAL_CDATE, Global_CDate, 0, 1},
1753 {DISPID_GLOBAL_CDBL, Global_CDbl, 0, 1},
1754 {DISPID_GLOBAL_CSNG, Global_CSng, 0, 1},
1755 {DISPID_GLOBAL_CSTR, Global_CStr, 0, 1},
1756 {DISPID_GLOBAL_HEX, Global_Hex, 0, 1},
1757 {DISPID_GLOBAL_OCT, Global_Oct, 0, 1},
1758 {DISPID_GLOBAL_VARTYPE, Global_VarType, 0, 1},
1759 {DISPID_GLOBAL_ISDATE, Global_IsDate, 0, 1},
1760 {DISPID_GLOBAL_ISEMPTY, Global_IsEmpty, 0, 1},
1761 {DISPID_GLOBAL_ISNULL, Global_IsNull, 0, 1},
1762 {DISPID_GLOBAL_ISNUMERIC, Global_IsNumeric, 0, 1},
1763 {DISPID_GLOBAL_ISARRAY, Global_IsArray, 0, 1},
1764 {DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1},
1765 {DISPID_GLOBAL_ATN, Global_Ant, 0, 1},
1766 {DISPID_GLOBAL_COS, Global_Cos, 0, 1},
1767 {DISPID_GLOBAL_SIN, Global_Sin, 0, 1},
1768 {DISPID_GLOBAL_TAN, Global_Tan, 0, 1},
1769 {DISPID_GLOBAL_EXP, Global_Exp, 0, 1},
1770 {DISPID_GLOBAL_LOG, Global_Log, 0, 1},
1771 {DISPID_GLOBAL_SQR, Global_Sqr, 0, 1},
1772 {DISPID_GLOBAL_RANDOMIZE, Global_Randomize, 0, 1},
1773 {DISPID_GLOBAL_RND, Global_Rnd, 0, 1},
1774 {DISPID_GLOBAL_TIMER, Global_Timer, 0, 0},
1775 {DISPID_GLOBAL_LBOUND, Global_LBound, 0, 1},
1776 {DISPID_GLOBAL_UBOUND, Global_UBound, 0, 1},
1777 {DISPID_GLOBAL_RGB, Global_RGB, 0, 3},
1778 {DISPID_GLOBAL_LEN, Global_Len, 0, 1},
1779 {DISPID_GLOBAL_LENB, Global_LenB, 0, 1},
1780 {DISPID_GLOBAL_LEFT, Global_Left, 0, 2},
1781 {DISPID_GLOBAL_LEFTB, Global_LeftB, 0, 2},
1782 {DISPID_GLOBAL_RIGHT, Global_Right, 0, 2},
1783 {DISPID_GLOBAL_RIGHTB, Global_RightB, 0, 2},
1784 {DISPID_GLOBAL_MID, Global_Mid, 0, 2, 3},
1785 {DISPID_GLOBAL_MIDB, Global_MidB, 0, 2, 3},
1786 {DISPID_GLOBAL_STRCOMP, Global_StrComp, 0, 2, 3},
1787 {DISPID_GLOBAL_LCASE, Global_LCase, 0, 1},
1788 {DISPID_GLOBAL_UCASE, Global_UCase, 0, 1},
1789 {DISPID_GLOBAL_LTRIM, Global_LTrim, 0, 1},
1790 {DISPID_GLOBAL_RTRIM, Global_RTrim, 0, 1},
1791 {DISPID_GLOBAL_TRIM, Global_Trim, 0, 1},
1792 {DISPID_GLOBAL_SPACE, Global_Space, 0, 1},
1793 {DISPID_GLOBAL_STRING, Global_String, 0, 0, 2},
1794 {DISPID_GLOBAL_INSTR, Global_InStr, 0, 2, 4},
1795 {DISPID_GLOBAL_INSTRB, Global_InStrB, 0, 3, 4},
1796 {DISPID_GLOBAL_ASCB, Global_AscB, 0, 1},
1797 {DISPID_GLOBAL_CHRB, Global_ChrB, 0, 1},
1798 {DISPID_GLOBAL_ASC, Global_Asc, 0, 1},
1799 {DISPID_GLOBAL_CHR, Global_Chr, 0, 1},
1800 {DISPID_GLOBAL_ASCW, Global_AscW, 0, 1},
1801 {DISPID_GLOBAL_CHRW, Global_ChrW, 0, 1},
1802 {DISPID_GLOBAL_ABS, Global_Abs, 0, 1},
1803 {DISPID_GLOBAL_FIX, Global_Fix, 0, 1},
1804 {DISPID_GLOBAL_INT, Global_Int, 0, 1},
1805 {DISPID_GLOBAL_SGN, Global_Sgn, 0, 1},
1806 {DISPID_GLOBAL_NOW, Global_Now, 0, 0},
1807 {DISPID_GLOBAL_DATE, Global_Date, 0, 0},
1808 {DISPID_GLOBAL_TIME, Global_Time, 0, 0},
1809 {DISPID_GLOBAL_DAY, Global_Day, 0, 1},
1810 {DISPID_GLOBAL_MONTH, Global_Month, 0, 1},
1811 {DISPID_GLOBAL_WEEKDAY, Global_Weekday, 0, 1, 2},
1812 {DISPID_GLOBAL_YEAR, Global_Year, 0, 1},
1813 {DISPID_GLOBAL_HOUR, Global_Hour, 0, 1},
1814 {DISPID_GLOBAL_MINUTE, Global_Minute, 0, 1},
1815 {DISPID_GLOBAL_SECOND, Global_Second, 0, 1},
1816 {DISPID_GLOBAL_DATEVALUE, Global_DateValue, 0, 1},
1817 {DISPID_GLOBAL_TIMEVALUE, Global_TimeValue, 0, 1},
1818 {DISPID_GLOBAL_DATESERIAL, Global_DateSerial, 0, 3},
1819 {DISPID_GLOBAL_TIMESERIAL, Global_TimeSerial, 0, 3},
1820 {DISPID_GLOBAL_INPUTBOX, Global_InputBox, 0, 1, 7},
1821 {DISPID_GLOBAL_MSGBOX, Global_MsgBox, 0, 1, 5},
1822 {DISPID_GLOBAL_CREATEOBJECT, Global_CreateObject, 0, 1},
1823 {DISPID_GLOBAL_GETOBJECT, Global_GetObject, 0, 0, 2},
1824 {DISPID_GLOBAL_DATEADD, Global_DateAdd, 0, 3},
1825 {DISPID_GLOBAL_DATEDIFF, Global_DateDiff, 0, 3, 5},
1826 {DISPID_GLOBAL_DATEPART, Global_DatePart, 0, 2, 4},
1827 {DISPID_GLOBAL_TYPENAME, Global_TypeName, 0, 1},
1828 {DISPID_GLOBAL_ARRAY, Global_Array, 0, 1},
1829 {DISPID_GLOBAL_ERASE, Global_Erase, 0, 1},
1830 {DISPID_GLOBAL_FILTER, Global_Filter, 0, 2, 4},
1831 {DISPID_GLOBAL_JOIN, Global_Join, 0, 1, 2},
1832 {DISPID_GLOBAL_SPLIT, Global_Split, 0, 1, 4},
1833 {DISPID_GLOBAL_REPLACE, Global_Replace, 0, 3, 6},
1834 {DISPID_GLOBAL_STRREVERSE, Global_StrReverse, 0, 1},
1835 {DISPID_GLOBAL_INSTRREV, Global_InStrRev, 0, 2, 4},
1836 {DISPID_GLOBAL_LOADPICTURE, Global_LoadPicture, 0, 1},
1837 {DISPID_GLOBAL_SCRIPTENGINE, Global_ScriptEngine, 0, 0},
1838 {DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION, Global_ScriptEngineMajorVersion, 0, 0},
1839 {DISPID_GLOBAL_SCRIPTENGINEMINORVERSION, Global_ScriptEngineMinorVersion, 0, 0},
1840 {DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION, Global_ScriptEngineBuildVersion, 0, 0},
1841 {DISPID_GLOBAL_FORMATNUMBER, Global_FormatNumber, 0, 1, 5},
1842 {DISPID_GLOBAL_FORMATCURRENCY, Global_FormatCurrency, 0, 1, 5},
1843 {DISPID_GLOBAL_FORMATPERCENT, Global_FormatPercent, 0, 1, 5},
1844 {DISPID_GLOBAL_FORMATDATETIME, Global_FormatDateTime, 0, 1, 2},
1845 {DISPID_GLOBAL_WEEKDAYNAME, Global_WeekdayName, 0, 1, 3},
1846 {DISPID_GLOBAL_MONTHNAME, Global_MonthName, 0, 1, 2},
1847 {DISPID_GLOBAL_ROUND, Global_Round, 0, 1, 2},
1848 {DISPID_GLOBAL_ESCAPE, Global_Escape, 0, 1},
1849 {DISPID_GLOBAL_UNESCAPE, Global_Unescape, 0, 1},
1850 {DISPID_GLOBAL_EVAL, Global_Eval, 0, 1},
1851 {DISPID_GLOBAL_EXECUTE, Global_Execute, 0, 1},
1852 {DISPID_GLOBAL_EXECUTEGLOBAL, Global_ExecuteGlobal, 0, 1},
1853 {DISPID_GLOBAL_GETREF, Global_GetRef, 0, 1},
1854 {DISPID_GLOBAL_VBMSGBOXHELPBUTTON, NULL, BP_GET, VT_I4, MB_HELP},
1855 {DISPID_GLOBAL_VBMSGBOXSETFOREGROUND, NULL, BP_GET, VT_I4, MB_SETFOREGROUND},
1856 {DISPID_GLOBAL_VBMSGBOXRIGHT, NULL, BP_GET, VT_I4, MB_RIGHT},
1857 {DISPID_GLOBAL_VBMSGBOXRTLREADING, NULL, BP_GET, VT_I4, MB_RTLREADING}
1858 };
1859
1860 HRESULT init_global(script_ctx_t *ctx)
1861 {
1862 HRESULT hres;
1863
1864 ctx->global_desc.ctx = ctx;
1865 ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
1866 ctx->global_desc.builtin_props = global_props;
1867
1868 hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
1869 if(FAILED(hres))
1870 return hres;
1871
1872 hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
1873 if(FAILED(hres))
1874 return hres;
1875
1876 hres = create_script_disp(ctx, &ctx->script_obj);
1877 if(FAILED(hres))
1878 return hres;
1879
1880 return init_err(ctx);
1881 }