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.

573 lines
15 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: priority.cpp
  6. * Content: Implements a process that uses DirectSound in prioirty
  7. * mode to simulate an aggressive external playback only
  8. * application (such as a game) that may be running while
  9. * the full duplex application is in use. Note that WinMain
  10. * is in fdtest.cpp, but the guts are here.
  11. * History:
  12. * Date By Reason
  13. * ============
  14. * 08/19/99 pnewson created
  15. * 10/28/99 pnewson Bug #113937 audible clicking during full duplex test
  16. * 11/02/99 pnewson Fix: Bug #116365 - using wrong DSBUFFERDESC
  17. * 01/21/2000 pnewson Workaround for broken SetNotificationPositions call.
  18. * undef DSOUND_BROKEN once the SetNotificationPositions
  19. * no longer broken.
  20. * 02/15/2000 pnewson Removed the workaround for bug 116365
  21. * 04/04/2000 pnewson Changed a SendMessage to PostMessage to fix deadlock
  22. * 04/19/2000 pnewson Error handling cleanup
  23. * 07/12/2000 rodtoll Bug #31468 - Add diagnostic spew to logfile to show what is failing the HW Wizard
  24. * 08/25/2000 rodtoll Bug #43363 - CommandPriorityStart does not init return param and uses stack trash.
  25. *
  26. ***************************************************************************/
  27. #include "dxvtlibpch.h"
  28. #undef DPF_SUBCOMP
  29. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  30. static HRESULT CommandLoop(CPriorityIPC* lpipcPriority);
  31. static HRESULT DispatchCommand(CPriorityIPC* lpipcPriority, SFDTestCommand* pfdtc);
  32. static HRESULT CommandPriorityStart(SFDTestCommandPriorityStart* pfdtcPriorityStart, HRESULT* phrIPC);
  33. static HRESULT CommandPriorityStop(SFDTestCommandPriorityStop* pfdtcPriorityStop, HRESULT* phrIPC);
  34. #undef DPF_MODNAME
  35. #define DPF_MODNAME "PriorityProcess"
  36. HRESULT PriorityProcess(HINSTANCE hResDLLInstance, HINSTANCE hPrevInstance, TCHAR *szCmdLine, int iCmdShow)
  37. {
  38. //DEBUG_ONLY(_asm int 3;)
  39. DPF_ENTER();
  40. HRESULT hr;
  41. CPriorityIPC ipcPriority;
  42. BOOL fIPCInit = FALSE;
  43. BOOL fGuardInit = FALSE;
  44. if (!InitGlobGuard())
  45. {
  46. return DVERR_OUTOFMEMORY;
  47. }
  48. fGuardInit = TRUE;
  49. // Init the common control library. Use the old style
  50. // call, so we're compatibile right back to 95.
  51. InitCommonControls();
  52. // get the mutex, events and shared memory stuff
  53. hr = ipcPriority.Init();
  54. if (FAILED(hr))
  55. {
  56. goto error_cleanup;
  57. }
  58. fIPCInit = TRUE;
  59. // start up the testing loop
  60. hr = CommandLoop(&ipcPriority);
  61. if (FAILED(hr))
  62. {
  63. goto error_cleanup;
  64. }
  65. // close the mutex, events and shared memory stuff
  66. hr = ipcPriority.Deinit();
  67. fIPCInit = FALSE;
  68. if (FAILED(hr))
  69. {
  70. goto error_cleanup;
  71. }
  72. DeinitGlobGuard();
  73. DPF_EXIT();
  74. return S_OK;
  75. error_cleanup:
  76. if (fIPCInit == TRUE)
  77. {
  78. ipcPriority.Deinit();
  79. fIPCInit = FALSE;
  80. }
  81. if (fGuardInit == TRUE)
  82. {
  83. DeinitGlobGuard();
  84. fGuardInit = FALSE;
  85. }
  86. DPF_EXIT();
  87. return hr;
  88. }
  89. #undef DPF_MODNAME
  90. #define DPF_MODNAME "CommandLoop"
  91. static HRESULT CommandLoop(CPriorityIPC* lpipcPriority)
  92. {
  93. DPF_ENTER();
  94. BOOL fRet;
  95. LONG lRet;
  96. HRESULT hr;
  97. DWORD dwRet;
  98. SFDTestCommand fdtc;
  99. // Kick the supervisor process to let it know
  100. // we're ready to go.
  101. hr = lpipcPriority->SignalParentReady();
  102. if (FAILED(hr))
  103. {
  104. DPF_EXIT();
  105. return hr;
  106. }
  107. // enter the main command loop
  108. while (1)
  109. {
  110. // wait for a command from the supervisor process
  111. fdtc.dwSize = sizeof(fdtc);
  112. hr = lpipcPriority->Receive(&fdtc);
  113. if (FAILED(hr))
  114. {
  115. Diagnostics_Write(DVF_ERRORLEVEL, "CPriorityIPC::Receive() failed, hr: 0x%x", hr);
  116. break;
  117. }
  118. // dispatch the command
  119. hr = DispatchCommand(lpipcPriority, &fdtc);
  120. if (FAILED(hr))
  121. {
  122. Diagnostics_Write(DVF_ERRORLEVEL, "DispatchCommand() failed, hr: 0x%x", hr);
  123. break;
  124. }
  125. if (hr == DV_EXIT)
  126. {
  127. DPFX(DPFPREP, DVF_INFOLEVEL, "Exiting Priority process command loop");
  128. break;
  129. }
  130. }
  131. DPF_EXIT();
  132. return hr;
  133. }
  134. #undef DPF_MODNAME
  135. #define DPF_MODNAME "DispatchCommand"
  136. static HRESULT DispatchCommand(CPriorityIPC* lpipcPriority, SFDTestCommand* pfdtc)
  137. {
  138. DPF_ENTER();
  139. HRESULT hr;
  140. HRESULT hrIPC;
  141. switch (pfdtc->fdtcc)
  142. {
  143. case fdtccExit:
  144. // ok - reply to the calling process to let them
  145. // know we are getting out.
  146. DPFX(DPFPREP, DVF_INFOLEVEL, "Priority received Exit command");
  147. lpipcPriority->Reply(DV_EXIT);
  148. // returning this code will break us out of
  149. // the command processing loop
  150. DPF_EXIT();
  151. return DV_EXIT;
  152. case fdtccPriorityStart:
  153. hr = CommandPriorityStart(&(pfdtc->fdtu.fdtcPriorityStart), &hrIPC);
  154. if (FAILED(hr))
  155. {
  156. lpipcPriority->Reply(hrIPC);
  157. DPF_EXIT();
  158. return hr;
  159. }
  160. hr = lpipcPriority->Reply(hrIPC);
  161. DPF_EXIT();
  162. return hr;
  163. case fdtccPriorityStop:
  164. hr = CommandPriorityStop(&(pfdtc->fdtu.fdtcPriorityStop), &hrIPC);
  165. if (FAILED(hr))
  166. {
  167. lpipcPriority->Reply(hrIPC);
  168. DPF_EXIT();
  169. return hr;
  170. }
  171. hr = lpipcPriority->Reply(hrIPC);
  172. DPF_EXIT();
  173. return hr;
  174. default:
  175. // Don't know this command. Reply with the appropriate
  176. // code.
  177. DPFX(DPFPREP, DVF_INFOLEVEL, "Priority received Unknown command");
  178. hr = lpipcPriority->Reply(DVERR_UNKNOWN);
  179. if (FAILED(hr))
  180. {
  181. DPF_EXIT();
  182. return hr;
  183. }
  184. // While this is an error, it is one that the calling
  185. // process needs to figure out. In the meantime, this
  186. // process will happily continue on.
  187. DPF_EXIT();
  188. return S_OK;
  189. }
  190. }
  191. #undef DPF_MODNAME
  192. #define DPF_MODNAME "CommandPriorityStart"
  193. HRESULT CommandPriorityStart(SFDTestCommandPriorityStart* pfdtcPriorityStart, HRESULT* phrIPC)
  194. {
  195. DPF_ENTER();
  196. *phrIPC = DV_OK;
  197. HRESULT hr = S_OK;
  198. DSBUFFERDESC dsbd;
  199. WAVEFORMATEX wfx;
  200. DWORD dwSizeWritten;
  201. DSBCAPS dsbc;
  202. LPVOID lpvAudio1 = NULL;
  203. DWORD dwAudio1Size = NULL;
  204. LPVOID lpvAudio2 = NULL;
  205. DWORD dwAudio2Size = NULL;
  206. DSBPOSITIONNOTIFY dsbPositionNotify;
  207. DWORD dwRet;
  208. LONG lRet;
  209. BOOL fRet;
  210. HWND hwnd;
  211. BYTE bSilence;
  212. BOOL bBufferPlaying = FALSE;
  213. GUID guidTmp;
  214. memset( &guidTmp, 0x00, sizeof( GUID ) );
  215. // initalize the global vars
  216. GlobGuardIn();
  217. g_lpdsPriorityRender = NULL;
  218. g_lpdsbPriorityPrimary = NULL;
  219. g_lpdsbPrioritySecondary = NULL;
  220. GlobGuardOut();
  221. Diagnostics_Write( DVF_INFOLEVEL, "-----------------------------------------------------------" );
  222. hr = Diagnostics_DeviceInfo( &pfdtcPriorityStart->guidRenderDevice, &guidTmp );
  223. if( FAILED( hr ) )
  224. {
  225. Diagnostics_Write( 0, "Error getting device information hr=0x%x", hr );
  226. }
  227. Diagnostics_Write( DVF_INFOLEVEL, "-----------------------------------------------------------" );
  228. Diagnostics_Write( DVF_INFOLEVEL, "Primary Format: " );
  229. Diagnositcs_WriteWAVEFORMATEX( DVF_INFOLEVEL, &pfdtcPriorityStart->wfxRenderFormat );
  230. // make sure the priority dialog is in the foreground
  231. DPFX(DPFPREP, DVF_INFOLEVEL, "Bringing Wizard to the foreground");
  232. fRet = SetForegroundWindow(pfdtcPriorityStart->hwndWizard);
  233. if (!fRet)
  234. {
  235. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to bring wizard to foreground, continuing anyway...");
  236. }
  237. // kick the progress bar forward one tick
  238. DPFX(DPFPREP, DVF_INFOLEVEL, "Incrementing progress bar in dialog");
  239. PostMessage(pfdtcPriorityStart->hwndProgress, PBM_STEPIT, 0, 0);
  240. // create the DirectSound interface
  241. DPFX(DPFPREP, DVF_INFOLEVEL, "Creating DirectSound");
  242. GlobGuardIn();
  243. hr = DirectSoundCreate(&pfdtcPriorityStart->guidRenderDevice, &g_lpdsPriorityRender, NULL);
  244. if (FAILED(hr))
  245. {
  246. g_lpdsPriorityRender = NULL;
  247. GlobGuardOut();
  248. Diagnostics_Write(DVF_ERRORLEVEL, "DirectSoundCreate failed, code: 0x%x", hr);
  249. *phrIPC = DVERR_SOUNDINITFAILURE;
  250. hr = DV_OK;
  251. goto error_cleanup;
  252. }
  253. GlobGuardOut();
  254. // set to priority mode
  255. DPFX(DPFPREP, DVF_INFOLEVEL, "Setting Cooperative Level");
  256. GlobGuardIn();
  257. hr = g_lpdsPriorityRender->SetCooperativeLevel(pfdtcPriorityStart->hwndWizard, DSSCL_PRIORITY);
  258. GlobGuardOut();
  259. if (FAILED(hr))
  260. {
  261. Diagnostics_Write(DVF_ERRORLEVEL, "SetCooperativeLevel failed, code: 0x%x", hr);
  262. *phrIPC = DVERR_SOUNDINITFAILURE;
  263. hr = DV_OK;
  264. goto error_cleanup;
  265. }
  266. // Create a primary buffer object with 3d controls.
  267. // We're not actually going to use the controls, but a game probably would,
  268. // and we are really trying to emulate a game in this process.
  269. DPFX(DPFPREP, DVF_INFOLEVEL, "Creating Primary Sound Buffer");
  270. ZeroMemory(&dsbd, sizeof(dsbd));
  271. dsbd.dwSize = sizeof(dsbd);
  272. dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
  273. dsbd.dwBufferBytes = 0;
  274. dsbd.dwReserved = 0;
  275. dsbd.lpwfxFormat = NULL;
  276. dsbd.guid3DAlgorithm = DS3DALG_DEFAULT;
  277. GlobGuardIn();
  278. hr = g_lpdsPriorityRender->CreateSoundBuffer((LPDSBUFFERDESC)&dsbd, &g_lpdsbPriorityPrimary, NULL);
  279. if (FAILED(hr))
  280. {
  281. g_lpdsbPriorityPrimary = NULL;
  282. GlobGuardOut();
  283. Diagnostics_Write(DVF_ERRORLEVEL, "CreateSoundBuffer failed, code: 0x%x", hr);
  284. *phrIPC = DVERR_SOUNDINITFAILURE;
  285. hr = DV_OK;
  286. goto error_cleanup;
  287. }
  288. GlobGuardOut();
  289. // Set the format of the primary buffer to the requested format.
  290. DPFX(DPFPREP, DVF_INFOLEVEL, "Setting Primary Buffer Format");
  291. GlobGuardIn();
  292. hr = g_lpdsbPriorityPrimary->SetFormat(&pfdtcPriorityStart->wfxRenderFormat);
  293. GlobGuardOut();
  294. if (FAILED(hr))
  295. {
  296. Diagnostics_Write(DVF_ERRORLEVEL, "SetFormat failed, code: 0x%x ", hr);
  297. *phrIPC = DVERR_SOUNDINITFAILURE;
  298. hr = DV_OK;
  299. goto error_cleanup;
  300. }
  301. // check to make sure the SetFormat actually worked
  302. DPFX(DPFPREP, DVF_INFOLEVEL, "Verifying Primary Buffer Format");
  303. GlobGuardIn();
  304. hr = g_lpdsbPriorityPrimary->GetFormat(&wfx, sizeof(wfx), &dwSizeWritten);
  305. GlobGuardOut();
  306. if (FAILED(hr))
  307. {
  308. Diagnostics_Write(DVF_ERRORLEVEL, "GetFormat failed, code: 0x%x ", hr);
  309. *phrIPC = DVERR_SOUNDINITFAILURE;
  310. hr = DV_OK;
  311. goto error_cleanup;
  312. }
  313. if (dwSizeWritten != sizeof(wfx))
  314. {
  315. *phrIPC = DVERR_SOUNDINITFAILURE;
  316. hr = DV_OK;
  317. goto error_cleanup;
  318. }
  319. if (memcmp(&wfx, &pfdtcPriorityStart->wfxRenderFormat, sizeof(wfx)) != 0)
  320. {
  321. // This is an interesting case. Is it really a full duplex error that
  322. // we are unable to initialize a primary buffer in this format?
  323. // Perhaps not. Perhaps it is sufficient that we can get full duplex
  324. // sound even if the forground priority mode app attempts to play
  325. // using this format. So just dump a debug note, and move along...
  326. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Warning: SetFormat on primary buffer did not actually set the format");
  327. }
  328. // Create a secondary buffer object with 3d controls.
  329. // We're not actually going to use the controls, but a game probably would,
  330. // and we are really trying to emulate a game in this process.
  331. DPFX(DPFPREP, DVF_INFOLEVEL, "Creating Secondary Buffer");
  332. dsbd.dwSize = sizeof(dsbd);
  333. dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;
  334. dsbd.dwBufferBytes =
  335. (pfdtcPriorityStart->wfxSecondaryFormat.nSamplesPerSec
  336. * pfdtcPriorityStart->wfxSecondaryFormat.nBlockAlign)
  337. / (1000 / gc_dwFrameSize);
  338. dsbd.dwReserved = 0;
  339. dsbd.guid3DAlgorithm = DS3DALG_DEFAULT;
  340. dsbd.lpwfxFormat = &(pfdtcPriorityStart->wfxSecondaryFormat);
  341. GlobGuardIn();
  342. hr = g_lpdsPriorityRender->CreateSoundBuffer((LPDSBUFFERDESC)&dsbd, &g_lpdsbPrioritySecondary, NULL);
  343. if (FAILED(hr))
  344. {
  345. g_lpdsbPrioritySecondary = NULL;
  346. GlobGuardOut();
  347. Diagnostics_Write(DVF_ERRORLEVEL, "CreateSoundBuffer failed, code: 0x%x Primary ", hr);
  348. *phrIPC = DVERR_SOUNDINITFAILURE;
  349. hr = DV_OK;
  350. goto error_cleanup;
  351. }
  352. GlobGuardOut();
  353. // clear out the secondary buffer
  354. DPFX(DPFPREP, DVF_INFOLEVEL, "Clearing Secondary Buffer");
  355. GlobGuardIn();
  356. hr = g_lpdsbPrioritySecondary->Lock(
  357. 0,
  358. 0,
  359. &lpvAudio1,
  360. &dwAudio1Size,
  361. &lpvAudio2,
  362. &dwAudio2Size,
  363. DSBLOCK_ENTIREBUFFER);
  364. GlobGuardOut();
  365. if (FAILED(hr))
  366. {
  367. Diagnostics_Write(DVF_ERRORLEVEL, "Lock failed, code: 0x%x ", hr);
  368. *phrIPC = DVERR_SOUNDINITFAILURE;
  369. hr = DV_OK;
  370. goto error_cleanup;
  371. }
  372. if (lpvAudio1 == NULL)
  373. {
  374. *phrIPC = DVERR_SOUNDINITFAILURE;
  375. hr = DV_OK;
  376. goto error_cleanup;
  377. }
  378. if (pfdtcPriorityStart->wfxSecondaryFormat.wBitsPerSample == 8)
  379. {
  380. bSilence = 0x80;
  381. }
  382. else
  383. {
  384. bSilence = 0x00;
  385. }
  386. memset(lpvAudio1, bSilence, dwAudio1Size);
  387. if (lpvAudio2 != NULL)
  388. {
  389. memset(lpvAudio2, bSilence, dwAudio2Size);
  390. }
  391. GlobGuardIn();
  392. hr = g_lpdsbPrioritySecondary->Unlock(
  393. lpvAudio1,
  394. dwAudio1Size,
  395. lpvAudio2,
  396. dwAudio2Size);
  397. GlobGuardOut();
  398. if (FAILED(hr))
  399. {
  400. Diagnostics_Write(DVF_ERRORLEVEL, "Unlock failed, code: 0x%x ", hr);
  401. *phrIPC = DVERR_SOUNDINITFAILURE;
  402. hr = DV_OK;
  403. goto error_cleanup;
  404. }
  405. // start playing the secondary buffer
  406. DPFX(DPFPREP, DVF_INFOLEVEL, "Playing Secondary Buffer");
  407. GlobGuardIn();
  408. hr = g_lpdsbPrioritySecondary->Play(0, 0, DSBPLAY_LOOPING);
  409. GlobGuardOut();
  410. if (FAILED(hr))
  411. {
  412. Diagnostics_Write(DVF_ERRORLEVEL, "Play failed, code: 0x%x ", hr);
  413. *phrIPC = DVERR_SOUNDINITFAILURE;
  414. hr = DV_OK;
  415. goto error_cleanup;
  416. }
  417. bBufferPlaying = TRUE;
  418. DPF_EXIT();
  419. Diagnostics_Write(DVF_INFOLEVEL, "Priority Result = DV_OK" );
  420. return DV_OK;
  421. error_cleanup:
  422. GlobGuardIn();
  423. if (bBufferPlaying == TRUE)
  424. {
  425. if (g_lpdsbPrioritySecondary != NULL)
  426. {
  427. g_lpdsbPrioritySecondary->Stop();
  428. }
  429. bBufferPlaying = FALSE;
  430. }
  431. if (g_lpdsbPrioritySecondary != NULL)
  432. {
  433. g_lpdsbPrioritySecondary->Release();
  434. g_lpdsbPrioritySecondary = NULL;
  435. }
  436. if (g_lpdsbPriorityPrimary != NULL)
  437. {
  438. g_lpdsbPriorityPrimary->Release();
  439. g_lpdsbPriorityPrimary = NULL;
  440. }
  441. if (g_lpdsPriorityRender != NULL)
  442. {
  443. g_lpdsPriorityRender->Release();
  444. g_lpdsPriorityRender = NULL;
  445. }
  446. GlobGuardOut();
  447. DPF_EXIT();
  448. Diagnostics_Write(DVF_INFOLEVEL, "Priority Result = 0x%x", hr );
  449. return hr;
  450. }
  451. #undef DPF_MODNAME
  452. #define DPF_MODNAME "CommandPriorityStop"
  453. HRESULT CommandPriorityStop(SFDTestCommandPriorityStop* pfdtcPriorityStop, HRESULT* phrIPC)
  454. {
  455. DPF_ENTER();
  456. HRESULT hr;
  457. LONG lRet;
  458. DWORD dwRet;
  459. *phrIPC = S_OK;
  460. hr = S_OK;
  461. GlobGuardIn();
  462. if (g_lpdsbPrioritySecondary != NULL)
  463. {
  464. DPFX(DPFPREP, DVF_INFOLEVEL, "Stopping Secondary Buffer");
  465. hr = g_lpdsbPrioritySecondary->Stop();
  466. }
  467. GlobGuardOut();
  468. if (FAILED(hr))
  469. {
  470. Diagnostics_Write(DVF_ERRORLEVEL, "Stop failed, code: 0x%x", hr);
  471. *phrIPC = DVERR_SOUNDINITFAILURE;
  472. hr = DV_OK;
  473. }
  474. GlobGuardIn();
  475. if (g_lpdsbPrioritySecondary != NULL)
  476. {
  477. DPFX(DPFPREP, DVF_INFOLEVEL, "Releasing Secondary Buffer");
  478. g_lpdsbPrioritySecondary->Release();
  479. g_lpdsbPrioritySecondary = NULL;
  480. }
  481. if (g_lpdsbPriorityPrimary != NULL)
  482. {
  483. DPFX(DPFPREP, DVF_INFOLEVEL, "Releasing Primary Buffer");
  484. g_lpdsbPriorityPrimary->Release();
  485. g_lpdsbPriorityPrimary = NULL;
  486. }
  487. if (g_lpdsPriorityRender != NULL)
  488. {
  489. DPFX(DPFPREP, DVF_INFOLEVEL, "Releasing DirectSound");
  490. g_lpdsPriorityRender->Release();
  491. g_lpdsPriorityRender = NULL;
  492. }
  493. GlobGuardOut();
  494. DPF_EXIT();
  495. return hr;
  496. }