Changeset 95870 in vbox for trunk/src/VBox/Runtime/r3/win
- Timestamp:
- Jul 27, 2022 2:38:01 AM (3 years ago)
- Location:
- trunk/src/VBox/Runtime/r3/win
- Files:
-
- 1 added
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp
r95834 r95870 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - No-CRT - Windows EXE startup code. 4 * 5 * @note Does not run static constructors and destructors! 3 * IPRT - No-CRT - Common Windows startup code. 6 4 */ 7 5 … … 41 39 #include <iprt/utf16.h> 42 40 43 #ifdef IPRT_NO_CRT44 # include <iprt/asm.h>45 # include <iprt/nocrt/stdlib.h>46 #endif47 48 41 #include "internal/compiler-vcc.h" 49 50 51 /*********************************************************************************************************************************52 * Structures and Typedefs *53 *********************************************************************************************************************************/54 #ifdef IPRT_NO_CRT55 typedef struct RTNOCRTATEXITCHUNK56 {57 PFNRTNOCRTATEXITCALLBACK apfnCallbacks[256];58 } RTNOCRTATEXITCHUNK;59 #endif60 42 61 43 … … 70 52 RT_C_DECLS_END 71 53 72 #ifdef IPRT_NO_CRT73 /** The first atexit() registration chunk. */74 static RTNOCRTATEXITCHUNK g_aAtExitPrealloc;75 /** Array of atexit() callback chunk pointers. */76 static RTNOCRTATEXITCHUNK *g_apAtExit[8192 / 256] = { &g_aAtExitPrealloc, };77 /** Chunk and callback index in one. */78 static volatile uint32_t g_idxNextAtExit = 0;79 #endif80 54 81 55 82 /********************************************************************************************************************************* 83 * External Symbols * 84 *********************************************************************************************************************************/ 85 extern DECLHIDDEN(void) InitStdHandles(PRTL_USER_PROCESS_PARAMETERS pParams); /* nocrt-streams-win.cpp */ /** @todo put in header */ 86 87 extern int main(int argc, char **argv, char **envp); /* in program */ 88 89 90 #ifdef IPRT_NO_CRT 91 extern "C" 92 int rtnocrt_atexit(PFNRTNOCRTATEXITCALLBACK pfnCallback) RT_NOEXCEPT 93 { 94 AssertPtr(pfnCallback); 95 96 /* 97 * Allocate a table index. 98 */ 99 uint32_t idx = ASMAtomicIncU32(&g_idxNextAtExit) - 1; 100 AssertReturnStmt(idx < RT_ELEMENTS(g_apAtExit) * RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks), 101 ASMAtomicDecU32(&g_idxNextAtExit), -1); 102 103 /* 104 * Make sure the table chunk is there. 105 */ 106 uint32_t idxChunk = idx / RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks); 107 RTNOCRTATEXITCHUNK *pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *); 108 if (!pChunk) 109 { 110 pChunk = (RTNOCRTATEXITCHUNK *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pChunk)); 111 AssertReturn(pChunk, -1); /* don't try decrement, someone could be racing us... */ 112 113 if (!ASMAtomicCmpXchgPtr(&g_apAtExit[idxChunk], pChunk, NULL)) 114 { 115 HeapFree(GetProcessHeap(), 0, pChunk); 116 117 pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *); 118 Assert(pChunk); 119 } 120 } 121 122 /* 123 * Add our callback. 124 */ 125 pChunk->apfnCallbacks[idxChunk % RT_ELEMENTS(pChunk->apfnCallbacks)] = pfnCallback; 126 return 0; 127 } 128 #endif 129 130 131 static int rtTerminateProcess(int32_t rcExit, bool fDoAtExit) 132 { 133 #ifdef IPRT_NO_CRT 134 /* 135 * Run atexit callback in reverse order. 136 */ 137 if (fDoAtExit) 138 { 139 uint32_t idxAtExit = ASMAtomicReadU32(&g_idxNextAtExit); 140 if (idxAtExit-- > 0) 141 { 142 uint32_t idxChunk = idxAtExit / RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks); 143 uint32_t idxCallback = idxAtExit % RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks); 144 for (;;) 145 { 146 RTNOCRTATEXITCHUNK *pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *); 147 if (pChunk) 148 { 149 do 150 { 151 PFNRTNOCRTATEXITCALLBACK pfnCallback = pChunk->apfnCallbacks[idxCallback]; 152 if (pfnCallback) /* Can be NULL see registration code */ 153 pfnCallback(); 154 } while (idxCallback-- > 0); 155 } 156 if (idxChunk == 0) 157 break; 158 idxChunk--; 159 idxCallback = RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks) - 1; 160 } 161 } 162 163 rtVccInitializersRunTerm(); 164 } 165 #else 166 RT_NOREF(fDoAtExit); 167 #endif 168 169 /* 170 * Terminate. 171 */ 172 for (;;) 173 NtTerminateProcess(NtCurrentProcess(), rcExit); 174 } 175 176 177 DECL_NO_INLINE(static, void) initProcExecPath(void) 56 void rtVccWinInitProcExecPath(void) 178 57 { 179 58 WCHAR wszPath[RTPATH_MAX]; … … 198 77 } 199 78 200 201 DECLASM(void) CustomMainEntrypoint(PPEB pPeb)202 {203 /*204 * Initialize stuff.205 */206 InitStdHandles(pPeb->ProcessParameters);207 initProcExecPath();208 209 RTEXITCODE rcExit;210 #ifdef IPRT_NO_CRT211 AssertCompile(sizeof(rcExit) == sizeof(int));212 rcExit = (RTEXITCODE)rtVccInitializersRunInit();213 if (rcExit == RTEXITCODE_SUCCESS)214 #endif215 {216 /*217 * Get and convert the command line to argc/argv format.218 */219 UNICODE_STRING const *pCmdLine = pPeb->ProcessParameters ? &pPeb->ProcessParameters->CommandLine : NULL;220 if (pCmdLine)221 {222 char *pszCmdLine = NULL;223 int rc = RTUtf16ToUtf8Ex(pCmdLine->Buffer, pCmdLine->Length / sizeof(WCHAR), &pszCmdLine, 0, NULL);224 if (RT_SUCCESS(rc))225 {226 char **papszArgv;227 int cArgs = 0;228 rc = RTGetOptArgvFromString(&papszArgv, &cArgs, pszCmdLine,229 RTGETOPTARGV_CNV_MODIFY_INPUT | RTGETOPTARGV_CNV_QUOTE_MS_CRT, NULL);230 if (RT_SUCCESS(rc))231 {232 /*233 * Call the main function.234 */235 AssertCompile(sizeof(rcExit) == sizeof(int));236 rcExit = (RTEXITCODE)main(cArgs, papszArgv, NULL /*envp*/);237 }238 else239 rcExit = RTMsgErrorExitFailure("Error parsing command line: %Rrc\n", rc);240 }241 else242 rcExit = RTMsgErrorExitFailure("Failed to convert command line to UTF-8: %Rrc\n", rc);243 }244 else245 rcExit = RTMsgErrorExitFailure("No command line\n");246 rtTerminateProcess(rcExit, true /*fDoAtExit*/);247 }248 #ifdef IPRT_NO_CRT249 else250 {251 RTMsgError("A C static initializor failed (%d)\n", rcExit);252 rtTerminateProcess(rcExit, false /*fDoAtExit*/);253 }254 #endif255 }256 -
trunk/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp
r95834 r95870 41 41 #include <iprt/utf16.h> 42 42 43 #ifdef IPRT_NO_CRT44 # include <iprt/asm.h>45 # include <iprt/nocrt/stdlib.h>46 #endif47 48 43 #include "internal/compiler-vcc.h" 49 50 51 /*********************************************************************************************************************************52 * Structures and Typedefs *53 *********************************************************************************************************************************/54 #ifdef IPRT_NO_CRT55 typedef struct RTNOCRTATEXITCHUNK56 {57 PFNRTNOCRTATEXITCALLBACK apfnCallbacks[256];58 } RTNOCRTATEXITCHUNK;59 #endif60 61 62 /*********************************************************************************************************************************63 * Global Variables *64 *********************************************************************************************************************************/65 RT_C_DECLS_BEGIN66 DECL_HIDDEN_DATA(char) g_szrtProcExePath[RTPATH_MAX] = "Unknown.exe";67 DECL_HIDDEN_DATA(size_t) g_cchrtProcExePath = 11;68 DECL_HIDDEN_DATA(size_t) g_cchrtProcExeDir = 0;69 DECL_HIDDEN_DATA(size_t) g_offrtProcName = 0;70 RT_C_DECLS_END71 72 #ifdef IPRT_NO_CRT73 /** The first atexit() registration chunk. */74 static RTNOCRTATEXITCHUNK g_aAtExitPrealloc;75 /** Array of atexit() callback chunk pointers. */76 static RTNOCRTATEXITCHUNK *g_apAtExit[8192 / 256] = { &g_aAtExitPrealloc, };77 /** Chunk and callback index in one. */78 static volatile uint32_t g_idxNextAtExit = 0;79 #endif80 44 81 45 … … 88 52 89 53 90 #ifdef IPRT_NO_CRT91 extern "C"92 int rtnocrt_atexit(PFNRTNOCRTATEXITCALLBACK pfnCallback) RT_NOEXCEPT93 {94 AssertPtr(pfnCallback);95 96 /*97 * Allocate a table index.98 */99 uint32_t idx = ASMAtomicIncU32(&g_idxNextAtExit) - 1;100 AssertReturnStmt(idx < RT_ELEMENTS(g_apAtExit) * RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks),101 ASMAtomicDecU32(&g_idxNextAtExit), -1);102 103 /*104 * Make sure the table chunk is there.105 */106 uint32_t idxChunk = idx / RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks);107 RTNOCRTATEXITCHUNK *pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *);108 if (!pChunk)109 {110 pChunk = (RTNOCRTATEXITCHUNK *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pChunk));111 AssertReturn(pChunk, -1); /* don't try decrement, someone could be racing us... */112 113 if (!ASMAtomicCmpXchgPtr(&g_apAtExit[idxChunk], pChunk, NULL))114 {115 HeapFree(GetProcessHeap(), 0, pChunk);116 117 pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *);118 Assert(pChunk);119 }120 }121 122 /*123 * Add our callback.124 */125 pChunk->apfnCallbacks[idxChunk % RT_ELEMENTS(pChunk->apfnCallbacks)] = pfnCallback;126 return 0;127 }128 #endif129 130 131 54 static int rtTerminateProcess(int32_t rcExit, bool fDoAtExit) 132 55 { … … 137 60 if (fDoAtExit) 138 61 { 139 uint32_t idxAtExit = ASMAtomicReadU32(&g_idxNextAtExit); 140 if (idxAtExit-- > 0) 141 { 142 uint32_t idxChunk = idxAtExit / RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks); 143 uint32_t idxCallback = idxAtExit % RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks); 144 for (;;) 145 { 146 RTNOCRTATEXITCHUNK *pChunk = ASMAtomicReadPtrT(&g_apAtExit[idxChunk], RTNOCRTATEXITCHUNK *); 147 if (pChunk) 148 { 149 do 150 { 151 PFNRTNOCRTATEXITCALLBACK pfnCallback = pChunk->apfnCallbacks[idxCallback]; 152 if (pfnCallback) /* Can be NULL see registration code */ 153 pfnCallback(); 154 } while (idxCallback-- > 0); 155 } 156 if (idxChunk == 0) 157 break; 158 idxChunk--; 159 idxCallback = RT_ELEMENTS(g_apAtExit[0]->apfnCallbacks) - 1; 160 } 161 } 162 62 rtVccTermRunAtExit(); 163 63 rtVccInitializersRunTerm(); 164 64 } … … 175 75 176 76 177 DECL_NO_INLINE(static, void) initProcExecPath(void)178 {179 WCHAR wszPath[RTPATH_MAX];180 UINT cwcPath = GetModuleFileNameW(NULL, wszPath, RT_ELEMENTS(wszPath));181 if (cwcPath)182 {183 char *pszDst = g_szrtProcExePath;184 int rc = RTUtf16ToUtf8Ex(wszPath, cwcPath, &pszDst, sizeof(g_szrtProcExePath), &g_cchrtProcExePath);185 if (RT_SUCCESS(rc))186 {187 g_cchrtProcExeDir = g_offrtProcName = RTPathFilename(pszDst) - g_szrtProcExePath;188 while ( g_cchrtProcExeDir >= 2189 && RTPATH_IS_SLASH(g_szrtProcExePath[g_cchrtProcExeDir - 1])190 && g_szrtProcExePath[g_cchrtProcExeDir - 2] != ':')191 g_cchrtProcExeDir--;192 }193 else194 RTMsgError("initProcExecPath: RTUtf16ToUtf8Ex failed: %Rrc\n", rc);195 }196 else197 RTMsgError("initProcExecPath: GetModuleFileNameW failed: %Rhrc\n", GetLastError());198 }199 200 201 77 DECLASM(void) CustomMainEntrypoint(PPEB pPeb) 202 78 { … … 204 80 * Initialize stuff. 205 81 */ 82 rtVccInitSecurityCookie(); 206 83 InitStdHandles(pPeb->ProcessParameters); 207 initProcExecPath();84 rtVccWinInitProcExecPath(); 208 85 209 86 RTEXITCODE rcExit;
Note:
See TracChangeset
for help on using the changeset viewer.