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.

397 lines
11 KiB

  1. #define UNICODE
  2. #include <nt.h>
  3. #include <ntrtl.h>
  4. #include <nturtl.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <windows.h>
  8. #include <mmsystem.h>
  9. #include <strsafe.h>
  10. #include <resrc1.h>
  11. #include "internal.h"
  12. const WCHAR *InRangeLabelKey = TEXT("AppEvents\\EventLabels\\InfraredInRange");
  13. const WCHAR *OutOfRangeLabelKey = TEXT("AppEvents\\EventLabels\\InfraredOutOfRange");
  14. const WCHAR *InterruptLabelKey = TEXT("AppEvents\\EventLabels\\InfraredInterrupt");
  15. const WCHAR *WirelessLinkKey = TEXT("AppEvents\\Schemes\\Apps\\WirelessLink");
  16. const WCHAR *InRangeSoundKey = TEXT("AppEvents\\Schemes\\Apps\\WirelessLink\\InfraredInRange");
  17. const WCHAR *OutOfRangeSoundKey = TEXT("AppEvents\\Schemes\\Apps\\WirelessLink\\InfraredOutOfRange");
  18. const WCHAR *InterruptSoundKey = TEXT("AppEvents\\Schemes\\Apps\\WirelessLink\\InfraredInterrupt");
  19. const WCHAR *CurrentSoundKey = TEXT(".Current");
  20. const WCHAR *DefaultSoundKey = TEXT(".Default");
  21. const WCHAR *InRangeWav = TEXT("ir_begin.wav");
  22. const WCHAR *OutOfRangeWav = TEXT("ir_end.wav");
  23. const WCHAR *InterruptWav = TEXT("ir_inter.wav");
  24. const WCHAR *SystemInfoKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion");
  25. const WCHAR *SystemRootVal = TEXT("SystemRoot");
  26. const WCHAR *MediaPath = TEXT("\\Media\\");
  27. TCHAR gSystemRoot[64];
  28. TCHAR InRangeWavPath[128];
  29. TCHAR OutOfRangeWavPath[128];
  30. TCHAR InterruptWavPath[128];
  31. HKEY ghInRangeKey = 0;
  32. HKEY ghOutOfRangeKey = 0;
  33. HKEY ghInterruptKey = 0;
  34. BOOL
  35. InitializeSound(
  36. HKEY CurrentUserKey,
  37. HANDLE Event
  38. )
  39. {
  40. if (CurrentUserKey)
  41. {
  42. CreateRegSoundData();
  43. // Open the wave file keys so we can monitor them for changes
  44. RegOpenKeyEx(CurrentUserKey, InRangeSoundKey, 0, KEY_READ, &ghInRangeKey);
  45. RegOpenKeyEx(CurrentUserKey, OutOfRangeSoundKey, 0, KEY_READ, &ghOutOfRangeKey);
  46. RegOpenKeyEx(CurrentUserKey, InterruptSoundKey, 0, KEY_READ, &ghInterruptKey);
  47. GetRegSoundData(Event);
  48. }
  49. return TRUE;
  50. }
  51. VOID
  52. UninitializeSound(
  53. VOID
  54. )
  55. {
  56. if (ghInRangeKey)
  57. {
  58. RegCloseKey(ghInRangeKey);
  59. ghInRangeKey = 0;
  60. }
  61. if (ghInterruptKey)
  62. {
  63. RegCloseKey(ghInterruptKey);
  64. ghInterruptKey = 0;
  65. }
  66. if (ghOutOfRangeKey)
  67. {
  68. RegCloseKey(ghOutOfRangeKey);
  69. ghOutOfRangeKey = 0;
  70. }
  71. return;
  72. }
  73. VOID
  74. CreateRegSoundEventLabel(
  75. const WCHAR *LabelKey,
  76. DWORD LabelId)
  77. {
  78. TCHAR LabelStr[64];
  79. // Load the localizable string label for the sound event
  80. if (!LoadString(ghInstance, LabelId, LabelStr, sizeof(LabelStr)/sizeof(TCHAR)))
  81. {
  82. DEBUGMSG(("IRMON: LoadString failed %d\n", GetLastError()));
  83. return;
  84. }
  85. if (RegSetValue(ghCurrentUserKey, LabelKey, REG_SZ, LabelStr,
  86. lstrlen(LabelStr)))
  87. {
  88. DEBUGMSG(("IRMON: RegSetValue failed %d\n", GetLastError()));
  89. }
  90. }
  91. VOID
  92. CreateRegSoundScheme(
  93. TCHAR *SystemRoot,
  94. const WCHAR *SoundKey,
  95. const WCHAR *WavFile)
  96. {
  97. HKEY hSoundKey;
  98. DWORD Disposition;
  99. TCHAR WavPath[128];
  100. if (RegCreateKeyEx(ghCurrentUserKey,
  101. SoundKey,
  102. 0, // reserved MBZ
  103. 0, // class name
  104. REG_OPTION_NON_VOLATILE,
  105. KEY_ALL_ACCESS,
  106. 0, // security attributes
  107. &hSoundKey,
  108. &Disposition))
  109. {
  110. DEBUGMSG(("IRMON: RegCreateKey failed %d\n", GetLastError()));
  111. return;
  112. }
  113. if (Disposition == REG_CREATED_NEW_KEY)
  114. {
  115. if (RegSetValue(hSoundKey, CurrentSoundKey, REG_SZ, WavFile,
  116. lstrlen(WavFile)))
  117. {
  118. DEBUGMSG(("IRMON: RegSetValue failed %d\n", GetLastError()));
  119. }
  120. StringCbCopy(WavPath, sizeof(WavPath), SystemRoot);
  121. StringCbCat(WavPath, sizeof(WavPath), MediaPath);
  122. StringCbCat(WavPath, sizeof(WavPath), WavFile);
  123. if (RegSetValue(hSoundKey, DefaultSoundKey, REG_SZ, WavPath,
  124. lstrlen(WavPath)))
  125. {
  126. DEBUGMSG(("IRMON: RegSetValue failed %d\n", GetLastError()));
  127. }
  128. }
  129. RegCloseKey(hSoundKey);
  130. }
  131. VOID
  132. CreateRegSoundData()
  133. {
  134. DWORD ValType;
  135. HKEY hKey, hUserKey;
  136. LONG Len;
  137. TCHAR WirelessLinkStr[64];
  138. // Get the system root so we can add default registry values
  139. // i.e. Schemes\WirelessLink\InfraredInRange\.Default = "C:\winnt\media\irin.wav"
  140. // ^^^^^^^^
  141. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SystemInfoKey, 0, KEY_READ, &hKey))
  142. {
  143. DEBUGMSG(("IRMON: RegOpenKey2 failed %d\n", GetLastError()));
  144. return;
  145. }
  146. Len = sizeof(gSystemRoot);
  147. if (RegQueryValueEx(hKey, SystemRootVal, 0, &ValType,
  148. (LPBYTE) gSystemRoot, &Len))
  149. {
  150. DEBUGMSG(("IRMON: RegQueryValue failed %d\n", GetLastError()));
  151. return;
  152. }
  153. RegCloseKey(hKey);
  154. // Create the sound EventLabels and schemes if they don't exist
  155. CreateRegSoundEventLabel(InRangeLabelKey, IDS_INRANGE_LABEL);
  156. CreateRegSoundEventLabel(OutOfRangeLabelKey, IDS_OUTOFRANGE_LABEL);
  157. CreateRegSoundEventLabel(InterruptLabelKey, IDS_INTERRUPT_LABEL);
  158. if (!LoadString(ghInstance, IDS_WIRELESSLINK, WirelessLinkStr, sizeof(WirelessLinkStr)/sizeof(TCHAR)))
  159. {
  160. DEBUGMSG(("IRMON: LoadString failed %d\n", GetLastError()));
  161. return;
  162. }
  163. if (RegSetValue(ghCurrentUserKey, WirelessLinkKey, REG_SZ, WirelessLinkStr,
  164. lstrlen(WirelessLinkStr)))
  165. {
  166. DEBUGMSG(("IRMON: RegSetValue failed %d\n", GetLastError()));
  167. }
  168. CreateRegSoundScheme(gSystemRoot, InRangeSoundKey, InRangeWav);
  169. CreateRegSoundScheme(gSystemRoot, OutOfRangeSoundKey, OutOfRangeWav);
  170. CreateRegSoundScheme(gSystemRoot, InterruptSoundKey, InterruptWav);
  171. }
  172. VOID
  173. GetRegSoundWavPath(
  174. const WCHAR *SoundKey,
  175. TCHAR *SoundWavPath,
  176. LONG cbPathLen)
  177. {
  178. TCHAR CurrRegPath[128];
  179. DWORD ValType;
  180. HKEY hSoundKey;
  181. int i;
  182. BOOLEAN FullPath = FALSE;
  183. LONG cbPathLenSave = cbPathLen;
  184. StringCbCopy(CurrRegPath, sizeof(CurrRegPath), SoundKey);
  185. StringCbCat(CurrRegPath, sizeof(CurrRegPath), TEXT("\\"));
  186. StringCbCat(CurrRegPath, sizeof(CurrRegPath), CurrentSoundKey);
  187. if (RegOpenKeyEx(ghCurrentUserKey, CurrRegPath, 0, KEY_READ, &hSoundKey))
  188. {
  189. DEBUGMSG(("IRMON: RegOpenKey3 failed %d\n", GetLastError()));
  190. return;
  191. }
  192. if (RegQueryValueEx(hSoundKey, NULL, 0, &ValType,
  193. (LPBYTE) SoundWavPath, &cbPathLenSave))
  194. {
  195. DEBUGMSG(("IRMON: RegQueryValue failed %d\n", GetLastError()));
  196. RegCloseKey(hSoundKey);
  197. return;
  198. }
  199. // the PlaySound API does not look in \winnt\media for
  200. // wav files when a filename is specified, so if this is not a full
  201. // pathname then we'll need to add "c:\winnt\media" to the WavPath.
  202. // I'm counting on a path without '\' as an indication that it is relative.
  203. for (i = 0; i < lstrlen(SoundWavPath); i++)
  204. {
  205. if (SoundWavPath[i] == TEXT('\\'))
  206. {
  207. FullPath = TRUE;
  208. break;
  209. }
  210. }
  211. if (!FullPath && lstrlen(SoundWavPath) != 0)
  212. {
  213. TCHAR TempStr[64];
  214. StringCbCopy(TempStr, sizeof(TempStr), SoundWavPath);
  215. StringCbCopy(SoundWavPath, cbPathLen,gSystemRoot);
  216. StringCbCat(SoundWavPath, cbPathLen, MediaPath);
  217. StringCbCat(SoundWavPath, cbPathLen, TempStr);
  218. }
  219. RegCloseKey(hSoundKey);
  220. }
  221. VOID
  222. GetRegSoundData(
  223. HANDLE Event
  224. )
  225. {
  226. GetRegSoundWavPath(InRangeSoundKey, InRangeWavPath, sizeof(InRangeWavPath));
  227. // DEBUGMSG(("IRMON: In range wav: %ws\n", InRangeWavPath));
  228. GetRegSoundWavPath(OutOfRangeSoundKey, OutOfRangeWavPath, sizeof(OutOfRangeWavPath));
  229. // DEBUGMSG(("IRMON: Out of range wav: %ws\n", OutOfRangeWavPath));
  230. GetRegSoundWavPath(InterruptSoundKey, InterruptWavPath, sizeof(InterruptWavPath));
  231. // DEBUGMSG(("IRMON: Interrupt wav: %ws\n", InterruptWavPath));
  232. RegNotifyChangeKeyValue(ghInRangeKey,
  233. TRUE, // watch child keys
  234. REG_NOTIFY_CHANGE_LAST_SET,
  235. Event,
  236. TRUE); // async
  237. RegNotifyChangeKeyValue(ghOutOfRangeKey,
  238. TRUE, // watch child keys
  239. REG_NOTIFY_CHANGE_LAST_SET,
  240. Event,
  241. TRUE); // async
  242. RegNotifyChangeKeyValue(ghInterruptKey,
  243. TRUE, // watch child keys
  244. REG_NOTIFY_CHANGE_LAST_SET,
  245. Event,
  246. TRUE); // async
  247. }
  248. VOID
  249. PlayIrSound(IRSOUND_EVENT SoundEvent)
  250. {
  251. int Beep1, Beep2, Beep3;
  252. BOOL SoundPlayed = FALSE;
  253. LPWSTR WaveSound;
  254. DWORD Flags = 0;
  255. switch (SoundEvent)
  256. {
  257. case INRANGE_SOUND:
  258. WaveSound = InRangeWavPath;
  259. Beep1 = 200;
  260. Beep2 = 250;
  261. Beep3 = 300;
  262. break;
  263. case OUTOFRANGE_SOUND:
  264. WaveSound = OutOfRangeWavPath;
  265. Beep1 = 300;
  266. Beep2 = 250;
  267. Beep3 = 200;
  268. break;
  269. case INTERRUPTED_SOUND:
  270. WaveSound = InterruptWavPath;
  271. Flags = SND_LOOP;
  272. Beep1 = 500;
  273. Beep2 = 350;
  274. Beep3 = 500;
  275. break;
  276. case END_INTERRUPTED_SOUND:
  277. WaveSound = NULL;
  278. SoundPlayed = TRUE;
  279. break;
  280. }
  281. if (SoundEvent != END_INTERRUPTED_SOUND && lstrlen(WaveSound) == 0) {
  282. //
  283. // the path of sound file is a null string, can't play anything
  284. //
  285. SoundPlayed = TRUE;
  286. } else if (waveOutGetNumDevs() > 0) {
  287. //
  288. // the functions are availible and there is at least on wave device
  289. //
  290. SoundPlayed = PlaySound(
  291. WaveSound,
  292. (HMODULE) NULL,
  293. SND_FILENAME | SND_ASYNC | Flags
  294. );
  295. if (WaveSound == NULL) {
  296. //
  297. // we just wanted to stop the wave, set this to true so it will not try to beep
  298. //
  299. SoundPlayed=TRUE;
  300. }
  301. }
  302. if (!SoundPlayed) {
  303. //
  304. // could not play a wave, just uses beeps
  305. //
  306. DEBUGMSG(("Not Wave enabled\n"));
  307. Beep(Beep1, 100);
  308. Beep(Beep2, 100);
  309. Beep(Beep3, 100);
  310. }
  311. }