📄 recinfo.c
字号:
return S_OK;
}
static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
LPCOLESTR szFieldName, VARIANT *pvarField)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField);
if(!pvData || !szFieldName || !pvarField)
return E_INVALIDARG;
for(i=0; i<This->n_vars; i++)
if(!strcmpW(This->fields[i].name, szFieldName))
break;
if(i == This->n_vars)
return TYPE_E_FIELDNOTFOUND;
VariantClear(pvarField);
return copy_to_variant(((PBYTE)pvData)+This->fields[i].offset, pvarField,
This->fields[i].vt);
}
static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);
if(!pvData || !szFieldName || !pvarField)
return E_INVALIDARG;
for(i=0; i<This->n_vars; i++)
if(!strcmpW(This->fields[i].name, szFieldName))
break;
if(i == This->n_vars)
return TYPE_E_FIELDNOTFOUND;
VariantClear(pvarField);
V_VT(pvarField) = VT_BYREF|This->fields[i].vt;
V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset;
*ppvDataCArray = NULL;
return S_OK;
}
static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData,
LPCOLESTR szFieldName, VARIANT *pvarField)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
TRACE("(%p)->(%08x %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
pvarField);
if(!pvData || !szFieldName || !pvarField
|| (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
return E_INVALIDARG;
if(wFlags == INVOKE_PROPERTYPUTREF) {
FIXME("wFlag == INVOKE_PROPERTYPUTREF not supported\n");
return E_NOTIMPL;
}
for(i=0; i<This->n_vars; i++)
if(!strcmpW(This->fields[i].name, szFieldName))
break;
if(i == This->n_vars)
return TYPE_E_FIELDNOTFOUND;
return copy_from_variant(pvarField, ((PBYTE)pvData)+This->fields[i].offset,
This->fields[i].vt);
}
static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags,
PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
FIXME("(%p)->(%08x %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
if(!pvData || !szFieldName || !pvarField
|| (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
return E_INVALIDARG;
for(i=0; i<This->n_vars; i++)
if(!strcmpW(This->fields[i].name, szFieldName))
break;
if(i == This->n_vars)
return TYPE_E_FIELDNOTFOUND;
return E_NOTIMPL;
}
static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames,
BSTR *rgBstrNames)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
ULONG n = This->n_vars;
int i;
TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames);
if(!pcNames)
return E_INVALIDARG;
if(*pcNames < n)
n = *pcNames;
if(rgBstrNames) {
for(i=0; i<n; i++)
rgBstrNames[i] = SysAllocString(This->fields[i].name);
}
*pcNames = n;
return S_OK;
}
static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
FIXME("(%p)->(%p) stub\n", This, pRecordInfo);
return FALSE;
}
static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
TRACE("(%p)\n", This);
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->size);
}
static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource,
PVOID *ppvDest)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)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);
}
static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
TRACE("(%p)->(%p)\n", This, pvRecord);
if(!HeapFree(GetProcessHeap(), 0, pvRecord))
return E_INVALIDARG;
return S_OK;
}
static const IRecordInfoVtbl IRecordInfoImplVtbl = {
IRecordInfoImpl_QueryInterface,
IRecordInfoImpl_AddRef,
IRecordInfoImpl_Release,
IRecordInfoImpl_RecordInit,
IRecordInfoImpl_RecordClear,
IRecordInfoImpl_RecordCopy,
IRecordInfoImpl_GetGuid,
IRecordInfoImpl_GetName,
IRecordInfoImpl_GetSize,
IRecordInfoImpl_GetTypeInfo,
IRecordInfoImpl_GetField,
IRecordInfoImpl_GetFieldNoCopy,
IRecordInfoImpl_PutField,
IRecordInfoImpl_PutFieldNoCopy,
IRecordInfoImpl_GetFieldNames,
IRecordInfoImpl_IsMatchingType,
IRecordInfoImpl_RecordCreate,
IRecordInfoImpl_RecordCreateCopy,
IRecordInfoImpl_RecordDestroy
};
/******************************************************************************
* GetRecordInfoFromGuids [OLEAUT32.322]
*
* RETURNS
* Success: S_OK
* Failure: E_INVALIDARG, if any argument is invalid.
*/
HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor,
ULONG uVerMinor, LCID lcid, REFGUID rGuidTypeInfo, IRecordInfo** ppRecInfo)
{
ITypeInfo *pTypeInfo;
ITypeLib *pTypeLib;
HRESULT hres;
TRACE("(%p,%d,%d,%d,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor,
lcid, rGuidTypeInfo, ppRecInfo);
hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib);
if(FAILED(hres)) {
WARN("LoadRegTypeLib failed!\n");
return hres;
}
hres = ITypeLib_GetTypeInfoOfGuid(pTypeLib, rGuidTypeInfo, &pTypeInfo);
ITypeLib_Release(pTypeLib);
if(FAILED(hres)) {
WARN("GetTypeInfoOfGuid failed!\n");
return hres;
}
hres = GetRecordInfoFromTypeInfo(pTypeInfo, ppRecInfo);
ITypeInfo_Release(pTypeInfo);
return hres;
}
/******************************************************************************
* GetRecordInfoFromTypeInfo [OLEAUT32.332]
*/
HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo) {
HRESULT hres;
TYPEATTR *typeattr;
IRecordInfoImpl *ret;
ITypeInfo *pTypeInfo;
int i;
GUID guid;
TRACE("(%p %p)\n", pTI, ppRecInfo);
if(!pTI || !ppRecInfo)
return E_INVALIDARG;
hres = ITypeInfo_GetTypeAttr(pTI, &typeattr);
if(FAILED(hres) || !typeattr) {
WARN("GetTypeAttr failed: %08x\n", hres);
return hres;
}
if(typeattr->typekind == TKIND_ALIAS) {
hres = ITypeInfo_GetRefTypeInfo(pTI, typeattr->tdescAlias.u.hreftype, &pTypeInfo);
memcpy(&guid, &typeattr->guid, sizeof(GUID));
ITypeInfo_ReleaseTypeAttr(pTI, typeattr);
if(FAILED(hres)) {
WARN("GetRefTypeInfo failed: %08x\n", hres);
return hres;
}
ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr);
}else {
pTypeInfo = pTI;
ITypeInfo_AddRef(pTypeInfo);
memcpy(&guid, &typeattr->guid, sizeof(GUID));
}
if(typeattr->typekind != TKIND_RECORD) {
WARN("typekind != TKIND_RECORD\n");
ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
ITypeInfo_Release(pTypeInfo);
return E_INVALIDARG;
}
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
ret->lpVtbl = &IRecordInfoImplVtbl;
ret->ref = 1;
ret->pTypeInfo = pTypeInfo;
ret->n_vars = typeattr->cVars;
ret->size = typeattr->cbSizeInstance;
ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
memcpy(&ret->guid, &guid, sizeof(GUID));
/* NOTE: Windows implementation calls ITypeInfo::GetCantainingTypeLib and
* ITypeLib::GetLibAttr, but we currently don't need this.
*/
hres = ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &ret->name, NULL, NULL, NULL);
if(FAILED(hres)) {
WARN("ITypeInfo::GetDocumentation failed\n");
ret->name = NULL;
}
ret->fields = HeapAlloc(GetProcessHeap(), 0, ret->n_vars*sizeof(VARDESC));
for(i = 0; i<ret->n_vars; i++) {
VARDESC *vardesc;
hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc);
if(FAILED(hres)) {
WARN("GetVarDesc failed\n");
continue;
}
ret->fields[i].vt = vardesc->elemdescVar.tdesc.vt;
ret->fields[i].varkind = vardesc->varkind;
ret->fields[i].offset = vardesc->u.oInst;
hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name,
NULL, NULL, NULL);
if(FAILED(hres))
WARN("GetDocumentation failed: %08x\n", hres);
ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
}
*ppRecInfo = (IRecordInfo*)ret;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -