summaryrefslogtreecommitdiffstats
path: root/private/crt32/dllstuff/crtexe.c
blob: fbaa86fffbf431f098ea740529a6f410736aaaf3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#ifdef	CRTDLL
/***
*crtexe.c - Initialization for client EXE using CRT DLL (Win32, Dosx32)
*
*	Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	Set up call to client's main() or WinMain().
*
*Revision History:
*	08-12-91  GJF	Module created.
*	01-05-92  GJF	Substantially revised
*	01-17-92  GJF	Restored Stevewo's scheme for unhandled exceptions.
*	01-29-92  GJF	Added support for linked-in options (equivalents of
*			binmode.obj, commode.obj and setargv.obj).
*	04-17-92  SKS	Add call to _initterm() to do C++ constructors (I386)
*	08-01-92  SRW   winxcpt.h replaced bu excpt.h which is included by oscalls.h
*	09-16-92  SKS	Prepare for C8 C++ for MIPS by calling C++ constructors
*	04-26-93  GJF	Made lpszCommandLine (unsigned char *) to deal with
*			chars > 127 in the command line.
*	04-27-93  GJF	Removed support for _RT_STACK, _RT_INTDIV,
*			_RT_INVALDISP and _RT_NONCONT.
*	05-14-93  GJF	Added support for quoted program names.
*	07-16-93  SRW	ALPHA Merge
*	12-07-93  GJF	MS C++ front-end now used on Alpha
*       05-24-94  SRW   Fix call to WinMain to match one in ..\startup\crt0.c
*
*******************************************************************************/

/*
 * SPECIAL BUILD MACRO! 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.
 */
#undef	CRTDLL
#define _DLL

#include <cruntime.h>
#include <oscalls.h>
#include <internal.h>
#include <rterr.h>
#include <stdlib.h>

#undef	_fmode		/* undefine these so that we can reference the */
#undef	_commode	/* local version as well as the DLL variables */

extern int _CRTVAR1 _fmode;	/* must match the definition in <stdlib.h> */
extern int _commode;		/* must match the definition in <internal.h> */

static int _dowildcard = 0;	/* passed to __GetMainArgs() */

/*
 * routine in DLL to do initialization (in this case, C++ constructors)
 */
typedef void (_CALLTYPE1 *PF)(void);

extern void _CALLTYPE4 _initterm(PF *, PF *);

/*
 * pointers to initialization sections
 */
extern PF __xc_a[], __xc_z[];	/* C++ initializers */

/***
*void mainCRTStartup(void)
*
*Purpose:
*	This routine does the C runtime initialization, calls main(), and
*	then exits.  It never returns.
*
*Entry:
*
*Exit:
*
*******************************************************************************/

#ifdef _WINMAIN_
void WinMainCRTStartup(
#else
void mainCRTStartup(
#endif
	void
	)
{
	int argc;	/* three standard arguments to main */
	char **argv;
	char **envp;

	int mainret;

#ifdef _WINMAIN_
	unsigned char *lpszCommandLine;
        STARTUPINFOA StartupInfo;
#endif

	/*
	 * Propogate the _fmode and _commode variables to the DLL
	 */

	*_fmode_dll = _fmode;
	*_commode_dll = _commode;

	/*
	 * Call _setargv(), which will call the __setargv() in this module
	 * if SETARGV.OBJ is linked with the EXE.  If SETARGV.OBJ is not
	 * linked with the EXE, a _dummy setargv() will be called.
	 */

	_setargv();

	/*
	 * Get the arguments for the call to main. Note this must be done
	 * explicitly, rather than as part of the dll's initialization, to
	 * implement optional expansion of wild card chars in filename args
	 */
	__GetMainArgs(&argc, &argv, &envp, _dowildcard);

	/*
	 * do C++ constructors (initializers) specific to this EXE
	 */
	_initterm( __xc_a, __xc_z );

	try {
#ifdef _WINMAIN_
		/*
		 * Skip past program name (first token in command line).
		 * Check for and handle quoted program name.
                 */
		lpszCommandLine = (unsigned char *)_acmdln;

		if ( *lpszCommandLine == '\"' ) {
		    /*
		     * Scan, and skip over, subsequent characters until
		     * another double-quote or a null is encountered.
		     */
		    while ( *++lpszCommandLine && (*lpszCommandLine
			     != '\"') );
		    /*
		     * If we stopped on a double-quote (usual case), skip
		     * over it.
		     */
		    if ( *lpszCommandLine == '\"' )
			lpszCommandLine++;
		}
		else {
		    while (*lpszCommandLine > ' ')
			lpszCommandLine++;
                }

		/*
		 * Skip past any white space preceeding the second token.
		 */
                while (*lpszCommandLine && (*lpszCommandLine <= ' ')) {
                    lpszCommandLine++;
		}

                StartupInfo.dwFlags = 0;
                GetStartupInfoA( &StartupInfo );

		mainret = WinMain( GetModuleHandle(NULL),
				   NULL,
				   lpszCommandLine,
                                   StartupInfo.dwFlags & STARTF_USESHOWWINDOW
                                        ? StartupInfo.wShowWindow
                                        : SW_SHOWDEFAULT
				 );
#else
		mainret = main(argc, argv, envp);
#endif
		exit(mainret);
	}
	except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
	{
		/*
		 * Should never reach here
		 */
		_exit( GetExceptionCode() );

	} /* end of try - except */

}

/***
*__setargv - dummy version (for wildcard expansion) for CRTDLL.DLL model only
*
*Purpose:
*	If the EXE that is linked with CRTDLL.LIB is linked explicitly with
*	SETARGV.OBJ, the call to _setargv() in the C Run-Time start-up code
*	(above) will call this routine, instead of calling a dummy version of
*	_setargv() which will do nothing.  This will set to one the static
*	variable which is passed to __GetMainArgs(), thus enabling wildcard
*	expansion of the command line arguments.
*
*	In the statically-linked C Run-Time models, _setargv() and __setargv()
*	are the actual routines that do the work, but this code exists in
*	CRTDLL.DLL and so some tricks have to be played to make the same
*	SETARGV.OBJ work for EXE's linked with both LIBC.LIB and CRTDLL.LIB.
*
*Entry:
*	The static variable _dowildcard is zero (presumably).
*
*Exit:
*	The static variable _dowildcard is set to one, meaning that the
*	routine __GetMainArgs() in CRTDLL.DLL *will* do wildcard expansion on
*	the command line arguments.  (The default behavior is that it won't.)
*
*Exceptions:
*
*******************************************************************************/

void _CALLTYPE1 __setargv ( void )
{
	_dowildcard = 1;
}
#endif	/* CRTDLL */