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