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

📄 mstartup.cpp

📁 C语言库函数的原型,有用的拿去
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***
*crtexe.c - Initialization for console EXE using CRT DLL
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       This is the actual startup routine for apps linking to the CRT DLL.
*       It calls the user's main routine [w]main() or [w]WinMain after
*       performing C Run-Time Library initialization.
*
*       With ifdefs, this source file also provides the source code for:
*       wcrtexe.c   the startup routine for console apps with wide chars
*       crtexew.c   the startup routine for Windows apps
*       wcrtexew.c  the startup routine for Windows apps with wide chars
*
*******************************************************************************/

#define _CPP_MSTARTUP

#using <mscorlib.dll>
#if defined (_DEBUG)
#using <system.dll>
#endif  /* defined (_DEBUG) */
/*
 * SPECIAL BUILD MACROS! Note that crtexe.c (and crtexew.c) is linked in with
 * the client's code. It does not go into crtdll.dll! Therefore, it must be
 * built under the _DLL switch (like user code) and CRTDLL must be undefined.
 * The symbol SPECIAL_CRTEXE is turned on to suppress the normal CRT DLL
 * definition of _fmode and _commode using __declspec(dllexport).  Otherwise
 * this module would not be able to refer to both the local and DLL versions
 * of these two variables.
 */

#undef MRTDLL

#define SPECIAL_CRTEXE

#include <crtdefs.h>
#include <cruntime.h>

#if defined (_M_CEE_MIXED)

/* Some inline functions (like NtCurrentTeb) need to be unmanaged */
#pragma managed(push, off)
#include <oscalls.h>
#pragma managed(pop)

#else  /* defined (_M_CEE_MIXED) */

#include <oscalls.h>

#endif  /* defined (_M_CEE_MIXED) */

#include <internal.h>
#include <process.h>
#include <math.h>
#include <sect_attribs.h>
#include <rterr.h>
#include <conio.h>
#include <gcroot.h>
#include <vcclr.h>
#include <eh.h>
#include <time.h>

#pragma warning(disable:4483)   // disable warning/error about __identifier(<string>)

extern "C" {

// Note that managed items held in these arrays are really metadata tokens
// not clrcall function pointers so it's OK for these to be _PGLOBAL.

#if defined (_M_CEE_MIXED)

#pragma const_seg(".CRTMP$XCA")
_PGLOBAL const _CRTALLOC(".CRTMP$XCA") _PVFVM __xc_mp_a[1] = { NULL };

#pragma const_seg(".CRTMP$XCZ")
_PGLOBAL const _CRTALLOC(".CRTMP$XCZ") _PVFVM __xc_mp_z[1] = { NULL };

#endif  /* defined (_M_CEE_MIXED) */

#pragma const_seg(".CRTMA$XCA")
_PGLOBAL const _CRTALLOC(".CRTMA$XCA") _PVFVM __xc_ma_a[1] = { NULL };

#pragma const_seg(".CRTMA$XCZ")
_PGLOBAL const _CRTALLOC(".CRTMA$XCZ") _PVFVM __xc_ma_z[1] = { NULL };

#pragma const_seg(".CRTVT$XCA")
_PGLOBAL const _CRTALLOC(".CRTVT$XCA") _PVFVM __xi_vt_a[1] = { NULL };

#pragma const_seg(".CRTVT$XCZ")
_PGLOBAL const _CRTALLOC(".CRTVT$XCZ") _PVFVM __xi_vt_z[1] = { NULL };

#pragma const_seg()  /* reset */

#pragma comment(linker, "/merge:.CRTMP=.rdata")
#pragma comment(linker, "/merge:.CRTMA=.rdata")
#pragma comment(linker, "/merge:.CRTVT=.rdata")

#pragma comment(linker, "/defaultlib:kernel32.lib")

#if defined (_M_CEE_MIXED)
extern "C" _PGLOBAL _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
extern "C" _PGLOBAL _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];    /* C initializers */
extern "C" _PGLOBAL _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
extern "C" _PGLOBAL _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];    /* C++ initializers */
#endif  /* defined (_M_CEE_MIXED) */
}

#if defined (_M_CEE_MIXED)
extern "C" int __clrcall _initatexit_m();
extern "C" void __clrcall _exit_callback(void);
#endif  /* defined (_M_CEE_MIXED) */
extern "C" int __clrcall _initatexit_app_domain();
extern "C" void __clrcall _app_exit_callback();

int __clrcall _initterm_e ( _PIFV *, _PIFV *);
void __clrcall _initterm ( _PVFV *, _PVFV *);
void __clrcall _initterm_m ( const _PVFVM *, const _PVFVM *);

#if defined (_M_CEE_MIXED)
#pragma managed(push, off)
[System::Diagnostics::DebuggerStepThroughAttribute]
void * __cdecl _getFiberPtrId()
{
    return ((PNT_TIB)NtCurrentTeb())->StackBase;
}

extern "C"
void __cdecl __security_init_cookie(void);
#pragma managed(pop)
#endif  /* defined (_M_CEE_MIXED) */

[System::Security::Permissions::SecurityPermissionAttribute(System::Security::Permissions::SecurityAction::Assert, UnmanagedCode = true)]
static void clock_wrapper()
{
        clock();
}

#include <minternal.h>

namespace __identifier("<CrtImplementationDetails>")
{

class TriBool
{
public:
    enum State { False = 0, True = -1, Unknown = 2 };
private:
    TriBool();
    ~TriBool();
};

class Progress
{
public:
    enum State { NotStarted = 0, Started, Finished };
private:
    Progress();
    ~Progress();
};

#if defined (_M_CEE_MIXED)

class AllDomains
{
public:
    // The number of domains in which the module is loaded
    _PGLOBAL static int Count;
};
_PGLOBAL int AllDomains::Count = 0;

class DefaultDomain
{
private:
    _PGLOBAL static TriBool::State hasPerProcess;
    _PGLOBAL static TriBool::State hasNative;
    /*static void __cdecl DoNothing()
    {
    }*/
    // No secret exposed; no side effect
    SECURITYSAFECRITICAL_ATTRIBUTE
    static HRESULT __stdcall DoNothing(void* cookie)
    {
        cookie;
        // Execute simple managed code
        System::GC::KeepAlive(System::Int32::MaxValue);
        return S_OK;
    }

public:
    _PGLOBAL static bool Entered;
    _PGLOBAL static bool InitializedNative;
    _PGLOBAL static bool InitializedNativeFromCCTOR;
    _PGLOBAL static bool InitializedPerProcess;

    SECURITYSAFECRITICAL_ATTRIBUTE
    inline static bool HasPerProcess()
    {
        if (hasPerProcess == TriBool::Unknown)
        {
            void **pBeg = (void **)(void *)__xc_mp_a;
            void **pEnd = (void **)(void *)__xc_mp_z;
            while (pBeg < pEnd)
            {
                if (*pBeg != 0)
                {
                    hasPerProcess = TriBool::True;
                    return true;
                }
                pBeg++;
            }

            hasPerProcess = TriBool::False;
            return false;
        }
        return hasPerProcess == TriBool::True;
    }

    SECURITYSAFECRITICAL_ATTRIBUTE
    inline static bool HasNative()
    {
        if (hasNative == TriBool::Unknown)
        {
            void **pBeg = (void **)(void *)__xi_a;
            void **pEnd = (void **)(void *)__xi_z;

            while (pBeg < pEnd)
            {
                if (*pBeg != 0)
                {
                    hasNative = TriBool::True;
                    return true;
                }
                pBeg++;
            }

            pBeg = (void **)(void *)__xc_a;
            pEnd = (void **)(void *)__xc_z;
            while (pBeg < pEnd)
            {
                if (*pBeg != 0)
                {
                    hasNative = TriBool::True;
                    return true;
                }
                pBeg++;
            }

            hasNative = TriBool::False;
            return false;
        }
        return hasNative == TriBool::True;
    }

    SECURITYSAFECRITICAL_ATTRIBUTE
    inline static bool NeedsInitialization()
    {
        return ((HasPerProcess() && !InitializedPerProcess) || (HasNative() && !InitializedNative && (__native_startup_state == __uninitialized)));
    }

    inline static bool NeedsUninitialization()
    {
        // If the default domain has been entered then there's a chance that
        // atexit has been called and we need to transition into it to uninitialize it.
        return Entered;
    }

    SECURITYCRITICAL_ATTRIBUTE
    inline static void Initialize()
    {
        // Trigger call to the module constructor
        DoCallBackInDefaultDomain(&DoNothing, nullptr);
    }

private:
    DefaultDomain();
    ~DefaultDomain();
};

_PGLOBAL bool DefaultDomain::Entered = false;
_PGLOBAL bool DefaultDomain::InitializedNative = false;
_PGLOBAL bool DefaultDomain::InitializedNativeFromCCTOR = false;
_PGLOBAL bool DefaultDomain::InitializedPerProcess = false;
_PGLOBAL TriBool::State DefaultDomain::hasPerProcess = TriBool::Unknown;
_PGLOBAL TriBool::State DefaultDomain::hasNative = TriBool::Unknown;

#endif  /* defined (_M_CEE_MIXED) */

class CurrentDomain
{
public:
    _AGLOBAL static int Initialized;
    _AGLOBAL static int Uninitialized;
    _AGLOBAL static bool IsDefaultDomain;
    _AGLOBAL static Progress::State InitializedVtables;
    _AGLOBAL static Progress::State InitializedNative;
    _AGLOBAL static Progress::State InitializedPerProcess;
    _AGLOBAL static Progress::State InitializedPerAppDomain;
private:
    CurrentDomain();  // Not instantiable
    ~CurrentDomain(); // Not instantiable
};

_AGLOBAL int CurrentDomain::Initialized = 0;
_AGLOBAL int CurrentDomain::Uninitialized = 0;
_AGLOBAL bool CurrentDomain::IsDefaultDomain = false;
_AGLOBAL Progress::State CurrentDomain::InitializedVtables = Progress::NotStarted;
_AGLOBAL Progress::State CurrentDomain::InitializedNative = Progress::NotStarted;
_AGLOBAL Progress::State CurrentDomain::InitializedPerProcess = Progress::NotStarted;
_AGLOBAL Progress::State CurrentDomain::InitializedPerAppDomain = Progress::NotStarted;

class LanguageSupport
{
private:
    // If a non-CRT exception is thrown, this member
    // holds a constant describing the current activity
    gcroot<String^> ErrorMessage;

    // Initializes vtables (which are per-appdomain)
    [System::Diagnostics::DebuggerStepThroughAttribute]
    SECURITYCRITICAL_ATTRIBUTE
    inline void InitializeVtables()
    {
        ErrorMessage = L"The C++ module failed to load during vtable initialization.\n";
        CurrentDomain::InitializedVtables = Progress::Started;
        _initterm_m((const _PVFVM *)__xi_vt_a, (const _PVFVM *)__xi_vt_z);
        CurrentDomain::InitializedVtables = Progress::Finished;
    }

#if defined (_M_CEE_MIXED)

    // This is a blocking call which won't return until the default app domain is initialized
    SECURITYCRITICAL_ATTRIBUTE
    inline void InitializeDefaultAppDomain()
    {
        ErrorMessage = L"The C++ module failed to load while attempting to initialize the default appdomain.\n";
        DefaultDomain::Initialize();
    }

    // Initializes native globals
    [System::Diagnostics::DebuggerStepThroughAttribute]
    SECURITYCRITICAL_ATTRIBUTE
    inline void InitializeNative()
    {
        MANAGED_ASSERT(CurrentDomain::IsDefaultDomain, "Native globals must be initialized in the default domain");

        ErrorMessage = L"The C++ module failed to load during native initialization.\n";

        __security_init_cookie();

        DefaultDomain::InitializedNative = true;

        using namespace _NATIVE_STARTUP_NAMESPACE;
        if (!NativeDll::IsSafeForManagedCode())
        {
            _amsg_exit( _RT_CRT_INIT_MANAGED_CONFLICT);
        }

        /*
        * In mixed code we make sure to initialize native globals as well.
        */
        if (__native_startup_state == __initializing)
        {
            _amsg_exit( _RT_CRT_INIT_MANAGED_CONFLICT);
        }
        else if (__native_startup_state == __uninitialized)
        {
            CurrentDomain::InitializedNative = Progress::Started;
            __native_startup_state = __initializing;
            if (_initterm_e(__xi_a, __xi_z) != 0)
            {
                ThrowModuleLoadException(ErrorMessage);
            }
            _initterm(__xc_a, __xc_z);
            __native_startup_state = __initialized;

⌨️ 快捷键说明

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