1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
16 #include <prettyprintsig.h>
23 #define LEGACY_ACTIVATION_SHIM_LOAD_LIBRARY WszLoadLibrary
24 #define LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
26 #define ENUM_BUFFER_SIZE 10
29 #define NumItems(s) (sizeof(s) / sizeof(s[0]))
31 #define ISFLAG(p,x) if (Is##p##x(flags)) strcat_s(sFlags,STRING_BUFFER_LEN, "["#x "] ");
33 extern HRESULT _FillVariant(
39 // Validator declarations.
40 extern DWORD g_ValModuleType;
41 #include <ivehandler.h>
43 // Tables for mapping element type to text
44 const char *g_szMapElementType[] =
82 const char *g_szMapUndecorateType[] =
120 // Provide enough entries for IMAGE_CEE_CS_CALLCONV_MASK (defined in CorHdr.h)
121 const char *g_strCalling[] =
141 const char *g_szNativeType[] =
143 "NATIVE_TYPE_END(DEPRECATED!)", // = 0x0, //DEPRECATED
144 "NATIVE_TYPE_VOID(DEPRECATED!)", // = 0x1, //DEPRECATED
145 "NATIVE_TYPE_BOOLEAN", // = 0x2, // (4 byte boolean value: TRUE = non-zero, FALSE = 0)
146 "NATIVE_TYPE_I1", // = 0x3,
147 "NATIVE_TYPE_U1", // = 0x4,
148 "NATIVE_TYPE_I2", // = 0x5,
149 "NATIVE_TYPE_U2", // = 0x6,
150 "NATIVE_TYPE_I4", // = 0x7,
151 "NATIVE_TYPE_U4", // = 0x8,
152 "NATIVE_TYPE_I8", // = 0x9,
153 "NATIVE_TYPE_U8", // = 0xa,
154 "NATIVE_TYPE_R4", // = 0xb,
155 "NATIVE_TYPE_R8", // = 0xc,
156 "NATIVE_TYPE_SYSCHAR(DEPRECATED!)", // = 0xd, //DEPRECATED
157 "NATIVE_TYPE_VARIANT(DEPRECATED!)", // = 0xe, //DEPRECATED
158 "NATIVE_TYPE_CURRENCY", // = 0xf,
159 "NATIVE_TYPE_PTR(DEPRECATED!)", // = 0x10, //DEPRECATED
161 "NATIVE_TYPE_DECIMAL(DEPRECATED!)", // = 0x11, //DEPRECATED
162 "NATIVE_TYPE_DATE(DEPRECATED!)", // = 0x12, //DEPRECATED
163 "NATIVE_TYPE_BSTR", // = 0x13,
164 "NATIVE_TYPE_LPSTR", // = 0x14,
165 "NATIVE_TYPE_LPWSTR", // = 0x15,
166 "NATIVE_TYPE_LPTSTR", // = 0x16,
167 "NATIVE_TYPE_FIXEDSYSSTRING", // = 0x17,
168 "NATIVE_TYPE_OBJECTREF(DEPRECATED!)", // = 0x18, //DEPRECATED
169 "NATIVE_TYPE_IUNKNOWN", // = 0x19,
170 "NATIVE_TYPE_IDISPATCH", // = 0x1a,
171 "NATIVE_TYPE_STRUCT", // = 0x1b,
172 "NATIVE_TYPE_INTF", // = 0x1c,
173 "NATIVE_TYPE_SAFEARRAY", // = 0x1d,
174 "NATIVE_TYPE_FIXEDARRAY", // = 0x1e,
175 "NATIVE_TYPE_INT", // = 0x1f,
176 "NATIVE_TYPE_UINT", // = 0x20,
178 "NATIVE_TYPE_NESTEDSTRUCT(DEPRECATED!)", // = 0x21, //DEPRECATED (use "NATIVE_TYPE_STRUCT)
180 "NATIVE_TYPE_BYVALSTR", // = 0x22,
182 "NATIVE_TYPE_ANSIBSTR", // = 0x23,
184 "NATIVE_TYPE_TBSTR", // = 0x24, // select BSTR or ANSIBSTR depending on platform
187 "NATIVE_TYPE_VARIANTBOOL", // = 0x25, // (2-byte boolean value: TRUE = -1, FALSE = 0)
188 "NATIVE_TYPE_FUNC", // = 0x26,
189 "NATIVE_TYPE_LPVOID", // = 0x27, // blind pointer (no deep marshaling)
191 "NATIVE_TYPE_ASANY", // = 0x28,
192 "<UNDEFINED NATIVE TYPE 0x29>",
193 "NATIVE_TYPE_ARRAY", // = 0x2a,
194 "NATIVE_TYPE_LPSTRUCT", // = 0x2b,
195 "NATIVE_TYPE_CUSTOMMARSHALER", // = 0x2c, // Custom marshaler.
196 "NATIVE_TYPE_ERROR", // = 0x2d, // VT_HRESULT when exporting to a typelib.
200 size_t g_cbCoffNames = 0;
202 mdMethodDef g_tkEntryPoint = 0; // integration with ILDASM
206 // helper to init signature buffer
207 void MDInfo::InitSigBuffer()
209 strcpy_s((LPSTR)m_sigBuf.Ptr(), 1, "");
210 } // void MDInfo::InitSigBuffer()
212 // helper to append a string into the signature buffer. If size of signature buffer is not big enough,
214 HRESULT MDInfo::AddToSigBuffer(__in_z __in const char *string)
217 size_t LL = strlen((LPSTR)m_sigBuf.Ptr()) + strlen(string) + 1;
218 IfFailRet( m_sigBuf.ReSizeNoThrow(LL) );
219 strcat_s((LPSTR)m_sigBuf.Ptr(), LL, string);
221 } // HRESULT MDInfo::AddToSigBuffer()
223 MDInfo::MDInfo(IMetaDataImport2 *pImport, IMetaDataAssemblyImport *pAssemblyImport, LPCWSTR szScope, strPassBackFn inPBFn, ULONG DumpFilter)
224 { // This constructor is specific to ILDASM/MetaInfo integration
226 _ASSERTE(pImport != NULL);
227 _ASSERTE(NumItems(g_szMapElementType) == NumItems(g_szMapUndecorateType));
228 _ASSERTE(NumItems(g_szMapElementType) == ELEMENT_TYPE_MAX);
230 Init(inPBFn, (DUMP_FILTER)DumpFilter);
234 if ((m_pAssemblyImport = pAssemblyImport))
235 m_pAssemblyImport->AddRef();
238 HRESULT hr = m_pImport->QueryInterface(IID_IMetaDataAssemblyImport, (void**) &m_pAssemblyImport);
240 Error("QueryInterface failed for IID_IMetaDataAssemblyImport.", hr);
243 } // MDInfo::MDInfo()
245 MDInfo::MDInfo(IMetaDataDispenserEx *pDispenser, LPCWSTR szScope, strPassBackFn inPBFn, ULONG DumpFilter)
250 _ASSERTE(pDispenser != NULL && inPBFn != NULL);
251 _ASSERTE(NumItems(g_szMapElementType) == NumItems(g_szMapUndecorateType));
252 _ASSERTE(NumItems(g_szMapElementType) == ELEMENT_TYPE_MAX);
254 Init(inPBFn, (DUMP_FILTER)DumpFilter);
256 // Attempt to open scope on given file
257 V_VT(&value) = VT_UI4;
258 V_UI4(&value) = MDImportOptionAll;
259 if (FAILED(hr = pDispenser->SetOption(MetaDataImportOption, &value)))
260 Error("SetOption failed.", hr);
262 hr = pDispenser->OpenScope(szScope, ofNoTransform, IID_IMetaDataImport2, (IUnknown**)&m_pImport);
263 if (hr == CLDB_E_BADUPDATEMODE)
265 V_VT(&value) = VT_UI4;
266 V_UI4(&value) = MDUpdateIncremental;
267 if (FAILED(hr = pDispenser->SetOption(MetaDataSetUpdate, &value)))
268 Error("SetOption failed.", hr);
269 hr = pDispenser->OpenScope(szScope, ofNoTransform, IID_IMetaDataImport2, (IUnknown**)&m_pImport);
272 Error("OpenScope failed", hr);
274 // Query for the IMetaDataAssemblyImport interface.
275 hr = m_pImport->QueryInterface(IID_IMetaDataAssemblyImport, (void**) &m_pAssemblyImport);
277 Error("QueryInterface failed for IID_IMetaDataAssemblyImport.", hr);
279 } // MDInfo::MDInfo()
282 MDInfo::MDInfo(IMetaDataDispenserEx *pDispenser, PBYTE pbMetaData, DWORD dwSize, strPassBackFn inPBFn, ULONG DumpFilter)
284 _ASSERTE(pDispenser != NULL && inPBFn != NULL);
285 _ASSERTE(NumItems(g_szMapElementType) == NumItems(g_szMapUndecorateType));
286 _ASSERTE(NumItems(g_szMapElementType) == ELEMENT_TYPE_MAX);
288 Init(inPBFn, (DUMP_FILTER)DumpFilter);
290 // Attempt to open scope on manifest. It's valid for this to fail, because
291 // the blob we open may just be the assembly resources (the space is
292 // overloaded until we remove LM -a assemblies, at which point this
293 // constructor should probably be removed too).
296 V_VT(&value) = VT_UI4;
297 V_UI4(&value) = MDImportOptionAll;
298 if (FAILED(hr = pDispenser->SetOption(MetaDataImportOption, &value)))
299 Error("SetOption failed.", hr);
300 if (SUCCEEDED(hr = pDispenser->OpenScopeOnMemory(pbMetaData, dwSize, ofNoTransform,
301 IID_IMetaDataImport2, (IUnknown**)&m_pImport)))
303 // Query for the IMetaDataAssemblyImport interface.
304 hr = m_pImport->QueryInterface(IID_IMetaDataAssemblyImport, (void**) &m_pAssemblyImport);
306 Error("QueryInterface failed for IID_IMetaDataAssemblyImport.", hr);
309 } // MDInfo::MDInfo()
312 strPassBackFn inPBFn, // Callback to write text.
313 DUMP_FILTER DumpFilter) // Flags to control the dump.
315 m_VEHandlerReporterPtr = 0;
317 m_DumpFilter = DumpFilter;
321 m_pAssemblyImport = NULL;
322 } // void MDInfo::Init()
328 m_pImport->Release();
329 if (m_pAssemblyImport)
330 m_pAssemblyImport->Release();
332 m_pTables->Release();
334 m_pTables2->Release();
335 } // MDInfo::~MDInfo()
337 //=====================================================================================================================
338 //#define EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
339 #ifndef EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
341 HINSTANCE GetModuleInst()
344 } // HINSTANCE GetModuleInst()
346 typedef HRESULT (*REPORTFCTN)(LPCWSTR, VEContext, HRESULT);
347 HRESULT DefaultReporter( // Return status.
348 LPCWSTR szMsg, // Error message.
349 VEContext Context, // Error context (offset,token)
350 HRESULT hrRpt) // Original HRESULT
355 // include token and offset from Context
356 if(Context.Token) printf(" [token:0x%08X]",Context.Token);
357 if(Context.uOffset) printf(" [at:0x%X]",Context.uOffset);
358 printf(" [hr:0x%08X]\n",hrRpt);
362 } // HRESULT DefaultReporter()
365 #ifdef FEATURE_METADATA_VALIDATOR
366 class MDVEHandlerClass : public IVEHandler
370 REPORTFCTN m_fnReport;
372 MDVEHandlerClass() { m_refCount=0; m_fnReport=DefaultReporter; };
373 virtual ~MDVEHandlerClass() { };
375 //-----------------------------------------------------------
377 //-----------------------------------------------------------
378 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, void** pInterface)
380 if (id == IID_IVEHandler)
381 *pInterface = (IVEHandler*)this;
383 else if (id == IID_IUnknown)
384 *pInterface = (IUnknown*)(IVEHandler*)this;
389 return E_NOINTERFACE;
395 ULONG STDMETHODCALLTYPE AddRef()
397 return InterlockedIncrement(&m_refCount);
400 ULONG STDMETHODCALLTYPE Release()
402 LONG refCount = InterlockedDecrement(&m_refCount);
403 if (refCount == 0) delete this;
406 //-----------------------------------------------------------
407 // IVEHandler support
408 //-----------------------------------------------------------
409 HRESULT STDMETHODCALLTYPE SetReporterFtn(__int64 lFnPtr)
411 m_fnReport = lFnPtr ? reinterpret_cast<REPORTFCTN>(lFnPtr)
416 //*****************************************************************************
417 // The Verification Event Handler itself. Declared in VEHandler.h as virtual, may be overridden
418 //*****************************************************************************
419 HRESULT STDMETHODCALLTYPE VEHandler(HRESULT hrRpt, VEContext Context, SAFEARRAY *psa)
421 WCHAR rcBuf[1024]; // Resource string.
422 WCHAR rcMsg[1024]; // Error message.
423 BYTE *marker; // User text.
426 WCHAR *pWsz[1024]; // is more than 1024 string arguments likely?
428 // Return warnings without text.
431 memset(pWsz,0,sizeof(pWsz));
434 // Convert safearray of variants into va_list
435 if(psa && (nVars = psa->rgsabound[0].cElements))
442 _ASSERTE(psa->fFeatures & FADF_VARIANT);
443 _ASSERTE(psa->cDims == 1);
444 marker = new BYTE[nVars*sizeof(double)]; // double being the largest variant element
445 for(i=0,pVar=(VARIANT *)(psa->pvData),pval=marker; i < nVars; pVar++,i++)
450 *(int *)pval = V_I1(pVar);
455 *(int *)pval = V_UI1(pVar);
461 *(int *)pval = V_I2(pVar);
466 *(int *)pval = V_UI2(pVar);
472 *(INT64 *)pval = V_I8(pVar);
473 pval += sizeof(INT64);
478 case VT_BYREF|VT_UI1: // it's ASCII string, convert it to UNICODE
480 PBYTE pb = V_UI1REF(pVar);
481 l = (ULONG32)strlen((char *)pb)+1;
483 WszMultiByteToWideChar(CP_ACP,0,(char*)pb,-1,pwsz,l);
484 for(k=0; pWsz[k]; k++);
487 *(WCHAR **)pval = pwsz;
488 pval += sizeof(WCHAR *);
493 *(int *)pval = V_I4(pVar);
502 // If this is one of our errors, then grab the error from the rc file.
503 if (HRESULT_FACILITY(hrRpt) == FACILITY_URT)
505 hr = UtilLoadStringRC(LOWORD(hrRpt), rcBuf, NumItems(rcBuf), true);
509 vswprintf_s(rcMsg, NumItems(rcMsg), rcBuf, (va_list) marker);
510 rcMsg[NumItems(rcMsg) - 1] = 0;
513 // Otherwise it isn't one of ours, so we need to see if the system can
514 // find the text for it.
517 if (WszFormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
518 0, hrRpt, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
519 rcMsg, NumItems(rcMsg), 0))
523 // System messages contain a trailing \r\n, which we don't want normally.
524 int iLen = lstrlenW(rcMsg);
525 if (iLen > 3 && rcMsg[iLen - 2] == '\r' && rcMsg[iLen - 1] == '\n')
526 rcMsg[iLen - 2] = '\0';
529 hr = HRESULT_FROM_WIN32(GetLastError());
531 if(marker) delete [] marker;
533 // If we failed to find the message anywhere, then issue a hard coded message.
536 swprintf_s(rcMsg, NumItems(rcMsg), W("COM+ Runtime Internal error: 0x%08x"), hrRpt);
537 //DEBUG_STMT(DbgWriteEx(rcMsg));
540 // delete WCHAR buffers allocated above (if any)
541 for(k=0; pWsz[k]; k++)
550 return (m_fnReport(rcMsg, Context,hrRpt) == S_OK ? S_OK : E_FAIL);
553 static HRESULT STDMETHODCALLTYPE CreateObject(REFIID id, void **object)
554 { return E_NOTIMPL; }
556 #endif // FEATURE_METADATA_VALIDATOR
559 //=====================================================================================================================
560 // DisplayMD() function
562 // Displays the meta data content of a file
564 void MDInfo::DisplayMD()
566 if ((m_DumpFilter & dumpAssem) && m_pAssemblyImport)
567 DisplayAssemblyInfo();
568 WriteLine("===========================================================");
569 // Metadata itself: Raw or normal view
570 if (m_DumpFilter & (dumpSchema | dumpHeader | dumpCSV | dumpRaw | dumpStats | dumpRawHeaps))
574 DisplayVersionInfo();
576 WriteLine("===========================================================");
577 DisplayGlobalFunctions();
578 DisplayGlobalFields();
579 DisplayGlobalMemberRefs();
583 DisplayMethodSpecs();
587 DisplayUserStrings();
589 // WriteLine("============================================================");
590 // WriteLine("Unresolved MemberRefs");
591 // DisplayMemberRefs(0x00000001, "\t");
593 VWrite("\n\nCoff symbol name overhead: %d\n", g_cbCoffNames);
595 WriteLine("===========================================================");
596 if (m_DumpFilter & dumpUnsat)
598 WriteLine("===========================================================");
599 #ifdef FEATURE_METADATA_VALIDATOR
600 if (m_DumpFilter & dumpValidate)
602 IMetaDataValidate *pValidate = 0;
603 #ifndef EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
604 MDVEHandlerClass *pVEHandler = 0;
606 IVEHandler *pVEHandler = 0;
608 const char *szErrStr = 0;
611 // Get a pointer to the Validator interface.
612 hr = m_pImport->QueryInterface(IID_IMetaDataValidate, (void **) &pValidate);
615 szErrStr = "QueryInterface failed for IMetaDataValidate.";
619 // Get a pointer to the VEHandler interface.
620 #ifndef EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
621 if((pVEHandler = new MDVEHandlerClass())) hr = S_OK;
624 hr = CoCreateInstance(CLSID_VEHandlerClass,
626 CLSCTX_INPROC_SERVER,
628 (void **)&pVEHandler);
632 #ifndef EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
633 szErrStr = "Failed to create VEHandler.";
635 szErrStr = "CoCreateInstance(VEHandler) failed.";
640 if(m_VEHandlerReporterPtr) pVEHandler->SetReporterFtn((__int64)m_VEHandlerReporterPtr);
642 hr = pValidate->ValidatorInit(g_ValModuleType, pVEHandler);
645 szErrStr = "ValidatorInit failed.";
649 hr = pValidate->ValidateMetaData();
652 szErrStr = "ValidateMetaData failed to run successfully.";
656 WriteLine("No warnings or errors found.");
657 else if (hr == VLDTR_S_WRN)
658 WriteLine("Warnings found.");
659 else if (hr == VLDTR_S_ERR)
660 WriteLine("Errors found.");
661 else if (hr == VLDTR_S_WRNERR)
662 WriteLine("Warnings and Errors found.");
664 VWriteLine("Validator returned unexpected success code, hr=0x%08x.", hr);
667 pValidate->Release();
668 #ifdef EXTERNAL_VE_HANDLER_FOR_MD_VALIDATION
670 pVEHandler->Release();
675 #endif // FEATURE_METADATA_VALIDATOR
676 WriteLine("===========================================================");
677 } // MDVEHandlerClass()
679 int MDInfo::WriteLine(__in_z __in const char *str)
681 ULONG32 count = (ULONG32) strlen(str);
686 } // int MDInfo::WriteLine()
688 int MDInfo::Write(__in_z __in const char *str)
690 ULONG32 count = (ULONG32) strlen(str);
694 } // int MDInfo::Write()
696 int MDInfo::VWriteLine(__in_z __in const char *str, ...)
701 va_start(marker, str);
702 count = VWriteMarker(str, marker);
706 } // int MDInfo::VWriteLine()
708 int MDInfo::VWrite(__in_z __in const char *str, ...)
713 va_start(marker, str);
714 count = VWriteMarker(str, marker);
717 } // int MDInfo::VWrite()
719 int MDInfo::VWriteMarker(__in_z __in const char *str, va_list marker)
723 // Used to allocate 1K, then if not enough, 2K, then 4K.
724 // Faster to allocate 32K right away and be done with it,
725 // we're not running on Commodore 64
726 if (FAILED(hr = m_output.ReSizeNoThrow(STRING_BUFFER_LEN * 8)))
727 Error("ReSize failed.", hr);
730 count = vsprintf_s((char *)m_output.Ptr(), STRING_BUFFER_LEN * 8, str, marker);
731 m_pbFn((char *)m_output.Ptr());
734 } // int MDInfo::VWriteToBuffer()
736 // Error() function -- prints an error and returns
737 void MDInfo::Error(const char* szError, HRESULT hr)
739 printf("\n%s\n",szError);
742 printf("Failed return code: 0x%08x\n", hr);
744 IErrorInfo *pIErr = NULL; // Error interface.
745 BSTR bstrDesc = NULL; // Description text.
746 #ifdef FEATURE_COMINTEROP
747 // Try to get an error info object and display the message.
748 if (GetErrorInfo(0, &pIErr) == S_OK &&
749 pIErr->GetDescription(&bstrDesc) == S_OK)
751 printf("%ls ", bstrDesc);
752 SysFreeString(bstrDesc);
755 // Free the error interface.
761 } // void MDInfo::Error()
763 // Print out the optional version info included in the MetaData.
765 void MDInfo::DisplayVersionInfo()
767 if (!(m_DumpFilter & MDInfo::dumpNoLogo))
775 hr = m_pImport->QueryInterface(IID_IMetaDataTables, (void**)&m_pTables);
776 else if (m_pAssemblyImport)
777 hr = m_pAssemblyImport->QueryInterface(IID_IMetaDataTables, (void**)&m_pTables);
781 Error("QueryInterface failed for IID_IMetaDataTables.", hr);
784 hr = m_pTables->GetString(1, &pVersionStr);
786 Error("GetString() failed.", hr);
787 if (strstr(pVersionStr, "Version of runtime against which the binary is built : ")
790 WriteLine(const_cast<char *>(pVersionStr));
793 } // void MDInfo::DisplayVersionInfo()
795 // Prints out information about the scope
797 void MDInfo::DisplayScopeInfo()
802 WCHAR scopeName[STRING_BUFFER_LEN];
803 WCHAR guidString[STRING_BUFFER_LEN];
805 hr = m_pImport->GetScopeProps( scopeName, STRING_BUFFER_LEN, 0, &mvid);
806 if (FAILED(hr)) Error("GetScopeProps failed.", hr);
808 VWriteLine("ScopeName : %ls",scopeName);
810 if (!(m_DumpFilter & MDInfo::dumpNoLogo))
811 VWriteLine("MVID : %ls",GUIDAsString(mvid, guidString, STRING_BUFFER_LEN));
813 hr = m_pImport->GetModuleFromScope(&mdm);
814 if (FAILED(hr)) Error("GetModuleFromScope failed.", hr);
815 DisplayPermissions(mdm, "");
816 DisplayCustomAttributes(mdm, "\t");
817 } // void MDInfo::DisplayScopeInfo()
819 void MDInfo::DisplayRaw()
821 int iDump; // Level of info to dump.
824 m_pImport->QueryInterface(IID_IMetaDataTables, (void**)&m_pTables);
826 Error("Can't get table info.");
828 m_pImport->QueryInterface(IID_IMetaDataTables2, (void**)&m_pTables2);
830 if (m_DumpFilter & dumpCSV)
832 if (m_DumpFilter & (dumpSchema | dumpHeader | dumpRaw | dumpStats))
834 if (m_DumpFilter & dumpRaw)
837 if (m_DumpFilter & dumpSchema)
842 DumpRaw(iDump, (m_DumpFilter & dumpStats) != 0);
844 if (m_DumpFilter & dumpRawHeaps)
846 } // void MDInfo::DisplayRaw()
848 // return the name of the type of token passed in
850 const char *MDInfo::TokenTypeName(mdToken inToken)
852 switch(TypeFromToken(inToken))
854 case mdtTypeDef: return "TypeDef";
855 case mdtInterfaceImpl: return "InterfaceImpl";
856 case mdtMethodDef: return "MethodDef";
857 case mdtFieldDef: return "FieldDef";
858 case mdtTypeRef: return "TypeRef";
859 case mdtMemberRef: return "MemberRef";
860 case mdtCustomAttribute:return "CustomAttribute";
861 case mdtParamDef: return "ParamDef";
862 case mdtProperty: return "Property";
863 case mdtEvent: return "Event";
864 case mdtTypeSpec: return "TypeSpec";
865 default: return "[UnknownTokenType]";
867 } // char *MDInfo::TokenTypeName()
869 // Prints out name of the given memberref
872 LPCWSTR MDInfo::MemberRefName(mdMemberRef inMemRef, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
877 hr = m_pImport->GetMemberRefProps( inMemRef, NULL, buffer, bufLen,
879 if (FAILED(hr)) Error("GetMemberRefProps failed.", hr);
882 } // LPCWSTR MDInfo::MemberRefName()
885 // Prints out information about the given memberref
888 void MDInfo::DisplayMemberRefInfo(mdMemberRef inMemRef, const char *preFix)
891 WCHAR memRefName[STRING_BUFFER_LEN];
894 PCCOR_SIGNATURE pbSigBlob;
896 char newPreFix[STRING_BUFFER_LEN];
899 hr = m_pImport->GetMemberRefProps( inMemRef, &token, memRefName, STRING_BUFFER_LEN,
900 &nameLen, &pbSigBlob, &ulSigBlob);
901 if (FAILED(hr)) Error("GetMemberRefProps failed.", hr);
903 VWriteLine("%s\t\tMember: (%8.8x) %ls: ", preFix, inMemRef, memRefName);
906 DisplaySignature(pbSigBlob, ulSigBlob, preFix);
908 VWriteLine("%s\t\tERROR: no valid signature ", preFix);
910 sprintf_s (newPreFix, STRING_BUFFER_LEN, "\t\t%s", preFix);
911 DisplayCustomAttributes(inMemRef, newPreFix);
912 } // void MDInfo::DisplayMemberRefInfo()
914 // Prints out information about all memberrefs of the given typeref
917 void MDInfo::DisplayMemberRefs(mdToken tkParent, const char *preFix)
919 HCORENUM memRefEnum = NULL;
921 mdMemberRef memRefs[ENUM_BUFFER_SIZE];
922 ULONG count, totalCount = 1;
925 while (SUCCEEDED(hr = m_pImport->EnumMemberRefs( &memRefEnum, tkParent,
926 memRefs, NumItems(memRefs), &count)) &&
929 for (ULONG i = 0; i < count; i++, totalCount++)
931 VWriteLine("%s\tMemberRef #%d (%08x)", preFix, totalCount, memRefs[i]);
932 VWriteLine("%s\t-------------------------------------------------------", preFix);
933 DisplayMemberRefInfo(memRefs[i], preFix);
936 m_pImport->CloseEnum( memRefEnum);
937 } // void MDInfo::DisplayMemberRefs()
939 // Prints out information about all resources in the com object
942 // Iterates through each typeref and prints out the information of each
945 void MDInfo::DisplayTypeRefs()
947 HCORENUM typeRefEnum = NULL;
948 mdTypeRef typeRefs[ENUM_BUFFER_SIZE];
949 ULONG count, totalCount=1;
952 while (SUCCEEDED(hr = m_pImport->EnumTypeRefs( &typeRefEnum,
953 typeRefs, NumItems(typeRefs), &count)) &&
956 for (ULONG i = 0; i < count; i++, totalCount++)
958 VWriteLine("TypeRef #%d (%08x)", totalCount, typeRefs[i]);
959 WriteLine("-------------------------------------------------------");
960 DisplayTypeRefInfo(typeRefs[i]);
961 DisplayMemberRefs(typeRefs[i], "");
965 m_pImport->CloseEnum( typeRefEnum);
966 } // void MDInfo::DisplayTypeRefs()
968 void MDInfo::DisplayTypeSpecs()
970 HCORENUM typespecEnum = NULL;
971 mdTypeSpec typespecs[ENUM_BUFFER_SIZE];
972 ULONG count, totalCount=1;
975 while (SUCCEEDED(hr = m_pImport->EnumTypeSpecs( &typespecEnum,
976 typespecs, NumItems(typespecs), &count)) &&
979 for (ULONG i = 0; i < count; i++, totalCount++)
981 VWriteLine("TypeSpec #%d (%08x)", totalCount, typespecs[i]);
982 WriteLine("-------------------------------------------------------");
983 DisplayTypeSpecInfo(typespecs[i], "");
984 DisplayMemberRefs(typespecs[i], "");
988 m_pImport->CloseEnum( typespecEnum);
989 } // void MDInfo::DisplayTypeSpecs()
991 void MDInfo::DisplayMethodSpecs()
993 HCORENUM MethodSpecEnum = NULL;
994 mdMethodSpec MethodSpecs[ENUM_BUFFER_SIZE];
995 ULONG count, totalCount=1;
999 ///// HACK until I implement EnumMethodSpecs!
1000 ///// while (SUCCEEDED(hr = m_pImport->EnumMethodSpecs( &MethodSpecEnum,
1001 ///// MethodSpecs, NumItems(MethodSpecs), &count)) &&
1003 for (ULONG rid=1; m_pImport->IsValidToken(TokenFromRid(rid, mdtMethodSpec)); ++rid)
1007 MethodSpecs[0] = TokenFromRid(rid, mdtMethodSpec);
1009 for (ULONG i = 0; i < count; i++, totalCount++)
1011 VWriteLine("MethodSpec #%d (%08x)", totalCount, MethodSpecs[i]);
1012 DisplayMethodSpecInfo(MethodSpecs[i], "");
1016 m_pImport->CloseEnum( MethodSpecEnum);
1017 } // void MDInfo::DisplayMethodSpecs()
1021 // Called to display the information about all typedefs in the object.
1024 void MDInfo::DisplayTypeDefs()
1026 HCORENUM typeDefEnum = NULL;
1027 mdTypeDef typeDefs[ENUM_BUFFER_SIZE];
1028 ULONG count, totalCount = 1;
1031 while (SUCCEEDED(hr = m_pImport->EnumTypeDefs( &typeDefEnum,
1032 typeDefs, NumItems(typeDefs), &count)) &&
1035 for (ULONG i = 0; i < count; i++, totalCount++)
1037 VWriteLine("TypeDef #%d (%08x)", totalCount, typeDefs[i]);
1038 WriteLine("-------------------------------------------------------");
1039 DisplayTypeDefInfo(typeDefs[i]);
1043 m_pImport->CloseEnum( typeDefEnum);
1044 } // void MDInfo::DisplayTypeDefs()
1046 // Called to display the information about all modulerefs in the object.
1049 void MDInfo::DisplayModuleRefs()
1051 HCORENUM moduleRefEnum = NULL;
1052 mdModuleRef moduleRefs[ENUM_BUFFER_SIZE];
1053 ULONG count, totalCount = 1;
1056 while (SUCCEEDED(hr = m_pImport->EnumModuleRefs( &moduleRefEnum,
1057 moduleRefs, NumItems(moduleRefs), &count)) &&
1060 for (ULONG i = 0; i < count; i++, totalCount++)
1062 VWriteLine("ModuleRef #%d (%08x)", totalCount, moduleRefs[i]);
1063 WriteLine("-------------------------------------------------------");
1064 DisplayModuleRefInfo(moduleRefs[i]);
1065 DisplayMemberRefs(moduleRefs[i], "");
1069 m_pImport->CloseEnum( moduleRefEnum);
1070 } // void MDInfo::DisplayModuleRefs()
1072 // Prints out information about the given moduleref
1075 void MDInfo::DisplayModuleRefInfo(mdModuleRef inModuleRef)
1078 WCHAR moduleRefName[STRING_BUFFER_LEN];
1082 hr = m_pImport->GetModuleRefProps( inModuleRef, moduleRefName, STRING_BUFFER_LEN,
1084 if (FAILED(hr)) Error("GetModuleRefProps failed.", hr);
1086 VWriteLine("\t\tModuleRef: (%8.8x) %ls: ", inModuleRef, moduleRefName);
1087 DisplayCustomAttributes(inModuleRef, "\t\t");
1088 } // void MDInfo::DisplayModuleRefInfo()
1091 // Called to display the information about all signatures in the object.
1094 void MDInfo::DisplaySignatures()
1096 HCORENUM signatureEnum = NULL;
1097 mdSignature signatures[ENUM_BUFFER_SIZE];
1098 ULONG count, totalCount = 1;
1101 while (SUCCEEDED(hr = m_pImport->EnumSignatures( &signatureEnum,
1102 signatures, NumItems(signatures), &count)) &&
1105 for (ULONG i = 0; i < count; i++, totalCount++)
1107 VWriteLine("Signature #%d (%#08x)", totalCount, signatures[i]);
1108 WriteLine("-------------------------------------------------------");
1109 DisplaySignatureInfo(signatures[i]);
1113 m_pImport->CloseEnum( signatureEnum);
1114 } // void MDInfo::DisplaySignatures()
1117 // Prints out information about the given signature
1120 void MDInfo::DisplaySignatureInfo(mdSignature inSignature)
1123 PCCOR_SIGNATURE pbSigBlob;
1127 hr = m_pImport->GetSigFromToken( inSignature, &pbSigBlob, &ulSigBlob );
1128 if (FAILED(hr)) Error("GetSigFromToken failed.", hr);
1130 DisplaySignature(pbSigBlob, ulSigBlob, "");
1132 VWriteLine("\t\tERROR: no valid signature ");
1133 } // void MDInfo::DisplaySignatureInfo()
1136 // returns the passed-in buffer which is filled with the name of the given
1137 // member in wide characters
1140 LPCWSTR MDInfo::MemberName(mdToken inToken, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1145 hr = m_pImport->GetMemberProps( inToken, NULL, buffer, bufLen,
1146 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1147 if (FAILED(hr)) Error("GetMemberProps failed.", hr);
1150 } // LPCWSTR MDInfo::MemberName()
1153 // displays information for the given method
1156 void MDInfo::DisplayMethodInfo(mdMethodDef inMethod, DWORD *pflags)
1159 mdTypeDef memTypeDef;
1160 WCHAR memberName[STRING_BUFFER_LEN];
1163 PCCOR_SIGNATURE pbSigBlob;
1169 hr = m_pImport->GetMethodProps( inMethod, &memTypeDef, memberName, STRING_BUFFER_LEN,
1170 &nameLen, &flags, &pbSigBlob, &ulSigBlob, &ulCodeRVA, &ulImplFlags);
1171 if (FAILED(hr)) Error("GetMethodProps failed.", hr);
1175 VWriteLine("\t\tMethodName: %ls (%8.8X)", memberName, inMethod);
1177 char sFlags[STRING_BUFFER_LEN];
1181 ISFLAG(Md, Private);
1184 ISFLAG(Md, FamANDAssem);
1185 ISFLAG(Md, FamORAssem);
1186 ISFLAG(Md, PrivateScope);
1189 ISFLAG(Md, Virtual);
1190 ISFLAG(Md, HideBySig);
1191 ISFLAG(Md, ReuseSlot);
1192 ISFLAG(Md, NewSlot);
1193 ISFLAG(Md, Abstract);
1194 ISFLAG(Md, SpecialName);
1195 ISFLAG(Md, RTSpecialName);
1196 ISFLAG(Md, PinvokeImpl);
1197 ISFLAG(Md, UnmanagedExport);
1199 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
1201 bool result = (((flags) & mdRTSpecialName) && !wcscmp((memberName), W(".ctor")));
1202 if (result) strcat_s(sFlags, STRING_BUFFER_LEN, "[.ctor] ");
1203 result = (((flags) & mdRTSpecialName) && !wcscmp((memberName), W(".cctor")));
1204 if (result) strcat_s(sFlags,STRING_BUFFER_LEN, "[.cctor] ");
1206 ISFLAG(Md, HasSecurity);
1207 ISFLAG(Md, RequireSecObject);
1209 VWriteLine("\t\tFlags : %s (%08x)", sFlags, flags);
1210 VWriteLine("\t\tRVA : 0x%08x", ulCodeRVA);
1212 flags = ulImplFlags;
1217 ISFLAG(Mi, Runtime);
1218 ISFLAG(Mi, Unmanaged);
1219 ISFLAG(Mi, Managed);
1220 ISFLAG(Mi, ForwardRef);
1221 ISFLAG(Mi, PreserveSig);
1222 ISFLAG(Mi, InternalCall);
1223 ISFLAG(Mi, Synchronized);
1224 ISFLAG(Mi, NoInlining);
1226 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
1228 VWriteLine("\t\tImplFlags : %s (%08x)", sFlags, flags);
1231 DisplaySignature(pbSigBlob, ulSigBlob, "");
1233 VWriteLine("\t\tERROR: no valid signature ");
1235 DisplayGenericParams(inMethod, "\t\t");
1237 } // void MDInfo::DisplayMethodInfo()
1239 // displays the member information for the given field
1242 void MDInfo::DisplayFieldInfo(mdFieldDef inField, DWORD *pdwFlags)
1245 mdTypeDef memTypeDef;
1246 WCHAR memberName[STRING_BUFFER_LEN];
1249 PCCOR_SIGNATURE pbSigBlob;
1251 DWORD dwCPlusTypeFlag;
1254 #ifdef FEATURE_COMINTEROP
1255 VARIANT defaultValue;
1257 ::VariantInit(&defaultValue);
1259 hr = m_pImport->GetFieldProps( inField, &memTypeDef, memberName, STRING_BUFFER_LEN,
1260 &nameLen, &flags, &pbSigBlob, &ulSigBlob, &dwCPlusTypeFlag,
1262 if (FAILED(hr)) Error("GetFieldProps failed.", hr);
1267 #ifdef FEATURE_COMINTEROP
1268 _FillVariant((BYTE)dwCPlusTypeFlag, pValue, cbValue, &defaultValue);
1271 char sFlags[STRING_BUFFER_LEN];
1275 ISFLAG(Fd, Private);
1277 ISFLAG(Fd, Assembly);
1278 ISFLAG(Fd, FamANDAssem);
1279 ISFLAG(Fd, FamORAssem);
1280 ISFLAG(Fd, PrivateScope);
1282 ISFLAG(Fd, InitOnly);
1283 ISFLAG(Fd, Literal);
1284 ISFLAG(Fd, NotSerialized);
1285 ISFLAG(Fd, SpecialName);
1286 ISFLAG(Fd, RTSpecialName);
1287 ISFLAG(Fd, PinvokeImpl);
1289 ISFLAG(Fd, HasDefault);
1291 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
1293 VWriteLine("\t\tField Name: %ls (%8.8X)", memberName, inField);
1294 VWriteLine("\t\tFlags : %s (%08x)", sFlags, flags);
1295 #ifdef FEATURE_COMINTEROP
1296 if (IsFdHasDefault(flags))
1297 VWriteLine("\tDefltValue: (%s) %ls", g_szMapElementType[dwCPlusTypeFlag], VariantAsString(&defaultValue));
1299 if (!ulSigBlob) // Signature size should be non-zero for fields
1300 VWriteLine("\t\tERROR: no valid signature ");
1302 DisplaySignature(pbSigBlob, ulSigBlob, "");
1303 #ifdef FEATURE_COMINTEROP
1304 ::VariantClear(&defaultValue);
1306 } // void MDInfo::DisplayFieldInfo()
1308 // displays the RVA for the given global field.
1309 void MDInfo::DisplayFieldRVA(mdFieldDef inFieldDef)
1314 hr = m_pImport->GetRVA(inFieldDef, &ulRVA, 0);
1315 if (FAILED(hr) && hr != CLDB_E_RECORD_NOTFOUND) Error("GetRVA failed.", hr);
1317 VWriteLine("\t\tRVA : 0x%08x", ulRVA);
1318 } // void MDInfo::DisplayFieldRVA()
1320 // displays information about every global function.
1321 void MDInfo::DisplayGlobalFunctions()
1323 WriteLine("Global functions");
1324 WriteLine("-------------------------------------------------------");
1325 DisplayMethods(mdTokenNil);
1327 } // void MDInfo::DisplayGlobalFunctions()
1329 // displays information about every global field.
1330 void MDInfo::DisplayGlobalFields()
1332 WriteLine("Global fields");
1333 WriteLine("-------------------------------------------------------");
1334 DisplayFields(mdTokenNil, NULL, 0);
1336 } // void MDInfo::DisplayGlobalFields()
1338 // displays information about every global memberref.
1339 void MDInfo::DisplayGlobalMemberRefs()
1341 WriteLine("Global MemberRefs");
1342 WriteLine("-------------------------------------------------------");
1343 DisplayMemberRefs(mdTokenNil, "");
1345 } // void MDInfo::DisplayGlobalMemberRefs()
1347 // displays information about every method in a given typedef
1350 void MDInfo::DisplayMethods(mdTypeDef inTypeDef)
1352 HCORENUM methodEnum = NULL;
1353 mdToken methods[ENUM_BUFFER_SIZE];
1355 ULONG count, totalCount = 1;
1359 while (SUCCEEDED(hr = m_pImport->EnumMethods( &methodEnum, inTypeDef,
1360 methods, NumItems(methods), &count)) &&
1363 for (ULONG i = 0; i < count; i++, totalCount++)
1365 VWriteLine("\tMethod #%d (%08x) %s", totalCount, methods[i], (methods[i] == g_tkEntryPoint) ? "[ENTRYPOINT]" : "");
1366 WriteLine("\t-------------------------------------------------------");
1367 DisplayMethodInfo(methods[i], &flags);
1368 DisplayParams(methods[i]);
1369 DisplayCustomAttributes(methods[i], "\t\t");
1370 DisplayPermissions(methods[i], "\t");
1371 DisplayMemberRefs(methods[i], "\t");
1373 // P-invoke data if present.
1374 if (IsMdPinvokeImpl(flags))
1375 DisplayPinvokeInfo(methods[i]);
1380 m_pImport->CloseEnum( methodEnum);
1381 } // void MDInfo::DisplayMethods()
1384 // displays information about every field in a given typedef
1387 void MDInfo::DisplayFields(mdTypeDef inTypeDef, COR_FIELD_OFFSET *rFieldOffset, ULONG cFieldOffset)
1389 HCORENUM fieldEnum = NULL;
1390 mdToken fields[ENUM_BUFFER_SIZE];
1391 ULONG count, totalCount = 1;
1396 while (SUCCEEDED(hr = m_pImport->EnumFields( &fieldEnum, inTypeDef,
1397 fields, NumItems(fields), &count)) &&
1400 for (ULONG i = 0; i < count; i++, totalCount++)
1402 VWriteLine("\tField #%d (%08x)",totalCount, fields[i]);
1403 WriteLine("\t-------------------------------------------------------");
1404 DisplayFieldInfo(fields[i], &flags);
1405 DisplayCustomAttributes(fields[i], "\t\t");
1406 DisplayPermissions(fields[i], "\t");
1407 DisplayFieldMarshal(fields[i]);
1409 // RVA if its a global field.
1410 if (inTypeDef == mdTokenNil)
1411 DisplayFieldRVA(fields[i]);
1413 // P-invoke data if present.
1414 if (IsFdPinvokeImpl(flags))
1415 DisplayPinvokeInfo(fields[i]);
1417 // Display offset if present.
1421 for (ULONG iLayout = 0; i < cFieldOffset; ++iLayout)
1423 if (RidFromToken(rFieldOffset[iLayout].ridOfField) == RidFromToken(fields[i]))
1426 VWriteLine("\t\tOffset : 0x%08x", rFieldOffset[iLayout].ulOffset);
1435 m_pImport->CloseEnum( fieldEnum);
1436 } // void MDInfo::DisplayFields()
1439 // displays information about every methodImpl in a given typedef
1442 void MDInfo::DisplayMethodImpls(mdTypeDef inTypeDef)
1444 HCORENUM methodImplEnum = NULL;
1445 mdMethodDef rtkMethodBody[ENUM_BUFFER_SIZE];
1446 mdMethodDef rtkMethodDecl[ENUM_BUFFER_SIZE];
1448 ULONG count, totalCount=1;
1452 while (SUCCEEDED(hr = m_pImport->EnumMethodImpls( &methodImplEnum, inTypeDef,
1453 rtkMethodBody, rtkMethodDecl, NumItems(rtkMethodBody), &count)) &&
1456 for (ULONG i = 0; i < count; i++, totalCount++)
1458 VWriteLine("\n\tMethodImpl #%d (%08x)", totalCount, totalCount);
1459 WriteLine("\t-------------------------------------------------------");
1460 VWriteLine("\t\tMethod Body Token : 0x%08x", rtkMethodBody[i]);
1461 VWriteLine("\t\tMethod Declaration Token : 0x%08x", rtkMethodDecl[i]);
1465 m_pImport->CloseEnum( methodImplEnum);
1466 } // void MDInfo::DisplayMethodImpls()
1468 // displays information about the given parameter
1471 void MDInfo::DisplayParamInfo(mdParamDef inParamDef)
1475 WCHAR paramName[STRING_BUFFER_LEN];
1483 #ifdef FEATURE_COMINTEROP
1484 ::VariantInit(&defValue);
1486 HRESULT hr = m_pImport->GetParamProps( inParamDef, &md, &num, paramName, NumItems(paramName),
1487 &nameLen, &flags, &dwCPlusFlags, &pValue, &cbValue);
1488 if (FAILED(hr)) Error("GetParamProps failed.", hr);
1490 _FillVariant((BYTE)dwCPlusFlags, pValue, cbValue, &defValue);
1492 char sFlags[STRING_BUFFER_LEN];
1496 ISFLAG(Pd, Optional);
1497 // "Reserved" flags.
1498 ISFLAG(Pd, HasDefault);
1499 ISFLAG(Pd, HasFieldMarshal);
1501 strcpy_s(sFlags,STRING_BUFFER_LEN, "[none]");
1503 VWrite("\t\t\t(%ld) ParamToken : (%08x) Name : %ls flags: %s (%08x)", num, inParamDef, paramName, sFlags, flags);
1504 #ifdef FEATURE_COMINTEROP
1505 if (IsPdHasDefault(flags))
1506 VWriteLine(" Default: (%s) %ls", g_szMapElementType[dwCPlusFlags], VariantAsString(&defValue));
1510 DisplayCustomAttributes(inParamDef, "\t\t\t");
1512 #ifdef FEATURE_COMINTEROP
1513 ::VariantClear(&defValue);
1515 } // void MDInfo::DisplayParamInfo()
1518 // displays all parameters for a given memberdef
1521 void MDInfo::DisplayParams(mdMethodDef inMethodDef)
1523 HCORENUM paramEnum = NULL;
1524 mdParamDef params[ENUM_BUFFER_SIZE];
1525 ULONG count, paramCount;
1530 while (SUCCEEDED(hr = m_pImport->EnumParams( ¶mEnum, inMethodDef,
1531 params, NumItems(params), &count)) &&
1536 m_pImport->CountEnum( paramEnum, ¶mCount);
1537 VWriteLine("\t\t%d Parameters", paramCount);
1539 for (ULONG i = 0; i < count; i++)
1541 DisplayParamInfo(params[i]);
1542 DisplayFieldMarshal(params[i]);
1546 m_pImport->CloseEnum( paramEnum);
1547 } // void MDInfo::DisplayParams()
1549 void MDInfo::DisplayGenericParams(mdToken tk, const char *prefix)
1551 HCORENUM paramEnum = NULL;
1552 mdParamDef params[ENUM_BUFFER_SIZE];
1553 ULONG count, paramCount;
1558 while (SUCCEEDED(hr = m_pImport->EnumGenericParams( ¶mEnum, tk,
1559 params, NumItems(params), &count)) &&
1564 m_pImport->CountEnum( paramEnum, ¶mCount);
1565 VWriteLine("%s%d Generic Parameters", prefix, paramCount);
1567 for (ULONG i = 0; i < count; i++)
1569 DisplayGenericParamInfo(params[i], prefix);
1573 m_pImport->CloseEnum( paramEnum);
1576 void MDInfo::DisplayGenericParamInfo(mdGenericParam tkParam, const char *prefix)
1579 WCHAR paramName[STRING_BUFFER_LEN];
1584 HCORENUM constraintEnum = NULL;
1585 mdParamDef constraints[4];
1586 ULONG count, constraintCount;
1591 HRESULT hr = m_pImport->GetGenericParamProps(tkParam, &ulSeq, &flags, &tkOwner, NULL, paramName, NumItems(paramName), &nameLen);
1592 if (FAILED(hr)) Error("GetGenericParamProps failed.", hr);
1594 VWriteLine("%s\t(%ld) GenericParamToken : (%08x) Name : %ls flags: %08x Owner: %08x", prefix, ulSeq, tkParam, paramName, flags, tkOwner);
1596 // Any constraints for the GenericParam
1597 while (SUCCEEDED(hr = m_pImport->EnumGenericParamConstraints(&constraintEnum, tkParam,
1598 constraints, NumItems(constraints), &count)) &&
1603 m_pImport->CountEnum( constraintEnum, &constraintCount);
1604 VWriteLine("%s\t\t%d Constraint(s)", prefix, constraintCount);
1606 VWrite("%s\t\t", prefix);
1607 for (ULONG i=0; i< count; ++i)
1609 hr = m_pImport->GetGenericParamConstraintProps(constraints[i], &owner, &constraint);
1610 if (owner != tkParam)
1611 VWrite("%08x (owner: %08x) ", constraint, owner);
1613 VWrite("%08x ", constraint);
1617 m_pImport->CloseEnum(constraintEnum);
1619 sprintf_s(newprefix, 30, "%s\t", prefix);
1620 DisplayCustomAttributes(tkParam, newprefix);
1623 LPCWSTR MDInfo::TokenName(mdToken inToken, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1625 LPCUTF8 pName; // Token name in UTF8.
1627 if (IsNilToken(inToken))
1630 m_pImport->GetNameFromToken(inToken, &pName);
1632 WszMultiByteToWideChar(CP_UTF8,0, pName,-1, buffer,bufLen);
1635 } // LPCWSTR MDInfo::TokenName()
1637 // prints out name of typeref or typedef
1640 LPCWSTR MDInfo::TypeDeforRefName(mdToken inToken, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1642 if (RidFromToken(inToken))
1644 if (TypeFromToken(inToken) == mdtTypeDef)
1645 return (TypeDefName((mdTypeDef) inToken, buffer, bufLen));
1646 else if (TypeFromToken(inToken) == mdtTypeRef)
1647 return (TypeRefName((mdTypeRef) inToken, buffer, bufLen));
1648 else if (TypeFromToken(inToken) == mdtTypeSpec)
1649 return W("[TypeSpec]");
1651 return W("[InvalidReference]");
1655 } // LPCWSTR MDInfo::TypeDeforRefName()
1657 LPCWSTR MDInfo::MemberDeforRefName(mdToken inToken, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1659 if (RidFromToken(inToken))
1661 if (TypeFromToken(inToken) == mdtMethodDef || TypeFromToken(inToken) == mdtFieldDef)
1662 return (MemberName(inToken, buffer, bufLen));
1663 else if (TypeFromToken(inToken) == mdtMemberRef)
1664 return (MemberRefName((mdMemberRef) inToken, buffer, bufLen));
1666 return W("[InvalidReference]");
1670 } // LPCWSTR MDInfo::MemberDeforRefName()
1672 // prints out only the name of the given typedef
1676 LPCWSTR MDInfo::TypeDefName(mdTypeDef inTypeDef, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1680 hr = m_pImport->GetTypeDefProps(
1681 // [IN] The import scope.
1682 inTypeDef, // [IN] TypeDef token for inquiry.
1683 buffer, // [OUT] Put name here.
1684 bufLen, // [IN] size of name buffer in wide chars.
1685 NULL, // [OUT] put size of name (wide chars) here.
1686 NULL, // [OUT] Put flags here.
1687 NULL); // [OUT] Put base class TypeDef/TypeRef here.
1690 swprintf_s(buffer, bufLen, W("[Invalid TypeDef]"));
1694 } // LPCWSTR MDInfo::TypeDefName()
1696 // prints out all the properties of a given typedef
1699 void MDInfo::DisplayTypeDefProps(mdTypeDef inTypeDef)
1702 WCHAR typeDefName[STRING_BUFFER_LEN];
1706 ULONG dwPacking; // Packing size of class, if specified.
1707 ULONG dwSize; // Total size of class, if specified.
1709 hr = m_pImport->GetTypeDefProps(
1710 inTypeDef, // [IN] TypeDef token for inquiry.
1711 typeDefName, // [OUT] Put name here.
1712 STRING_BUFFER_LEN, // [IN] size of name buffer in wide chars.
1713 &nameLen, // [OUT] put size of name (wide chars) here.
1714 &flags, // [OUT] Put flags here.
1715 &extends); // [OUT] Put base class TypeDef/TypeRef here.
1716 if (FAILED(hr)) Error("GetTypeDefProps failed.", hr);
1718 char sFlags[STRING_BUFFER_LEN];
1719 WCHAR szTempBuf[STRING_BUFFER_LEN];
1721 VWriteLine("\tTypDefName: %ls (%8.8X)",typeDefName,inTypeDef);
1722 VWriteLine("\tFlags : %s (%08x)",ClassFlags(flags, sFlags), flags);
1723 VWriteLine("\tExtends : %8.8X [%s] %ls",extends,TokenTypeName(extends),
1724 TypeDeforRefName(extends, szTempBuf, NumItems(szTempBuf)));
1726 hr = m_pImport->GetClassLayout(inTypeDef, &dwPacking, 0,0,0, &dwSize);
1728 VWriteLine("\tLayout : Packing:%d, Size:%d", dwPacking, dwSize);
1730 if (IsTdNested(flags))
1732 mdTypeDef tkEnclosingClass;
1734 hr = m_pImport->GetNestedClassProps(inTypeDef, &tkEnclosingClass);
1737 VWriteLine("\tEnclosingClass : %ls (%8.8X)", TypeDeforRefName(tkEnclosingClass,
1738 szTempBuf, NumItems(szTempBuf)), tkEnclosingClass);
1740 else if (hr == CLDB_E_RECORD_NOTFOUND)
1741 WriteLine("ERROR: EnclosingClass not found for NestedClass");
1743 Error("GetNestedClassProps failed.", hr);
1745 } // void MDInfo::DisplayTypeDefProps()
1747 // Prints out the name of the given TypeRef
1750 LPCWSTR MDInfo::TypeRefName(mdTypeRef tr, __out_ecount(bufLen) LPWSTR buffer, ULONG bufLen)
1754 hr = m_pImport->GetTypeRefProps(
1755 tr, // The class ref token.
1756 NULL, // Resolution scope.
1757 buffer, // Put the name here.
1758 bufLen, // Size of the name buffer, wide chars.
1759 NULL); // Put actual size of name here.
1762 swprintf_s(buffer, bufLen, W("[Invalid TypeRef]"));
1766 } // LPCWSTR MDInfo::TypeRefName()
1768 // Prints out all the info of the given TypeRef
1771 void MDInfo::DisplayTypeRefInfo(mdTypeRef tr)
1774 mdToken tkResolutionScope;
1775 WCHAR typeRefName[STRING_BUFFER_LEN];
1778 hr = m_pImport->GetTypeRefProps(
1779 tr, // The class ref token.
1780 &tkResolutionScope, // ResolutionScope.
1781 typeRefName, // Put the name here.
1782 STRING_BUFFER_LEN, // Size of the name buffer, wide chars.
1783 &nameLen); // Put actual size of name here.
1785 if (FAILED(hr)) Error("GetTypeRefProps failed.", hr);
1787 VWriteLine("Token: 0x%08x", tr);
1788 VWriteLine("ResolutionScope: 0x%08x", tkResolutionScope);
1789 VWriteLine("TypeRefName: %ls",typeRefName);
1791 DisplayCustomAttributes(tr, "\t");
1792 } // void MDInfo::DisplayTypeRefInfo()
1795 void MDInfo::DisplayTypeSpecInfo(mdTypeSpec ts, const char *preFix)
1798 PCCOR_SIGNATURE pvSig;
1804 hr = m_pImport->GetTypeSpecFromToken(
1805 ts, // The class ref token.
1809 if (FAILED(hr)) Error("GetTypeSpecFromToken failed.", hr);
1811 // DisplaySignature(pvSig, cbSig, preFix);
1813 if (FAILED(hr = GetOneElementType(pvSig, cbSig, &cb)))
1816 VWriteLine("%s\tTypeSpec :%s", preFix, (LPSTR)m_sigBuf.Ptr());
1819 if (m_DumpFilter & dumpMoreHex)
1821 char rcNewPrefix[80];
1822 sprintf_s(rcNewPrefix, 80, "%s\tSignature", preFix);
1823 DumpHex(rcNewPrefix, pvSig, cbSig, false, 24);
1827 } // void MDInfo::DisplayTypeSpecInfo()
1829 void MDInfo::DisplayMethodSpecInfo(mdMethodSpec ms, const char *preFix)
1832 PCCOR_SIGNATURE pvSig;
1838 hr = m_pImport->GetMethodSpecProps(
1839 ms, // The MethodSpec token
1840 &tk, // The MethodDef or MemberRef
1841 &pvSig, // Signature.
1842 &cbSig); // Size of signature.
1844 VWriteLine("%s\tParent : 0x%08x", preFix, tk);
1845 DisplaySignature(pvSig, cbSig, preFix);
1848 } // void MDInfo::DisplayMethodSpecInfo()
1850 // Return the passed-in buffer filled with a string detailing the class flags
1851 // associated with the class.
1854 char *MDInfo::ClassFlags(DWORD flags, __out_ecount(STRING_BUFFER_LEN) char *sFlags)
1857 ISFLAG(Td, NotPublic);
1859 ISFLAG(Td, NestedPublic);
1860 ISFLAG(Td, NestedPrivate);
1861 ISFLAG(Td, NestedFamily);
1862 ISFLAG(Td, NestedAssembly);
1863 ISFLAG(Td, NestedFamANDAssem);
1864 ISFLAG(Td, NestedFamORAssem);
1865 ISFLAG(Td, AutoLayout);
1866 ISFLAG(Td, SequentialLayout);
1867 ISFLAG(Td, ExplicitLayout);
1869 ISFLAG(Td, Interface);
1870 ISFLAG(Td, Abstract);
1872 ISFLAG(Td, SpecialName);
1874 ISFLAG(Td, Serializable);
1875 ISFLAG(Td, AnsiClass);
1876 ISFLAG(Td, UnicodeClass);
1877 ISFLAG(Td, AutoClass);
1878 ISFLAG(Td, BeforeFieldInit);
1879 ISFLAG(Td, Forwarder);
1881 ISFLAG(Td, RTSpecialName);
1882 ISFLAG(Td, HasSecurity);
1883 ISFLAG(Td, WindowsRuntime);
1885 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
1888 } // char *MDInfo::ClassFlags()
1890 // prints out all info on the given typeDef, including all information that
1891 // is specific to a given typedef
1894 void MDInfo::DisplayTypeDefInfo(mdTypeDef inTypeDef)
1896 DisplayTypeDefProps(inTypeDef);
1898 // Get field layout information.
1899 HRESULT hr = NOERROR;
1900 COR_FIELD_OFFSET *rFieldOffset = NULL;
1901 ULONG cFieldOffset = 0;
1902 hr = m_pImport->GetClassLayout(inTypeDef, NULL, rFieldOffset, 0, &cFieldOffset, NULL);
1903 if (SUCCEEDED(hr) && cFieldOffset)
1905 rFieldOffset = new COR_FIELD_OFFSET[cFieldOffset];
1906 if (rFieldOffset == NULL)
1907 Error("_calloc failed.", E_OUTOFMEMORY);
1908 hr = m_pImport->GetClassLayout(inTypeDef, NULL, rFieldOffset, cFieldOffset, &cFieldOffset, NULL);
1909 if (FAILED(hr)) { delete [] rFieldOffset; Error("GetClassLayout() failed.", hr); }
1912 //No reason to display members if we're displaying fields and methods separately
1913 DisplayGenericParams(inTypeDef, "\t");
1914 DisplayFields(inTypeDef, rFieldOffset, cFieldOffset);
1915 delete [] rFieldOffset;
1916 DisplayMethods(inTypeDef);
1917 DisplayProperties(inTypeDef);
1918 DisplayEvents(inTypeDef);
1919 DisplayMethodImpls(inTypeDef);
1920 DisplayPermissions(inTypeDef, "");
1922 DisplayInterfaceImpls(inTypeDef);
1923 DisplayCustomAttributes(inTypeDef, "\t");
1924 } // void MDInfo::DisplayTypeDefInfo()
1926 // print out information about every the given typeDef's interfaceImpls
1929 void MDInfo::DisplayInterfaceImpls(mdTypeDef inTypeDef)
1931 HCORENUM interfaceImplEnum = NULL;
1932 mdTypeRef interfaceImpls[ENUM_BUFFER_SIZE];
1933 ULONG count, totalCount = 1;
1936 while(SUCCEEDED(hr = m_pImport->EnumInterfaceImpls( &interfaceImplEnum,
1937 inTypeDef,interfaceImpls,NumItems(interfaceImpls), &count)) &&
1940 for (ULONG i = 0; i < count; i++, totalCount++)
1942 VWriteLine("\tInterfaceImpl #%d (%08x)", totalCount, interfaceImpls[i]);
1943 WriteLine("\t-------------------------------------------------------");
1944 DisplayInterfaceImplInfo(interfaceImpls[i]);
1945 DisplayPermissions(interfaceImpls[i], "\t");
1949 m_pImport->CloseEnum( interfaceImplEnum);
1950 } // void MDInfo::DisplayInterfaceImpls()
1952 // print the information for the given interface implementation
1955 void MDInfo::DisplayInterfaceImplInfo(mdInterfaceImpl inImpl)
1961 WCHAR szTempBuf[STRING_BUFFER_LEN];
1963 hr = m_pImport->GetInterfaceImplProps( inImpl, &typeDef, &token);
1964 if (FAILED(hr)) Error("GetInterfaceImplProps failed.", hr);
1966 VWriteLine("\t\tClass : %ls",TypeDeforRefName(typeDef, szTempBuf, NumItems(szTempBuf)));
1967 VWriteLine("\t\tToken : %8.8X [%s] %ls",token,TokenTypeName(token), TypeDeforRefName(token, szTempBuf, NumItems(szTempBuf)));
1969 DisplayCustomAttributes(inImpl, "\t\t");
1970 } // void MDInfo::DisplayInterfaceImplInfo()
1972 // displays the information for a particular property
1975 void MDInfo::DisplayPropertyInfo(mdProperty inProp)
1979 WCHAR propName[STRING_BUFFER_LEN];
1981 #ifdef FEATURE_COMINTEROP
1982 VARIANT defaultValue;
1986 DWORD dwCPlusTypeFlag;
1987 mdMethodDef setter, getter, otherMethod[ENUM_BUFFER_SIZE];
1989 PCCOR_SIGNATURE pbSigBlob;
1993 #ifdef FEATURE_COMINTEROP
1994 ::VariantInit(&defaultValue);
1996 hr = m_pImport->GetPropertyProps(
1997 inProp, // [IN] property token
1998 &typeDef, // [OUT] typedef containing the property declarion.
2000 propName, // [OUT] Property name
2001 STRING_BUFFER_LEN, // [IN] the count of wchar of szProperty
2002 NULL, // [OUT] actual count of wchar for property name
2004 &flags, // [OUT] property flags.
2006 &pbSigBlob, // [OUT] Signature Blob.
2007 &ulSigBlob, // [OUT] Number of bytes in the signature blob.
2009 &dwCPlusTypeFlag, // [OUT] default value
2013 &setter, // [OUT] setter method of the property
2014 &getter, // [OUT] getter method of the property
2016 otherMethod, // [OUT] other methods of the property
2017 ENUM_BUFFER_SIZE, // [IN] size of rmdOtherMethod
2018 &others); // [OUT] total number of other method of this property
2020 if (FAILED(hr)) Error("GetPropertyProps failed.", hr);
2022 VWriteLine("\t\tProp.Name : %ls (%8.8X)",propName,inProp);
2024 char sFlags[STRING_BUFFER_LEN];
2027 ISFLAG(Pr, SpecialName);
2028 ISFLAG(Pr, RTSpecialName);
2029 ISFLAG(Pr, HasDefault);
2031 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
2033 VWriteLine("\t\tFlags : %s (%08x)", sFlags, flags);
2036 DisplaySignature(pbSigBlob, ulSigBlob, "");
2038 VWriteLine("\t\tERROR: no valid signature ");
2040 WCHAR szTempBuf[STRING_BUFFER_LEN];
2042 #ifdef FEATURE_COMINTEROP
2043 _FillVariant((BYTE)dwCPlusTypeFlag, pValue, cbValue, &defaultValue);
2044 VWriteLine("\t\tDefltValue: %ls",VariantAsString(&defaultValue));
2047 VWriteLine("\t\tSetter : (%08x) %ls",setter,MemberDeforRefName(setter, szTempBuf, NumItems(szTempBuf)));
2048 VWriteLine("\t\tGetter : (%08x) %ls",getter,MemberDeforRefName(getter, szTempBuf, NumItems(szTempBuf)));
2050 // do something with others?
2051 VWriteLine("\t\t%ld Others",others);
2052 DisplayCustomAttributes(inProp, "\t\t");
2054 #ifdef FEATURE_COMINTEROP
2055 ::VariantClear(&defaultValue);
2057 } // void MDInfo::DisplayPropertyInfo()
2059 // displays info for each property
2062 void MDInfo::DisplayProperties(mdTypeDef inTypeDef)
2064 HCORENUM propEnum = NULL;
2065 mdProperty props[ENUM_BUFFER_SIZE];
2066 ULONG count, totalCount = 1;
2070 while(SUCCEEDED(hr = m_pImport->EnumProperties( &propEnum,
2071 inTypeDef,props,NumItems(props), &count)) &&
2074 for (ULONG i = 0; i < count; i++, totalCount++)
2076 VWriteLine("\tProperty #%d (%08x)", totalCount, props[i]);
2077 WriteLine("\t-------------------------------------------------------");
2078 DisplayPropertyInfo(props[i]);
2079 DisplayPermissions(props[i], "\t");
2083 m_pImport->CloseEnum( propEnum);
2084 } // void MDInfo::DisplayProperties()
2086 // Display all information about a particular event
2089 void MDInfo::DisplayEventInfo(mdEvent inEvent)
2093 WCHAR eventName[STRING_BUFFER_LEN];
2096 mdMethodDef addOn, removeOn, fire, otherMethod[ENUM_BUFFER_SIZE];
2100 hr = m_pImport->GetEventProps(
2102 inEvent, // [IN] event token
2103 &typeDef, // [OUT] typedef containing the event declarion.
2105 eventName, // [OUT] Event name
2106 STRING_BUFFER_LEN, // [IN] the count of wchar of szEvent
2107 NULL, // [OUT] actual count of wchar for event's name
2109 &flags, // [OUT] Event flags.
2110 &eventType, // [OUT] EventType class
2112 &addOn, // [OUT] AddOn method of the event
2113 &removeOn, // [OUT] RemoveOn method of the event
2114 &fire, // [OUT] Fire method of the event
2116 otherMethod, // [OUT] other method of the event
2117 NumItems(otherMethod), // [IN] size of rmdOtherMethod
2118 &totalOther); // [OUT] total number of other method of this event
2119 if (FAILED(hr)) Error("GetEventProps failed.", hr);
2121 VWriteLine("\t\tName : %ls (%8.8X)",eventName,inEvent);
2123 char sFlags[STRING_BUFFER_LEN];
2126 ISFLAG(Ev, SpecialName);
2127 ISFLAG(Ev, RTSpecialName);
2129 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
2131 VWriteLine("\t\tFlags : %s (%08x)", sFlags, flags);
2133 WCHAR szTempBuf[STRING_BUFFER_LEN];
2135 VWriteLine("\t\tEventType : %8.8X [%s]",eventType,TokenTypeName(eventType));
2136 VWriteLine("\t\tAddOnMethd: (%08x) %ls",addOn,MemberDeforRefName(addOn, szTempBuf, NumItems(szTempBuf)));
2137 VWriteLine("\t\tRmvOnMethd: (%08x) %ls",removeOn,MemberDeforRefName(removeOn, szTempBuf, NumItems(szTempBuf)));
2138 VWriteLine("\t\tFireMethod: (%08x) %ls",fire,MemberDeforRefName(fire, szTempBuf, NumItems(szTempBuf)));
2140 VWriteLine("\t\t%ld OtherMethods",totalOther);
2142 DisplayCustomAttributes(inEvent, "\t\t");
2143 } // void MDInfo::DisplayEventInfo()
2145 // Display information about all events in a typedef
2147 void MDInfo::DisplayEvents(mdTypeDef inTypeDef)
2149 HCORENUM eventEnum = NULL;
2150 mdProperty events[ENUM_BUFFER_SIZE];
2151 ULONG count, totalCount = 1;
2155 while(SUCCEEDED(hr = m_pImport->EnumEvents( &eventEnum,
2156 inTypeDef,events,NumItems(events), &count)) &&
2159 for (ULONG i = 0; i < count; i++, totalCount++)
2161 VWriteLine("\tEvent #%d (%08x)", totalCount, events[i]);
2162 WriteLine("\t-------------------------------------------------------");
2163 DisplayEventInfo(events[i]);
2164 DisplayPermissions(events[i], "\t");
2168 m_pImport->CloseEnum( eventEnum);
2169 } // void MDInfo::DisplayEvents()
2172 // print info for the passed-in custom attribute
2173 // This function is used to print the custom attribute information for both TypeDefs and
2174 // MethodDefs which need slightly different formatting. preFix helps fix it up.
2177 void MDInfo::DisplayCustomAttributeInfo(mdCustomAttribute inValue, const char *preFix)
2179 const BYTE *pValue; // The custom value.
2180 ULONG cbValue; // Length of the custom value.
2181 HRESULT hr; // A result.
2182 mdToken tkObj; // Attributed object.
2183 mdToken tkType; // Type of the custom attribute.
2184 mdToken tk; // For name lookup.
2185 LPCUTF8 pMethName=0; // Name of custom attribute ctor, if any.
2186 CQuickBytes qSigName; // Buffer to pretty-print signature.
2187 PCCOR_SIGNATURE pSig=0; // Signature of ctor.
2188 ULONG cbSig; // Size of the signature.
2189 BOOL bCoffSymbol = false; // true for coff symbol CA's.
2190 WCHAR rcName[MAX_CLASS_NAME]; // Name of the type.
2192 hr = m_pImport->GetCustomAttributeProps( // S_OK or error.
2193 inValue, // The attribute.
2194 &tkObj, // The attributed object
2195 &tkType, // The attributes type.
2196 (const void**)&pValue, // Put pointer to data here.
2197 &cbValue); // Put size here.
2198 if (FAILED(hr)) Error("GetCustomAttributeProps failed.", hr);
2200 VWriteLine("%s\tCustomAttribute Type: %08x", preFix, tkType);
2202 // Get the name of the memberref or methoddef.
2205 // Get the member name, and the parent token.
2206 switch (TypeFromToken(tk))
2209 hr = m_pImport->GetNameFromToken(tk, &pMethName);
2210 if (FAILED(hr)) Error("GetNameFromToken failed.", hr);
2211 hr = m_pImport->GetMemberRefProps( tk, &tk, 0, 0, 0, &pSig, &cbSig);
2212 if (FAILED(hr)) Error("GetMemberRefProps failed.", hr);
2215 hr = m_pImport->GetNameFromToken(tk, &pMethName);
2216 if (FAILED(hr)) Error("GetNameFromToken failed.", hr);
2217 hr = m_pImport->GetMethodProps(tk, &tk, 0, 0, 0, 0, &pSig, &cbSig, 0, 0);
2218 if (FAILED(hr)) Error("GetMethodProps failed.", hr);
2222 // Get the type name.
2223 switch (TypeFromToken(tk))
2226 hr = m_pImport->GetTypeDefProps(tk, rcName,MAX_CLASS_NAME,0, 0,0);
2227 if (FAILED(hr)) Error("GetTypeDefProps failed.", hr);
2230 hr = m_pImport->GetTypeRefProps(tk, 0, rcName,MAX_CLASS_NAME,0);
2231 if (FAILED(hr)) Error("GetTypeRefProps failed.", hr);
2236 if (pSig && pMethName)
2239 LPWSTR pwzName = (LPWSTR)(new WCHAR[iLen= 1+(ULONG32)strlen(pMethName)]);
2242 WszMultiByteToWideChar(CP_UTF8,0, pMethName,-1, pwzName,iLen);
2243 PrettyPrintSigLegacy(pSig, cbSig, pwzName, &qSigName, m_pImport);
2248 VWrite("%s\tCustomAttributeName: %ls", preFix, rcName);
2249 if (pSig && pMethName)
2250 VWrite(" :: %S", qSigName.Ptr());
2252 // Keep track of coff overhead.
2253 if (!wcscmp(W("__DecoratedName"), rcName))
2256 g_cbCoffNames += cbValue + 6;
2260 VWriteLine("%s\tLength: %ld", preFix, cbValue);
2262 sprintf_s(newPreFix, 40, "%s\tValue ", preFix);
2263 DumpHex(newPreFix, pValue, cbValue);
2265 VWriteLine("%s\t %s", preFix, pValue);
2267 // Try to decode the constructor blob. This is incomplete, but covers the most popular cases.
2269 { // Interpret the signature.
2270 PCCOR_SIGNATURE ps = pSig;
2279 unsigned __int64 uI64;
2283 CustomAttributeParser CA(pValue, cbValue);
2284 CA.ValidateProlog();
2286 // Get the calling convention.
2287 cb = CorSigUncompressData(ps, &ulData);
2289 // Get the count of params.
2290 cb = CorSigUncompressData(ps, &cParams);
2292 // Get the return value.
2293 cb = CorSigUncompressData(ps, &ulData);
2295 if (ulData == ELEMENT_TYPE_VOID)
2297 VWrite("%s\tctor args: (", preFix);
2298 // For each param...
2299 for (ULONG i=0; i<cParams; ++i)
2300 { // Get the next param type.
2301 cb = CorSigUncompressData(ps, &ulData);
2307 // For ET_OBJECT, the next byte in the blob is the ET of the actual data.
2308 case ELEMENT_TYPE_OBJECT:
2312 case ELEMENT_TYPE_I1:
2313 case ELEMENT_TYPE_U1:
2317 case ELEMENT_TYPE_I2:
2318 case ELEMENT_TYPE_U2:
2322 case ELEMENT_TYPE_I4:
2323 case ELEMENT_TYPE_U4:
2327 VWrite("%d", ulVal);
2329 case ELEMENT_TYPE_STRING:
2330 CA.GetString(&pStr, &cbVal);
2331 VWrite("\"%s\"", pStr);
2333 // The only class type that we accept is Type, which is stored as a string.
2334 case ELEMENT_TYPE_CLASS:
2335 // Eat the class type.
2336 cb = CorSigUncompressData(ps, &ulData);
2338 // Get the name of the type.
2339 CA.GetString(&pStr, &cbVal);
2340 VWrite("typeof(%s)", pStr);
2342 case SERIALIZATION_TYPE_TYPE:
2343 CA.GetString(&pStr, &cbVal);
2344 VWrite("typeof(%s)", pStr);
2346 case ELEMENT_TYPE_I8:
2347 case ELEMENT_TYPE_U8:
2350 VWrite("%#lx", uI64);
2352 case ELEMENT_TYPE_R4:
2353 dblVal = CA.GetR4();
2354 VWrite("%f", dblVal);
2356 case ELEMENT_TYPE_R8:
2357 dblVal = CA.GetR8();
2358 VWrite("%f", dblVal);
2363 Write(" <can not decode> ");
2372 } // void MDInfo::DisplayCustomAttributeInfo()
2374 // Print all custom values for the given token
2375 // This function is used to print the custom value information for all tokens.
2376 // which need slightly different formatting. preFix helps fix it up.
2379 void MDInfo::DisplayCustomAttributes(mdToken inToken, const char *preFix)
2381 HCORENUM customAttributeEnum = NULL;
2382 mdTypeRef customAttributes[ENUM_BUFFER_SIZE];
2383 ULONG count, totalCount = 1;
2386 while(SUCCEEDED(hr = m_pImport->EnumCustomAttributes( &customAttributeEnum, inToken, 0,
2387 customAttributes, NumItems(customAttributes), &count)) &&
2390 for (ULONG i = 0; i < count; i++, totalCount++)
2392 VWriteLine("%sCustomAttribute #%d (%08x)", preFix, totalCount, customAttributes[i]);
2393 VWriteLine("%s-------------------------------------------------------", preFix);
2394 DisplayCustomAttributeInfo(customAttributes[i], preFix);
2397 m_pImport->CloseEnum( customAttributeEnum);
2398 } // void MDInfo::DisplayCustomAttributes()
2400 // Show the passed-in token's permissions
2404 void MDInfo::DisplayPermissions(mdToken tk, const char *preFix)
2406 HCORENUM permissionEnum = NULL;
2407 mdPermission permissions[ENUM_BUFFER_SIZE];
2408 ULONG count, totalCount = 1;
2412 while (SUCCEEDED(hr = m_pImport->EnumPermissionSets( &permissionEnum,
2413 tk, 0, permissions, NumItems(permissions), &count)) &&
2416 for (ULONG i = 0; i < count; i++, totalCount++)
2418 VWriteLine("%s\tPermission #%d (%08x)", preFix, totalCount, permissions[i]);
2419 VWriteLine("%s\t-------------------------------------------------------", preFix);
2420 DisplayPermissionInfo(permissions[i], preFix);
2424 m_pImport->CloseEnum( permissionEnum);
2425 } // void MDInfo::DisplayPermissions()
2427 // print properties of given rolecheck
2431 void MDInfo::DisplayPermissionInfo(mdPermission inPermission, const char *preFix)
2434 const BYTE *pvPermission;
2436 const char *flagDesc = NULL;
2437 char newPreFix[STRING_BUFFER_LEN];
2441 hr = m_pImport->GetPermissionSetProps( inPermission, &dwAction,
2442 (const void**)&pvPermission, &cbPermission);
2443 if (FAILED(hr)) Error("GetPermissionSetProps failed.", hr);
2447 case dclActionNil: flagDesc = "ActionNil"; break;
2448 case dclRequest: flagDesc = "Request"; break;
2449 case dclDemand: flagDesc = "Demand"; break;
2450 case dclAssert: flagDesc = "Assert"; break;
2451 case dclDeny: flagDesc = "Deny"; break;
2452 case dclPermitOnly: flagDesc = "PermitOnly"; break;
2453 case dclLinktimeCheck: flagDesc = "LinktimeCheck"; break;
2454 case dclInheritanceCheck: flagDesc = "InheritanceCheck"; break;
2455 case dclRequestMinimum: flagDesc = "RequestMinimum"; break;
2456 case dclRequestOptional: flagDesc = "RequestOptional"; break;
2457 case dclRequestRefuse: flagDesc = "RequestRefuse"; break;
2458 case dclPrejitGrant: flagDesc = "PrejitGrant"; break;
2459 case dclPrejitDenied: flagDesc = "PrejitDenied"; break;
2460 case dclNonCasDemand: flagDesc = "NonCasDemand"; break;
2461 case dclNonCasLinkDemand: flagDesc = "NonCasLinkDemand"; break;
2462 case dclNonCasInheritance: flagDesc = "NonCasInheritance"; break;
2465 VWriteLine("%s\t\tAction : %s", preFix, flagDesc);
2466 VWriteLine("%s\t\tBlobLen : %d", preFix, cbPermission);
2469 sprintf_s(newPreFix, STRING_BUFFER_LEN, "%s\tBlob", preFix);
2470 DumpHex(newPreFix, pvPermission, cbPermission, false, 24);
2473 sprintf_s (newPreFix, STRING_BUFFER_LEN, "\t\t%s", preFix);
2474 DisplayCustomAttributes(inPermission, newPreFix);
2475 } // void MDInfo::DisplayPermissionInfo()
2478 // simply prints out the given GUID in standard form
2480 LPWSTR MDInfo::GUIDAsString(GUID inGuid, __out_ecount(bufLen) LPWSTR guidString, ULONG bufLen)
2482 StringFromGUID2(inGuid, guidString, bufLen);
2484 } // LPWSTR MDInfo::GUIDAsString()
2486 #ifdef FEATURE_COMINTEROP
2487 LPCWSTR MDInfo::VariantAsString(VARIANT *pVariant)
2490 if (V_VT(pVariant) == VT_UNKNOWN)
2492 _ASSERTE(V_UNKNOWN(pVariant) == NULL);
2495 else if (SUCCEEDED(hr = ::VariantChangeType(pVariant, pVariant, 0, VT_BSTR)))
2496 return V_BSTR(pVariant);
2497 else if (hr == DISP_E_BADVARTYPE && V_VT(pVariant) == VT_I8)
2499 // allocate the bstr.
2502 // Set variant type to bstr.
2503 V_VT(pVariant) = VT_BSTR;
2504 // Create the ansi string.
2505 sprintf_s(szStr, 32, "%I64d", V_CY(pVariant).int64);
2506 // Convert to unicode.
2507 WszMultiByteToWideChar(CP_ACP, 0, szStr, -1, wszStr, 32);
2508 // convert to bstr and set variant value.
2509 V_BSTR(pVariant) = ::SysAllocString(wszStr);
2510 if (V_BSTR(pVariant) == NULL)
2511 Error("SysAllocString() failed.", E_OUTOFMEMORY);
2512 return V_BSTR(pVariant);
2517 } // LPWSTR MDInfo::VariantAsString()
2520 bool TrySigUncompress(PCCOR_SIGNATURE pData, // [IN] compressed data
2521 ULONG *pDataOut, // [OUT] the expanded *pData
2524 ULONG ulSize = CorSigUncompressData(pData, pDataOut);
2525 if (ulSize == (ULONG)-1)
2536 void MDInfo::DisplayFieldMarshal(mdToken inToken)
2538 PCCOR_SIGNATURE pvNativeType; // [OUT] native type of this field
2539 ULONG cbNativeType; // [OUT] the count of bytes of *ppvNativeType
2543 hr = m_pImport->GetFieldMarshal( inToken, &pvNativeType, &cbNativeType);
2544 if (FAILED(hr) && hr != CLDB_E_RECORD_NOTFOUND) Error("GetFieldMarshal failed.", hr);
2545 if (hr != CLDB_E_RECORD_NOTFOUND)
2551 char szNTDesc[STRING_BUFFER_LEN];
2553 while (cbCur < cbNativeType)
2557 ulData = NATIVE_TYPE_MAX;
2558 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2560 if (ulData >= sizeof(g_szNativeType)/sizeof(*g_szNativeType))
2565 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "%s ", g_szNativeType[ulData]);
2568 case NATIVE_TYPE_FIXEDSYSSTRING:
2570 if (cbCur < cbNativeType)
2572 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2574 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{StringElementCount: %d} ",ulData);
2578 case NATIVE_TYPE_FIXEDARRAY:
2580 if (cbCur < cbNativeType)
2582 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2584 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{ArrayElementCount: %d",ulData);
2586 if (cbCur < cbNativeType)
2588 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2590 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, ", ArrayElementType(NT): %d",ulData);
2593 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc,"}");
2597 case NATIVE_TYPE_ARRAY:
2599 if (cbCur < cbNativeType)
2601 BOOL bElemTypeSpecified;
2603 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2605 if (ulData != NATIVE_TYPE_MAX)
2607 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{ArrayElementType(NT): %d", ulData);
2608 bElemTypeSpecified = TRUE;
2612 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{");
2613 bElemTypeSpecified = FALSE;
2616 if (cbCur < cbNativeType)
2618 if (bElemTypeSpecified)
2619 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, ", ");
2621 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2623 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "SizeParamIndex: %d",ulData);
2625 if (cbCur < cbNativeType)
2627 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2629 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, ", SizeParamMultiplier: %d",ulData);
2631 if (cbCur < cbNativeType)
2633 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2635 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, ", SizeConst: %d",ulData);
2640 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "}");
2644 case NATIVE_TYPE_SAFEARRAY:
2646 if (cbCur < cbNativeType)
2648 if (!TrySigUncompress(&pvNativeType[cbCur], &ulData, &cbCur))
2650 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{SafeArraySubType(VT): %d, ",ulData);
2652 // Extract the element type name if it is specified.
2653 if (cbCur < cbNativeType)
2655 LPUTF8 strTemp = NULL;
2657 int ByteCountLength = 0;
2659 strLen = CPackedLen::GetLength(&pvNativeType[cbCur], &ByteCountLength);
2660 cbCur += ByteCountLength;
2661 strTemp = (LPUTF8)(new char[strLen + 1]);
2664 memcpy(strTemp, (LPUTF8)&pvNativeType[cbCur], strLen);
2665 strTemp[strLen] = 0;
2666 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "ElementTypeName: %s}", strTemp);
2668 _ASSERTE(cbCur == cbNativeType);
2674 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "ElementTypeName: }");
2679 case NATIVE_TYPE_CUSTOMMARSHALER:
2681 LPUTF8 strTemp = NULL;
2683 int ByteCountLength = 0;
2685 // Extract the typelib GUID.
2686 strLen = CPackedLen::GetLength(&pvNativeType[cbCur], &ByteCountLength);
2687 cbCur += ByteCountLength;
2688 strTemp = (LPUTF8)(new char[strLen + 1]);
2691 memcpy(strTemp, (LPUTF8)&pvNativeType[cbCur], strLen);
2692 strTemp[strLen] = 0;
2693 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "{Typelib: %s, ", strTemp);
2695 _ASSERTE(cbCur < cbNativeType);
2698 // Extract the name of the native type.
2699 strLen = CPackedLen::GetLength(&pvNativeType[cbCur], &ByteCountLength);
2700 cbCur += ByteCountLength;
2701 strTemp = (LPUTF8)(new char[strLen + 1]);
2704 memcpy(strTemp, (LPUTF8)&pvNativeType[cbCur], strLen);
2705 strTemp[strLen] = 0;
2706 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "Native: %s, ", strTemp);
2708 _ASSERTE(cbCur < cbNativeType);
2712 // Extract the name of the custom marshaler.
2713 strLen = CPackedLen::GetLength(&pvNativeType[cbCur], &ByteCountLength);
2714 cbCur += ByteCountLength;
2715 strTemp = (LPUTF8)(new char[strLen + 1]);
2718 memcpy(strTemp, (LPUTF8)&pvNativeType[cbCur], strLen);
2719 strTemp[strLen] = 0;
2720 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "Marshaler: %s, ", strTemp);
2722 _ASSERTE(cbCur < cbNativeType);
2725 // Extract the cookie string.
2726 strLen = CPackedLen::GetLength(&pvNativeType[cbCur], &ByteCountLength);
2727 cbCur += ByteCountLength;
2730 strTemp = (LPUTF8)(new char[strLen + 1]);
2733 memcpy(strTemp, (LPUTF8)&pvNativeType[cbCur], strLen);
2734 strTemp[strLen] = 0;
2735 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "Cookie: ");
2737 // Copy the cookie string and transform the embedded nulls into \0's.
2738 for (int i = 0; i < strLen - 1; i++, cbCur++)
2740 if (strTemp[i] == 0)
2741 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "\\0");
2743 szNTDesc[ulStrLoc++] = strTemp[i];
2745 szNTDesc[ulStrLoc++] = strTemp[strLen - 1];
2752 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "Cookie: ");
2755 // Finish the custom marshaler native type description.
2756 ulStrLoc += sprintf_s(szNTDesc + ulStrLoc, STRING_BUFFER_LEN-ulStrLoc, "}");
2757 _ASSERTE(cbCur <= cbNativeType);
2762 // normal nativetype element: do nothing
2765 VWriteLine("\t\t\t\t%s",szNTDesc);
2766 if (ulData >= NATIVE_TYPE_MAX)
2769 if (cbCur == (ULONG)-1)
2771 // There was something that we didn't grok in the signature.
2772 // Just dump out the blob as hex
2773 VWrite("\t\t\t\t{", szNTDesc);
2774 while (cbNativeType--)
2775 VWrite(" %2.2X", *pvNativeType++);
2779 } // void MDInfo::DisplayFieldMarshal()
2781 void MDInfo::DisplayPinvokeInfo(mdToken inToken)
2783 HRESULT hr = NOERROR;
2785 WCHAR rcImport[512];
2786 mdModuleRef tkModuleRef;
2788 char sFlags[STRING_BUFFER_LEN];
2790 hr = m_pImport->GetPinvokeMap(inToken, &flags, rcImport,
2791 NumItems(rcImport), 0, &tkModuleRef);
2794 if (hr != CLDB_E_RECORD_NOTFOUND)
2795 VWriteLine("ERROR: GetPinvokeMap failed.", hr);
2799 WriteLine("\t\tPinvoke Map Data:");
2800 VWriteLine("\t\tEntry point: %S", rcImport);
2801 VWriteLine("\t\tModule ref: %08x", tkModuleRef);
2804 ISFLAG(Pm, NoMangle);
2805 ISFLAG(Pm, CharSetNotSpec);
2806 ISFLAG(Pm, CharSetAnsi);
2807 ISFLAG(Pm, CharSetUnicode);
2808 ISFLAG(Pm, CharSetAuto);
2809 ISFLAG(Pm, SupportsLastError);
2810 ISFLAG(Pm, CallConvWinapi);
2811 ISFLAG(Pm, CallConvCdecl);
2812 ISFLAG(Pm, CallConvStdcall);
2813 ISFLAG(Pm, CallConvThiscall);
2814 ISFLAG(Pm, CallConvFastcall);
2816 ISFLAG(Pm, BestFitEnabled);
2817 ISFLAG(Pm, BestFitDisabled);
2818 ISFLAG(Pm, BestFitUseAssem);
2819 ISFLAG(Pm, ThrowOnUnmappableCharEnabled);
2820 ISFLAG(Pm, ThrowOnUnmappableCharDisabled);
2821 ISFLAG(Pm, ThrowOnUnmappableCharUseAssem);
2823 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
2825 VWriteLine("\t\tMapping flags: %s (%08x)", sFlags, flags);
2826 } // void MDInfo::DisplayPinvokeInfo()
2829 /////////////////////////////////////////////////////////////////////////
2830 // void DisplaySignature(PCCOR_SIGNATURE pbSigBlob, ULONG ulSigBlob);
2832 // Display COM+ signature -- taken from cordump.cpp's DumpSignature
2833 /////////////////////////////////////////////////////////////////////////
2834 void MDInfo::DisplaySignature(PCCOR_SIGNATURE pbSigBlob, ULONG ulSigBlob, const char *preFix)
2838 // 428793: Prefix complained correctly about unitialized data.
2839 ULONG ulData = (ULONG) IMAGE_CEE_CS_CALLCONV_MAX;
2841 HRESULT hr = NOERROR;
2842 ULONG ulSigBlobStart = ulSigBlob;
2844 // initialize sigBuf
2847 cb = CorSigUncompressData(pbSigBlob, &ulData);
2848 VWriteLine("%s\t\tCallCnvntn: %s", preFix, (g_strCalling[ulData & IMAGE_CEE_CS_CALLCONV_MASK]));
2854 if (ulData & IMAGE_CEE_CS_CALLCONV_HASTHIS)
2855 VWriteLine("%s\t\thasThis ", preFix);
2856 if (ulData & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS)
2857 VWriteLine("%s\t\texplicit ", preFix);
2858 if (ulData & IMAGE_CEE_CS_CALLCONV_GENERIC)
2859 VWriteLine("%s\t\tgeneric ", preFix);
2861 // initialize sigBuf
2863 if ( isCallConv(ulData,IMAGE_CEE_CS_CALLCONV_FIELD) )
2866 // display field type
2867 if (FAILED(hr = GetOneElementType(&pbSigBlob[cbCur], ulSigBlob, &cb)))
2869 VWriteLine("%s\t\tField type: %s", preFix, (LPSTR)m_sigBuf.Ptr());
2877 if (ulData & IMAGE_CEE_CS_CALLCONV_GENERIC)
2880 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulTyArgs);
2885 VWriteLine("%s\t\tType Arity:%d ", preFix, ulTyArgs);
2887 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulArgs);
2893 if (ulData != IMAGE_CEE_CS_CALLCONV_LOCAL_SIG && ulData != IMAGE_CEE_CS_CALLCONV_GENERICINST)
2895 // display return type when it is not a local varsig
2896 if (FAILED(hr = GetOneElementType(&pbSigBlob[cbCur], ulSigBlob, &cb)))
2898 VWriteLine("%s\t\tReturnType:%s", preFix, (LPSTR)m_sigBuf.Ptr());
2905 // display count of argument
2906 // display arguments
2908 VWriteLine("%s\t\t%ld Arguments", preFix, ulArgs);
2910 VWriteLine("%s\t\tNo arguments.", preFix);
2913 while (i < ulArgs && ulSigBlob > 0)
2917 // Handle the sentinal for varargs because it isn't counted in the args.
2918 CorSigUncompressData(&pbSigBlob[cbCur], &ulDataTemp);
2921 // initialize sigBuf
2924 if (FAILED(hr = GetOneElementType(&pbSigBlob[cbCur], ulSigBlob, &cb)))
2927 VWriteLine("%s\t\t\tArgument #%ld: %s",preFix, i, (LPSTR)m_sigBuf.Ptr());
2937 // Nothing consumed but not yet counted.
2941 // We should have consumed all signature blob. If not, dump the sig in hex.
2942 // Also dump in hex if so requested.
2943 if (m_DumpFilter & dumpMoreHex || ulSigBlob != 0)
2945 // Did we not consume enough, or try to consume too much?
2947 WriteLine("\tERROR IN SIGNATURE: Signature should be larger.");
2951 VWrite("\tERROR IN SIGNATURE: Not all of signature blob was consumed. %d byte(s) remain", ulSigBlob);
2952 // If it is short, just append it to the end.
2956 for (; ulSigBlob; ++cbCur, --ulSigBlob)
2957 VWrite("%02x ", pbSigBlob[cbCur]);
2964 // Any appropriate error message has been issued. Dump sig in hex, as determined
2965 // by error or command line switch.
2967 ulSigBlob = ulSigBlobStart;
2968 char rcNewPrefix[80];
2969 sprintf_s(rcNewPrefix, 80, "%s\t\tSignature ", preFix);
2970 DumpHex(rcNewPrefix, pbSigBlob, ulSigBlob, false, 24);
2974 Error("ERROR!! Bad signature blob value!");
2976 } // void MDInfo::DisplaySignature()
2979 /////////////////////////////////////////////////////////////////////////
2980 // HRESULT GetOneElementType(mdScope tkScope, BYTE *pbSigBlob, ULONG ulSigBlob, ULONG *pcb)
2982 // Adds description of element type to the end of buffer -- caller must ensure
2983 // buffer is large enough.
2984 /////////////////////////////////////////////////////////////////////////
2985 HRESULT MDInfo::GetOneElementType(PCCOR_SIGNATURE pbSigBlob, ULONG ulSigBlob, ULONG *pcb)
2987 HRESULT hr = S_OK; // A result.
2990 ULONG ulData = ELEMENT_TYPE_MAX;
2995 cb = CorSigUncompressData(pbSigBlob, &ulData);
2998 // Handle the modifiers.
2999 if (ulData & ELEMENT_TYPE_MODIFIER)
3001 if (ulData == ELEMENT_TYPE_SENTINEL)
3002 IfFailGo(AddToSigBuffer("<ELEMENT_TYPE_SENTINEL>"));
3003 else if (ulData == ELEMENT_TYPE_PINNED)
3004 IfFailGo(AddToSigBuffer("PINNED"));
3010 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3016 // Handle the underlying element types.
3017 if (ulData >= ELEMENT_TYPE_MAX)
3022 while (ulData == ELEMENT_TYPE_PTR || ulData == ELEMENT_TYPE_BYREF)
3024 IfFailGo(AddToSigBuffer(" "));
3025 IfFailGo(AddToSigBuffer(g_szMapElementType[ulData]));
3026 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulData);
3029 IfFailGo(AddToSigBuffer(" "));
3030 IfFailGo(AddToSigBuffer(g_szMapElementType[ulData]));
3031 if (CorIsPrimitiveType((CorElementType)ulData) ||
3032 ulData == ELEMENT_TYPE_TYPEDBYREF ||
3033 ulData == ELEMENT_TYPE_OBJECT ||
3034 ulData == ELEMENT_TYPE_I ||
3035 ulData == ELEMENT_TYPE_U)
3037 // If this is a primitive type, we are done
3040 if (ulData == ELEMENT_TYPE_VALUETYPE ||
3041 ulData == ELEMENT_TYPE_CLASS ||
3042 ulData == ELEMENT_TYPE_CMOD_REQD ||
3043 ulData == ELEMENT_TYPE_CMOD_OPT)
3045 cb = CorSigUncompressToken(&pbSigBlob[cbCur], &tk);
3048 // get the name of type ref. Don't care if truncated
3049 if (TypeFromToken(tk) == mdtTypeDef || TypeFromToken(tk) == mdtTypeRef)
3051 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %ls",TypeDeforRefName(tk, m_szTempBuf, NumItems(m_szTempBuf)));
3052 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3056 _ASSERTE(TypeFromToken(tk) == mdtTypeSpec);
3057 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %8x", tk);
3058 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3060 if (ulData == ELEMENT_TYPE_CMOD_REQD ||
3061 ulData == ELEMENT_TYPE_CMOD_OPT)
3063 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3070 if (ulData == ELEMENT_TYPE_SZARRAY)
3072 // display the base type of SZARRAY
3073 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3078 // instantiated type
3079 if (ulData == ELEMENT_TYPE_GENERICINST)
3081 // display the type constructor
3082 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3086 cb = CorSigUncompressData(&pbSigBlob[cbCur], &numArgs);
3088 IfFailGo(AddToSigBuffer("<"));
3092 if (cbCur > ulSigBlob)
3094 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3099 IfFailGo(AddToSigBuffer(","));
3101 IfFailGo(AddToSigBuffer(">"));
3104 if (ulData == ELEMENT_TYPE_VAR)
3107 cb = CorSigUncompressData(&pbSigBlob[cbCur], &index);
3109 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, "!%d", index);
3110 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3113 if (ulData == ELEMENT_TYPE_MVAR)
3116 cb = CorSigUncompressData(&pbSigBlob[cbCur], &index);
3118 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, "!!%d", index);
3119 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3122 if (ulData == ELEMENT_TYPE_FNPTR)
3124 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulData);
3126 if (ulData & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS)
3127 IfFailGo(AddToSigBuffer(" explicit"));
3128 if (ulData & IMAGE_CEE_CS_CALLCONV_HASTHIS)
3129 IfFailGo(AddToSigBuffer(" hasThis"));
3131 IfFailGo(AddToSigBuffer(" "));
3132 IfFailGo(AddToSigBuffer(g_strCalling[ulData & IMAGE_CEE_CS_CALLCONV_MASK]));
3134 // Get number of args
3136 cb = CorSigUncompressData(&pbSigBlob[cbCur], &numArgs);
3140 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3144 IfFailGo(AddToSigBuffer("("));
3147 if (cbCur > ulSigBlob)
3149 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3154 IfFailGo(AddToSigBuffer(","));
3156 IfFailGo(AddToSigBuffer(" )"));
3160 if(ulData != ELEMENT_TYPE_ARRAY) return E_FAIL;
3162 // display the base type of SDARRAY
3163 if (FAILED(GetOneElementType(&pbSigBlob[cbCur], ulSigBlob-cbCur, &cb)))
3167 // display the rank of MDARRAY
3168 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulData);
3170 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %d", ulData);
3171 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3173 // we are done if no rank specified
3176 // how many dimensions have size specified?
3177 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulData);
3179 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %d", ulData);
3180 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3183 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulTemp);
3184 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %d", ulTemp);
3185 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3189 // how many dimensions have lower bounds specified?
3190 cb = CorSigUncompressData(&pbSigBlob[cbCur], &ulData);
3192 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %d", ulData);
3193 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3197 cb = CorSigUncompressSignedInt(&pbSigBlob[cbCur], &iTemp);
3198 sprintf_s(m_tempFormatBuffer, STRING_BUFFER_LEN, " %d", iTemp);
3199 IfFailGo(AddToSigBuffer(m_tempFormatBuffer));
3205 if (cbCur > ulSigBlob)
3209 } // HRESULT MDInfo::GetOneElementType()
3211 // Display the fields of the N/Direct custom value structure.
3213 void MDInfo::DisplayCorNativeLink(COR_NATIVE_LINK *pCorNLnk, const char *preFix)
3215 // Print the LinkType.
3216 const char *curField = "\tLink Type : ";
3217 switch(pCorNLnk->m_linkType)
3220 VWriteLine("%s%s%s(%02x)", preFix, curField, "nltNone", pCorNLnk->m_linkType);
3223 VWriteLine("%s%s%s(%02x)", preFix, curField, "nltAnsi", pCorNLnk->m_linkType);
3226 VWriteLine("%s%s%s(%02x)", preFix, curField, "nltUnicode", pCorNLnk->m_linkType);
3229 VWriteLine("%s%s%s(%02x)", preFix, curField, "nltAuto", pCorNLnk->m_linkType);
3232 _ASSERTE(!"Invalid Native Link Type!");
3235 // Print the link flags
3236 curField = "\tLink Flags : ";
3237 switch(pCorNLnk->m_flags)
3240 VWriteLine("%s%s%s(%02x)", preFix, curField, "nlfNone", pCorNLnk->m_flags);
3243 VWriteLine("%s%s%s(%02x)", preFix, curField, "nlfLastError", pCorNLnk->m_flags);
3246 _ASSERTE(!"Invalid Native Link Flags!");
3249 // Print the entry point.
3250 WCHAR memRefName[STRING_BUFFER_LEN];
3252 hr = m_pImport->GetMemberRefProps( pCorNLnk->m_entryPoint, NULL, memRefName,
3253 STRING_BUFFER_LEN, NULL, NULL, NULL);
3254 if (FAILED(hr)) Error("GetMemberRefProps failed.", hr);
3255 VWriteLine("%s\tEntry Point : %ls (0x%08x)", preFix, memRefName, pCorNLnk->m_entryPoint);
3256 } // void MDInfo::DisplayCorNativeLink()
3258 // Fills given varaint with value given in pValue and of type in bCPlusTypeFlag
3260 // Taken from MetaInternal.cpp
3262 HRESULT _FillVariant(
3263 BYTE bCPlusTypeFlag,
3268 HRESULT hr = NOERROR;
3269 switch (bCPlusTypeFlag)
3271 case ELEMENT_TYPE_BOOLEAN:
3272 V_VT(pvar) = VT_BOOL;
3273 V_BOOL(pvar) = *((BYTE*)pValue); //*((UNALIGNED VARIANT_BOOL *)pValue);
3275 case ELEMENT_TYPE_I1:
3277 V_I1(pvar) = *((CHAR*)pValue);
3279 case ELEMENT_TYPE_U1:
3280 V_VT(pvar) = VT_UI1;
3281 V_UI1(pvar) = *((BYTE*)pValue);
3283 case ELEMENT_TYPE_I2:
3285 V_I2(pvar) = GET_UNALIGNED_VAL16(pValue);
3287 case ELEMENT_TYPE_U2:
3288 case ELEMENT_TYPE_CHAR:
3289 V_VT(pvar) = VT_UI2;
3290 V_UI2(pvar) = GET_UNALIGNED_VAL16(pValue);
3292 case ELEMENT_TYPE_I4:
3294 V_I4(pvar) = GET_UNALIGNED_VAL32(pValue);
3296 case ELEMENT_TYPE_U4:
3297 V_VT(pvar) = VT_UI4;
3298 V_UI4(pvar) = GET_UNALIGNED_VAL32(pValue);
3300 case ELEMENT_TYPE_R4:
3303 __int32 Value = GET_UNALIGNED_VAL32(pValue);
3304 V_R4(pvar) = (float &)Value;
3307 case ELEMENT_TYPE_R8:
3310 __int64 Value = GET_UNALIGNED_VAL64(pValue);
3311 V_R8(pvar) = (double &) Value;
3315 case ELEMENT_TYPE_STRING:
3317 V_VT(pvar) = VT_BSTR;
3320 TempString = (WCHAR *)alloca(cbValue);
3321 memcpy(TempString, pValue, cbValue);
3322 SwapStringLength(TempString, cbValue/sizeof(WCHAR));
3324 TempString = (WCHAR *)pValue;
3326 // allocated bstr here
3327 V_BSTR(pvar) = ::SysAllocStringLen((LPWSTR)TempString, cbValue/sizeof(WCHAR));
3328 if (V_BSTR(pvar) == NULL)
3332 case ELEMENT_TYPE_CLASS:
3333 V_VT(pvar) = VT_UNKNOWN;
3334 V_UNKNOWN(pvar) = NULL;
3335 // _ASSERTE( GET_UNALIGNED_VAL32(pValue) == 0);
3337 case ELEMENT_TYPE_I8:
3339 V_CY(pvar).int64 = GET_UNALIGNED_VAL64(pValue);
3341 case ELEMENT_TYPE_U8:
3342 V_VT(pvar) = VT_UI8;
3343 V_CY(pvar).int64 = GET_UNALIGNED_VAL64(pValue);
3345 case ELEMENT_TYPE_VOID:
3346 V_VT(pvar) = VT_EMPTY;
3349 _ASSERTE(!"bad constant value type!");
3353 } // HRESULT _FillVariant()
3355 void MDInfo::DisplayAssembly()
3357 if (m_pAssemblyImport)
3359 DisplayAssemblyInfo();
3360 DisplayAssemblyRefs();
3362 DisplayExportedTypes();
3363 DisplayManifestResources();
3365 } // void MDInfo::DisplayAssembly()
3367 void MDInfo::DisplayAssemblyInfo()
3371 const BYTE *pbPublicKey;
3374 WCHAR szName[STRING_BUFFER_LEN];
3375 ASSEMBLYMETADATA MetaData;
3378 hr = m_pAssemblyImport->GetAssemblyFromScope(&mda);
3379 if (hr == CLDB_E_RECORD_NOTFOUND)
3381 else if (FAILED(hr)) Error("GetAssemblyFromScope() failed.", hr);
3383 // Get the required sizes for the arrays of locales, processors etc.
3384 ZeroMemory(&MetaData, sizeof(ASSEMBLYMETADATA));
3385 hr = m_pAssemblyImport->GetAssemblyProps(mda,
3386 NULL, NULL, // Public Key.
3387 NULL, // Hash Algorithm.
3388 NULL, 0, NULL, // Name.
3391 if (FAILED(hr)) Error("GetAssemblyProps() failed.", hr);
3393 // Allocate space for the arrays in the ASSEMBLYMETADATA structure.
3394 if (MetaData.cbLocale)
3395 MetaData.szLocale = new WCHAR[MetaData.cbLocale];
3396 if (MetaData.ulProcessor)
3397 MetaData.rProcessor = new DWORD[MetaData.ulProcessor];
3399 MetaData.rOS = new OSINFO[MetaData.ulOS];
3401 hr = m_pAssemblyImport->GetAssemblyProps(mda,
3402 (const void **)&pbPublicKey, &cbPublicKey,
3404 szName, STRING_BUFFER_LEN, NULL,
3407 if (FAILED(hr)) Error("GetAssemblyProps() failed.", hr);
3408 WriteLine("Assembly");
3409 WriteLine("-------------------------------------------------------");
3410 VWriteLine("\tToken: 0x%08x", mda);
3411 VWriteLine("\tName : %ls", szName);
3412 DumpHex("\tPublic Key ", pbPublicKey, cbPublicKey, false, 24);
3413 VWriteLine("\tHash Algorithm : 0x%08x", ulHashAlgId);
3414 DisplayASSEMBLYMETADATA(&MetaData);
3415 if(MetaData.szLocale) delete [] MetaData.szLocale;
3416 if(MetaData.rProcessor) delete [] MetaData.rProcessor;
3417 if(MetaData.rOS) delete [] MetaData.rOS;
3419 char sFlags[STRING_BUFFER_LEN];
3420 DWORD flags = dwFlags;
3423 ISFLAG(Af, PublicKey);
3424 ISFLAG(Af, Retargetable);
3425 ISFLAG(AfContentType_, WindowsRuntime);
3428 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
3430 VWriteLine("\tFlags : %s (%08x)", sFlags, dwFlags);
3431 DisplayCustomAttributes(mda, "\t");
3432 DisplayPermissions(mda, "\t");
3434 } // void MDInfo::DisplayAssemblyInfo()
3436 void MDInfo::DisplayAssemblyRefs()
3438 HCORENUM assemblyRefEnum = NULL;
3439 mdAssemblyRef AssemblyRefs[ENUM_BUFFER_SIZE];
3441 ULONG totalCount = 1;
3444 while (SUCCEEDED(hr = m_pAssemblyImport->EnumAssemblyRefs( &assemblyRefEnum,
3445 AssemblyRefs, NumItems(AssemblyRefs), &count)) &&
3448 for (ULONG i = 0; i < count; i++, totalCount++)
3450 VWriteLine("AssemblyRef #%d (%08x)", totalCount, AssemblyRefs[i]);
3451 WriteLine("-------------------------------------------------------");
3452 DisplayAssemblyRefInfo(AssemblyRefs[i]);
3456 m_pAssemblyImport->CloseEnum(assemblyRefEnum);
3457 } // void MDInfo::DisplayAssemblyRefs()
3459 void MDInfo::DisplayAssemblyRefInfo(mdAssemblyRef inAssemblyRef)
3462 const BYTE *pbPublicKeyOrToken;
3463 ULONG cbPublicKeyOrToken;
3464 WCHAR szName[STRING_BUFFER_LEN];
3465 ASSEMBLYMETADATA MetaData;
3466 const BYTE *pbHashValue;
3470 VWriteLine("\tToken: 0x%08x", inAssemblyRef);
3472 // Get sizes for the arrays in the ASSEMBLYMETADATA structure.
3473 ZeroMemory(&MetaData, sizeof(ASSEMBLYMETADATA));
3474 hr = m_pAssemblyImport->GetAssemblyRefProps(inAssemblyRef,
3475 NULL, NULL, // Public Key or Token.
3476 NULL, 0, NULL, // Name.
3478 NULL, NULL, // HashValue.
3480 if (FAILED(hr)) Error("GetAssemblyRefProps() failed.", hr);
3482 // Allocate space for the arrays in the ASSEMBLYMETADATA structure.
3483 if (MetaData.cbLocale)
3484 MetaData.szLocale = new WCHAR[MetaData.cbLocale];
3485 if (MetaData.ulProcessor)
3486 MetaData.rProcessor = new DWORD[MetaData.ulProcessor];
3488 MetaData.rOS = new OSINFO[MetaData.ulOS];
3490 hr = m_pAssemblyImport->GetAssemblyRefProps(inAssemblyRef,
3491 (const void **)&pbPublicKeyOrToken, &cbPublicKeyOrToken,
3492 szName, STRING_BUFFER_LEN, NULL,
3494 (const void **)&pbHashValue, &cbHashValue,
3496 if (FAILED(hr)) Error("GetAssemblyRefProps() failed.", hr);
3498 DumpHex("\tPublic Key or Token", pbPublicKeyOrToken, cbPublicKeyOrToken, false, 24);
3499 VWriteLine("\tName: %ls", szName);
3500 DisplayASSEMBLYMETADATA(&MetaData);
3501 if(MetaData.szLocale) delete [] MetaData.szLocale;
3502 if(MetaData.rProcessor) delete [] MetaData.rProcessor;
3503 if(MetaData.rOS) delete [] MetaData.rOS;
3504 DumpHex("\tHashValue Blob", pbHashValue, cbHashValue, false, 24);
3506 char sFlags[STRING_BUFFER_LEN];
3507 DWORD flags = dwFlags;
3510 ISFLAG(Af, PublicKey);
3511 ISFLAG(Af, Retargetable);
3512 ISFLAG(AfContentType_, WindowsRuntime);
3514 ISFLAG(Af, LegacyLibrary);
3515 ISFLAG(Af, LegacyPlatform);
3516 ISFLAG(Af, Library);
3517 ISFLAG(Af, Platform);
3520 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
3522 VWriteLine("\tFlags: %s (%08x)", sFlags, dwFlags);
3523 DisplayCustomAttributes(inAssemblyRef, "\t");
3525 } // void MDInfo::DisplayAssemblyRefInfo()
3527 void MDInfo::DisplayFiles()
3529 HCORENUM fileEnum = NULL;
3530 mdFile Files[ENUM_BUFFER_SIZE];
3532 ULONG totalCount = 1;
3535 while (SUCCEEDED(hr = m_pAssemblyImport->EnumFiles( &fileEnum,
3536 Files, NumItems(Files), &count)) &&
3539 for (ULONG i = 0; i < count; i++, totalCount++)
3541 VWriteLine("File #%d (%08x)", totalCount, Files[i]);
3542 WriteLine("-------------------------------------------------------");
3543 DisplayFileInfo(Files[i]);
3547 m_pAssemblyImport->CloseEnum(fileEnum);
3548 } // void MDInfo::DisplayFiles()
3550 void MDInfo::DisplayFileInfo(mdFile inFile)
3553 WCHAR szName[STRING_BUFFER_LEN];
3554 const BYTE *pbHashValue;
3558 VWriteLine("\tToken: 0x%08x", inFile);
3560 hr = m_pAssemblyImport->GetFileProps(inFile,
3561 szName, STRING_BUFFER_LEN, NULL,
3562 (const void **)&pbHashValue, &cbHashValue,
3564 if (FAILED(hr)) Error("GetFileProps() failed.", hr);
3565 VWriteLine("\tName : %ls", szName);
3566 DumpHex("\tHashValue Blob ", pbHashValue, cbHashValue, false, 24);
3568 char sFlags[STRING_BUFFER_LEN];
3569 DWORD flags = dwFlags;
3572 ISFLAG(Ff, ContainsMetaData);
3573 ISFLAG(Ff, ContainsNoMetaData);
3575 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
3577 VWriteLine("\tFlags : %s (%08x)", sFlags, dwFlags);
3578 DisplayCustomAttributes(inFile, "\t");
3581 } // MDInfo::DisplayFileInfo()
3583 void MDInfo::DisplayExportedTypes()
3585 HCORENUM comTypeEnum = NULL;
3586 mdExportedType ExportedTypes[ENUM_BUFFER_SIZE];
3588 ULONG totalCount = 1;
3591 while (SUCCEEDED(hr = m_pAssemblyImport->EnumExportedTypes( &comTypeEnum,
3592 ExportedTypes, NumItems(ExportedTypes), &count)) &&
3595 for (ULONG i = 0; i < count; i++, totalCount++)
3597 VWriteLine("ExportedType #%d (%08x)", totalCount, ExportedTypes[i]);
3598 WriteLine("-------------------------------------------------------");
3599 DisplayExportedTypeInfo(ExportedTypes[i]);
3603 m_pAssemblyImport->CloseEnum(comTypeEnum);
3604 } // void MDInfo::DisplayExportedTypes()
3606 void MDInfo::DisplayExportedTypeInfo(mdExportedType inExportedType)
3609 WCHAR szName[STRING_BUFFER_LEN];
3610 mdToken tkImplementation;
3611 mdTypeDef tkTypeDef;
3613 char sFlags[STRING_BUFFER_LEN];
3615 VWriteLine("\tToken: 0x%08x", inExportedType);
3617 hr = m_pAssemblyImport->GetExportedTypeProps(inExportedType,
3618 szName, STRING_BUFFER_LEN, NULL,
3622 if (FAILED(hr)) Error("GetExportedTypeProps() failed.", hr);
3623 VWriteLine("\tName: %ls", szName);
3624 VWriteLine("\tImplementation token: 0x%08x", tkImplementation);
3625 VWriteLine("\tTypeDef token: 0x%08x", tkTypeDef);
3626 VWriteLine("\tFlags : %s (%08x)",ClassFlags(dwFlags, sFlags), dwFlags);
3627 DisplayCustomAttributes(inExportedType, "\t");
3629 } // void MDInfo::DisplayExportedTypeInfo()
3631 void MDInfo::DisplayManifestResources()
3633 HCORENUM manifestResourceEnum = NULL;
3634 mdManifestResource ManifestResources[ENUM_BUFFER_SIZE];
3636 ULONG totalCount = 1;
3639 while (SUCCEEDED(hr = m_pAssemblyImport->EnumManifestResources( &manifestResourceEnum,
3640 ManifestResources, NumItems(ManifestResources), &count)) &&
3643 for (ULONG i = 0; i < count; i++, totalCount++)
3645 VWriteLine("ManifestResource #%d (%08x)", totalCount, ManifestResources[i]);
3646 WriteLine("-------------------------------------------------------");
3647 DisplayManifestResourceInfo(ManifestResources[i]);
3651 m_pAssemblyImport->CloseEnum(manifestResourceEnum);
3652 } // void MDInfo::DisplayManifestResources()
3654 void MDInfo::DisplayManifestResourceInfo(mdManifestResource inManifestResource)
3657 WCHAR szName[STRING_BUFFER_LEN];
3658 mdToken tkImplementation;
3662 VWriteLine("\tToken: 0x%08x", inManifestResource);
3664 hr = m_pAssemblyImport->GetManifestResourceProps(inManifestResource,
3665 szName, STRING_BUFFER_LEN, NULL,
3669 if (FAILED(hr)) Error("GetManifestResourceProps() failed.", hr);
3670 VWriteLine("Name: %ls", szName);
3671 VWriteLine("Implementation token: 0x%08x", tkImplementation);
3672 VWriteLine("Offset: 0x%08x", dwOffset);
3674 char sFlags[STRING_BUFFER_LEN];
3675 DWORD flags = dwFlags;
3679 ISFLAG(Mr, Private);
3681 strcpy_s(sFlags, STRING_BUFFER_LEN, "[none]");
3683 VWriteLine("\tFlags: %s (%08x)", sFlags, dwFlags);
3684 DisplayCustomAttributes(inManifestResource, "\t");
3686 } // void MDInfo::DisplayManifestResourceInfo()
3688 void MDInfo::DisplayASSEMBLYMETADATA(ASSEMBLYMETADATA *pMetaData)
3692 VWriteLine("\tVersion: %d.%d.%d.%d", pMetaData->usMajorVersion, pMetaData->usMinorVersion, pMetaData->usBuildNumber, pMetaData->usRevisionNumber);
3693 VWriteLine("\tMajor Version: 0x%08x", pMetaData->usMajorVersion);
3694 VWriteLine("\tMinor Version: 0x%08x", pMetaData->usMinorVersion);
3695 VWriteLine("\tBuild Number: 0x%08x", pMetaData->usBuildNumber);
3696 VWriteLine("\tRevision Number: 0x%08x", pMetaData->usRevisionNumber);
3697 VWriteLine("\tLocale: %ls", pMetaData->cbLocale ? pMetaData->szLocale : W("<null>"));
3698 for (i = 0; i < pMetaData->ulProcessor; i++)
3699 VWriteLine("\tProcessor #%ld: 0x%08x", i+1, pMetaData->rProcessor[i]);
3700 for (i = 0; i < pMetaData->ulOS; i++)
3702 VWriteLine("\tOS #%ld:", i+1);
3703 VWriteLine("\t\tOS Platform ID: 0x%08x", pMetaData->rOS[i].dwOSPlatformId);
3704 VWriteLine("\t\tOS Major Version: 0x%08x", pMetaData->rOS[i].dwOSMajorVersion);
3705 VWriteLine("\t\tOS Minor Version: 0x%08x", pMetaData->rOS[i].dwOSMinorVersion);
3707 } // void MDInfo::DisplayASSEMBLYMETADATA()
3709 void MDInfo::DisplayUserStrings()
3711 HCORENUM stringEnum = NULL; // string enumerator.
3712 mdString Strings[ENUM_BUFFER_SIZE]; // String tokens from enumerator.
3713 CQuickArray<WCHAR> rUserString; // Buffer to receive string.
3714 WCHAR *szUserString; // Working pointer into buffer.
3715 ULONG chUserString; // Size of user string.
3716 CQuickArray<char> rcBuf; // Buffer to hold the BLOB version of the string.
3717 char *szBuf; // Working pointer into buffer.
3718 ULONG chBuf; // Saved size of the user string.
3719 ULONG count; // Items returned from enumerator.
3720 ULONG totalCount = 1; // Running count of strings.
3721 bool bUnprint = false; // Is an unprintable character found?
3722 HRESULT hr; // A result.
3723 while (SUCCEEDED(hr = m_pImport->EnumUserStrings( &stringEnum,
3724 Strings, NumItems(Strings), &count)) &&
3727 if (totalCount == 1)
3728 { // If only one, it is the NULL string, so don't print it.
3729 WriteLine("User Strings");
3730 WriteLine("-------------------------------------------------------");
3732 for (ULONG i = 0; i < count; i++, totalCount++)
3734 do { // Try to get the string into the existing buffer.
3735 hr = m_pImport->GetUserString( Strings[i], rUserString.Ptr(),(ULONG32)rUserString.MaxSize(), &chUserString);
3736 if (hr == CLDB_S_TRUNCATION)
3737 { // Buffer wasn't big enough, try to enlarge it.
3738 if (FAILED(rUserString.ReSizeNoThrow(chUserString)))
3739 Error("malloc failed.", E_OUTOFMEMORY);
3742 } while (hr == CLDB_S_TRUNCATION);
3743 if (FAILED(hr)) Error("GetUserString failed.", hr);
3745 szUserString = rUserString.Ptr();
3746 chBuf = chUserString;
3748 VWrite("%08x : (%2d) L\"", Strings[i], chUserString);
3749 for (ULONG j=0; j<chUserString; j++)
3751 switch (*szUserString)
3754 Write("\\0"); break;
3756 Write("\\r"); break;
3758 Write("\\n"); break;
3760 Write("\\t"); break;
3762 if (iswprint(*szUserString))
3763 VWrite("%lc", *szUserString);
3772 if((j>0)&&((j&0x7F)==0)) WriteLine("");
3776 // Print the user string as a blob if an unprintable character is found.
3780 szUserString = rUserString.Ptr();
3781 if (FAILED(hr = rcBuf.ReSizeNoThrow(81))) //(chBuf * 5 + 1);
3782 Error("ReSize failed.", hr);
3783 szBuf = rcBuf.Ptr();
3785 WriteLine("\t\tUser string has unprintables, hex format below:");
3786 for (j = 0,k=0; j < chBuf; j++)
3788 sprintf_s (&szBuf[k*5], 81, "%04x ", szUserString[j]);
3790 if((k==16)||(j == (chBuf-1)))
3793 VWriteLine("\t\t%s", szBuf);
3801 m_pImport->CloseEnum(stringEnum);
3802 } // void MDInfo::DisplayUserStrings()
3804 void MDInfo::DisplayUnsatInfo()
3812 Write("\nUnresolved Externals\n");
3813 Write("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
3815 while ( (hr = m_pImport->EnumUnresolvedMethods(
3819 &cMethods)) == S_OK && cMethods )
3821 if ( TypeFromToken(tk) == mdtMethodDef )
3823 // a method definition without implementation
3824 DisplayMethodInfo( tk );
3826 else if ( TypeFromToken(tk) == mdtMemberRef )
3828 // an unresolved MemberRef to a global function
3829 DisplayMemberRefInfo( tk, "" );
3833 _ASSERTE(!"Unknown token kind!");
3836 m_pImport->CloseEnum(henum);
3837 } // void MDInfo::DisplayUnsatInfo()
3839 //*******************************************************************************
3840 // This code is used for debugging purposes only. This will just print out the
3842 //*******************************************************************************
3843 const char *MDInfo::DumpRawNameOfType(ULONG iType)
3845 if (iType <= iRidMax)
3847 const char *pNameTable;
3848 m_pTables->GetTableInfo(iType, 0,0,0,0, &pNameTable);
3852 // Is the field a coded token?
3853 if (iType <= iCodedTokenMax)
3855 int iCdTkn = iType - iCodedToken;
3856 const char *pNameCdTkn;
3857 m_pTables->GetCodedTokenInfo(iCdTkn, 0,0, &pNameCdTkn);
3882 static char buf[30];
3883 sprintf_s(buf, 30, "unknown type 0x%02x", iType);
3885 } // const char *MDInfo::DumpRawNameOfType()
3887 void MDInfo::DumpRawCol(ULONG ixTbl, ULONG ixCol, ULONG rid, bool bStats)
3889 ULONG ulType; // Type of a column.
3890 ULONG ulVal; // Value of a column.
3891 LPCUTF8 pString; // Pointer to a string.
3892 const void *pBlob; // Pointer to a blob.
3893 ULONG cb; // Size of something.
3895 m_pTables->GetColumn(ixTbl, ixCol, rid, &ulVal);
3896 m_pTables->GetColumnInfo(ixTbl, ixCol, 0, 0, &ulType, 0);
3898 if (ulType <= iRidMax)
3900 const char *pNameTable;
3901 m_pTables->GetTableInfo(ulType, 0,0,0,0, &pNameTable);
3902 VWrite("%s[%x]", pNameTable, ulVal);
3905 // Is the field a coded token?
3906 if (ulType <= iCodedTokenMax)
3908 int iCdTkn = ulType - iCodedToken;
3909 const char *pNameCdTkn;
3910 m_pTables->GetCodedTokenInfo(iCdTkn, 0,0, &pNameCdTkn);
3911 VWrite("%s[%08x]", pNameCdTkn, ulVal);
3919 VWrite("%02x", ulVal);
3923 VWrite("%04x", ulVal);
3927 VWrite("%08x", ulVal);
3930 if (ulVal && (m_DumpFilter & dumpNames))
3932 m_pTables->GetString(ulVal, &pString);
3933 VWrite("(%x)\"%s\"", ulVal, pString);
3936 VWrite("string#%x", ulVal);
3937 if (bStats && ulVal)
3939 m_pTables->GetString(ulVal, &pString);
3940 cb = (ULONG) strlen(pString) + 1;
3945 VWrite("guid#%x", ulVal);
3946 if (bStats && ulVal)
3952 VWrite("blob#%x", ulVal);
3953 if (bStats && ulVal)
3955 m_pTables->GetBlob(ulVal, &cb, &pBlob);
3965 VWrite("unknown type 0x%04x", ulVal);
3969 } // void MDInfo::DumpRawCol()
3971 ULONG MDInfo::DumpRawColStats(ULONG ixTbl, ULONG ixCol, ULONG cRows)
3974 ULONG ulType; // Type of a column.
3975 ULONG ulVal; // Value of a column.
3976 LPCUTF8 pString; // Pointer to a string.
3977 const void *pBlob; // Pointer to a blob.
3978 ULONG cb; // Size of something.
3980 m_pTables->GetColumnInfo(ixTbl, ixCol, 0, 0, &ulType, 0);
3982 if (IsHeapType(ulType))
3984 for (ULONG rid=1; rid<=cRows; ++rid)
3986 m_pTables->GetColumn(ixTbl, ixCol, rid, &ulVal);
3993 m_pTables->GetString(ulVal, &pString);
3994 cb = (ULONG) strlen(pString);
4005 m_pTables->GetBlob(ulVal, &cb, &pBlob);
4019 } // ULONG MDInfo::DumpRawColStats()
4021 int MDInfo::DumpHex(
4022 const char *szPrefix, // String prefix for first line.
4023 const void *pvData, // The data to print.
4024 ULONG cbData, // Bytes of data to print.
4025 int bText, // If true, also dump text.
4026 ULONG nLine) // Bytes per line to print.
4028 const BYTE *pbData = static_cast<const BYTE*>(pvData);
4029 ULONG i; // Loop control.
4030 ULONG nPrint; // Number to print in an iteration.
4031 ULONG nSpace; // Spacing calculations.
4032 ULONG nPrefix; // Size of the prefix.
4033 ULONG nLines=0; // Number of lines printed.
4034 const char *pPrefix; // For counting spaces in the prefix.
4036 // Round down to 8 characters.
4037 nLine = nLine & ~0x7;
4039 for (nPrefix=0, pPrefix=szPrefix; *pPrefix; ++pPrefix)
4041 if (*pPrefix == '\t')
4042 nPrefix = (nPrefix + 8) & ~7;
4046 //nPrefix = strlen(szPrefix);
4048 { // Write the line prefix.
4050 VWrite("%s:", szPrefix);
4052 VWrite("%*s:", nPrefix, "");
4056 // Calculate spacing.
4057 nPrint = min(cbData, nLine);
4058 nSpace = nLine - nPrint;
4061 for(i=0; i<nPrint; i++)
4065 VWrite("%02x ", pbData[i]);
4069 // Space out to the text spot.
4071 VWrite("%*s", nSpace*3+nSpace/8, "");
4074 for(i=0; i<nPrint; i++)
4075 VWrite("%c", (isprint(pbData[i])) ? pbData[i] : ' ');
4076 // Space out the text, and finish the line.
4077 VWrite("%*s<", nSpace, "");
4081 // Next data to print.
4088 } // int MDInfo::DumpHex()
4090 void MDInfo::DumpRawHeaps()
4092 HRESULT hr; // A result.
4093 ULONG ulSize; // Bytes in a heap.
4094 const BYTE *pData; // Pointer to a blob.
4095 ULONG cbData; // Size of a blob.
4096 ULONG oData; // Offset of current blob.
4097 char rcPrefix[30]; // To format line prefix.
4099 m_pTables->GetBlobHeapSize(&ulSize);
4101 VWriteLine("Blob Heap: %d(%#x) bytes", ulSize,ulSize);
4105 m_pTables->GetBlob(oData, &cbData, (const void**)&pData);
4106 sprintf_s(rcPrefix, 30, "%5x,%-2x", oData, cbData);
4107 DumpHex(rcPrefix, pData, cbData);
4108 hr = m_pTables->GetNextBlob(oData, &oData);
4112 m_pTables->GetStringHeapSize(&ulSize);
4114 VWriteLine("String Heap: %d(%#x) bytes", ulSize,ulSize);
4116 const char *pString;
4119 m_pTables->GetString(oData, &pString);
4120 if (m_DumpFilter & dumpMoreHex)
4122 sprintf_s(rcPrefix, 30, "%08x", oData);
4123 DumpHex(rcPrefix, pString, (ULONG)strlen(pString)+1);
4127 VWrite("%08x: %s\n", oData, pString);
4128 hr = m_pTables->GetNextString(oData, &oData);
4133 DisplayUserStrings();
4135 } // void MDInfo::DumpRawHeaps()
4138 void MDInfo::DumpRaw(int iDump, bool bunused)
4140 ULONG cTables; // Tables in the database.
4141 ULONG cCols; // Columns in a table.
4142 ULONG cRows; // Rows in a table.
4143 ULONG cbRow; // Bytes in a row of a table.
4144 ULONG iKey; // Key column of a table.
4145 const char *pNameTable; // Name of a table.
4146 ULONG oCol; // Offset of a column.
4147 ULONG cbCol; // Size of a column.
4148 ULONG ulType; // Type of a column.
4149 const char *pNameColumn; // Name of a column.
4152 // Heaps is easy -- there is a specific bit for that.
4153 bool bStats = (m_DumpFilter & dumpStats) != 0;
4154 // Rows are harder. Was there something else that limited data?
4155 BOOL bRows = (m_DumpFilter & (dumpSchema | dumpHeader)) == 0;
4156 BOOL bSchema = bRows || (m_DumpFilter & dumpSchema);
4157 // (m_DumpFilter & (dumpSchema | dumpHeader | dumpCSV | dumpRaw | dumpStats | dumpRawHeaps))
4161 // Get the raw metadata header.
4162 const BYTE *pbData = NULL;
4163 const BYTE *pbStream = NULL; // One of the stream.s
4164 const BYTE *pbMd = NULL; // The metadata stream.
4166 ULONG cbStream = 0; // One of the streams.
4167 ULONG cbMd = 0; // The metadata stream.
4172 m_pTables2->GetMetaDataStorage((const void**)&pbData, &cbData);
4174 // Per the ECMA spec, the section data looks like this:
4175 struct MDSTORAGESIGNATURE
4177 ULONG lSignature; // "Magic" signature.
4178 USHORT iMajorVer; // Major file version.
4179 USHORT iMinorVer; // Minor file version.
4180 ULONG iExtraData; // Offset to next structure of information
4181 ULONG iVersionString; // Length of version string
4182 BYTE pVersion[0]; // Version string
4184 struct MDSTORAGEHEADER
4186 BYTE fFlags; // STGHDR_xxx flags.
4188 USHORT iStreams; // How many streams are there.
4190 const MDSTORAGESIGNATURE *pStorage = (const MDSTORAGESIGNATURE *) pbData;
4191 const MDSTORAGEHEADER *pSHeader = (const MDSTORAGEHEADER *)(pbData + sizeof(MDSTORAGESIGNATURE) + pStorage->iVersionString);
4193 VWriteLine("Metadata section: 0x%08x, version: %d.%d, extra: %d, version len: %d, version: %s", pStorage->lSignature, pStorage->iMajorVer, pStorage->iMinorVer, pStorage->iExtraData, pStorage->iVersionString, pStorage->pVersion);
4194 VWriteLine(" flags: 0x%02x, streams: %d", pSHeader->fFlags, pSHeader->iStreams);
4195 if (m_DumpFilter & dumpMoreHex)
4197 const BYTE *pbEnd = pbData;
4198 ULONG cb = sizeof(MDSTORAGESIGNATURE) + pStorage->iVersionString + sizeof(MDSTORAGEHEADER);
4199 hr = m_pTables2->GetMetaDataStreamInfo(0, &pName, (const void**)&pbEnd, &cbStream);
4201 cb = (ULONG)(pbEnd - pbData);
4202 DumpHex(" ", pbData, cb);
4205 for (ix=0; hr == S_OK; ++ix)
4207 hr = m_pTables2->GetMetaDataStreamInfo(ix, &pName, (const void**)&pbStream, &cbStream);
4210 if (strcmp(pName, "#~") == 0 || strcmp(pName, "#-") == 0)
4216 VWriteLine("Stream %d: name: %s, size %d", ix, pName, cbStream);
4217 // hex for individual stream headers in metadata section dump. hex for
4218 // the streams themselves distributed throughout the dump.
4223 // Per ECMA, the metadata header looks like this:
4226 ULONG m_ulReserved; // Reserved, must be zero.
4227 BYTE m_major; // Version numbers.
4229 BYTE m_heaps; // Bits for heap sizes.
4230 BYTE m_rid; // log-base-2 of largest rid.
4231 unsigned __int64 m_maskvalid; // Bit mask of present table counts.
4232 unsigned __int64 m_sorted; // Bit mask of sorted tables. };
4236 pMd = (const MD *)pbMd;
4238 VWriteLine("Metadata header: %d.%d, heaps: 0x%02x, rid: 0x%02x, valid: 0x%016I64x, sorted: 0x%016I64x",
4239 pMd->m_major, pMd->m_minor, pMd->m_heaps, pMd->m_rid,
4240 (ULONGLONG)GET_UNALIGNED_VAL64(&(pMd->m_maskvalid)),
4241 (ULONGLONG)GET_UNALIGNED_VAL64(&(pMd->m_sorted)));
4243 if (m_DumpFilter & dumpMoreHex)
4245 DumpHex(" ", pbMd, sizeof(MD));
4251 m_pTables->GetNumTables(&cTables);
4253 m_pTables->GetStringHeapSize(&ulSize);
4254 VWrite("Strings: %d(%#x)", ulSize, ulSize);
4255 m_pTables->GetBlobHeapSize(&ulSize);
4256 VWrite(", Blobs: %d(%#x)", ulSize, ulSize);
4257 m_pTables->GetGuidHeapSize(&ulSize);
4258 VWrite(", Guids: %d(%#x)", ulSize, ulSize);
4259 m_pTables->GetUserStringHeapSize(&ulSize);
4260 VWriteLine(", User strings: %d(%#x)", ulSize, ulSize);
4262 for (ULONG ixTbl = 0; ixTbl < cTables; ++ixTbl)
4264 m_pTables->GetTableInfo(ixTbl, &cbRow, &cRows, &cCols, &iKey, &pNameTable);
4266 if (bRows) // when dumping rows, print a break between row data and schema
4267 VWriteLine("=================================================");
4268 VWriteLine("%2d(%#x): %-20s cRecs:%5d(%#x), cbRec:%3d(%#x), cbTable:%6d(%#x)",
4269 ixTbl, ixTbl, pNameTable, cRows, cRows, cbRow, cbRow, cbRow * cRows, cbRow * cRows);
4271 if (!bSchema && !bRows)
4274 // Dump column definitions for the table.
4276 for (ixCol=0; ixCol<cCols; ++ixCol)
4278 m_pTables->GetColumnInfo(ixTbl, ixCol, &oCol, &cbCol, &ulType, &pNameColumn);
4280 VWrite(" col %2x:%c %-12s oCol:%2x, cbCol:%x, %-7s",
4281 ixCol, ((ixCol==iKey)?'*':' '), pNameColumn, oCol, cbCol, DumpRawNameOfType(ulType));
4285 ulSize = DumpRawColStats(ixTbl, ixCol, cRows);
4287 VWrite("(%d)", ulSize);
4296 for (ULONG rid = 1; rid <= cRows; ++rid)
4299 VWriteLine("-------------------------------------------------");
4300 VWrite(" %3x == ", rid);
4301 for (ixCol=0; ixCol < cCols; ++ixCol)
4303 if (ixCol) VWrite(", ");
4304 VWrite("%d:", ixCol);
4305 DumpRawCol(ixTbl, ixCol, rid, bStats);
4310 } // void MDInfo::DumpRaw()
4312 void MDInfo::DumpRawCSV()
4314 ULONG cTables; // Tables in the database.
4315 ULONG cCols; // Columns in a table.
4316 ULONG cRows; // Rows in a table.
4317 ULONG cbRow; // Bytes in a row of a table.
4318 const char *pNameTable; // Name of a table.
4321 m_pTables->GetNumTables(&cTables);
4323 VWriteLine("Name,Size,cRecs,cbRec");
4325 m_pTables->GetStringHeapSize(&ulSize);
4326 VWriteLine("Strings,%d", ulSize);
4328 m_pTables->GetBlobHeapSize(&ulSize);
4329 VWriteLine("Blobs,%d", ulSize);
4331 m_pTables->GetGuidHeapSize(&ulSize);
4332 VWriteLine("Guids,%d", ulSize);
4334 for (ULONG ixTbl = 0; ixTbl < cTables; ++ixTbl)
4336 m_pTables->GetTableInfo(ixTbl, &cbRow, &cRows, &cCols, NULL, &pNameTable);
4337 VWriteLine("%s,%d,%d,%d", pNameTable, cbRow*cRows, cRows, cbRow);
4340 } // void MDInfo::DumpRawCSV()