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.

149 lines
5.4 KiB

  1. /***
  2. *cgets.c - buffered keyboard input
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _cgets() - read a string directly from console
  8. *
  9. *Revision History:
  10. * 06-09-89 PHG Module created, based on asm version
  11. * 03-12-90 GJF Made calling type _CALLTYPE1, added #include
  12. * <cruntime.h> and fixed copyright. Also, cleaned
  13. * up the formatting a bit.
  14. * 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
  15. * 07-24-90 SBM Removed '32' from API names
  16. * 08-13-90 SBM Compiles cleanly with -W3
  17. * 09-28-90 GJF New-style function declarator.
  18. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  19. * 12-13-90 GJF Fixed a couple of bugs.
  20. * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
  21. * 01-16-91 GJF ANSI naming.
  22. * 01-25-91 SRW Get/SetConsoleMode parameters changed (_WIN32_)
  23. * 02-18-91 SRW Get/SetConsoleMode required read/write access (_WIN32_)
  24. * 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
  25. * 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
  26. * 07-26-91 GJF Took out init. stuff and cleaned up the error
  27. * handling [_WIN32_].
  28. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  29. * 04-19-93 GJF Use ReadConsole instead of ReadFile.
  30. * 09-06-94 CFW Remove Cruiser support.
  31. * 12-03-94 SKS Clean up OS/2 references
  32. * 03-02-95 GJF Treat string[0] as an unsigned value.
  33. * 12-08-95 SKS _coninph is now initialized on demand
  34. * 02-07-98 GJF Changes for Win64: _coninph is now an intptr_t.
  35. * 04-29-02 GB Added try-finally arounds lock-unlock.
  36. *
  37. *******************************************************************************/
  38. #include <cruntime.h>
  39. #include <oscalls.h>
  40. #include <mtdll.h>
  41. #include <conio.h>
  42. #include <stdlib.h>
  43. #include <internal.h>
  44. /*
  45. * mask to clear the bits required to be 0 in the handle state passed to
  46. * DOSSETFHSTATE.
  47. */
  48. #define FHSTATEMASK 0xffd07888
  49. /*
  50. * declaration for console handle
  51. */
  52. extern intptr_t _coninpfh;
  53. /***
  54. *char *_cgets(string) - read string from console
  55. *
  56. *Purpose:
  57. * Reads a string from the console via ReadConsole on a cooked console
  58. * handle. string[0] must contain the maximum length of the
  59. * string. Returns pointer to str[2].
  60. *
  61. * NOTE: _cgets() does NOT check the pushback character buffer (i.e.,
  62. * _chbuf). Thus, _cgets() will not return any character that is
  63. * pushed back by the _ungetch() call.
  64. *
  65. *Entry:
  66. * char *string - place to store read string, str[0] = max length.
  67. *
  68. *Exit:
  69. * returns pointer to str[2], where the string starts.
  70. * returns NULL if error occurs
  71. *
  72. *Exceptions:
  73. *
  74. *******************************************************************************/
  75. char * __cdecl _cgets (
  76. char *string
  77. )
  78. {
  79. ULONG oldstate;
  80. ULONG num_read;
  81. char *result;
  82. _mlock(_CONIO_LOCK); /* lock the console */
  83. __TRY
  84. string[1] = 0; /* no chars read yet */
  85. result = &string[2];
  86. /*
  87. * _coninpfh, the handle to the console input, is created the first
  88. * time that either _getch() or _cgets() or _kbhit() is called.
  89. */
  90. if ( _coninpfh == -2 )
  91. __initconin();
  92. if ( _coninpfh == -1 ) {
  93. result=NULL;
  94. } else {
  95. GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
  96. SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
  97. ENABLE_ECHO_INPUT );
  98. if ( !ReadConsole( (HANDLE)_coninpfh,
  99. (LPVOID)result,
  100. (unsigned char)string[0],
  101. &num_read,
  102. NULL )
  103. )
  104. result = NULL;
  105. if ( result != NULL ) {
  106. /* set length of string and null terminate it */
  107. if (string[num_read] == '\r') {
  108. string[1] = (char)(num_read - 2);
  109. string[num_read] = '\0';
  110. } else if ( (num_read == (ULONG)(unsigned char)string[0]) &&
  111. (string[num_read + 1] == '\r') ) {
  112. /* special case 1 - \r\n straddles the boundary */
  113. string[1] = (char)(num_read -1);
  114. string[1 + num_read] = '\0';
  115. } else if ( (num_read == 1) && (string[2] == '\n') ) {
  116. /* special case 2 - read a single '\n'*/
  117. string[1] = string[2] = '\0';
  118. } else {
  119. string[1] = (char)num_read;
  120. string[2 + num_read] = '\0';
  121. }
  122. }
  123. SetConsoleMode( (HANDLE)_coninpfh, oldstate );
  124. }
  125. __FINALLY
  126. _munlock(_CONIO_LOCK); /* unlock the console */
  127. __END_TRY_FINALLY
  128. return result;
  129. }