static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); HRESULT hres; TRACE("(%p)->(%p)\n", This, pvRecord); hres = IRecordInfo_RecordClear(iface, pvRecord); if(FAILED(hres)) return hres; if(!HeapFree(GetProcessHeap(), 0, pvRecord)) return E_INVALIDARG; return S_OK; }
static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting, PVOID pvNew) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); HRESULT hr = S_OK; int i; TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew); if(!pvExisting || !pvNew) return E_INVALIDARG; /* release already stored data */ IRecordInfo_RecordClear(iface, pvNew); for (i = 0; i < This->n_vars; i++) { void *src, *dest; if (This->fields[i].varkind != VAR_PERINSTANCE) { ERR("varkind != VAR_PERINSTANCE\n"); continue; } src = ((BYTE*)pvExisting) + This->fields[i].offset; dest = ((BYTE*)pvNew) + This->fields[i].offset; switch (This->fields[i].vt) { case VT_BSTR: { BSTR src_str = *(BSTR*)src; if (src_str) { BSTR str = SysAllocString(*(BSTR*)src); if (!str) hr = E_OUTOFMEMORY; *(BSTR*)dest = str; } else *(BSTR*)dest = NULL; break; } case VT_UNKNOWN: case VT_DISPATCH: { IUnknown *unk = *(IUnknown**)src; *(IUnknown**)dest = unk; if (unk) IUnknown_AddRef(unk); break; } case VT_SAFEARRAY: hr = SafeArrayCopy(src, dest); break; default: { /* copy directly for types that don't need deep copy */ int len = get_type_size(NULL, This->fields[i].vt); memcpy(dest, src, len); break; } } if (FAILED(hr)) break; } if (FAILED(hr)) IRecordInfo_RecordClear(iface, pvNew); return hr; }
/* Free data items in an array */ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) { if (psa->pvData && !(psa->fFeatures & FADF_DATADELETED)) { ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); if (ulStartCell > ulCellCount) { FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell); return E_UNEXPECTED; } ulCellCount -= ulStartCell; if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell; while(ulCellCount--) { if (*lpUnknown) IUnknown_Release(*lpUnknown); lpUnknown++; } } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *lpRecInfo; if (SUCCEEDED(SafeArrayGetRecordInfo(psa, &lpRecInfo))) { PBYTE pRecordData = psa->pvData; while(ulCellCount--) { IRecordInfo_RecordClear(lpRecInfo, pRecordData); pRecordData += psa->cbElements; } IRecordInfo_Release(lpRecInfo); } } else if (psa->fFeatures & FADF_BSTR) { BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell; while(ulCellCount--) { SysFreeString(*lpBstr); lpBstr++; } } else if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell; while(ulCellCount--) { HRESULT hRet = VariantClear(lpVariant); if (FAILED(hRet)) FIXME("VariantClear of element failed!\n"); lpVariant++; } } } return S_OK; }