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(<); 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(<); 1531 SystemTimeToVariantTime(<, &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(<); 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(<); 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 } 2478