Source code of Windows XP (NT5)
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.

222 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. beep.c
  5. Abstract:
  6. This module contains the Win32 Beep APIs
  7. Author:
  8. Steve Wood (stevewo) 5-Oct-1991
  9. Revision History:
  10. --*/
  11. #include "basedll.h"
  12. #pragma hdrstop
  13. #include <ntddbeep.h>
  14. #include "conapi.h"
  15. #define IsActiveConsoleSession() (BOOLEAN)(USER_SHARED_DATA->ActiveConsoleId == NtCurrentPeb()->SessionId)
  16. /*
  17. * Forward declaration
  18. */
  19. VOID NotifySoundSentry(VOID);
  20. BOOL
  21. APIENTRY
  22. Beep(
  23. DWORD dwFreq,
  24. DWORD dwDuration
  25. )
  26. {
  27. OBJECT_ATTRIBUTES ObjectAttributes;
  28. UNICODE_STRING NameString;
  29. NTSTATUS Status;
  30. IO_STATUS_BLOCK IoStatus;
  31. BEEP_SET_PARAMETERS BeepParameters;
  32. HANDLE hBeepDevice, hTSBeepDevice;
  33. if ( IsTerminalServer() ) {
  34. if ( !pWinStationBeepOpen ) {
  35. HMODULE hwinsta = NULL;
  36. /*
  37. * Get handle to winsta.dll
  38. */
  39. if ( (hwinsta = LoadLibraryW( L"WINSTA" )) != NULL ) {
  40. pWinStationBeepOpen = (PWINSTATIONBEEPOPEN)
  41. GetProcAddress( hwinsta, "_WinStationBeepOpen" );
  42. }
  43. }
  44. hTSBeepDevice = NULL;
  45. if ( pWinStationBeepOpen )
  46. hTSBeepDevice = (*pWinStationBeepOpen)( -1 ); //Current Session
  47. }
  48. if ( IsTerminalServer() && !IsActiveConsoleSession() ) {
  49. hBeepDevice = hTSBeepDevice;
  50. if ( hBeepDevice == NULL )
  51. Status = STATUS_ACCESS_DENIED;
  52. else
  53. Status = STATUS_SUCCESS;
  54. }
  55. else {
  56. RtlInitUnicodeString( &NameString, DD_BEEP_DEVICE_NAME_U );
  57. InitializeObjectAttributes( &ObjectAttributes,
  58. &NameString,
  59. 0,
  60. NULL,
  61. NULL
  62. );
  63. Status = NtCreateFile( &hBeepDevice,
  64. FILE_READ_DATA | FILE_WRITE_DATA,
  65. &ObjectAttributes,
  66. &IoStatus,
  67. NULL,
  68. 0,
  69. FILE_SHARE_READ | FILE_SHARE_WRITE,
  70. FILE_OPEN_IF,
  71. 0,
  72. NULL,
  73. 0L
  74. );
  75. }
  76. if (!NT_SUCCESS( Status )) {
  77. if ( IsTerminalServer() && hTSBeepDevice ) {
  78. NtClose( hTSBeepDevice );
  79. }
  80. BaseSetLastNTError( Status );
  81. return( FALSE );
  82. }
  83. //
  84. // 0,0 is a special case used to turn off a beep. Otherwise
  85. // validate the dwFreq parameter to be in range.
  86. //
  87. if ((dwFreq != 0 || dwDuration != 0) &&
  88. (dwFreq < (ULONG)0x25 || dwFreq > (ULONG)0x7FFF)
  89. ) {
  90. Status = STATUS_INVALID_PARAMETER;
  91. }
  92. else {
  93. BeepParameters.Frequency = dwFreq;
  94. BeepParameters.Duration = dwDuration;
  95. Status = NtDeviceIoControlFile( hBeepDevice,
  96. NULL,
  97. NULL,
  98. NULL,
  99. &IoStatus,
  100. IOCTL_BEEP_SET,
  101. &BeepParameters,
  102. sizeof( BeepParameters ),
  103. NULL,
  104. 0
  105. );
  106. }
  107. if ( IsTerminalServer() && IsActiveConsoleSession() && hTSBeepDevice ) {
  108. //
  109. // It's the console and since we got a beep device, it's being shadowed.
  110. // So let's do it one more time for the shadow client.
  111. //
  112. if ( NT_SUCCESS(Status) ) {
  113. NtDeviceIoControlFile( hTSBeepDevice,
  114. NULL,
  115. NULL,
  116. NULL,
  117. &IoStatus,
  118. IOCTL_BEEP_SET,
  119. &BeepParameters,
  120. sizeof( BeepParameters ),
  121. NULL,
  122. 0
  123. );
  124. }
  125. NtClose( hTSBeepDevice );
  126. }
  127. NotifySoundSentry();
  128. if (!NT_SUCCESS( Status )) {
  129. BaseSetLastNTError( Status );
  130. NtClose( hBeepDevice );
  131. return( FALSE );
  132. }
  133. else {
  134. //
  135. // Beep device is asynchronous, so sleep for duration
  136. // to allow this beep to complete.
  137. //
  138. if (dwDuration != (DWORD)-1 && (dwFreq != 0 || dwDuration != 0)) {
  139. SleepEx( dwDuration, TRUE );
  140. }
  141. NtClose( hBeepDevice );
  142. return( TRUE );
  143. }
  144. }
  145. VOID
  146. NotifySoundSentry(VOID)
  147. {
  148. #if defined(BUILD_WOW6432)
  149. ULONG VideoMode;
  150. if (!GetConsoleDisplayMode(&VideoMode)) {
  151. VideoMode = 0;
  152. }
  153. //
  154. // SoundSentry is currently only supported for Windows mode - no
  155. // full screen support.
  156. //
  157. if (VideoMode == 0) {
  158. CsrBasepSoundSentryNotification(VideoMode);
  159. }
  160. #else
  161. BASE_API_MSG m;
  162. PBASE_SOUNDSENTRY_NOTIFICATION_MSG e = &m.u.SoundSentryNotification;
  163. if (!GetConsoleDisplayMode(&e->VideoMode)) {
  164. e->VideoMode = 0;
  165. }
  166. //
  167. // SoundSentry is currently only supported for Windows mode - no
  168. // full screen support.
  169. //
  170. if (e->VideoMode == 0) {
  171. CsrClientCallServer((PCSR_API_MSG)&m,
  172. NULL,
  173. CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
  174. BasepSoundSentryNotification ),
  175. sizeof( *e )
  176. );
  177. }
  178. #endif
  179. }