Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

841 lines
26 KiB

  1. /***
  2. *crtlib.c - CRT DLL initialization and termination routine (Win32, Dosx32)
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This module contains initialization entry point for the CRT DLL
  8. * in the Win32 environment. It also contains some of the supporting
  9. * initialization and termination code.
  10. *
  11. *Revision History:
  12. * 08-12-91 GJF Module created. Sort of.
  13. * 01-17-92 GJF Return exception code value for RTEs corresponding
  14. * to exceptions.
  15. * 01-29-92 GJF Support for wildcard expansion in filenames on the
  16. * command line.
  17. * 02-14-92 GJF Moved file inheritance stuff to ioinit.c. Call to
  18. * inherit() is replace by call to _ioinit().
  19. * 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor
  20. * 09-04-92 GJF Replaced _CALLTYPE3 with WINAPI.
  21. * 09-30-92 SRW Call _heap_init before _mtinit
  22. * 10-19-92 SKS Add "dowildcard" parameter to GetMainArgs()
  23. * Prepend a second "_" to name since it is internal-only
  24. * 03-20-93 SKS Remove obsolete variables _osmode, _cpumode, etc.
  25. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  26. * 04-07-93 SKS Add _CRTIMP keyword for CRT DLL model
  27. * Change __GetMainArgs to __getmainargs
  28. * 04-13-93 SKS Change call to _mtdeletelocks to new routine _mtterm
  29. * 04-26-93 SKS Change _CRTDLL_INIT to fail loading on failure to
  30. * initialize/clean up, rather than calling _amsg_exit().
  31. * 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV,
  32. * _RT_INVALDISP and _RT_NONCONT.
  33. * 05-06-93 SKS Add call to _heap_term to free up all allocated memory
  34. * *and* address space. This must be the last thing done.
  35. * 06-03-93 GJF Added __proc_attached flag.
  36. * 06-07-93 GJF Incorporated SteveWo's code to call LoadLibrary, from
  37. * crtdll.c.
  38. * 11-05-93 CFW Undefine GetEnviromentStrings.
  39. * 11-09-93 GJF Added call to __initmbctable (must happen before
  40. * environment strings are processed).
  41. * 11-09-93 GJF Merged with NT SDK version (primarily the change of
  42. * 06-07-93 noted above). Also, replace MTHREAD with
  43. * _MT.
  44. * 11-23-93 CFW GetEnviromentStrings undef moved to internal.h.
  45. * 11-23-93 CFW Wide char enable.
  46. * 11-29-93 CFW Wide environment.
  47. * 12-02-93 CFW Remove WPRFLAG dependencies since only one version.
  48. * 12-13-93 SKS Free up per-thread CRT data on DLL_THREAD_DETACH
  49. * with a call to _freeptd() in _CRT_INIT()
  50. * 01-11-94 GJF Use __GetMainArgs name when building libs for NT SDK.
  51. * 02-07-94 CFW POSIXify.
  52. * 03-04-94 SKS Add _newmode parameter to _*getmainargs (except NTSDK)
  53. * 03-31-94 CFW Use __crtGetEnvironmentStrings.
  54. * 04-08-93 CFW Move __crtXXX calls past initialization.
  55. * 04-28-94 GJF Major changes for Win32S support! Added
  56. * AllocPerProcessDataStuct() to allocate and initialize
  57. * the per-process data structure needed in the Win32s
  58. * version of msvcrt*.dll. Also, added a function to
  59. * free and access functions for all read-write global
  60. * variables which might be used by a Win32s app.
  61. * 05-04-94 GJF Made access functions conditional on _M_IX86, added
  62. * some comments to function headers, and fixed a
  63. * possible bug in AllocPerProcessDataStruct (the return
  64. * value for success was NOT explicitly set to something
  65. * nonzero).
  66. * 05-10-94 GJF Added version check so that Win32 version (Win32s)
  67. * will not load on Win32s (resp., Win32).
  68. * 09-06-94 CFW Remove _INTL switch.
  69. * 09-06-94 CFW Remove _MBCS_OS switch.
  70. * 09-06-94 GJF Added __error_mode and __app_type.
  71. * 09-15-94 SKS Clean up comments to avoid source release problems
  72. * 09-21-94 SKS Fix typo: no leading _ on "DLL_FOR_WIN32S"
  73. * 10-04-94 CFW Removed #ifdef _KANJI
  74. * 10-04-94 BWT Fix _NTSDK build
  75. * 11-22-94 CFW Must create wide environment if none.
  76. * 12-19-94 GJF Changed "MSVCRT20" to "MSVCRT30". Also, put testing for
  77. * Win32S under #ifdef _M_IX86. Both changes from Richard
  78. * Shupak.
  79. * 01-16-95 CFW Set default debug output for console.
  80. * 02-13-95 GJF Added initialization for the new _ppd_tzstd and
  81. * _ppd_tzdst fields, thereby fixing the definition of
  82. * _ppd__tzname.
  83. * 02-15-95 CFW Make all CRT message boxes look alike.
  84. * 02-24-95 CFW Use __crtMessageBoxA.
  85. * 02-27-95 CFW Change __crtMessageBoxA params.
  86. * 03-08-95 GJF Added initialization for _ppd__nstream. Removed
  87. * _ppd_lastiob.
  88. * 02-24-95 CFW Call _CrtDumpMemoryLeaks.
  89. * 04-06-95 CFW Use __crtGetEnvironmentStringsA.
  90. * 04-17-95 SKS Free TLS index ppdindex when it is no longer needed
  91. * 04-26-95 GJF Added support for winheap in DLL_FOR_WIN32S build.
  92. * 05-02-95 GJF No _ppd__heap_maxregsize, _ppd__heap_regionsize or
  93. * _ppd__heap_resetsize for WINHEAP.
  94. * 05-24-95 CFW Official ANSI C++ new handler added.
  95. * 06-13-95 CFW De-install client dump hook as client EXE/DLL is gone.
  96. * 06-14-95 GJF Changes for new lowio scheme (__pioinof[]) - no more
  97. * per-process data initialization needed (Win32s) and
  98. * added a call to _ioterm().
  99. * 07-04-95 GJF Interface to __crtGetEnvironmentStrings and _setenvp
  100. * changes slightly.
  101. * 06-27-95 CFW Add win32s support for debug libs.
  102. * 07-03-95 CFW Changed offset of _lc_handle[LC_CTYPE], added sanity
  103. * check to crtlib.c to catch changes to win32s.h that
  104. * modify offset.
  105. * 07-07-95 CFW Simplify default report mode scheme.
  106. * 07-25-95 CFW Add win32s support for user visible debug heap vars.
  107. * 08-21-95 SKS (_ppd_)_CrtDbgMode needs to be initialized for Win32s
  108. * 08-31-95 GJF Added _dstbias.
  109. * 11-09-95 GJF Changed "ISTNT" to "IsTNT".
  110. * 03-18-96 SKS Add _fileinfo to variables implemented as functions.
  111. * 04-22-96 GJF Check for failure of heap initialization.
  112. * 05-14-96 GJF Changed where __proc_attached is set so that it
  113. * denotes successful completion of initialization.
  114. * 06-11-96 JWM Changed string "MSVCRT40" to "MSVCRT" in _CRTDLL_INIT().
  115. * 06-27-96 GJF Purged Win32s support. Note, the access functions must
  116. * be retained for backwards compatibility.
  117. * 06-28-96 SKS Remove obsolete local variable "hmod".
  118. * 03-17-97 RDK Add reference to _mbcasemap.
  119. * 07-24-97 GJF heap_init changed slightly to support option to use
  120. * heap running directly on Win32 API.
  121. * 08-08-97 GJF Rearranged #ifdef-s so ptd is only defined when it is
  122. * used (under ANSI_NEW_HANDLER).
  123. * 10-02-98 GJF Use GetVersionEx instead of GetVersion and store OS ID
  124. * in _osplatform.
  125. * 04-30-99 GJF Don't clean up system resources if the whole process
  126. * if terminating.
  127. * 09-02-99 PML Put Win32s check in system CRT only.
  128. * 02-02-00 GB Added ATTACH_THREAD support for _CRT_INIT where we
  129. * initialise per thread data so that in case where we
  130. * are short of memory, we don't have to kill the whole
  131. * process for inavailablity of space.
  132. * 08-22-00 GB Fixed potentia leak of ptd in CRT_INIT
  133. * 09-06-00 GB Changed the function definations of _pctype and
  134. * _pwctype to const
  135. * 03-16-01 PML _alloca the OSVERSIONINFO so /GS can work (vs7#224261)
  136. * 03-19-01 BWT Add test to preclude msvcrt.dll loading on anything other
  137. * than the OS it ships with.
  138. * 03-26-01 PML Use GetVersionExA, not GetVersionEx (vs7#230286)
  139. * 03-27-01 PML Fail DLL load instead of calling _amsg_exit, and
  140. * propogate error on EXE arg parsing up (vs7#231220).
  141. * 03-28-01 PML Protect against GetModuleFileName overflow (vs7#231284)
  142. * 04-05-01 PML Clean up on DLL unload due to FreeLibrary, or on
  143. * termination by ExitProcess instead of exit (vs7#235781)
  144. * 04-30-01 BWT Remove _NTSDK and just return false if the OS doesn't match
  145. * 12-12-01 BWT getptd->getptd_noexit - deal with error here.
  146. * 02-20-02 BWT prefast fixes - don't use alloca
  147. *
  148. *******************************************************************************/
  149. #if defined(CRTDLL)
  150. #include <cruntime.h>
  151. #include <oscalls.h>
  152. #include <dos.h>
  153. #include <internal.h>
  154. #include <malloc.h>
  155. #include <mbctype.h>
  156. #include <mtdll.h>
  157. #include <process.h>
  158. #include <rterr.h>
  159. #include <stdio.h>
  160. #include <stdlib.h>
  161. #include <string.h>
  162. #include <awint.h>
  163. #include <tchar.h>
  164. #include <time.h>
  165. #include <dbgint.h>
  166. #ifdef _SYSCRT
  167. #include <ntverp.h>
  168. #endif
  169. /*
  170. * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH
  171. */
  172. static int proc_attached = 0;
  173. /*
  174. * command line, environment, and a few other globals
  175. */
  176. wchar_t *_wcmdln = NULL; /* points to wide command line */
  177. char *_acmdln = NULL; /* points to command line */
  178. char *_aenvptr = NULL; /* points to environment block */
  179. #ifndef _POSIX_
  180. wchar_t *_wenvptr = NULL; /* points to wide environment block */
  181. #endif /* _POSIX_ */
  182. void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
  183. extern int _newmode; /* declared in <internal.h> */
  184. int __error_mode = _OUT_TO_DEFAULT;
  185. int __app_type = _UNKNOWN_APP;
  186. static void __cdecl inherit(void); /* local function */
  187. /***
  188. *int __[w]getmainargs - get values for args to main()
  189. *
  190. *Purpose:
  191. * This function invokes the command line parsing and copies the args
  192. * to main back through the passsed pointers. The reason for doing
  193. * this here, rather than having _CRTDLL_INIT do the work and exporting
  194. * the __argc and __argv, is to support the linked-in option to have
  195. * wildcard characters in filename arguments expanded.
  196. *
  197. *Entry:
  198. * int *pargc - pointer to argc
  199. * _TCHAR ***pargv - pointer to argv
  200. * _TCHAR ***penvp - pointer to envp
  201. * int dowildcard - flag (true means expand wildcards in cmd line)
  202. * _startupinfo * startinfo- other info to be passed to CRT DLL
  203. *
  204. *Exit:
  205. * Returns 0 on success, negative if _*setargv returns an error. Values
  206. * for the arguments to main() are copied through the passed pointers.
  207. *
  208. *******************************************************************************/
  209. #if !defined(_POSIX_)
  210. _CRTIMP int __cdecl __wgetmainargs (
  211. int *pargc,
  212. wchar_t ***pargv,
  213. wchar_t ***penvp,
  214. int dowildcard,
  215. _startupinfo * startinfo)
  216. {
  217. int ret;
  218. #ifdef ANSI_NEW_HANDLER
  219. #ifdef _MT
  220. /* set per-thread new handler for main thread */
  221. _ptiddata ptd = _getptd_noexit();
  222. if (!ptd) {
  223. #ifdef _SYSCRT
  224. ExitProcess(-1); // Failed to parse the cmdline - bail
  225. #else
  226. return -1;
  227. #endif
  228. }
  229. ptd->_newh = startinfo->newh;
  230. #endif
  231. /* set global default per-thread new handler */
  232. _defnewh = startinfo->newh;
  233. #endif /* ANSI_NEW_HANDLER */
  234. /* set global new mode flag */
  235. _newmode = startinfo->newmode;
  236. if ( dowildcard )
  237. ret = __wsetargv(); /* do wildcard expansion after parsing args */
  238. else
  239. ret = _wsetargv(); /* NO wildcard expansion; just parse args */
  240. if (ret < 0)
  241. #ifdef _SYSCRT
  242. ExitProcess(-1); // Failed to parse the cmdline - bail
  243. #else
  244. return ret;
  245. #endif
  246. *pargc = __argc;
  247. *pargv = __wargv;
  248. /*
  249. * if wide environment does not already exist,
  250. * create it from multibyte environment
  251. */
  252. if (!_wenviron)
  253. __mbtow_environ();
  254. *penvp = _wenviron;
  255. return ret;
  256. }
  257. #endif /* !defined(_POSIX_) */
  258. _CRTIMP int __cdecl __getmainargs (
  259. int *pargc,
  260. char ***pargv,
  261. char ***penvp,
  262. int dowildcard
  263. ,
  264. _startupinfo * startinfo
  265. )
  266. {
  267. int ret;
  268. #ifdef ANSI_NEW_HANDLER
  269. #ifdef _MT
  270. /* set per-thread new handler for main thread */
  271. _ptiddata ptd = _getptd_noexit();
  272. if (!ptd) {
  273. #ifdef _SYSCRT
  274. ExitProcess(-1); // Failed to parse the cmdline - bail
  275. #else
  276. return ret;
  277. #endif
  278. }
  279. ptd->_newh = startinfo->newh;
  280. #endif
  281. /* set global default per-thread new handler */
  282. _defnewh = startinfo->newh;
  283. #endif /* ANSI_NEW_HANDLER */
  284. /* set global new mode flag */
  285. _newmode = startinfo->newmode;
  286. if ( dowildcard )
  287. ret = __setargv(); /* do wildcard expansion after parsing args */
  288. else
  289. ret = _setargv(); /* NO wildcard expansion; just parse args */
  290. if (ret < 0)
  291. #ifdef _SYSCRT
  292. ExitProcess(-1); // Failed to parse the cmdline - bail
  293. #else
  294. return ret;
  295. #endif
  296. *pargc = __argc;
  297. *pargv = __argv;
  298. *penvp = _environ;
  299. return ret;
  300. }
  301. /***
  302. *BOOL _CRTDLL_INIT(hDllHandle, dwReason, lpreserved) - C DLL initialization.
  303. *
  304. *Purpose:
  305. * This routine does the C runtime initialization.
  306. *
  307. *Entry:
  308. *
  309. *Exit:
  310. *
  311. *******************************************************************************/
  312. typedef void (__stdcall *NTVERSION_INFO_FCN)(PDWORD, PDWORD, PDWORD);
  313. BOOL WINAPI _CRTDLL_INIT(
  314. HANDLE hDllHandle,
  315. DWORD dwReason,
  316. LPVOID lpreserved
  317. )
  318. {
  319. if ( dwReason == DLL_PROCESS_ATTACH ) {
  320. OSVERSIONINFOA *posvi;
  321. #if defined(_SYSCRT)
  322. // The app may have set Win32VersionValue in the PE header to change
  323. // GetVersionEx. Ask NTDLL for the real version and bail if we don't match.
  324. DWORD NtMajorVersion;
  325. DWORD NtMinorVersion;
  326. #ifdef _WIN64
  327. NTVERSION_INFO_FCN GetNtVersionInfo = (NTVERSION_INFO_FCN) GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetNtVersionNumbers");
  328. if (!GetNtVersionInfo)
  329. GetNtVersionInfo = (NTVERSION_INFO_FCN) GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetNtVersionInfo");
  330. if (!GetNtVersionInfo)
  331. return FALSE;
  332. GetNtVersionInfo(&NtMajorVersion, &NtMinorVersion, NULL);
  333. #else
  334. void __declspec(dllimport) __stdcall RtlGetNtVersionNumbers(PDWORD, PDWORD, PDWORD);
  335. RtlGetNtVersionNumbers(&NtMajorVersion, &NtMinorVersion, NULL);
  336. #endif
  337. if ((NtMajorVersion != VER_PRODUCTMAJORVERSION) || (NtMinorVersion != VER_PRODUCTMINORVERSION))
  338. return FALSE;
  339. #endif /* _SYSCRT */
  340. /*
  341. * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid
  342. * triggering the /GS buffer overrun detection. That can't be
  343. * used here, since the guard cookie isn't available until we
  344. * initialize it from here!
  345. */
  346. posvi = (OSVERSIONINFOA *)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA));
  347. if (!posvi)
  348. return FALSE;
  349. /*
  350. * Get the full Win32 version.
  351. */
  352. posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  353. if ( !GetVersionExA(posvi) ) {
  354. HeapFree(GetProcessHeap(), 0, posvi);
  355. return FALSE;
  356. }
  357. _osplatform = posvi->dwPlatformId;
  358. _winmajor = posvi->dwMajorVersion;
  359. _winminor = posvi->dwMinorVersion;
  360. /*
  361. * The somewhat bizarre calculations of _osver and _winver are
  362. * required for backward compatibility (used to use GetVersion)
  363. */
  364. _osver = (posvi->dwBuildNumber) & 0x07fff;
  365. HeapFree(GetProcessHeap(), 0, posvi);
  366. if ( _osplatform != VER_PLATFORM_WIN32_NT )
  367. _osver |= 0x08000;
  368. _winver = (_winmajor << 8) + _winminor;
  369. #ifdef _MT
  370. if ( !_heap_init(1) ) /* initialize heap */
  371. #else
  372. if ( !_heap_init(0) ) /* initialize heap */
  373. #endif
  374. /*
  375. * The heap cannot be initialized, return failure to the
  376. * loader.
  377. */
  378. return FALSE;
  379. #ifdef _MT
  380. if(!_mtinit()) /* initialize multi-thread */
  381. {
  382. /*
  383. * If the DLL load is going to fail, we must clean up
  384. * all resources that have already been allocated.
  385. */
  386. _heap_term(); /* heap is now invalid! */
  387. return FALSE; /* fail DLL load on failure */
  388. }
  389. #endif /* _MT */
  390. if (_ioinit() < 0) { /* inherit file info */
  391. /* Clean up already-allocated resources */
  392. #ifdef _MT
  393. /* free TLS index, call _mtdeletelocks() */
  394. _mtterm();
  395. #endif /* _MT */
  396. _heap_term(); /* heap is now invalid! */
  397. return FALSE; /* fail DLL load on failure */
  398. }
  399. _aenvptr = (char *)__crtGetEnvironmentStringsA();
  400. _acmdln = (char *)GetCommandLineA();
  401. #ifndef _POSIX_
  402. _wcmdln = (wchar_t *)__crtGetCommandLineW();
  403. #endif /* _POSIX_ */
  404. #ifdef _MBCS
  405. /*
  406. * Initialize multibyte ctype table. Always done since it is
  407. * needed for processing the environment strings.
  408. */
  409. __initmbctable();
  410. #endif
  411. /*
  412. * For CRT DLL, since we don't know the type (wide or multibyte)
  413. * of the program, we create only the multibyte type since that
  414. * is by far the most likely case. Wide environment will be created
  415. * on demand as usual.
  416. */
  417. if (_setenvp() < 0 || /* get environ info */
  418. _cinit() != 0) /* do C data initialize */
  419. {
  420. _ioterm(); /* shut down lowio */
  421. #ifdef _MT
  422. _mtterm(); /* free TLS index, call _mtdeletelocks() */
  423. #endif /* _MT */
  424. _heap_term(); /* heap is now invalid! */
  425. return FALSE; /* fail DLL load on failure */
  426. }
  427. /*
  428. * Increment flag indicating process attach notification
  429. * has been received.
  430. */
  431. proc_attached++;
  432. }
  433. else if ( dwReason == DLL_PROCESS_DETACH ) {
  434. /*
  435. * if a client process is detaching, make sure minimal
  436. * runtime termination is performed and clean up our
  437. * 'locks' (i.e., delete critical sections).
  438. */
  439. if ( proc_attached > 0 ) {
  440. proc_attached--;
  441. /*
  442. * Any basic clean-up done here may also need
  443. * to be done below if Process Attach is partly
  444. * processed and then a failure is encountered.
  445. */
  446. if ( _C_Termination_Done == FALSE )
  447. _cexit();
  448. __CRTDLL_CallStaticTerminators();
  449. #ifdef _DEBUG
  450. /* Dump all memory leaks */
  451. if (_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF)
  452. {
  453. _CrtSetDumpClient(NULL);
  454. _CrtDumpMemoryLeaks();
  455. }
  456. #endif
  457. /*
  458. * What remains is to clean up the system resources we have
  459. * used (handles, critical sections, memory,...,etc.). This
  460. * needs to be done if the whole process is NOT terminating.
  461. */
  462. if ( lpreserved == NULL )
  463. {
  464. /*
  465. * The process is NOT terminating so we must clean up...
  466. */
  467. _ioterm();
  468. #ifdef _MT
  469. /* free TLS index, call _mtdeletelocks() */
  470. _mtterm();
  471. #endif /* _MT */
  472. /* This should be the last thing the C run-time does */
  473. _heap_term(); /* heap is now invalid! */
  474. }
  475. }
  476. else
  477. /* no prior process attach, just return */
  478. return FALSE;
  479. }
  480. #ifdef _MT
  481. else if ( dwReason == DLL_THREAD_ATTACH )
  482. {
  483. _ptiddata ptd;
  484. if ( ((ptd = _calloc_crt(1, sizeof(struct _tiddata))) != NULL))
  485. {
  486. if (FLS_SETVALUE(__tlsindex, (LPVOID)ptd) ) {
  487. /*
  488. * Initialize of per-thread data
  489. */
  490. _initptd(ptd);
  491. ptd->_tid = GetCurrentThreadId();
  492. ptd->_thandle = (uintptr_t)(-1);
  493. } else
  494. {
  495. _free_crt(ptd);
  496. return FALSE;
  497. }
  498. } else
  499. {
  500. return FALSE;
  501. }
  502. }
  503. else if ( dwReason == DLL_THREAD_DETACH )
  504. {
  505. _freeptd(NULL); /* free up per-thread CRT data */
  506. }
  507. #endif /* _MT */
  508. return TRUE;
  509. }
  510. /***
  511. *_amsg_exit(rterrnum) - Fast exit fatal errors
  512. *
  513. *Purpose:
  514. * Exit the program with error code of 255 and appropriate error
  515. * message.
  516. *
  517. *Entry:
  518. * int rterrnum - error message number (amsg_exit only).
  519. *
  520. *Exit:
  521. * Calls exit() (for integer divide-by-0) or _exit() indirectly
  522. * through _aexit_rtn [amsg_exit].
  523. * For multi-thread: calls _exit() function
  524. *
  525. *Exceptions:
  526. *
  527. *******************************************************************************/
  528. void __cdecl _amsg_exit (
  529. int rterrnum
  530. )
  531. {
  532. if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
  533. _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
  534. _FF_MSGBANNER(); /* write run-time error banner */
  535. _NMSG_WRITE(rterrnum); /* write message */
  536. _aexit_rtn(255); /* normally _exit(255) */
  537. }
  538. #if defined(_M_IX86 )
  539. /*
  540. * Functions to access user-visible, per-process variables
  541. */
  542. /*
  543. * Macro to construct the name of the access function from the variable
  544. * name.
  545. */
  546. #define AFNAME(var) __p_ ## var
  547. /*
  548. * Macro to construct the access function's return value from the variable
  549. * name.
  550. */
  551. #define AFRET(var) &var
  552. /*
  553. ***
  554. *** Template
  555. ***
  556. _CRTIMP __cdecl
  557. AFNAME() (void)
  558. {
  559. return AFRET();
  560. }
  561. ***
  562. ***
  563. ***
  564. */
  565. #ifdef _DEBUG
  566. _CRTIMP long *
  567. AFNAME(_crtAssertBusy) (void)
  568. {
  569. return AFRET(_crtAssertBusy);
  570. }
  571. _CRTIMP long *
  572. AFNAME(_crtBreakAlloc) (void)
  573. {
  574. return AFRET(_crtBreakAlloc);
  575. }
  576. _CRTIMP int *
  577. AFNAME(_crtDbgFlag) (void)
  578. {
  579. return AFRET(_crtDbgFlag);
  580. }
  581. #endif /* _DEBUG */
  582. _CRTIMP char ** __cdecl
  583. AFNAME(_acmdln) (void)
  584. {
  585. return AFRET(_acmdln);
  586. }
  587. _CRTIMP wchar_t ** __cdecl
  588. AFNAME(_wcmdln) (void)
  589. {
  590. return AFRET(_wcmdln);
  591. }
  592. _CRTIMP unsigned int * __cdecl
  593. AFNAME(_amblksiz) (void)
  594. {
  595. return AFRET(_amblksiz);
  596. }
  597. _CRTIMP int * __cdecl
  598. AFNAME(__argc) (void)
  599. {
  600. return AFRET(__argc);
  601. }
  602. _CRTIMP char *** __cdecl
  603. AFNAME(__argv) (void)
  604. {
  605. return AFRET(__argv);
  606. }
  607. _CRTIMP wchar_t *** __cdecl
  608. AFNAME(__wargv) (void)
  609. {
  610. return AFRET(__wargv);
  611. }
  612. _CRTIMP int * __cdecl
  613. AFNAME(_commode) (void)
  614. {
  615. return AFRET(_commode);
  616. }
  617. _CRTIMP int * __cdecl
  618. AFNAME(_daylight) (void)
  619. {
  620. return AFRET(_daylight);
  621. }
  622. _CRTIMP long * __cdecl
  623. AFNAME(_dstbias) (void)
  624. {
  625. return AFRET(_dstbias);
  626. }
  627. _CRTIMP char *** __cdecl
  628. AFNAME(_environ) (void)
  629. {
  630. return AFRET(_environ);
  631. }
  632. _CRTIMP wchar_t *** __cdecl
  633. AFNAME(_wenviron) (void)
  634. {
  635. return AFRET(_wenviron);
  636. }
  637. _CRTIMP int * __cdecl
  638. AFNAME(_fmode) (void)
  639. {
  640. return AFRET(_fmode);
  641. }
  642. _CRTIMP int * __cdecl
  643. AFNAME(_fileinfo) (void)
  644. {
  645. return AFRET(_fileinfo);
  646. }
  647. _CRTIMP char *** __cdecl
  648. AFNAME(__initenv) (void)
  649. {
  650. return AFRET(__initenv);
  651. }
  652. _CRTIMP wchar_t *** __cdecl
  653. AFNAME(__winitenv) (void)
  654. {
  655. return AFRET(__winitenv);
  656. }
  657. _CRTIMP FILE *
  658. AFNAME(_iob) (void)
  659. {
  660. return &_iob[0];
  661. }
  662. _CRTIMP unsigned char * __cdecl
  663. AFNAME(_mbctype) (void)
  664. {
  665. return &_mbctype[0];
  666. }
  667. _CRTIMP unsigned char * __cdecl
  668. AFNAME(_mbcasemap) (void)
  669. {
  670. return &_mbcasemap[0];
  671. }
  672. _CRTIMP int * __cdecl
  673. AFNAME(__mb_cur_max) (void)
  674. {
  675. return AFRET(__mb_cur_max);
  676. }
  677. _CRTIMP unsigned int * __cdecl
  678. AFNAME(_osver) (void)
  679. {
  680. return AFRET(_osver);
  681. }
  682. _CRTIMP const unsigned short ** __cdecl
  683. AFNAME(_pctype) (void)
  684. {
  685. return AFRET(_pctype);
  686. }
  687. _CRTIMP const unsigned short ** __cdecl
  688. AFNAME(_pwctype) (void)
  689. {
  690. return AFRET(_pwctype);
  691. }
  692. _CRTIMP char ** __cdecl
  693. AFNAME(_pgmptr) (void)
  694. {
  695. return AFRET(_pgmptr);
  696. }
  697. _CRTIMP wchar_t ** __cdecl
  698. AFNAME(_wpgmptr) (void)
  699. {
  700. return AFRET(_wpgmptr);
  701. }
  702. _CRTIMP long * __cdecl
  703. AFNAME(_timezone) (void)
  704. {
  705. return AFRET(_timezone);
  706. }
  707. _CRTIMP char ** __cdecl
  708. AFNAME(_tzname) (void)
  709. {
  710. return &_tzname[0];
  711. }
  712. _CRTIMP unsigned int * __cdecl
  713. AFNAME(_winmajor) (void)
  714. {
  715. return AFRET(_winmajor);
  716. }
  717. _CRTIMP unsigned int * __cdecl
  718. AFNAME(_winminor) (void)
  719. {
  720. return AFRET(_winminor);
  721. }
  722. _CRTIMP unsigned int * __cdecl
  723. AFNAME(_winver) (void)
  724. {
  725. return AFRET(_winver);
  726. }
  727. #endif /* _M_IX86 */
  728. #endif /* CRTDLL */