Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrecinfo.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005 Jacek Caban 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include <stdarg.h> 00020 00021 #define COBJMACROS 00022 #define NONAMELESSUNION 00023 #define NONAMELESSSTRUCT 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "objbase.h" 00028 #include "oaidl.h" 00029 #include "oleauto.h" 00030 00031 #include "wine/unicode.h" 00032 #include "wine/debug.h" 00033 00034 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00035 00036 typedef struct { 00037 enum VARENUM vt; 00038 VARKIND varkind; 00039 ULONG offset; 00040 BSTR name; 00041 } fieldstr; 00042 00043 typedef struct { 00044 const IRecordInfoVtbl *lpVtbl; 00045 LONG ref; 00046 00047 GUID guid; 00048 UINT lib_index; 00049 WORD n_vars; 00050 ULONG size; 00051 BSTR name; 00052 fieldstr *fields; 00053 ITypeInfo *pTypeInfo; 00054 } IRecordInfoImpl; 00055 00056 static HRESULT copy_to_variant(void *src, VARIANT *pvar, enum VARENUM vt) 00057 { 00058 TRACE("%p %p %d\n", src, pvar, vt); 00059 00060 #define CASE_COPY(x) \ 00061 case VT_ ## x: \ 00062 memcpy(&V_ ## x(pvar), src, sizeof(V_ ## x(pvar))); \ 00063 break 00064 00065 switch(vt) { 00066 CASE_COPY(I2); 00067 CASE_COPY(I4); 00068 CASE_COPY(R4); 00069 CASE_COPY(R8); 00070 CASE_COPY(CY); 00071 CASE_COPY(DATE); 00072 CASE_COPY(BSTR); 00073 CASE_COPY(ERROR); 00074 CASE_COPY(BOOL); 00075 CASE_COPY(DECIMAL); 00076 CASE_COPY(I1); 00077 CASE_COPY(UI1); 00078 CASE_COPY(UI2); 00079 CASE_COPY(UI4); 00080 CASE_COPY(I8); 00081 CASE_COPY(UI8); 00082 CASE_COPY(INT); 00083 CASE_COPY(UINT); 00084 CASE_COPY(INT_PTR); 00085 CASE_COPY(UINT_PTR); 00086 default: 00087 FIXME("Not supported type: %d\n", vt); 00088 return E_NOTIMPL; 00089 }; 00090 #undef CASE_COPY 00091 00092 V_VT(pvar) = vt; 00093 return S_OK; 00094 } 00095 00096 static HRESULT copy_from_variant(VARIANT *src, void *dest, enum VARENUM vt) 00097 { 00098 VARIANT var; 00099 HRESULT hres; 00100 00101 TRACE("(%p(%d) %p %d)\n", src, V_VT(src), dest, vt); 00102 00103 hres = VariantChangeType(&var, src, 0, vt); 00104 if(FAILED(hres)) 00105 return hres; 00106 00107 #define CASE_COPY(x) \ 00108 case VT_ ## x: \ 00109 memcpy(dest, &V_ ## x(&var), sizeof(V_ ## x(&var))); \ 00110 break 00111 00112 switch(vt) { 00113 CASE_COPY(I2); 00114 CASE_COPY(I4); 00115 CASE_COPY(R4); 00116 CASE_COPY(R8); 00117 CASE_COPY(CY); 00118 CASE_COPY(DATE); 00119 CASE_COPY(BSTR); 00120 CASE_COPY(ERROR); 00121 CASE_COPY(BOOL); 00122 CASE_COPY(DECIMAL); 00123 CASE_COPY(I1); 00124 CASE_COPY(UI1); 00125 CASE_COPY(UI2); 00126 CASE_COPY(UI4); 00127 CASE_COPY(I8); 00128 CASE_COPY(UI8); 00129 CASE_COPY(INT); 00130 CASE_COPY(UINT); 00131 CASE_COPY(INT_PTR); 00132 CASE_COPY(UINT_PTR); 00133 default: 00134 FIXME("Not supported type: %d\n", V_VT(&var)); 00135 return E_NOTIMPL; 00136 }; 00137 #undef CASE_COPY 00138 return S_OK; 00139 } 00140 00141 static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID riid, 00142 void **ppvObject) 00143 { 00144 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); 00145 00146 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRecordInfo, riid)) { 00147 *ppvObject = iface; 00148 IRecordInfo_AddRef(iface); 00149 return S_OK; 00150 } 00151 00152 FIXME("Not supported interface: %s\n", debugstr_guid(riid)); 00153 return E_NOINTERFACE; 00154 } 00155 00156 static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface) 00157 { 00158 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00159 ULONG ref = InterlockedIncrement(&This->ref); 00160 TRACE("(%p) -> %d\n", This, ref); 00161 return ref; 00162 } 00163 00164 static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface) 00165 { 00166 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00167 ULONG ref = InterlockedDecrement(&This->ref); 00168 00169 TRACE("(%p) -> %d\n", This, ref); 00170 00171 if(!ref) { 00172 int i; 00173 for(i=0; i<This->n_vars; i++) 00174 SysFreeString(This->fields[i].name); 00175 HeapFree(GetProcessHeap(), 0, This->name); 00176 HeapFree(GetProcessHeap(), 0, This->fields); 00177 ITypeInfo_Release(This->pTypeInfo); 00178 HeapFree(GetProcessHeap(), 0, This); 00179 } 00180 return ref; 00181 } 00182 00183 static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew) 00184 { 00185 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00186 TRACE("(%p)->(%p)\n", This, pvNew); 00187 00188 if(!pvNew) 00189 return E_INVALIDARG; 00190 00191 memset(pvNew, 0, This->size); 00192 return S_OK; 00193 } 00194 00195 static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting) 00196 { 00197 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00198 int i; 00199 PVOID var; 00200 00201 TRACE("(%p)->(%p)\n", This, pvExisting); 00202 00203 if(!pvExisting) 00204 return E_INVALIDARG; 00205 00206 for(i=0; i<This->n_vars; i++) { 00207 if(This->fields[i].varkind != VAR_PERINSTANCE) { 00208 ERR("varkind != VAR_PERINSTANCE\n"); 00209 continue; 00210 } 00211 var = ((PBYTE)pvExisting)+This->fields[i].offset; 00212 switch(This->fields[i].vt) { 00213 case VT_BSTR: 00214 SysFreeString(*(BSTR*)var); 00215 *(BSTR*)var = NULL; 00216 break; 00217 case VT_I2: 00218 case VT_I4: 00219 case VT_R4: 00220 case VT_R8: 00221 case VT_CY: 00222 case VT_DATE: 00223 case VT_ERROR: 00224 case VT_BOOL: 00225 case VT_DECIMAL: 00226 case VT_I1: 00227 case VT_UI1: 00228 case VT_UI2: 00229 case VT_UI4: 00230 case VT_I8: 00231 case VT_UI8: 00232 case VT_INT: 00233 case VT_UINT: 00234 break; 00235 case VT_INT_PTR: 00236 case VT_UINT_PTR: 00237 *(void**)var = NULL; 00238 break; 00239 case VT_SAFEARRAY: 00240 SafeArrayDestroy(var); 00241 break; 00242 default: 00243 FIXME("Not supported vt = %d\n", This->fields[i].vt); 00244 break; 00245 } 00246 } 00247 00248 return S_OK; 00249 } 00250 00251 static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting, 00252 PVOID pvNew) 00253 { 00254 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00255 00256 TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew); 00257 00258 if(!pvExisting || !pvNew) 00259 return E_INVALIDARG; 00260 00261 memcpy(pvExisting, pvNew, This->size); 00262 return S_OK; 00263 } 00264 00265 static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid) 00266 { 00267 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00268 00269 TRACE("(%p)->(%p)\n", This, pguid); 00270 00271 if(!pguid) 00272 return E_INVALIDARG; 00273 00274 *pguid = This->guid; 00275 return S_OK; 00276 } 00277 00278 static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrName) 00279 { 00280 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00281 00282 TRACE("(%p)->(%p)\n", This, pbstrName); 00283 00284 if(!pbstrName) 00285 return E_INVALIDARG; 00286 00287 *pbstrName = SysAllocString(This->name); 00288 return S_OK; 00289 } 00290 00291 static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize) 00292 { 00293 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00294 00295 TRACE("(%p)->(%p)\n", This, pcbSize); 00296 00297 if(!pcbSize) 00298 return E_INVALIDARG; 00299 00300 *pcbSize = This->size; 00301 return S_OK; 00302 } 00303 00304 static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo) 00305 { 00306 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00307 00308 TRACE("(%p)->(%p)\n", This, ppTypeInfo); 00309 00310 if(!ppTypeInfo) 00311 return E_INVALIDARG; 00312 00313 ITypeInfo_AddRef(This->pTypeInfo); 00314 *ppTypeInfo = This->pTypeInfo; 00315 00316 return S_OK; 00317 } 00318 00319 static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData, 00320 LPCOLESTR szFieldName, VARIANT *pvarField) 00321 { 00322 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00323 int i; 00324 00325 TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField); 00326 00327 if(!pvData || !szFieldName || !pvarField) 00328 return E_INVALIDARG; 00329 00330 for(i=0; i<This->n_vars; i++) 00331 if(!strcmpW(This->fields[i].name, szFieldName)) 00332 break; 00333 if(i == This->n_vars) 00334 return TYPE_E_FIELDNOTFOUND; 00335 00336 VariantClear(pvarField); 00337 return copy_to_variant(((PBYTE)pvData)+This->fields[i].offset, pvarField, 00338 This->fields[i].vt); 00339 } 00340 00341 static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData, 00342 LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray) 00343 { 00344 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00345 int i; 00346 00347 TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray); 00348 00349 if(!pvData || !szFieldName || !pvarField) 00350 return E_INVALIDARG; 00351 00352 for(i=0; i<This->n_vars; i++) 00353 if(!strcmpW(This->fields[i].name, szFieldName)) 00354 break; 00355 if(i == This->n_vars) 00356 return TYPE_E_FIELDNOTFOUND; 00357 00358 VariantClear(pvarField); 00359 V_VT(pvarField) = VT_BYREF|This->fields[i].vt; 00360 V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset; 00361 *ppvDataCArray = NULL; 00362 return S_OK; 00363 } 00364 00365 static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData, 00366 LPCOLESTR szFieldName, VARIANT *pvarField) 00367 { 00368 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00369 int i; 00370 00371 TRACE("(%p)->(%08x %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName), 00372 pvarField); 00373 00374 if(!pvData || !szFieldName || !pvarField 00375 || (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT)) 00376 return E_INVALIDARG; 00377 00378 if(wFlags == INVOKE_PROPERTYPUTREF) { 00379 FIXME("wFlag == INVOKE_PROPERTYPUTREF not supported\n"); 00380 return E_NOTIMPL; 00381 } 00382 00383 for(i=0; i<This->n_vars; i++) 00384 if(!strcmpW(This->fields[i].name, szFieldName)) 00385 break; 00386 if(i == This->n_vars) 00387 return TYPE_E_FIELDNOTFOUND; 00388 00389 return copy_from_variant(pvarField, ((PBYTE)pvData)+This->fields[i].offset, 00390 This->fields[i].vt); 00391 } 00392 00393 static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags, 00394 PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField) 00395 { 00396 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00397 int i; 00398 00399 FIXME("(%p)->(%08x %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField); 00400 00401 if(!pvData || !szFieldName || !pvarField 00402 || (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT)) 00403 return E_INVALIDARG; 00404 00405 for(i=0; i<This->n_vars; i++) 00406 if(!strcmpW(This->fields[i].name, szFieldName)) 00407 break; 00408 if(i == This->n_vars) 00409 return TYPE_E_FIELDNOTFOUND; 00410 00411 return E_NOTIMPL; 00412 } 00413 00414 static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames, 00415 BSTR *rgBstrNames) 00416 { 00417 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00418 ULONG n = This->n_vars, i; 00419 00420 TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames); 00421 00422 if(!pcNames) 00423 return E_INVALIDARG; 00424 00425 if(*pcNames < n) 00426 n = *pcNames; 00427 00428 if(rgBstrNames) { 00429 for(i=0; i<n; i++) 00430 rgBstrNames[i] = SysAllocString(This->fields[i].name); 00431 } 00432 00433 *pcNames = n; 00434 return S_OK; 00435 } 00436 00437 static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo) 00438 { 00439 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00440 00441 FIXME("(%p)->(%p) stub\n", This, pRecordInfo); 00442 00443 return FALSE; 00444 } 00445 00446 static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface) 00447 { 00448 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00449 00450 TRACE("(%p)\n", This); 00451 00452 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->size); 00453 } 00454 00455 static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, 00456 PVOID *ppvDest) 00457 { 00458 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00459 00460 TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest); 00461 00462 if(!pvSource || !ppvDest) 00463 return E_INVALIDARG; 00464 00465 *ppvDest = IRecordInfo_RecordCreate(iface); 00466 return IRecordInfo_RecordCopy(iface, pvSource, *ppvDest); 00467 } 00468 00469 static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord) 00470 { 00471 IRecordInfoImpl *This = (IRecordInfoImpl*)iface; 00472 HRESULT hres; 00473 00474 TRACE("(%p)->(%p)\n", This, pvRecord); 00475 00476 hres = IRecordInfo_RecordClear(iface, pvRecord); 00477 if(FAILED(hres)) 00478 return hres; 00479 00480 if(!HeapFree(GetProcessHeap(), 0, pvRecord)) 00481 return E_INVALIDARG; 00482 00483 return S_OK; 00484 } 00485 00486 static const IRecordInfoVtbl IRecordInfoImplVtbl = { 00487 IRecordInfoImpl_QueryInterface, 00488 IRecordInfoImpl_AddRef, 00489 IRecordInfoImpl_Release, 00490 IRecordInfoImpl_RecordInit, 00491 IRecordInfoImpl_RecordClear, 00492 IRecordInfoImpl_RecordCopy, 00493 IRecordInfoImpl_GetGuid, 00494 IRecordInfoImpl_GetName, 00495 IRecordInfoImpl_GetSize, 00496 IRecordInfoImpl_GetTypeInfo, 00497 IRecordInfoImpl_GetField, 00498 IRecordInfoImpl_GetFieldNoCopy, 00499 IRecordInfoImpl_PutField, 00500 IRecordInfoImpl_PutFieldNoCopy, 00501 IRecordInfoImpl_GetFieldNames, 00502 IRecordInfoImpl_IsMatchingType, 00503 IRecordInfoImpl_RecordCreate, 00504 IRecordInfoImpl_RecordCreateCopy, 00505 IRecordInfoImpl_RecordDestroy 00506 }; 00507 00508 /****************************************************************************** 00509 * GetRecordInfoFromGuids [OLEAUT32.322] 00510 * 00511 * RETURNS 00512 * Success: S_OK 00513 * Failure: E_INVALIDARG, if any argument is invalid. 00514 */ 00515 HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor, 00516 ULONG uVerMinor, LCID lcid, REFGUID rGuidTypeInfo, IRecordInfo** ppRecInfo) 00517 { 00518 ITypeInfo *pTypeInfo; 00519 ITypeLib *pTypeLib; 00520 HRESULT hres; 00521 00522 TRACE("(%p,%d,%d,%d,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor, 00523 lcid, rGuidTypeInfo, ppRecInfo); 00524 00525 hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib); 00526 if(FAILED(hres)) { 00527 WARN("LoadRegTypeLib failed!\n"); 00528 return hres; 00529 } 00530 00531 hres = ITypeLib_GetTypeInfoOfGuid(pTypeLib, rGuidTypeInfo, &pTypeInfo); 00532 ITypeLib_Release(pTypeLib); 00533 if(FAILED(hres)) { 00534 WARN("GetTypeInfoOfGuid failed!\n"); 00535 return hres; 00536 } 00537 00538 hres = GetRecordInfoFromTypeInfo(pTypeInfo, ppRecInfo); 00539 ITypeInfo_Release(pTypeInfo); 00540 return hres; 00541 } 00542 00543 /****************************************************************************** 00544 * GetRecordInfoFromTypeInfo [OLEAUT32.332] 00545 */ 00546 HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo) { 00547 HRESULT hres; 00548 TYPEATTR *typeattr; 00549 IRecordInfoImpl *ret; 00550 ITypeInfo *pTypeInfo; 00551 int i; 00552 GUID guid; 00553 00554 TRACE("(%p %p)\n", pTI, ppRecInfo); 00555 00556 if(!pTI || !ppRecInfo) 00557 return E_INVALIDARG; 00558 00559 hres = ITypeInfo_GetTypeAttr(pTI, &typeattr); 00560 if(FAILED(hres) || !typeattr) { 00561 WARN("GetTypeAttr failed: %08x\n", hres); 00562 return hres; 00563 } 00564 00565 if(typeattr->typekind == TKIND_ALIAS) { 00566 hres = ITypeInfo_GetRefTypeInfo(pTI, typeattr->tdescAlias.u.hreftype, &pTypeInfo); 00567 guid = typeattr->guid; 00568 ITypeInfo_ReleaseTypeAttr(pTI, typeattr); 00569 if(FAILED(hres)) { 00570 WARN("GetRefTypeInfo failed: %08x\n", hres); 00571 return hres; 00572 } 00573 ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr); 00574 }else { 00575 pTypeInfo = pTI; 00576 ITypeInfo_AddRef(pTypeInfo); 00577 guid = typeattr->guid; 00578 } 00579 00580 if(typeattr->typekind != TKIND_RECORD) { 00581 WARN("typekind != TKIND_RECORD\n"); 00582 ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr); 00583 ITypeInfo_Release(pTypeInfo); 00584 return E_INVALIDARG; 00585 } 00586 00587 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); 00588 ret->lpVtbl = &IRecordInfoImplVtbl; 00589 ret->ref = 1; 00590 ret->pTypeInfo = pTypeInfo; 00591 ret->n_vars = typeattr->cVars; 00592 ret->size = typeattr->cbSizeInstance; 00593 ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr); 00594 00595 ret->guid = guid; 00596 00597 /* NOTE: Windows implementation calls ITypeInfo::GetCantainingTypeLib and 00598 * ITypeLib::GetLibAttr, but we currently don't need this. 00599 */ 00600 00601 hres = ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &ret->name, NULL, NULL, NULL); 00602 if(FAILED(hres)) { 00603 WARN("ITypeInfo::GetDocumentation failed\n"); 00604 ret->name = NULL; 00605 } 00606 00607 ret->fields = HeapAlloc(GetProcessHeap(), 0, ret->n_vars*sizeof(VARDESC)); 00608 for(i = 0; i<ret->n_vars; i++) { 00609 VARDESC *vardesc; 00610 hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc); 00611 if(FAILED(hres)) { 00612 WARN("GetVarDesc failed\n"); 00613 continue; 00614 } 00615 ret->fields[i].vt = vardesc->elemdescVar.tdesc.vt; 00616 ret->fields[i].varkind = vardesc->varkind; 00617 ret->fields[i].offset = vardesc->u.oInst; 00618 hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name, 00619 NULL, NULL, NULL); 00620 if(FAILED(hres)) 00621 WARN("GetDocumentation failed: %08x\n", hres); 00622 ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc); 00623 } 00624 00625 *ppRecInfo = (IRecordInfo*)ret; 00626 00627 return S_OK; 00628 } Generated on Sun May 27 2012 04:25:43 for ReactOS by
1.7.6.1
|