⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdbghook.cpp

📁 C语言库函数的原型,有用的拿去
💻 CPP
📖 第 1 页 / 共 2 页
字号:
);

template<>
static int __cdecl _CrtSetReportHook2_thunk
(
    int mode,
    _CRT_REPORT_HOOK pfnNewHook
)
{
    return _CrtSetReportHook2(mode, pfnNewHook);
}

template<>
static int __cdecl _CrtSetReportHook2_thunk
(
    int mode,
    _CRT_REPORT_HOOKW pfnNewHook
)
{
    return _CrtSetReportHookW2(mode, pfnNewHook);
}

template<typename HookType, typename CharType>
class CCrtReportHook2DB
{
public:
    struct CReportHookList
    {
        CReportHookList *m_pNext;
        CReportHookList *m_pPrev;
        HookType m_Hook;
        int m_Refcount;

        CReportHookList()
            : m_pNext(NULL), m_pPrev(NULL), m_Hook(NULL), m_Refcount(0)
        {
        }

        static CReportHookList* create()
        {
            return reinterpret_cast<CReportHookList*>(calloc(1, sizeof(CReportHookList)));
        }

        static void destroy(CReportHookList* pReportHookList)
        {
            free(pReportHookList);
        }
    };

    CReportHookList *findHook(HookType pfnHook)
    {
        CReportHookList *retval=NULL;

        for (retval = m_HeadNode.m_pNext;
                retval != NULL && retval->m_Hook != pfnHook;
                retval = retval->m_pNext);

        return retval;
    }

    int updateHook(CReportHookList *pCReportHookList)
    {
        int retval = 0;
        if (pCReportHookList->m_pPrev != NULL)
        {
            disconnect(pCReportHookList);
            setHead(pCReportHookList);
            retval = pCReportHookList->m_Refcount++;
        }
        else
        {
            setHead(pCReportHookList);
            retval = pCReportHookList->m_Refcount = 1;
        }
        return retval;
    }

    int deleteHook(CReportHookList *pCReportHookList)
    {
        int retval = 0;
        if ((retval = --pCReportHookList->m_Refcount) == 0)
        {
            disconnect(pCReportHookList);
            CReportHookList::destroy(pCReportHookList);
        }
        return retval;
    }

    /* lock must be already held */
    int callReportHooks(int i, CharType *pCh, int *pInt)
    {
        int retval = 0;
        for (CReportHookList *ptmp = m_HeadNode.m_pNext;
                ptmp != NULL;
                ptmp = ptmp->m_pNext)
        {
            if (ptmp->m_Hook)
            {
                if (retval = (*(ptmp->m_Hook))(i, pCh, pInt))
                    break;
            }
        }
        return retval;
    }

    /* lock must be already held */
    void removeReportHooks()
    {
        CReportHookList* ptmp = m_HeadNode.m_pNext;
        while (ptmp != NULL)
        {
            CReportHookList* current = ptmp;
            ptmp = ptmp->m_pNext;
            CReportHookList::destroy(current);
        }
    }

    CCrtReportHook2DB()
    {
    }

    static __declspec(appdomain) bool callback_registered;
    static __declspec(appdomain) class CCrtReportHook2DB<HookType, CharType> __ReportHookDB;

private:
    void disconnect(CReportHookList* pCReportHookList)
    {
        // Remove an item from the list

        // Assume item is in list
        pCReportHookList->m_pPrev->m_pNext = pCReportHookList->m_pNext;

        // Check whether item is at end of list
        if (pCReportHookList->m_pNext)
        {
            pCReportHookList->m_pNext->m_pPrev = pCReportHookList->m_pPrev;
        }
    }

    void setHead(CReportHookList* pCReportHookList)
    {
        pCReportHookList->m_pNext = m_HeadNode.m_pNext;
        if (pCReportHookList->m_pNext != NULL)
        {
            pCReportHookList->m_pNext->m_pPrev = pCReportHookList;
        }
        m_HeadNode.m_pNext = pCReportHookList;
        pCReportHookList->m_pPrev = &m_HeadNode;
    }

    // Data members
private:
    CReportHookList m_HeadNode;
};

template<typename HookType, typename CharType>
__declspec(appdomain) bool CCrtReportHook2DB<HookType, CharType>::callback_registered=false;

template<typename HookType, typename CharType>
__declspec(appdomain) CCrtReportHook2DB<HookType, CharType> CCrtReportHook2DB<HookType, CharType>::__ReportHookDB;

template<typename CharType, typename DBType>
static int __cdecl _CrtReportHook2_managed_thunk(int i, CharType *pCh, int *pInt)
{
    /* lock was already taken by caller */
    return DBType::__ReportHookDB.callReportHooks(i, pCh, pInt);
}

template<typename NativeHookType, typename CharType, typename DBType>
static void __clrcall _CrtReportHook2_managed_cleanup(void)
{
    _CrtSetReportHook2_thunk(_CRT_RPTHOOK_REMOVE, static_cast<NativeHookType>(_CrtReportHook2_managed_thunk<CharType, DBType>) );

    _mlock(_DEBUG_LOCK);
    __try
    {
        DBType::__ReportHookDB.removeReportHooks();
    }
    __finally
    {
        _munlock(_DEBUG_LOCK);
    }
}

/***
*_CRT_REPORT_HOOK_M _CrtSetReportHook2() - configure client report hook in list
*
*Purpose:
*       Install or remove a client report hook from the report list.  Exists
*       separately from _CrtSetReportHook because the older function doesn't
*       work well in an environment where DLLs that are loaded and unloaded
*       dynamically out of LIFO order want to install report hooks.
*
*Entry:
*       int mode - _CRT_RPTHOOK_INSTALL or _CRT_RPTHOOK_REMOVE
*       _CRT_REPORT_HOOK_M pfnNewHook - report hook to install/remove/query
*
*Exit:
*       Returns -1 if an error was encountered, with EINVAL or ENOMEM set,
*       else returns the reference count of pfnNewHook after the call.
*
*Exceptions:
*       Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

template<typename NativeHookType, typename HookType, typename CharType, typename DBType>
int __cdecl _CrtSetReportHook2_impl
(
    int mode,
    HookType pfnNewHook,
    int (* pfnHook)(int, NativeHookType)
)
{
    DBType::CReportHookList *pHook=NULL;
    int ret=0;

    /* validation section */
    _VALIDATE_RETURN(mode == _CRT_RPTHOOK_INSTALL || mode == _CRT_RPTHOOK_REMOVE, EINVAL, -1);
    _VALIDATE_RETURN(pfnNewHook != NULL, EINVAL, -1);

    _mlock(_DEBUG_LOCK);
    __try
    {

        /* Search for new hook function to see if it's already installed */
        pHook = DBType::__ReportHookDB.findHook(pfnNewHook);

        if (mode == _CRT_RPTHOOK_REMOVE)
        {
            /* Remove request - free list node if refcount goes to zero */
            if (pHook != NULL)
            {
                DBType::__ReportHookDB.deleteHook(pHook);
            }
            else
            {
                _RPTF0(_CRT_ASSERT, "The hook function is not in the list!");
                ret = -1;
                errno = EINVAL;
            }
        }
        else
        {
            /* Insert request */
            if (pHook != NULL)
            {
                /* Hook function already registered, move to head of list */
                ret = DBType::__ReportHookDB.updateHook(pHook);
            }
            else
            {
                /* Hook function not already registered, insert new node */
                pHook = DBType::CReportHookList::create();
                if (pHook == NULL)
                {
                    /* malloc fails: we do not assert here */
                    ret = -1;
                    errno = ENOMEM;
                }
                else
                {
                    pHook->m_Hook = pfnNewHook;
                    ret = DBType::__ReportHookDB.updateHook(pHook);
                    if (DBType::callback_registered == false)
                    {
                        if(_atexit_m_appdomain(_CrtReportHook2_managed_cleanup<NativeHookType, CharType, DBType>)!=0)
                        {
                            ret=-1;
                            errno=ENOMEM;
                        }
                        else
                        {
                            pfnHook(_CRT_RPTHOOK_INSTALL, static_cast<NativeHookType>(_CrtReportHook2_managed_thunk<CharType, DBType>));

                            DBType::callback_registered=true;
                        }
                    }
                }
            }
        }

    }
    __finally
    {
        _munlock(_DEBUG_LOCK);
    }

    return ret;
}

_MRTIMP int __cdecl _CrtSetReportHook2
(
    int mode,
    _CRT_REPORT_HOOK_M pfnNewHook
)
{
    return _CrtSetReportHook2_impl<_CRT_REPORT_HOOK, _CRT_REPORT_HOOK_M, char, CCrtReportHook2DB<_CRT_REPORT_HOOK_M, char> >(mode, pfnNewHook, _CrtSetReportHook2_thunk );
}

_MRTIMP int __cdecl _CrtSetReportHookW2
(
    int mode,
    _CRT_REPORT_HOOKW_M pfnNewHook
)
{
    return _CrtSetReportHook2_impl<_CRT_REPORT_HOOKW, _CRT_REPORT_HOOKW_M, wchar_t, CCrtReportHook2DB<_CRT_REPORT_HOOKW_M, wchar_t> >(mode, pfnNewHook, _CrtSetReportHook2_thunk);
}
#endif  /* _DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -