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.

384 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 - 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: devmap.cpp
  6. * Content: Maps various default devices GUIDs to real guids.
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 11-24-99 pnewson Created
  12. * 12-02-99 rodtoll Added new functions for mapping device IDs and finding default
  13. * devices.
  14. * rodtoll Updated mapping function to map default devices to real GUIDs
  15. * for non-DX7.1 platforms.
  16. * 01/25/2000 pnewson Added DV_MapWaveIDToGUID
  17. * 04/14/2000 rodtoll Bug #32341 GUID_NULL and NULL map to different devices
  18. * Updated so both map to default voice device
  19. * 04/19/2000 pnewson Error handling cleanup
  20. * 04/20/2000 rodtoll Bug #32889 - Unable to run on non-admin accounts on Win2k
  21. * 06/28/2000 rodtoll Prefix Bug #38022
  22. * rodtoll Whistler Bug #128427 - Unable to run voice wizard from multimedia control panel
  23. * 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h, added STR_* and strutils.h
  24. * 01/08/2001 rodtoll WINBUG #256541 Pseudo: Loss of functionality: Voice Wizrd can't be launched.
  25. * 04/02/2001 simonpow Fixes for PREfast bugs #354859
  26. * 02/28/2002 rodtoll WINBUG #550105 - SECURITY: DPVOICE: Dead code
  27. * - Removed old device mapping functions which are no longer used.
  28. * rodtoll Fix for regression caused by TCHAR conversion (Post DirectX 8.1 work)
  29. * - Source was updated to retrieve device information from DirectSound w/Unicode
  30. * but routines which wanted the information needed Unicode.
  31. *
  32. ***************************************************************************/
  33. #include "dxvutilspch.h"
  34. #undef DPF_SUBCOMP
  35. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  36. #define REGSTR_WAVEMAPPER L"Software\\Microsoft\\Multimedia\\Sound Mapper"
  37. #define REGSTR_PLAYBACK L"Playback"
  38. #define REGSTR_RECORD L"Record"
  39. // function pointer typedefs
  40. typedef HRESULT (* PFGETDEVICEID)(LPCGUID, LPGUID);
  41. typedef HRESULT (WINAPI *DSENUM)( LPDSENUMCALLBACK lpDSEnumCallback,LPVOID lpContext );
  42. // DV_MapGUIDToWaveID
  43. //
  44. // This function maps the specified GUID to the corresponding waveIN/waveOut device
  45. // ID. For default devices it looks up the system's default device, for other devices
  46. // it uses the private interface.
  47. //
  48. #undef DPF_MODNAME
  49. #define DPF_MODNAME "DV_MapGUIDToWaveID"
  50. HRESULT DV_MapGUIDToWaveID( BOOL fCapture, const GUID &guidDevice, DWORD *pdwDevice )
  51. {
  52. LPKSPROPERTYSET pPropertySet;
  53. PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA pData;
  54. GUID tmpGUID;
  55. HRESULT hr;
  56. DPFX(DPFPREP, DVF_INFOLEVEL, "Mapping non GUID_NULL to Wave ID" );
  57. hr = DirectSoundPrivateCreate( &pPropertySet );
  58. if( FAILED( hr ) )
  59. {
  60. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to map GUID." );
  61. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to map GUID to wave. Defaulting to ID 0 hr=0x%x", hr );
  62. *pdwDevice = 0;
  63. }
  64. else
  65. {
  66. tmpGUID = guidDevice;
  67. hr = PrvGetDeviceDescription( pPropertySet, tmpGUID, &pData );
  68. if( FAILED( hr ) )
  69. {
  70. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to find GUID. Defaulting to ID 0 hr=0x%x", hr );
  71. }
  72. else
  73. {
  74. *pdwDevice = pData->WaveDeviceId;
  75. DPFX(DPFPREP, DVF_INFOLEVEL, "Mapped GUID to Wave ID %d", *pdwDevice );
  76. delete pData;
  77. }
  78. pPropertySet->Release();
  79. }
  80. return hr;
  81. }
  82. // DV_MapWaveIDToGUID
  83. //
  84. // This function maps the specified waveIN/waveOut device ID to the corresponding DirectSound
  85. // GUID.
  86. //
  87. #undef DPF_MODNAME
  88. #define DPF_MODNAME "DV_MapWaveIDToGUID"
  89. HRESULT DV_MapWaveIDToGUID( BOOL fCapture, DWORD dwDevice, GUID &guidDevice )
  90. {
  91. HRESULT hr;
  92. LPKSPROPERTYSET ppKsPropertySet;
  93. HMODULE hModule;
  94. hModule = LoadLibraryA( "dsound.dll " );
  95. if( hModule == NULL )
  96. {
  97. DPFX(DPFPREP, DVF_ERRORLEVEL, "Could not load dsound.dll" );
  98. return DVERR_GENERIC;
  99. }
  100. hr = DirectSoundPrivateCreate( &ppKsPropertySet );
  101. if( FAILED( hr ) )
  102. {
  103. FreeLibrary( hModule );
  104. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get interface for ID<-->GUID Map hr=0x%x", hr );
  105. return hr;
  106. }
  107. // CODEWORK: Remove these checks since the builds are separate now.
  108. if( DNGetOSType() == VER_PLATFORM_WIN32_NT )
  109. {
  110. WAVEINCAPSW wiCapsW;
  111. WAVEOUTCAPSW woCapsW;
  112. MMRESULT mmr;
  113. if( fCapture )
  114. {
  115. mmr = waveInGetDevCapsW( dwDevice, &wiCapsW, sizeof( WAVEINCAPSW ) );
  116. }
  117. else
  118. {
  119. mmr = waveOutGetDevCapsW( dwDevice, &woCapsW, sizeof( WAVEOUTCAPSW ) );
  120. }
  121. if( mmr != MMSYSERR_NOERROR )
  122. {
  123. DPFX(DPFPREP, DVF_ERRORLEVEL, "Specified device is invalid hr=0x%x", mmr );
  124. ppKsPropertySet->Release();
  125. FreeLibrary( hModule );
  126. return DVERR_INVALIDPARAM;
  127. }
  128. hr = PrvGetWaveDeviceMappingW( ppKsPropertySet, (fCapture) ? wiCapsW.szPname : woCapsW.szPname , fCapture, &guidDevice );
  129. }
  130. else
  131. {
  132. WAVEINCAPSA wiCapsA;
  133. WAVEOUTCAPSA woCapsA;
  134. MMRESULT mmr;
  135. if( fCapture )
  136. {
  137. mmr = waveInGetDevCapsA( dwDevice, &wiCapsA, sizeof( WAVEINCAPSA ) );
  138. }
  139. else
  140. {
  141. mmr = waveOutGetDevCapsA( dwDevice, &woCapsA, sizeof( WAVEOUTCAPSA ) );
  142. }
  143. if( mmr != MMSYSERR_NOERROR )
  144. {
  145. DPFX(DPFPREP, DVF_ERRORLEVEL, "Specified device is invalid hr=0x%x", mmr );
  146. ppKsPropertySet->Release();
  147. FreeLibrary( hModule );
  148. return DVERR_INVALIDPARAM;
  149. }
  150. hr = PrvGetWaveDeviceMapping( ppKsPropertySet, (fCapture) ? wiCapsA.szPname : woCapsA.szPname , fCapture, &guidDevice );
  151. }
  152. ppKsPropertySet->Release();
  153. if( FAILED( hr ) )
  154. {
  155. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to map ID-->GUID hr=0x%x", hr );
  156. }
  157. FreeLibrary( hModule );
  158. return hr;
  159. }
  160. #undef DPF_MODNAME
  161. #define DPF_MODNAME "DV_MapCaptureDevice"
  162. HRESULT DV_MapCaptureDevice(const GUID* lpguidCaptureDeviceIn, GUID* lpguidCaptureDeviceOut)
  163. {
  164. LONG lRet;
  165. HRESULT hr;
  166. PFGETDEVICEID pfGetDeviceID;
  167. // attempt to map any default guids to real guids...
  168. HINSTANCE hDSound = LoadLibraryA("dsound.dll");
  169. if (hDSound == NULL)
  170. {
  171. lRet = GetLastError();
  172. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get instance handle to DirectSound dll: dsound.dll");
  173. DPFX(DPFPREP, DVF_ERRORLEVEL, "LoadLibrary error code: %i", lRet);
  174. hr = DVERR_GENERIC;
  175. goto error_cleanup;
  176. }
  177. // attempt to get a pointer to the GetDeviceId function
  178. pfGetDeviceID = (PFGETDEVICEID)GetProcAddress(hDSound, "GetDeviceID");
  179. if (pfGetDeviceID == NULL)
  180. {
  181. lRet = GetLastError();
  182. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get a pointer to GetDeviceID function: GetDeviceID");
  183. DPFX(DPFPREP, DVF_WARNINGLEVEL, "GetProcAddress error code: %i", lRet);
  184. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Fatal error.");
  185. *lpguidCaptureDeviceOut = *lpguidCaptureDeviceIn;
  186. return DVERR_GENERIC;
  187. }
  188. else
  189. {
  190. // Use the GetDeviceID function to map the devices.
  191. if (lpguidCaptureDeviceIn == NULL)
  192. {
  193. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: Mapping null device pointer to DSDEVID_DefaultCapture");
  194. lpguidCaptureDeviceIn = &DSDEVID_DefaultCapture;
  195. }
  196. else if (*lpguidCaptureDeviceIn == GUID_NULL)
  197. {
  198. // GetDeviceID does not accept GUID_NULL, since it does not know
  199. // if we are asking for a capture or playback device. So we map
  200. // GUID_NULL to the system default capture device here. Then
  201. // GetDeviceID can map it to the real device.
  202. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: Mapping GUID_NULL to DSDEVID_DefaultCapture");
  203. lpguidCaptureDeviceIn = &DSDEVID_DefaultCapture;
  204. }
  205. GUID guidTemp;
  206. hr = pfGetDeviceID(lpguidCaptureDeviceIn, &guidTemp);
  207. if (FAILED(hr))
  208. {
  209. DPFX(DPFPREP, DVF_ERRORLEVEL, "GetDeviceID failed: %i", hr);
  210. if (hr == DSERR_NODRIVER)
  211. {
  212. hr = DVERR_INVALIDDEVICE;
  213. }
  214. else
  215. {
  216. hr = DVERR_GENERIC;
  217. }
  218. goto error_cleanup;
  219. }
  220. if (*lpguidCaptureDeviceIn != guidTemp)
  221. {
  222. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: GetDeviceID mapped device GUID");
  223. *lpguidCaptureDeviceOut = guidTemp;
  224. }
  225. else
  226. {
  227. *lpguidCaptureDeviceOut = *lpguidCaptureDeviceIn;
  228. }
  229. }
  230. if (!FreeLibrary(hDSound))
  231. {
  232. lRet = GetLastError();
  233. DPFX(DPFPREP, DVF_ERRORLEVEL, "FreeLibrary failed, code: %i", lRet);
  234. hr = DVERR_GENERIC;
  235. goto error_cleanup;
  236. }
  237. return DV_OK;
  238. error_cleanup:
  239. if (hDSound != NULL)
  240. {
  241. FreeLibrary(hDSound);
  242. }
  243. DPF_EXIT();
  244. return hr;
  245. }
  246. #undef DPF_MODNAME
  247. #define DPF_MODNAME "DV_MapPlaybackDevice"
  248. HRESULT DV_MapPlaybackDevice(const GUID* lpguidPlaybackDeviceIn, GUID* lpguidPlaybackDeviceOut)
  249. {
  250. LONG lRet;
  251. HRESULT hr;
  252. PFGETDEVICEID pfGetDeviceID;
  253. // attempt to map any default guids to real guids...
  254. HINSTANCE hDSound = LoadLibraryA("dsound.dll");
  255. if (hDSound == NULL)
  256. {
  257. lRet = GetLastError();
  258. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get instance handle to DirectSound dll: dsound.dll");
  259. DPFX(DPFPREP, DVF_ERRORLEVEL, "LoadLibrary error code: %i", lRet);
  260. hr = DVERR_GENERIC;
  261. goto error_cleanup;
  262. }
  263. // attempt to get a pointer to the GetDeviceId function
  264. pfGetDeviceID = (PFGETDEVICEID)GetProcAddress(hDSound, "GetDeviceID");
  265. if (pfGetDeviceID == NULL)
  266. {
  267. lRet = GetLastError();
  268. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get a pointer to GetDeviceID function: GetDeviceID");
  269. DPFX(DPFPREP, DVF_WARNINGLEVEL, "GetProcAddress error code: %i", lRet);
  270. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Fatal error!");
  271. *lpguidPlaybackDeviceOut = *lpguidPlaybackDeviceIn;
  272. return DVERR_GENERIC;
  273. }
  274. else
  275. {
  276. // Use the GetDeviceID function to map the devices.
  277. if (lpguidPlaybackDeviceIn == NULL)
  278. {
  279. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: Mapping null device pointer to DSDEVID_DefaultPlayback");
  280. lpguidPlaybackDeviceIn = &DSDEVID_DefaultPlayback;
  281. }
  282. else if (*lpguidPlaybackDeviceIn == GUID_NULL)
  283. {
  284. // GetDeviceID does not accept GUID_NULL, since it does not know
  285. // if we are asking for a capture or playback device. So we map
  286. // GUID_NULL to the system default playback device here. Then
  287. // GetDeviceID can map it to the real device.
  288. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: Mapping GUID_NULL to DSDEVID_DefaultPlayback");
  289. lpguidPlaybackDeviceIn = &DSDEVID_DefaultPlayback;
  290. }
  291. GUID guidTemp;
  292. hr = pfGetDeviceID(lpguidPlaybackDeviceIn, &guidTemp);
  293. if (FAILED(hr))
  294. {
  295. DPFX(DPFPREP, DVF_ERRORLEVEL, "GetDeviceID failed: %i", hr);
  296. if (hr == DSERR_NODRIVER)
  297. {
  298. hr = DVERR_INVALIDDEVICE;
  299. }
  300. else
  301. {
  302. hr = DVERR_GENERIC;
  303. }
  304. goto error_cleanup;
  305. }
  306. if (*lpguidPlaybackDeviceIn != guidTemp)
  307. {
  308. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: GetDeviceID mapped device GUID");
  309. *lpguidPlaybackDeviceOut = guidTemp;
  310. }
  311. else
  312. {
  313. *lpguidPlaybackDeviceOut = *lpguidPlaybackDeviceIn;
  314. }
  315. }
  316. if (!FreeLibrary(hDSound))
  317. {
  318. lRet = GetLastError();
  319. DPFX(DPFPREP, DVF_ERRORLEVEL, "FreeLibrary failed, code: %i", lRet);
  320. hr = DVERR_GENERIC;
  321. goto error_cleanup;
  322. }
  323. return DV_OK;
  324. error_cleanup:
  325. if (hDSound != NULL)
  326. {
  327. FreeLibrary(hDSound);
  328. }
  329. DPF_EXIT();
  330. return hr;
  331. }