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.

366 lines
12 KiB

  1. /****************************************************************************
  2. *
  3. * File: testmus.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Mike Anderson (manders@microsoft.com)
  6. * Purpose: Test DMusic functionality on this machine
  7. *
  8. * (C) Copyright 1998 Microsoft Corp. All rights reserved.
  9. *
  10. ****************************************************************************/
  11. #include <Windows.h>
  12. #include <multimon.h>
  13. #include <dmusicc.h>
  14. #include <dmusici.h>
  15. #include "reginfo.h"
  16. #include "sysinfo.h"
  17. #include "dispinfo.h"
  18. #include "musinfo.h"
  19. #include "testmus.h"
  20. #include "resource.h"
  21. #ifndef ReleasePpo
  22. #define ReleasePpo(ppo) \
  23. if (*(ppo) != NULL) \
  24. { \
  25. (*(ppo))->Release(); \
  26. *(ppo) = NULL; \
  27. } \
  28. else (VOID)0
  29. #endif
  30. enum TESTID
  31. {
  32. TESTID_COINITIALIZE = 1,
  33. TESTID_CREATEDMLOADER,
  34. TESTID_CREATEDMPERF,
  35. TESTID_INITPERF,
  36. TESTID_CREATEPORT,
  37. TESTID_ACTIVATEPORT,
  38. TESTID_SETAUTODOWNLOAD,
  39. TESTID_ADDPORT,
  40. TESTID_ASSIGNPCHANNELBLOCK,
  41. TESTID_SPEWRESOURCETOFILE,
  42. TESTID_SETSEARCHDIRECTORY,
  43. TESTID_LOADERGETOBJECT,
  44. TESTID_PLAYSEGMENT,
  45. };
  46. BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp (yuck)
  47. static HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName);
  48. static HRESULT LoadSegment( BOOL fUseCWD );
  49. static VOID DeleteTempFile(TCHAR* pszFileName);
  50. /****************************************************************************
  51. *
  52. * TestMusic
  53. *
  54. ****************************************************************************/
  55. VOID TestMusic(HWND hwndMain, MusicInfo* pMusicInfo)
  56. {
  57. HRESULT hr;
  58. MusicPort* pMusicPort = NULL;
  59. IDirectMusicLoader* pLoader = NULL;
  60. IDirectMusicPerformance* pPerformance = NULL;
  61. IDirectMusic* pdm = NULL;
  62. IDirectMusicPort* pPort = NULL;
  63. IDirectMusicSegment* pSegment = NULL;
  64. BOOL bComInitialized = FALSE;
  65. TCHAR szFmt[300];
  66. TCHAR sz[300];
  67. TCHAR szTitle[100];
  68. if (pMusicInfo == NULL)
  69. return;
  70. // Determine pMusicPort of port to test:
  71. for (pMusicPort = pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL; pMusicPort = pMusicPort->m_pMusicPortNext)
  72. {
  73. if (pMusicPort->m_guid == pMusicInfo->m_guidMusicPortTest)
  74. break;
  75. }
  76. if (pMusicPort == NULL)
  77. return;
  78. LoadString(NULL, IDS_APPFULLNAME, szTitle, 100);
  79. LoadString(NULL, IDS_STARTDMUSICTEST, szFmt, 300);
  80. wsprintf(sz, szFmt, pMusicPort->m_szDescription);
  81. if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
  82. return;
  83. // Remove info from any previous test:
  84. ZeroMemory(&pMusicInfo->m_testResult, sizeof(TestResult));
  85. pMusicInfo->m_testResult.m_bStarted = TRUE;
  86. // Initialize COM
  87. if (FAILED(hr = CoInitialize(NULL)))
  88. {
  89. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_COINITIALIZE;
  90. pMusicInfo->m_testResult.m_hr = hr;
  91. goto LEnd;
  92. }
  93. bComInitialized = TRUE;
  94. // Create performance object
  95. if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicPerformance, NULL,
  96. CLSCTX_INPROC, IID_IDirectMusicPerformance, (VOID**)&pPerformance)))
  97. {
  98. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMPERF;
  99. pMusicInfo->m_testResult.m_hr = hr;
  100. goto LEnd;
  101. }
  102. // Initialize the performance -- also creates DirectMusic object
  103. if (FAILED(hr = pPerformance->Init(&pdm, NULL, hwndMain)))
  104. {
  105. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_INITPERF;
  106. pMusicInfo->m_testResult.m_hr = hr;
  107. goto LEnd;
  108. }
  109. // Create a port using the user-specified GUID
  110. DMUS_PORTPARAMS portParams;
  111. ZeroMemory(&portParams, sizeof(portParams));
  112. portParams.dwSize = sizeof(portParams);
  113. portParams.dwValidParams = DMUS_PORTPARAMS_EFFECTS | DMUS_PORTPARAMS_CHANNELGROUPS |
  114. DMUS_PORTPARAMS_AUDIOCHANNELS;
  115. portParams.dwEffectFlags = DMUS_EFFECT_REVERB;
  116. portParams.dwChannelGroups = pMusicPort->m_dwMaxChannelGroups;
  117. portParams.dwAudioChannels = pMusicPort->m_dwMaxAudioChannels;
  118. if (FAILED(hr = pdm->CreatePort(pMusicPort->m_guid, &portParams, &pPort, NULL)))
  119. {
  120. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEPORT;
  121. pMusicInfo->m_testResult.m_hr = hr;
  122. goto LEnd;
  123. }
  124. // Activate the port
  125. if (FAILED(hr = pPort->Activate(TRUE)))
  126. {
  127. // Bug 21677: catch case where user has no sound card
  128. if (hr == DSERR_NODRIVER && !pMusicPort->m_bExternal)
  129. {
  130. LoadString(NULL, IDS_NOSOUNDDRIVER, sz, 300);
  131. MessageBox(hwndMain, sz, szTitle, MB_OK);
  132. }
  133. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ACTIVATEPORT;
  134. pMusicInfo->m_testResult.m_hr = hr;
  135. goto LEnd;
  136. }
  137. // Set autodownloading to be on
  138. BOOL fAutoDownload;
  139. fAutoDownload = TRUE;
  140. if (FAILED(hr = pPerformance->SetGlobalParam(GUID_PerfAutoDownload,
  141. &fAutoDownload, sizeof(BOOL))))
  142. {
  143. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETAUTODOWNLOAD;
  144. pMusicInfo->m_testResult.m_hr = hr;
  145. goto LEnd;
  146. }
  147. // Add the port to the performance
  148. if (FAILED(hr = pPerformance->AddPort(pPort)))
  149. {
  150. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ADDPORT;
  151. pMusicInfo->m_testResult.m_hr = hr;
  152. goto LEnd;
  153. }
  154. if (FAILED(hr = pPerformance->AssignPChannelBlock(0, pPort, 1)))
  155. {
  156. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ASSIGNPCHANNELBLOCK;
  157. pMusicInfo->m_testResult.m_hr = hr;
  158. goto LEnd;
  159. }
  160. if (FAILED(hr = SpewResourceToFile(TEXT("SGMT"), IDR_TSTSGMT, TEXT("Edge.sgt"))))
  161. {
  162. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE;
  163. pMusicInfo->m_testResult.m_hr = hr;
  164. goto LEnd;
  165. }
  166. if (FAILED(hr = SpewResourceToFile(TEXT("STYL"), IDR_TSTSTYL, TEXT("Edge.sty"))))
  167. {
  168. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE;
  169. pMusicInfo->m_testResult.m_hr = hr;
  170. goto LEnd;
  171. }
  172. // Create loader object
  173. if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicLoader, NULL,
  174. CLSCTX_INPROC, IID_IDirectMusicLoader, (VOID**)&pLoader)))
  175. {
  176. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMLOADER;
  177. pMusicInfo->m_testResult.m_hr = hr;
  178. goto LEnd;
  179. }
  180. // Set search path to temp dir to find segment and style:
  181. WCHAR wszDir[MAX_PATH];
  182. TCHAR szTempPath[MAX_PATH];
  183. GetTempPath(MAX_PATH, szTempPath);
  184. if( lstrlen(szTempPath) > 0 )
  185. szTempPath[lstrlen(szTempPath) - 1] = '\0';
  186. #ifdef UNICODE
  187. lstrcpy(wszDir, szTempPath);
  188. #else
  189. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTempPath, -1, wszDir, MAX_PATH);
  190. #endif
  191. if (FAILED(hr = pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wszDir, FALSE)))
  192. {
  193. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETSEARCHDIRECTORY;
  194. pMusicInfo->m_testResult.m_hr = hr;
  195. goto LEnd;
  196. }
  197. // Load the segment
  198. // now load the segment file.
  199. // sections load as type Segment, as do MIDI files, for example.
  200. DMUS_OBJECTDESC objDesc; // Object descriptor for pLoader->GetObject()
  201. objDesc.guidClass = CLSID_DirectMusicSegment;
  202. objDesc.dwSize = sizeof(DMUS_OBJECTDESC);
  203. wcscpy(objDesc.wszFileName, L"edge.sgt");
  204. objDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
  205. if (FAILED(hr = pLoader->GetObject(&objDesc, IID_IDirectMusicSegment, (VOID**)&pSegment)))
  206. {
  207. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_LOADERGETOBJECT;
  208. pMusicInfo->m_testResult.m_hr = hr;
  209. goto LEnd;
  210. }
  211. // Play the segment and wait. The DMUS_SEGF_BEAT indicates to play on the
  212. // next beat if there is a segment currently playing. The first 0 indicates
  213. // to play (on the next beat from) now.
  214. // The final NULL means do not return an IDirectMusicSegmentState* in
  215. // the last parameter.
  216. if (FAILED(hr = pPerformance->PlaySegment(pSegment, DMUS_SEGF_BEAT, 0, NULL)))
  217. {
  218. pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_PLAYSEGMENT;
  219. pMusicInfo->m_testResult.m_hr = hr;
  220. goto LEnd;
  221. }
  222. if (pMusicPort->m_bExternal)
  223. LoadString(NULL, IDS_EXTERNALMUSICPLAYING, sz, 300);
  224. else
  225. LoadString(NULL, IDS_MUSICPLAYING, sz, 300);
  226. MessageBox(hwndMain, sz, szTitle, MB_OK);
  227. pPerformance->Stop(pSegment, NULL, 0, 0);
  228. LEnd:
  229. DeleteTempFile(TEXT("Edge.sgt"));
  230. DeleteTempFile(TEXT("Edge.sty"));
  231. ReleasePpo(&pdm);
  232. ReleasePpo(&pPort);
  233. if (pPerformance != NULL)
  234. pPerformance->CloseDown();
  235. ReleasePpo(&pPerformance);
  236. ReleasePpo(&pLoader);
  237. if (bComInitialized)
  238. {
  239. // Release COM
  240. CoUninitialize();
  241. }
  242. if (pMusicInfo->m_testResult.m_iStepThatFailed == 0)
  243. {
  244. LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, 300);
  245. lstrcpy(pMusicInfo->m_testResult.m_szDescription, sz);
  246. LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, 300);
  247. lstrcpy(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz);
  248. }
  249. else
  250. {
  251. TCHAR szDesc[300];
  252. TCHAR szError[300];
  253. if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR +
  254. pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200))
  255. {
  256. LoadString(NULL, IDS_UNKNOWNERROR, sz, 300);
  257. lstrcpy(szDesc, sz);
  258. }
  259. LoadString(NULL, IDS_FAILUREFMT, sz, 300);
  260. BTranslateError(pMusicInfo->m_testResult.m_hr, szError);
  261. wsprintf(pMusicInfo->m_testResult.m_szDescription, sz,
  262. pMusicInfo->m_testResult.m_iStepThatFailed,
  263. szDesc, pMusicInfo->m_testResult.m_hr, szError);
  264. // Nonlocalized version:
  265. if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR_ENGLISH +
  266. pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200))
  267. {
  268. LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, 300);
  269. lstrcpy(szDesc, sz);
  270. }
  271. LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, 300);
  272. BTranslateError(pMusicInfo->m_testResult.m_hr, szError, TRUE);
  273. wsprintf(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz,
  274. pMusicInfo->m_testResult.m_iStepThatFailed,
  275. szDesc, pMusicInfo->m_testResult.m_hr, szError);
  276. }
  277. }
  278. /****************************************************************************
  279. *
  280. * SpewResourceToFile
  281. *
  282. ****************************************************************************/
  283. HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName)
  284. {
  285. TCHAR szTempPath[MAX_PATH];
  286. HRSRC hResInfo = NULL;
  287. HGLOBAL hResData = NULL;
  288. BYTE* pbData = NULL;
  289. HANDLE hfile;
  290. DWORD numBytes;
  291. DWORD numBytesWritten;
  292. GetTempPath(MAX_PATH, szTempPath);
  293. if( lstrlen(szTempPath) + lstrlen(pszFileName) < MAX_PATH )
  294. lstrcat(szTempPath, pszFileName);
  295. szTempPath[MAX_PATH-1]=0;
  296. if (NULL == (hResInfo = FindResource(NULL, MAKEINTRESOURCE(idRes), pszResType)))
  297. return E_FAIL;
  298. numBytes = SizeofResource(NULL, hResInfo);
  299. if (NULL == (hResData = LoadResource(NULL, hResInfo)))
  300. return E_FAIL;
  301. if (NULL == (pbData = (BYTE*)LockResource(hResData)))
  302. return E_FAIL;
  303. hfile = CreateFile(szTempPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  304. FILE_ATTRIBUTE_TEMPORARY, NULL);
  305. if (hfile == INVALID_HANDLE_VALUE)
  306. return E_FAIL;
  307. WriteFile(hfile, pbData, numBytes, &numBytesWritten, NULL);
  308. CloseHandle(hfile);
  309. return S_OK;
  310. }
  311. /****************************************************************************
  312. *
  313. * DeleteTempFile
  314. *
  315. ****************************************************************************/
  316. VOID DeleteTempFile(TCHAR* pszFileName)
  317. {
  318. TCHAR szTempPath[MAX_PATH];
  319. GetTempPath(MAX_PATH, szTempPath);
  320. if( lstrlen(szTempPath) + lstrlen(pszFileName) < MAX_PATH )
  321. lstrcat(szTempPath, pszFileName);
  322. szTempPath[MAX_PATH-1]=0;
  323. DeleteFile(szTempPath);
  324. }