コード例 #1
0
ファイル: usrmarshal.c プロジェクト: howard5888/wineT
unsigned char * WINAPI LPSAFEARRAY_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
{
    HRESULT hr;

    TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", Buffer, *ppsa);

    ALIGN_POINTER(Buffer, 3);
    *(ULONG_PTR *)Buffer = *ppsa ? TRUE : FALSE;
    Buffer += sizeof(ULONG_PTR);
    if (*ppsa)
    {
        VARTYPE vt;
        SAFEARRAY *psa = *ppsa;
        ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
        wireSAFEARRAY wiresa;
        SF_TYPE sftype;
        GUID guid;

        *(ULONG *)Buffer = psa->cDims;
        Buffer += sizeof(ULONG);
        wiresa = (wireSAFEARRAY)Buffer;
        wiresa->cDims = psa->cDims;
        wiresa->fFeatures = psa->fFeatures;
        wiresa->cbElements = psa->cbElements;

        hr = SafeArrayGetVartype(psa, &vt);
        if (FAILED(hr))
            RpcRaiseException(hr);
        wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);

        Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);

        sftype = SAFEARRAY_GetUnionType(psa);
        *(ULONG *)Buffer = sftype;
        Buffer += sizeof(ULONG);

        *(ULONG *)Buffer = ulCellCount;
        Buffer += sizeof(ULONG);
        *(ULONG_PTR *)Buffer = (ULONG_PTR)psa->pvData;
        Buffer += sizeof(ULONG_PTR);
        if (sftype == SF_HAVEIID)
        {
            SafeArrayGetIID(psa, &guid);
            memcpy(Buffer, &guid, sizeof(guid));
            Buffer += sizeof(guid);
        }

        memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims);
        Buffer += sizeof(psa->rgsabound[0]) * psa->cDims;

        *(ULONG *)Buffer = ulCellCount;
        Buffer += sizeof(ULONG);

        if (psa->pvData)
        {
            switch (sftype)
            {
                case SF_BSTR:
                {
                    BSTR* lpBstr;

                    for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
                        Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr);

                    break;
                }
                case SF_DISPATCH:
                case SF_UNKNOWN:
                case SF_HAVEIID:
                    FIXME("marshal interfaces\n");
                    break;
                case SF_VARIANT:
                {
                    VARIANT* lpVariant;

                    for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
                        Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant);

                    break;
                }
                case SF_RECORD:
                {
                    IRecordInfo* pRecInfo = NULL;

                    hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
                    if (FAILED(hr))
                        RpcRaiseException(hr);

                    if (pRecInfo)
                    {
                        FIXME("write record info %p\n", pRecInfo);

                        IRecordInfo_Release(pRecInfo);
                    }
                    break;
                }

                case SF_I8:
                    ALIGN_POINTER(Buffer, 7);
                    /* fallthrough */
                case SF_I1:
                case SF_I2:
                case SF_I4:
                    /* Just copy the data over */
                    memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements);
                    Buffer += ulCellCount * psa->cbElements;
                    break;
                default:
                    break;
            }
        }

    }
    return Buffer;
}
コード例 #2
0
ファイル: safearray.c プロジェクト: hoangduit/reactos
/* Copy data items from one array to another. Destination data is freed before copy. */
static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest)
{
  HRESULT hr = S_OK;

  if (!psa->pvData)
    return S_OK;

  if (!dest->pvData || psa->fFeatures & FADF_DATADELETED)
    return E_INVALIDARG;
  else
  {
    ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);

    dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | (psa->fFeatures & ~ignored_copy_features);

    if (psa->fFeatures & FADF_VARIANT)
    {
      VARIANT *src_var = psa->pvData;
      VARIANT *dest_var = dest->pvData;

      while(ulCellCount--)
      {
        HRESULT hRet;

        /* destination is cleared automatically */
        hRet = VariantCopy(dest_var, src_var);
        if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%08x, element %u\n", hRet, ulCellCount);
        src_var++;
        dest_var++;
      }
    }
    else if (psa->fFeatures & FADF_BSTR)
    {
      BSTR *src_bstr = psa->pvData;
      BSTR *dest_bstr = dest->pvData;

      while(ulCellCount--)
      {
        SysFreeString(*dest_bstr);
        if (*src_bstr)
        {
          *dest_bstr = SysAllocStringByteLen((char*)*src_bstr, SysStringByteLen(*src_bstr));
          if (!*dest_bstr)
            return E_OUTOFMEMORY;
        }
        else
          *dest_bstr = NULL;
        src_bstr++;
        dest_bstr++;
      }
    }
    else if (psa->fFeatures & FADF_RECORD)
    {
      BYTE *dest_data = dest->pvData;
      BYTE *src_data = psa->pvData;
      IRecordInfo *record;

      SafeArrayGetRecordInfo(psa, &record);
      while (ulCellCount--)
      {
          /* RecordCopy() clears destination record */
          hr = IRecordInfo_RecordCopy(record, src_data, dest_data);
          if (FAILED(hr)) break;
          src_data += psa->cbElements;
          dest_data += psa->cbElements;
      }

      SafeArraySetRecordInfo(dest, record);
      /* This value is set to 32 bytes by default on descriptor creation,
         update with actual structure size. */
      dest->cbElements = psa->cbElements;
      IRecordInfo_Release(record);
    }
    else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
    {
      IUnknown **dest_unk = dest->pvData;
      IUnknown **src_unk = psa->pvData;

      /* release old iface, addref new one */
      while (ulCellCount--)
      {
          if (*dest_unk)
              IUnknown_Release(*dest_unk);
          *dest_unk = *src_unk;
          if (*dest_unk)
              IUnknown_AddRef(*dest_unk);
          src_unk++;
          dest_unk++;
      }
    }
    else
    {
      /* Copy the data over */
      memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements);
    }

    if (psa->fFeatures & FADF_HAVEIID)
    {
      GUID guid;
      SafeArrayGetIID(psa, &guid);
      SafeArraySetIID(dest, &guid);
    }
    else if (psa->fFeatures & FADF_HAVEVARTYPE)
    {
      SAFEARRAY_SetHiddenDWORD(dest, SAFEARRAY_GetHiddenDWORD(psa));
    }
  }

  return hr;
}