Exemple #1
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);    
}
Exemple #2
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;
}
Exemple #3
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);
}
Exemple #4
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;
}
Exemple #5
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()