- Timestamp:
- May 30, 2001, 7:43:39 PM (24 years ago)
- Location:
- trunk/src/oleaut32
- Files:
-
- 2 added
- 4 edited
-
asmutil.asm (added)
-
asmutil.h (added)
-
itypeinfo.cpp (modified) (3 diffs)
-
makefile (modified) (2 diffs)
-
typelib.cpp (modified) (3 diffs)
-
variant.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/oleaut32/itypeinfo.cpp
r4962 r5840 1 /* $Id: itypeinfo.cpp,v 1. 5 2001-01-18 18:12:20sandervl Exp $ */1 /* $Id: itypeinfo.cpp,v 1.6 2001-05-30 17:43:38 sandervl Exp $ */ 2 2 /* 3 3 * ITypeInfo interface … … 16 16 #include "olectl.h" 17 17 #include "itypelib.h" 18 #include <debugtools.h> 19 #include "asmutil.h" 18 20 19 21 HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, … … 463 465 // 464 466 // ---------------------------------------------------------------------- 467 /** 468 * Coerce arguments and, if necessary, sorts named arguments in the order 469 * specified in the function's FUNCDESC 470 * 471 * NOTE: the arguments are left in reverse order by design. 472 * (see INVOKE_InvokeStdCallFunction for more information) 473 */ 474 static HRESULT 475 INVOKE_AllocateCoerceAndSortArguments(FUNCDESC* pFuncDesc, 476 DISPPARAMS* pDispParams, 477 VARIANTARG** ppaArgsCoerced, 478 unsigned int* puBadArg) 479 { 480 HRESULT hr; 481 UINT index; 482 483 VARIANTARG* paArgsCoerced = (VARIANTARG*)HeapAlloc(GetProcessHeap(), 484 HEAP_ZERO_MEMORY, 485 pDispParams->cArgs * sizeof(VARIANTARG)); 486 487 if ( !paArgsCoerced ) 488 { 489 hr = E_OUTOFMEMORY; 490 goto cleanup; 491 } 492 493 if ( !pDispParams->cNamedArgs ) 494 { 495 /* "Arguments are stored in pDispParams->rgvarg in reverse order" 496 * 497 * Windows Platform SDK, IDispatch::Invoke. 498 * See puArgErr argument description. 499 */ 500 VARIANTARG* paSrcArg = &pDispParams->rgvarg[pDispParams->cArgs - 1]; 501 VARIANTARG* paDstArg = &paArgsCoerced[pDispParams->cArgs - 1]; 502 503 /* sanity check to verify we have enough required 504 * arguments to call the method 505 */ 506 if ( pDispParams->cArgs < pFuncDesc->cParams - pFuncDesc->cParamsOpt ) 507 { 508 hr = DISP_E_BADPARAMCOUNT; 509 goto cleanup; 510 } 511 512 /* coerce all the arguments, if required */ 513 for ( index = 0; 514 index < pDispParams->cArgs; 515 ++index, --paSrcArg, --paDstArg ) 516 { 517 /* checks if the VARTYPEs matches */ 518 VARTYPE vtdest = pFuncDesc->lprgelemdescParam[index].tdesc.vt; 519 520 if ( V_VT(paSrcArg) != vtdest ) 521 { 522 USHORT wFlags = 0; 523 524 /* we don't use VariantChangeTypeEx 525 * because we assume system lcid (e.g. 0) 526 */ 527 hr = VariantChangeType(paDstArg, paSrcArg, wFlags, vtdest); 528 529 if ( FAILED(hr) ) goto bad_arg_err; 530 } 531 else 532 { 533 hr = VariantCopy(paDstArg, paSrcArg); 534 535 if ( FAILED(hr) ) goto bad_arg_err; 536 } 537 } 538 } 539 else 540 { 541 FIXME("Named arguments not supported!\n"); 542 /* 543 named arguments not supported ? 544 hr = DISP_E_NONAMEDARGS 545 546 For each argument 547 Check if DISPID can be found in typeinfo 548 549 Found -> 550 required argument? 551 yes -> increase required argument counter. next. 552 no -> next. 553 554 Not Found -> DISP_E_PARAMNOTFOUND, puBadArg = arg index. 555 556 if function required arguments != counter 557 DISP_E_PARAMNOTOPTIONAL 558 559 Coerce arguments at the right spot in the variant array 560 */ 561 } 562 563 hr = S_OK; 564 *ppaArgsCoerced = paArgsCoerced; 565 return hr; 566 567 568 bad_arg_err: 569 *puBadArg = index; 570 571 cleanup: 572 if ( paArgsCoerced ) 573 { 574 HeapFree(GetProcessHeap(), 0, paArgsCoerced); 575 } 576 577 return hr; 578 } 579 580 /* 581 static 582 WINE_EXCEPTION_FILTER(INVOKE_ExceptionHandler) 583 { 584 FIXME("Exception handler currently does nothing.\n"); 585 return EXCEPTION_EXECUTE_HANDLER; 586 } 587 */ 588 589 static HRESULT 590 INVOKE_InvokeStdCallFunction(IUnknown* pIUnk, 591 FUNCDESC* pFuncDesc, 592 VARIANTARG* paArgsCoerced, 593 VARIANT* pVarResult, 594 EXCEPINFO* pExcepInfo) 595 { 596 typedef DWORD (WINAPI *pDWORDRetFunc) (IUnknown*); 597 typedef double (WINAPI *pDoubleRetFunc)(IUnknown*); 598 599 HRESULT hr = E_FAIL; 600 601 DWORD dwVtblBaseAddr; /* address of vtbl */ 602 DWORD dwFuncAddr; /* address of method */ 603 DWORD paramsize = 0; 604 605 int i; /* index of argument */ 606 607 /* Process method arguments. 608 * 609 * Following stdcall convention, arguments are pushed on the stack from 610 * right to left. However, since they were stored in reverse order 611 * in DISPPARAMS structure (and left in that order during coercion) 612 * we push the arguments from 0 to cArgs - 1. 613 */ 614 DWORD *pStack = (DWORD *)alloca(sizeof(double)*pFuncDesc->cParams + 8); 615 PBYTE pStackPtr = (PBYTE)((char *)pStack + sizeof(double)*pFuncDesc->cParams); 616 617 //Don't include the pIUnknown parameter 618 for ( i = 0; i < pFuncDesc->cParams; ++i ) 619 { 620 /* Decision of pushing 32 or 64 bits is based on argument's VARTYPE */ 621 VARIANT* pVar = &(paArgsCoerced[i]); 622 PVOID pValue = &(pVar->cVal); 623 624 if(pVar == NULL) {//TODO: Is this correct? 625 /* push 32 bits on stack */ 626 pStackPtr -= sizeof(DWORD); 627 * (DWORD*) pStackPtr = 0; 628 629 paramsize += sizeof(DWORD); 630 } 631 else 632 switch ( V_VT(pVar) ) 633 { 634 /* QUAD-sized values */ 635 case VT_R8: 636 case VT_DATE: 637 /* push 64 bits on stack */ 638 pStackPtr -= sizeof(double); 639 * (double*) pStackPtr = *(double*) pValue; 640 641 paramsize += sizeof(double); 642 break; 643 644 /* DWORD-sized values */ 645 default: 646 /* push 32 bits on stack */ 647 pStackPtr -= sizeof(DWORD); 648 * (DWORD*) pStackPtr = * (DWORD*) pValue; 649 650 paramsize += sizeof(DWORD); 651 break; 652 } 653 } 654 /* assign function pointer to ITypeImpl->vtbl[index] */ 655 dwVtblBaseAddr = (DWORD) ((IUnknown*) pIUnk)->lpVtbl; 656 dwFuncAddr = * (DWORD*) (dwVtblBaseAddr + pFuncDesc->oVft); 657 658 /* remove comments around __TRY for SEH 659 __TRY 660 */ 661 { 662 DWORD dwRet = 0; 663 double dblRet = 0; 664 665 //push pIUnk 666 pStackPtr -= sizeof(DWORD); 667 * (DWORD*) pStackPtr = * (DWORD*) pIUnk; 668 paramsize += sizeof(DWORD); 669 670 /* invoke function */ 671 if ( pFuncDesc->elemdescFunc.tdesc.vt == VT_R8 || 672 pFuncDesc->elemdescFunc.tdesc.vt == VT_DATE ) 673 { 674 dblRet = invokeStdCallDouble((PVOID)dwFuncAddr, paramsize/4, pStackPtr); 675 } 676 else 677 { 678 dwRet = invokeStdCallDword((PVOID)dwFuncAddr, paramsize/4, pStackPtr); 679 } 680 681 /* fill result variant */ 682 if ( pVarResult ) 683 { 684 pVarResult->vt = pFuncDesc->elemdescFunc.tdesc.vt; 685 686 if ( pFuncDesc->elemdescFunc.tdesc.vt == VT_R8 || 687 pFuncDesc->elemdescFunc.tdesc.vt == VT_DATE ) 688 { 689 V_UNION(pVarResult, dblVal) = dblRet; 690 } 691 else 692 { 693 V_UNION(pVarResult, lVal) = dwRet; 694 } 695 } 696 hr = S_OK; 697 } 698 699 /* remove comments to enable SEH 700 __EXCEPT (INVOKE_ExceptionHandler); 701 __ENDTRY; 702 */ 703 704 return hr; 705 } 706 707 static BOOL 708 INVOKE_RetrieveFuncDesc(oListIter<TLBFuncDesc *> itrFunc, 709 MEMBERID memid, 710 UINT16 wFlags, 711 FUNCDESC** ppFuncDesc) 712 { 713 BOOL bFound = FALSE; 714 715 // Search functions... 716 for (itrFunc.MoveStart(); itrFunc.IsValid(); itrFunc.MoveNext()) 717 { 718 if (itrFunc.Element()->funcdesc.memid == memid && 719 itrFunc.Element()->funcdesc.invkind == wFlags) 720 { 721 *ppFuncDesc = &(itrFunc.Element()->funcdesc); 722 return TRUE; 723 } 724 } 725 726 return(bFound); 727 } 728 729 static HRESULT 730 INVOKE_DeferToParentTypeInfos(ITypeInfo2* iface, 731 VOID* pIUnk, 732 MEMBERID memid, 733 UINT16 wFlags, 734 DISPPARAMS* pDispParams, 735 VARIANT* pVarResult, 736 EXCEPINFO* pExcepInfo, 737 UINT* puArgErr) 738 { 739 HRESULT hr = E_FAIL; 740 741 unsigned short index; 742 ITypeInfo* pRefTypeInfo = NULL; 743 744 /* retrieve ITypeInfoImpl ptr from ITypeInfo ptr */ 745 ICOM_THIS( ITypeInfoImpl, iface); 746 /* call Invoke on implemented type */ 747 for ( index = 0; index < This->TypeAttr.cImplTypes ; ++index ) 748 { 749 HREFTYPE hRef; 750 751 hr = ITypeInfo_GetRefTypeOfImplType(iface, index, &hRef); 752 753 if ( FAILED(hr) ) 754 { 755 hr = DISP_E_MEMBERNOTFOUND; 756 goto cleanup; 757 } 758 759 hr = ITypeInfo_GetRefTypeInfo(iface, hRef, &pRefTypeInfo); 760 761 if ( FAILED(hr) ) 762 { 763 hr = DISP_E_MEMBERNOTFOUND; 764 goto cleanup; 765 } 766 767 hr = ITypeInfo_Invoke(pRefTypeInfo, 768 pIUnk, 769 memid, 770 wFlags, 771 pDispParams, 772 pVarResult, 773 pExcepInfo, 774 puArgErr); 775 776 if ( hr == S_OK ) 777 break; 778 } 779 cleanup: 780 if (pRefTypeInfo) 781 ITypeInfo2_Release(pRefTypeInfo); 782 783 return hr; 784 } 785 /** 786 * ITypeInfo::Invoke 787 * 788 * Invokes a method, or accesses a property of an object, that implements the 789 * interface described by the type description. 790 * 791 * Handles all the "magic" between your Automation controller 792 * and components. 793 * 794 * 1. Find the method's position in the vtable based on 795 * the dispid and the information contained in the type library. 796 * 797 * 2. Push all the arguments on the stack, accordingly to the __stdcall 798 * calling convention, e.g. right to left. 799 * 800 * 3. Coerce the retrieved value as the variant type stored in the type library. 801 * 802 * 4. Store return value in VarResult variant 803 * 804 * 5. Return to the Invoke() caller the return value for dispid method. 805 * 806 * NOT SUPPORTED : inherited types 807 * 808 */ 465 809 HRESULT WIN32API ITypeInfoImpl_Invoke(ITypeInfo2 * iface, 466 VOID *pIUnk, MEMBERID memid, UINT16 dwFlags,810 VOID *pIUnk, MEMBERID memid, UINT16 wFlags, 467 811 DISPPARAMS *pDispParams, VARIANT *pVarResult, 468 EXCEPINFO *pExcepInfo, UINT *pArgErr) 469 { 470 ICOM_THIS(ITypeInfoImpl, iface); 471 472 dprintf(("OLEAUT32: ITypeInfoImpl(%p)->Invoke() STUB!\n", This)); 473 474 return E_NOTIMPL; 812 EXCEPINFO *pExcepInfo, UINT *puArgErr) 813 { 814 ICOM_THIS(ITypeInfoImpl, iface); 815 HRESULT hr = E_FAIL; 816 FUNCDESC* pFuncDesc; 817 VARIANT* paArgsCoerced = NULL; /* coerced arguments */ 818 BOOL bFound; /* function found */ 819 820 821 dprintf(("TypeInfo_fnInvoke: (%p) (%p, memid=0x%08lx, 0x%08x, %p, %p, %p, %p)", 822 This, pIUnk, memid, wFlags, 823 pDispParams, pVarResult, pExcepInfo, puArgErr )); 824 825 // dump_TypeInfo(This); 826 827 if ( pDispParams ) 828 { 829 // dump_DispParms(pDispParams); 830 831 if ( pDispParams->cNamedArgs != pDispParams->cArgs ) 832 { 833 WARN("named arguments count differs from number of arguments!\n"); 834 } 835 } 836 837 if ( memid < 0 ) 838 { 839 FIXME("standard MEMBERID resolution not fully implemented\n"); 840 841 switch ( memid ) 842 { 843 case DISPID_CONSTRUCTOR: 844 memid = This->TypeAttr.memidConstructor; 845 break; 846 case DISPID_DESTRUCTOR: 847 memid = This->TypeAttr.memidDestructor; 848 break; 849 case DISPID_UNKNOWN: 850 default: 851 return DISP_E_MEMBERNOTFOUND; 852 } 853 } 854 855 /* REMINDER: 856 * 857 * "properties are an equivalent expression of get and put functions 858 * for data members" 859 * 860 * (Brockschmidt - Inside OLE, 2nd Edition, 861 * Chap.14 # The Mechanics of OLE Automation) 862 * 863 * Thus, the following points to the list of methods AND properties 864 */ 865 866 /* find FUNCDESC by memid */ 867 FIXME("possible collision between property and method names\n"); 868 869 bFound = INVOKE_RetrieveFuncDesc(This->pFunctions, 870 memid, 871 wFlags, 872 &pFuncDesc); 873 874 if ( !bFound ) 875 { 876 if ( !(This->TypeAttr.cImplTypes) ) return DISP_E_MEMBERNOTFOUND; 877 878 /* indirect recursion : following function calls ITypeInfo::Invoke */ 879 hr = INVOKE_DeferToParentTypeInfos(iface, 880 pIUnk, 881 memid, 882 wFlags, 883 pDispParams, 884 pVarResult, 885 pExcepInfo, 886 puArgErr ); 887 } 888 else 889 { 890 /* Validate invoke context. No return value on property put/putref */ 891 if ( wFlags & DISPATCH_PROPERTYPUTREF ) 892 { 893 if ( pFuncDesc->lprgelemdescParam[0].tdesc.vt != VT_BYREF ) 894 { 895 TRACE("Property put by reference not supported by object\n"); 896 return DISP_E_MEMBERNOTFOUND; 897 } 898 899 pVarResult = NULL; 900 } 901 else if ( wFlags & DISPATCH_PROPERTYPUT ) 902 { 903 pVarResult = NULL; 904 } 905 else if ( wFlags & DISPATCH_PROPERTYGET || 906 wFlags & DISPATCH_METHOD ) 907 { 908 /* verify if property isn't read-only */ 909 } 910 else 911 { 912 TRACE("Invalid method call context\n"); 913 return DISP_E_MEMBERNOTFOUND; 914 } 915 916 if ( pDispParams && pDispParams->cArgs > 0 ) 917 { 918 /* this allocates an array of VARIANTARG 919 * in their final form for invocation 920 */ 921 hr = INVOKE_AllocateCoerceAndSortArguments(pFuncDesc, 922 pDispParams, 923 &paArgsCoerced, 924 puArgErr); 925 if ( FAILED(hr) ) return hr; 926 } 927 928 switch ( pFuncDesc->callconv ) 929 { 930 case CC_STDCALL: 931 hr = INVOKE_InvokeStdCallFunction((IUnknown *)pIUnk, 932 pFuncDesc, 933 paArgsCoerced, 934 pVarResult, 935 pExcepInfo); 936 break; 937 default: 938 FIXME("Calling convention not supported!\n"); 939 return E_FAIL; 940 } 941 } 942 943 return hr; 475 944 } 476 945 -
trunk/src/oleaut32/makefile
r5579 r5840 1 # $Id: makefile,v 1.2 4 2001-04-24 19:44:50sandervl Exp $1 # $Id: makefile,v 1.25 2001-05-30 17:43:39 sandervl Exp $ 2 2 3 3 # … … 33 33 $(OBJDIR)\parsedt.obj \ 34 34 $(OBJDIR)\olepicture.obj \ 35 $(OBJDIR)\asmutil.obj \ 35 36 #$(OBJDIR)\iPicture.obj \ 36 37 #$(OBJDIR)\iPictureNone.obj \ -
trunk/src/oleaut32/typelib.cpp
r5650 r5840 1 /* $Id: typelib.cpp,v 1. 19 2001-05-03 18:18:53sandervl Exp $ */1 /* $Id: typelib.cpp,v 1.20 2001-05-30 17:43:39 sandervl Exp $ */ 2 2 /* 3 3 * ITypelib interface … … 248 248 may be NULL*/ 249 249 { 250 dprintfGlobal(("OLEAUT32: RegisterTypeLib() - stub\n")); 251 252 return S_OK; /* FIXME: pretend everything is OK */ 250 HRESULT res; 251 TLIBATTR *attr; 252 OLECHAR guid[80]; 253 LPSTR guidA; 254 CHAR keyName[120]; 255 HKEY key, subKey; 256 257 #ifdef __WIN32OS2__ 258 dprintfGlobal(("OLEAUT32: RegisterTypeLib() %x %ls %ls", ptlib, szFullPath, szHelpDir)); 259 #endif 260 261 if (ptlib == NULL || szFullPath == NULL) 262 return E_INVALIDARG; 263 264 if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr))) 265 return E_FAIL; 266 267 StringFromGUID2(&attr->guid, guid, 80); 268 guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid); 269 #ifdef __WIN32OS2__ 270 sprintf(keyName, "SOFTWARE\\Classes\\TypeLib\\%s\\%x.%x", 271 guidA, attr->wMajorVerNum, attr->wMinorVerNum); 272 #else 273 snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x", 274 guidA, attr->wMajorVerNum, attr->wMinorVerNum); 275 #endif 276 HeapFree(GetProcessHeap(), 0, guidA); 277 278 res = S_OK; 279 #ifdef __WIN32OS2__ 280 if (RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, 281 #else 282 if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, 283 #endif 284 KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) 285 { 286 LPOLESTR doc; 287 288 if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL))) 289 { 290 if (RegSetValueExW(key, NULL, 0, REG_SZ, 291 (BYTE *)doc, lstrlenW(doc) * sizeof(OLECHAR)) != ERROR_SUCCESS) 292 res = E_FAIL; 293 294 SysFreeString(doc); 295 } 296 else 297 res = E_FAIL; 298 299 /* FIXME: This *seems* to be 0 always, not sure though */ 300 if (res == S_OK && RegCreateKeyExA(key, "0\\win32", 0, NULL, 0, 301 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) 302 { 303 if (RegSetValueExW(subKey, NULL, 0, REG_SZ, 304 (BYTE *)szFullPath, lstrlenW(szFullPath) * sizeof(OLECHAR)) != ERROR_SUCCESS) 305 res = E_FAIL; 306 307 RegCloseKey(subKey); 308 } 309 else 310 res = E_FAIL; 311 312 if (res == S_OK && RegCreateKeyExA(key, "FLAGS", 0, NULL, 0, 313 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) 314 { 315 CHAR buf[20]; 316 /* FIXME: is %u correct? */ 317 #ifdef __WIN32OS2__ 318 sprintf(buf, "%u", attr->wLibFlags); 319 if (RegSetValueExA(subKey, NULL, 0, REG_SZ, 320 (LPBYTE)buf, lstrlenA(buf) + 1) != ERROR_SUCCESS) 321 #else 322 snprintf(buf, strlen(buf), "%u", attr->wLibFlags); 323 if (RegSetValueExA(subKey, NULL, 0, REG_SZ, 324 buf, lstrlenA(buf) + 1) != ERROR_SUCCESS) 325 #endif 326 res = E_FAIL; 327 } 328 RegCloseKey(key); 329 } 330 else 331 res = E_FAIL; 332 333 ITypeLib_ReleaseTLibAttr(ptlib, attr); 334 return res; 253 335 } 254 336 … … 265 347 SYSKIND syskind) 266 348 { 267 dprintfGlobal(("OLEAUT32: UnRegisterTypeLib() - stub")); 268 269 return S_OK; /* FIXME: pretend everything is OK */ 349 OLECHAR guid[80]; 350 LPSTR guidA; 351 CHAR keyName[120]; 352 HKEY key, subKey; 353 354 StringFromGUID2(libid, guid, 80); 355 guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid); 356 sprintf(keyName, "SOFTWARE\\Classes\\TypeLib\\%s\\%x.%x", 357 guidA, wVerMajor, wVerMinor); 358 RegDeleteKeyA(HKEY_LOCAL_MACHINE, keyName); 359 HeapFree(GetProcessHeap(), 0, guidA); 360 361 return S_OK; 270 362 } 271 363 -
trunk/src/oleaut32/variant.c
r4837 r5840 25 25 #define WINE_LARGE_INTEGER 26 26 #include "oleaut32.h" 27 27 28 #endif 28 29 … … 47 48 48 49 DEFAULT_DEBUG_CHANNEL(ole); 50 51 #ifdef __WIN32OS2__ 52 #undef FIXME 53 #undef TRACE 54 #ifdef DEBUG 55 #define FIXME WriteLogNoEOL("FIXME %s: ", __FUNCTION__); WriteLog 56 #define TRACE WriteLogNoEOL("%s", __FUNCTION__); WriteLog 57 #else 58 #define FIXME 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 59 #define TRACE 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 60 #endif 61 #endif 49 62 50 63 #ifndef FLT_MAX … … 1030 1043 case( VT_INT ): 1031 1044 case( VT_I4 ): 1045 #ifdef __WIN32OS2__ 1046 case( VT_HRESULT ): 1047 #endif 1032 1048 res = VariantCopy( pd, ps ); 1033 1049 break;
Note:
See TracChangeset
for help on using the changeset viewer.
