summaryrefslogtreecommitdiffstats
path: root/private/crt32/dllstuff/crtlib.c
blob: 8a813c5801708a2c4b1ed90c3d26d21f6a62c700 (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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#ifdef  CRTDLL
/***
*crtlib.c - CRT DLL initialization and termination routine (Win32, Dosx32)
*
*       Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved.
*
*Purpose:
*       This module contains initialization entry point for the CRT DLL in
*       Win32 and Dosx32 environments. It also contains some of the supporting
*       initialization and termination code.
*
*Revision History:
*       08-12-91  GJF   Module created. Sort of.
*       01-17-92  GJF   Return exception code value for RTEs corresponding
*                       to exceptions.
*       01-29-92  GJF   Support for wildcard expansion in filenames on the
*                       command line.
*       02-14-92  GJF   Moved file inheritance stuff to ioinit.c. Call to
*                       inherit() is replace by call to _ioinit().
*	08-26-92  SKS	Add _osver, _winver, _winmajor, _winminor
*	09-04-92  GJF	Replaced _CALLTYPE3 with WINAPI.
*	09-30-92  SRW	Call _heap_init before _mtinit
*	10-19-92  SKS	Add "dowildcard" parameter to GetMainArgs()
*			Prepend a second "_" to name since it is internal-only
*	04-16-93  SKS	Change call to _mtdeletelocks to _mtterm.  _mtterm
*			calls _mtdeletelocks and also frees up the TLS index.
*	04-27-93  GJF	Removed support for _RT_STACK, _RT_INTDIV,
*			_RT_INVALDISP and _RT_NONCONT.
*	05-11-93  SKS	Change _CRTDLL_INIT to fail loading on failure to
*			initialize/clean up, rather than calling _amsg_exit().
*	06-03-93  GJF	Added __proc_attached flag.
*	06-07-93  GJF	Incorporated SteveWo's code to call LoadLibrary, from
*			crtdll.c.
*	12-14-93  SKS	Add _freeptd(), which frees up the per-thread data
*			maintained by the C run-time library.
*
*******************************************************************************/

#include <cruntime.h>
#include <oscalls.h>
#include <dos.h>
#include <internal.h>
#include <os2dll.h>
#include <process.h>
#include <rterr.h>
#include <stdlib.h>
#include <string.h>

/*
 * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH
 */
static int __proc_attached = 0;

/*
 * command line, environment, and a few other globals
 */
char *_acmdln;          /* points to command line */
char *_aenvptr;         /* points to environment block */

void (_CALLTYPE1 * _aexit_rtn)(int) = _exit;   /* RT message return procedure */

static void _CALLTYPE4 inherit(void);  /* local function */


/***
*void __GetMainArgs(pargc, pargv, penvp, dowildcard) - get values for args to main()
*
*Purpose:
*       This function invokes the command line parsing and copies the args
*       to main back through the passsed pointers. The reason for doing
*       this here, rather than having _CRTDLL_INIT do the work and exporting
*       the __argc and __argv, is to support the linked-in option to have
*       wildcard characters in filename arguments expanded.
*
*Entry:
*       int *pargc      - pointer to argc
*       char ***pargv   - pointer to argv
*       char ***penvp   - pointer to envp
*	int dowildcard  - flag (true means expand wildcards in cmd line)
*
*Exit:
*       No return value. Values for the arguments to main() are copied through
*       the passed pointers.
*
*******************************************************************************/


void _CALLTYPE1 __GetMainArgs (
        int *pargc,
        char ***pargv,
        char ***penvp,
	int dowildcard)
{
        if ( dowildcard )
                __setargv();	/* do wildcard expansion after parsing args */
        else
                _setargv();	/* NO wildcard expansion; just parse args */

        *pargc = __argc;
        *pargv = __argv;
        *penvp = _environ;
}


/***
*BOOL _CRTDLL_INIT(hDllHandle, dwReason, lpreserved) - C DLL initialization.
*
*Purpose:
*       This routine does the C runtime initialization.
*
*Entry:
*
*Exit:
*
*******************************************************************************/

BOOL WINAPI _CRTDLL_INIT(
        HANDLE  hDllHandle,
        DWORD   dwReason,
        LPVOID  lpreserved
        )
{
	char szDllName[ MAX_PATH ];

	if ( dwReason == DLL_PROCESS_ATTACH ) {

		/*
		 * Increment flag indicating process attach notification
		 * has been received.
		 */
		__proc_attached++;

		/*
		 * Pin ourselves in memory since we dont clean up if we
		 * unload.
		 */
		if ( !GetModuleFileName( hDllHandle,
					 szDllName,
					 sizeof(szDllName))
		   )
		{
                    strcpy(szDllName, "CRTDLL");
                }
		LoadLibrary(szDllName);
	}
	else if ( dwReason == DLL_PROCESS_DETACH ) {
		/*
		 * if this is a process detach notification, make sure there
		 * has been a prior process attach notification.
		 */
		if ( __proc_attached > 0 )
			__proc_attached--;
		else
			/* no prior process attach, just return */
			return FALSE;
	}
	else if ( dwReason == DLL_THREAD_DETACH )
	{
		_freeptd(NULL); 	/* free up per-thread CRT data */
	}
  

        /*
         * Only do initialization when a client process attaches to
         * the DLL.
         */
        if ( dwReason != DLL_PROCESS_ATTACH ) {
                /*
                 * if a client process is detaching, make sure minimal
                 * runtime termination is performed and clean up our
                 * 'locks' (i.e., delete critical sections).
                 */
		if ( dwReason == DLL_PROCESS_DETACH ) {

			if ( _C_Termination_Done == FALSE )
				_c_exit();
#ifdef MTHREAD
			_mtterm();  /* free TLS index, call _mtdeletelocks() */
#endif
		}

                return TRUE;
	}

        _acmdln = (char *)GetCommandLine();
        _aenvptr = (char *)GetEnvironmentStrings();

        /*
         * Get the full Win32 version
         */
        _osversion =                    /* OBSOLETE */
        _osver = GetVersion();

        _winminor = (_osver >> 8) & 0x00FF ;
        _winmajor = _osver & 0x00FF ;
        _winver = (_winmajor << 8) + _winminor;
        _osver = (_osver >> 16) & 0x00FFFF ;

        /* --------- The following block is OBSOLETE --------- */

        /*
         * unpack base version info
         */
        _baseversion = (_osversion & 0xFFFF0000) >> 16;
        _baseminor = _baseversion & 0x00FF;
        _basemajor = (_baseversion & 0xFF00) >> 8;

        /*
         * unpack top-level version info (Windows version)
         */
        _osversion &= 0x0000FFFF;
        _osmajor = _osversion & 0x00FF;
        _osminor = (_osversion & 0xFF00) >> 8;

        /* --------- The preceding block is OBSOLETE --------- */

        _heap_init();                           /* initialize heap */
#ifdef MTHREAD
	if(!_mtinit())				/* initialize multi-thread */
		return FALSE;			/* fail DLL load on failure */
#endif
        _ioinit();                              /* inherit file info */
        _setenvp();                             /* get environ info */

        _cinit();                               /* do C data initialize */

        return TRUE;
}

/***
*_amsg_exit(rterrnum) - Fast exit fatal errors
*
*Purpose:
*       Exit the program with error code of 255 and appropriate error
*       message.
*
*Entry:
*       int rterrnum - error message number (amsg_exit only).
*
*Exit:
*       Calls exit() (for integer divide-by-0) or _exit() indirectly
*       through _aexit_rtn [amsg_exit].
*       For multi-thread: calls _exit() function
*
*Exceptions:
*
*******************************************************************************/

void _CALLTYPE1 _amsg_exit (
        int rterrnum
        )
{
        _FF_MSGBANNER();                        /* write run-time error banner */
        _NMSG_WRITE(rterrnum);                  /* write message */

        _aexit_rtn(255);                        /* normally _exit(255) */
}
#endif  /* CRTDLL */