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.

239 lines
6.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 BeepOpenFunction;
  41. BeepOpenFunction = (PWINSTATIONBEEPOPEN)
  42. GetProcAddress( hwinsta, "_WinStationBeepOpen" );
  43. if (BeepOpenFunction
  44. && ! InterlockedCompareExchangePointer((PVOID *)&pWinStationBeepOpen,
  45. BeepOpenFunction,
  46. NULL)) {
  47. // We got a function, and we were the first to
  48. // store our function to the global -- so pin the
  49. // dll containing the function.
  50. LdrAddRefDll(LDR_ADDREF_DLL_PIN, hwinsta);
  51. } else {
  52. // Either we didn't get a function, or we weren't
  53. // the first to store our function to the global
  54. // -- so we don't need our reference to the dll.
  55. FreeLibrary(hwinsta);
  56. }
  57. }
  58. }
  59. hTSBeepDevice = NULL;
  60. if ( pWinStationBeepOpen )
  61. hTSBeepDevice = (*pWinStationBeepOpen)( -1 ); //Current Session
  62. }
  63. if ( IsTerminalServer() && !IsActiveConsoleSession() ) {
  64. hBeepDevice = hTSBeepDevice;
  65. if ( hBeepDevice == NULL )
  66. Status = STATUS_ACCESS_DENIED;
  67. else
  68. Status = STATUS_SUCCESS;
  69. }
  70. else {
  71. RtlInitUnicodeString( &NameString, DD_BEEP_DEVICE_NAME_U );
  72. InitializeObjectAttributes( &ObjectAttributes,
  73. &NameString,
  74. 0,
  75. NULL,
  76. NULL
  77. );
  78. Status = NtCreateFile( &hBeepDevice,
  79. FILE_READ_DATA | FILE_WRITE_DATA,
  80. &ObjectAttributes,
  81. &IoStatus,
  82. NULL,
  83. 0,
  84. FILE_SHARE_READ | FILE_SHARE_WRITE,
  85. FILE_OPEN_IF,
  86. 0,
  87. NULL,
  88. 0L
  89. );
  90. }
  91. if (!NT_SUCCESS( Status )) {
  92. if ( IsTerminalServer() && hTSBeepDevice ) {
  93. NtClose( hTSBeepDevice );
  94. }
  95. BaseSetLastNTError( Status );
  96. return( FALSE );
  97. }
  98. //
  99. // 0,0 is a special case used to turn off a beep. Otherwise
  100. // validate the dwFreq parameter to be in range.
  101. //
  102. if ((dwFreq != 0 || dwDuration != 0) &&
  103. (dwFreq < (ULONG)0x25 || dwFreq > (ULONG)0x7FFF)
  104. ) {
  105. Status = STATUS_INVALID_PARAMETER;
  106. }
  107. else {
  108. BeepParameters.Frequency = dwFreq;
  109. BeepParameters.Duration = dwDuration;
  110. Status = NtDeviceIoControlFile( hBeepDevice,
  111. NULL,
  112. NULL,
  113. NULL,
  114. &IoStatus,
  115. IOCTL_BEEP_SET,
  116. &BeepParameters,
  117. sizeof( BeepParameters ),
  118. NULL,
  119. 0
  120. );
  121. }
  122. if ( IsTerminalServer() && IsActiveConsoleSession() && hTSBeepDevice ) {
  123. //
  124. // It's the console and since we got a beep device, it's being shadowed.
  125. // So let's do it one more time for the shadow client.
  126. //
  127. if ( NT_SUCCESS(Status) ) {
  128. NtDeviceIoControlFile( hTSBeepDevice,
  129. NULL,
  130. NULL,
  131. NULL,
  132. &IoStatus,
  133. IOCTL_BEEP_SET,
  134. &BeepParameters,
  135. sizeof( BeepParameters ),
  136. NULL,
  137. 0
  138. );
  139. }
  140. NtClose( hTSBeepDevice );
  141. }
  142. NotifySoundSentry();
  143. if (!NT_SUCCESS( Status )) {
  144. BaseSetLastNTError( Status );
  145. NtClose( hBeepDevice );
  146. return( FALSE );
  147. }
  148. else {
  149. //
  150. // Beep device is asynchronous, so sleep for duration
  151. // to allow this beep to complete.
  152. //
  153. if (dwDuration != (DWORD)-1 && (dwFreq != 0 || dwDuration != 0)) {
  154. SleepEx( dwDuration, TRUE );
  155. }
  156. NtClose( hBeepDevice );
  157. return( TRUE );
  158. }
  159. }
  160. VOID
  161. NotifySoundSentry(VOID)
  162. {
  163. #if defined(BUILD_WOW6432)
  164. ULONG VideoMode;
  165. if (!GetConsoleDisplayMode(&VideoMode)) {
  166. VideoMode = 0;
  167. }
  168. //
  169. // SoundSentry is currently only supported for Windows mode - no
  170. // full screen support.
  171. //
  172. if (VideoMode == 0) {
  173. CsrBasepSoundSentryNotification(VideoMode);
  174. }
  175. #else
  176. BASE_API_MSG m;
  177. PBASE_SOUNDSENTRY_NOTIFICATION_MSG e = &m.u.SoundSentryNotification;
  178. if (!GetConsoleDisplayMode(&e->VideoMode)) {
  179. e->VideoMode = 0;
  180. }
  181. //
  182. // SoundSentry is currently only supported for Windows mode - no
  183. // full screen support.
  184. //
  185. if (e->VideoMode == 0) {
  186. CsrClientCallServer((PCSR_API_MSG)&m,
  187. NULL,
  188. CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
  189. BasepSoundSentryNotification ),
  190. sizeof( *e )
  191. );
  192. }
  193. #endif
  194. }