home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / corhlpr.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  16.3 KB  |  423 lines

  1. /*****************************************************************************
  2.  **                                                                         **
  3.  ** Corhlpr.h - this file contains a set of "as is" code that may be        **
  4.  **             used by developers writing compilers and tools against      **
  5.  **             the COM+ Runtime.  The code is not officially supported,    **
  6.  **             but is code being used by the Runtime itself.               **
  7.  **                                                                         **
  8.  ** Copyright (c) 1996-2000 Microsoft Corporation.  All Rights Reserved.    **
  9.  **                                                                         **
  10.  *****************************************************************************/
  11.  
  12.  
  13. #ifndef __CORHLPR_H__
  14. #define __CORHLPR_H__
  15.  
  16. #include "cor.h"
  17. #include "corhdr.h"
  18. #include "corerror.h"
  19.  
  20.  
  21.  
  22. //*****************************************************************************
  23. // There are a set of macros commonly used in the helpers which you will want
  24. // to override to get richer behavior.  The following defines what is needed
  25. // if you chose not to do the extra work.
  26. //*****************************************************************************
  27. #ifndef IfFailGoto
  28. #define IfFailGoto(EXPR, LABEL) \
  29. do { hr = (EXPR); if(FAILED(hr)) { goto LABEL; } } while (0)
  30. #endif
  31.  
  32. #ifndef IfFailGo
  33. #define IfFailGo(EXPR) IfFailGoto(EXPR, ErrExit)
  34. #endif
  35.  
  36. #ifndef _ASSERTE
  37. #define _ASSERTE(expr)
  38. #endif
  39.  
  40.  
  41.  
  42.  
  43.  
  44. //*****************************************************************************
  45. //
  46. //***** Utility helpers
  47. //
  48. //*****************************************************************************
  49.  
  50.  
  51.  
  52.  
  53.  
  54. //*****************************************************************************
  55. //
  56. // **** CQuickBytes
  57. // This helper class is useful for cases where 90% of the time you allocate 512
  58. // or less bytes for a data structure.  This class contains a 512 byte buffer.
  59. // Alloc() will return a pointer to this buffer if your allocation is small
  60. // enough, otherwise it asks the heap for a larger buffer which is freed for
  61. // you.  No mutex locking is required for the small allocation case, making the
  62. // code run faster, less heap fragmentation, etc...  Each instance will allocate
  63. // 520 bytes, so use accordinly.
  64. //
  65. //*****************************************************************************
  66. #define     CQUICKBYTES_BASE_SIZE           512
  67. #define     CQUICKBYTES_INCREMENTAL_SIZE    128
  68. class CQuickBytes
  69. {
  70. public:
  71.     CQuickBytes() :
  72.         pbBuff(0),
  73.         iSize(0),
  74.         cbTotal(CQUICKBYTES_BASE_SIZE)
  75.     { }
  76.  
  77.     ~CQuickBytes()
  78.     {
  79.         if (pbBuff)
  80.             free(pbBuff);
  81.     }
  82.  
  83.     void *Alloc(int iItems)
  84.     {
  85.         iSize = iItems;
  86.         if (iItems <= CQUICKBYTES_BASE_SIZE)
  87.         {
  88.             cbTotal = CQUICKBYTES_BASE_SIZE;
  89.             return (&rgData[0]);
  90.         }
  91.         else
  92.         {
  93.             if (pbBuff) free(pbBuff);
  94.             pbBuff = malloc(iItems);
  95.             cbTotal = pbBuff ? iItems : 0;
  96.             return (pbBuff);
  97.         }
  98.     }
  99.  
  100.     HRESULT ReSize(int iItems)
  101.     {
  102.         void *pbBuffNew;
  103.         if (iItems <= cbTotal)
  104.         {
  105.             iSize = iItems;
  106.             return NOERROR;
  107.         }
  108.  
  109.         pbBuffNew = malloc(iItems + CQUICKBYTES_INCREMENTAL_SIZE);
  110.         if (!pbBuffNew)
  111.             return E_OUTOFMEMORY;
  112.         if (pbBuff) 
  113.         {
  114.             memcpy(pbBuffNew, pbBuff, cbTotal);
  115.             free(pbBuff);
  116.         }
  117.         else
  118.         {
  119.             _ASSERTE(cbTotal == CQUICKBYTES_BASE_SIZE);
  120.             memcpy(pbBuffNew, rgData, cbTotal);
  121.         }
  122.         cbTotal = iItems + CQUICKBYTES_INCREMENTAL_SIZE;
  123.         iSize = iItems;
  124.         pbBuff = pbBuffNew;
  125.         return NOERROR;
  126.         
  127.     }
  128.     operator PVOID()
  129.     { return ((pbBuff) ? pbBuff : &rgData[0]); }
  130.  
  131.     void *Ptr()
  132.     { return ((pbBuff) ? pbBuff : &rgData[0]); }
  133.  
  134.     int Size()
  135.     { return (iSize); }
  136.  
  137.     int MaxSize()
  138.     { return (cbTotal); }
  139.  
  140.     void        *pbBuff;
  141.     int         iSize;              // number of bytes used
  142.     int         cbTotal;            // total bytes allocated in the buffer
  143.     BYTE        rgData[512];
  144. };
  145.  
  146.  
  147.  
  148.  
  149. //*****************************************************************************
  150. //
  151. //***** Signature helpers
  152. //
  153. //*****************************************************************************
  154.  
  155. inline bool isCallConv(unsigned sigByte, CorCallingConvention conv)
  156. {
  157.     return ((sigByte & IMAGE_CEE_CS_CALLCONV_MASK) == (unsigned) conv); 
  158. }
  159.  
  160. HRESULT _CountBytesOfOneArg(
  161.     PCCOR_SIGNATURE pbSig, 
  162.     ULONG       *pcbTotal);
  163.  
  164. HRESULT _GetFixedSigOfVarArg(           // S_OK or error.
  165.     PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob of COM+ method signature
  166.     ULONG   cbSigBlob,                  // [IN] size of signature
  167.     CQuickBytes *pqbSig,                // [OUT] output buffer for fixed part of VarArg Signature
  168.     ULONG   *pcbSigBlob);               // [OUT] number of bytes written to the above output buffer
  169.  
  170.  
  171.  
  172.  
  173. //*****************************************************************************
  174. //
  175. //***** File format helper classes
  176. //
  177. //*****************************************************************************
  178.  
  179.  
  180.  
  181. //*****************************************************************************
  182. typedef struct tagCOR_ILMETHOD_SECT_SMALL : IMAGE_COR_ILMETHOD_SECT_SMALL {
  183.         //Data follows  
  184.     const BYTE* Data() const { return(((const BYTE*) this) + sizeof(struct tagCOR_ILMETHOD_SECT_SMALL)); }    
  185. } COR_ILMETHOD_SECT_SMALL;
  186.  
  187.  
  188. /************************************/
  189. /* NOTE this structure must be DWORD aligned!! */
  190. typedef struct tagCOR_ILMETHOD_SECT_FAT : IMAGE_COR_ILMETHOD_SECT_FAT {
  191.         //Data follows  
  192.     const BYTE* Data() const { return(((const BYTE*) this) + sizeof(struct tagCOR_ILMETHOD_SECT_FAT)); }  
  193. } COR_ILMETHOD_SECT_FAT;
  194.  
  195.  
  196. /************************************/
  197. /* NOTE this structure must be DWORD aligned!! */
  198. struct COR_ILMETHOD_SECT 
  199. {
  200.     bool More() const           { return((AsSmall()->Kind & CorILMethod_Sect_MoreSects) != 0); }    
  201.     CorILMethodSect Kind() const{ return((CorILMethodSect) (AsSmall()->Kind & CorILMethod_Sect_KindMask)); }    
  202.     const COR_ILMETHOD_SECT* Next() const   {   
  203.         if (!More()) return(0); 
  204.         if (IsFat()) return(((COR_ILMETHOD_SECT*) &AsFat()->Data()[AsFat()->DataSize])->Align());    
  205.         return(((COR_ILMETHOD_SECT*) &AsSmall()->Data()[AsSmall()->DataSize])->Align()); 
  206.         }   
  207.     const COR_ILMETHOD_SECT* NextLoc() const   {   
  208.         if (IsFat()) return(((COR_ILMETHOD_SECT*) &AsFat()->Data()[AsFat()->DataSize])->Align());    
  209.         return(((COR_ILMETHOD_SECT*) &AsSmall()->Data()[AsSmall()->DataSize])->Align()); 
  210.         }   
  211.     const BYTE* Data() const {  
  212.         if (IsFat()) return(AsFat()->Data());   
  213.         return(AsSmall()->Data());  
  214.         }   
  215.     unsigned DataSize() const { 
  216.         if (IsFat()) return(AsFat()->DataSize); 
  217.         return(AsSmall()->DataSize);    
  218.         }   
  219.  
  220.     friend struct COR_ILMETHOD; 
  221.     friend struct tagCOR_ILMETHOD_FAT; 
  222.     friend struct tagCOR_ILMETHOD_TINY;    
  223.     bool IsFat() const                            { return((AsSmall()->Kind & CorILMethod_Sect_FatFormat) != 0); }  
  224.     const COR_ILMETHOD_SECT* Align() const        { return((COR_ILMETHOD_SECT*) ((((UINT_PTR) this) + 3) & ~3));  } 
  225. protected:
  226.     const COR_ILMETHOD_SECT_FAT*   AsFat() const  { return((COR_ILMETHOD_SECT_FAT*) this); }    
  227.     const COR_ILMETHOD_SECT_SMALL* AsSmall() const{ return((COR_ILMETHOD_SECT_SMALL*) this); }  
  228.  
  229.     // The body is either a COR_ILMETHOD_SECT_SMALL or COR_ILMETHOD_SECT_FAT    
  230.     // (as indicated by the CorILMethod_Sect_FatFormat bit  
  231. };
  232.  
  233. //*****************************************************************************
  234. struct COR_ILMETHOD_SECT_EH_FAT : public COR_ILMETHOD_SECT_FAT {
  235.     static unsigned Size(unsigned ehCount) {    
  236.         return (sizeof(COR_ILMETHOD_SECT_EH_FAT) +  
  237.                 sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT) * (ehCount-1)); 
  238.         }   
  239.                     
  240.     IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT Clauses[1];     // actually variable size   
  241. };
  242.  
  243. //*****************************************************************************
  244. struct COR_ILMETHOD_SECT_EH_SMALL : public COR_ILMETHOD_SECT_SMALL {
  245.     static unsigned Size(unsigned ehCount) {    
  246.         return (sizeof(COR_ILMETHOD_SECT_EH_SMALL) +    
  247.                 sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL) * (ehCount-1));   
  248.         }   
  249.                     
  250.     WORD Reserved;                                  // alignment padding    
  251.     IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL Clauses[1];   // actually variable size   
  252. };
  253.  
  254.  
  255. /***********************************/
  256. // exported functions (implementation in Format\Format.cpp:
  257. extern "C" {
  258. IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* __stdcall SectEH_EHClause(void *pSectEH, unsigned idx, IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* buff);
  259.         // compute the size of the section (best format)    
  260.         // codeSize is the size of the method   
  261.     // deprecated
  262. unsigned __stdcall SectEH_SizeWithCode(unsigned ehCount, unsigned codeSize);  
  263.  
  264.     // will return worse-case size and then Emit will return actual size
  265. unsigned __stdcall SectEH_SizeWorst(unsigned ehCount);  
  266.  
  267.     // will return exact size which will match the size returned by Emit
  268. unsigned __stdcall SectEH_SizeExact(unsigned ehCount, IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses);  
  269.  
  270.         // emit the section (best format);  
  271. unsigned __stdcall SectEH_Emit(unsigned size, unsigned ehCount,   
  272.                   IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses,
  273.                   BOOL moreSections, BYTE* outBuff);
  274. } // extern "C"
  275.  
  276.  
  277. struct COR_ILMETHOD_SECT_EH : public COR_ILMETHOD_SECT
  278. {
  279.     unsigned EHCount() const {  
  280.         return(IsFat() ? (Fat.DataSize / sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)) : 
  281.                         (Small.DataSize / sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL))); 
  282.     }   
  283.  
  284.         // return one clause in its fat form.  Use 'buff' if needed 
  285.     const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* EHClause(unsigned idx, IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* buff) const
  286.     { return SectEH_EHClause((void *)this, idx, buff); };
  287.         // compute the size of the section (best format)    
  288.         // codeSize is the size of the method   
  289.     // deprecated
  290.     unsigned static Size(unsigned ehCount, unsigned codeSize)
  291.     { return SectEH_SizeWithCode(ehCount, codeSize); };
  292.  
  293.     // will return worse-case size and then Emit will return actual size
  294.     unsigned static Size(unsigned ehCount)
  295.     { return SectEH_SizeWorst(ehCount); };
  296.  
  297.     // will return exact size which will match the size returned by Emit
  298.     unsigned static Size(unsigned ehCount, const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses)
  299.     { return SectEH_SizeExact(ehCount, (IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)clauses);  };
  300.  
  301.         // emit the section (best format);  
  302.     unsigned static Emit(unsigned size, unsigned ehCount,   
  303.                   const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses,   
  304.                   bool moreSections, BYTE* outBuff)
  305.     { return SectEH_Emit(size, ehCount, (IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)clauses, moreSections, outBuff); };
  306.  
  307. //private:
  308.  
  309.     union { 
  310.         COR_ILMETHOD_SECT_EH_SMALL Small;   
  311.         COR_ILMETHOD_SECT_EH_FAT Fat;   
  312.         };  
  313. };
  314.  
  315.  
  316. /***************************************************************************/
  317. /* Used when the method is tiny (< 64 bytes), and there are no local vars */
  318. typedef struct tagCOR_ILMETHOD_TINY : IMAGE_COR_ILMETHOD_TINY
  319. {
  320.     bool     IsTiny() const         { return((Flags_CodeSize & (CorILMethod_FormatMask >> 1)) == CorILMethod_TinyFormat); } 
  321.     unsigned GetCodeSize() const    { return(((unsigned) Flags_CodeSize) >> (CorILMethod_FormatShift-1)); } 
  322.     unsigned GetMaxStack() const    { return(8); }  
  323.     BYTE*    GetCode() const        { return(((BYTE*) this) + sizeof(struct tagCOR_ILMETHOD_TINY)); } 
  324.     DWORD    GetLocalVarSigTok() const  { return(0); }  
  325.     COR_ILMETHOD_SECT* GetSect() const { return(0); }   
  326. } COR_ILMETHOD_TINY;
  327.  
  328.  
  329. /************************************/
  330. // This strucuture is the 'fat' layout, where no compression is attempted. 
  331. // Note that this structure can be added on at the end, thus making it extensible
  332. typedef struct tagCOR_ILMETHOD_FAT : IMAGE_COR_ILMETHOD_FAT
  333. {
  334.     bool     IsFat() const              { return((Flags & CorILMethod_FormatMask) == CorILMethod_FatFormat); }  
  335.     unsigned GetMaxStack() const        { return(MaxStack); }   
  336.     unsigned GetCodeSize() const        { return(CodeSize); }   
  337.     mdToken  GetLocalVarSigTok() const      { return(LocalVarSigTok); } 
  338.     BYTE*    GetCode() const            { return(((BYTE*) this) + 4*Size); }    
  339.     const COR_ILMETHOD_SECT* GetSect() const {  
  340.         if (!(Flags & CorILMethod_MoreSects)) return(0);    
  341.         return(((COR_ILMETHOD_SECT*) (GetCode() + GetCodeSize()))->Align());    
  342.         }   
  343. } COR_ILMETHOD_FAT;
  344.  
  345.  
  346. extern "C" {
  347. /************************************/
  348. // exported functions (impl. Format\Format.cpp)
  349. unsigned __stdcall IlmethodSize(COR_ILMETHOD_FAT* header, BOOL MoreSections);    
  350.         // emit the header (bestFormat) return amount emitted   
  351. unsigned __stdcall IlmethodEmit(unsigned size, COR_ILMETHOD_FAT* header, 
  352.                   BOOL moreSections, BYTE* outBuff);    
  353. }
  354.  
  355. struct COR_ILMETHOD
  356. {
  357.         // a COR_ILMETHOD header should not be decoded by hand.  Instead us 
  358.         // COR_ILMETHOD_DECODER to decode it.   
  359.     friend class COR_ILMETHOD_DECODER;  
  360.  
  361.         // compute the size of the header (best format) 
  362.     unsigned static Size(const COR_ILMETHOD_FAT* header, bool MoreSections)
  363.     { return IlmethodSize((COR_ILMETHOD_FAT*)header,MoreSections); };
  364.         // emit the header (bestFormat) return amount emitted   
  365.     unsigned static Emit(unsigned size, const COR_ILMETHOD_FAT* header, 
  366.                   bool moreSections, BYTE* outBuff)
  367.     { return IlmethodEmit(size, (COR_ILMETHOD_FAT*)header, moreSections, outBuff); };
  368.  
  369. //private:
  370.     union   
  371.     {   
  372.         COR_ILMETHOD_TINY       Tiny;   
  373.         COR_ILMETHOD_FAT        Fat;    
  374.     };  
  375.         // Code follows the Header, then immedately after the code comes    
  376.         // any sections (COR_ILMETHOD_SECT).    
  377. };
  378.  
  379. extern "C" {
  380. /***************************************************************************/
  381. /* COR_ILMETHOD_DECODER is the only way functions internal to the EE should
  382.    fetch data from a COR_ILMETHOD.  This way any dependancy on the file format
  383.    (and the multiple ways of encoding the header) is centralized to the 
  384.    COR_ILMETHOD_DECODER constructor) */
  385.     void __stdcall DecoderInit(void * pThis, COR_ILMETHOD* header);
  386.     int  __stdcall DecoderGetOnDiskSize(void * pThis, COR_ILMETHOD* header);
  387. } // extern "C"
  388.  
  389. class COR_ILMETHOD_DECODER : public COR_ILMETHOD_FAT  
  390. {
  391. public:
  392.         // Decode the COR header into a more convinient internal form   
  393.         // This is the ONLY way you should access COR_ILMETHOD so format changes are easier 
  394.     COR_ILMETHOD_DECODER(const COR_ILMETHOD* header) { DecoderInit(this,(COR_ILMETHOD*)header); };   
  395.  
  396.         // The constructor above can not do a 'complete' job, because it    
  397.         // can not look up the local variable signature meta-data token.    
  398.         // This method should be used in s  
  399.     COR_ILMETHOD_DECODER(COR_ILMETHOD* header, void *pInternalImport);  
  400.  
  401.     unsigned EHCount() const {  
  402.         if (EH == 0) return(0); 
  403.         else return(EH->EHCount()); 
  404.         }   
  405.  
  406.     // returns total size of method for use in copying
  407.     int GetOnDiskSize(const COR_ILMETHOD* header) { return DecoderGetOnDiskSize(this,(COR_ILMETHOD*)header); };
  408.  
  409.     // Flags        these are available because we inherit COR_ILMETHOD_FAT 
  410.     // MaxStack 
  411.     // CodeSize 
  412.     const BYTE* Code;   
  413.     PCCOR_SIGNATURE LocalVarSig;        // pointer to signature blob, or 0 if none  
  414.     const COR_ILMETHOD_SECT_EH* EH;     // eh table if any  0 if none   
  415.     const COR_ILMETHOD_SECT* Sect;      // additional sections  0 if none   
  416. };
  417.  
  418. STDAPI_(void)   ReleaseFusionInterfaces();
  419. BOOL STDMETHODCALLTYPE   BeforeFusionShutdown();
  420.  
  421. #endif // __CORHLPR_H__
  422.  
  423.