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.

129 lines
4.2 KiB

  1. /***
  2. *putch.c - contains the _putch() routine
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * The routine "_putch()" writes a single character to the console.
  8. *
  9. * NOTE: In real-mode MS-DOS the character is actually written to standard
  10. * output, and is therefore redirected when standard output is redirected.
  11. * However, under Win32 console mode, the character is ALWAYS written
  12. * to the console, even when standard output has been redirected.
  13. *
  14. *Revision History:
  15. * 06-08-89 PHG Module created, based on asm version
  16. * 03-13-90 GJF Made calling type _CALLTYPE1, added #include
  17. * <cruntime.h> and fixed copyright. Also, cleaned up
  18. * the formatting a bit.
  19. * 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
  20. * 07-24-90 SBM Removed '32' from API names
  21. * 10-01-90 GJF New-style function declarators.
  22. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  23. * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
  24. * 01-16-91 GJF ANSI naming.
  25. * 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
  26. * 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
  27. * 07-26-91 GJF Took out init. stuff and cleaned up the error
  28. * handling [_WIN32_].
  29. * 03-20-93 GJF Use WriteConsole instead of WriteFile.
  30. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  31. * 09-06-94 CFW Remove Cruiser support.
  32. * 09-06-94 CFW Replace MTHREAD with _MT.
  33. * 12-03-94 SKS Clean up OS/2 references
  34. * 12-08-95 SKS _confh is now initialized on demand
  35. * 02-07-98 GJF Changes for Win64: type of _confh is now intptr_t.
  36. * 04-29-02 GB Added try-finally arounds lock-unlock.
  37. *
  38. *******************************************************************************/
  39. #include <cruntime.h>
  40. #include <oscalls.h>
  41. #include <conio.h>
  42. #include <internal.h>
  43. #include <mtdll.h>
  44. #include <stdio.h>
  45. /*
  46. * declaration for console handle
  47. */
  48. extern intptr_t _confh;
  49. /***
  50. *int _putch(c) - write a character to the console
  51. *
  52. *Purpose:
  53. * Calls WriteConsole to output the character
  54. * Note: in Win32 console mode always writes to console even
  55. * when stdout redirected
  56. *
  57. *Entry:
  58. * c - Character to be output
  59. *
  60. *Exit:
  61. * If an error is returned from WriteConsole
  62. * Then returns EOF
  63. * Otherwise
  64. * returns character that was output
  65. *
  66. *Exceptions:
  67. *
  68. *******************************************************************************/
  69. #ifdef _MT
  70. /* normal version lock and unlock the console, and then call the _lk version
  71. which directly accesses the console without locking. */
  72. int __cdecl _putch (
  73. int c
  74. )
  75. {
  76. int ch;
  77. _mlock(_CONIO_LOCK); /* secure the console lock */
  78. __TRY
  79. ch = _putch_lk(c); /* output the character */
  80. __FINALLY
  81. _munlock(_CONIO_LOCK); /* release the console lock */
  82. __END_TRY_FINALLY
  83. return ch;
  84. }
  85. #endif /* _MT */
  86. /* define version which accesses the console directly - normal version in
  87. non-_MT situations, special _lk version in _MT */
  88. #ifdef _MT
  89. int __cdecl _putch_lk (
  90. #else
  91. int __cdecl _putch (
  92. #endif
  93. int c
  94. )
  95. {
  96. /* can't use ch directly unless sure we have a big-endian machine */
  97. unsigned char ch = (unsigned char)c;
  98. ULONG num_written;
  99. /*
  100. * _confh, the handle to the console output, is created the
  101. * first time that either _putch() or _cputs() is called.
  102. */
  103. if (_confh == -2)
  104. __initconout();
  105. /* write character to console file handle */
  106. if ( (_confh == -1) || !WriteConsole( (HANDLE)_confh,
  107. (LPVOID)&ch,
  108. 1,
  109. &num_written,
  110. NULL )
  111. )
  112. /* return error indicator */
  113. return EOF;
  114. return ch;
  115. }