summaryrefslogtreecommitdiff
path: root/src/inc/formattype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/formattype.cpp')
-rw-r--r--src/inc/formattype.cpp1574
1 files changed, 1574 insertions, 0 deletions
diff --git a/src/inc/formattype.cpp b/src/inc/formattype.cpp
new file mode 100644
index 0000000000..76aa506bf1
--- /dev/null
+++ b/src/inc/formattype.cpp
@@ -0,0 +1,1574 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+//
+/******************************************************************************/
+/* formatType.cpp */
+/******************************************************************************/
+#include "formattype.h"
+
+/******************************************************************************/
+char* asString(CQuickBytes *out) {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ SIZE_T oldSize = out->Size();
+ out->ReSizeThrows(oldSize + 1);
+ char* cur = &((char*) out->Ptr())[oldSize];
+ *cur = 0;
+ out->ReSizeThrows(oldSize); // Don't count the null character
+ return((char*) out->Ptr());
+}
+
+void appendStr(CQuickBytes *out, const char* str, unsigned len) {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ if(len == (unsigned)(-1)) len = (unsigned)strlen(str);
+ SIZE_T oldSize = out->Size();
+ out->ReSizeThrows(oldSize + len);
+ char* cur = &((char*) out->Ptr())[oldSize];
+ memcpy(cur, str, len);
+ // Note no trailing null!
+}
+
+void appendChar(CQuickBytes *out, char chr) {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ SIZE_T oldSize = out->Size();
+ out->ReSizeThrows(oldSize + 1);
+ ((char*) out->Ptr())[oldSize] = chr;
+ // Note no trailing null!
+}
+
+void insertStr(CQuickBytes *out, const char* str) {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ unsigned len = (unsigned)strlen(str);
+ SIZE_T oldSize = out->Size();
+ out->ReSizeThrows(oldSize + len);
+ char* cur = &((char*) out->Ptr())[len];
+ memmove(cur,out->Ptr(),oldSize);
+ memcpy(out->Ptr(), str, len);
+ // Note no trailing null!
+}
+
+static void appendStrNum(CQuickBytes *out, int num) {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ char buff[16];
+ sprintf_s(buff, COUNTOF(buff), "%d", num);
+ appendStr(out, buff);
+}
+
+const PCCOR_SIGNATURE PrettyPrintSignature(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ unsigned typeLen, // the lenght of 'typePtr'
+ const char* name, // can be "", the name of the method for this sig 0 means local var sig
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig
+ _In_opt_z_ const char* inlabel, // prefix for names (NULL if no names required)
+ BOOL printTyArity=FALSE);
+
+
+PCCOR_SIGNATURE PrettyPrintTypeOrDef(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI); // ptr to IMDInternal class with ComSig
+
+//*****************************************************************************
+// Parse a length, return the length, size of the length.
+//*****************************************************************************
+ULONG GetLength( // Length or -1 on error.
+ void const *pData, // First byte of length.
+ int *pSizeLen) // Put size of length here, if not 0.
+{
+ LIMITED_METHOD_CONTRACT;
+
+ BYTE const *pBytes = reinterpret_cast<BYTE const*>(pData);
+
+ if(pBytes)
+ {
+ if ((*pBytes & 0x80) == 0x00) // 0??? ????
+ {
+ if (pSizeLen) *pSizeLen = 1;
+ return (*pBytes & 0x7f);
+ }
+
+ if ((*pBytes & 0xC0) == 0x80) // 10?? ????
+ {
+ if (pSizeLen) *pSizeLen = 2;
+ return ((*pBytes & 0x3f) << 8 | *(pBytes+1));
+ }
+
+ if ((*pBytes & 0xE0) == 0xC0) // 110? ????
+ {
+ if (pSizeLen) *pSizeLen = 4;
+ return ((*pBytes & 0x1f) << 24 | *(pBytes+1) << 16 | *(pBytes+2) << 8 | *(pBytes+3));
+ }
+ }
+ if(pSizeLen) *pSizeLen = 0;
+ return 0;
+}
+
+
+/******************************************************************************/
+const char* PrettyPrintSig(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ unsigned typeLen, // the length of 'typePtr'
+ const char* name, // can be "", the name of the method for this sig 0 means local var sig
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig
+ const char* inlabel, // prefix for names (NULL if no names required)
+ BOOL printTyArity)
+{
+ STATIC_CONTRACT_THROWS;
+
+ // This had a _try/__except handler earlier that would swallow exceptions like
+ // SO and breakpoint. Obviously, swallowing any of them is not the right thing to do.
+ //
+ // Thus, we replace it with EX_TRY/EX_CATCH that automatically kicks in with SO
+ // handling if it sees any SO going past it. Also, C++ catch will not swallow
+ // the breakpoint exception (which is what we want).
+ EX_TRY
+ {
+ PrettyPrintSignature(typePtr,
+ typeLen,
+ name,
+ out,
+ pIMDI,
+ inlabel,
+ printTyArity);
+ }
+ EX_CATCH
+ {
+ out->Shrink(0);
+ appendStr(out,"ERROR PARSING THE SIGNATURE");
+ }
+#if defined(__ILDASM__)
+ // Dont allow ildasm to swallow bad SEH exceptions
+ EX_END_CATCH(RethrowCorruptingExceptions);
+#else // __ILDASM__
+ EX_END_CATCH(SwallowAllExceptions);
+#endif // __ILDASM__
+
+ return(asString(out));
+}
+
+/********************************************************************************/
+// Converts a com signature to a printable signature.
+// Note that return value is pointing at the CQuickBytes buffer,
+
+const PCCOR_SIGNATURE PrettyPrintSignature(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ unsigned typeLen, // the lenght of 'typePtr'
+ const char* name, // can be "", the name of the method for this sig 0 means local var sig
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig
+ const char* inlabel, // prefix for names (NULL if no names required)
+ BOOL printTyArity)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ unsigned numArgs;
+ unsigned numTyArgs = 0;
+ PCCOR_SIGNATURE typeEnd = typePtr + typeLen;
+ unsigned ixArg= 0; //arg index
+ char argname[1024];
+ char label[MAX_PREFIX_SIZE];
+ const char* openpar = "(";
+ const char* closepar = ")";
+ ParamDescriptor* pszArgName = NULL; // ptr to array of names (if provided by debug info)
+
+ if(inlabel && *inlabel) // check for *inlabel is totally unnecessary, added to pacify the PREFIX
+ {
+ strcpy_s(label,MAX_PREFIX_SIZE,inlabel);
+ ixArg = label[strlen(label)-1] - '0';
+ label[strlen(label)-1] = 0;
+ if(label[0] == '@') // it's pointer!
+ {
+#ifdef _WIN64
+ pszArgName = (ParamDescriptor*)_atoi64(&label[1]);
+#else // !_WIN64
+ pszArgName = (ParamDescriptor*)(size_t)atoi(&label[1]);
+#endif // _WIN64
+ }
+ }
+
+ // 0 means a local var sig
+ if (name != 0)
+ {
+ // get the calling convention out
+ unsigned callConv = CorSigUncompressData(typePtr);
+
+ // should not be a local var sig
+ _ASSERTE(!isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_LOCAL_SIG));
+
+ if (isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_FIELD))
+ {
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ if (*name)
+ {
+ appendChar(out, ' ');
+ appendStr(out, name);
+ }
+ return(typePtr);
+ }
+
+ if (callConv & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS)
+ appendStr(out, KEYWORD("explicit "));
+
+ if (callConv & IMAGE_CEE_CS_CALLCONV_HASTHIS)
+ appendStr(out, KEYWORD("instance "));
+
+ if (isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_GENERICINST))
+ {
+ openpar = LTN();
+ closepar = GTN();
+ }
+ else
+ {
+ static const char* const callConvNames[8] = {
+ "",
+ "unmanaged cdecl ",
+ "unmanaged stdcall ",
+ "unmanaged thiscall ",
+ "unmanaged fastcall ",
+ "vararg ",
+ "<error> ",
+ "<error> "
+ };
+ appendStr(out, KEYWORD(callConvNames[callConv & 7]));
+ }
+
+ if (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
+ {
+ numTyArgs = CorSigUncompressData(typePtr);
+ }
+ numArgs = CorSigUncompressData(typePtr);
+ if (!isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_GENERICINST))
+ {
+ // do return type
+ if(pszArgName)
+ {
+ argname[0] = 0;
+ DumpParamAttr(argname,COUNTOF(argname),pszArgName[ixArg+numArgs].attr);
+ appendStr(out,argname);
+ }
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ if(pszArgName)
+ {
+ argname[0] = ' '; argname[1] = 0;
+ DumpMarshaling(pIMDI,argname,COUNTOF(argname),pszArgName[ixArg+numArgs].tok);
+ appendStr(out,argname);
+ }
+ if(*name != 0)
+ {
+ appendChar(out, ' ');
+ appendStr(out, name);
+ }
+ if((numTyArgs != 0)&&printTyArity)
+ {
+ appendStr(out,LTN());
+ appendChar(out,'[');
+ appendStrNum(out,numTyArgs);
+ appendChar(out,']');
+ appendStr(out,GTN());
+ }
+ }
+ }
+ else
+ {
+ // get the calling convention out
+#ifdef _DEBUG
+ unsigned callConv =
+#endif
+ CorSigUncompressData(typePtr);
+#ifdef _DEBUG
+ (void)callConv; //prevent "unused variable" warning from GCC
+ // should be a local var sig
+ _ASSERTE(callConv == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
+#endif
+
+ numArgs = CorSigUncompressData(typePtr);
+ }
+
+ appendStr(out, openpar);
+
+ bool needComma = false;
+ while(typePtr < typeEnd)
+ {
+ if(name) // printing the arguments
+ {
+ PREFIX_ASSUME(typePtr != NULL);
+ if (*typePtr == ELEMENT_TYPE_SENTINEL)
+ {
+ if (needComma)
+ appendChar(out, ',');
+ appendStr(out, "...");
+ typePtr++;
+ }
+ else
+ {
+ if (numArgs <= 0)
+ break;
+ if (needComma)
+ appendChar(out, ',');
+ if(pszArgName)
+ {
+ argname[0] = 0;
+ DumpParamAttr(argname,COUNTOF(argname),pszArgName[ixArg].attr);
+ appendStr(out,argname);
+ }
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ if(inlabel)
+ {
+ if(pszArgName)
+ {
+ argname[0] = ' '; argname[1] = 0;
+ DumpMarshaling(pIMDI,argname,COUNTOF(argname),pszArgName[ixArg].tok);
+ strcat_s(argname, COUNTOF(argname), ProperName(pszArgName[ixArg++].name));
+ }
+ else sprintf_s(argname,COUNTOF(argname)," %s_%d",label,ixArg++);
+ appendStr(out,argname);
+ }
+ --numArgs;
+ }
+ }
+ else // printing local vars
+ {
+ if (numArgs <= 0)
+ break;
+ if(pszArgName)
+ {
+ if(pszArgName[ixArg].attr == 0xFFFFFFFF)
+ {
+ CQuickBytes fake_out;
+ typePtr = PrettyPrintTypeOrDef(typePtr, &fake_out, pIMDI);
+ ixArg++;
+ numArgs--;
+ continue;
+ }
+ }
+ if (needComma)
+ appendChar(out, ',');
+ if(pszArgName)
+ {
+ sprintf_s(argname,COUNTOF(argname),"[%d] ",pszArgName[ixArg].attr);
+ appendStr(out,argname);
+ }
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ if(inlabel)
+ {
+ if(pszArgName)
+ {
+ sprintf_s(argname,COUNTOF(argname)," %s",ProperLocalName(pszArgName[ixArg++].name));
+ }
+ else sprintf_s(argname,COUNTOF(argname)," %s_%d",label,ixArg++);
+ appendStr(out,argname);
+ }
+ --numArgs;
+ }
+ needComma = true;
+ }
+ // Have we finished printing all the arguments?
+ if (numArgs > 0) {
+ appendStr(out, ERRORMSG(" [SIGNATURE ENDED PREMATURELY]"));
+ }
+
+ appendStr(out, closepar);
+ return(typePtr);
+}
+
+
+/******************************************************************************/
+// pretty prints 'type' or its 'typedef' to the buffer 'out' returns a poitner to the next type,
+// or 0 on a format failure; outside ILDASM -- simple wrapper for PrettyPrintType
+
+PCCOR_SIGNATURE PrettyPrintTypeOrDef(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI) // ptr to IMDInternal class with ComSig
+{
+ CONTRACTL
+ {
+ THROWS;
+ SO_TOLERANT;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ PCCOR_SIGNATURE pBegin, pEnd=NULL;
+
+ BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(ThrowStackOverflow());
+
+#ifdef __ILDASM__
+ ULONG L = (ULONG)(out->Size());
+#endif
+ pBegin = typePtr;
+ pEnd = PrettyPrintType(typePtr,out,pIMDI);
+#ifdef __ILDASM__
+ if(pEnd > pBegin) // PrettyPrintType can return NULL
+ {
+ DWORD i;
+ ULONG l = (ULONG)(pEnd - pBegin);
+ for(i=0; i < g_NumTypedefs; i++)
+ {
+ if(((*g_typedefs)[i].cb == l)
+ && (memcmp((*g_typedefs)[i].psig,pBegin,l)==0))
+ {
+ out->Shrink(L); // discard output of PrettyPrintType
+ appendStr(out, JUMPPT(ProperName((*g_typedefs)[i].szName),(*g_typedefs)[i].tkSelf));
+ break;
+ }
+ }
+ }
+#endif
+ END_SO_INTOLERANT_CODE;
+ return pEnd;
+}
+
+/******************************************************************************/
+// pretty prints 'type' to the buffer 'out' returns a pointer to the next type,
+// or 0 on a format failure
+
+PCCOR_SIGNATURE PrettyPrintType(
+ PCCOR_SIGNATURE typePtr, // type to convert,
+ CQuickBytes *out, // where to put the pretty printed string
+ IMDInternalImport *pIMDI) // ptr to IMDInternal class with ComSig
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ mdToken tk;
+ const char* str;
+ int typ;
+ CQuickBytes tmp;
+ CQuickBytes Appendix;
+ BOOL Reiterate;
+ int n;
+
+ do {
+ Reiterate = FALSE;
+ switch(typ = *typePtr++) {
+ case ELEMENT_TYPE_VOID :
+ str = "void"; goto APPEND;
+ case ELEMENT_TYPE_BOOLEAN :
+ str = "bool"; goto APPEND;
+ case ELEMENT_TYPE_CHAR :
+ str = "char"; goto APPEND;
+ case ELEMENT_TYPE_I1 :
+ str = "int8"; goto APPEND;
+ case ELEMENT_TYPE_U1 :
+ str = "uint8"; goto APPEND;
+ case ELEMENT_TYPE_I2 :
+ str = "int16"; goto APPEND;
+ case ELEMENT_TYPE_U2 :
+ str = "uint16"; goto APPEND;
+ case ELEMENT_TYPE_I4 :
+ str = "int32"; goto APPEND;
+ case ELEMENT_TYPE_U4 :
+ str = "uint32"; goto APPEND;
+ case ELEMENT_TYPE_I8 :
+ str = "int64"; goto APPEND;
+ case ELEMENT_TYPE_U8 :
+ str = "uint64"; goto APPEND;
+ case ELEMENT_TYPE_R4 :
+ str = "float32"; goto APPEND;
+ case ELEMENT_TYPE_R8 :
+ str = "float64"; goto APPEND;
+ case ELEMENT_TYPE_U :
+ str = "native uint"; goto APPEND;
+ case ELEMENT_TYPE_I :
+ str = "native int"; goto APPEND;
+ case ELEMENT_TYPE_OBJECT :
+ str = "object"; goto APPEND;
+ case ELEMENT_TYPE_STRING :
+ str = "string"; goto APPEND;
+ case ELEMENT_TYPE_TYPEDBYREF :
+ str = "typedref"; goto APPEND;
+ APPEND:
+ appendStr(out, KEYWORD((char*)str));
+ break;
+
+ case ELEMENT_TYPE_VALUETYPE :
+ str = "valuetype ";
+ goto DO_CLASS;
+ case ELEMENT_TYPE_CLASS :
+ str = "class ";
+ goto DO_CLASS;
+
+ DO_CLASS:
+ appendStr(out, KEYWORD((char*)str));
+ typePtr += CorSigUncompressToken(typePtr, &tk);
+ if(IsNilToken(tk))
+ {
+ appendStr(out, "[ERROR! NIL TOKEN]");
+ }
+ else PrettyPrintClass(out, tk, pIMDI);
+ REGISTER_REF(g_tkRefUser,tk)
+ break;
+
+ case ELEMENT_TYPE_SZARRAY :
+ insertStr(&Appendix,"[]");
+ Reiterate = TRUE;
+ break;
+
+ case ELEMENT_TYPE_ARRAY :
+ {
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ PREFIX_ASSUME(typePtr != NULL);
+ unsigned rank = CorSigUncompressData(typePtr);
+ // <TODO> what is the syntax for the rank 0 case? </TODO>
+ if (rank == 0) {
+ appendStr(out, ERRORMSG("[BAD: RANK == 0!]"));
+ }
+ else {
+ _ASSERTE(rank != 0);
+
+#ifdef _PREFAST_
+#pragma prefast(push)
+#pragma prefast(disable:22009 "Suppress PREFAST warnings about integer overflow")
+#endif
+ int* lowerBounds = (int*) _alloca(sizeof(int)*2*rank);
+ int* sizes = &lowerBounds[rank];
+ memset(lowerBounds, 0, sizeof(int)*2*rank);
+
+ unsigned numSizes = CorSigUncompressData(typePtr);
+ _ASSERTE(numSizes <= rank);
+ unsigned i;
+ for(i =0; i < numSizes; i++)
+ sizes[i] = CorSigUncompressData(typePtr);
+
+ unsigned numLowBounds = CorSigUncompressData(typePtr);
+ _ASSERTE(numLowBounds <= rank);
+ for(i = 0; i < numLowBounds; i++)
+ typePtr+=CorSigUncompressSignedInt(typePtr,&lowerBounds[i]);
+
+ appendChar(out, '[');
+ if (rank == 1 && numSizes == 0 && numLowBounds == 0)
+ appendStr(out, "...");
+ else {
+ for(i = 0; i < rank; i++)
+ {
+ //if (sizes[i] != 0 || lowerBounds[i] != 0)
+ {
+ if (lowerBounds[i] == 0 && i < numSizes)
+ appendStrNum(out, sizes[i]);
+ else
+ {
+ if(i < numLowBounds)
+ {
+ appendStrNum(out, lowerBounds[i]);
+ appendStr(out, "...");
+ if (/*sizes[i] != 0 && */i < numSizes)
+ appendStrNum(out, lowerBounds[i] + sizes[i] - 1);
+ }
+ }
+ }
+ if (i < rank-1)
+ appendChar(out, ',');
+ }
+ }
+ appendChar(out, ']');
+#ifdef _PREFAST_
+#pragma prefast(pop)
+#endif
+ }
+ } break;
+
+ case ELEMENT_TYPE_VAR :
+ appendChar(out, '!');
+ n = CorSigUncompressData(typePtr);
+#ifdef __ILDASM__
+ if(!PrettyPrintGP(g_tkVarOwner,out,n))
+#endif
+ appendStrNum(out, n);
+ break;
+
+ case ELEMENT_TYPE_MVAR :
+ appendChar(out, '!');
+ appendChar(out, '!');
+ n = CorSigUncompressData(typePtr);
+#ifdef __ILDASM__
+ if(!PrettyPrintGP(g_tkMVarOwner,out,n))
+#endif
+ appendStrNum(out, n);
+ break;
+
+ case ELEMENT_TYPE_FNPTR :
+ appendStr(out, KEYWORD("method "));
+ typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL);
+ break;
+
+ case ELEMENT_TYPE_GENERICINST :
+ {
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ appendStr(out, LTN());
+ unsigned numArgs = CorSigUncompressData(typePtr);
+ bool needComma = false;
+ while(numArgs--)
+ {
+ if (needComma)
+ appendChar(out, ',');
+ typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
+ needComma = true;
+ }
+ appendStr(out, GTN());
+ break;
+ }
+
+#ifndef __ILDASM__
+ case ELEMENT_TYPE_INTERNAL :
+ {
+ // ELEMENT_TYPE_INTERNAL <TypeHandle>
+ _ASSERTE(sizeof(TypeHandle) == sizeof(void *));
+ TypeHandle typeHandle;
+ typePtr += CorSigUncompressPointer(typePtr, (void **)&typeHandle);
+
+ MethodTable *pMT = NULL;
+ if (typeHandle.IsTypeDesc())
+ {
+ pMT = typeHandle.AsTypeDesc()->GetMethodTable();
+ if (pMT)
+ {
+ PrettyPrintClass(out, pMT->GetCl(), pMT->GetMDImport());
+
+ // It could be a "native version" of the managed type used in interop
+ if (typeHandle.AsTypeDesc()->IsNativeValueType())
+ appendStr(out, "_NativeValueType");
+ }
+ else
+ appendStr(out, "(null)");
+ }
+ else
+ {
+ pMT = typeHandle.AsMethodTable();
+ if (pMT)
+ PrettyPrintClass(out, pMT->GetCl(), pMT->GetMDImport());
+ else
+ appendStr(out, "(null)");
+ }
+
+ char sz[32];
+ if(IsCompilationProcess())
+ {
+ sprintf_s(sz, COUNTOF(sz), " /* TOKEN: 0x%x */", pMT != NULL ? pMT->GetCl() : 0);
+ }
+ else
+ {
+ sprintf_s(sz, COUNTOF(sz), " /* MT: 0x%p */", pMT);
+ }
+ appendStr(out, sz);
+ break;
+ }
+#endif
+
+
+ // Modifiers or depedent types
+ case ELEMENT_TYPE_CMOD_OPT :
+ str = " modopt("; goto ADDCLASSTOCMOD;
+ case ELEMENT_TYPE_CMOD_REQD :
+ str = " modreq(";
+ ADDCLASSTOCMOD:
+ typePtr += CorSigUncompressToken(typePtr, &tk);
+ if (IsNilToken(tk))
+ {
+ Debug_ReportError("Nil token in custom modifier");
+ }
+ tmp.Shrink(0);
+ appendStr(&tmp, KEYWORD((char*)str));
+ PrettyPrintClass(&tmp, tk, pIMDI);
+ appendChar(&tmp,')');
+ str = (const char *) asString(&tmp);
+ goto MODIFIER;
+ case ELEMENT_TYPE_PINNED :
+ str = " pinned"; goto MODIFIER;
+ case ELEMENT_TYPE_PTR :
+ str = "*"; goto MODIFIER;
+ case ELEMENT_TYPE_BYREF :
+ str = AMP(); goto MODIFIER;
+ MODIFIER:
+ insertStr(&Appendix, str);
+ Reiterate = TRUE;
+ break;
+
+ default:
+ case ELEMENT_TYPE_SENTINEL :
+ case ELEMENT_TYPE_END :
+ //_ASSERTE(!"Unknown Type");
+ if(typ)
+ {
+ char sz[64];
+ sprintf_s(sz,COUNTOF(sz),"/* UNKNOWN TYPE (0x%X)*/",typ);
+ appendStr(out, ERRORMSG(sz));
+ }
+ break;
+ } // end switch
+ } while(Reiterate);
+ appendStr(out,asString(&Appendix));
+ return(typePtr);
+}
+
+/******************************************************************/
+const char* PrettyPrintClass(
+ CQuickBytes *out, // where to put the pretty printed string
+ mdToken tk, // The class token to look up
+ IMDInternalImport *pIMDI) // ptr to IMDInternalImport class with ComSig
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ if(tk == mdTokenNil) // Zero resolution scope for "somewhere here" TypeRefs
+ {
+ appendStr(out,"[*]");
+ return(asString(out));
+ }
+ if(!pIMDI->IsValidToken(tk))
+ {
+ char str[1024];
+ sprintf_s(str,COUNTOF(str)," [ERROR: INVALID TOKEN 0x%8.8X] ",tk);
+ appendStr(out,ERRORMSG(str));
+ return(asString(out));
+ }
+ switch(TypeFromToken(tk))
+ {
+ case mdtTypeRef:
+ case mdtTypeDef:
+#ifdef __ILDASM__
+ DWORD ix;
+ for(ix = 0; ix < g_NumTypedefs; ix++)
+ {
+ if((*g_typedefs)[ix].tkTypeSpec == tk) break;
+ }
+ if(ix < g_NumTypedefs)
+ {
+ appendStr(out,JUMPPT(ProperName((*g_typedefs)[ix].szName),(*g_typedefs)[ix].tkSelf));
+ }
+ else
+#endif
+ {
+ const char *nameSpace = 0;
+ const char *name = 0;
+ mdToken tkEncloser;
+
+ if (TypeFromToken(tk) == mdtTypeRef)
+ {
+ if (FAILED(pIMDI->GetResolutionScopeOfTypeRef(tk, &tkEncloser)))
+ {
+ tkEncloser = mdTypeDefNil;
+ }
+ if (FAILED(pIMDI->GetNameOfTypeRef(tk, &nameSpace, &name)))
+ {
+ nameSpace = name = "Invalid TypeRef record";
+ }
+ }
+ else
+ {
+ if (FAILED(pIMDI->GetNestedClassProps(tk,&tkEncloser)))
+ {
+ tkEncloser = mdTypeDefNil;
+ }
+ if (FAILED(pIMDI->GetNameOfTypeDef(tk, &name, &nameSpace)))
+ {
+ nameSpace = name = "Invalid TypeDef record";
+ }
+ }
+ MAKE_NAME_IF_NONE(name,tk);
+ if((tkEncloser == mdTokenNil) || RidFromToken(tkEncloser))
+ {
+ PrettyPrintClass(out,tkEncloser,pIMDI);
+ if (TypeFromToken(tkEncloser) == mdtTypeRef || TypeFromToken(tkEncloser) == mdtTypeDef)
+ {
+ appendChar(out, '/');
+ //nameSpace = ""; //don't print namespaces for nested classes!
+ }
+ }
+ if(TypeFromToken(tk)==mdtTypeDef)
+ {
+ unsigned L = (unsigned)strlen(ProperName(name))+1;
+ char* szFN = NULL;
+ if(nameSpace && *nameSpace)
+ {
+ const char* sz = ProperName(nameSpace);
+ L+= (unsigned)strlen(sz)+1;
+ szFN = new char[L];
+ sprintf_s(szFN,L,"%s.",sz);
+ }
+ else
+ {
+ szFN = new char[L];
+ *szFN = 0;
+ }
+ strcat_s(szFN,L, ProperName(name));
+ appendStr(out,JUMPPT(szFN,tk));
+ VDELETE(szFN);
+ }
+ else
+ {
+ if (nameSpace && *nameSpace) {
+ appendStr(out, ProperName(nameSpace));
+ appendChar(out, '.');
+ }
+
+ appendStr(out, ProperName(name));
+ }
+ if(g_fDumpTokens)
+ {
+ char tmp[16];
+ sprintf_s(tmp,COUNTOF(tmp),"/*%08X*/",tk);
+ appendStr(out,COMMENT(tmp));
+ }
+ }
+ break;
+
+ case mdtAssemblyRef:
+ {
+ LPCSTR szName = NULL;
+#ifdef __ILDASM__
+ if (rAsmRefName && (RidFromToken(tk) <= ulNumAsmRefs))
+ {
+ szName = rAsmRefName[RidFromToken(tk)-1];
+ }
+ else
+#endif
+ {
+ if (FAILED(pIMDI->GetAssemblyRefProps(tk,NULL,NULL,&szName,NULL,NULL,NULL,NULL)))
+ {
+ szName = NULL;
+ }
+ }
+ if ((szName != NULL) && ((*szName) != 0 ))
+ {
+ appendChar(out, '[');
+ appendStr(out,JUMPPT(ProperName(szName),tk));
+ if(g_fDumpTokens)
+ {
+ char tmp[16];
+ sprintf_s(tmp,COUNTOF(tmp),"/*%08X*/",tk);
+ appendStr(out,COMMENT(tmp));
+ }
+ appendChar(out, ']');
+ }
+ }
+ break;
+ case mdtAssembly:
+ {
+ LPCSTR szName;
+ if (FAILED(pIMDI->GetAssemblyProps(tk,NULL,NULL,NULL,&szName,NULL,NULL)))
+ {
+ szName = NULL;
+ }
+ if ((szName != NULL) && ((*szName) != 0))
+ {
+ appendChar(out, '[');
+ appendStr(out,JUMPPT(ProperName(szName),tk));
+ if(g_fDumpTokens)
+ {
+ char tmp[16];
+ sprintf_s(tmp,COUNTOF(tmp),"/* %08X */",tk);
+ appendStr(out,COMMENT(tmp));
+ }
+ appendChar(out, ']');
+ }
+ }
+ break;
+ case mdtModuleRef:
+ {
+ LPCSTR szName;
+ if (FAILED(pIMDI->GetModuleRefProps(tk, &szName)))
+ {
+ szName = NULL;
+ }
+ if ((szName != NULL) && ((*szName) != 0))
+ {
+ appendChar(out, '[');
+ appendStr(out,KEYWORD(".module "));
+ appendStr(out,JUMPPT(ProperName(szName),tk));
+ if(g_fDumpTokens)
+ {
+ char tmp[16];
+ sprintf_s(tmp,COUNTOF(tmp),"/*%08X*/",tk);
+ appendStr(out,COMMENT(tmp));
+ }
+ appendChar(out, ']');
+ }
+ }
+ break;
+
+ case mdtTypeSpec:
+ {
+#ifdef __ILDASM__
+ DWORD ix;
+ for(ix = 0; ix < g_NumTypedefs; ix++)
+ {
+ if((*g_typedefs)[ix].tkTypeSpec == tk) break;
+ }
+ if(ix < g_NumTypedefs)
+ {
+ appendStr(out,JUMPPT(ProperName((*g_typedefs)[ix].szName),(*g_typedefs)[ix].tkSelf));
+ }
+ else
+#endif
+ {
+ ULONG cSig;
+ PCCOR_SIGNATURE sig;
+ if (FAILED(pIMDI->GetSigFromToken(tk, &cSig, &sig)))
+ {
+ char tmp[64];
+ sprintf_s(tmp, COUNTOF(tmp), "/*Invalid %08X record*/", tk);
+ appendStr(out, COMMENT(tmp));
+ }
+ else
+ {
+ PrettyPrintType(sig, out, pIMDI);
+ }
+ }
+ if(g_fDumpTokens)
+ {
+ char tmp[16];
+ sprintf_s(tmp,COUNTOF(tmp),"/*%08X*/",tk);
+ appendStr(out,COMMENT(tmp));
+ }
+ }
+ break;
+
+ case mdtModule:
+ break;
+
+ default:
+ {
+ char str[128];
+ sprintf_s(str,COUNTOF(str)," [ERROR: INVALID TOKEN TYPE 0x%8.8X] ",tk);
+ appendStr(out,ERRORMSG(str));
+ }
+ }
+ return(asString(out));
+}
+
+const char* TrySigUncompressAndDumpSimpleNativeType(
+ PCCOR_SIGNATURE pData, // [IN] compressed data
+ ULONG *pDataOut, // [OUT] the expanded *pData
+ ULONG &cbCur,
+ SString &buf)
+{
+ const char* sz = NULL;
+ ULONG ulSize = CorSigUncompressData(pData, pDataOut);
+ if (ulSize != (ULONG)-1)
+ {
+ switch (*pDataOut)
+ {
+ case NATIVE_TYPE_VOID: sz = " void"; break;
+ case NATIVE_TYPE_BOOLEAN: sz = " bool"; break;
+ case NATIVE_TYPE_I1: sz = " int8"; break;
+ case NATIVE_TYPE_U1: sz = " unsigned int8"; break;
+ case NATIVE_TYPE_I2: sz = " int16"; break;
+ case NATIVE_TYPE_U2: sz = " unsigned int16"; break;
+ case NATIVE_TYPE_I4: sz = " int32"; break;
+ case NATIVE_TYPE_U4: sz = " unsigned int32"; break;
+ case NATIVE_TYPE_I8: sz = " int64"; break;
+ case NATIVE_TYPE_U8: sz = " unsigned int64"; break;
+ case NATIVE_TYPE_R4: sz = " float32"; break;
+ case NATIVE_TYPE_R8: sz = " float64"; break;
+ case NATIVE_TYPE_SYSCHAR: sz = " syschar"; break;
+ case NATIVE_TYPE_VARIANT: sz = " variant"; break;
+ case NATIVE_TYPE_CURRENCY: sz = " currency"; break;
+ case NATIVE_TYPE_DECIMAL: sz = " decimal"; break;
+ case NATIVE_TYPE_DATE: sz = " date"; break;
+ case NATIVE_TYPE_BSTR: sz = " bstr"; break;
+ case NATIVE_TYPE_LPSTR: sz = " lpstr"; break;
+ case NATIVE_TYPE_LPWSTR: sz = " lpwstr"; break;
+ case NATIVE_TYPE_LPTSTR: sz = " lptstr"; break;
+ case NATIVE_TYPE_OBJECTREF: sz = " objectref"; break;
+ case NATIVE_TYPE_STRUCT: sz = " struct"; break;
+ case NATIVE_TYPE_ERROR: sz = " error"; break;
+ case NATIVE_TYPE_INT: sz = " int"; break;
+ case NATIVE_TYPE_UINT: sz = " uint"; break;
+ case NATIVE_TYPE_NESTEDSTRUCT: sz = " nested struct"; break;
+ case NATIVE_TYPE_BYVALSTR: sz = " byvalstr"; break;
+ case NATIVE_TYPE_ANSIBSTR: sz = " ansi bstr"; break;
+ case NATIVE_TYPE_TBSTR: sz = " tbstr"; break;
+ case NATIVE_TYPE_VARIANTBOOL: sz = " variant bool"; break;
+ case NATIVE_TYPE_FUNC: sz = " method"; break;
+ case NATIVE_TYPE_ASANY: sz = " as any"; break;
+ case NATIVE_TYPE_LPSTRUCT: sz = " lpstruct"; break;
+ case NATIVE_TYPE_PTR:
+ case NATIVE_TYPE_SAFEARRAY:
+ case NATIVE_TYPE_ARRAY:
+ case NATIVE_TYPE_FIXEDSYSSTRING:
+ case NATIVE_TYPE_FIXEDARRAY:
+ case NATIVE_TYPE_INTF:
+ case NATIVE_TYPE_IUNKNOWN:
+ case NATIVE_TYPE_IDISPATCH:
+ case NATIVE_TYPE_CUSTOMMARSHALER:
+ case NATIVE_TYPE_END:
+ case NATIVE_TYPE_MAX:
+ sz = ""; break;
+ default: sz = NULL;
+ }
+ }
+ if (sz)
+ cbCur += ulSize;
+ else
+ buf.Clear();
+
+ return sz;
+}
+
+bool TrySigUncompress(PCCOR_SIGNATURE pData, // [IN] compressed data
+ ULONG *pDataOut, // [OUT] the expanded *pData
+ ULONG &cbCur,
+ SString &buf)
+{
+ ULONG ulSize = CorSigUncompressData(pData, pDataOut);
+ if (ulSize == (ULONG)-1)
+ {
+ buf.Clear();
+ return false;
+ } else
+ {
+ cbCur += ulSize;
+ return true;
+ }
+}
+
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
+char* DumpMarshaling(IMDInternalImport* pImport,
+ __inout_ecount(cchszString) char* szString,
+ DWORD cchszString,
+ mdToken tok)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ PCCOR_SIGNATURE pSigNativeType = NULL;
+ ULONG cbNativeType = 0;
+ SString buf;
+ if (RidFromToken(tok) &&
+ SUCCEEDED(pImport->GetFieldMarshal( // return error if no native type associate with the token
+ tok, // [IN] given fielddef
+ &pSigNativeType, // [OUT] the native type signature
+ &cbNativeType))) // [OUT] the count of bytes of *ppvNativeType
+ {
+ ULONG cbCur = 0;
+ ULONG ulData;
+ const char *sz = NULL;
+ BOOL fAddAsterisk = FALSE, fAddBrackets = FALSE;
+ buf.AppendPrintf(" %s(", KEYWORD("marshal"));
+ while (cbCur < cbNativeType)
+ {
+ ulData = NATIVE_TYPE_MAX;
+ sz = TrySigUncompressAndDumpSimpleNativeType(&pSigNativeType[cbCur], &ulData, cbCur, buf);
+ if (!sz)
+ goto error;
+ if(*sz == 0)
+ {
+ switch (ulData)
+ {
+ case NATIVE_TYPE_PTR:
+ sz = "";
+ fAddAsterisk = TRUE;
+ break;
+ case NATIVE_TYPE_SAFEARRAY:
+ sz = "";
+ buf.AppendASCII(KEYWORD(" safearray"));
+ ulData = VT_EMPTY;
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ }
+ switch(ulData & VT_TYPEMASK)
+ {
+ case VT_EMPTY: sz=""; break;
+ case VT_NULL: sz=" null"; break;
+ case VT_VARIANT: sz=" variant"; break;
+ case VT_CY: sz=" currency"; break;
+ case VT_VOID: sz=" void"; break;
+ case VT_BOOL: sz=" bool"; break;
+ case VT_I1: sz=" int8"; break;
+ case VT_I2: sz=" int16"; break;
+ case VT_I4: sz=" int32"; break;
+ case VT_I8: sz=" int64"; break;
+ case VT_R4: sz=" float32"; break;
+ case VT_R8: sz=" float64"; break;
+ case VT_UI1: sz=" unsigned int8"; break;
+ case VT_UI2: sz=" unsigned int16"; break;
+ case VT_UI4: sz=" unsigned int32"; break;
+ case VT_UI8: sz=" unsigned int64"; break;
+ case VT_PTR: sz=" *"; break;
+ case VT_DECIMAL: sz=" decimal"; break;
+ case VT_DATE: sz=" date"; break;
+ case VT_BSTR: sz=" bstr"; break;
+ case VT_LPSTR: sz=" lpstr"; break;
+ case VT_LPWSTR: sz=" lpwstr"; break;
+ case VT_UNKNOWN: sz=" iunknown"; break;
+ case VT_DISPATCH: sz=" idispatch"; break;
+ case VT_SAFEARRAY: sz=" safearray"; break;
+ case VT_INT: sz=" int"; break;
+ case VT_UINT: sz=" unsigned int"; break;
+ case VT_ERROR: sz=" error"; break;
+ case VT_HRESULT: sz=" hresult"; break;
+ case VT_CARRAY: sz=" carray"; break;
+ case VT_USERDEFINED: sz=" userdefined"; break;
+ case VT_RECORD: sz=" record"; break;
+ case VT_FILETIME: sz=" filetime"; break;
+ case VT_BLOB: sz=" blob"; break;
+ case VT_STREAM: sz=" stream"; break;
+ case VT_STORAGE: sz=" storage"; break;
+ case VT_STREAMED_OBJECT: sz=" streamed_object"; break;
+ case VT_STORED_OBJECT: sz=" stored_object"; break;
+ case VT_BLOB_OBJECT: sz=" blob_object"; break;
+ case VT_CF: sz=" cf"; break;
+ case VT_CLSID: sz=" clsid"; break;
+ default: sz=NULL; break;
+ }
+ if(sz) buf.AppendASCII(KEYWORD(sz));
+ else
+ {
+ // buf.AppendPrintf(ERRORMSG(" [ILLEGAL VARIANT TYPE 0x%X]"),ulData & VT_TYPEMASK);
+ buf.Clear();
+ goto error;
+ }
+ sz="";
+ switch(ulData & (~VT_TYPEMASK))
+ {
+ case VT_ARRAY: sz = "[]"; break;
+ case VT_VECTOR: sz = " vector"; break;
+ case VT_BYREF: sz = "&"; break;
+ case VT_BYREF|VT_ARRAY: sz = "&[]"; break;
+ case VT_BYREF|VT_VECTOR: sz = "& vector"; break;
+ case VT_ARRAY|VT_VECTOR: sz = "[] vector"; break;
+ case VT_BYREF|VT_ARRAY|VT_VECTOR: sz = "&[] vector"; break;
+ }
+ buf.AppendASCII(KEYWORD(sz));
+ sz="";
+
+ // Extract the user defined sub type name.
+ if (cbCur < cbNativeType)
+ {
+ LPUTF8 strTemp = NULL;
+ int strLen = 0;
+ int ByteCountLength = 0;
+ strLen = GetLength(&pSigNativeType[cbCur], &ByteCountLength);
+ cbCur += ByteCountLength;
+ if(strLen)
+ {
+#ifdef _PREFAST_
+#pragma prefast(push)
+#pragma prefast(disable:22009 "Suppress PREFAST warnings about integer overflow")
+#endif
+ strTemp = (LPUTF8)_alloca(strLen + 1);
+ memcpy(strTemp, (LPUTF8)&pSigNativeType[cbCur], strLen);
+ strTemp[strLen] = 0;
+ buf.AppendPrintf(", \"%s\"", UnquotedProperName(strTemp));
+ cbCur += strLen;
+#ifdef _PREFAST_
+#pragma prefast(pop)
+#endif
+ }
+ }
+ break;
+
+ case NATIVE_TYPE_ARRAY:
+ sz = "";
+ fAddBrackets = TRUE;
+ break;
+ case NATIVE_TYPE_FIXEDSYSSTRING:
+ {
+ sz = "";
+ buf.AppendASCII(KEYWORD(" fixed sysstring"));
+ buf.AppendASCII(" [");
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ buf.AppendPrintf("%d",ulData);
+ }
+ buf.AppendASCII("]");
+ }
+ break;
+ case NATIVE_TYPE_FIXEDARRAY:
+ {
+ sz = "";
+ buf.AppendASCII(KEYWORD(" fixed array"));
+ buf.AppendASCII(" [");
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ buf.AppendPrintf("%d",ulData);
+ }
+ buf.AppendASCII("]");
+ if (cbCur < cbNativeType)
+ {
+ sz = TrySigUncompressAndDumpSimpleNativeType(&pSigNativeType[cbCur], &ulData, cbCur, buf);
+ if (!sz)
+ goto error;
+ }
+ }
+ break;
+
+ case NATIVE_TYPE_INTF:
+ buf.AppendASCII(KEYWORD(" interface"));
+ goto DumpIidParamIndex;
+ case NATIVE_TYPE_IUNKNOWN:
+ buf.AppendASCII(KEYWORD(" iunknown"));
+ goto DumpIidParamIndex;
+ case NATIVE_TYPE_IDISPATCH:
+ buf.AppendASCII(KEYWORD(" idispatch"));
+ DumpIidParamIndex:
+ sz = " ";
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ buf.AppendPrintf("(%s = %d)",KEYWORD("iidparam"),ulData);
+ }
+ break;
+
+ case NATIVE_TYPE_CUSTOMMARSHALER:
+ {
+ LPUTF8 strTemp = NULL;
+ int strLen = 0;
+ int ByteCountLength = 0;
+ BOOL fFourStrings = FALSE;
+
+ sz = "";
+ buf.AppendASCII(KEYWORD(" custom"));
+ buf.AppendASCII(" (");
+ // Extract the typelib GUID.
+ strLen = GetLength(&pSigNativeType[cbCur], &ByteCountLength);
+ cbCur += ByteCountLength;
+ if(strLen)
+ {
+ fFourStrings = TRUE;
+ strTemp = (LPUTF8)(new char[strLen + 1]);
+ if(strTemp)
+ {
+ memcpy(strTemp, (LPUTF8)&pSigNativeType[cbCur], strLen);
+ strTemp[strLen] = 0;
+ buf.AppendPrintf("\"%s\",",UnquotedProperName(strTemp));
+ cbCur += strLen;
+ VDELETE(strTemp);
+ }
+ }
+ if(cbCur >= cbNativeType)
+ {
+ // buf.AppendASCII(ERRORMSG("/* INCOMPLETE MARSHALER INFO */"));
+ buf.Clear();
+ goto error;
+ }
+ else
+ {
+ //_ASSERTE(cbCur < cbNativeType);
+
+ // Extract the name of the native type.
+ strLen = GetLength(&pSigNativeType[cbCur], &ByteCountLength);
+ cbCur += ByteCountLength;
+ if(fFourStrings)
+ {
+ if(strLen)
+ {
+ strTemp = (LPUTF8)(new char[strLen + 1]);
+ if(strTemp)
+ {
+ memcpy(strTemp, (LPUTF8)&pSigNativeType[cbCur], strLen);
+ strTemp[strLen] = 0;
+ buf.AppendPrintf("\"%s\",",UnquotedProperName(strTemp));
+ cbCur += strLen;
+ VDELETE(strTemp);
+ }
+ }
+ else buf.AppendASCII("\"\",");
+ }
+ if(cbCur >= cbNativeType)
+ {
+ // buf.AppendASCII(ERRORMSG("/* INCOMPLETE MARSHALER INFO */"));
+ buf.Clear();
+ goto error;
+ }
+ else
+ {
+ //_ASSERTE(cbCur < cbNativeType);
+
+ // Extract the name of the custom marshaler.
+ strLen = GetLength(&pSigNativeType[cbCur], &ByteCountLength);
+ cbCur += ByteCountLength;
+ if(strLen)
+ {
+ strTemp = (LPUTF8)(new char[strLen + 1]);
+ if(strTemp)
+ {
+ memcpy(strTemp, (LPUTF8)&pSigNativeType[cbCur], strLen);
+ strTemp[strLen] = 0;
+ buf.AppendPrintf("\"%s\",",UnquotedProperName(strTemp));
+ cbCur += strLen;
+ VDELETE(strTemp);
+ }
+ }
+ else buf.AppendASCII("\"\",");
+ if(cbCur >= cbNativeType)
+ {
+ // buf.AppendASCII(ERRORMSG("/* INCOMPLETE MARSHALER INFO */"));
+ buf.Clear();
+ goto error;
+ }
+ else
+ {
+ // Extract the cookie string.
+ strLen = GetLength(&pSigNativeType[cbCur], &ByteCountLength);
+ cbCur += ByteCountLength;
+
+ if(cbCur+strLen > cbNativeType)
+ {
+ // buf.AppendASCII(ERRORMSG("/* INCOMPLETE MARSHALER INFO */"));
+ buf.Clear();
+ goto error;
+ }
+ else
+ {
+ if(strLen)
+ {
+ strTemp = (LPUTF8)(new (nothrow) char[strLen + 1]);
+ if(strTemp)
+ {
+ memcpy(strTemp, (LPUTF8)&pSigNativeType[cbCur], strLen);
+ strTemp[strLen] = 0;
+
+ buf.AppendASCII("\"");
+ // Copy the cookie string and transform the embedded nulls into \0's.
+ for (int i = 0; i < strLen - 1; i++, cbCur++)
+ {
+ if (strTemp[i] == 0)
+ buf.AppendASCII("\\0");
+ else
+ {
+ buf.AppendPrintf("%c", strTemp[i]);
+ }
+ }
+ buf.AppendPrintf("%c\"", strTemp[strLen - 1]);
+ cbCur++;
+ VDELETE(strTemp);
+ }
+ }
+ else
+ buf.AppendASCII("\"\"");
+ //_ASSERTE(cbCur <= cbNativeType);
+ }
+ }
+ }
+ }
+ buf.AppendASCII(")");
+ }
+ break;
+ default:
+ {
+ sz = "";
+ }
+ } // end switch
+ }
+ if(*sz)
+ {
+ buf.AppendASCII(KEYWORD(sz));
+ if(fAddAsterisk)
+ {
+ buf.AppendASCII("*");
+ fAddAsterisk = FALSE;
+ }
+ if(fAddBrackets)
+ {
+ ULONG ulSizeParam=(ULONG)-1,ulSizeConst=(ULONG)-1;
+ buf.AppendASCII("[");
+ fAddBrackets = FALSE;
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ ulSizeParam = ulData;
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ ulSizeConst = ulData;
+ if (cbCur < cbNativeType)
+ {
+ // retrieve flags
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ if((ulData & 1) == 0) ulSizeParam = 0xFFFFFFFF;
+ }
+ }
+ }
+ if(ulSizeConst != 0xFFFFFFFF)
+ {
+ buf.AppendPrintf("%d",ulSizeConst);
+ // if(ulSizeParam == 0) ulSizeParam = 0xFFFFFFFF; // don't need +0
+ }
+ if(ulSizeParam != 0xFFFFFFFF)
+ {
+ buf.AppendPrintf(" + %d",ulSizeParam);
+ }
+ buf.AppendASCII("]");
+ }
+
+ }
+
+ if (ulData >= NATIVE_TYPE_MAX)
+ break;
+ } // end while (cbCur < cbNativeType)
+ // still can have outstanding asterisk or brackets
+ if(fAddAsterisk)
+ {
+ buf.AppendASCII("*");
+ fAddAsterisk = FALSE;
+ }
+ if(fAddBrackets)
+ {
+ ULONG ulSizeParam=(ULONG)-1,ulSizeConst=(ULONG)-1;
+ buf.AppendASCII("[");
+ fAddBrackets = FALSE;
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ ulSizeParam = ulData;
+ if (cbCur < cbNativeType)
+ {
+ if (!TrySigUncompress(&pSigNativeType[cbCur], &ulData, cbCur, buf))
+ goto error;
+ ulSizeConst = ulData;
+ }
+ }
+ if(ulSizeConst != 0xFFFFFFFF)
+ {
+ buf.AppendPrintf("%d",ulSizeConst);
+ // if(ulSizeParam == 0) ulSizeParam = 0xFFFFFFFF; // don't need +0
+ }
+ if(ulSizeParam != 0xFFFFFFFF)
+ {
+ buf.AppendPrintf(" + %d",ulSizeParam);
+ }
+ buf.AppendASCII("]");
+ }
+ buf.AppendASCII(") ");
+ }// end if(SUCCEEDED
+error:
+ if (buf.IsEmpty() && cbNativeType != 0)
+ {
+ // There was something that we didn't grok in the signature.
+ // Just dump out the blob as hex
+ buf.AppendPrintf(" %s({", KEYWORD("marshal"));
+ while (cbNativeType--)
+ buf.AppendPrintf(" %2.2X", *pSigNativeType++);
+ buf.AppendASCII(" }) ");
+
+ char * tgt = szString + strlen(szString);
+ int sprintf_ret = sprintf_s(tgt, cchszString - (tgt - szString), "%S", buf.GetUnicode());
+ if (sprintf_ret == -1)
+ {
+ // Hit an error. Oh well, nothing to do...
+ return tgt;
+ }
+ else
+ {
+ return tgt + sprintf_ret;
+ }
+ }
+ else
+ {
+ char * tgt = szString + strlen(szString);
+ int sprintf_ret = sprintf_s(tgt, cchszString - (tgt - szString), "%S", buf.GetUnicode());
+ if (sprintf_ret == -1)
+ {
+ // There was an error, possibly with converting the Unicode characters.
+ buf.Clear();
+ if (cbNativeType != 0)
+ goto error;
+ return tgt; // Oh well, nothing to do...
+ }
+ else
+ {
+ return tgt + sprintf_ret;
+ }
+ }
+}
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+char* DumpParamAttr(__inout_ecount(cchszString) char* szString, DWORD cchszString, DWORD dwAttr)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ char *szptr = &szString[strlen(szString)];
+ char *was_szptr = szptr;
+ if(IsPdIn(dwAttr))
+ {
+ szptr+=sprintf_s(szptr,cchszString - (szptr - was_szptr), KEYWORD("[in]"));
+ }
+ if(IsPdOut(dwAttr))
+ {
+ szptr+=sprintf_s(szptr,cchszString - (szptr - was_szptr),KEYWORD("[out]"));
+ }
+ if(IsPdOptional(dwAttr))
+ {
+ szptr+=sprintf_s(szptr,cchszString - (szptr - was_szptr),KEYWORD("[opt]"));
+ }
+ if(szptr != was_szptr)
+ {
+ szptr+=sprintf_s(szptr,cchszString - (szptr - was_szptr)," ");
+ }
+ return szptr;
+}