VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: nocrt-startup-exe-win.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - No-CRT - Windows EXE startup code.
4 *
5 * @note Does not run static constructors and destructors!
6 */
7
8/*
9 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * The contents of this file may alternatively be used under the terms
28 * of the Common Development and Distribution License Version 1.0
29 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
30 * in the VirtualBox distribution, in which case the provisions of the
31 * CDDL are applicable instead of those of the GPL.
32 *
33 * You may elect to license modified versions of this file under the
34 * terms and conditions of either the GPL or the CDDL or both.
35 *
36 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
37 */
38
39
40/*********************************************************************************************************************************
41* Header Files *
42*********************************************************************************************************************************/
43#include "internal/nocrt.h"
44#include "internal/process.h"
45
46#include <iprt/nt/nt-and-windows.h>
47#include <iprt/getopt.h>
48#include <iprt/message.h>
49#include <iprt/path.h>
50#include <iprt/string.h>
51#include <iprt/utf16.h>
52
53#include "internal/compiler-vcc.h"
54
55
56/*********************************************************************************************************************************
57* External Symbols *
58*********************************************************************************************************************************/
59extern int main(int argc, char **argv, char **envp); /* in program */
60#ifndef IPRT_NO_CRT
61extern DECLHIDDEN(void) InitStdHandles(PRTL_USER_PROCESS_PARAMETERS pParams); /* nocrt-streams-win.cpp */ /** @todo put in header */
62#endif
63
64
65static int rtTerminateProcess(int32_t rcExit, bool fDoAtExit)
66{
67#ifdef IPRT_NO_CRT
68 /*
69 * Run atexit callback in reverse order.
70 */
71 if (fDoAtExit)
72 {
73 rtVccTermRunAtExit();
74 rtVccInitializersRunTerm();
75 }
76#else
77 RT_NOREF(fDoAtExit);
78#endif
79
80 /*
81 * Terminate.
82 */
83 for (;;)
84 NtTerminateProcess(NtCurrentProcess(), rcExit);
85}
86
87
88DECLASM(void) CustomMainEntrypoint(void)
89{
90 /* Looks like might have gotten the PPEB as parameter here before NT4,
91 however, there the EXE entry function clearly takes no parameters.
92 So, we have to retrieve the PEB our selves here. */
93 PPEB_COMMON const pPeb = RTNtCurrentPeb();
94
95 /*
96 * Initialize stuff.
97 */
98#ifdef IPRT_NO_CRT
99# ifdef RT_ARCH_X86
100 rtVccWinInitBssOnNt3(pPeb->ImageBaseAddress);
101# endif
102 rtVccInitSecurityCookie();
103#else
104 InitStdHandles(pPeb->ProcessParameters);
105#endif
106 rtVccWinInitProcExecPath();
107
108 RTEXITCODE rcExit;
109#ifdef IPRT_NO_CRT
110 AssertCompile(sizeof(rcExit) == sizeof(int));
111 rcExit = (RTEXITCODE)rtVccInitializersRunInit();
112 if (rcExit == RTEXITCODE_SUCCESS)
113#endif
114 {
115 /*
116 * Get and convert the command line to argc/argv format.
117 */
118 rcExit = RTEXITCODE_INIT;
119 UNICODE_STRING const *pCmdLine = pPeb->ProcessParameters ? &pPeb->ProcessParameters->CommandLine : NULL;
120 if (pCmdLine)
121 {
122 char *pszCmdLine = NULL;
123 int rc = RTUtf16ToUtf8Ex(pCmdLine->Buffer, pCmdLine->Length / sizeof(WCHAR), &pszCmdLine, 0, NULL);
124 if (RT_SUCCESS(rc))
125 {
126 char **papszArgv;
127 int cArgs = 0;
128 rc = RTGetOptArgvFromString(&papszArgv, &cArgs, pszCmdLine,
129 RTGETOPTARGV_CNV_MODIFY_INPUT | RTGETOPTARGV_CNV_QUOTE_MS_CRT, NULL);
130 if (RT_SUCCESS(rc))
131 {
132 /*
133 * Call the main function.
134 */
135 AssertCompile(sizeof(rcExit) == sizeof(int));
136 rcExit = (RTEXITCODE)main(cArgs, papszArgv, NULL /*envp*/);
137 }
138 else
139#ifdef IPRT_NOCRT_WITHOUT_FATAL_WRITE
140 RTMsgError("Error parsing command line: %Rrc\n", rc);
141#else
142 rtNoCrtFatalMsgWithRc(RT_STR_TUPLE("Error parsing command line: "), rc);
143#endif
144 }
145 else
146#ifdef IPRT_NOCRT_WITHOUT_FATAL_WRITE
147 RTMsgError("Failed to convert command line to UTF-8: %Rrc\n", rc);
148#else
149 rtNoCrtFatalMsgWithRc(RT_STR_TUPLE("Failed to convert command line to UTF-8: "), rc);
150#endif
151 }
152 else
153#ifdef IPRT_NOCRT_WITHOUT_FATAL_WRITE
154 RTMsgError("No command line\n");
155#else
156 rtNoCrtFatalMsg(RT_STR_TUPLE("No command line\r\n"));
157#endif
158 rtTerminateProcess(rcExit, true /*fDoAtExit*/);
159 }
160#ifdef IPRT_NO_CRT
161 else
162 {
163# ifdef IPRT_NOCRT_WITHOUT_FATAL_WRITE
164 RTMsgError("A C static initializor failed (%d)\n", rcExit);
165# else
166 rtNoCrtFatalWriteBegin(RT_STR_TUPLE("A C static initializor failed ("));
167 rtNoCrtFatalWriteWinRc(rcExit);
168 rtNoCrtFatalWriteEnd(RT_STR_TUPLE("\r\n"));
169# endif
170 rtTerminateProcess(rcExit, false /*fDoAtExit*/);
171 }
172#endif
173}
174
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use