static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, PVOID *ppvDest) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest); if(!pvSource || !ppvDest) return E_INVALIDARG; *ppvDest = IRecordInfo_RecordCreate(iface); return IRecordInfo_RecordCopy(iface, pvSource, *ppvDest); }
/************************************************************************* * SafeArrayPutElement (OLEAUT32.26) * * Put an item into a SafeArray. * * PARAMS * psa [I] SafeArray to insert into * rgIndices [I] Indices to insert at * pvData [I] Data to insert * * RETURNS * Success: S_OK. The item is inserted * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvDest; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvDest); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = pvData; VARIANT* lpDest = lpvDest; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR lpBstr = (BSTR)pvData; BSTR* lpDest = lpvDest; SysFreeString(*lpDest); *lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr)); if (!*lpDest) hRet = E_OUTOFMEMORY; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown *lpUnknown = pvData; IUnknown **lpDest = lpvDest; if (lpUnknown) IUnknown_AddRef(lpUnknown); if (*lpDest) IUnknown_Release(*lpDest); *lpDest = lpUnknown; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, pvData, lpvDest); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(lpvDest, pvData, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
/************************************************************************* * SafeArrayGetElement (OLEAUT32.25) * * Get an item from a SafeArray. * * PARAMS * psa [I] SafeArray to get from * rgIndices [I] Indices to get from * pvData [O] Destination for data * * RETURNS * Success: S_OK. The item data is returned in pvData. * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices || !pvData) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvSrc; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvSrc); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = lpvSrc; VARIANT* lpDest = pvData; /* The original content of pvData is ignored. */ V_VT(lpDest) = VT_EMPTY; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR* lpBstr = lpvSrc; BSTR* lpDest = pvData; if (*lpBstr) { *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); if (!*lpBstr) hRet = E_OUTOFMEMORY; } else *lpDest = NULL; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown **src_unk = lpvSrc; IUnknown **dest_unk = pvData; if (*src_unk) IUnknown_AddRef(*src_unk); *dest_unk = *src_unk; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, lpvSrc, pvData); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(pvData, lpvSrc, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
/* 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; }