📄 mcrtexe.cpp
字号:
startinfo.newmode = _query_new_mode();
#if !defined (_MANAGED_MAIN) && !defined (_WINMAIN_)
/* init the cmdline (_acmdln or _wcmdln) with the array<String^> */
/* no need to do this if we use managed main or WinMain */
argret = __tinit_cmdline(arguments);
if (argret < 0)
_amsg_exit(_RT_SPACEARG);
#endif /* !defined (_MANAGED_MAIN) && !defined (_WINMAIN_) */
#ifdef WPRFLAG
argret = __wgetmainargs(&argc, &argv, &envp,
_dowildcard, &startinfo);
#else /* WPRFLAG */
argret = __getmainargs(&argc, &argv, &envp,
_dowildcard, &startinfo);
#endif /* WPRFLAG */
if (argret < 0)
_amsg_exit(_RT_SPACEARG);
#if defined (_MANAGED_MAIN)
mainret = main(arguments);
#else /* defined (_MANAGED_MAIN) */
#ifdef _WINMAIN_
/*
* Skip past program name (first token in command line).
* Check for and handle quoted program name.
*/
#ifdef WPRFLAG
lpszCommandLine = (wchar_t *) *_IMP___WCMDLN;
#else /* WPRFLAG */
lpszCommandLine = (char *) *_IMP___ACMDLN;
#endif /* WPRFLAG */
while (*lpszCommandLine > SPACECHAR ||
(*lpszCommandLine&&inDoubleQuote)) {
/*
* Flip the count from 1 to 0 or 0 to 1 if current character
* is DOUBLEQUOTE
*/
if (*lpszCommandLine==DQUOTECHAR) inDoubleQuote=!inDoubleQuote;
#ifdef _MBCS
if (_ismbblead(*lpszCommandLine)) {
if (lpszCommandLine) {
lpszCommandLine++;
}
}
#endif /* _MBCS */
++lpszCommandLine;
}
/*
* Skip past any white space preceeding the second token.
*/
while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) {
lpszCommandLine++;
}
mainret = _tWinMain(
NULL,
NULL,
lpszCommandLine,
__startup_info.dwFlags & STARTF_USESHOWWINDOW
? __startup_info.wShowWindow
: SW_SHOWDEFAULT
);
#else /* _WINMAIN_ */
mainret = __CxxPureMSILEntry(argc, argv, envp);
#endif /* _WINMAIN_ */
#endif /* defined (_MANAGED_MAIN) */
}
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
{
/*
* Should never reach here
*/
mainret = GetExceptionCode();
} /* end of try - except */
return mainret;
}
#if !defined (_MANAGED_MAIN) && !defined (_WINMAIN_)
SECURITYCRITICAL_ATTRIBUTE
static int __clrcall __tinit_cmdline(array<String^> ^arguments)
{
::System::Text::StringBuilder sb;
const ::System::Char SPACE_SCHAR = ' ';
const ::System::Char DQUOTE_SCHAR = '\"';
const ::System::Char SLASH_SCHAR = '\\';
const _TCHAR SPACE_TCHAR = _T(' ');
const _TCHAR DQUOTE_TCHAR = _T('\"');
const _TCHAR QUESTIONMARK_TCHAR = _T('?');
/* To add the arguments to the cmdline, we use the same rules used to parse the cmdline,
from parse_cmdline, in stdargv.c. The rules are:
2N backslashes + " ==> N backslashes and begin/end quote
2N+1 backslashes + " ==> N backslashes + literal "
N backslashes ==> N backslashes
so here we use the reverse:
always surround each argument with doublequotes
a literal " in the argument becomes 1 backslash + literal "
N backslashes + literal " become 2N+1 backslashes + literal "
N backslashes at the end of the argument become 2N backslashes (because we have the closing doublequote)
*/
for each (String ^arg in arguments)
{
sb.Append(SPACE_SCHAR); /* insert a space between the args */
sb.Append(DQUOTE_SCHAR); /* begin with a double quote */
for (int i = 0; i < arg->Length; ++i)
{
if (arg[i] == DQUOTE_SCHAR)
{
sb.Append(SLASH_SCHAR);
sb.Append(DQUOTE_SCHAR);
}
else if (arg[i] == SLASH_SCHAR)
{
int numSlash = 0;
while (i < arg->Length && arg[i] == SLASH_SCHAR)
{
++numSlash;
++i;
}
if (i < arg->Length)
{
if (arg[i] == DQUOTE_SCHAR)
{
/* we have a 'literal' double quote preceeded by numSlash backslashes:
we will need to append 2 * numSlash backslashes + 1 backslash + 1 double quote */
sb.Append(SLASH_SCHAR, (2 * numSlash) + 1);
sb.Append(DQUOTE_SCHAR);
}
else
{
/* we have a non double quote char (arg[i]) preceeded by numSlash backslashes:
we will simply need to append numSlash backslashes + arg[i] */
sb.Append(SLASH_SCHAR, numSlash);
sb.Append(arg[i]);
}
}
else
{
/* the string ends with numSlash backslashes: we need to append 2 * numSlash backslashes
and then add the final double quote (below) */
sb.Append(SLASH_SCHAR, 2 * numSlash);
break;
}
}
else
{
/* normal char (not a double quote nor a backslash) */
sb.Append(arg[i]);
}
}
sb.Append(DQUOTE_SCHAR); /* end with a double quote */
}
size_t cchArguments = sb.Length;
#ifndef WPRFLAG
cchArguments *= MB_CUR_MAX; /* for multibyte chars, assume that every char will use the maximum space (for this locale) */
#endif /* WPRFLAG */
size_t cmdlineSize =
1 + /* begin double quote for argv[0] */
MAX_PATH + /* argv[0] */
1 + /* end double quote for argv[0] */
cchArguments + /* argv[1..(argc - 1)] (contains initial space) */
1; /* terminating null */
_TCHAR *tcmdline = (_TCHAR *)_malloc_crt(cmdlineSize * sizeof(_TCHAR));
if (tcmdline == NULL)
{
return -1;
}
_TCHAR *p = tcmdline;
*p++ = DQUOTE_TCHAR;
int cch = GetModuleFileName(NULL, p, MAX_PATH);
p += cch;
*p++ = DQUOTE_TCHAR;
#ifndef WPRFLAG
int bytesWritten = -1;
errno_t saveErrno = errno;
#endif /* WPRFLAG */
for (int i = 0; i < sb.Length; ++i)
{
wchar_t wc = sb[i];
#ifdef WPRFLAG
*p++ = wc;
#else /* WPRFLAG */
wctomb_s(&bytesWritten, p, cmdlineSize - (p - tcmdline), wc);
if (bytesWritten == -1)
{
*p++ = QUESTIONMARK_TCHAR;
}
else
{
p += bytesWritten;
}
#endif /* WPRFLAG */
}
*p = 0;
#ifndef WPRFLAG
errno = saveErrno;
#endif /* WPRFLAG */
#ifdef WPRFLAG
_wcmdln = tcmdline;
#else /* WPRFLAG */
_acmdln = tcmdline;
#endif /* WPRFLAG */
return 0;
}
#endif /* !defined (_MANAGED_MAIN) && !defined (_WINMAIN_) */
#if defined (_MANAGED_MAIN)
static void __clrcall __set_managed_app_type(void)
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pPEHeader;
PIMAGE_OPTIONAL_HEADER pNTHeader;
pDOSHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
if ( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE )
return;
pPEHeader = (PIMAGE_NT_HEADERS)((char *)pDOSHeader +
pDOSHeader->e_lfanew);
if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
return;
pNTHeader = (PIMAGE_OPTIONAL_HEADER)&pPEHeader->OptionalHeader;
if ( pNTHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC )
return;
switch (pNTHeader->Subsystem) {
case IMAGE_SUBSYSTEM_WINDOWS_CUI:
__set_app_type(_CONSOLE_APP);
break;
default:
__set_app_type(_GUI_APP);
}
}
#endif /* defined (_MANAGED_MAIN) */
/*
* This function is the shared initialization between MIXED and PURE. In Mixed, this function
* is called during _mixed_pre_c_init(), but in PURE, this function is called during
* mainCRTStartup.
*/
SECURITYCRITICAL_ATTRIBUTE
static void __CLRCALL_OR_CDECL _common_init()
{
/*
* Set __app_type properly
*/
#if defined (_MANAGED_MAIN)
__set_managed_app_type();
#elif defined (_WINMAIN_)
__set_app_type(_GUI_APP);
#else /* defined (_WINMAIN_) */
__set_app_type(_CONSOLE_APP);
#endif /* defined (_WINMAIN_) */
/*
* Propogate the _fmode and _commode variables to the DLL
*/
*_IMP___FMODE = _fmode;
*_IMP___COMMODE = _commode;
/* Enable per-thread locale if user asked for it */
if(__globallocalestatus == -1)
{
_configthreadlocale(-1);
}
}
#endif /* MRTDLL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -