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.

1214 lines
39 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dvshared.cpp
  6. * Content: Utility functions for DirectXVoice structures.
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/06/99 rodtoll Created It
  12. * 07/26/99 rodtoll Added support for DirectXVoiceNotify interface
  13. * 07/30/99 rodtoll Updated to remove references to removed wave members
  14. * of sounddeviceconfig
  15. * 08/03/99 rodtoll Updated to use new IDirectXVoiceNotify interface
  16. * transport instead of old test transport
  17. * 08/04/99 rodtoll Added new validation functions
  18. * 08/10/99 rodtoll Removed TODO pragmas
  19. * 08/25/99 rodtoll General Cleanup/Modifications to support new
  20. * compression sub-system.
  21. * Added new DUMP functions
  22. * Moved several compression functions to dvcdb
  23. * 09/03/99 rodtoll Bug #102159 - Parameter Validations on Initialize
  24. * 09/08/99 rodtoll Updated for new compression structure in dump func
  25. * 09/10/99 rodtoll Added DV_ValidSessionDesc function
  26. * rodtoll Various param validation code added
  27. * 09/10/99 rodtoll Complete object validation funcs added
  28. * 09/13/99 rodtoll Updated DV_ValidSoundDeviceConfig to reflect new struct
  29. * rodtoll Updated DV_DUMP_SoundDeviceConfig for new struct
  30. * 09/14/99 rodtoll Added new Init params and DV_ValidMessageArray
  31. * 09/20/99 rodtoll Added checks for memory allocation failures
  32. * rodtoll Addes stricter checks on notify masks & used new notifyperiodmax
  33. * 09/29/99 rodtoll Updated to allow specification of new voice suppression info
  34. * 10/04/99 rodtoll Updated to allow initialize to take an LPUNKNOWN instead of LPVOID
  35. * 10/05/99 rodtoll Additional comments
  36. * 10/07/99 rodtoll Updated to handle Unicode Strings
  37. * 10/08/99 rodtoll Fixed for passing NULL in the DirectSound Pointers
  38. * 10/15/99 rodtoll Removed check for GUID_NULL since default devices are now mapped there
  39. * 10/18/99 rodtoll Fix: Calling Initialize twice passes
  40. * 10/20/99 rodtoll Fix: Bug #114116 Initialize called with invalid message IDs results in crash
  41. * rodtoll Fix: Bug #114218 Parameter validation for initialize
  42. * 10/25/99 rodtoll Fix: Bug #114682 Session Desc maint functions fail
  43. * 10/27/99 pnewson Fix: Bug #113935 - Saved AGC values should be device specific
  44. * 10/28/99 pnewson Bug #114176 updated DVSOUNDDEVICECONFIG struct
  45. * 11/10/99 rodtoll Adding waveIN/waveOut caps and echo suppression
  46. * 11/17/99 rodtoll Fix: Bug #115538 - dwSize members of > sizeof struct were accepted
  47. * rodtoll Fix: Bug #115827 - Calling SetNotifyMask w/no callback should fail
  48. * rodtoll Fix: Bug #116440 - Remove unused flags
  49. * 11/20/99 rodtoll Fixed code which allows new force flags to recognize millenium debug flags
  50. * 11/23/99 rodtoll Removed unrequired code.
  51. * rodtoll Change error for insufficient buffer size to an info level (since expected in many cases)
  52. * rodtoll Fixed ref count problem when calling Iniitalize > 1 times (first time succesful)
  53. * 12/08/99 rodtoll Fix: Bug #121054 - Added support for new flags supporting capture focus
  54. * 12/16/99 rodtoll Updated to remove voice suppression and accept new session flags
  55. * 01/14/2000 rodtoll Added DV_ValidTargetList function
  56. * rodtoll Fixed Dump function for DVSOUNDDEVICECONFIG
  57. * rodtoll Updated DV_ValidMessageArray to remove old messages
  58. * 01/21/2000 pnewson Support DVSOUNDCONFIG_TESTMODE and DVRECORDVOLUME_LAST
  59. * 01/24/2000 pnewson Added check for valid hwnd DV_ValidSoundDeviceConfig
  60. * 01/27/2000 rodtoll Bug #129934 - Update Create3DSoundBuffer to take DSBUFFERDESC
  61. * Updated param validations to check new params
  62. * 01/28/2000 rodtoll Bug #130480 - Updated so Host Migration is no longer valid ID for servers
  63. * 02/08/2000 rodtoll Bug #131496 - Selecting DVTHRESHOLD_DEFAULT results in voice
  64. * never being detected
  65. * 03/29/2000 rodtoll Added support for new flag: DVSOUNDCONFIG_SETCONVERSIONQUALITY
  66. * 06/21/2000 rodtoll Fixed a memory leak if you Connect, Disconnect then Re-Connect.
  67. * rodtoll Bug #35767 We must implement ability to allow DSound effects processing in Voice buffers.
  68. * 07/22/2000 rodtoll Bug #40284 - Initialize() and SetNotifyMask() should return invalidparam instead of invalidpointer
  69. * 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h, added STR_* and strutils.h
  70. * 08/31/2000 rodtoll Bug #43804 - DVOICE: dwSensitivity structure member is confusing - should be dwThreshold
  71. * 09/14/2000 rodtoll Bug #45001 - DVOICE: AV if client has targetted > 10 players
  72. * 04/02/2001 simonpow Bug #354859 Fixes for PREfast (unecessary variable declarations in
  73. * DV_ValidBufferSettings method)
  74. *
  75. ***************************************************************************/
  76. #include "dxvoicepch.h"
  77. // Useful macros for checking record/suppression volumes
  78. #define DV_ValidRecordVolume( x ) DV_ValidPlaybackVolume( x )
  79. #define DV_ValidSuppressionVolume( x ) DV_ValidPlaybackVolume( x )
  80. // VTABLES for all of the interfaces supported by the object
  81. extern LPVOID dvcInterface[];
  82. extern LPVOID dvsInterface[];
  83. extern LPVOID dvtInterface[];
  84. extern LPVOID dvServerNotifyInterface[];
  85. extern LPVOID dvClientNotifyInterface[];
  86. #undef DPF_MODNAME
  87. #define DPF_MODNAME "DV_ValidTargetList"
  88. HRESULT DV_ValidTargetList( PDVID pdvidTargets, DWORD dwNumTargets )
  89. {
  90. if( (pdvidTargets != NULL && dwNumTargets == 0) ||
  91. (pdvidTargets == NULL && dwNumTargets > 0 ) )
  92. {
  93. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid params" );
  94. return DVERR_INVALIDPARAM;
  95. }
  96. if( dwNumTargets == 0 )
  97. return DV_OK;
  98. if( pdvidTargets != NULL &&
  99. !DNVALID_READPTR( pdvidTargets, dwNumTargets*sizeof( DVID ) ) )
  100. {
  101. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid array of player targets" );
  102. return DVERR_INVALIDPOINTER;
  103. }
  104. // Search for duplicates in the targets
  105. for( DWORD dwIndex = 0; dwIndex < dwNumTargets; dwIndex++ )
  106. {
  107. if( pdvidTargets[dwIndex] == DVID_ALLPLAYERS && dwNumTargets > 1 )
  108. {
  109. DPFX(DPFPREP, DVF_ERRORLEVEL, "Cannot specify allplayers (or noplayers) in addition to other ids" );
  110. return DVERR_INVALIDPARAM;
  111. }
  112. for( DWORD dwInnerIndex = dwIndex+1; dwInnerIndex < dwNumTargets; dwInnerIndex++ )
  113. {
  114. if( pdvidTargets[dwInnerIndex] == pdvidTargets[dwIndex] )
  115. {
  116. DPFX(DPFPREP, DVF_ERRORLEVEL, "Duplicate found in target list" );
  117. return DVERR_INVALIDPARAM;
  118. }
  119. }
  120. }
  121. // Set max # of targets to ensure we don't exceed target buffer size
  122. if( dwNumTargets > DV_MAX_TARGETS )
  123. {
  124. DPFX(DPFPREP, DVF_ERRORLEVEL, "You can only have a maximum of %d targets", DV_MAX_TARGETS );
  125. return DVERR_NOTALLOWED;
  126. }
  127. return DV_OK;
  128. }
  129. #undef DPF_MODNAME
  130. #define DPF_MODNAME "DV_ValidBufferSettings"
  131. // DV_ValidBufferSettings
  132. //
  133. // This function is used to check to ensure that the buffer specified is in a valid
  134. // format to be used by voice.
  135. //
  136. HRESULT DV_ValidBufferSettings( LPDIRECTSOUNDBUFFER lpdsBuffer, DWORD dwPriority, DWORD dwFlags, LPWAVEFORMATEX pwfxPlayFormat )
  137. {
  138. // If buffer was specified make sure it's valid
  139. if( lpdsBuffer != NULL &&
  140. !DNVALID_READPTR( lpdsBuffer, sizeof( IDirectSoundBuffer * ) ) )
  141. {
  142. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer" );
  143. return DVERR_INVALIDPOINTER;
  144. }
  145. if( lpdsBuffer )
  146. {
  147. DWORD dwLength = 0;
  148. HRESULT hr = DS_OK;
  149. DWORD dwSize1 = 0, dwSize2 = 0;
  150. DWORD dwBufferSize1=0, dwBufferSize2=0;
  151. PVOID pvBuffer1 = NULL, pvBuffer2 = NULL;
  152. LPWAVEFORMATEX pwfxFormat = NULL;
  153. DWORD dwFormatSize = 0;
  154. DSBCAPS dsbCaps;
  155. DWORD dwStatus = 0;
  156. // Flip on a try-except block to ensure calls into dsound don't crash on us.
  157. _try
  158. {
  159. // Get the format of the buffer -- make sure it matches our format
  160. hr = lpdsBuffer->GetFormat( pwfxFormat, 0, &dwFormatSize );
  161. if( hr != DSERR_INVALIDPARAM && hr != DS_OK )
  162. {
  163. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error getting format of ds buffer hr=0x%x", hr );
  164. return DVERR_INVALIDBUFFER;
  165. }
  166. pwfxFormat = (LPWAVEFORMATEX) new BYTE[dwFormatSize];
  167. if( !pwfxFormat )
  168. {
  169. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error allocating memory" );
  170. return DVERR_INVALIDBUFFER;
  171. }
  172. hr = lpdsBuffer->GetFormat( pwfxFormat, dwFormatSize, &dwFormatSize );
  173. if( FAILED( hr ) )
  174. {
  175. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error getting format of buffer hr=0x%x", hr );
  176. hr = DVERR_INVALIDBUFFER;
  177. goto VALID_EXIT;
  178. }
  179. // Make sure the format matches
  180. if( memcmp( pwfxPlayFormat, pwfxFormat, sizeof( WAVEFORMATEX ) ) != 0 )
  181. {
  182. DPFX(DPFPREP, DVF_ERRORLEVEL, "DS buffer is not of the correct format hr=0x%x", hr );
  183. hr = DVERR_INVALIDBUFFER;
  184. goto VALID_EXIT;
  185. }
  186. memset( &dsbCaps, 0x00, sizeof( DSBCAPS ) );
  187. dsbCaps.dwSize = sizeof( DSBCAPS );
  188. hr = lpdsBuffer->GetCaps( &dsbCaps );
  189. if( FAILED( hr ) )
  190. {
  191. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get buffer caps hr=0x%x", hr );
  192. hr = DVERR_INVALIDBUFFER;
  193. goto VALID_EXIT;
  194. }
  195. if( !(dsbCaps.dwFlags & DSBCAPS_CTRL3D) )
  196. {
  197. DPFX(DPFPREP, DVF_ERRORLEVEL, "You must specify 3D flags for buffers hr=0x%x", hr );
  198. hr = DVERR_INVALIDBUFFER;
  199. goto VALID_EXIT;
  200. }
  201. if( !(dsbCaps.dwFlags & DSBCAPS_GETCURRENTPOSITION2) )
  202. {
  203. DPFX(DPFPREP, DVF_ERRORLEVEL, "You must specify ctrlposnotify for buffers hr=0x%x", hr );
  204. hr = DVERR_INVALIDBUFFER;
  205. goto VALID_EXIT;
  206. }
  207. if( dsbCaps.dwFlags & DSBCAPS_PRIMARYBUFFER )
  208. {
  209. DPFX(DPFPREP, DVF_ERRORLEVEL, "You cannot pass in a primary buffer" );
  210. hr = DVERR_INVALIDBUFFER;
  211. goto VALID_EXIT;
  212. }
  213. if( dsbCaps.dwBufferBytes < pwfxPlayFormat->nAvgBytesPerSec )
  214. {
  215. DPFX(DPFPREP, DVF_ERRORLEVEL, "Buffer size is less then one second worth of audio" );
  216. hr = DVERR_INVALIDBUFFER;
  217. goto VALID_EXIT;
  218. }
  219. hr = lpdsBuffer->GetStatus( &dwStatus );
  220. if( FAILED( hr ) )
  221. {
  222. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error getting buffer status hr=0x%x", hr );
  223. hr = DVERR_INVALIDBUFFER;
  224. goto VALID_EXIT;
  225. }
  226. if( dwStatus & DSBSTATUS_PLAYING )
  227. {
  228. DPFX(DPFPREP, DVF_ERRORLEVEL, "Buffer must be stopped" );
  229. hr = DVERR_INVALIDBUFFER;
  230. goto VALID_EXIT;
  231. }
  232. // Check to see if the buffer is locked already
  233. hr = lpdsBuffer->Lock( 0, 0, &pvBuffer1, &dwBufferSize1, &pvBuffer2, &dwBufferSize2, DSBLOCK_ENTIREBUFFER );
  234. if( FAILED( hr ) )
  235. {
  236. DPFX(DPFPREP, DVF_ERRORLEVEL, "Could not lock the buffer, likely is already locked hr=0x%x", hr );
  237. hr = DVERR_LOCKEDBUFFER;
  238. goto VALID_EXIT;
  239. }
  240. lpdsBuffer->Unlock( pvBuffer1, dwBufferSize1, pvBuffer2, dwBufferSize2 );
  241. VALID_EXIT:
  242. if( pwfxFormat )
  243. delete[] pwfxFormat;
  244. return hr;
  245. }
  246. _except( EXCEPTION_EXECUTE_HANDLER )
  247. {
  248. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error during validation of directsound buffer" );
  249. if( pwfxFormat )
  250. delete[] pwfxFormat;
  251. return DVERR_INVALIDPOINTER;
  252. }
  253. }
  254. return DV_OK;
  255. }
  256. // DV_ValidPlaybackVolume
  257. //
  258. // Checks the specified playback volume to ensure it's valid
  259. BOOL DV_ValidPlaybackVolume( LONG lPlaybackVolume )
  260. {
  261. if( (lPlaybackVolume >= DSBVOLUME_MIN) && (lPlaybackVolume <= DSBVOLUME_MAX) )
  262. {
  263. return TRUE;
  264. }
  265. else
  266. {
  267. return FALSE;
  268. }
  269. }
  270. // DV_ValidNotifyPeriod
  271. //
  272. // Checks the specified notification period to ensure it's valid
  273. //
  274. BOOL DV_ValidNotifyPeriod( DWORD dwNotifyPeriod )
  275. {
  276. if( (dwNotifyPeriod == 0) || (dwNotifyPeriod >= DVNOTIFYPERIOD_MINPERIOD) )
  277. {
  278. return TRUE;
  279. }
  280. else
  281. {
  282. return FALSE;
  283. }
  284. }
  285. #undef DPF_MODNAME
  286. #define DPF_MODNAME "DV_ValidSoundDeviceConfig"
  287. // DV_ValidSoundDeviceConfig
  288. //
  289. // Checks the specified sound device configuration to ensure that it's
  290. // valid.
  291. //
  292. HRESULT DV_ValidSoundDeviceConfig( LPDVSOUNDDEVICECONFIG lpSoundDeviceConfig, LPWAVEFORMATEX pwfxPlayFormat )
  293. {
  294. HRESULT hr;
  295. if( lpSoundDeviceConfig == NULL )
  296. {
  297. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer" );
  298. return DVERR_INVALIDPOINTER;
  299. }
  300. if( !DNVALID_READPTR( lpSoundDeviceConfig, sizeof(DVSOUNDDEVICECONFIG) ) )
  301. {
  302. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid read pointer" );
  303. return DVERR_INVALIDPOINTER;
  304. }
  305. if( lpSoundDeviceConfig->dwSize != sizeof( DVSOUNDDEVICECONFIG ) )
  306. {
  307. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid size" );
  308. return DVERR_INVALIDPARAM;
  309. }
  310. if( (lpSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_NOFOCUS) &&
  311. (lpSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_STRICTFOCUS) )
  312. {
  313. DPFX(DPFPREP, DVF_ERRORLEVEL, "Cannot specify no focus and strictfocus" );
  314. return DVERR_INVALIDPARAM;
  315. }
  316. if( lpSoundDeviceConfig->dwFlags &
  317. ~(DVSOUNDCONFIG_AUTOSELECT | DVSOUNDCONFIG_HALFDUPLEX |
  318. DVSOUNDCONFIG_STRICTFOCUS | DVSOUNDCONFIG_NOFOCUS |
  319. DVSOUNDCONFIG_TESTMODE | DVSOUNDCONFIG_NORMALMODE |
  320. DVSOUNDCONFIG_SETCONVERSIONQUALITY |
  321. #if defined(_DEBUG) || defined(DEBUG) || defined(DBG)
  322. DVSOUNDCONFIG_FORCEWAVEOUT | DVSOUNDCONFIG_FORCEWAVEIN |
  323. #endif
  324. DVSOUNDCONFIG_ALLOWWAVEOUT | DVSOUNDCONFIG_ALLOWWAVEIN ) )
  325. {
  326. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid flags" );
  327. return DVERR_INVALIDFLAGS;
  328. }
  329. if( (lpSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_NORMALMODE) && lpSoundDeviceConfig->lpdsPlaybackDevice )
  330. {
  331. DPFX(DPFPREP, DVF_ERRORLEVEL, "Cannot specify normal mode AND specify dsound object" );
  332. return DVERR_INVALIDPARAM;
  333. }
  334. if( lpSoundDeviceConfig->lpdsPlaybackDevice != NULL)
  335. {
  336. if (!DNVALID_READPTR(lpSoundDeviceConfig->lpdsPlaybackDevice, sizeof(IDirectSound)))
  337. {
  338. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid playback device object" );
  339. return DVERR_INVALIDPARAM;
  340. }
  341. }
  342. if( lpSoundDeviceConfig->lpdsCaptureDevice != NULL)
  343. {
  344. if (!DNVALID_READPTR(lpSoundDeviceConfig->lpdsCaptureDevice, sizeof(IDirectSoundCapture)))
  345. {
  346. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid capture device object" );
  347. return DVERR_INVALIDPARAM;
  348. }
  349. }
  350. if (!IsWindow(lpSoundDeviceConfig->hwndAppWindow))
  351. {
  352. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid window handle");
  353. return DVERR_INVALIDPARAM;
  354. }
  355. hr = DV_ValidBufferSettings( lpSoundDeviceConfig->lpdsMainBuffer,
  356. lpSoundDeviceConfig->dwMainBufferPriority,
  357. lpSoundDeviceConfig->dwMainBufferFlags, pwfxPlayFormat );
  358. if( FAILED( hr ) )
  359. {
  360. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid buffer or buffer settings specified in sound config hr=0x%x", hr );
  361. return hr;
  362. }
  363. return DV_OK;
  364. }
  365. #undef DPF_MODNAME
  366. #define DPF_MODNAME "DV_ValidClientConfig"
  367. // DV_ValidClientConfig
  368. //
  369. // Checks the valid client configuration structure to ensure it's valid
  370. //
  371. HRESULT DV_ValidClientConfig( LPDVCLIENTCONFIG lpClientConfig )
  372. {
  373. if( lpClientConfig == NULL || !DNVALID_READPTR(lpClientConfig,sizeof(DVCLIENTCONFIG)) )
  374. {
  375. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer" );
  376. return E_POINTER;
  377. }
  378. if( lpClientConfig->dwSize != sizeof( DVCLIENTCONFIG ) )
  379. {
  380. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid size" );
  381. return DVERR_INVALIDPARAM;
  382. }
  383. if( lpClientConfig->dwFlags &
  384. ~(DVCLIENTCONFIG_RECORDMUTE | DVCLIENTCONFIG_PLAYBACKMUTE |
  385. DVCLIENTCONFIG_AUTOVOICEACTIVATED | DVCLIENTCONFIG_AUTORECORDVOLUME |
  386. DVCLIENTCONFIG_MUTEGLOBAL | DVCLIENTCONFIG_MANUALVOICEACTIVATED |
  387. DVCLIENTCONFIG_AUTOVOLUMERESET | DVCLIENTCONFIG_ECHOSUPPRESSION )
  388. )
  389. {
  390. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid flags" );
  391. return DVERR_INVALIDFLAGS;
  392. }
  393. if( lpClientConfig->dwFlags & DVCLIENTCONFIG_MANUALVOICEACTIVATED &&
  394. lpClientConfig->dwFlags & DVCLIENTCONFIG_AUTOVOICEACTIVATED )
  395. {
  396. DPFX(DPFPREP, DVF_ERRORLEVEL, "Cannot specify manual AND auto voice activated" );
  397. return DVERR_INVALIDFLAGS;
  398. }
  399. if( lpClientConfig->dwFlags & DVCLIENTCONFIG_AUTORECORDVOLUME )
  400. {
  401. if( !DV_ValidRecordVolume(lpClientConfig->lRecordVolume)
  402. && lpClientConfig->lRecordVolume != DVRECORDVOLUME_LAST )
  403. {
  404. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid record volume w/auto" );
  405. return DVERR_INVALIDPARAM;
  406. }
  407. }
  408. else
  409. {
  410. if( !DV_ValidRecordVolume( lpClientConfig->lRecordVolume ) )
  411. {
  412. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid recording volume" );
  413. return DVERR_INVALIDPARAM;
  414. }
  415. }
  416. if( !DV_ValidPlaybackVolume( lpClientConfig->lPlaybackVolume ) )
  417. {
  418. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid playback volume" );
  419. return DVERR_INVALIDPARAM;
  420. }
  421. // If it's NOT manual, this parameter must be 0.
  422. if( !(lpClientConfig->dwFlags & DVCLIENTCONFIG_MANUALVOICEACTIVATED) )
  423. {
  424. if( lpClientConfig->dwThreshold != DVTHRESHOLD_UNUSED )
  425. {
  426. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid sensitivity w/auto" );
  427. return DVERR_INVALIDPARAM;
  428. }
  429. }
  430. else
  431. {
  432. if( !DV_ValidSensitivity( lpClientConfig->dwThreshold ) )
  433. {
  434. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid sensitivity" );
  435. return DVERR_INVALIDPARAM;
  436. }
  437. }
  438. if( !DV_ValidBufferAggresiveness( lpClientConfig->dwBufferAggressiveness ) ||
  439. !DV_ValidBufferQuality( lpClientConfig->dwBufferQuality ) ||
  440. !DV_ValidNotifyPeriod( lpClientConfig->dwNotifyPeriod ) )
  441. {
  442. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid volume/aggresiveness/period" );
  443. return DVERR_INVALIDPARAM;
  444. }
  445. return DV_OK;
  446. }
  447. #undef DPF_MODNAME
  448. #define DPF_MODNAME "DV_ValidSessionDesc"
  449. // DV_ValidSessionDesc
  450. //
  451. // Checks the specified session description to ensure it's valid.
  452. //
  453. HRESULT DV_ValidSessionDesc( LPDVSESSIONDESC lpSessionDesc )
  454. {
  455. if( lpSessionDesc == NULL ||
  456. !DNVALID_READPTR( lpSessionDesc, sizeof(DVSESSIONDESC) ) )
  457. {
  458. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer" );
  459. return E_POINTER;
  460. }
  461. if( lpSessionDesc->dwSize != sizeof( DVSESSIONDESC) )
  462. {
  463. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid size" );
  464. return DVERR_INVALIDPARAM;
  465. }
  466. if( !DV_ValidBufferAggresiveness( lpSessionDesc->dwBufferAggressiveness ) ||
  467. !DV_ValidBufferQuality( lpSessionDesc->dwBufferQuality ) )
  468. {
  469. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid buffer settings" );
  470. return DVERR_INVALIDPARAM;
  471. }
  472. if( lpSessionDesc->dwSessionType != DVSESSIONTYPE_PEER &&
  473. lpSessionDesc->dwSessionType != DVSESSIONTYPE_MIXING &&
  474. lpSessionDesc->dwSessionType != DVSESSIONTYPE_FORWARDING &&
  475. lpSessionDesc->dwSessionType != DVSESSIONTYPE_ECHO )
  476. {
  477. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid session type" );
  478. return DVERR_INVALIDPARAM;
  479. }
  480. if( lpSessionDesc->dwFlags & ~(DVSESSION_SERVERCONTROLTARGET | DVSESSION_NOHOSTMIGRATION) )
  481. {
  482. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid flags" );
  483. return DVERR_INVALIDFLAGS;
  484. }
  485. return DV_OK;
  486. }
  487. // DV_ValidBufferAggresiveness
  488. //
  489. // Checks the specified aggressiveness to ensure it's valid
  490. //
  491. BOOL DV_ValidBufferAggresiveness( DWORD dwValue )
  492. {
  493. if( dwValue != DVBUFFERAGGRESSIVENESS_DEFAULT &&
  494. ((dwValue < DVBUFFERAGGRESSIVENESS_MIN) ||
  495. dwValue > DVBUFFERAGGRESSIVENESS_MAX) )
  496. {
  497. return FALSE;
  498. }
  499. else
  500. {
  501. return TRUE;
  502. }
  503. }
  504. // DV_ValidBufferQuality
  505. //
  506. // Checks the specified buffer quality to ensure it's valid
  507. //
  508. BOOL DV_ValidBufferQuality( DWORD dwValue )
  509. {
  510. if( dwValue != DVBUFFERQUALITY_DEFAULT &&
  511. ((dwValue < DVBUFFERQUALITY_MIN) ||
  512. dwValue > DVBUFFERQUALITY_MAX) )
  513. {
  514. return FALSE;
  515. }
  516. else
  517. {
  518. return TRUE;
  519. }
  520. }
  521. // DV_ValidSensitivity
  522. //
  523. // Checks the sensitivity to ensure it's valid
  524. //
  525. BOOL DV_ValidSensitivity( DWORD dwValue )
  526. {
  527. if( dwValue != DVTHRESHOLD_DEFAULT &&
  528. (// Commented out because min is currently 0 (dwValue < DVTHRESHOLD_MIN) ||
  529. (dwValue > DVTHRESHOLD_MAX) ) )
  530. {
  531. return FALSE;
  532. }
  533. else
  534. {
  535. return TRUE;
  536. }
  537. }
  538. #undef DPF_MODNAME
  539. #define DPF_MODNAME "DV_CopySessionDescToBuffer"
  540. //
  541. // DV_CopySessionDescToBuffer
  542. //
  543. // Checks the parameters for validity and then copies the specified session description
  544. // to the specified buffer. (If it will fit).
  545. //
  546. HRESULT DV_CopySessionDescToBuffer( LPVOID lpTarget, LPDVSESSIONDESC lpdvSessionDesc, LPDWORD lpdwSize )
  547. {
  548. LPDVSESSIONDESC lpSessionDesc = (LPDVSESSIONDESC) lpTarget;
  549. if( lpdwSize == NULL ||
  550. !DNVALID_READPTR( lpdwSize, sizeof(DWORD) ))
  551. {
  552. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer" );
  553. return E_POINTER;
  554. }
  555. if( (*lpdwSize) < sizeof( DVSESSIONDESC ) )
  556. {
  557. *lpdwSize = sizeof( DVSESSIONDESC );
  558. DPFX(DPFPREP, DVF_INFOLEVEL, "Error size" );
  559. return DVERR_BUFFERTOOSMALL;
  560. }
  561. *lpdwSize = sizeof( DVSESSIONDESC );
  562. if( lpTarget == NULL || !DNVALID_WRITEPTR(lpTarget,sizeof( DVSESSIONDESC )) )
  563. {
  564. DPFX(DPFPREP, DVF_ERRORLEVEL, "Target buffer pointer bad" );
  565. return E_POINTER;
  566. }
  567. memcpy( lpTarget, lpdvSessionDesc, sizeof( DVSESSIONDESC ) );
  568. DPFX(DPFPREP, DVF_ENTRYLEVEL, "DVCE::GetSessionDesc() Success" );
  569. return DV_OK;
  570. }
  571. #undef DPF_MODNAME
  572. #define DPF_MODNAME "DV_GetWaveFormatExSize"
  573. DWORD DV_GetWaveFormatExSize( LPWAVEFORMATEX lpwfxFormat )
  574. {
  575. DNASSERT( lpwfxFormat != NULL );
  576. return (lpwfxFormat->cbSize+sizeof(WAVEFORMATEX));
  577. }
  578. #undef DPF_MODNAME
  579. #define DPF_MODNAME "DV_AddRef"
  580. STDAPI DV_AddRef(LPDIRECTVOICEOBJECT lpDV )
  581. {
  582. LONG rc;
  583. DNEnterCriticalSection( &lpDV->csCountLock );
  584. rc = ++lpDV->lIntRefCnt;
  585. DNLeaveCriticalSection( &lpDV->csCountLock );
  586. return rc;
  587. }
  588. #undef DPF_MODNAME
  589. #define DPF_MODNAME "DV_Initialize"
  590. //
  591. // DV_Initialize
  592. //
  593. // Responsible for initializing the specified directvoice object with the specified parameters.
  594. //
  595. STDAPI DV_Initialize( LPDIRECTVOICEOBJECT lpdvObject, LPUNKNOWN lpTransport, LPDVMESSAGEHANDLER lpMessageHandler, LPVOID lpUserContext, LPDWORD lpdwMessages, DWORD dwNumElements )
  596. {
  597. HRESULT hr = S_OK;
  598. LPUNKNOWN lpUnknown = lpTransport;
  599. LPDIRECTPLAYVOICETRANSPORT lpdvNotify;
  600. CDirectVoiceDirectXTransport *lpdxTransport;
  601. if( lpUnknown == NULL )
  602. {
  603. DPFX(DPFPREP, DVF_ERRORLEVEL, "Bad pointer" );
  604. return DVERR_NOTRANSPORT;
  605. }
  606. // Fix a memory leak if you Connect/Disconnect and then reconnect.
  607. if( lpdvObject->lpDVTransport )
  608. {
  609. delete lpdvObject->lpDVTransport;
  610. lpdvObject->lpDVTransport = NULL;
  611. }
  612. // Try and retrieve transport interface from the object we got.
  613. hr = lpUnknown->QueryInterface( IID_IDirectPlayVoiceTransport, (void **) &lpdvNotify );
  614. // If we failed, default to the old type
  615. if( FAILED( hr ) )
  616. {
  617. if( hr == E_NOINTERFACE )
  618. {
  619. DPFX(DPFPREP, DVF_ERRORLEVEL, "The specified interface is not a valid transport" );
  620. return DVERR_NOTRANSPORT;
  621. }
  622. else
  623. {
  624. DPFX(DPFPREP, DVF_ERRORLEVEL, "Query for interface failed hr = 0x%x", hr );
  625. return DVERR_GENERIC;
  626. }
  627. }
  628. // Otherwise, startup the new transport system.
  629. else
  630. {
  631. lpdxTransport = new CDirectVoiceDirectXTransport(lpdvNotify);
  632. if( lpdxTransport == NULL )
  633. {
  634. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to allocate transport" );
  635. lpdvNotify->Release();
  636. return DVERR_OUTOFMEMORY;
  637. }
  638. lpdvNotify->Release();
  639. }
  640. hr = lpdvObject->lpDVEngine->Initialize( static_cast<CDirectVoiceTransport *>(lpdxTransport), lpMessageHandler, lpUserContext, lpdwMessages, dwNumElements );
  641. if( FAILED( hr ) )
  642. {
  643. delete lpdxTransport;
  644. return hr;
  645. }
  646. lpdvObject->lpDVTransport = static_cast<CDirectVoiceTransport *>(lpdxTransport);
  647. return S_OK;
  648. }
  649. #undef DPF_MODNAME
  650. #define DPF_MODNAME "DV_DUMP_Caps"
  651. // DV_DUMP_Caps
  652. //
  653. // Dumps a DVCAPS structure
  654. //
  655. void DV_DUMP_Caps( LPDVCAPS lpdvCaps )
  656. {
  657. DNASSERT( lpdvCaps != NULL );
  658. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  659. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVCAPS Dump Addr=0x%p", lpdvCaps );
  660. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvCaps->dwSize );
  661. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvCaps->dwFlags );
  662. }
  663. #undef DPF_MODNAME
  664. #define DPF_MODNAME "DV_DUMP_GUID"
  665. void DV_DUMP_GUID( GUID guid )
  666. {
  667. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}", guid.Data1, guid.Data2, guid.Data3,
  668. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  669. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
  670. }
  671. #undef DPF_MODNAME
  672. #define DPF_MODNAME "DV_DUMP_CompressionInfo"
  673. void DV_DUMP_CompressionInfo( LPDVCOMPRESSIONINFO lpdvCompressionInfo, DWORD dwNumElements )
  674. {
  675. DNASSERT( lpdvCompressionInfo != NULL );
  676. DWORD dwIndex;
  677. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  678. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVCOMPRESSIONINFO Array Dump Addr=0x%p", lpdvCompressionInfo );
  679. for( dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
  680. {
  681. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvCompressionInfo[dwIndex].dwSize );
  682. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvCompressionInfo[dwIndex].dwFlags );
  683. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszDescription = %s", lpdvCompressionInfo[dwIndex].lpszDescription );
  684. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszName = %s", lpdvCompressionInfo[dwIndex].lpszName );
  685. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guidType = " );
  686. DV_DUMP_GUID( lpdvCompressionInfo[dwIndex].guidType );
  687. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwMaxBitsPerSecond = %d", lpdvCompressionInfo[dwIndex].dwMaxBitsPerSecond );
  688. }
  689. }
  690. #undef DPF_MODNAME
  691. #define DPF_MODNAME "DV_DUMP_FullCompressionInfo"
  692. void DV_DUMP_FullCompressionInfo( LPDVFULLCOMPRESSIONINFO lpdvfCompressionInfo, DWORD dwNumElements )
  693. {
  694. DNASSERT( lpdvfCompressionInfo != NULL );
  695. DWORD dwIndex;
  696. LPSTR lpszTmp;
  697. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  698. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVFULLCOMPRESSIONINFO Array Dump Addr=0x%p", lpdvfCompressionInfo );
  699. for( dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
  700. {
  701. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvfCompressionInfo[dwIndex].dwSize );
  702. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvfCompressionInfo[dwIndex].dwFlags );
  703. if( FAILED( STR_AllocAndConvertToANSI( &lpszTmp, lpdvfCompressionInfo[dwIndex].lpszDescription ) ) )
  704. {
  705. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszDescription = <Convert Failed>" );
  706. }
  707. else
  708. {
  709. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszDescription = %s", lpszTmp );
  710. delete [] lpszTmp;
  711. }
  712. if( FAILED( STR_AllocAndConvertToANSI( &lpszTmp, lpdvfCompressionInfo[dwIndex].lpszName ) ) )
  713. {
  714. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszName = <Convert Failed>" );
  715. }
  716. else
  717. {
  718. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpszName = %s", lpszTmp );
  719. delete [] lpszTmp;
  720. }
  721. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guidType = " );
  722. DV_DUMP_GUID( lpdvfCompressionInfo[dwIndex].guidType );
  723. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  724. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpwfxFormat = 0x%p", lpdvfCompressionInfo[dwIndex].lpwfxFormat );
  725. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFramesPerBuffer = %d", lpdvfCompressionInfo[dwIndex].dwFramesPerBuffer );
  726. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwTrailFrames = %d", lpdvfCompressionInfo[dwIndex].dwTrailFrames );
  727. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwTimeout = %d", lpdvfCompressionInfo[dwIndex].dwTimeout );
  728. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "bMinConnectType = %d", (DWORD) lpdvfCompressionInfo[dwIndex].bMinConnectType );
  729. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFrameLength = %d", lpdvfCompressionInfo[dwIndex].dwFrameLength );
  730. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFrame8Khz = %d", lpdvfCompressionInfo[dwIndex].dwFrame8Khz );
  731. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFrame11Khz = %d", lpdvfCompressionInfo[dwIndex].dwFrame11Khz );
  732. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFrame22Khz = %d", lpdvfCompressionInfo[dwIndex].dwFrame22Khz );
  733. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFrame44Khz = %d", lpdvfCompressionInfo[dwIndex].dwFrame44Khz );
  734. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwMaxBitsPerSecond = %d", lpdvfCompressionInfo[dwIndex].dwMaxBitsPerSecond );
  735. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "wInnerQueueSize = %d", lpdvfCompressionInfo[dwIndex].wInnerQueueSize );
  736. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "wMaxHighWaterMark = %d", lpdvfCompressionInfo[dwIndex].wMaxHighWaterMark );
  737. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "bMaxQueueSize = %d", (DWORD) lpdvfCompressionInfo[dwIndex].bMaxQueueSize );
  738. }
  739. }
  740. #undef DPF_MODNAME
  741. #define DPF_MODNAME "DV_DUMP_SessionDesc"
  742. void DV_DUMP_SessionDesc( LPDVSESSIONDESC lpdvSessionDesc )
  743. {
  744. DNASSERT( lpdvSessionDesc != NULL );
  745. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  746. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVSESSIONDESC Dump Addr=0x%p", lpdvSessionDesc );
  747. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvSessionDesc->dwSize );
  748. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvSessionDesc->dwFlags );
  749. DPFX(DPFPREP, DVF_STRUCTUREDUMP, " %s", (lpdvSessionDesc->dwFlags & DVSESSION_SERVERCONTROLTARGET) ? "DVSESSION_SERVERCONTROLTARGET," : "");
  750. switch( lpdvSessionDesc->dwSessionType )
  751. {
  752. case DVSESSIONTYPE_PEER:
  753. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSessionType = DVSESSIONTYPE_PEER" );
  754. break;
  755. case DVSESSIONTYPE_MIXING:
  756. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSessionType = DVSESSIONTYPE_MIXING" );
  757. break;
  758. case DVSESSIONTYPE_FORWARDING:
  759. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSessionType = DVSESSIONTYPE_FORWARDING" );
  760. break;
  761. case DVSESSIONTYPE_ECHO:
  762. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSessionType = DVSESSIONTYPE_ECHO" );
  763. break;
  764. default:
  765. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSessionType = Unknown" );
  766. break;
  767. }
  768. if( lpdvSessionDesc->dwBufferAggressiveness == DVBUFFERAGGRESSIVENESS_DEFAULT )
  769. {
  770. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferAggressiveness = DEFAULT" );
  771. }
  772. else
  773. {
  774. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferAggressiveness = %d", lpdvSessionDesc->dwBufferAggressiveness );
  775. }
  776. if( lpdvSessionDesc->dwBufferQuality == DVBUFFERQUALITY_DEFAULT )
  777. {
  778. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferQuality = DEFAULT" );
  779. }
  780. else
  781. {
  782. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferQuality = %d", lpdvSessionDesc->dwBufferQuality );
  783. }
  784. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guidCT = " );
  785. DV_DUMP_GUID( lpdvSessionDesc->guidCT );
  786. }
  787. #undef DPF_MODNAME
  788. #define DPF_MODNAME "DV_DUMP_DSBDESC"
  789. void DV_DUMP_DSBDESC( LPDSBUFFERDESC lpdsBufferDesc )
  790. {
  791. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  792. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DSBUFFERDESC DUMP Addr=0x%p", lpdsBufferDesc );
  793. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdsBufferDesc->dwSize );
  794. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdsBufferDesc->dwFlags );
  795. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferBytes = %d", lpdsBufferDesc->dwBufferBytes );
  796. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwReserved = %d", lpdsBufferDesc->dwReserved );
  797. if( lpdsBufferDesc->dwSize >= sizeof( DSBUFFERDESC1 ) )
  798. {
  799. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guid3DAlgorithm = " );
  800. DV_DUMP_GUID( lpdsBufferDesc->guid3DAlgorithm );
  801. }
  802. if( lpdsBufferDesc->lpwfxFormat == NULL )
  803. {
  804. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpwfxFormat = NULL" );
  805. }
  806. else
  807. {
  808. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpwfxFormat = " );
  809. DV_DUMP_WaveFormatEx(lpdsBufferDesc->lpwfxFormat);
  810. }
  811. }
  812. #undef DPF_MODNAME
  813. #define DPF_MODNAME "DV_DUMP_SoundDeviceConfig"
  814. void DV_DUMP_SoundDeviceConfig( LPDVSOUNDDEVICECONFIG lpdvSoundConfig )
  815. {
  816. DNASSERT( lpdvSoundConfig != NULL );
  817. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  818. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVSOUNDDEVICECONFIG Dump Addr=0x%p", lpdvSoundConfig );
  819. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvSoundConfig->dwSize );
  820. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvSoundConfig->dwFlags );
  821. DPFX(DPFPREP, DVF_STRUCTUREDUMP, " %s%s",
  822. (lpdvSoundConfig->dwFlags & DVSOUNDCONFIG_AUTOSELECT) ? "DVSOUNDCONFIG_AUTOSELECT," : "",
  823. (lpdvSoundConfig->dwFlags & DVSOUNDCONFIG_HALFDUPLEX) ? "DVSESSION_HALFDUPLEX," : "",
  824. (lpdvSoundConfig->dwFlags & DVSOUNDCONFIG_STRICTFOCUS) ? "DVSOUNDCONFIG_STRICTFOCUS," : "",
  825. (lpdvSoundConfig->dwFlags & DVSOUNDCONFIG_NOFOCUS) ? "DVSOUNDCONFIG_NOFOCUS," : "");
  826. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guidPlaybackDevice =" );
  827. DV_DUMP_GUID( lpdvSoundConfig->guidPlaybackDevice );
  828. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "guidCaptureDevice =" );
  829. DV_DUMP_GUID( lpdvSoundConfig->guidCaptureDevice );
  830. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  831. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpdsPlaybackDevice = 0x%p", lpdvSoundConfig->lpdsPlaybackDevice ) ;
  832. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpdsCaptureDevice = 0x%p", lpdvSoundConfig->lpdsCaptureDevice ) ;
  833. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lpdsMainBuffer = 0x%p", lpdvSoundConfig->lpdsMainBuffer );
  834. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwMainBufferPriority = 0x%x", lpdvSoundConfig->dwMainBufferPriority );
  835. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwMainBufferFlags = 0x%x", lpdvSoundConfig->dwMainBufferFlags );
  836. }
  837. #undef DPF_MODNAME
  838. #define DPF_MODNAME "DV_DUMP_ClientConfig"
  839. void DV_DUMP_ClientConfig( LPDVCLIENTCONFIG lpdvClientConfig )
  840. {
  841. DNASSERT( lpdvClientConfig != NULL );
  842. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  843. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "DVCLIENTCONFIG Dump Addr = 0x%p", lpdvClientConfig );
  844. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwSize = %d", lpdvClientConfig->dwSize );
  845. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwFlags = 0x%x", lpdvClientConfig->dwFlags );
  846. DPFX(DPFPREP, DVF_STRUCTUREDUMP, " %s%s%s%s%s%s",
  847. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_RECORDMUTE) ? "DVCLIENTCONFIG_RECORDMUTE," : "",
  848. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_PLAYBACKMUTE) ? "DVCLIENTCONFIG_PLAYBACKMUTE," : "",
  849. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_MANUALVOICEACTIVATED) ? "DVCLIENTCONFIG_MANUALVOICEACTIVATED," : "",
  850. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_AUTOVOICEACTIVATED) ? "DVCLIENTCONFIG_AUTOVOICEACTIVATED," : "",
  851. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_MUTEGLOBAL) ? "DVCLIENTCONFIG_MUTEGLOBAL," : "",
  852. (lpdvClientConfig->dwFlags & DVCLIENTCONFIG_AUTORECORDVOLUME) ? "DVCLIENTCONFIG_AUTORECORDVOLUME" : "" );
  853. if( lpdvClientConfig->dwBufferAggressiveness == DVBUFFERAGGRESSIVENESS_DEFAULT )
  854. {
  855. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferAggressiveness = DEFAULT" );
  856. }
  857. else
  858. {
  859. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferAggressiveness = %d", lpdvClientConfig->dwBufferAggressiveness );
  860. }
  861. if( lpdvClientConfig->dwBufferQuality == DVBUFFERQUALITY_DEFAULT )
  862. {
  863. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferQuality = DEFAULT" );
  864. }
  865. else
  866. {
  867. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwBufferQuality = %d", lpdvClientConfig->dwBufferQuality );
  868. }
  869. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "dwNotifyPeriod = %d", lpdvClientConfig->dwNotifyPeriod );
  870. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lPlaybackVolume = %li", lpdvClientConfig->lPlaybackVolume );
  871. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "lRecordVolume = %li", lpdvClientConfig->lRecordVolume );
  872. }
  873. #undef DPF_MODNAME
  874. #define DPF_MODNAME "DV_DUMP_WaveFormatEx"
  875. void DV_DUMP_WaveFormatEx( LPWAVEFORMATEX lpwfxFormat )
  876. {
  877. DNASSERT( lpwfxFormat != NULL );
  878. // 7/31/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  879. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "WAVEFORMATEX Dump Addr = 0x%p", lpwfxFormat );
  880. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "wFormatTag = %d", lpwfxFormat->wFormatTag );
  881. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "nSamplesPerSec = %d", lpwfxFormat->nSamplesPerSec );
  882. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "nChannels = %d", lpwfxFormat->nChannels );
  883. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "wBitsPerSample = %d", lpwfxFormat->wBitsPerSample );
  884. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "nAvgBytesPerSec = %d", lpwfxFormat->nAvgBytesPerSec );
  885. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "nBlockAlign = %d", lpwfxFormat->nBlockAlign );
  886. DPFX(DPFPREP, DVF_STRUCTUREDUMP, "cbSize = %d", lpwfxFormat->cbSize );
  887. }
  888. #undef DPF_MODNAME
  889. #define DPF_MODNAME "DV_ValidDirectVoiceObject"
  890. // DV_ValidDirectVoiceObject
  891. //
  892. // Checks to ensure the specified pointer points to a valid directvoice
  893. // object.
  894. BOOL DV_ValidDirectVoiceObject( LPDIRECTVOICEOBJECT lpdv )
  895. {
  896. if( lpdv == NULL )
  897. {
  898. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object is null" );
  899. return FALSE;
  900. }
  901. if( !DNVALID_READPTR( lpdv, sizeof( DIRECTVOICEOBJECT ) ) )
  902. {
  903. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid read ptr" );
  904. return FALSE;
  905. }
  906. if( lpdv->lpDVEngine != NULL &&
  907. !DNVALID_READPTR( lpdv->lpDVEngine, sizeof( CDirectVoiceEngine ) ) )
  908. {
  909. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid engine" );
  910. return FALSE;
  911. }
  912. if( lpdv->lpDVTransport != NULL &&
  913. !DNVALID_READPTR( lpdv->lpDVEngine, sizeof( CDirectVoiceTransport ) ) )
  914. {
  915. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid transport" );
  916. return FALSE;
  917. }
  918. return TRUE;
  919. }
  920. #undef DPF_MODNAME
  921. #define DPF_MODNAME "DV_ValidDirectXVoiceClientObject"
  922. // DV_ValidDirectXVoiceClientObject
  923. //
  924. // Checks to ensure the specified pointer points to a valid directvoice
  925. // object.
  926. BOOL DV_ValidDirectXVoiceClientObject( LPDIRECTVOICEOBJECT lpdvc )
  927. {
  928. if( !DV_ValidDirectVoiceObject( lpdvc ) )
  929. {
  930. return FALSE;
  931. }
  932. if( lpdvc->lpVtbl != dvcInterface )
  933. {
  934. DPFX(DPFPREP, DVF_ERRORLEVEL, "Bad vtable" );
  935. return FALSE;
  936. }
  937. if( lpdvc->dvNotify.lpNotifyVtble != NULL &&
  938. lpdvc->dvNotify.lpNotifyVtble != dvClientNotifyInterface )
  939. {
  940. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid notify vtable" );
  941. return FALSE;
  942. }
  943. LPDIRECTVOICECLIENTOBJECT lpdvClientObject = (LPDIRECTVOICECLIENTOBJECT) lpdvc;
  944. if( lpdvClientObject->lpDVClientEngine != NULL &&
  945. !DNVALID_READPTR( lpdvClientObject->lpDVClientEngine, sizeof( CDirectVoiceClientEngine ) ) )
  946. {
  947. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid client engine" );
  948. return FALSE;
  949. }
  950. return TRUE;
  951. }
  952. #undef DPF_MODNAME
  953. #define DPF_MODNAME "DV_ValidDirectXVoiceServerObject"
  954. // DV_ValidDirectXVoiceServerObject
  955. //
  956. // Checks to ensure the specified pointer points to a valid directvoice
  957. // object.
  958. BOOL DV_ValidDirectXVoiceServerObject( LPDIRECTVOICEOBJECT lpdvs )
  959. {
  960. if( !DV_ValidDirectVoiceObject( lpdvs ) )
  961. {
  962. return FALSE;
  963. }
  964. if( lpdvs->lpVtbl != dvsInterface )
  965. {
  966. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid server vtable" );
  967. return FALSE;
  968. }
  969. if( lpdvs->dvNotify.lpNotifyVtble != NULL &&
  970. lpdvs->dvNotify.lpNotifyVtble != dvServerNotifyInterface )
  971. {
  972. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid notify vtable" );
  973. return FALSE;
  974. }
  975. LPDIRECTVOICESERVEROBJECT lpdvServerObject = (LPDIRECTVOICESERVEROBJECT) lpdvs;
  976. if( lpdvServerObject->lpDVServerEngine != NULL &&
  977. !DNVALID_READPTR( lpdvServerObject->lpDVServerEngine, sizeof( CDirectVoiceServerEngine ) ) )
  978. {
  979. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid server engine" );
  980. return FALSE;
  981. }
  982. return TRUE;
  983. }
  984. #undef DPF_MODNAME
  985. #define DPF_MODNAME "DV_ValidMessageArray"
  986. // Validate message mask.
  987. //
  988. // May be too strict to enforce server only or client/only.
  989. //
  990. HRESULT DV_ValidMessageArray( LPDWORD lpdwMessages, DWORD dwNumMessages, BOOL fServer )
  991. {
  992. if( dwNumMessages > 0 &&
  993. (lpdwMessages == NULL ||
  994. !DNVALID_READPTR( lpdwMessages, sizeof(DWORD)*dwNumMessages )) )
  995. {
  996. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer passed for the lpdwMessages parameter." );
  997. return DVERR_INVALIDPOINTER;
  998. }
  999. if( lpdwMessages != NULL && dwNumMessages == 0 )
  1000. {
  1001. DPFX(DPFPREP, DVF_ERRORLEVEL, "Non-NULL notification array with 0 size" );
  1002. return DVERR_INVALIDPARAM;
  1003. }
  1004. DWORD dwIndex, dwSubIndex;
  1005. for( dwIndex = 0; dwIndex < dwNumMessages; dwIndex++ )
  1006. {
  1007. if( lpdwMessages[dwIndex] < DVMSGID_MINBASE || lpdwMessages[dwIndex] > DVMSGID_MAXBASE )
  1008. {
  1009. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid message specified in notification array" );
  1010. return DVERR_INVALIDPARAM;
  1011. }
  1012. switch( lpdwMessages[dwIndex] )
  1013. {
  1014. // Player only messages
  1015. case DVMSGID_PLAYERVOICESTART:
  1016. case DVMSGID_PLAYERVOICESTOP:
  1017. case DVMSGID_RECORDSTART:
  1018. case DVMSGID_RECORDSTOP:
  1019. case DVMSGID_CONNECTRESULT:
  1020. case DVMSGID_DISCONNECTRESULT:
  1021. case DVMSGID_INPUTLEVEL:
  1022. case DVMSGID_OUTPUTLEVEL:
  1023. case DVMSGID_SETTARGETS:
  1024. case DVMSGID_PLAYEROUTPUTLEVEL:
  1025. case DVMSGID_LOSTFOCUS:
  1026. case DVMSGID_GAINFOCUS:
  1027. case DVMSGID_HOSTMIGRATED:
  1028. case DVMSGID_LOCALHOSTSETUP:
  1029. if( fServer )
  1030. {
  1031. DPFX(DPFPREP, 0, "Client-only notification ID specified in server notification mask" );
  1032. return DVERR_INVALIDPARAM;
  1033. }
  1034. break;
  1035. }
  1036. for( dwSubIndex = 0; dwSubIndex < dwNumMessages; dwSubIndex++ )
  1037. {
  1038. if( dwIndex != dwSubIndex &&
  1039. lpdwMessages[dwIndex] == lpdwMessages[dwSubIndex] )
  1040. {
  1041. DPFX(DPFPREP, 0, "Duplicate IDs specified in notification mask" );
  1042. return DVERR_INVALIDPARAM;
  1043. }
  1044. }
  1045. }
  1046. return TRUE;
  1047. }