Fix build with CoreCLR preview-7. accepted/tizen/unified/20190813.220001 submit/tizen/20190813.035844
authorMikhail Kurinnoi <m.kurinnoi@samsung.net>
Tue, 13 Aug 2019 10:08:16 +0000 (13:08 +0300)
committerAlexander Soldatov/AI Compiler Lab /SRR/Staff Engineer/삼성전자 <soldatov.a@samsung.com>
Tue, 13 Aug 2019 11:14:29 +0000 (14:14 +0300)
Temporary solution. Code should be refactored in order
to use corpriv.h and metadata.h directly (part of CoreCLR).

packaging/netcoredbg.spec
src/debug/netcoredbg/CMakeLists.txt
src/debug/netcoredbg/sos_md.h [new file with mode: 0644]
src/debug/netcoredbg/vscodeprotocol.cpp

index ac7c03e1e9ae4f5f58ee455f358a2415bb72bc8a..8b9bccd9abdd47b6e672bd5747d8d35d0daadae8 100644 (file)
@@ -25,6 +25,7 @@ BuildRequires: unzip
 BuildRequires: corefx-managed
 BuildRequires: libdlog-devel
 Requires: coreclr
+Requires: coreclr-diagnostics
 
 # .NET Core Runtime
 %define dotnetdir       dotnet
index 9496fcddb8572fc59664115ccc16ba8d2135923d..6316d6f0759edd760d44bc774fb189a4fd3a33b2 100644 (file)
@@ -27,7 +27,6 @@ include_directories(${CORECLR_DIR}/src/debug/inc)
 include_directories(${CORECLR_DIR}/src/debug/shim)
 include_directories(${CORECLR_DIR}/src/dlls/dbgshim)
 include_directories(${CORECLR_DIR}/src/coreclr/hosts/inc)
-include_directories(${CORECLR_DIR}/src/ToolBox/SOS/Strike)
 
 # Build native part of the debugger
 
diff --git a/src/debug/netcoredbg/sos_md.h b/src/debug/netcoredbg/sos_md.h
new file mode 100644 (file)
index 0000000..74ac2d6
--- /dev/null
@@ -0,0 +1,923 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ==++==
+// 
+// 
+// ==--==
+
+#ifndef __SOS_MD_H__
+#define __SOS_MD_H__
+
+#define IfErrGoTo(s, label) { \
+       hresult = (s); \
+       if(FAILED(hresult)){ \
+         goto label; }}
+
+class CQuickBytes;
+
+// TODO: Cleanup code to allow SOS to directly include the metadata header files.
+//#include "MetaData.h"
+//#include "corpriv.h"
+
+/*
+ *
+ * Metadata definitions needed for PrettyPrint functions.
+ *   The original definitions for the types and interfaces below exist in
+ *   inc\MetaData.h and inc\CorPriv.h
+ * TODO:
+ *   Cleanup code to allow SOS to directly include the metadata header files.
+ *     Currently it's extremely difficult due to symbol redefinitions.
+ *   Always keep the definitions below in sync with the originals.
+ * NOTES:
+ *   Since SOS runs in a native debugger session, since it does not use EnC,
+ *      and in order to minimize the amount of duplication we changed the
+ *      method definitions that deal with UTSemReadWrite* arguments to take
+ *      void* arguments instead.
+ *   Also, some of the interface methods take CQuickBytes as arguments.
+ *      If these methods are ever used it becomes crucial to maintain binary
+ *      compatibility b/w the CQuickBytes defined in SOS and the definition
+ *      from the EE.
+ *
+ */
+typedef enum tagEnumType
+{
+    MDSimpleEnum        = 0x0,                  // simple enumerator that doesn't allocate memory 
+    MDDynamicArrayEnum = 0x2,                   // dynamic array that holds tokens
+    MDCustomEnum = 0x3,                         // Custom enumerator that doesnt work with the enum functions
+} EnumType;
+
+struct HENUMInternal
+{
+    DWORD       m_tkKind;                   // kind of tables that the enum is holding the result
+    ULONG       m_ulCount;                  // count of total entries holding by the enumerator
+    
+    EnumType    m_EnumType;
+
+    struct {
+        ULONG   m_ulStart;
+        ULONG   m_ulEnd;
+        ULONG   m_ulCur;
+    } u;
+
+    // m_cursor will go away when we no longer support running EE with uncompressed
+    // format. WHEN WE REMOVE THIS, REMOVE ITS VESTIAGES FROM ZeroEnum as well
+    //
+    char        m_cursor[32];               // cursor holding query result for read/write mode
+};
+
+typedef struct _MDDefaultValue
+{
+#if DBG_TARGET_BIGENDIAN
+    _MDDefaultValue(void)
+    {
+        m_bType = ELEMENT_TYPE_END;
+    }
+    ~_MDDefaultValue(void)
+    {
+        if (m_bType == ELEMENT_TYPE_STRING)
+        {
+            delete[] m_wzValue;
+        }
+    }
+#endif
+
+    // type of default value 
+    BYTE            m_bType;                // CorElementType for the default value
+    
+    // the default value
+    union
+    {
+        BOOL        m_bValue;               // ELEMENT_TYPE_BOOLEAN
+        CHAR        m_cValue;               // ELEMENT_TYPE_I1
+        BYTE        m_byteValue;            // ELEMENT_TYPE_UI1
+        SHORT       m_sValue;               // ELEMENT_TYPE_I2
+        USHORT      m_usValue;              // ELEMENT_TYPE_UI2
+        LONG        m_lValue;               // ELEMENT_TYPE_I4
+        ULONG       m_ulValue;              // ELEMENT_TYPE_UI4
+        LONGLONG    m_llValue;              // ELEMENT_TYPE_I8
+        ULONGLONG   m_ullValue;             // ELEMENT_TYPE_UI8
+        FLOAT       m_fltValue;             // ELEMENT_TYPE_R4
+        DOUBLE      m_dblValue;             // ELEMENT_TYPE_R8
+        LPCWSTR     m_wzValue;              // ELEMENT_TYPE_STRING
+        IUnknown    *m_unkValue;            // ELEMENT_TYPE_CLASS       
+    };
+    ULONG   m_cbSize;   // default value size (for blob)
+    
+} MDDefaultValue;
+
+typedef struct
+{
+    RID         m_ridFieldCur;          // indexing to the field table
+    RID         m_ridFieldEnd;          // end index to field table
+} MD_CLASS_LAYOUT;
+
+typedef struct
+{
+    USHORT      usMajorVersion;         // Major Version.   
+    USHORT      usMinorVersion;         // Minor Version.
+    USHORT      usBuildNumber;          // Build Number.
+    USHORT      usRevisionNumber;       // Revision Number.
+    LPCSTR      szLocale;               // Locale.
+    DWORD       *rProcessor;            // Processor array.
+    ULONG       ulProcessor;            // [IN/OUT] Size of the processor array/Actual # of entries filled in.
+    OSINFO      *rOS;                   // OSINFO array.
+    ULONG       ulOS;                   // [IN/OUT]Size of the OSINFO array/Actual # of entries filled in.
+} AssemblyMetaDataInternal;
+
+typedef struct
+{
+    mdMethodDef m_memberdef;
+    DWORD       m_dwSemantics;
+} ASSOCIATE_RECORD;
+
+typedef BOOL (*PSIGCOMPARE)(PCCOR_SIGNATURE, DWORD, PCCOR_SIGNATURE, DWORD, void*);
+
+EXTERN_GUID(IID_IMDInternalImport, 0xce0f34ed, 0xbbc6, 0x11d2, 0x94, 0x1e, 0x0, 0x0, 0xf8, 0x8, 0x34, 0x60);
+#undef  INTERFACE
+#define INTERFACE IMDInternalImport
+DECLARE_INTERFACE_(IMDInternalImport, IUnknown)
+{
+    //*****************************************************************************
+    // return the count of entries of a given kind in a scope 
+    // For example, pass in mdtMethodDef will tell you how many MethodDef 
+    // contained in a scope
+    //*****************************************************************************
+    STDMETHOD_(ULONG, GetCountWithTokenKind)(// return hresult
+        DWORD       tkKind) PURE;           // [IN] pass in the kind of token. 
+
+    //*****************************************************************************
+    // enumerator for typedef
+    //*****************************************************************************
+    STDMETHOD(EnumTypeDefInit)(             // return hresult
+        HENUMInternal *phEnum) PURE;        // [OUT] buffer to fill for enumerator data
+
+    STDMETHOD_(ULONG, EnumTypeDefGetCount)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to retrieve information  
+
+    STDMETHOD_(void, EnumTypeDefReset)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to retrieve information  
+
+    STDMETHOD_(bool, EnumTypeDefNext)(      // return hresult
+        HENUMInternal *phEnum,              // [IN] input enum
+        mdTypeDef   *ptd) PURE;             // [OUT] return token
+
+    STDMETHOD_(void, EnumTypeDefClose)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to retrieve information  
+
+    //*****************************************************************************
+    // enumerator for MethodImpl
+    //*****************************************************************************
+    STDMETHOD(EnumMethodImplInit)(          // return hresult
+        mdTypeDef       td,                 // [IN] TypeDef over which to scope the enumeration.
+        HENUMInternal   *phEnumBody,        // [OUT] buffer to fill for enumerator data for MethodBody tokens.
+        HENUMInternal   *phEnumDecl) PURE;  // [OUT] buffer to fill for enumerator data for MethodDecl tokens.
+    
+    STDMETHOD_(ULONG, EnumMethodImplGetCount)(
+        HENUMInternal   *phEnumBody,        // [IN] MethodBody enumerator.  
+        HENUMInternal   *phEnumDecl) PURE;  // [IN] MethodDecl enumerator.
+    
+    STDMETHOD_(void, EnumMethodImplReset)(
+        HENUMInternal   *phEnumBody,        // [IN] MethodBody enumerator.
+        HENUMInternal   *phEnumDecl) PURE;  // [IN] MethodDecl enumerator.
+    
+    STDMETHOD(EnumMethodImplNext)(          // return hresult (S_OK = TRUE, S_FALSE = FALSE or error code)
+        HENUMInternal   *phEnumBody,        // [IN] input enum for MethodBody
+        HENUMInternal   *phEnumDecl,        // [IN] input enum for MethodDecl
+        mdToken         *ptkBody,           // [OUT] return token for MethodBody
+        mdToken         *ptkDecl) PURE;     // [OUT] return token for MethodDecl
+    
+    STDMETHOD_(void, EnumMethodImplClose)(
+        HENUMInternal   *phEnumBody,        // [IN] MethodBody enumerator.
+        HENUMInternal   *phEnumDecl) PURE;  // [IN] MethodDecl enumerator.
+    
+    //*****************************************
+    // Enumerator helpers for memberdef, memberref, interfaceimp,
+    // event, property, exception, param
+    //***************************************** 
+
+    STDMETHOD(EnumGlobalFunctionsInit)(     // return hresult
+        HENUMInternal   *phEnum) PURE;      // [OUT] buffer to fill for enumerator data
+
+    STDMETHOD(EnumGlobalFieldsInit)(        // return hresult
+        HENUMInternal   *phEnum) PURE;      // [OUT] buffer to fill for enumerator data
+
+    STDMETHOD(EnumInit)(                    // return S_FALSE if record not found
+        DWORD       tkKind,                 // [IN] which table to work on
+        mdToken     tkParent,               // [IN] token to scope the search
+        HENUMInternal *phEnum) PURE;        // [OUT] the enumerator to fill 
+
+    STDMETHOD(EnumAllInit)(                 // return S_FALSE if record not found
+        DWORD       tkKind,                 // [IN] which table to work on
+        HENUMInternal *phEnum) PURE;        // [OUT] the enumerator to fill 
+
+    STDMETHOD_(bool, EnumNext)(
+        HENUMInternal *phEnum,              // [IN] the enumerator to retrieve information  
+        mdToken     *ptk) PURE;             // [OUT] token to scope the search
+
+    STDMETHOD_(ULONG, EnumGetCount)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to retrieve information  
+
+    STDMETHOD_(void, EnumReset)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to be reset  
+
+    STDMETHOD_(void, EnumClose)(
+        HENUMInternal *phEnum) PURE;        // [IN] the enumerator to be closed
+
+    //*****************************************
+    // Enumerator helpers for declsecurity.
+    //*****************************************
+    STDMETHOD(EnumPermissionSetsInit)(      // return S_FALSE if record not found
+        mdToken     tkParent,               // [IN] token to scope the search
+        CorDeclSecurity Action,             // [IN] Action to scope the search
+        HENUMInternal *phEnum) PURE;        // [OUT] the enumerator to fill 
+
+    //*****************************************
+    // Enumerator helpers for CustomAttribute
+    //*****************************************
+    STDMETHOD(EnumCustomAttributeByNameInit)(// return S_FALSE if record not found
+        mdToken     tkParent,               // [IN] token to scope the search
+        LPCSTR      szName,                 // [IN] CustomAttribute's name to scope the search
+        HENUMInternal *phEnum) PURE;        // [OUT] the enumerator to fill 
+
+    //*****************************************
+    // Nagivator helper to navigate back to the parent token given a token.
+    // For example, given a memberdef token, it will return the containing typedef.
+    //
+    // the mapping is as following:
+    //  ---given child type---------parent type
+    //  mdMethodDef                 mdTypeDef
+    //  mdFieldDef                  mdTypeDef
+    //  mdInterfaceImpl             mdTypeDef
+    //  mdParam                     mdMethodDef
+    //  mdProperty                  mdTypeDef
+    //  mdEvent                     mdTypeDef
+    //
+    //***************************************** 
+    STDMETHOD(GetParentToken)(
+        mdToken     tkChild,                // [IN] given child token
+        mdToken     *ptkParent) PURE;       // [OUT] returning parent
+
+    //*****************************************
+    // Custom value helpers
+    //***************************************** 
+    STDMETHOD(GetCustomAttributeProps)(  // S_OK or error.
+        mdCustomAttribute at,               // [IN] The attribute.
+        mdToken     *ptkType) PURE;         // [OUT] Put attribute type here.
+    
+    STDMETHOD(GetCustomAttributeAsBlob)(
+        mdCustomAttribute cv,               // [IN] given custom value token
+        void const  **ppBlob,               // [OUT] return the pointer to internal blob
+        ULONG       *pcbSize) PURE;         // [OUT] return the size of the blob
+    
+    // returned void in v1.0/v1.1
+    STDMETHOD (GetScopeProps)(
+        LPCSTR      *pszName,               // [OUT] scope name
+        GUID        *pmvid) PURE;           // [OUT] version id
+    
+    // finding a particular method 
+    STDMETHOD(FindMethodDef)(
+        mdTypeDef   classdef,               // [IN] given typedef
+        LPCSTR      szName,                 // [IN] member name
+        PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature
+        ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob
+        mdMethodDef *pmd) PURE;             // [OUT] matching memberdef
+
+    // return a iSeq's param given a MethodDef
+    STDMETHOD(FindParamOfMethod)(           // S_OK or error.
+        mdMethodDef md,                     // [IN] The owning method of the param.
+        ULONG       iSeq,                   // [IN] The sequence # of the param.
+        mdParamDef  *pparamdef) PURE;       // [OUT] Put ParamDef token here.
+
+    //*****************************************
+    //
+    // GetName* functions
+    //
+    //*****************************************
+
+    // return the name and namespace of typedef
+    STDMETHOD(GetNameOfTypeDef)(
+        mdTypeDef   classdef,               // given classdef
+        LPCSTR      *pszname,               // return class name(unqualified)
+        LPCSTR      *psznamespace) PURE;    // return the name space name
+
+    STDMETHOD(GetIsDualOfTypeDef)(
+        mdTypeDef   classdef,               // [IN] given classdef.
+        ULONG       *pDual) PURE;           // [OUT] return dual flag here.
+
+    STDMETHOD(GetIfaceTypeOfTypeDef)(
+        mdTypeDef   classdef,               // [IN] given classdef.
+        ULONG       *pIface) PURE;          // [OUT] 0=dual, 1=vtable, 2=dispinterface
+
+    // get the name of either methoddef
+    STDMETHOD(GetNameOfMethodDef)(  // return the name of the memberdef in UTF8
+        mdMethodDef md,             // given memberdef
+        LPCSTR     *pszName) PURE;
+    
+    STDMETHOD(GetNameAndSigOfMethodDef)(
+        mdMethodDef      methoddef,         // [IN] given memberdef
+        PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to a blob value of CLR signature
+        ULONG           *pcbSigBlob,        // [OUT] count of bytes in the signature blob
+        LPCSTR          *pszName) PURE;
+    
+    // return the name of a FieldDef
+    STDMETHOD(GetNameOfFieldDef)(
+        mdFieldDef fd,              // given memberdef
+        LPCSTR    *pszName) PURE;
+    
+    // return the name of typeref
+    STDMETHOD(GetNameOfTypeRef)(
+        mdTypeRef   classref,               // [IN] given typeref
+        LPCSTR      *psznamespace,          // [OUT] return typeref name
+        LPCSTR      *pszname) PURE;         // [OUT] return typeref namespace
+    
+    // return the resolutionscope of typeref
+    STDMETHOD(GetResolutionScopeOfTypeRef)(
+        mdTypeRef classref,                 // given classref
+        mdToken  *ptkResolutionScope) PURE;
+    
+    // Find the type token given the name.
+    STDMETHOD(FindTypeRefByName)(
+        LPCSTR      szNamespace,            // [IN] Namespace for the TypeRef.
+        LPCSTR      szName,                 // [IN] Name of the TypeRef.
+        mdToken     tkResolutionScope,      // [IN] Resolution Scope fo the TypeRef.
+        mdTypeRef   *ptk) PURE;             // [OUT] TypeRef token returned.
+    
+    // return the TypeDef properties
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetTypeDefProps)(  
+        mdTypeDef   classdef,               // given classdef
+        DWORD       *pdwAttr,               // return flags on class, tdPublic, tdAbstract
+        mdToken     *ptkExtends) PURE;      // [OUT] Put base class TypeDef/TypeRef here
+    
+    // return the item's guid
+    STDMETHOD(GetItemGuid)(     
+        mdToken     tkObj,                  // [IN] given item.
+        CLSID       *pGuid) PURE;           // [out[ put guid here.
+
+    // Get enclosing class of the NestedClass.
+    STDMETHOD(GetNestedClassProps)(         // S_OK or error
+        mdTypeDef   tkNestedClass,          // [IN] NestedClass token.
+        mdTypeDef   *ptkEnclosingClass) PURE; // [OUT] EnclosingClass token.
+
+    // Get count of Nested classes given the enclosing class.
+    STDMETHOD(GetCountNestedClasses)(       // return count of Nested classes.
+        mdTypeDef   tkEnclosingClass,       // Enclosing class.
+        ULONG      *pcNestedClassesCount) PURE;
+    
+    // Return array of Nested classes given the enclosing class.
+    STDMETHOD(GetNestedClasses)(            // Return actual count.
+        mdTypeDef   tkEnclosingClass,       // [IN] Enclosing class.
+        mdTypeDef   *rNestedClasses,        // [OUT] Array of nested class tokens.
+        ULONG       ulNestedClasses,        // [IN] Size of array.
+        ULONG      *pcNestedClasses) PURE;
+
+    // return the ModuleRef properties
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetModuleRefProps)(
+        mdModuleRef mur,                    // [IN] moduleref token
+        LPCSTR      *pszName) PURE;         // [OUT] buffer to fill with the moduleref name
+
+    //*****************************************
+    //
+    // GetSig* functions
+    //
+    //*****************************************
+    STDMETHOD(GetSigOfMethodDef)(
+        mdMethodDef      methoddef,     // [IN] given memberdef
+        ULONG           *pcbSigBlob,    // [OUT] count of bytes in the signature blob
+        PCCOR_SIGNATURE *ppSig) PURE;
+    
+    STDMETHOD(GetSigOfFieldDef)(
+        mdMethodDef      methoddef,     // [IN] given memberdef
+        ULONG           *pcbSigBlob,    // [OUT] count of bytes in the signature blob
+        PCCOR_SIGNATURE *ppSig) PURE;
+    
+    STDMETHOD(GetSigFromToken)(
+        mdToken           tk, 
+        ULONG *           pcbSig, 
+        PCCOR_SIGNATURE * ppSig) PURE;
+    
+    
+    
+    //*****************************************
+    // get method property
+    //*****************************************
+    STDMETHOD(GetMethodDefProps)(
+        mdMethodDef md,             // The method for which to get props.
+        DWORD      *pdwFlags) PURE;
+    
+    //*****************************************
+    // return method implementation informaiton, like RVA and implflags
+    //*****************************************
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetMethodImplProps)(
+        mdToken     tk,                     // [IN] MethodDef
+        ULONG       *pulCodeRVA,            // [OUT] CodeRVA
+        DWORD       *pdwImplFlags) PURE;    // [OUT] Impl. Flags
+
+    //*****************************************
+    // return method implementation informaiton, like RVA and implflags
+    //*****************************************
+    STDMETHOD(GetFieldRVA)(
+        mdFieldDef  fd,                     // [IN] fielddef 
+        ULONG       *pulCodeRVA) PURE;      // [OUT] CodeRVA
+    
+    //*****************************************
+    // get field property
+    //*****************************************
+    STDMETHOD(GetFieldDefProps)(
+        mdFieldDef fd,                  // [IN] given fielddef
+        DWORD     *pdwFlags) PURE;      // [OUT] return fdPublic, fdPrive, etc flags
+    
+    //*****************************************************************************
+    // return default value of a token(could be paramdef, fielddef, or property
+    //*****************************************************************************
+    STDMETHOD(GetDefaultValue)(  
+        mdToken     tk,                     // [IN] given FieldDef, ParamDef, or Property
+        MDDefaultValue *pDefaultValue) PURE;// [OUT] default value to fill
+
+    
+    //*****************************************
+    // get dispid of a MethodDef or a FieldDef
+    //*****************************************
+    STDMETHOD(GetDispIdOfMemberDef)(        // return hresult
+        mdToken     tk,                     // [IN] given methoddef or fielddef
+        ULONG       *pDispid) PURE;         // [OUT] Put the dispid here.
+
+    //*****************************************
+    // return TypeRef/TypeDef given an InterfaceImpl token
+    //*****************************************
+    STDMETHOD(GetTypeOfInterfaceImpl)(  // return the TypeRef/typedef token for the interfaceimpl
+        mdInterfaceImpl iiImpl,         // given a interfaceimpl
+        mdToken        *ptkType) PURE;
+    
+    //*****************************************
+    // look up function for TypeDef
+    //*****************************************
+    STDMETHOD(FindTypeDef)(
+        LPCSTR      szNamespace,            // [IN] Namespace for the TypeDef.
+        LPCSTR      szName,                 // [IN] Name of the TypeDef.
+        mdToken     tkEnclosingClass,       // [IN] TypeRef/TypeDef Token for the enclosing class.
+        mdTypeDef   *ptypedef) PURE;        // [IN] return typedef
+
+    //*****************************************
+    // return name and sig of a memberref
+    //*****************************************
+    STDMETHOD(GetNameAndSigOfMemberRef)(    // return name here
+        mdMemberRef      memberref,         // given memberref
+        PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to a blob value of CLR signature
+        ULONG           *pcbSigBlob,        // [OUT] count of bytes in the signature blob
+        LPCSTR          *pszName) PURE;
+    
+    //*****************************************************************************
+    // Given memberref, return the parent. It can be TypeRef, ModuleRef, MethodDef
+    //*****************************************************************************
+    STDMETHOD(GetParentOfMemberRef)(
+        mdMemberRef memberref,          // given memberref
+        mdToken    *ptkParent) PURE;    // return the parent token
+    
+    STDMETHOD(GetParamDefProps)(
+        mdParamDef paramdef,        // given a paramdef
+        USHORT    *pusSequence,     // [OUT] slot number for this parameter
+        DWORD     *pdwAttr,         // [OUT] flags
+        LPCSTR    *pszName) PURE;   // [OUT] return the name of the parameter
+    
+    STDMETHOD(GetPropertyInfoForMethodDef)( // Result.
+        mdMethodDef md,                     // [IN] memberdef
+        mdProperty  *ppd,                   // [OUT] put property token here
+        LPCSTR      *pName,                 // [OUT] put pointer to name here
+        ULONG       *pSemantic) PURE;       // [OUT] put semantic here
+    
+    //*****************************************
+    // class layout/sequence information
+    //*****************************************
+    STDMETHOD(GetClassPackSize)(            // return error if class doesn't have packsize
+        mdTypeDef   td,                     // [IN] give typedef
+        ULONG       *pdwPackSize) PURE;     // [OUT] 1, 2, 4, 8, or 16
+
+    STDMETHOD(GetClassTotalSize)(           // return error if class doesn't have total size info
+        mdTypeDef   td,                     // [IN] give typedef
+        ULONG       *pdwClassSize) PURE;    // [OUT] return the total size of the class
+
+    STDMETHOD(GetClassLayoutInit)(
+        mdTypeDef   td,                     // [IN] give typedef
+        MD_CLASS_LAYOUT *pLayout) PURE;     // [OUT] set up the status of query here
+
+    STDMETHOD(GetClassLayoutNext)(
+        MD_CLASS_LAYOUT *pLayout,           // [IN|OUT] set up the status of query here
+        mdFieldDef  *pfd,                   // [OUT] return the fielddef
+        ULONG       *pulOffset) PURE;       // [OUT] return the offset/ulSequence associate with it
+
+    //*****************************************
+    // marshal information of a field
+    //*****************************************
+    STDMETHOD(GetFieldMarshal)(             // return error if no native type associate with the token
+        mdFieldDef  fd,                     // [IN] given fielddef
+        PCCOR_SIGNATURE *pSigNativeType,    // [OUT] the native type signature
+        ULONG       *pcbNativeType) PURE;   // [OUT] the count of bytes of *ppvNativeType
+
+
+    //*****************************************
+    // property APIs
+    //*****************************************
+    // find a property by name
+    STDMETHOD(FindProperty)(
+        mdTypeDef   td,                     // [IN] given a typdef
+        LPCSTR      szPropName,             // [IN] property name
+        mdProperty  *pProp) PURE;           // [OUT] return property token
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetPropertyProps)(
+        mdProperty  prop,                   // [IN] property token
+        LPCSTR      *szProperty,            // [OUT] property name
+        DWORD       *pdwPropFlags,          // [OUT] property flags.
+        PCCOR_SIGNATURE *ppvSig,            // [OUT] property type. pointing to meta data internal blob
+        ULONG       *pcbSig) PURE;          // [OUT] count of bytes in *ppvSig
+
+    //**********************************
+    // Event APIs
+    //**********************************
+    STDMETHOD(FindEvent)(
+        mdTypeDef   td,                     // [IN] given a typdef
+        LPCSTR      szEventName,            // [IN] event name
+        mdEvent     *pEvent) PURE;          // [OUT] return event token
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetEventProps)(
+        mdEvent     ev,                     // [IN] event token
+        LPCSTR      *pszEvent,              // [OUT] Event name
+        DWORD       *pdwEventFlags,         // [OUT] Event flags.
+        mdToken     *ptkEventType) PURE;    // [OUT] EventType class
+
+
+    //**********************************
+    // find a particular associate of a property or an event
+    //**********************************
+    STDMETHOD(FindAssociate)(
+        mdToken     evprop,                 // [IN] given a property or event token
+        DWORD       associate,              // [IN] given a associate semantics(setter, getter, testdefault, reset, AddOn, RemoveOn, Fire)
+        mdMethodDef *pmd) PURE;             // [OUT] return method def token 
+
+    // Note, void function in v1.0/v1.1
+    STDMETHOD(EnumAssociateInit)(
+        mdToken     evprop,                 // [IN] given a property or an event token
+        HENUMInternal *phEnum) PURE;        // [OUT] cursor to hold the query result
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetAllAssociates)(
+        HENUMInternal *phEnum,              // [IN] query result form GetPropertyAssociateCounts
+        ASSOCIATE_RECORD *pAssociateRec,    // [OUT] struct to fill for output
+        ULONG       cAssociateRec) PURE;    // [IN] size of the buffer
+
+
+    //**********************************
+    // Get info about a PermissionSet.
+    //**********************************
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetPermissionSetProps)(
+        mdPermission pm,                    // [IN] the permission token.
+        DWORD       *pdwAction,             // [OUT] CorDeclSecurity.
+        void const  **ppvPermission,        // [OUT] permission blob.
+        ULONG       *pcbPermission) PURE;   // [OUT] count of bytes of pvPermission.
+
+    //****************************************
+    // Get the String given the String token.
+    // Returns a pointer to the string, or NULL in case of error.
+    //****************************************
+    STDMETHOD(GetUserString)(
+        mdString stk,                   // [IN] the string token.
+        ULONG   *pchString,             // [OUT] count of characters in the string.
+        BOOL    *pbIs80Plus,            // [OUT] specifies where there are extended characters >= 0x80.
+        LPCWSTR *pwszUserString) PURE;
+    
+    //*****************************************************************************
+    // p-invoke APIs.
+    //*****************************************************************************
+    STDMETHOD(GetPinvokeMap)(
+        mdToken     tk,                     // [IN] FieldDef, MethodDef.
+        DWORD       *pdwMappingFlags,       // [OUT] Flags used for mapping.
+        LPCSTR      *pszImportName,         // [OUT] Import name.
+        mdModuleRef *pmrImportDLL) PURE;    // [OUT] ModuleRef token for the target DLL.
+
+    //*****************************************************************************
+    // helpers to convert a text signature to a com format
+    //*****************************************************************************
+    STDMETHOD(ConvertTextSigToComSig)(      // Return hresult.
+        BOOL        fCreateTrIfNotFound,    // [IN] create typeref if not found
+        LPCSTR      pSignature,             // [IN] class file format signature
+        CQuickBytes *pqbNewSig,             // [OUT] place holder for CLR signature
+        ULONG       *pcbCount) PURE;        // [OUT] the result size of signature
+
+    //*****************************************************************************
+    // Assembly MetaData APIs.
+    //*****************************************************************************
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetAssemblyProps)(
+        mdAssembly  mda,                    // [IN] The Assembly for which to get the properties.
+        const void  **ppbPublicKey,         // [OUT] Pointer to the public key.
+        ULONG       *pcbPublicKey,          // [OUT] Count of bytes in the public key.
+        ULONG       *pulHashAlgId,          // [OUT] Hash Algorithm.
+        LPCSTR      *pszName,               // [OUT] Buffer to fill with name.
+        AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData.
+        DWORD       *pdwAssemblyFlags) PURE;// [OUT] Flags.
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetAssemblyRefProps)(
+        mdAssemblyRef mdar,                 // [IN] The AssemblyRef for which to get the properties.
+        const void  **ppbPublicKeyOrToken,  // [OUT] Pointer to the public key or token.
+        ULONG       *pcbPublicKeyOrToken,   // [OUT] Count of bytes in the public key or token.
+        LPCSTR      *pszName,               // [OUT] Buffer to fill with name.
+        AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData.
+        const void  **ppbHashValue,         // [OUT] Hash blob.
+        ULONG       *pcbHashValue,          // [OUT] Count of bytes in the hash blob.
+        DWORD       *pdwAssemblyRefFlags) PURE; // [OUT] Flags.
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetFileProps)(
+        mdFile      mdf,                    // [IN] The File for which to get the properties.
+        LPCSTR      *pszName,               // [OUT] Buffer to fill with name.
+        const void  **ppbHashValue,         // [OUT] Pointer to the Hash Value Blob.
+        ULONG       *pcbHashValue,          // [OUT] Count of bytes in the Hash Value Blob.
+        DWORD       *pdwFileFlags) PURE;    // [OUT] Flags.
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetExportedTypeProps)(
+        mdExportedType   mdct,              // [IN] The ExportedType for which to get the properties.
+        LPCSTR      *pszNamespace,          // [OUT] Namespace.
+        LPCSTR      *pszName,               // [OUT] Name.
+        mdToken     *ptkImplementation,     // [OUT] mdFile or mdAssemblyRef that provides the ExportedType.
+        mdTypeDef   *ptkTypeDef,            // [OUT] TypeDef token within the file.
+        DWORD       *pdwExportedTypeFlags) PURE; // [OUT] Flags.
+
+    // returned void in v1.0/v1.1
+    STDMETHOD(GetManifestResourceProps)(
+        mdManifestResource  mdmr,           // [IN] The ManifestResource for which to get the properties.
+        LPCSTR      *pszName,               // [OUT] Buffer to fill with name.
+        mdToken     *ptkImplementation,     // [OUT] mdFile or mdAssemblyRef that provides the ExportedType.
+        DWORD       *pdwOffset,             // [OUT] Offset to the beginning of the resource within the file.
+        DWORD       *pdwResourceFlags) PURE;// [OUT] Flags.
+
+    STDMETHOD(FindExportedTypeByName)(      // S_OK or error
+        LPCSTR      szNamespace,            // [IN] Namespace of the ExportedType.   
+        LPCSTR      szName,                 // [IN] Name of the ExportedType.   
+        mdExportedType   tkEnclosingType,   // [IN] ExportedType for the enclosing class.
+        mdExportedType   *pmct) PURE;       // [OUT] Put ExportedType token here.
+
+    STDMETHOD(FindManifestResourceByName)(  // S_OK or error
+        LPCSTR      szName,                 // [IN] Name of the ManifestResource.   
+        mdManifestResource *pmmr) PURE;     // [OUT] Put ManifestResource token here.
+
+    STDMETHOD(GetAssemblyFromScope)(        // S_OK or error
+        mdAssembly  *ptkAssembly) PURE;     // [OUT] Put token here.
+
+    STDMETHOD(GetCustomAttributeByName)(    // S_OK or error
+        mdToken     tkObj,                  // [IN] Object with Custom Attribute.
+        LPCUTF8     szName,                 // [IN] Name of desired Custom Attribute.
+        const void  **ppData,               // [OUT] Put pointer to data here.
+        ULONG       *pcbData) PURE;         // [OUT] Put size of data here.
+
+    // Note: The return type of this method was void in v1
+    STDMETHOD(GetTypeSpecFromToken)(      // S_OK or error.
+        mdTypeSpec typespec,                // [IN] Signature token.
+        PCCOR_SIGNATURE *ppvSig,            // [OUT] return pointer to token.
+        ULONG       *pcbSig) PURE;               // [OUT] return size of signature.
+
+    STDMETHOD(SetUserContextData)(          // S_OK or E_NOTIMPL
+        IUnknown    *pIUnk) PURE;           // The user context.
+
+    STDMETHOD_(BOOL, IsValidToken)(         // True or False.
+        mdToken     tk) PURE;               // [IN] Given token.
+
+    STDMETHOD(TranslateSigWithScope)(
+        IMDInternalImport *pAssemImport,    // [IN] import assembly scope.
+        const void  *pbHashValue,           // [IN] hash value for the import assembly.
+        ULONG       cbHashValue,            // [IN] count of bytes in the hash value.
+        PCCOR_SIGNATURE pbSigBlob,          // [IN] signature in the importing scope
+        ULONG       cbSigBlob,              // [IN] count of bytes of signature
+        IMetaDataAssemblyEmit *pAssemEmit,  // [IN] assembly emit scope.
+        IMetaDataEmit *emit,                // [IN] emit interface
+        CQuickBytes *pqkSigEmit,            // [OUT] buffer to hold translated signature
+        ULONG       *pcbSig) PURE;          // [OUT] count of bytes in the translated signature
+
+    // since SOS does not need to call method below, change return value to IUnknown* (from IMetaModelCommon*)
+    STDMETHOD_(IUnknown*, GetMetaModelCommon)(  // Return MetaModelCommon interface.
+        ) PURE;
+
+    STDMETHOD_(IUnknown *, GetCachedPublicInterface)(BOOL fWithLock) PURE;   // return the cached public interface
+    STDMETHOD(SetCachedPublicInterface)(IUnknown *pUnk) PURE;  // no return value
+    // since SOS does not use the next 2 methods replace UTSemReadWrite* with void* in the signature
+    STDMETHOD_(void*, GetReaderWriterLock)() PURE;   // return the reader writer lock
+    STDMETHOD(SetReaderWriterLock)(void * pSem) PURE; 
+
+    STDMETHOD_(mdModule, GetModuleFromScope)() PURE;             // [OUT] Put mdModule token here.
+
+
+    //-----------------------------------------------------------------
+    // Additional custom methods
+
+    // finding a particular method 
+    STDMETHOD(FindMethodDefUsingCompare)(
+        mdTypeDef   classdef,               // [IN] given typedef
+        LPCSTR      szName,                 // [IN] member name
+        PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature
+        ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob
+        PSIGCOMPARE pSignatureCompare,      // [IN] Routine to compare signatures
+        void*       pSignatureArgs,         // [IN] Additional info to supply the compare function
+        mdMethodDef *pmd) PURE;             // [OUT] matching memberdef
+
+    // Additional v2 methods.
+
+    //*****************************************
+    // return a field offset for a given field
+    //*****************************************
+    STDMETHOD(GetFieldOffset)(
+        mdFieldDef  fd,                     // [IN] fielddef 
+        ULONG       *pulOffset) PURE;       // [OUT] FieldOffset
+
+    STDMETHOD(GetMethodSpecProps)(
+        mdMethodSpec ms,                    // [IN] The method instantiation
+        mdToken *tkParent,                  // [OUT] MethodDef or MemberRef
+        PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
+        ULONG       *pcbSigBlob) PURE;      // [OUT] actual size of signature blob  
+
+    STDMETHOD(GetTableInfoWithIndex)(
+        ULONG      index,                   // [IN] pass in the table index
+        void       **pTable,                // [OUT] pointer to table at index
+        void       **pTableSize) PURE;      // [OUT] size of table at index
+
+    STDMETHOD(ApplyEditAndContinue)(
+        void        *pDeltaMD,              // [IN] the delta metadata
+        ULONG       cbDeltaMD,              // [IN] length of pData
+        IMDInternalImport **ppv) PURE;      // [OUT] the resulting metadata interface
+
+    //**********************************
+    // Generics APIs
+    //**********************************
+    STDMETHOD(GetGenericParamProps)(        // S_OK or error.
+        mdGenericParam rd,                  // [IN] The type parameter
+        ULONG* pulSequence,                 // [OUT] Parameter sequence number
+        DWORD* pdwAttr,                     // [OUT] Type parameter flags (for future use)       
+        mdToken *ptOwner,                   // [OUT] The owner (TypeDef or MethodDef) 
+        DWORD *reserved,                    // [OUT] The kind (TypeDef/Ref/Spec, for future use)
+        LPCSTR *szName) PURE;               // [OUT] The name
+
+    STDMETHOD(GetGenericParamConstraintProps)(      // S_OK or error.
+        mdGenericParamConstraint rd,            // [IN] The constraint token
+        mdGenericParam *ptGenericParam,         // [OUT] GenericParam that is constrained
+        mdToken      *ptkConstraintType) PURE;  // [OUT] TypeDef/Ref/Spec constraint
+
+    //*****************************************************************************
+    // This function gets the "built for" version of a metadata scope.
+    //  NOTE: if the scope has never been saved, it will not have a built-for
+    //  version, and an empty string will be returned.
+    //*****************************************************************************
+    STDMETHOD(GetVersionString)(    // S_OK or error.
+        LPCSTR      *pVer) PURE;       // [OUT] Put version string here.
+
+
+    STDMETHOD(SafeAndSlowEnumCustomAttributeByNameInit)(// return S_FALSE if record not found
+        mdToken     tkParent,               // [IN] token to scope the search
+        LPCSTR      szName,                 // [IN] CustomAttribute's name to scope the search
+        HENUMInternal *phEnum) PURE;             // [OUT] The enumerator
+
+    STDMETHOD(SafeAndSlowEnumCustomAttributeByNameNext)(// return S_FALSE if record not found
+        mdToken     tkParent,               // [IN] token to scope the search
+        LPCSTR      szName,                 // [IN] CustomAttribute's name to scope the search
+        HENUMInternal *phEnum,              // [IN] The enumerator
+        mdCustomAttribute *mdAttribute) PURE;     // [OUT] The custom attribute that was found 
+
+
+    STDMETHOD(GetTypeDefRefTokenInTypeSpec)(// return S_FALSE if enclosing type does not have a token
+        mdTypeSpec  tkTypeSpec,               // [IN] TypeSpec token to look at
+        mdToken    *tkEnclosedToken) PURE;    // [OUT] The enclosed type token
+
+#define MD_STREAM_VER_1X    0x10000
+#define MD_STREAM_VER_2_B1  0x10001
+#define MD_STREAM_VER_2     0x20000
+    STDMETHOD_(DWORD, GetMetadataStreamVersion)() PURE;  //returns DWORD with major version of
+                                // MD stream in senior word and minor version--in junior word
+
+    STDMETHOD(GetNameOfCustomAttribute)(// S_OK or error
+        mdCustomAttribute mdAttribute,      // [IN] The Custom Attribute
+        LPCUTF8          *pszNamespace,     // [OUT] Namespace of Custom Attribute.
+        LPCUTF8          *pszName) PURE;    // [OUT] Name of Custom Attribute.
+
+    STDMETHOD(SetOptimizeAccessForSpeed)(// S_OK or error
+        BOOL    fOptSpeed) PURE;
+
+    STDMETHOD(SetVerifiedByTrustedSource)(// S_OK or error
+        BOOL    fVerified) PURE;
+
+};  // IMDInternalImport
+
+EXTERN_GUID(IID_IMetaDataHelper, 0xad93d71d, 0xe1f2, 0x11d1, 0x94, 0x9, 0x0, 0x0, 0xf8, 0x8, 0x34, 0x60);
+
+#undef  INTERFACE
+#define INTERFACE IMetaDataHelper
+DECLARE_INTERFACE_(IMetaDataHelper, IUnknown)
+{
+    // helper functions
+    // This function is exposing the ability to translate signature from a given
+    // source scope to a given target scope.
+    // 
+    STDMETHOD(TranslateSigWithScope)(
+        IMetaDataAssemblyImport *pAssemImport, // [IN] importing assembly interface
+        const void  *pbHashValue,           // [IN] Hash Blob for Assembly.
+        ULONG       cbHashValue,            // [IN] Count of bytes.
+        IMetaDataImport *import,            // [IN] importing interface
+        PCCOR_SIGNATURE pbSigBlob,          // [IN] signature in the importing scope
+        ULONG       cbSigBlob,              // [IN] count of bytes of signature
+        IMetaDataAssemblyEmit *pAssemEmit,  // [IN] emit assembly interface
+        IMetaDataEmit *emit,                // [IN] emit interface
+        PCOR_SIGNATURE pvTranslatedSig,     // [OUT] buffer to hold translated signature
+        ULONG       cbTranslatedSigMax,
+        ULONG       *pcbTranslatedSig) PURE;// [OUT] count of bytes in the translated signature
+
+    STDMETHOD(GetMetadata)(
+        ULONG       ulSelect,               // [IN] Selector.
+        void        **ppData) PURE;         // [OUT] Put pointer to data here.
+
+    STDMETHOD_(IUnknown *, GetCachedInternalInterface)(BOOL fWithLock) PURE;    // S_OK or error
+    STDMETHOD(SetCachedInternalInterface)(IUnknown * pUnk) PURE;    // S_OK or error
+    // since SOS does not use the next 2 methods replace UTSemReadWrite* with void* in the signature
+    STDMETHOD_(void*, GetReaderWriterLock)() PURE;   // return the reader writer lock
+    STDMETHOD(SetReaderWriterLock)(void * pSem) PURE;
+};
+
+/********************************************************************************/
+
+// Fine grained formatting flags used by the PrettyPrint APIs below.
+// Upto FormatStubInfo they mirror the values used by TypeString, after that
+// they're used to enable specifying differences between the ILDASM-style 
+// output and the C#-like output prefered by the rest of SOS.
+typedef enum 
+{
+  FormatBasic       =   0x00000000, // Not a bitmask, simply the tersest flag settings possible
+  FormatNamespace   =   0x00000001, // Include namespace and/or enclosing class names in type names
+  FormatFullInst    =   0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
+  FormatAssembly    =   0x00000004, // Include assembly display name in type names
+  FormatSignature   =   0x00000008, // Include signature in method names
+  FormatNoVersion   =   0x00000010, // Suppress version and culture information in all assembly names
+  FormatDebug       =   0x00000020, // For debug printing of types only
+  FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
+  FormatStubInfo    =   0x00000080, // Include stub info like {unbox-stub}
+  // following flags are not present in TypeString::FormatFlags
+  FormatSlashSep    =   0x00000100, // Whether nested types are NS.C1/C2 or NS.C1+C2
+  FormatKwInNames   =   0x00000200, // Whether "class" and "valuetype" appear in type names in certain instances
+  FormatCSharp      =   0x0000004b, // Used to generate a C#-like string representation of the token
+  FormatILDasm      =   0x000003ff, // Used to generate an ILDASM-style string representation of the token
+}
+PPFormatFlags;
+
+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);
+
+const char* PrettyPrintClass(
+    CQuickBytes *out,                   // where to put the pretty printed string   
+       mdToken tk,                                                     // The class token to look up 
+    IMDInternalImport *pIMDI,           // ptr to IMDInternalImport class with ComSig
+    DWORD formatFlags = FormatILDasm);
+
+// We have a proliferation of functions that translate a (module/token) pair to
+// a string, but none of them were as complete as PrettyPrintClass. Most were
+// not handling generic instantiations appropriately. PrettyPrintClassFromToken
+// provides this missing functionality. If passed "FormatCSharp" it will generate
+// a name fitting the format used throughout SOS, with the exception of !dumpil
+// (due to its ILDASM ancestry).
+// TODO: Refactor the code in PrettyPrintClassFromToken, NameForTypeDef_s,
+// TODO: NameForToken_s, MDInfo::TypeDef/RefName
+void PrettyPrintClassFromToken(
+    TADDR moduleAddr,                   // the module containing the token
+    mdToken tok,                        // the class token to look up
+    __out_ecount(cbName) WCHAR* mdName, // where to put the pretty printed string
+    size_t cbName,                      // the capacity of the buffer
+    DWORD formatFlags = FormatCSharp);  // the format flags for the types
+
+inline HRESULT GetMDInternalFromImport(IMetaDataImport* pIMDImport, IMDInternalImport **ppIMDI)
+{
+    HRESULT hresult = E_FAIL;
+    IUnknown *pUnk = NULL;
+    IMetaDataHelper *pIMDH = NULL;
+
+    IfErrGoTo(pIMDImport->QueryInterface(IID_IMetaDataHelper, (void**)&pIMDH), Cleanup);
+    pUnk = pIMDH->GetCachedInternalInterface(FALSE);
+    if (pUnk == NULL)
+        goto Cleanup;
+    IfErrGoTo(pUnk->QueryInterface(IID_IMDInternalImport, (void**)ppIMDI), Cleanup);
+
+Cleanup:
+    if (pUnk)
+        pUnk->Release();
+    if (pIMDH != NULL)
+        pIMDH->Release();
+
+    return hresult;
+}
+
+#endif
index 0e2568b9df1e7584481acddfc2497fe63d73fe27..e13501b836a35f6c7ed0f02471f8b88cdcabe38b 100644 (file)
@@ -7,6 +7,8 @@
 #include <iostream>
 #include <unordered_map>
 
+#include <winerror.h>
+
 #include "torelease.h"
 #include "cputil.h"
 #include "logger.h"