- Timestamp:
- Jun 11, 2002, 8:30:56 AM (23 years ago)
- Location:
- trunk/src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/oleaut32/tmarshal.c
r8450 r8640 44 44 45 45 static const WCHAR riidW[5] = {'r','i','i','d',0}; 46 static const WCHAR pdispparamsW[] = {'p','d','i','s','p','p','a','r','a','m','s',0}; 47 static const WCHAR ppvObjectW[] = {'p','p','v','O','b','j','e','c','t',0}; 46 48 47 49 WINE_DEFAULT_DEBUG_CHANNEL(ole); … … 183 185 PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) { 184 186 if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) { 185 *ppv = (LPVOID)iface; 187 *ppv = (LPVOID)iface; 186 188 /* No ref counting, static class */ 187 189 return S_OK; … … 252 254 253 255 /* Determine nr of functions. Since we use the toplevel interface and all 254 * inherited ones have lower numbers, we are ok to not to descent into 256 * inherited ones have lower numbers, we are ok to not to descent into 255 257 * the inheritance tree I think. 256 258 */ … … 275 277 #include <pshpack1.h> 276 278 #endif 277 278 279 typedef struct _TMAsmProxy { 279 280 BYTE popleax; … … 286 287 WORD bytestopop; 287 288 } WINE_PACKED TMAsmProxy; 288 289 289 #ifdef __WIN32OS2__ 290 290 #include <poppack.h> … … 366 366 }; 367 367 368 /* how much space do we use on stack in DWORD steps. */ 369 static int const 370 _argsize(DWORD vt) { 371 switch (vt) { 372 case VT_VARIANT: 373 return (sizeof(VARIANT)+3)/sizeof(DWORD); 374 default: 375 return 1; 376 } 377 } 378 379 static int 380 _xsize(TYPEDESC *td) { 381 switch (td->vt) { 382 case VT_VARIANT: 383 return sizeof(VARIANT)+3; 384 case VT_CARRAY: { 385 int i, arrsize = 1; 386 ARRAYDESC *adesc = td->u.lpadesc; 387 388 for (i=0;i<adesc->cDims;i++) 389 arrsize *= adesc->rgbounds[i].cElements; 390 return arrsize*_xsize(&adesc->tdescElem); 391 } 392 case VT_UI2: 393 case VT_I2: 394 return 2; 395 case VT_UI1: 396 case VT_I1: 397 return 1; 398 default: 399 return 4; 400 } 401 } 402 368 403 static HRESULT 369 marshall_param( 370 ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf 404 serialize_param( 405 ITypeInfo *tinfo, 406 BOOL writeit, 407 BOOL debugout, 408 BOOL dealloc, 409 TYPEDESC *tdesc, 410 DWORD *arg, 411 marshal_state *buf 371 412 ) { 372 int relaydeb = TRACE_ON(olerelay);373 HRESULT hres; 374 375 if (!tdesc) tdesc = &(elem->tdesc); 413 HRESULT hres = S_OK; 414 415 TRACE("(tdesc.vt %d)\n",tdesc->vt); 416 376 417 switch (tdesc->vt) { 377 case VT_ NULL:418 case VT_EMPTY: /* nothing. empty variant for instance */ 378 419 return S_OK; 379 case VT_BSTR: { /* DWORD size, string data */ 380 381 if (*arg) { 420 case VT_BOOL: 421 case VT_ERROR: 422 case VT_UI4: 423 case VT_UINT: 424 case VT_I4: 425 case VT_UI2: 426 case VT_UI1: 427 hres = S_OK; 428 if (debugout) MESSAGE("%lx",*arg); 429 if (writeit) 430 hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); 431 return hres; 432 case VT_VARIANT: { 433 TYPEDESC tdesc2; 434 VARIANT *vt = (VARIANT*)arg; 435 DWORD vttype = V_VT(vt); 436 437 if (debugout) MESSAGE("Vt(%ld)(",vttype); 438 tdesc2.vt = vttype; 439 if (writeit) { 440 hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype)); 441 if (hres) return hres; 442 } 443 /* need to recurse since we need to free the stuff */ 444 hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,&(V_I4(vt)),buf); 445 if (debugout) MESSAGE(")"); 446 return hres; 447 } 448 case VT_BSTR: { 449 if (debugout) { 450 if (arg) 451 MESSAGE("%s",debugstr_w((BSTR)*arg)); 452 else 453 MESSAGE("<bstr NULL>"); 454 } 455 if (writeit) { 456 if (!*arg) { 457 DWORD fakelen = -1; 458 hres = xbuf_add(buf,(LPBYTE)&fakelen,4); 459 if (hres) 460 return hres; 461 } else { 382 462 DWORD *bstr = ((DWORD*)(*arg))-1; 383 463 384 if (relaydeb) MESSAGE("%s",debugstr_w((LPWSTR)(bstr+1))); 385 return xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4); 386 } else { 387 DWORD xnull = 0; 388 389 return xbuf_add(buf,(LPBYTE)&xnull,sizeof(xnull)); 390 } 391 } 392 case VT_BOOL: 393 case VT_I4: 394 if (relaydeb) MESSAGE("%ld",*arg); 395 return xbuf_add(buf,(LPBYTE)arg,4); 396 case VT_VARIANT: { 397 /* We use ourselves to marshal the value further */ 398 TYPEDESC tdesc2; 399 VARIANT *vt = (VARIANT*)arg; 400 DWORD vttype = V_VT(vt); 401 402 hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype)); 403 if (hres) return hres; 404 tdesc2.vt = vttype; 405 if (relaydeb) MESSAGE("Vt %ld ",vttype); 406 /* shield your eyes, bad pointer voodoo below */ 407 return marshall_param(tinfo,elem,&tdesc2,(DWORD*)&(V_I4(vt)),buf); 408 } 409 case VT_PTR: 410 return marshall_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)*arg,buf); 464 hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4); 465 if (hres) 466 return hres; 467 } 468 } 469 if (dealloc && arg) 470 SysFreeString((BSTR)arg); 471 return S_OK; 472 } 473 case VT_PTR: { 474 DWORD cookie; 475 476 if (debugout) MESSAGE("*"); 477 if (writeit) { 478 cookie = *arg ? 0x42424242 : 0; 479 hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie)); 480 if (hres) 481 return hres; 482 } 483 if (!*arg) { 484 if (debugout) MESSAGE("NULL"); 485 return S_OK; 486 } 487 hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf); 488 if (dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)arg); 489 return hres; 490 } 491 case VT_UNKNOWN: 492 if (debugout) MESSAGE("unk(0x%lx)",*arg); 493 if (writeit) 494 hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); 495 return hres; 496 case VT_DISPATCH: 497 if (debugout) MESSAGE("idisp(0x%lx)",*arg); 498 if (writeit) 499 hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); 500 return hres; 411 501 case VT_VOID: 412 hres = _marshal_interface(buf,&(buf->iid),(LPUNKNOWN)arg); 413 if (hres) { 414 FIXME("Failed unmarshaling VT_VOID with guid %s?\n",debugstr_guid(&(buf->iid))); 415 } 416 return hres; 502 if (debugout) MESSAGE("<void>"); 503 return S_OK; 417 504 case VT_USERDEFINED: { 418 505 ITypeInfo *tinfo2; 419 506 TYPEATTR *tattr; 420 507 421 /*FIXME("VT_USERDEFINED arg is %p, *arg is %p\n",arg,*arg);*/422 508 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); 423 509 if (hres) { … … 428 514 switch (tattr->typekind) { 429 515 case TKIND_INTERFACE: 430 if ( relaydeb) MESSAGE("if(%p), vtbl %p",arg,(LPVOID)*arg);431 hres =_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);516 if (writeit) 517 hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg); 432 518 break; 433 case TKIND_RECORD: 434 if (relaydeb) MESSAGE("record %p",arg); 435 if (buf->thisisiid) 519 case TKIND_RECORD: { 520 int i; 521 if (debugout) MESSAGE("{"); 522 for (i=0;i<tattr->cVars;i++) { 523 VARDESC *vdesc; 524 ELEMDESC *elem2; 525 TYPEDESC *tdesc2; 526 527 hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); 528 if (hres) { 529 FIXME("Could not get vardesc of %d\n",i); 530 return hres; 531 } 532 /* Need them for hack below */ 533 /* 534 memset(names,0,sizeof(names)); 535 hres = ITypeInfo_GetNames(tinfo2,vdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames); 536 if (nrofnames > sizeof(names)/sizeof(names[0])) { 537 ERR("Need more names!\n"); 538 } 539 if (!hres && debugout) 540 MESSAGE("%s=",debugstr_w(names[0])); 541 */ 542 elem2 = &vdesc->elemdescVar; 543 tdesc2 = &elem2->tdesc; 544 hres = serialize_param( 545 tinfo2, 546 writeit, 547 debugout, 548 dealloc, 549 tdesc2, 550 (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), 551 buf 552 ); 553 if (hres!=S_OK) 554 return hres; 555 if (debugout && (i<(tattr->cVars-1))) 556 MESSAGE(","); 557 } 558 if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID))) 436 559 memcpy(&(buf->iid),arg,sizeof(buf->iid)); 437 hres = xbuf_add(buf,(LPBYTE)arg,tattr->cbSizeInstance);560 if (debugout) MESSAGE("}"); 438 561 break; 562 } 439 563 default: 440 564 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind); … … 445 569 return hres; 446 570 } 571 case VT_CARRAY: { 572 ARRAYDESC *adesc = tdesc->u.lpadesc; 573 int i, arrsize = 1; 574 575 if (debugout) MESSAGE("carr"); 576 for (i=0;i<adesc->cDims;i++) { 577 if (debugout) MESSAGE("[%ld]",adesc->rgbounds[i].cElements); 578 arrsize *= adesc->rgbounds[i].cElements; 579 } 580 if (debugout) MESSAGE("["); 581 for (i=0;i<arrsize;i++) { 582 hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem)), buf); 583 if (hres) 584 return hres; 585 if (debugout && (i<arrsize-1)) MESSAGE(","); 586 } 587 if (debugout) MESSAGE("]"); 588 return S_OK; 589 } 447 590 default: 448 ERR("Cannot marshal type %d\n",tdesc->vt); 449 /*dump_ELEMDESC(elem);*/ 591 ERR("Unhandled marshal type %d.\n",tdesc->vt); 592 return S_OK; 593 } 594 } 595 596 static HRESULT 597 serialize_LPVOID_ptr( 598 ITypeInfo *tinfo, 599 BOOL writeit, 600 BOOL debugout, 601 BOOL dealloc, 602 TYPEDESC *tdesc, 603 DWORD *arg, 604 marshal_state *buf 605 ) { 606 HRESULT hres; 607 DWORD cookie; 608 609 if ((tdesc->vt != VT_PTR) || 610 (tdesc->u.lptdesc->vt != VT_PTR) || 611 (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID) 612 ) { 613 FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n"); 450 614 return E_FAIL; 451 615 } 616 cookie = (*arg) ? 0x42424242: 0x0; 617 if (writeit) { 618 hres = xbuf_add(buf, (LPVOID)&cookie, sizeof(cookie)); 619 if (hres) 620 return hres; 621 } 622 if (!*arg) { 623 if (debugout) MESSAGE("<lpvoid NULL>"); 624 return S_OK; 625 } 626 if (debugout) 627 MESSAGE("ppv(%p)",*(LPUNKNOWN*)*arg); 628 if (writeit) { 629 hres = _marshal_interface(buf,&(buf->iid),*(LPUNKNOWN*)*arg); 630 if (hres) 631 return hres; 632 } 633 if (dealloc) 634 HeapFree(GetProcessHeap(),0,(LPVOID)*arg); 452 635 return S_OK; 453 636 } 454 637 455 638 static HRESULT 456 unmarshall_param( 457 ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf 639 serialize_DISPPARAM_ptr( 640 ITypeInfo *tinfo, 641 BOOL writeit, 642 BOOL debugout, 643 BOOL dealloc, 644 TYPEDESC *tdesc, 645 DWORD *arg, 646 marshal_state *buf 647 ) { 648 DWORD cookie; 649 HRESULT hres; 650 DISPPARAMS *disp; 651 int i; 652 653 if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) { 654 FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n"); 655 return E_FAIL; 656 } 657 658 cookie = *arg ? 0x42424242 : 0x0; 659 if (writeit) { 660 hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie)); 661 if (hres) 662 return hres; 663 } 664 if (!*arg) { 665 if (debugout) MESSAGE("<DISPPARAMS NULL>"); 666 return S_OK; 667 } 668 disp = (DISPPARAMS*)*arg; 669 if (writeit) { 670 hres = xbuf_add(buf,(LPBYTE)&disp->cArgs,sizeof(disp->cArgs)); 671 if (hres) 672 return hres; 673 } 674 if (debugout) MESSAGE("D{"); 675 for (i=0;i<disp->cArgs;i++) { 676 TYPEDESC vtdesc; 677 678 vtdesc.vt = VT_VARIANT; 679 serialize_param( 680 tinfo, 681 writeit, 682 debugout, 683 dealloc, 684 &vtdesc, 685 (DWORD*)(disp->rgvarg+i), 686 buf 687 ); 688 if (debugout && (i<disp->cArgs-1)) 689 MESSAGE(","); 690 } 691 if (dealloc) 692 HeapFree(GetProcessHeap(),0,disp->rgvarg); 693 if (writeit) { 694 hres = xbuf_add(buf,(LPBYTE)&disp->cNamedArgs,sizeof(disp->cNamedArgs)); 695 if (hres) 696 return hres; 697 } 698 if (debugout) MESSAGE("}{"); 699 for (i=0;i<disp->cNamedArgs;i++) { 700 TYPEDESC vtdesc; 701 702 vtdesc.vt = VT_UINT; 703 serialize_param( 704 tinfo, 705 writeit, 706 debugout, 707 dealloc, 708 &vtdesc, 709 (DWORD*)(disp->rgdispidNamedArgs+i), 710 buf 711 ); 712 if (debugout && (i<disp->cNamedArgs-1)) 713 MESSAGE(","); 714 } 715 if (debugout) MESSAGE("}"); 716 if (dealloc) { 717 HeapFree(GetProcessHeap(),0,disp->rgdispidNamedArgs); 718 HeapFree(GetProcessHeap(),0,disp); 719 } 720 return S_OK; 721 } 722 723 static HRESULT 724 deserialize_param( 725 ITypeInfo *tinfo, 726 BOOL readit, 727 BOOL debugout, 728 BOOL alloc, 729 TYPEDESC *tdesc, 730 DWORD *arg, 731 marshal_state *buf 458 732 ) { 459 733 HRESULT hres = S_OK; 460 int relaydeb = TRACE_ON(olerelay); 461 462 if (!tdesc) tdesc = &(elem->tdesc); 463 switch (tdesc->vt) { 464 case VT_I4: { 465 DWORD x; 466 xbuf_get(buf,(LPBYTE)&x,sizeof(x)); 467 *arg = x; 468 if (relaydeb) MESSAGE("%ld ",x); 734 735 TRACE("vt %d at %p\n",tdesc->vt,arg); 736 737 while (1) { 738 switch (tdesc->vt) { 739 case VT_EMPTY: 740 if (debugout) MESSAGE("<empty>"); 741 return S_OK; 742 case VT_NULL: 743 if (debugout) MESSAGE("<null>"); 744 return S_OK; 745 case VT_VARIANT: { 746 VARIANT *vt = (VARIANT*)arg; 747 748 if (readit) { 749 DWORD vttype; 750 TYPEDESC tdesc2; 751 hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype)); 752 if (hres) { 753 FIXME("vt type not read?\n"); 754 return hres; 755 } 756 memset(&tdesc2,0,sizeof(tdesc2)); 757 tdesc2.vt = vttype; 758 V_VT(vt) = vttype; 759 if (debugout) MESSAGE("Vt(%ld)(",vttype); 760 hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, &(V_I4(vt)), buf); 761 MESSAGE(")"); 762 return hres; 763 } else { 764 VariantInit(vt); 765 return S_OK; 766 } 767 } 768 case VT_ERROR: 769 case VT_BOOL: case VT_I4: case VT_UI4: case VT_UINT: 770 case VT_UI2: 771 case VT_UI1: 772 if (readit) { 773 hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); 774 if (hres) FIXME("Failed to read integer 4 byte\n"); 775 } 776 if (debugout) MESSAGE("%lx",*arg); 777 return hres; 778 case VT_BSTR: { 779 WCHAR *str; 780 DWORD len; 781 782 if (readit) { 783 hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD)); 784 if (hres) { 785 FIXME("failed to read bstr klen\n"); 786 return hres; 787 } 788 if (len == -1) { 789 *arg = 0; 790 if (debugout) MESSAGE("<bstr NULL>"); 791 } else { 792 str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR)); 793 hres = xbuf_get(buf,(LPBYTE)str,len); 794 if (hres) { 795 FIXME("Failed to read BSTR.\n"); 796 return hres; 797 } 798 *arg = (DWORD)SysAllocStringLen(str,len); 799 if (debugout) MESSAGE("%s",debugstr_w(str)); 800 HeapFree(GetProcessHeap(),0,str); 801 } 802 } else { 803 *arg = 0; 804 } 805 return S_OK; 806 } 807 case VT_PTR: { 808 DWORD cookie; 809 BOOL derefhere = 0; 810 811 derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED); 812 813 if (readit) { 814 hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie)); 815 if (hres) { 816 FIXME("Failed to load pointer cookie.\n"); 817 return hres; 818 } 819 if (cookie != 0x42424242) { 820 if (debugout) MESSAGE("NULL"); 821 *arg = 0; 822 return S_OK; 823 } 824 if (debugout) MESSAGE("*"); 825 } 826 if (alloc) { 827 if (derefhere) 828 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc)); 829 } 830 if (derefhere) 831 return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf); 832 else 833 return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); 834 } 835 case VT_UNKNOWN: 836 /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ 837 if (alloc) 838 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); 839 hres = S_OK; 840 if (readit) 841 hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); 842 if (debugout) 843 MESSAGE("unk(%p)",arg); 844 return hres; 845 case VT_DISPATCH: 846 hres = S_OK; 847 if (readit) 848 hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg); 849 if (debugout) 850 MESSAGE("idisp(%p)",arg); 851 return hres; 852 case VT_VOID: 853 if (debugout) MESSAGE("<void>"); 854 return S_OK; 855 case VT_USERDEFINED: { 856 ITypeInfo *tinfo2; 857 TYPEATTR *tattr; 858 859 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); 860 if (hres) { 861 FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype); 862 return hres; 863 } 864 hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr); 865 if (hres) { 866 FIXME("Could not get typeattr in VT_USERDEFINED.\n"); 867 } else { 868 if (alloc) 869 *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance); 870 switch (tattr->typekind) { 871 case TKIND_INTERFACE: 872 if (readit) 873 hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); 874 break; 875 case TKIND_RECORD: { 876 int i; 877 878 if (debugout) MESSAGE("{"); 879 for (i=0;i<tattr->cVars;i++) { 880 VARDESC *vdesc; 881 882 hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); 883 if (hres) { 884 FIXME("Could not get vardesc of %d\n",i); 885 return hres; 886 } 887 hres = deserialize_param( 888 tinfo2, 889 readit, 890 debugout, 891 alloc, 892 &vdesc->elemdescVar.tdesc, 893 (DWORD*)(((LPBYTE)*arg)+vdesc->u.oInst), 894 buf 895 ); 896 if (debugout && (i<tattr->cVars-1)) MESSAGE(","); 897 } 898 if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID))) 899 memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid)); 900 if (debugout) MESSAGE("}"); 901 break; 902 } 903 default: 904 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind); 905 hres = E_FAIL; 906 break; 907 } 908 } 909 if (hres) 910 FIXME("failed to stuballoc in TKIND_RECORD.\n"); 911 ITypeInfo_Release(tinfo2); 912 return hres; 913 } 914 case VT_CARRAY: { 915 /* arg is pointing to the start of the array. */ 916 ARRAYDESC *adesc = tdesc->u.lpadesc; 917 int arrsize,i; 918 arrsize = 1; 919 if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n"); 920 for (i=0;i<adesc->cDims;i++) 921 arrsize *= adesc->rgbounds[i].cElements; 922 for (i=0;i<arrsize;i++) 923 deserialize_param( 924 tinfo, 925 readit, 926 debugout, 927 alloc, 928 &adesc->tdescElem, 929 (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem)), 930 buf 931 ); 932 return S_OK; 933 } 934 default: 935 ERR("No handler for VT type %d!\n",tdesc->vt); 936 return S_OK; 937 } 938 } 939 } 940 941 static HRESULT 942 deserialize_LPVOID_ptr( 943 ITypeInfo *tinfo, 944 BOOL readit, 945 BOOL debugout, 946 BOOL alloc, 947 TYPEDESC *tdesc, 948 DWORD *arg, 949 marshal_state *buf 950 ) { 951 HRESULT hres; 952 DWORD cookie; 953 954 if ((tdesc->vt != VT_PTR) || 955 (tdesc->u.lptdesc->vt != VT_PTR) || 956 (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID) 957 ) { 958 FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n"); 959 return E_FAIL; 960 } 961 if (alloc) 962 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID)); 963 if (readit) { 964 hres = xbuf_get(buf, (LPVOID)&cookie, sizeof(cookie)); 965 if (hres) 966 return hres; 967 if (cookie != 0x42424242) { 968 *(DWORD*)*arg = 0; 969 if (debugout) MESSAGE("<lpvoid NULL>"); 970 return S_OK; 971 } 972 } 973 if (readit) { 974 hres = _unmarshal_interface(buf,&buf->iid,(LPUNKNOWN*)*arg); 975 if (hres) 976 return hres; 977 } 978 if (debugout) MESSAGE("ppv(%p)",(LPVOID)*arg); 979 return S_OK; 980 } 981 982 static HRESULT 983 deserialize_DISPPARAM_ptr( 984 ITypeInfo *tinfo, 985 BOOL readit, 986 BOOL debugout, 987 BOOL alloc, 988 TYPEDESC *tdesc, 989 DWORD *arg, 990 marshal_state *buf 991 ) { 992 DWORD cookie; 993 DISPPARAMS *disps; 994 HRESULT hres; 995 int i; 996 997 if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) { 998 FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n"); 999 return E_FAIL; 1000 } 1001 if (readit) { 1002 hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie)); 1003 if (hres) 1004 return hres; 1005 if (cookie == 0) { 1006 *arg = 0; 1007 if (debugout) MESSAGE("<DISPPARAMS NULL>"); 1008 return S_OK; 1009 } 1010 } 1011 if (alloc) 1012 *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPPARAMS)); 1013 disps = (DISPPARAMS*)*arg; 1014 if (!readit) 469 1015 return S_OK; 470 } 471 case VT_PTR: 472 if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) && 473 (tdesc->u.lptdesc->vt != VT_VOID) 474 ) 475 hres = unmarshall_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)(*arg),buf); 476 else 477 hres = unmarshall_param(tinfo,elem,tdesc->u.lptdesc,arg,buf); 478 if (relaydeb) MESSAGE("%p ",(LPVOID)*arg); 479 return S_OK; 480 case VT_USERDEFINED: { 481 ITypeInfo *tinfo2; 482 TYPEATTR *tattr; 483 484 if (relaydeb) MESSAGE("%p",arg); 485 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); 486 if (hres) { 487 FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype); 488 return hres; 489 } 490 hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr); 491 if (hres) { 492 FIXME("Could not get typeattr in VT_USERDEFINED.\n"); 493 return hres; 494 } 495 switch (tattr->typekind) { 496 case TKIND_INTERFACE: 497 hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); 498 break; 499 case TKIND_RECORD: 500 hres = xbuf_get(buf,(LPBYTE)arg,tattr->cbSizeInstance); 501 break; 502 default: 503 hres = E_FAIL; 504 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind); 505 } 506 ITypeInfo_Release(tinfo2); 507 return hres; 508 } 509 case VT_VOID: 510 /* Hacky. If we are LPVOID* we apparently have to guess the IID 511 * for the interface. This sucks pretty badly. */ 512 return _unmarshal_interface(buf,&(buf->iid),(LPUNKNOWN*)arg); 513 default: ERR("Cannot unmarshal type %d\n",tdesc->vt); 514 return E_FAIL; 515 } 1016 hres = xbuf_get(buf, (LPBYTE)&disps->cArgs, sizeof(disps->cArgs)); 1017 if (hres) 1018 return hres; 1019 if (alloc) 1020 disps->rgvarg = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(VARIANT)*disps->cArgs); 1021 if (debugout) MESSAGE("D{"); 1022 for (i=0; i< disps->cArgs; i++) { 1023 TYPEDESC vdesc; 1024 1025 vdesc.vt = VT_VARIANT; 1026 hres = deserialize_param( 1027 tinfo, 1028 readit, 1029 debugout, 1030 alloc, 1031 &vdesc, 1032 (DWORD*)(disps->rgvarg+i), 1033 buf 1034 ); 1035 } 1036 if (debugout) MESSAGE("}{"); 1037 hres = xbuf_get(buf, (LPBYTE)&disps->cNamedArgs, sizeof(disps->cNamedArgs)); 1038 if (hres) 1039 return hres; 1040 if (disps->cNamedArgs) { 1041 if (alloc) 1042 disps->rgdispidNamedArgs = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPID)*disps->cNamedArgs); 1043 for (i=0; i< disps->cNamedArgs; i++) { 1044 TYPEDESC vdesc; 1045 1046 vdesc.vt = VT_UINT; 1047 hres = deserialize_param( 1048 tinfo, 1049 readit, 1050 debugout, 1051 alloc, 1052 &vdesc, 1053 (DWORD*)(disps->rgdispidNamedArgs+i), 1054 buf 1055 ); 1056 if (debugout && i<(disps->cNamedArgs-1)) MESSAGE(","); 1057 } 1058 } 1059 if (debugout) MESSAGE("}"); 516 1060 return S_OK; 517 1061 } … … 520 1064 static HRESULT 521 1065 _get_funcdesc( 522 ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc, 523 BSTR *iname, BSTR *fname 1066 ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc, BSTR *iname, BSTR *fname 524 1067 ) { 525 1068 int i = 0, j = 0; … … 569 1112 } 570 1113 return E_FAIL; 571 }572 573 /* how much space do we use on stack in DWORD steps. */574 static int575 _argsize(DWORD vt_type) {576 switch (vt_type) {577 case VT_VARIANT:578 return (sizeof(VARIANT)+3)/sizeof(DWORD);579 default:580 return 1;581 }582 1114 } 583 1115 … … 620 1152 /* Need them for hack below */ 621 1153 memset(names,0,sizeof(names)); 622 ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames); 623 if (nrofnames > sizeof(names)/sizeof(names[0])) { 1154 if (ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames)) 1155 nrofnames = 0; 1156 if (nrofnames > sizeof(names)/sizeof(names[0])) 624 1157 ERR("Need more names!\n"); 625 } 1158 626 1159 memset(&buf,0,sizeof(buf)); 627 1160 buf.iid = IID_IUnknown; … … 633 1166 for (i=0;i<fdesc->cParams;i++) { 634 1167 ELEMDESC *elem = fdesc->lprgelemdescParam+i; 1168 BOOL isserialized = FALSE; 635 1169 if (relaydeb) { 636 1170 if (i) MESSAGE(","); 637 1171 if (i+1<nrofnames && names[i+1]) 638 1172 MESSAGE("%s=",debugstr_w(names[i+1])); 639 }640 if (((i+1)<nrofnames) && !lstrcmpW(names[i+1],riidW)) {641 buf.thisisiid = TRUE;642 } else {643 buf.thisisiid = FALSE;644 1173 } 645 1174 /* No need to marshal other data than FIN */ … … 649 1178 continue; 650 1179 } 651 hres = marshall_param(tpinfo->tinfo,elem,NULL,xargs,&buf); 1180 if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) { 1181 /* If the parameter is 'riid', we use it as interface IID 1182 * for a later ppvObject serialization. 1183 */ 1184 buf.thisisiid = !lstrcmpW(names[i+1],riidW); 1185 1186 /* DISPPARAMS* needs special serializer */ 1187 if (!lstrcmpW(names[i+1],pdispparamsW)) { 1188 hres = serialize_DISPPARAM_ptr( 1189 tpinfo->tinfo, 1190 elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, 1191 relaydeb, 1192 FALSE, 1193 &elem->tdesc, 1194 xargs, 1195 &buf 1196 ); 1197 isserialized = TRUE; 1198 } 1199 if (!lstrcmpW(names[i+1],ppvObjectW)) { 1200 hres = serialize_LPVOID_ptr( 1201 tpinfo->tinfo, 1202 elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, 1203 relaydeb, 1204 FALSE, 1205 &elem->tdesc, 1206 xargs, 1207 &buf 1208 ); 1209 if (hres == S_OK) 1210 isserialized = TRUE; 1211 } 1212 } 1213 if (!isserialized) 1214 hres = serialize_param( 1215 tpinfo->tinfo, 1216 elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, 1217 relaydeb, 1218 FALSE, 1219 &elem->tdesc, 1220 xargs, 1221 &buf 1222 ); 1223 1224 if (hres) { 1225 FIXME("Failed to serialize param, hres %lx\n",hres); 1226 break; 1227 } 652 1228 xargs+=_argsize(elem->tdesc.vt); 653 if (hres) {654 FIXME("Failed to marshall param, hres %lx\n",hres);655 break;656 }657 1229 } 658 1230 } … … 667 1239 } 668 1240 memcpy(msg.Buffer,buf.base,buf.curoff); 1241 if (relaydeb) MESSAGE("\n"); 669 1242 hres = IRpcChannelBuffer_SendReceive(tpinfo->chanbuf,&msg,&status); 670 1243 if (hres) { … … 672 1245 return hres; 673 1246 } 1247 relaydeb = TRACE_ON(olerelay); 674 1248 if (relaydeb) MESSAGE(" = %08lx (",status); 675 1249 if (buf.base) … … 687 1261 for (i=0;i<fdesc->cParams;i++) { 688 1262 ELEMDESC *elem = fdesc->lprgelemdescParam+i; 1263 BOOL isdeserialized = FALSE; 689 1264 690 1265 if (relaydeb) { … … 698 1273 continue; 699 1274 } 700 hres = unmarshall_param(tpinfo->tinfo,elem,&(elem->tdesc),xargs,&buf); 701 xargs += _argsize(elem->tdesc.vt); 1275 if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) { 1276 /* If the parameter is 'riid', we use it as interface IID 1277 * for a later ppvObject serialization. 1278 */ 1279 buf.thisisiid = !lstrcmpW(names[i+1],riidW); 1280 1281 /* deserialize DISPPARAM */ 1282 if (!lstrcmpW(names[i+1],pdispparamsW)) { 1283 hres = deserialize_DISPPARAM_ptr( 1284 tpinfo->tinfo, 1285 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1286 relaydeb, 1287 FALSE, 1288 &(elem->tdesc), 1289 xargs, 1290 &buf 1291 ); 1292 if (hres) { 1293 FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres); 1294 break; 1295 } 1296 isdeserialized = TRUE; 1297 } 1298 if (!lstrcmpW(names[i+1],ppvObjectW)) { 1299 hres = deserialize_LPVOID_ptr( 1300 tpinfo->tinfo, 1301 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1302 relaydeb, 1303 FALSE, 1304 &elem->tdesc, 1305 xargs, 1306 &buf 1307 ); 1308 if (hres == S_OK) 1309 isdeserialized = TRUE; 1310 } 1311 } 1312 if (!isdeserialized) 1313 hres = deserialize_param( 1314 tpinfo->tinfo, 1315 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1316 relaydeb, 1317 FALSE, 1318 &(elem->tdesc), 1319 xargs, 1320 &buf 1321 ); 702 1322 if (hres) { 703 1323 FIXME("Failed to unmarshall param, hres %lx\n",hres); 704 1324 break; 705 1325 } 706 } 707 } 708 if (relaydeb) MESSAGE(")\n"); 1326 xargs += _argsize(elem->tdesc.vt); 1327 } 1328 } 1329 if (relaydeb) MESSAGE(")\n\n"); 709 1330 HeapFree(GetProcessHeap(),0,buf.base); 710 1331 return status; … … 721 1342 FUNCDESC *fdesc; 722 1343 TMProxyImpl *proxy; 723 1344 724 1345 TRACE("(...%s...)\n",debugstr_guid(riid)); 725 1346 hres = _get_typeinfo_for_iid(riid,&tinfo); … … 851 1472 } 852 1473 853 static HRESULT854 stuballoc_param(855 ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf856 ) {857 HRESULT hres;858 859 while (1) {860 switch (tdesc->vt) {861 case VT_VARIANT: {862 DWORD vttype;863 VARIANT *vt = (VARIANT*)arg;864 TYPEDESC tdesc2;865 866 hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));867 if (hres) return hres;868 memset(&tdesc2,0,sizeof(tdesc));869 tdesc2.vt = vttype;870 V_VT(vt) = vttype;871 return stuballoc_param(tinfo,elem,&tdesc2,&(V_I4(vt)),buf);872 }873 case VT_BOOL: case VT_I4:874 xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));875 return S_OK;876 case VT_BSTR: {877 WCHAR *str;878 DWORD len;879 880 hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));881 if (hres)882 return hres;883 str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));884 hres = xbuf_get(buf,(LPBYTE)str,len);885 if (hres) return hres;886 *arg = (DWORD)SysAllocStringLen(str,len);887 HeapFree(GetProcessHeap(),0,str);888 return S_OK;889 }890 case VT_PTR:891 if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) &&892 (tdesc->u.lptdesc->vt != VT_VOID)893 ) {894 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID));895 arg = (DWORD*)*arg;896 }897 tdesc = tdesc->u.lptdesc;898 break;899 case VT_UNKNOWN:900 /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */901 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));902 return S_OK;903 case VT_VOID:904 *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID));905 hres = S_OK;906 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN)907 hres = _unmarshal_interface(buf,&(buf->iid),(LPUNKNOWN*)arg);908 return hres;909 case VT_USERDEFINED: {910 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN) {911 ITypeInfo *tinfo2;912 TYPEATTR *tattr;913 914 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);915 if (hres) {916 FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);917 return hres;918 }919 hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);920 if (hres) {921 FIXME("Could not get typeattr in VT_USERDEFINED.\n");922 return hres;923 }924 switch (tattr->typekind) {925 case TKIND_INTERFACE:926 hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);927 break;928 case TKIND_RECORD:929 *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance);930 hres = xbuf_get(buf,(LPBYTE)*arg,tattr->cbSizeInstance);931 if (buf->thisisiid)932 memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid));933 break;934 default:935 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);936 hres = E_FAIL;937 break;938 }939 ITypeInfo_Release(tinfo2);940 return hres;941 } else {942 *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID));943 return S_OK;944 }945 }946 default:947 ERR("No handler for VT type %d, just allocating 4 bytes.\n",tdesc->vt);948 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));949 return S_OK;950 }951 }952 }953 954 static HRESULT955 stubunalloc_param(956 ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf957 ) {958 HRESULT hres = S_OK;959 960 if (!tdesc) tdesc = &(elem->tdesc);961 962 switch (tdesc->vt) {963 case VT_BOOL:964 case VT_I4:965 hres = S_OK;966 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)967 hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));968 return hres;969 case VT_VARIANT: {970 TYPEDESC tdesc2;971 VARIANT *vt = (VARIANT*)arg;972 DWORD vttype = V_VT(vt);973 974 tdesc2.vt = vttype;975 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {976 hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));977 if (hres) return hres;978 }979 /* need to recurse since we need to free the stuff */980 hres = stubunalloc_param(tinfo,elem,&tdesc2,&(V_I4(vt)),buf);981 return hres;982 }983 case VT_BSTR: {984 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {985 DWORD *bstr = ((DWORD*)(*arg))-1;986 987 hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);988 if (hres)989 return hres;990 }991 SysFreeString((BSTR)*arg);992 return S_OK;993 }994 case VT_PTR:995 /*FIXME("VT_PTR *arg is %p\n",(LPVOID)*arg);*/996 if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) &&997 (tdesc->u.lptdesc->vt != VT_VOID)998 ) {999 hres = stubunalloc_param(tinfo,elem,tdesc->u.lptdesc,arg,buf);1000 } else {1001 hres = stubunalloc_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)*arg,buf);1002 HeapFree(GetProcessHeap(),0,(LPVOID)*arg);1003 }1004 return hres;1005 case VT_UNKNOWN:1006 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {1007 FIXME("Marshaling back VT_UNKNOWN %lx\n",*arg);1008 hres = xbuf_add(buf,(LPBYTE)*arg,sizeof(DWORD));1009 }1010 HeapFree(GetProcessHeap(),0,(LPVOID)*arg);1011 return hres;1012 case VT_VOID:1013 hres = S_OK;1014 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)1015 hres = _marshal_interface(buf,&(buf->iid),(LPUNKNOWN)*arg);1016 return hres;1017 case VT_USERDEFINED: {1018 ITypeInfo *tinfo2;1019 TYPEATTR *tattr;1020 1021 if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {1022 /*FIXME("VT_USERDEFINED arg is %p, *arg is %p\n",arg,*arg);*/1023 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);1024 if (hres) {1025 FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);1026 return hres;1027 }1028 ITypeInfo_GetTypeAttr(tinfo2,&tattr);1029 switch (tattr->typekind) {1030 case TKIND_INTERFACE:1031 hres = _marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)*arg);1032 break;1033 case TKIND_RECORD:1034 hres = xbuf_add(buf,(LPBYTE)arg,tattr->cbSizeInstance);1035 break;1036 default:1037 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);1038 hres = E_FAIL;1039 break;1040 }1041 ITypeInfo_Release(tinfo2);1042 }1043 return hres;1044 }1045 default:1046 ERR("Unhandled marshal type %d.\n",tdesc->vt);1047 HeapFree(GetProcessHeap(),0,(LPVOID)*arg);1048 return S_OK;1049 }1050 }1051 1052 1474 static HRESULT WINAPI 1053 1475 TMStubImpl_Invoke( … … 1104 1526 for (i=0;i<fdesc->cParams;i++) { 1105 1527 ELEMDESC *elem = fdesc->lprgelemdescParam+i; 1106 1107 if (((i+1)<nrofnames) && !lstrcmpW(names[i+1],riidW)) 1108 buf.thisisiid = TRUE; 1109 else 1110 buf.thisisiid = FALSE; 1111 hres = stuballoc_param(This->tinfo,elem,&(elem->tdesc),xargs,&buf); 1528 BOOL isdeserialized = FALSE; 1529 1530 if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) { 1531 /* If the parameter is 'riid', we use it as interface IID 1532 * for a later ppvObject serialization. 1533 */ 1534 buf.thisisiid = !lstrcmpW(names[i+1],riidW); 1535 1536 /* deserialize DISPPARAM */ 1537 if (!lstrcmpW(names[i+1],pdispparamsW)) { 1538 hres = deserialize_DISPPARAM_ptr( 1539 This->tinfo, 1540 elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, 1541 FALSE, 1542 TRUE, 1543 &(elem->tdesc), 1544 xargs, 1545 &buf 1546 ); 1547 if (hres) { 1548 FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres); 1549 break; 1550 } 1551 isdeserialized = TRUE; 1552 } 1553 if (!lstrcmpW(names[i+1],ppvObjectW)) { 1554 hres = deserialize_LPVOID_ptr( 1555 This->tinfo, 1556 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1557 FALSE, 1558 TRUE, 1559 &elem->tdesc, 1560 xargs, 1561 &buf 1562 ); 1563 if (hres == S_OK) 1564 isdeserialized = TRUE; 1565 } 1566 } 1567 if (!isdeserialized) 1568 hres = deserialize_param( 1569 This->tinfo, 1570 elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, 1571 FALSE, 1572 TRUE, 1573 &(elem->tdesc), 1574 xargs, 1575 &buf 1576 ); 1112 1577 xargs += _argsize(elem->tdesc.vt); 1113 1578 if (hres) { 1114 FIXME("Failed to stuballocparam %s, hres %lx\n",debugstr_w(names[i+1]),hres);1579 FIXME("Failed to deserialize param %s, hres %lx\n",debugstr_w(names[i+1]),hres); 1115 1580 break; 1116 1581 } … … 1132 1597 for (i=0;i<fdesc->cParams;i++) { 1133 1598 ELEMDESC *elem = fdesc->lprgelemdescParam+i; 1134 hres = stubunalloc_param(This->tinfo,elem,NULL,xargs,&buf); 1599 BOOL isserialized = FALSE; 1600 1601 if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) { 1602 /* If the parameter is 'riid', we use it as interface IID 1603 * for a later ppvObject serialization. 1604 */ 1605 buf.thisisiid = !lstrcmpW(names[i+1],riidW); 1606 1607 /* DISPPARAMS* needs special serializer */ 1608 if (!lstrcmpW(names[i+1],pdispparamsW)) { 1609 hres = serialize_DISPPARAM_ptr( 1610 This->tinfo, 1611 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1612 FALSE, 1613 TRUE, 1614 &elem->tdesc, 1615 xargs, 1616 &buf 1617 ); 1618 isserialized = TRUE; 1619 } 1620 if (!lstrcmpW(names[i+1],ppvObjectW)) { 1621 hres = serialize_LPVOID_ptr( 1622 This->tinfo, 1623 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1624 FALSE, 1625 TRUE, 1626 &elem->tdesc, 1627 xargs, 1628 &buf 1629 ); 1630 if (hres == S_OK) 1631 isserialized = TRUE; 1632 } 1633 } 1634 if (!isserialized) 1635 hres = serialize_param( 1636 This->tinfo, 1637 elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, 1638 FALSE, 1639 TRUE, 1640 &elem->tdesc, 1641 xargs, 1642 &buf 1643 ); 1135 1644 xargs += _argsize(elem->tdesc.vt); 1136 1645 if (hres) { -
trunk/src/oleaut32/typelib.c
r8450 r8640 2913 2913 len = *(DWORD*)(pAfterOTIBlks + 2); 2914 2914 2915 /* Now add this to pLibBLk and then add 0x216, sprinkle a bit a 2916 magic dust and we should be pointing at the beginning of the name 2915 /* Now add this to pLibBLk look at what we're pointing at and 2916 possibly add 0x20, then add 0x216, sprinkle a bit a magic 2917 dust and we should be pointing at the beginning of the name 2917 2918 table */ 2918 2919 pNameTable = (char*)pLibBlk + len + 0x216; 2919 2920 pNameTable = (char*)pLibBlk + len; 2921 2922 switch(*(WORD*)pNameTable) { 2923 case 0xffff: 2924 break; 2925 case 0x0200: 2926 pNameTable += 0x20; 2927 break; 2928 default: 2929 FIXME("pNameTable jump = %x\n", *(WORD*)pNameTable); 2930 break; 2931 } 2920 2932 2933 pNameTable += 0x216; 2934 2921 2935 pNameTable += 2; 2922 2936 … … 4044 4058 DWORD (* WINAPI xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func; 4045 4059 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6]); 4060 break; 4061 } 4062 case 8: { 4063 DWORD (* WINAPI xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func; 4064 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); 4065 break; 4066 } 4067 case 9: { 4068 DWORD (* WINAPI xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func; 4069 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); 4046 4070 break; 4047 4071 } … … 4086 4110 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6]); 4087 4111 break; 4112 } 4113 case 8: { 4114 DWORD (WINAPI *xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func; 4115 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); 4116 break; 4117 } 4118 case 9: { 4119 DWORD (WINAPI *xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func; 4120 res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); 4121 break; 4088 4122 } 4089 4123 #endif -
trunk/src/oleaut32/typelib.h
r8450 r8640 50 50 * structure of the typelib type2 header 51 51 * it is at the beginning of a type lib file 52 * 52 * 53 53 */ 54 54 typedef struct tagMSFT_Header { … … 192 192 } MSFT_FuncRecord; 193 193 194 /* after this may follow an array with default value pointers if the 195 * appropriate bit in the FKCCIC field has been set: 194 /* after this may follow an array with default value pointers if the 195 * appropriate bit in the FKCCIC field has been set: 196 196 * INT oDefautlValue[nrargs]; 197 197 */ … … 304 304 305 305 /* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These 306 are p ersumbably unique to within the file and look something like306 are presumably unique to within the file and look something like 307 307 "AAAAAAAAAA" with the first character incremented from 'A' to ensure 308 308 uniqueness. I guess successive chars increment when we need to wrap … … 358 358 WORD name_offs; /* offset to name in name table */ 359 359 WORD more_bytes; /* if this is non-zero we get this many 360 bytes before the next element, which seem 360 bytes before the next element, which seem 361 361 to reference the docstring of the type ? */ 362 362 WORD res20; /* 0xffff */ … … 457 457 WORD rettype; /* return type VT_?? or offset to ret type */ 458 458 WORD vtblpos; /* position in vtbl? */ 459 WORD funcflags; /* present if magic == 0x6c */ 459 WORD funcflags; /* present if magic == 0x6c */ 460 460 /* Param list starts, repeat next two as required */ 461 461 #if 0 -
trunk/src/shell32/dialogs.c
r8614 r8640 1 /* $Id: dialogs.c,v 1.3 2002-06-09 12:41:20 sandervl Exp $ */2 1 /* 3 2 * common shell dialogs 3 * 4 * Copyright 2000 Juergen Schmied 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 4 19 */ 5 #ifdef __WIN32OS2__ 6 #define ICOM_CINTERFACE 1 7 #include <odin.h> 8 #endif 20 9 21 #include <string.h> 10 22 #include <stdio.h> 11 23 #include "winerror.h" 12 #include "debugtools.h" 24 #include "winreg.h" 25 #include "commdlg.h" 26 #include "wine/debug.h" 13 27 14 28 #include "shellapi.h" … … 17 31 #include "undocshell.h" 18 32 19 DEFAULT_DEBUG_CHANNEL(shell); 33 typedef struct 34 { 35 HWND hwndOwner ; 36 HICON hIcon ; 37 LPCSTR lpstrDirectory ; 38 LPCSTR lpstrTitle ; 39 LPCSTR lpstrDescription ; 40 UINT uFlags ; 41 } RUNFILEDLGPARAMS ; 42 43 typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ; 44 45 WINE_DEFAULT_DEBUG_CHANNEL(shell); 46 BOOL CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ; 47 void FillList (HWND, char *) ; 20 48 21 49 22 50 /************************************************************************* 23 51 * PickIconDlg [SHELL32.62] 24 * 52 * 25 53 */ 26 54 BOOL WINAPI PickIconDlg( … … 49 77 UINT uFlags) 50 78 { 51 FIXME("(0x%04x 0x%04x %s %s %s 0x%08x):stub.\n", 52 hwndOwner, hIcon, lpstrDirectory, lpstrTitle, lpstrDescription, uFlags); 79 80 RUNFILEDLGPARAMS rfdp = {hwndOwner, hIcon, lpstrDirectory, lpstrTitle, lpstrDescription, uFlags} ; 81 HRSRC hRes; 82 LPVOID template; 83 TRACE("\n"); 84 85 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_RUN_DLG", RT_DIALOGA))) 86 { 87 MessageBoxA (hwndOwner, "Couldn't find dialog.", "Nix", MB_OK) ; 88 return; 89 } 90 if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes))) 91 { 92 MessageBoxA (hwndOwner, "Couldn't load dialog.", "Nix", MB_OK) ; 93 return; 94 } 95 96 DialogBoxIndirectParamA(GetWindowLongA( hwndOwner, GWL_HINSTANCE ), 97 template, hwndOwner, RunDlgProc, (LPARAM)&rfdp); 98 53 99 } 100 101 /* Dialog procedure for RunFileDlg */ 102 BOOL CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 103 { 104 int ic ; 105 char *psz, szMsg[256] ; 106 static RUNFILEDLGPARAMS *prfdp = NULL ; 107 108 switch (message) 109 { 110 case WM_INITDIALOG : 111 prfdp = (RUNFILEDLGPARAMS *)lParam ; 112 SetWindowTextA (hwnd, prfdp->lpstrTitle) ; 113 SetClassLongA (hwnd, GCL_HICON, prfdp->hIcon) ; 114 SendMessageA (GetDlgItem (hwnd, 12297), STM_SETICON, (WPARAM)LoadIconA ((HINSTANCE)NULL, IDI_WINLOGOA), 0) ; 115 FillList (GetDlgItem (hwnd, 12298), NULL) ; 116 SetFocus (GetDlgItem (hwnd, 12298)) ; 117 return TRUE ; 118 119 case WM_COMMAND : 120 { 121 STARTUPINFOA si ; 122 PROCESS_INFORMATION pi ; 123 124 si.cb = sizeof (STARTUPINFOA) ; 125 si.lpReserved = NULL ; 126 si.lpDesktop = NULL ; 127 si.lpTitle = NULL ; 128 si.dwX = 0 ; 129 si.dwY = 0 ; 130 si.dwXSize = 0 ; 131 si.dwYSize = 0 ; 132 si.dwXCountChars = 0 ; 133 si.dwYCountChars = 0 ; 134 si.dwFillAttribute = 0 ; 135 si.dwFlags = 0 ; 136 si.cbReserved2 = 0 ; 137 si.lpReserved2 = NULL ; 138 139 switch (LOWORD (wParam)) 140 { 141 case IDOK : 142 { 143 HWND htxt = (HWND)NULL ; 144 if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298)))) 145 { 146 psz = malloc (ic + 2) ; 147 GetWindowTextA (htxt, psz, ic + 1) ; 148 149 if (!CreateProcessA (NULL, psz, NULL, NULL, TRUE, 150 NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 151 { 152 char *pszSysMsg = NULL ; 153 FormatMessageA ( 154 FORMAT_MESSAGE_ALLOCATE_BUFFER | 155 FORMAT_MESSAGE_FROM_SYSTEM | 156 FORMAT_MESSAGE_IGNORE_INSERTS, 157 NULL, GetLastError (), 158 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 159 (LPSTR)&pszSysMsg, 0, NULL 160 ) ; 161 sprintf (szMsg, "Error: %s", pszSysMsg) ; 162 LocalFree ((HLOCAL)pszSysMsg) ; 163 MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ; 164 165 free (psz) ; 166 SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 167 return TRUE ; 168 } 169 FillList (htxt, psz) ; 170 free (psz) ; 171 EndDialog (hwnd, 0) ; 172 } 173 } 174 175 case IDCANCEL : 176 EndDialog (hwnd, 0) ; 177 return TRUE ; 178 179 case 12288 : 180 { 181 HMODULE hComdlg = (HMODULE)NULL ; 182 LPFNOFN ofnProc = NULL ; 183 static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ; 184 static OPENFILENAMEA ofn = 185 { 186 sizeof (OPENFILENAMEA), 187 (HWND)NULL, 188 (HINSTANCE)NULL, 189 "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0", 190 (LPSTR)NULL, 191 0, 192 0, 193 szFName, 194 1023, 195 szFileTitle, 196 255, 197 (LPCSTR)szInitDir, 198 "Browse", 199 OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, 200 0, 201 0, 202 (LPCSTR)NULL, 203 0, 204 (LPOFNHOOKPROC)NULL, 205 (LPCSTR)NULL 206 } ; 207 208 ofn.hwndOwner = hwnd ; 209 210 if ((HMODULE)NULL == (hComdlg = LoadLibraryExA ("comdlg32", (HANDLE)NULL, 0))) 211 { 212 MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; 213 return TRUE ; 214 } 215 216 if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA"))) 217 { 218 MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; 219 return TRUE ; 220 } 221 222 ofnProc (&ofn) ; 223 224 SetFocus (GetDlgItem (hwnd, IDOK)) ; 225 SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ; 226 SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 227 SetFocus (GetDlgItem (hwnd, IDOK)) ; 228 229 FreeLibrary (hComdlg) ; 230 231 return TRUE ; 232 } 233 } 234 return TRUE ; 235 } 236 } 237 238 /* This should be DefDlgProcA, but that doesn't work */ 239 return FALSE ; 240 } 241 242 /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */ 243 void FillList (HWND hCb, char *pszLatest) 244 { 245 HKEY hkey ; 246 /* char szDbgMsg[256] = "" ; */ 247 char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ; 248 DWORD icList = 0, icCmd = 0 ; 249 int Nix ; 250 251 SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ; 252 253 if (ERROR_SUCCESS != RegCreateKeyExA ( 254 HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU", 255 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL)) 256 MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ; 257 258 if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList)) 259 MessageBoxA (hCb, "Unable to grab size for MRUList !", "Nix", MB_OK) ; 260 if (icList > 0) 261 { 262 pszList = malloc (icList) ; 263 if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, pszList, &icList)) 264 MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK) ; 265 } 266 else 267 { 268 pszList = malloc (icList = 1) ; 269 pszList[0] = 0 ; 270 } 271 272 for (Nix = 0 ; Nix < icList - 1 ; Nix++) 273 { 274 if (pszList[Nix] > cMax) 275 cMax = pszList[Nix] ; 276 277 szIndex[0] = pszList[Nix] ; 278 279 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd)) 280 MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ; 281 pszCmd = realloc (pszCmd, icCmd) ; 282 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, pszCmd, &icCmd)) 283 MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ; 284 285 if (NULL != pszLatest) 286 { 287 if (!strcasecmp (pszCmd, pszLatest)) 288 { 289 /* 290 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ; 291 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; 292 */ 293 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ; 294 SetWindowTextA (hCb, pszCmd) ; 295 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 296 297 cMatch = pszList[Nix] ; 298 memmove (&pszList[1], pszList, Nix) ; 299 pszList[0] = cMatch ; 300 continue ; 301 } 302 } 303 304 if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest) 305 { 306 /* 307 sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ; 308 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; 309 */ 310 SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ; 311 if (!Nix) 312 { 313 SetWindowTextA (hCb, pszCmd) ; 314 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 315 } 316 317 } 318 else 319 { 320 /* 321 sprintf (szDbgMsg, "Doing loop thing.\n") ; 322 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; 323 */ 324 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ; 325 SetWindowTextA (hCb, pszLatest) ; 326 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 327 328 cMatch = pszList[Nix] ; 329 memmove (&pszList[1], pszList, Nix) ; 330 pszList[0] = cMatch ; 331 szIndex[0] = cMatch ; 332 RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ; 333 } 334 } 335 336 if (!cMatch && NULL != pszLatest) 337 { 338 /* 339 sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ; 340 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; 341 */ 342 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ; 343 SetWindowTextA (hCb, pszLatest) ; 344 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; 345 346 cMatch = ++cMax ; 347 pszList = realloc (pszList, ++icList) ; 348 memmove (&pszList[1], pszList, icList - 1) ; 349 pszList[0] = cMatch ; 350 szIndex[0] = cMatch ; 351 RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ; 352 } 353 354 RegSetValueExA (hkey, "MRUList", 0, REG_SZ, pszList, strlen (pszList) + 1) ; 355 356 free (pszCmd) ; 357 free (pszList) ; 358 } 54 359 55 360 /************************************************************************* … … 63 368 TRACE("(0x%08x)\n", hWndOwner); 64 369 #ifdef __WIN32OS2__ 65 if (MessageBoxA( hWndOwner, "Do you want to exit Odin?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == ID OK)370 if (MessageBoxA( hWndOwner, "Do you want to exit Odin?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == IDYES) 66 371 #else 67 if (MessageBoxA( hWndOwner, "Do you want to exit WINE?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == ID OK)372 if (MessageBoxA( hWndOwner, "Do you want to exit WINE?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == IDYES) 68 373 #endif 69 374 { -
trunk/src/shell32/resources/shell32_En.orc
r8594 r8640 1 /* $Id: shell32_En.orc,v 1. 1 2002-06-08 07:27:00sandervl Exp $ */1 /* $Id: shell32_En.orc,v 1.2 2002-06-11 06:30:56 sandervl Exp $ */ 2 2 LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT 3 3 … … 29 29 } 30 30 #endif 31 32 SHELL_RUN_DLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 227, 95 33 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 34 CAPTION "" 35 FONT 8, "Helv" 36 { 37 ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE 38 LTEXT "Type the name of a program, folder, document, or Internet resource, and Wine will open it for you.", 12289, 36, 11, 182, 18 39 LTEXT "&Open:", 12305, 7, 39, 24, 10 40 CONTROL "", 12298, "COMBOBOX", WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_DISABLENOSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 41 DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP 42 PUSHBUTTON "Cancel", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP 43 PUSHBUTTON "&Browse...", 12288, 170, 63, 50, 14, WS_TABSTOP 44 } 31 45 32 46 /* columns in the shellview */
Note:
See TracChangeset
for help on using the changeset viewer.