Ejemplo n.º 1
0
// _skipFunkyModifiersInSignature will skip the modifiers that
// we don't care about.  Everything we care about is listed as
// a case in CreateValueByType.  Specifically, we care about:
ULONG _skipFunkyModifiersInSignature(PCCOR_SIGNATURE sig)
{
    ULONG cb = 0;
    ULONG skippedCB = 0;
    ULONG elementType;

    // Need to skip all funky modifiers in the signature to get us to
    // the first bit of good stuff.
    do
    {
        cb = CorSigUncompressData(&sig[skippedCB], &elementType);

        switch( elementType )
        {
        case ELEMENT_TYPE_CMOD_REQD:
        case ELEMENT_TYPE_CMOD_OPT:
            {    
                mdToken typeRef;
                skippedCB += cb;
                skippedCB += CorSigUncompressToken(&sig[skippedCB], &typeRef);

                break;
            }
        case ELEMENT_TYPE_MAX:
            {
                _ASSERTE( !"_skipFunkyModifiersInSignature:Given an invalid type!" );
                break;
            }
        
        case ELEMENT_TYPE_MODIFIER:
        case ELEMENT_TYPE_PINNED:
            {
                // Since these are all followed by another ELEMENT_TYPE,
                // we're done.
                skippedCB += cb;
                break;
            }
        default:
            {
                // Since we didn't find any modifiers, don't skip 
                // anything.
                cb = 0;
                break;
            }
        }
    } while (cb > 0);

    return skippedCB;
}
Ejemplo n.º 2
0
//PrettyPrinting type names
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
    DWORD formatFlags /*= formatILDasm*/)
{
    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, (char*)str);
                break;  

            case ELEMENT_TYPE_VALUETYPE    :   
                if ((formatFlags & FormatKwInNames) != 0) 
                    str = "valuetype ";   
                else str = "";
                goto DO_CLASS;  
            case ELEMENT_TYPE_CLASS         :   
                if ((formatFlags & FormatKwInNames) != 0) 
                    str = "class "; 
                else str = "";
                goto DO_CLASS;  

            DO_CLASS:
                appendStr(out, (char*)str);
                typePtr += CorSigUncompressToken(typePtr, &tk); 
                if(IsNilToken(tk))
                {
                    appendStr(out, "[ERROR! NIL TOKEN]");
                }
                else PrettyPrintClass(out, tk, pIMDI, formatFlags);
                break;  

            case ELEMENT_TYPE_SZARRAY    :   
                insertStr(&Appendix,"[]");
                Reiterate = TRUE;
                break;
            
            case ELEMENT_TYPE_ARRAY       :   
                {   
                typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
                unsigned rank = CorSigUncompressData(typePtr);  
                    // <TODO> what is the syntax for the rank 0 case? </TODO> 
                if (rank == 0) {
                    appendStr(out, "[BAD: RANK == 0!]");
                }
                else {
                    _ASSERTE(rank != 0);
#ifdef _PREFAST_
#pragma warning(push)
#pragma warning(disable:22009) // "Suppress PREfast warnings about integer overflow"
// PREFAST warns about using _alloca in a loop.  However when we're in this switch case we do NOT
// set Reiterate to true, so we only execute through the loop once!
#pragma warning(disable:6263) // "Suppress PREfast warnings about stack overflow due to _alloca in a loop."
#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 warning(pop)
#endif
                }
                } break;    

            case ELEMENT_TYPE_VAR        :   
                appendChar(out, '!');
                n  = CorSigUncompressData(typePtr);
                appendStrNum(out, n);
                break;

            case ELEMENT_TYPE_MVAR        :   
                appendChar(out, '!');    
                appendChar(out, '!');    
                n  = CorSigUncompressData(typePtr);
                appendStrNum(out, n);
                break;

            case ELEMENT_TYPE_FNPTR :   
                appendStr(out, "method ");  
                appendStr(out, "METHOD"); // was: typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL);
                break;

            case ELEMENT_TYPE_GENERICINST :
            {
              typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
              if ((formatFlags & FormatSignature) == 0)
                  break;

              if ((formatFlags & FormatAngleBrackets) != 0)
                  appendStr(out, "<");
              else
                  appendStr(out,"[");
              unsigned numArgs = CorSigUncompressData(typePtr);    
              bool needComma = false;
              while(numArgs--)
              {
                  if (needComma)
                      appendChar(out, ',');
                  typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
                  needComma = true;
              }
              if ((formatFlags & FormatAngleBrackets) != 0)
                  appendStr(out, ">");
              else
                  appendStr(out,"]");
              break;
            }

            case ELEMENT_TYPE_PINNED	:
                str = " pinned"; goto MODIFIER;
            case ELEMENT_TYPE_PTR           :
                str = "*"; goto MODIFIER;
            case ELEMENT_TYPE_BYREF         :
                str = "&"; 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, sz);
                }
                break;  
        } // end switch
    } while(Reiterate);
    if (Appendix.Size() > 0)
        appendStr(out,asString(&Appendix));

    return(typePtr);    
}
Ejemplo n.º 3
0
bool SignatureReader::ReadType(byte type)
{
    /*
    Type ::= ( BOOLEAN | CHAR | I1 | U1 | U2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | I | U |
                    | VALUETYPE TypeDefOrRefEncoded
                    | CLASS TypeDefOrRefEncoded
                    | STRING 
                    | OBJECT
                    | PTR CustomMod* VOID
                    | PTR CustomMod* Type
                    | FNPTR MethodDefSig
                    | FNPTR MethodRefSig
                    | ARRAY Type ArrayShape
                    | SZARRAY CustomMod* Type
                    | GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount Type *
                    | VAR Number
                    | MVAR Number
    */

	switch (type) {
		case ELEMENT_TYPE_VOID:
			this->output << L"void";
			break;
		case ELEMENT_TYPE_BOOLEAN:
			this->output << L"bool";
			break;
		case ELEMENT_TYPE_CHAR:
			this->output << L"char"; 
			break;
		case ELEMENT_TYPE_I:
			this->output << L"IntPtr";
			break;
		case ELEMENT_TYPE_U:
			this->output << L"UIntPtr";
			break;
		case ELEMENT_TYPE_I1:
			this->output << L"sbyte"; 
			break;
		case ELEMENT_TYPE_U1:
			this->output << L"byte"; 
			break;
		case ELEMENT_TYPE_I2:
			this->output << L"short"; 
			break;
		case ELEMENT_TYPE_U2:
			this->output << L"ushort"; 
			break;
		case ELEMENT_TYPE_I4:
			this->output << L"int"; 
			break;
		case ELEMENT_TYPE_U4:
			this->output << L"uint"; 
			break;
		case ELEMENT_TYPE_I8:
			this->output << L"long"; 
			break;
		case ELEMENT_TYPE_U8:
			this->output << L"ulong"; 
			break;
		case ELEMENT_TYPE_R4:
			this->output << L"float"; 
			break;
		case ELEMENT_TYPE_R8:
			this->output << L"double"; 
			break;
		case ELEMENT_TYPE_STRING:
			this->output << L"string"; 
			break;
		case ELEMENT_TYPE_OBJECT:
			this->output << L"object";
			break;
		case ELEMENT_TYPE_CLASS:
		case ELEMENT_TYPE_VALUETYPE:
			mdToken token;
			WCHAR zName[1024];
			ULONG length;
			CorSigUncompressToken(this->data, &token);
			HRESULT	hr;
			hr = this->metaData->GetTypeRefProps(token, nullptr, zName, 1024, &length);
			hr = this->metaData->GetTypeDefProps(token, zName, 1024, &length, nullptr, nullptr);
			if (SUCCEEDED(hr) && length > 0)
				AppendEscapedString(zName);
			else {
				hr = this->metaData->GetTypeRefProps(token, nullptr, zName, 1024, &length);
				hr = this->metaData->GetTypeDefProps(token, zName, 1024, &length, nullptr, nullptr);
				if (SUCCEEDED(hr) && length > 0)
					AppendEscapedString(zName);
				else
					this->output << L"?";
			}
			int tmp2;
			if (!this->ReadCompressedInt(&tmp2))
				return false;
			break;
		case ELEMENT_TYPE_ARRAY:
		case ELEMENT_TYPE_SZARRAY:
			this->ReadArrayType(type);
			break;
		case ELEMENT_TYPE_CMOD_OPT:
		case ELEMENT_TYPE_CMOD_REQD:
			this->output << L"cmod";
			break;
		case ELEMENT_TYPE_FNPTR:
			this->output << L"fnptr";
			break;
		case ELEMENT_TYPE_PTR:
			if (!this->ReadByte(&type))
				return false;
			while (type == ELEMENT_TYPE_CMOD_OPT || type == ELEMENT_TYPE_CMOD_REQD) {
				int tmp2;

				if (!this->ReadCompressedInt(&tmp2))
					return false;

				if (!this->ReadByte(&type))
					return false;
			}

			ReadType(type);
			this->output << L"*";
			break;
		case ELEMENT_TYPE_GENERICINST:
			if (!this->ReadByte(&type))
				return false;
			CorSigUncompressToken(this->data, &token);
			// don't ask me why this is necessary, but it doesn't work without either line of these.
			hr = this->metaData->GetTypeRefProps(token, nullptr, zName, 1024, &length);
			hr = this->metaData->GetTypeDefProps(token, zName, 1024, &length, nullptr, nullptr);
			if (SUCCEEDED(hr) && length > 0)
				AppendEscapedString(zName);
			else
				this->output << L"?";
			if (!this->ReadCompressedInt(&tmp2))
				return false;
			this->output << L"<";
			int genArgCount;
			if (!this->ReadCompressedInt(&genArgCount))
				return false;
			for (int i = 0; i < genArgCount; i++) {
				if (!this->ReadByte(&type))
					return false;
				this->ReadType(type);
				if ((i + 1) < genArgCount)
					this->output << L",";
			}
			this->output << L">";
			break;
		case ELEMENT_TYPE_MVAR: // print "!!number"
			this->output << L"!";
		case ELEMENT_TYPE_VAR: // print "!number"
			this->output << L"!"; 
			int number;
			if (!this->ReadCompressedInt(&number))
				return false;
			this->output << number;
			break;
		default:
			this->output << L"?";
			break;
	}

	return true;
}
Ejemplo n.º 4
0
HRESULT _CountBytesOfOneArg(
    PCCOR_SIGNATURE pbSig,
    ULONG       *pcbTotal)  // Initially, *pcbTotal contains the remaining size of the sig blob
{
    ULONG       cb;
    ULONG       cbTotal=0;
    ULONG       cbTotalMax;
    CorElementType ulElementType;
    ULONG       ulData;
    ULONG       ulTemp;
    int         iData;
    mdToken     tk;
    ULONG       cArg;
    ULONG       callingconv;
    ULONG       cArgsIndex;
    HRESULT     hr = NOERROR;

    if(pcbTotal==NULL) return E_FAIL;
    cbTotalMax = *pcbTotal;

    CHECK_REMAINDER;
    cbTotal = CorSigUncompressElementType(pbSig, &ulElementType);
    while (CorIsModifierElementType((CorElementType) ulElementType))
    {
        CHECK_REMAINDER;
        cbTotal += CorSigUncompressElementType(&pbSig[cbTotal], &ulElementType);
    }
    switch (ulElementType)
    {
        case ELEMENT_TYPE_SZARRAY:
        case 0x1e /* obsolete */:
            // skip over base type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
            cbTotal += cb;
            break;

        case ELEMENT_TYPE_FNPTR:
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData (&pbSig[cbTotal], &callingconv);

            // remember number of bytes to represent the arg counts
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData (&pbSig[cbTotal], &cArg);

            // how many bytes to represent the return type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) );
            cbTotal += cb;

            // loop through argument
            for (cArgsIndex = 0; cArgsIndex < cArg; cArgsIndex++)
            {
                CHECK_REMAINDER;
                cb = cbTotalMax - cbTotal;
                IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) );
                cbTotal += cb;
            }

            break;

        case ELEMENT_TYPE_ARRAY:
            // syntax : ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j]

            // skip over base type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
            cbTotal += cb;

            // Parse for the rank
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);

            // if rank == 0, we are done
            if (ulData == 0)
                break;

            // any size of dimension specified?
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);
            while (ulData--)
            {
                CHECK_REMAINDER;
                cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulTemp);
            }

            // any lower bound specified?
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);

            while (ulData--)
            {
                CHECK_REMAINDER;
                cbTotal += CorSigUncompressSignedInt(&pbSig[cbTotal], &iData);
            }

            break;
        case ELEMENT_TYPE_VALUETYPE:
        case ELEMENT_TYPE_CLASS:
        case ELEMENT_TYPE_CMOD_REQD:
        case ELEMENT_TYPE_CMOD_OPT:
            // count the bytes for the token compression
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressToken(&pbSig[cbTotal], &tk);
            if ( ulElementType == ELEMENT_TYPE_CMOD_REQD ||
                 ulElementType == ELEMENT_TYPE_CMOD_OPT)
            {
                // skip over base type
                CHECK_REMAINDER;
                cb = cbTotalMax - cbTotal;
                IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
                cbTotal += cb;
            }
            break;
        default:
            break;
    }

    *pcbTotal = cbTotal;
ErrExit:
    return hr;
}
Ejemplo n.º 5
0
unsigned SizeOfField(PCCOR_SIGNATURE *ppSig, ULONG cSig, IMDInternalImport* pImport)
{
	unsigned ret = 0xFFFFFFFF;
	if(ppSig && *ppSig && cSig && pImport)
	{
        unsigned callConv = CorSigUncompressData(*ppSig);  
        if (isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_FIELD))
        {
			mdToken  tk;    
			int typ;
			BOOL Reiterate;
			unsigned uElementNumber = 1;
			PCCOR_SIGNATURE pSigOrig = *ppSig;
			PCCOR_SIGNATURE pSigEnd = *ppSig+cSig;

			do {
				Reiterate = FALSE;
				switch(typ = *(*ppSig)++) {    
					case ELEMENT_TYPE_VOID          :   
						return 0;
						
					case ELEMENT_TYPE_I1            :   
					case ELEMENT_TYPE_U1            :   
					case ELEMENT_TYPE_BOOLEAN       :   
						return uElementNumber; 

					case ELEMENT_TYPE_CHAR          :   
					case ELEMENT_TYPE_I2            :   
					case ELEMENT_TYPE_U2            :   
						return (uElementNumber << 1); 

					case ELEMENT_TYPE_I4            :   
					case ELEMENT_TYPE_U4            :   
					case ELEMENT_TYPE_R4            :   
						return (uElementNumber << 2); 
						
					case ELEMENT_TYPE_I8            :   
					case ELEMENT_TYPE_U8            :   
					case ELEMENT_TYPE_R8            :   
						return (uElementNumber << 3); 
						
					//case ELEMENT_TYPE_R             :   
					//	return (uElementNumber * sizeof(float)); 
						
					case ELEMENT_TYPE_OBJECT        :   
					case ELEMENT_TYPE_STRING        :   
					case ELEMENT_TYPE_FNPTR :   
					case ELEMENT_TYPE_CLASS         :   
					case ELEMENT_TYPE_PTR           :   
					case ELEMENT_TYPE_BYREF         :   
					//case ELEMENT_TYPE_VAR        :   
					case ELEMENT_TYPE_U             :   
					case ELEMENT_TYPE_I             :   
						return (uElementNumber * sizeof(void*)); 
						
					case ELEMENT_TYPE_TYPEDBYREF        :   // pair of ptrs
						return (uElementNumber * sizeof(void*)<<1); 

					case ELEMENT_TYPE_VALUETYPE    :
						*ppSig += CorSigUncompressToken(*ppSig, &tk); 
						ret = SizeOfValueType(tk,pImport);
						if(ret != 0xFFFFFFFF) ret *= uElementNumber;
						return ret;

						// Modifiers or depedant types  

					// uncomment when and if this type is supported by the Runtime
					//case ELEMENT_TYPE_VALUEARRAY    :   

					case ELEMENT_TYPE_ARRAY       :   
						ret = SizeOfField(ppSig, cSig-(unsigned)((*ppSig)-pSigOrig), pImport);
						if(ret != 0xFFFFFFFF)
						{
							unsigned rank = CorSigUncompressData(*ppSig);  
							if (rank == 0) ret = 0xFFFFFFFF;
							else 
							{
								int* lowerBounds = (int*) _alloca(sizeof(int)*2*rank);  
								int* sizes       = &lowerBounds[rank];  
								memset(lowerBounds, 0, sizeof(int)*2*rank); 
								
								unsigned numSizes = CorSigUncompressData(*ppSig);  
                                _ASSERTE(numSizes <= rank);
                                unsigned i;
                                for(i =0; i < numSizes; i++)
									sizes[i] = CorSigUncompressData(*ppSig);   
								
								unsigned numLowBounds = CorSigUncompressData(*ppSig);  
								_ASSERTE(numLowBounds <= rank); 
								for(i = 0; i < numLowBounds; i++)   
									*ppSig+=CorSigUncompressSignedInt(*ppSig,&lowerBounds[i]); 
								
								for(i = 0; i < numSizes; i++)   
								{   
									if (sizes[i]) uElementNumber *= sizes[i];
								}   
								ret *= uElementNumber;  
							}
						}
						return ret;    

					case ELEMENT_TYPE_CMOD_OPT	:
					case ELEMENT_TYPE_CMOD_REQD	:
						*ppSig += CorSigUncompressToken(*ppSig, &tk); 
					case ELEMENT_TYPE_PINNED	:
					case ELEMENT_TYPE_SZARRAY    : // uElementNumber doesn't change
						if(*ppSig < pSigEnd) Reiterate = TRUE;
						break;  

					default:    
					case ELEMENT_TYPE_SENTINEL      :   
					case ELEMENT_TYPE_END           :   
						break;  
				} // end switch
			} while(Reiterate);
		} // end if(CALLCONV_FIELD)
	} // end if(signature && import)
	return ret;
}
Ejemplo n.º 6
0
// see "MetaData Unmanaged API.doc" file available inside 
// Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Tool Developers Guide\docs\ 
// for meta data informations
CParameterInfo* CParameterInfo::Parse(IN IMetaDataImport *pMetaDataImport,IN PCOR_SIGNATURE pSigParam,OUT PCOR_SIGNATURE* pNextSig)
{	
    CParameterInfo* pParameterInfo=NULL;
    COR_SIGNATURE SigContent;

    *pNextSig=0;

    pParameterInfo=new CParameterInfo();
    if (!pParameterInfo)
        return NULL;

    //SigParam:
    //1) 0,N ELEMENT_TYPE_CMOD_REQD/ELEMENT_TYPE_CMOD_OPT
    //2) a) 0,1 TYPE_BYREF + 1 Type
    //   or
    //   b) 1 TYPE_TYPEDBYREF

    SigContent=*pSigParam;
    pSigParam++;

    switch (SigContent) 
    {	
    // 1) 0,N ELEMENT_TYPE_CMOD_REQD/ELEMENT_TYPE_CMOD_OPT
    case ELEMENT_TYPE_CMOD_REQD:
    case ELEMENT_TYPE_CMOD_OPT:
        {	
            // in these 2 case we don't get
            mdToken	Token;	
            TCHAR szClassName[MAX_LENGTH];

            *szClassName=0;
            pSigParam += CorSigUncompressToken(pSigParam,&Token); 
            if (TypeFromToken(Token)!=mdtTypeRef)
            {
                HRESULT	hr;
                WCHAR szName[MAX_LENGTH];
                DWORD szNameSize;
                *szName=0;
                hr = pMetaDataImport->GetTypeDefProps(Token, 
                                                szName,
                                                MAX_LENGTH,
                                                &szNameSize,
                                                NULL,
                                                NULL);
                szName[MAX_LENGTH-1]=0;
                if (FAILED(hr)
                    || (szName==0)
                    )
                {
                    wsprintfW(szName,L"ParamToken%u",Token);
                }

#if (defined(UNICODE)||defined(_UNICODE))
                _tcsncpy(szClassName,szName,MAX_LENGTH);
#else
                wcstombs(szClassName,szName,MAX_LENGTH);
#endif
                szClassName[MAX_LENGTH-1]=0;
            }

            _tcscpy(pParameterInfo->szName,szClassName);
            // get type
            pParameterInfo->WinAPIOverrideType=CSupportedParameters::GetParamType(pParameterInfo->szName);
            // get sizes
            pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
            pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        }
        break;
    // 2) b) 1 TYPE_TYPEDBYREF
    case ELEMENT_TYPE_TYPEDBYREF:
        //A TYPEDBYREF is a simple structure of two DWORDs – one indicates the type of the parameter, the other, its value.
        //This struct is pushed on the stack by the caller.  
        //So, only at runtime, is the type of the parameter actually provided.  
        //TYPEDBYREF was originally introduced to support VB’s "refany" argument-passing technique
        _tcscpy(pParameterInfo->szName,_T("ULONG64"));
        // get type
        pParameterInfo->WinAPIOverrideType=PARAM_INT64;
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;	
    // 2) a) 0,1 TYPE_BYREF + 1 Type
    case ELEMENT_TYPE_BYREF:   
        // delete current info
        delete pParameterInfo;

        // get type infos
        pParameterInfo=CParameterInfo::Parse(pMetaDataImport,pSigParam,&pSigParam); 
        if (!pParameterInfo)
            return NULL;
        _tcscat(pParameterInfo->szName,_T("*"));

        pParameterInfo->bPointedParameter=TRUE;

        // get type
        if (pParameterInfo->WinAPIOverrideType & EXTENDED_TYPE_FLAG_MASK)
            pParameterInfo->WinAPIOverrideType=PARAM_POINTER;
        else
            pParameterInfo->WinAPIOverrideType=CSupportedParameters::GetParamType(pParameterInfo->szName);

        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;

    //////////////////////////
    // from now only Type
    //////////////////////////

    //Type :=	VOID (for return type)
    //          | Intrinsic (BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | I  | U)
    //          | VALUETYPE			TypeDefOrRefEncoded
    //          | CLASS         	TypeDefOrRefEncoded
    //          | STRING
    //          | OBJECT
    //          | PTR				CustomMod*  VOID
    //          | PTR				CustomMod*  Type
    //          | FNPTR				MethodDefSig
    //          | FNPTR				MethodRefSig
    //          | ARRAY     		Type		ArrayShape
    //          | SZARRAY 			CustomMod*  Type

    case ELEMENT_TYPE_VOID:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_VOID;
        _tcscpy(pParameterInfo->szName,_T("VOID"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;					
    case ELEMENT_TYPE_BOOLEAN:	
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_BOOL;
        _tcscpy(pParameterInfo->szName,_T("BOOL"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;	
    case ELEMENT_TYPE_CHAR:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_WCHAR;
        _tcscpy(pParameterInfo->szName,_T("WCHAR"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_I1:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_CHAR;
        _tcscpy(pParameterInfo->szName,_T("SBYTE"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_U1:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_BYTE;
        _tcscpy(pParameterInfo->szName,_T("BYTE"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_I2:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_SHORT;
        _tcscpy(pParameterInfo->szName,_T("SHORT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_U2:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_USHORT;
        _tcscpy(pParameterInfo->szName,_T("USHORT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;			
    case ELEMENT_TYPE_I4:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_INT;
        _tcscpy(pParameterInfo->szName,_T("INT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;
    case ELEMENT_TYPE_U4:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_UINT;
        _tcscpy(pParameterInfo->szName,_T("UINT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_I8:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_INT64;
        _tcscpy(pParameterInfo->szName,_T("INT64"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_U8:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_INT64;
        _tcscpy(pParameterInfo->szName,_T("UINT64"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_R4:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_FLOAT;
        _tcscpy(pParameterInfo->szName,_T("float"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;			
    case ELEMENT_TYPE_R8:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_DOUBLE;
        _tcscpy(pParameterInfo->szName,_T("double"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		
    case ELEMENT_TYPE_U:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_UINT;
        _tcscpy(pParameterInfo->szName,_T("UINT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		 
    case ELEMENT_TYPE_I:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_INT;
        _tcscpy(pParameterInfo->szName,_T("INT"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;			  

    case ELEMENT_TYPE_OBJECT:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_POINTER;
        _tcscpy(pParameterInfo->szName,_T("PVOID"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		 
    case ELEMENT_TYPE_STRING:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_NET_STRING;
        _tcscpy(pParameterInfo->szName,_T("string"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;		 

    case ELEMENT_TYPE_VALUETYPE:
    case ELEMENT_TYPE_CLASS:
        {
            HRESULT	hResult=E_FAIL;
            mdToken	Token;	
            TCHAR szClassName[MAX_LENGTH];
            WCHAR szName[MAX_LENGTH];
            DWORD szNameSize;
            *szClassName=0;
            *szName=0;
            pSigParam+=CorSigUncompressToken(pSigParam,&Token); 
            if ( TypeFromToken( Token ) == mdtTypeDef )
            {
                hResult = pMetaDataImport->GetTypeDefProps( Token, szName, MAX_LENGTH, &szNameSize, NULL, NULL );
            }
            else if ( TypeFromToken( Token ) == mdtTypeRef )
            {
                hResult = pMetaDataImport->GetTypeRefProps(Token, NULL,szName, MAX_LENGTH, &szNameSize);
            }

            szName[MAX_LENGTH-1]=0;
            if (FAILED(hResult)
                || (szName==0)
                || (*szName<32) || (*szName>126) // assume readable name
                )
            {
                wsprintfW(szName,L"ParamToken%u",Token);
            }
#if (defined(UNICODE)||defined(_UNICODE))
            _tcsncpy( szClassName,szName, MAX_LENGTH);
#else
            wcstombs( szClassName, szName, MAX_LENGTH );
#endif
            szClassName[MAX_LENGTH-1]=0;

            _tcscpy(pParameterInfo->szName,szClassName);

            // set default type
            pParameterInfo->WinAPIOverrideType=PARAM_POINTER;
            // get sizes
            pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
            pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
            break;
        }
    case ELEMENT_TYPE_FNPTR:
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_POINTER;
        _tcscpy(pParameterInfo->szName,_T("FunctionPointer"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;
    case ELEMENT_TYPE_SZARRAY:
        // The SZARRAY production describes a frequently-used, special-case of ARRAY 
        // that's to say, a single-dimension (rank 1) array, with a zero lower bound, and no specified size
        // delete current info
        delete pParameterInfo;

        // get type infos
        pParameterInfo=CParameterInfo::Parse(pMetaDataImport,pSigParam,&pSigParam); 
        if (!pParameterInfo)
            return NULL;
        _tcscat(pParameterInfo->szName,_T("*"));
        pParameterInfo->bPointedParameter=TRUE;

        // get type
        pParameterInfo->WinAPIOverrideType=CSupportedParameters::GetParamType(pParameterInfo->szName);
        pParameterInfo->WinAPIOverrideType|=EXTENDED_TYPE_FLAG_NET_SINGLE_DIM_ARRAY;
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);

        break;		
    case ELEMENT_TYPE_ARRAY:	
        {	
            //1) rank
            //2) num size
            //3) 0-N Sizes
            //4) nb low bounds
            //5) 0-N low bounds
            //
            //ex
            //                Type	Rank	NumSizes	    Size*	NumLoBounds	LoBound*
            //[0..2]	        I4	    1	        1	    3	        0	
            //[,,,,,,]	        I4	    6	        0			
            //[0..3, 0..2,,,,]  I4	    6	        2	    4,3	        0	
            //[1..2, 6..8]	    I4	    2	        2	    2,3	        2	    1,6
            //[5, 3..5, , ]	    I4	    3	        2	    5,3	        2	    0,3
            ULONG rank;

            // delete current info
            delete pParameterInfo;
            // parse element
            pParameterInfo=CParameterInfo::Parse(pMetaDataImport,pSigParam,&pSigParam);
            if (!pParameterInfo)
                return NULL;
            _tcscat(pParameterInfo->szName,_T("*"));
            pParameterInfo->bPointedParameter=TRUE;

            // get type
            pParameterInfo->WinAPIOverrideType=CSupportedParameters::GetParamType(pParameterInfo->szName);
            pParameterInfo->WinAPIOverrideType|=EXTENDED_TYPE_FLAG_NET_MULTIPLE_DIM_ARRAY;
            pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
            pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);

            // we have to do parsing even if not necessary to find next signature
            // 1) rank
            rank = CorSigUncompressData((PCCOR_SIGNATURE&)pSigParam);
            
            if ( rank > 0 ) 
            {
                ULONG *lower;	
                ULONG *sizes; 	
                ULONG numsizes; 
                ULONG arraysize=(sizeof(ULONG)*2*rank);

                lower=(ULONG*)_alloca(arraysize);                                                        
                memset(lower,0,arraysize); 
                sizes=&lower[rank];

                // 2) num size
                numsizes = CorSigUncompressData((PCCOR_SIGNATURE&)pSigParam);	
                if ( numsizes <= rank )
                {
                    ULONG numlower;
                    ULONG i;

                    // 3) sizes
                    for ( i = 0; i < numsizes; i++ )	
                        sizes[i] = CorSigUncompressData((PCCOR_SIGNATURE&)pSigParam);	


                    // 4) num lower
                    numlower = CorSigUncompressData((PCCOR_SIGNATURE&)pSigParam);	
                    if ( numlower <= rank )
                    {
                        // 5) low bounds
                        for ( i = 0; i < numlower; i++)	
                            lower[i] = CorSigUncompressData((PCCOR_SIGNATURE&)pSigParam); 

                        //// to display array size only
                        //_tcscat( pParameterInfo->szName, "[" );	
                        //for ( i = 0; i < rank; i++ )	
                        //{	
                        //    if ( (sizes[i] != 0) && (lower[i] != 0) )	
                        //    {	
                        //        if ( lower[i] == 0 )	
                        //            _stprintf ( pParameterInfo->szName, _T("%d"), sizes[i] );	

                        //        else	
                        //        {	
                        //            _stprintf( pParameterInfo->szName, _T("%d"), lower[i] );	
                        //            _tcscat( pParameterInfo->szName, _T("...") );	

                        //            if ( sizes[i] != 0 )	
                        //                _stprintf( pParameterInfo->szName, _T("%d"), (lower[i] + sizes[i] + 1) );	
                        //        }	
                        //    }

                        //    if ( i < (rank - 1) ) 
                        //        _tcscat( pParameterInfo->szName, _T(",") );	
                        //}	

                        //_tcscat( pParameterInfo->szName, _T("]") );  

                    }						
                }
            }

        } 
        break;	


    case ELEMENT_TYPE_PINNED:
        // delete current info
        delete pParameterInfo;
        // parse element
        pParameterInfo=CParameterInfo::Parse(pMetaDataImport,pSigParam,&pSigParam); 
        if (!pParameterInfo)
            return NULL;
        // _tcscat(pParameterInfo->szName,_T("pinned"));	
        break;	


    case ELEMENT_TYPE_PTR:  
        // delete current info
        delete pParameterInfo;

        // get type infos
        pParameterInfo=CParameterInfo::Parse(pMetaDataImport,pSigParam,&pSigParam); 
        if (!pParameterInfo)
            return NULL;
        _tcscat(pParameterInfo->szName,_T("*"));

        pParameterInfo->bPointedParameter=TRUE;

        // get type
        if (pParameterInfo->WinAPIOverrideType & EXTENDED_TYPE_FLAG_MASK)
            pParameterInfo->WinAPIOverrideType=PARAM_POINTER;
        else
            pParameterInfo->WinAPIOverrideType=CSupportedParameters::GetParamType(pParameterInfo->szName);

        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);

        break;   


    default:	
    case ELEMENT_TYPE_END:	
    case ELEMENT_TYPE_SENTINEL:	
        // set default type
        pParameterInfo->WinAPIOverrideType=PARAM_UNKNOWN;
        _tcscpy(pParameterInfo->szName,_T("Unknown"));
        // get sizes
        pParameterInfo->StackSize=CSupportedParameters::GetParamStackSize(pParameterInfo->WinAPIOverrideType);
        pParameterInfo->PointedSize=CSupportedParameters::GetParamPointedSize(pParameterInfo->WinAPIOverrideType);
        break;				                      				            

    } // switch	

    // fill output parameters
    *pNextSig=pSigParam;

    return pParameterInfo;
}
Ejemplo n.º 7
0
//
// _skipTypeInSignature -- skip past a type in a given signature.
// Returns the number of bytes used by the type in the signature.
//
//
ULONG _skipTypeInSignature(PCCOR_SIGNATURE sig, bool *pfPassedVarArgSentinel)
{
    ULONG cb = 0;
    ULONG elementType;

    if (pfPassedVarArgSentinel != NULL)
        *pfPassedVarArgSentinel = false;

    cb += _skipFunkyModifiersInSignature(&sig[cb]);

    if (_detectAndSkipVASentinel(&sig[cb]))
    {
        cb += _detectAndSkipVASentinel(&sig[cb]);
        // Recursively deal with the real type.
        cb += _skipTypeInSignature(&sig[cb], pfPassedVarArgSentinel);

        if (pfPassedVarArgSentinel != NULL)
            *pfPassedVarArgSentinel = true;
    }
    else
    {
        cb += CorSigUncompressData(&sig[cb], &elementType);
    
        if ((elementType == ELEMENT_TYPE_CLASS) ||
            (elementType == ELEMENT_TYPE_VALUETYPE))
        {
            // Skip over typeref.
            mdToken typeRef;
            cb += CorSigUncompressToken(&sig[cb], &typeRef);
        }
        else if ((elementType == ELEMENT_TYPE_PTR) ||
                 (elementType == ELEMENT_TYPE_BYREF) ||
                 (elementType == ELEMENT_TYPE_PINNED) ||
                 (elementType == ELEMENT_TYPE_SZARRAY))
        {
            // Skip over extra embedded type.
            cb += _skipTypeInSignature(&sig[cb]);
        }
        else if (elementType == ELEMENT_TYPE_ARRAY)
        {
            // Skip over extra embedded type.
            cb += _skipTypeInSignature(&sig[cb]);

        // Skip over rank
            ULONG rank;
            cb += CorSigUncompressData(&sig[cb], &rank);

            if (rank > 0)
            {
                // how many sizes?
                ULONG sizes;
                cb += CorSigUncompressData(&sig[cb], &sizes);

                // read out all the sizes
                unsigned int i;

                for (i = 0; i < sizes; i++)
                {
                    ULONG dimSize;
                    cb += CorSigUncompressData(&sig[cb], &dimSize);
                }

                // how many lower bounds?
                ULONG lowers;
                cb += CorSigUncompressData(&sig[cb], &lowers);

            // read out all the lower bounds.
                for (i = 0; i < lowers; i++)
                {
                    int lowerBound;
                    cb += CorSigUncompressSignedInt(&sig[cb], &lowerBound);
                }
            }
        }  else if ( (elementType == ELEMENT_TYPE_FNPTR) )
        {
            // We've got a method signature within this signature,
            // so traverse it

            // Run past the calling convetion, then get the
            // arg count, and return type   

            ULONG cArgs;
            cb += _skipMethodSignatureHeader(&sig[cb], &cArgs);

            ULONG i;
            for(i = 0; i < cArgs; i++)
            {
                cb += _skipTypeInSignature(&sig[cb]);
            }
        }
    }
    
    return (cb);
}
Ejemplo n.º 8
0
ULONG _sizeOfElementInstance(PCCOR_SIGNATURE sig, mdTypeDef *pmdValueClass)
{

    ULONG cb = _skipFunkyModifiersInSignature(sig);

    sig = &sig[cb];
        
    if (pmdValueClass != NULL)
        *pmdValueClass = mdTokenNil;

    switch (*sig)
    {
    case ELEMENT_TYPE_I8:
    case ELEMENT_TYPE_U8:
    case ELEMENT_TYPE_R8:

        return 8;

    case ELEMENT_TYPE_I4:
    case ELEMENT_TYPE_U4:
    case ELEMENT_TYPE_R4:
#ifdef WIN32
    case ELEMENT_TYPE_I:
    case ELEMENT_TYPE_U:        
#endif // WIN32
        
        return 4;
        break;

    case ELEMENT_TYPE_I2:
    case ELEMENT_TYPE_U2:
    case ELEMENT_TYPE_CHAR:
        return 2;

    case ELEMENT_TYPE_I1:
    case ELEMENT_TYPE_U1:
    case ELEMENT_TYPE_BOOLEAN:
        return 1;

    case ELEMENT_TYPE_STRING:
    case ELEMENT_TYPE_PTR:
    case ELEMENT_TYPE_BYREF:
    case ELEMENT_TYPE_CLASS:
    case ELEMENT_TYPE_OBJECT:
    case ELEMENT_TYPE_FNPTR:
    case ELEMENT_TYPE_TYPEDBYREF:
    case ELEMENT_TYPE_ARRAY:
    case ELEMENT_TYPE_SZARRAY:
        return sizeof(void *);

    case ELEMENT_TYPE_VOID:
        return 0;

    case ELEMENT_TYPE_END:
    case ELEMENT_TYPE_CMOD_REQD:
    case ELEMENT_TYPE_CMOD_OPT:
        _ASSERTE(!"Asked for the size of an element that doesn't have a size!");
        return 0;

    case ELEMENT_TYPE_VALUETYPE:
        if (pmdValueClass != NULL)
        {
            PCCOR_SIGNATURE sigTemp = &sig[cb];
            ULONG Ignore;
            cb += CorSigUncompressData(sigTemp, &Ignore);
            sigTemp = &sig[cb];
            *pmdValueClass=CorSigUncompressToken(sigTemp);
        }
        return 0;
    default:
        if ( _detectAndSkipVASentinel(sig))
        {
            cb += _detectAndSkipVASentinel(sig);
            return _sizeOfElementInstance(&sig[cb]);
        }
        
        _ASSERTE( !"_sizeOfElementInstance given bogus value to size!" );
        return 0;
    }
}
Ejemplo n.º 9
0
//*****************************************************************************
// walk one type and mark tokens embedded in the signature
//*****************************************************************************
HRESULT FilterManager::MarkFieldSignature(
    PCCOR_SIGNATURE pbSig,              // [IN] point to the current byte to visit in the signature
    ULONG       cbSig,                  // [IN] count of bytes available.
    ULONG       *pcbUsed)               // [OUT] count of bytes consumed.
{
    HRESULT     hr = NOERROR;           // A result.
    ULONG       cb;                     // Bytes in one signature element.
    ULONG       cbUsed = 0;             // Total bytes consumed from signature.
    CorElementType ulElementType;       // ELEMENT_TYPE_xxx from signature.
    ULONG       ulData;                 // Some data (like a count) from the signature.
    ULONG       ulTemp;                 // Unused data.
    mdToken     token;                  // A token from the signature.
    int         iData;                  // Integer data from signature.

    VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) );

    // Skip the modifiers...
    while (CorIsModifierElementType((CorElementType) ulElementType))
    {
        VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) );
    }

    // Examine the signature element
    switch (ulElementType)
    {
        case ELEMENT_TYPE_SZARRAY:
            // syntax: SZARRAY <BaseType>

            // conver the base type for the SZARRAY or GENERICARRAY
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_CMOD_REQD:
        case ELEMENT_TYPE_CMOD_OPT:
            // syntax: {CMOD_REQD|CMOD_OPT} <token> <signature>

            // now get the embedded token
            VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) );

            // Mark the token
            IfFailGo( Mark(token) );

            // mark the base type
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_VAR:
        case ELEMENT_TYPE_MVAR:
            // syntax: VAR <index>
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );
            break;

        case ELEMENT_TYPE_ARRAY:
            // syntax: ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j]

            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );

            // Parse for the rank
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // if rank == 0, we are done
            if (ulData == 0)
                break;

            // Any size of dimension specified?
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Consume sizes of dimension.
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulTemp) );
            }

            // Any lower bounds specified?
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Consume lower bounds.
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN( CorSigUncompressSignedInt(pbSig, &iData) );
            }

            break;

        case ELEMENT_TYPE_FNPTR:
            // function pointer is followed by another complete signature
            VALIDATE_SIGNATURE_LEN_HR( MarkSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_VALUETYPE:
        case ELEMENT_TYPE_CLASS:
            // syntax: {CLASS | VALUECLASS} <token>
            VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) );

            // Mark it.
            IfFailGo( Mark(token) );
            break;

        case ELEMENT_TYPE_GENERICINST:
            // syntax:  ELEMENT_TYPE_GEENRICINST <ELEMENT_TYPE_CLASS | ELEMENT_TYPE_VALUECLASS> <token> <n> <n params>
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );

            // Get the number of generic parameters
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Get the generic parameters
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            }
            break;

        default:
            // If valid element (I4, etc), great.  Otherwise, return error.
            if ((ulElementType >= ELEMENT_TYPE_MAX) || 
                (ulElementType == ELEMENT_TYPE_PTR) || 
                (ulElementType == ELEMENT_TYPE_BYREF) || 
                (ulElementType == ELEMENT_TYPE_VALUEARRAY_UNSUPPORTED))
            {
                IfFailGo(META_E_BAD_SIGNATURE);
            }
            break;
    }

ErrExit:
    *pcbUsed = cbUsed;
    return hr;
} // HRESULT FilterManager::MarkFieldSignature()