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.

277 lines
7.7 KiB

  1. #include "nt.h"
  2. #include "ntrtl.h"
  3. #include "nturtl.h"
  4. #include "stdafx.h"
  5. #include <windows.h>
  6. #include <winsta.h>
  7. #include <rdpsndp.h>
  8. #include <rdpstrm.h>
  9. #include <stdio.h>
  10. #include <strstrea.h>
  11. extern ostrstream szMoreInfo;
  12. BOOL
  13. IsTSRedirectingAudio( VOID )
  14. {
  15. BOOL rv;
  16. static BOOL bChecked = FALSE;
  17. static BOOL RemoteConsoleAudio = 0; // Allow audio play at
  18. // the console
  19. // when console session is
  20. // remoted
  21. // is not consle ?
  22. //
  23. rv = !(USER_SHARED_DATA->ActiveConsoleId ==
  24. NtCurrentPeb()->SessionId);
  25. // console, we don't redirect
  26. if ( !rv )
  27. {
  28. szMoreInfo << "Running on the console" << endl;
  29. goto exitpt;
  30. } else
  31. szMoreInfo << "Running in a session" << endl;
  32. // check if audio is redirected on PTS
  33. //
  34. if ( !bChecked )
  35. {
  36. WINSTATIONCLIENT ClientData;
  37. ULONG Length;
  38. if (WinStationQueryInformation(SERVERNAME_CURRENT,
  39. LOGONID_CURRENT,
  40. WinStationClient,
  41. &ClientData,
  42. sizeof(ClientData),
  43. &Length ))
  44. {
  45. RemoteConsoleAudio = ClientData.fRemoteConsoleAudio;
  46. }
  47. else {
  48. szMoreInfo << "WinStatinQueryInformation failed=" <<
  49. GetLastError() << endl;
  50. RemoteConsoleAudio = 0;
  51. }
  52. }
  53. rv = !RemoteConsoleAudio;
  54. exitpt:
  55. return rv;
  56. }
  57. BOOL
  58. IsTSAudioDriverEnabled( VOID )
  59. {
  60. BOOL rv = FALSE;
  61. WINSTATIONCONFIG config;
  62. BOOLEAN fSuccess;
  63. DWORD returnedLength;
  64. fSuccess = WinStationQueryInformation(NULL, LOGONID_CURRENT,
  65. WinStationConfiguration, &config,
  66. sizeof(config), &returnedLength);
  67. if (!fSuccess)
  68. {
  69. szMoreInfo << "WinStatinQueryInformation failed=" <<
  70. GetLastError() <<endl;
  71. goto exitpt;
  72. }
  73. rv = !config.User.fDisableCam;
  74. exitpt:
  75. return rv;
  76. }
  77. BOOL
  78. DumpStreamInfo( VOID )
  79. {
  80. BOOL rv = TRUE;
  81. HANDLE hEv = NULL;
  82. HANDLE hStream = NULL;
  83. PSNDSTREAM Stream = NULL;
  84. DWORD dw;
  85. hEv = OpenEvent(EVENT_ALL_ACCESS,
  86. FALSE,
  87. TSSND_DATAREADYEVENT);
  88. if ( NULL == hEv )
  89. {
  90. szMoreInfo << "ERROR: Can't open DataReady event=" <<
  91. GetLastError() <<endl;
  92. rv = FALSE;
  93. } else {
  94. szMoreInfo << "OK: DataReady event exist" << endl;
  95. dw = WaitForSingleObject( hEv, 0 );
  96. if ( WAIT_OBJECT_0 == dw )
  97. {
  98. szMoreInfo << "WARNING: DataReady event is signaled (playing sound ?)" <<endl;
  99. SetEvent( hEv );
  100. rv = FALSE;
  101. } else
  102. szMoreInfo << "OK: DataReady event is not signaled" <<endl;
  103. CloseHandle( hEv );
  104. }
  105. hEv = OpenEvent(EVENT_ALL_ACCESS,
  106. FALSE,
  107. TSSND_STREAMISEMPTYEVENT);
  108. if ( NULL == hEv )
  109. {
  110. szMoreInfo << "ERROR: Can't open StreamEmpty event=" <<
  111. GetLastError() <<endl;
  112. rv = FALSE;
  113. } else {
  114. szMoreInfo << "OK: StreamEmpty event exist" <<endl;
  115. dw = WaitForSingleObject( hEv, 0 );
  116. if ( WAIT_OBJECT_0 == dw )
  117. {
  118. szMoreInfo << "WARNING: StreamEmpty is signaled (playing sound ?)" <<endl;
  119. rv = FALSE;
  120. } else {
  121. szMoreInfo << "OK: StreamEmpty event is not signaled" <<endl;
  122. SetEvent( hEv );
  123. }
  124. CloseHandle( hEv );
  125. }
  126. hEv = OpenEvent(EVENT_ALL_ACCESS,
  127. FALSE,
  128. TSSND_WAITTOINIT);
  129. if ( NULL == hEv )
  130. {
  131. szMoreInfo << "ERROR: Can't open WaitToInit event=" <<
  132. GetLastError() <<endl;
  133. rv = FALSE;
  134. }
  135. else {
  136. szMoreInfo << "OK: WaitToInit event exist" <<endl;
  137. dw = WaitForSingleObject( hEv, 0 );
  138. if ( WAIT_OBJECT_0 == dw )
  139. {
  140. szMoreInfo << "OK: WaitToInit is signaled" <<endl;
  141. } else {
  142. szMoreInfo << "WARNING: WaitToInit is NOT signaled" <<endl;
  143. rv = FALSE;
  144. }
  145. CloseHandle( hEv );
  146. }
  147. hEv = OpenMutex(SYNCHRONIZE,
  148. FALSE,
  149. TSSND_STREAMMUTEX);
  150. if ( NULL == hEv )
  151. {
  152. szMoreInfo << "ERROR: Can't open Stream mutex=" <<
  153. GetLastError() <<endl;
  154. rv = FALSE;
  155. } else {
  156. szMoreInfo << "OK: Stream mutex exist" <<endl;
  157. dw = WaitForSingleObject( hEv, 3000 );
  158. if ( WAIT_OBJECT_0 != dw )
  159. {
  160. szMoreInfo << "WARNING: Can't acquire Stream mutext after more than 3 seconds" <<endl;
  161. rv = FALSE;
  162. } else {
  163. szMoreInfo << "OK: Stream mutext acquired" <<endl;
  164. ReleaseMutex( hEv );
  165. }
  166. CloseHandle( hEv );
  167. }
  168. hStream = OpenFileMapping(
  169. FILE_MAP_ALL_ACCESS,
  170. FALSE,
  171. TSSND_STREAMNAME
  172. );
  173. if (NULL == hStream)
  174. {
  175. szMoreInfo << "ERROR: Can't open the stream mapping" <<
  176. GetLastError() <<endl;
  177. rv = FALSE;
  178. goto exitpt;
  179. }
  180. Stream = (PSNDSTREAM)MapViewOfFile(
  181. hStream,
  182. FILE_MAP_ALL_ACCESS,
  183. 0, 0, // offset
  184. sizeof(*Stream)
  185. );
  186. if (NULL == Stream)
  187. {
  188. szMoreInfo << "ERROR: Can't map the stream view: " <<
  189. GetLastError() <<endl;
  190. rv = FALSE;
  191. goto exitpt;
  192. }
  193. szMoreInfo << "SNDSTREAM:" <<endl;
  194. szMoreInfo << "bNewVolume: 0x" << hex << Stream->bNewVolume <<endl;
  195. szMoreInfo << "bNewPitch: 0x" << hex << Stream->bNewPitch <<endl;
  196. szMoreInfo << "dwSoundCaps: 0x" << hex << Stream->dwSoundCaps <<endl;
  197. if ( 0 != (TSSNDCAPS_ALIVE & Stream->dwSoundCaps) )
  198. szMoreInfo << "\tTSSNDCAPS_ALIVE" <<endl;
  199. if ( 0 != (TSSNDCAPS_VOLUME & Stream->dwSoundCaps) )
  200. szMoreInfo << "\tTSSNDCAPS_VOLUME" << endl;
  201. if ( 0 != (TSSNDCAPS_PITCH & Stream->dwSoundCaps) )
  202. szMoreInfo << "\tTSSNDCAPS_PITCH" <<endl;
  203. szMoreInfo << "dwVolume: 0x" << hex << Stream->dwVolume <<endl;
  204. szMoreInfo << "dwPitch: 0x" << hex << Stream->dwPitch <<endl;
  205. dw = Stream->cLastBlockQueued;
  206. szMoreInfo << "cLastBlockQueued: 0x" << hex << dw <<endl;
  207. dw = Stream->cLastBlockSent;
  208. szMoreInfo << "cLastBlockSent: 0x" << hex << dw <<endl;
  209. dw = Stream->cLastBlockConfirmed;
  210. szMoreInfo << "cLastBlockConfirmed: 0x" << hex << dw <<endl;
  211. exitpt:
  212. if ( rv )
  213. szMoreInfo << "OK: Stream seems good" <<endl;
  214. else
  215. szMoreInfo << "ERROR: Stream doesn't seem very healthy" <<endl;
  216. if ( NULL != Stream )
  217. UnmapViewOfFile( Stream );
  218. if ( NULL != hStream )
  219. CloseHandle( hStream );
  220. return rv;
  221. }
  222. BOOL
  223. IsAudioOk(
  224. VOID
  225. )
  226. {
  227. INT rv = TRUE;
  228. if ( !IsTSRedirectingAudio() )
  229. {
  230. szMoreInfo << "Audio is not redirected" <<endl;
  231. goto exitpt;
  232. }
  233. if ( !IsTSAudioDriverEnabled() )
  234. {
  235. szMoreInfo << "TS Auidio driver is disabled" <<endl;
  236. goto exitpt;
  237. }
  238. szMoreInfo << "Audio redirection is enabled. Dumping stream info" <<endl;
  239. rv = DumpStreamInfo();
  240. exitpt:
  241. return rv;
  242. }