📄 puremsilcode.cpp
字号:
/***
*msilexit.cpp - Exit routines for mixdll.
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* This file provides at_exit support for clrcall functions. Here you will
* find implementation for both managed process exit and appdomain exit.
*
*******************************************************************************/
#ifdef MRTDLL
#undef MRTDLL
#endif /* MRTDLL */
#include <internal.h>
#include <mtdll.h>
#pragma warning(disable:4439) // C4439: function with a managed parameter must have a __clrcall calling convention
#pragma warning(disable:4483) // disable warning/error about __identifier(<string>)
#if defined (_M_CEE_MIXED)
/***
* static void _initterm(_PIFV * pfbegin, _PIFV * pfend) - call entries in
* function pointer table
*
*Purpose:
* Walk a table of function pointers, calling each entry, as follows:
*
* 1. walk from beginning to end, pfunctbl is assumed to point
* to the beginning of the table, which is currently a null entry,
* as is the end entry.
* 2. skip NULL entries
* 3. stop walking when the end of the table is encountered
*
*Entry:
* _PVFV *pfbegin - pointer to the beginning of the table (first
* valid entry).
* _PVFV *pfend - pointer to the end of the table (after last
* valid entry).
*
*Exit:
* Returns 0 if passed, 1 if falied.
*
*Notes:
* This routine must be exported in the CRT DLL model so that the client
* EXE and client DLL(s) can call it to initialize their C++ constructors.
*
*Exceptions:
* If either pfbegin or pfend is NULL, or invalid, all bets are off!
*
*******************************************************************************/
[System::Diagnostics::DebuggerStepThroughAttribute]
SECURITYCRITICAL_ATTRIBUTE
int __clrcall _initterm_e (
_PIFV * pfbegin,
_PIFV * pfend
)
{
int ret = 0;
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are valid.
*/
while ( pfbegin < pfend && ret == 0)
{
/*
* if current table entry is non-NULL, call thru it.
*/
if ( *pfbegin != NULL )
ret = (**pfbegin)();
++pfbegin;
}
return ret;
}
/***
* static void _initterm(_PVFV * pfbegin, _PVFV * pfend) - call entries in
* function pointer table
*
*Purpose:
* Walk a table of function pointers, calling each entry, as follows:
*
* 1. walk from beginning to end, pfunctbl is assumed to point
* to the beginning of the table, which is currently a null entry,
* as is the end entry.
* 2. skip NULL entries
* 3. stop walking when the end of the table is encountered
*
*Entry:
* _PVFV *pfbegin - pointer to the beginning of the table (first
* valid entry).
* _PVFV *pfend - pointer to the end of the table (after last
* valid entry).
*
*Exit:
* No return value
*
*Notes:
* This routine must be exported in the CRT DLL model so that the client
* EXE and client DLL(s) can call it to initialize their C++ constructors.
*
*Exceptions:
* If either pfbegin or pfend is NULL, or invalid, all bets are off!
*
*******************************************************************************/
[System::Diagnostics::DebuggerStepThroughAttribute]
SECURITYCRITICAL_ATTRIBUTE
void __clrcall _initterm (
_PVFV * pfbegin,
_PVFV * pfend
)
{
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are valid.
*/
while ( pfbegin < pfend )
{
/*
* if current table entry is non-NULL, call thru it.
*/
if ( *pfbegin != NULL )
(**pfbegin)();
++pfbegin;
}
}
#endif /* defined (_M_CEE_MIXED) */
namespace __identifier("<CrtImplementationDetails>")
{
class ThisModule
{
private:
[System::Diagnostics::DebuggerStepThroughAttribute]
static System::ModuleHandle Handle()
{
return ThisModule::typeid->Module->ModuleHandle;
}
public:
template <class T>
[System::Diagnostics::DebuggerStepThroughAttribute]
SECURITYCRITICAL_ATTRIBUTE
static T* ResolveMethod(T* methodToken)
{
return (T*)Handle().ResolveMethodHandle((int)(size_t)methodToken).GetFunctionPointer().ToPointer();
}
};
}
/***
* void _initterm_m(_PVFVM * pfbegin, _PVFVM * pfend) - call entries in
* function pointer table
*
*Purpose:
* Walk a table of function pointers, calling each entry, as follows:
*
* 1. walk from beginning to end, pfunctbl is assumed to point
* to the beginning of the table, which is currently a null entry,
* as is the end entry.
* 2. skip NULL entries
* 3. stop walking when the end of the table is encountered
*
*Entry:
* _PVFVM *pfbegin - pointer to the beginning of the table (first
* valid entry).
* _PVFVM *pfend - pointer to the end of the table (after last
* valid entry).
*
*Exit:
* No return value
*
*Notes:
*
*Exceptions:
* If either pfbegin or pfend is NULL, or invalid, all bets are off!
*
*******************************************************************************/
[System::Diagnostics::DebuggerStepThroughAttribute]
SECURITYCRITICAL_ATTRIBUTE
// needed due to having unverifiable code in compiler-generated initializers
ASSERT_UNMANAGED_CODE_ATTRIBUTE
void __clrcall _initterm_m (
const _PVFVM * pfbegin,
const _PVFVM * pfend
)
{
using namespace __identifier("<CrtImplementationDetails>");
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are valid.
*/
while ( pfbegin < pfend )
{
/*
* if current table entry is non-NULL, call thru it.
*/
/*
* GetRuntimeMethodHandleFromMetadataToken call needs to be changed to
* call ResolveMethodHandle once that method becomes available in the
* VBL CLR. Disabling the warning for now.
*/
if ( *pfbegin != NULL )
{
_PVFVM pfn = ThisModule::ResolveMethod(*pfbegin);
(pfn)();
}
++pfbegin;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -