Unified · Split
| @@ -1,48 +1,78 @@ | ||
| 1 | 1 | // ============================================= |
| 2 | 2 | // crt1.c |
| 3 | 3 | |
| 4 | −#include <stdlib.h> | |
| 5 | 4 | // For ExitProcess |
| 5 | +// windows.h header file should be included before any other library include | |
| 6 | 6 | #include <windows.h> |
| 7 | +#include <stdio.h> | |
| 8 | +#include <stdlib.h> | |
| 9 | + | |
| 10 | +#define _UNKNOWN_APP 0 | |
| 11 | +#define _CONSOLE_APP 1 | |
| 12 | +#define _GUI_APP 2 | |
| 7 | 13 | |
| 8 | −#define __UNKNOWN_APP 0 | |
| 9 | −#define __CONSOLE_APP 1 | |
| 10 | −#define __GUI_APP 2 | |
| 11 | −void __set_app_type(int); | |
| 12 | −void _controlfp(unsigned a, unsigned b); | |
| 14 | +#define _MCW_PC 0x00030000 // Precision Control | |
| 15 | +#define _PC_24 0x00020000 // 24 bits | |
| 16 | +#define _PC_53 0x00010000 // 53 bits | |
| 17 | +#define _PC_64 0x00000000 // 64 bits | |
| 13 | 18 | |
| 14 | 19 | typedef struct |
| 15 | 20 | { |
| 16 | 21 | int newmode; |
| 17 | 22 | } _startupinfo; |
| 18 | 23 | |
| 19 | −// prototype of __getmainargs: | |
| 20 | −// in msvcrt v6.0 : return void | |
| 21 | −// in msvcrt v7.0 : return int | |
| 22 | −// using first for compatibility | |
| 23 | −void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*); | |
| 24 | −int main(int argc, char **argv, char **env); | |
| 24 | +// Prototype of __getmainargs: | |
| 25 | +// in msvcrt v6.x : returns void (windows 98, 2000) | |
| 26 | +// in msvcrt v7.x : returns int (windows xp and above) | |
| 27 | +// Using the last for check the result. A negative value means no success. | |
| 28 | +// These are the test results of call to __getmainargs with the heap fully: | |
| 29 | +// win 98, 2000 : | |
| 30 | +// program termination with error code 255 after call _amsg_exit(8) | |
| 31 | +// prints: "runtime error R6008\r\n- not enough space for arguments\r\n" | |
| 32 | +// win xp : | |
| 33 | +// returns -1 | |
| 34 | +// win 7, 8 : | |
| 35 | +// program termination with error code -1 after call ExitProcess(-1) | |
| 36 | +// | |
| 37 | +// Checking the return of this function also works on windows 98 and 2000 | |
| 38 | +// because internally it sets to eax the value of the third parameter. | |
| 39 | +// In this case is &env and at that point it is not a negative value. | |
| 25 | 40 | |
| 26 | −int _start(void) | |
| 41 | +int __cdecl __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*); | |
| 42 | +void __cdecl __set_app_type(int apptype); | |
| 43 | +unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); | |
| 44 | + | |
| 45 | +void _start(void); | |
| 46 | +int main(int argc, char * argv[], char * env[]); | |
| 47 | + | |
| 48 | +void _start(void) | |
| 27 | 49 | { |
| 28 | 50 | __TRY__ |
| 29 | − int argc; char **argv; char **env; | |
| 30 | − _startupinfo start_info = {0}; | |
| 51 | + int argc; | |
| 52 | + char **argv; | |
| 53 | + char **env; | |
| 54 | + _startupinfo start_info; | |
| 55 | + | |
| 56 | + // Sets the current application type | |
| 57 | + __set_app_type(_CONSOLE_APP); | |
| 31 | 58 | |
| 32 | − _controlfp(0x10000, 0x30000); | |
| 33 | − __set_app_type(__CONSOLE_APP); | |
| 59 | + // Set default FP precision to 53 bits (8-byte double) | |
| 60 | + // _MCW_PC (Precision control) is not supported on | |
| 61 | + // the ARM and x64 architectures | |
| 62 | +#if defined(_X86_) && !defined(__x86_64) | |
| 63 | + _controlfp(_PC_53, _MCW_PC); | |
| 64 | +#endif | |
| 34 | 65 | |
| 35 | − argv = NULL; | |
| 36 | − __getmainargs(&argc, &argv, &env, 0, &start_info); | |
| 37 | − // check success comparing if argv now is not NULL | |
| 38 | − if (argv != NULL) | |
| 66 | + start_info.newmode = 0; | |
| 67 | + if ( __getmainargs( &argc, &argv, &env, 0, &start_info ) < 0 ) | |
| 39 | 68 | { |
| 40 | − exit( main(argc, argv, env) ); | |
| 69 | + ExitProcess(-1); | |
| 41 | 70 | } |
| 42 | 71 | else |
| 43 | 72 | { |
| 44 | − ExitProcess(-1); | |
| 73 | + exit( main(argc, argv, env) ); | |
| 45 | 74 | } |
| 75 | + | |
| 46 | 76 | } |
| 47 | 77 | |
| 48 | 78 | // ============================================= |