Changeset 5840 for trunk/src


Ignore:
Timestamp:
May 30, 2001, 7:43:39 PM (24 years ago)
Author:
sandervl
Message:

typelib updates

Location:
trunk/src/oleaut32
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/oleaut32/itypeinfo.cpp

    r4962 r5840  
    1 /* $Id: itypeinfo.cpp,v 1.5 2001-01-18 18:12:20 sandervl Exp $ */
     1/* $Id: itypeinfo.cpp,v 1.6 2001-05-30 17:43:38 sandervl Exp $ */
    22/*
    33 * ITypeInfo interface
     
    1616#include "olectl.h"
    1717#include "itypelib.h"
     18#include <debugtools.h>
     19#include "asmutil.h"
    1820
    1921HRESULT WINAPI LoadRegTypeLib(REFGUID rguid,
     
    463465//
    464466// ----------------------------------------------------------------------
     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 */
     474static HRESULT
     475INVOKE_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
     568bad_arg_err:
     569    *puBadArg = index;
     570
     571cleanup:
     572    if ( paArgsCoerced )
     573    {
     574        HeapFree(GetProcessHeap(), 0, paArgsCoerced);
     575    }
     576   
     577    return hr;
     578}
     579
     580/*
     581static
     582WINE_EXCEPTION_FILTER(INVOKE_ExceptionHandler)
     583{
     584    FIXME("Exception handler currently does nothing.\n");
     585    return EXCEPTION_EXECUTE_HANDLER;
     586}
     587*/
     588
     589static HRESULT
     590INVOKE_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
     707static BOOL
     708INVOKE_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
     729static HRESULT
     730INVOKE_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    }
     779cleanup:
     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 */
    465809HRESULT WIN32API ITypeInfoImpl_Invoke(ITypeInfo2 * iface,
    466                                 VOID  *pIUnk, MEMBERID memid, UINT16 dwFlags,
     810                                VOID  *pIUnk, MEMBERID memid, UINT16 wFlags,
    467811                                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;
    475944}
    476945
  • trunk/src/oleaut32/makefile

    r5579 r5840  
    1 # $Id: makefile,v 1.24 2001-04-24 19:44:50 sandervl Exp $
     1# $Id: makefile,v 1.25 2001-05-30 17:43:39 sandervl Exp $
    22
    33#
     
    3333$(OBJDIR)\parsedt.obj \
    3434$(OBJDIR)\olepicture.obj \
     35$(OBJDIR)\asmutil.obj \
    3536#$(OBJDIR)\iPicture.obj \
    3637#$(OBJDIR)\iPictureNone.obj \
  • trunk/src/oleaut32/typelib.cpp

    r5650 r5840  
    1 /* $Id: typelib.cpp,v 1.19 2001-05-03 18:18:53 sandervl Exp $ */
     1/* $Id: typelib.cpp,v 1.20 2001-05-30 17:43:39 sandervl Exp $ */
    22/*
    33 * ITypelib interface
     
    248248                                                         may be NULL*/
    249249{
    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;
    253335}
    254336
     
    265347    SYSKIND             syskind)
    266348{
    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;
    270362}
    271363
  • trunk/src/oleaut32/variant.c

    r4837 r5840  
    2525#define WINE_LARGE_INTEGER
    2626#include "oleaut32.h"
     27
    2728#endif
    2829
     
    4748
    4849DEFAULT_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
    4962
    5063#ifndef FLT_MAX
     
    10301043        case( VT_INT ):
    10311044        case( VT_I4 ):
     1045#ifdef __WIN32OS2__
     1046        case( VT_HRESULT ):
     1047#endif
    10321048            res = VariantCopy( pd, ps );
    10331049            break;
Note: See TracChangeset for help on using the changeset viewer.