ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

recinfo.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.