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.

649 lines
23 KiB

  1. /****************************************************************************
  2. *
  3. * File: musinfo.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Mike Anderson (manders@microsoft.com)
  6. * Purpose: Gather information about DirectMusic
  7. *
  8. * (C) Copyright 1998 Microsoft Corp. All rights reserved.
  9. *
  10. ****************************************************************************/
  11. #include <tchar.h>
  12. #include <Windows.h>
  13. #include <multimon.h>
  14. #include <dmusicc.h>
  15. #include <dmusici.h>
  16. #include <stdio.h> // for sscanf
  17. #include "reginfo.h"
  18. #include "sysinfo.h"
  19. #include "dispinfo.h" // for TestResult
  20. #include "fileinfo.h" // for GetFileVersion
  21. #include "musinfo.h"
  22. #include "resource.h"
  23. static BOOL DoesDMHWAccelExist(IDirectMusic* pdm);
  24. static BOOL IsDMHWAccelEnabled(VOID);
  25. static HRESULT CheckRegistry(RegError** ppRegErrorFirst);
  26. /****************************************************************************
  27. *
  28. * GetBasicMusicInfo - Just create the MusicInfo object and note whether
  29. * a valid installation of DirectMusic is present.
  30. *
  31. ****************************************************************************/
  32. HRESULT GetBasicMusicInfo(MusicInfo** ppMusicInfo)
  33. {
  34. HRESULT hr = S_OK;
  35. MusicInfo* pMusicInfoNew;
  36. TCHAR szPath[MAX_PATH];
  37. TCHAR szVersion[100];
  38. DWORD dwMajor;
  39. DWORD dwMinor;
  40. DWORD dwRevision;
  41. DWORD dwBuild;
  42. pMusicInfoNew = new MusicInfo;
  43. if (pMusicInfoNew == NULL)
  44. return E_OUTOFMEMORY;
  45. *ppMusicInfo = pMusicInfoNew;
  46. ZeroMemory(pMusicInfoNew, sizeof(MusicInfo));
  47. GetSystemDirectory(szPath, MAX_PATH);
  48. lstrcat(szPath, TEXT("\\dmusic.dll"));
  49. WIN32_FIND_DATA findFileData;
  50. HANDLE hFind = FindFirstFile(szPath, &findFileData);
  51. if (hFind != INVALID_HANDLE_VALUE)
  52. {
  53. FindClose(hFind);
  54. // Only accept DX 6.1 or higher, since tests fail on 6.0's DirectMusic:
  55. if (SUCCEEDED(hr = GetFileVersion(szPath, szVersion, NULL, NULL, NULL)))
  56. {
  57. _stscanf(szVersion, TEXT("%d.%d.%d.%d"), &dwMajor, &dwMinor, &dwRevision, &dwBuild);
  58. if (dwMajor > 4 ||
  59. dwMajor >= 4 && dwMinor > 6 ||
  60. dwMajor >= 4 && dwMinor >= 6 && dwRevision >= 2)
  61. {
  62. pMusicInfoNew->m_bDMusicInstalled = TRUE;
  63. return S_OK;
  64. }
  65. }
  66. }
  67. return hr;
  68. }
  69. /****************************************************************************
  70. *
  71. * GetExtraMusicInfo - Get details of all ports, default port, and DLS path.
  72. *
  73. ****************************************************************************/
  74. HRESULT GetExtraMusicInfo(MusicInfo* pMusicInfo)
  75. {
  76. HRESULT hr = S_OK;
  77. IDirectMusic* pdm = NULL;
  78. LONG iPort;
  79. DMUS_PORTCAPS portCaps;
  80. MusicPort* pMusicPortNew = NULL;
  81. MusicPort* pMusicPort = NULL;
  82. GUID guidDefaultPort;
  83. if (pMusicInfo == NULL)
  84. return E_FAIL;
  85. BOOL bWasDisabled = FALSE;
  86. HKEY hkey = NULL;
  87. DWORD dwSize;
  88. DWORD dwType;
  89. DWORD dwData;
  90. // See if HW is disabled in registry, and if so, re-enable it (briefly)
  91. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  92. TEXT("SOFTWARE\\Microsoft\\DirectMusic"), 0, KEY_ALL_ACCESS, &hkey))
  93. {
  94. dwSize = sizeof(dwData);
  95. if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("DisableHWAcceleration"), NULL, &dwType, (BYTE *)&dwData, &dwSize))
  96. {
  97. if (dwData != 0)
  98. {
  99. bWasDisabled = TRUE;
  100. dwData = FALSE; // enable (un-disable) HW
  101. RegSetValueEx(hkey, TEXT("DisableHWAcceleration"), NULL,
  102. REG_DWORD, (BYTE *)&dwData, sizeof(dwData));
  103. }
  104. }
  105. // note: don't close hkey until end of function
  106. }
  107. // Initialize COM
  108. if (FAILED(hr = CoInitialize(NULL)))
  109. return hr;
  110. if (FAILED(hr = CoCreateInstance(CLSID_DirectMusic, NULL, CLSCTX_INPROC,
  111. IID_IDirectMusic, (VOID**)&pdm)))
  112. {
  113. goto LEnd;
  114. }
  115. pMusicInfo->m_bAccelerationExists = DoesDMHWAccelExist(pdm);
  116. if (bWasDisabled)
  117. {
  118. // re-disable HW
  119. dwData = TRUE; // disable HW
  120. RegSetValueEx(hkey, TEXT("DisableHWAcceleration"), NULL,
  121. REG_DWORD, (BYTE *)&dwData, sizeof(dwData));
  122. }
  123. if (hkey != NULL)
  124. RegCloseKey(hkey);
  125. pMusicInfo->m_bAccelerationEnabled = IsDMHWAccelEnabled();
  126. // Get default port
  127. if (FAILED(hr = pdm->GetDefaultPort(&guidDefaultPort)))
  128. goto LEnd;
  129. iPort = 0;
  130. portCaps.dwSize = sizeof(portCaps);
  131. while (TRUE)
  132. {
  133. hr = pdm->EnumPort(iPort, &portCaps);
  134. if (hr == S_FALSE)
  135. break;
  136. if (FAILED(hr))
  137. goto LEnd;
  138. pMusicPortNew = new MusicPort;
  139. if (pMusicPortNew == NULL)
  140. {
  141. hr = E_OUTOFMEMORY;
  142. goto LEnd;
  143. }
  144. ZeroMemory(pMusicPortNew, sizeof(MusicPort));
  145. if (guidDefaultPort == portCaps.guidPort)
  146. {
  147. // Special case: always put default device at head of the list.
  148. pMusicPortNew->m_pMusicPortNext = pMusicInfo->m_pMusicPortFirst;
  149. pMusicInfo->m_pMusicPortFirst = pMusicPortNew;
  150. }
  151. else if (pMusicInfo->m_pMusicPortFirst == NULL)
  152. {
  153. pMusicInfo->m_pMusicPortFirst = pMusicPortNew;
  154. }
  155. else
  156. {
  157. for (pMusicPort = pMusicInfo->m_pMusicPortFirst;
  158. pMusicPort->m_pMusicPortNext != NULL;
  159. pMusicPort = pMusicPort->m_pMusicPortNext)
  160. {
  161. }
  162. pMusicPort->m_pMusicPortNext = pMusicPortNew;
  163. }
  164. pMusicPortNew->m_guid = portCaps.guidPort;
  165. pMusicPortNew->m_dwMaxAudioChannels = portCaps.dwMaxAudioChannels;
  166. pMusicPortNew->m_dwMaxChannelGroups = portCaps.dwMaxChannelGroups;
  167. if (guidDefaultPort == portCaps.guidPort)
  168. pMusicPortNew->m_bDefaultPort = TRUE;
  169. pMusicPortNew->m_bSoftware = (portCaps.dwFlags & DMUS_PC_SOFTWARESYNTH ? TRUE : FALSE);
  170. pMusicPortNew->m_bKernelMode = (portCaps.dwType == DMUS_PORT_KERNEL_MODE ? TRUE : FALSE);
  171. pMusicPortNew->m_bUsesDLS = (portCaps.dwFlags & DMUS_PC_DLS ? TRUE : FALSE);
  172. pMusicPortNew->m_bExternal = (portCaps.dwFlags & DMUS_PC_EXTERNAL ? TRUE : FALSE);
  173. pMusicPortNew->m_bOutputPort = (portCaps.dwClass == DMUS_PC_OUTPUTCLASS);
  174. #ifdef UNICODE
  175. lstrcpy(pMusicPortNew->m_szDescription, portCaps.wszDescription);
  176. #else
  177. WideCharToMultiByte(CP_ACP, 0, portCaps.wszDescription, -1, pMusicPortNew->m_szDescription, sizeof pMusicPortNew->m_szDescription, 0, 0);
  178. #endif
  179. iPort++;
  180. }
  181. // Get General Midi DLS File Path and store it in first MusicPort
  182. TCHAR szGMFilePath[MAX_PATH];
  183. DWORD dwBufferLen;
  184. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectMusic"), 0, KEY_READ, &hkey))
  185. {
  186. dwBufferLen = MAX_PATH;
  187. if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("GMFilePath"), 0, NULL, (LPBYTE)szGMFilePath, &dwBufferLen))
  188. {
  189. ExpandEnvironmentStrings(szGMFilePath, pMusicInfo->m_szGMFilePath, MAX_PATH);
  190. GetRiffFileVersion(pMusicInfo->m_szGMFilePath, pMusicInfo->m_szGMFileVersion);
  191. }
  192. RegCloseKey(hkey);
  193. }
  194. LEnd:
  195. if (pdm != NULL)
  196. pdm->Release();
  197. // Release COM
  198. CoUninitialize();
  199. if (FAILED(hr = CheckRegistry(&pMusicInfo->m_pRegErrorFirst)))
  200. return hr;
  201. return hr;
  202. }
  203. /****************************************************************************
  204. *
  205. * DoesDMHWAccelExist
  206. *
  207. ****************************************************************************/
  208. BOOL DoesDMHWAccelExist(IDirectMusic* pdm)
  209. {
  210. BOOL bHWAccel = FALSE;
  211. // See if default port is hardware
  212. GUID guidDefaultPort;
  213. LONG iPort;
  214. DMUS_PORTCAPS portCaps;
  215. HRESULT hr;
  216. if (SUCCEEDED(pdm->GetDefaultPort(&guidDefaultPort)))
  217. {
  218. iPort = 0;
  219. portCaps.dwSize = sizeof(portCaps);
  220. while (TRUE)
  221. {
  222. hr = pdm->EnumPort(iPort, &portCaps);
  223. if (hr == S_FALSE)
  224. break;
  225. if (FAILED(hr))
  226. break;
  227. if (guidDefaultPort == portCaps.guidPort)
  228. {
  229. if ((portCaps.dwFlags & DMUS_PC_SOFTWARESYNTH) == 0)
  230. bHWAccel = TRUE;
  231. break;
  232. }
  233. iPort++;
  234. }
  235. }
  236. return bHWAccel;
  237. }
  238. /****************************************************************************
  239. *
  240. * IsDMHWAccelEnabled
  241. *
  242. ****************************************************************************/
  243. BOOL IsDMHWAccelEnabled(VOID)
  244. {
  245. HKEY hkey;
  246. DWORD dwSize;
  247. DWORD dwType;
  248. DWORD dwData;
  249. BOOL bIsDMHWAccelEnabled = TRUE;
  250. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  251. TEXT("SOFTWARE\\Microsoft\\DirectMusic"), 0, KEY_ALL_ACCESS, &hkey))
  252. {
  253. dwSize = sizeof(dwData);
  254. if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("DisableHWAcceleration"), NULL, &dwType, (BYTE *)&dwData, &dwSize))
  255. {
  256. if (dwData != 0)
  257. bIsDMHWAccelEnabled = FALSE;
  258. }
  259. RegCloseKey( hkey );
  260. }
  261. return bIsDMHWAccelEnabled;
  262. }
  263. /****************************************************************************
  264. *
  265. * CheckRegistryClass - Helper function for CheckRegistry
  266. *
  267. ****************************************************************************/
  268. HRESULT CheckRegistryClass(RegError** ppRegErrorFirst, TCHAR* pszGuid,
  269. TCHAR* pszName, TCHAR* pszLeaf, TCHAR* pszOptLeaf2 = NULL )
  270. {
  271. HRESULT hr;
  272. HKEY HKCR = HKEY_CLASSES_ROOT;
  273. TCHAR szKey[200];
  274. TCHAR szData[200];
  275. wsprintf(szKey, TEXT("CLSID\\%s"), pszGuid);
  276. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszName)))
  277. return hr;
  278. wsprintf(szKey, TEXT("CLSID\\%s\\InprocServer32"), pszGuid);
  279. if( pszOptLeaf2 == NULL )
  280. {
  281. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszLeaf, CRF_LEAF)))
  282. return hr;
  283. }
  284. else
  285. {
  286. HRESULT hrReg1, hrReg2;
  287. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszLeaf, CRF_LEAF, &hrReg1 )))
  288. return hr;
  289. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszOptLeaf2, CRF_LEAF, &hrReg2 )))
  290. return hr;
  291. if( hrReg1 == RET_NOERROR || hrReg2 == RET_NOERROR )
  292. {
  293. // If one succeeded, then the other failed, and they both can't succeed.
  294. // So delete the first error, since it isn't needed.
  295. RegError* pRegErrorDelete = *ppRegErrorFirst;
  296. *ppRegErrorFirst = (*ppRegErrorFirst)->m_pRegErrorNext;
  297. delete pRegErrorDelete;
  298. }
  299. }
  300. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT("ThreadingModel"), TEXT("Both"))))
  301. return hr;
  302. wsprintf(szKey, TEXT("CLSID\\%s\\ProgID"), pszGuid);
  303. wsprintf(szData, TEXT("Microsoft.%s.1"), pszName);
  304. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), szData)))
  305. return hr;
  306. wsprintf(szKey, TEXT("CLSID\\%s\\VersionIndependentProgID"), pszGuid);
  307. wsprintf(szData, TEXT("Microsoft.%s"), pszName);
  308. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), szData)))
  309. return hr;
  310. wsprintf(szKey, TEXT("Microsoft.%s"), pszName);
  311. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszName)))
  312. return hr;
  313. wsprintf(szKey, TEXT("Microsoft.%s\\CLSID"), pszName);
  314. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszGuid)))
  315. return hr;
  316. wsprintf(szKey, TEXT("Microsoft.%s\\CurVer"), pszName);
  317. wsprintf(szData, TEXT("Microsoft.%s.1"), pszName);
  318. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), szData)))
  319. return hr;
  320. wsprintf(szKey, TEXT("Microsoft.%s.1"), pszName);
  321. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszName)))
  322. return hr;
  323. wsprintf(szKey, TEXT("Microsoft.%s.1\\CLSID"), pszName);
  324. if (FAILED(hr = CheckRegString(ppRegErrorFirst, HKCR, szKey, TEXT(""), pszGuid)))
  325. return hr;
  326. return S_OK;
  327. }
  328. /****************************************************************************
  329. *
  330. * CheckRegistry
  331. *
  332. ****************************************************************************/
  333. HRESULT CheckRegistry(RegError** ppRegErrorFirst)
  334. {
  335. HRESULT hr;
  336. HKEY HKCR = HKEY_CLASSES_ROOT;
  337. TCHAR szVersion[100];
  338. HKEY hkey;
  339. DWORD cbData;
  340. ULONG ulType;
  341. DWORD dwMajor = 0;
  342. DWORD dwMinor = 0;
  343. DWORD dwRevision = 0;
  344. DWORD dwBuild = 0;
  345. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectX"),
  346. 0, KEY_READ, &hkey))
  347. {
  348. cbData = 100;
  349. RegQueryValueEx(hkey, TEXT("Version"), 0, &ulType, (LPBYTE)szVersion, &cbData);
  350. RegCloseKey(hkey);
  351. if (lstrlen(szVersion) > 6 &&
  352. lstrlen(szVersion) < 20)
  353. {
  354. _stscanf(szVersion, TEXT("%d.%d.%d.%d"), &dwMajor, &dwMinor, &dwRevision, &dwBuild);
  355. }
  356. }
  357. // No registry checking on DX versions before DX7
  358. if (dwMinor < 7)
  359. return S_OK;
  360. // DirectMusicCollection
  361. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{480FF4B0-28B2-11D1-BEF7-00C04FBF8FEF}"), TEXT("DirectMusicCollection"), TEXT("dmusic.dll"), TEXT("dmusicd.dll") )))
  362. return hr;
  363. // DirectMusic
  364. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{636B9F10-0C7D-11D1-95B2-0020AFDC7421}"), TEXT("DirectMusic"), TEXT("dmusic.dll"), TEXT("dmusicd.dll") )))
  365. return hr;
  366. // DirectMusicSection
  367. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{3F037241-414E-11D1-A7CE-00A0C913F73C}"), TEXT("DirectMusicSection"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  368. return hr;
  369. // DirectMusicSynth
  370. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{58C2B4D0-46E7-11D1-89AC-00A0C9054129}"), TEXT("DirectMusicSynth"), TEXT("dmsynth.dll"), TEXT("dmsynthd.dll") )))
  371. return hr;
  372. // DirectMusicBand
  373. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{79BA9E00-B6EE-11D1-86BE-00C04FBF8FEF}"), TEXT("DirectMusicBand"), TEXT("dmband.dll"), TEXT("dmbandd.dll") )))
  374. return hr;
  375. // DirectMusicSynthSink
  376. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{AEC17CE3-A514-11D1-AFA6-00AA0024D8B6}"), TEXT("DirectMusicSynthSink"), TEXT("dmsynth.dll"), TEXT("dmsynthd.dll") )))
  377. return hr;
  378. // DirectMusicPerformance
  379. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2881-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicPerformance"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  380. return hr;
  381. // DirectMusicSegment
  382. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2882-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicSegment"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  383. return hr;
  384. // DirectMusicSegmentState
  385. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2883-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicSegmentState"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  386. return hr;
  387. // DirectMusicGraph
  388. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2884-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicGraph"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  389. return hr;
  390. // DirectMusicTempoTrack
  391. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2885-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicTempoTrack"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  392. return hr;
  393. // DirectMusicSeqTrack
  394. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2886-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicSeqTrack"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  395. return hr;
  396. // DirectMusicSysExTrack
  397. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2887-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicSysExTrack"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  398. return hr;
  399. // DirectMusicTimeSigTrack
  400. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2888-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicTimeSigTrack"), TEXT("dmime.dll"), TEXT("dmimed.dll") )))
  401. return hr;
  402. // DirectMusicStyle
  403. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288a-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicStyle"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  404. return hr;
  405. // DirectMusicChordTrack
  406. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288b-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicChordTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  407. return hr;
  408. // DirectMusicCommandTrack
  409. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288c-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicCommandTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  410. return hr;
  411. // DirectMusicStyleTrack
  412. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288d-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicStyleTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  413. return hr;
  414. // DirectMusicMotifTrack
  415. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288e-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicMotifTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  416. return hr;
  417. // DirectMusicChordMap
  418. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC288f-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicChordMap"), TEXT("dmcompos.dll"), TEXT("dmcompod.dll") )))
  419. return hr;
  420. // DirectMusicComposer
  421. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2890-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicComposer"), TEXT("dmcompos.dll"), TEXT("dmcompod.dll") )))
  422. return hr;
  423. // DirectMusicLoader
  424. // This check fails when upgrading Win98SE (or possibly any system with DX 6.1 or 6.1a) to Win2000 RC2. So skip it
  425. // if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2892-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicLoader"), TEXT("dmloader.dll"))))
  426. // return hr;
  427. // DirectMusicBandTrack
  428. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2894-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicBandTrack"), TEXT("dmband.dll"), TEXT("dmbandd.dll") )))
  429. return hr;
  430. // DirectMusicChordMapTrack
  431. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2896-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicChordMapTrack"), TEXT("dmcompos.dll"), TEXT("dmcompod.dll") )))
  432. return hr;
  433. // DirectMusicAuditionTrack
  434. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2897-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicAuditionTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  435. return hr;
  436. // DirectMusicMuteTrack
  437. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D2AC2898-B39B-11D1-8704-00600893B1BD}"), TEXT("DirectMusicMuteTrack"), TEXT("dmstyle.dll"), TEXT("dmstyled.dll") )))
  438. return hr;
  439. // DirectMusicTemplate
  440. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{D30BCC65-60E8-11D1-A7CE-00A0C913F73C}"), TEXT("DirectMusicTemplate"), TEXT("dmcompos.dll"), TEXT("dmcompod.dll") )))
  441. return hr;
  442. // DirectMusicSignPostTrack
  443. if (FAILED(hr = CheckRegistryClass(ppRegErrorFirst, TEXT("{F17E8672-C3B4-11D1-870B-00600893B1BD}"), TEXT("DirectMusicSignPostTrack"), TEXT("dmcompos.dll"), TEXT("dmcompod.dll") )))
  444. return hr;
  445. return S_OK;
  446. }
  447. /****************************************************************************
  448. *
  449. * DestroyMusicInfo
  450. *
  451. ****************************************************************************/
  452. VOID DestroyMusicInfo(MusicInfo* pMusicInfo)
  453. {
  454. if( pMusicInfo )
  455. {
  456. DestroyReg( &pMusicInfo->m_pRegErrorFirst );
  457. MusicPort* pMusicPort;
  458. MusicPort* pMusicPortNext;
  459. for (pMusicPort = pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL;
  460. pMusicPort = pMusicPortNext)
  461. {
  462. pMusicPortNext = pMusicPort->m_pMusicPortNext;
  463. delete pMusicPort;
  464. }
  465. delete pMusicInfo;
  466. }
  467. }
  468. /****************************************************************************
  469. *
  470. * DiagnoseMusic
  471. *
  472. ****************************************************************************/
  473. VOID DiagnoseMusic(SysInfo* pSysInfo, MusicInfo* pMusicInfo)
  474. {
  475. TCHAR szMessage[500];
  476. BOOL bProblem = FALSE;
  477. _tcscpy( pSysInfo->m_szMusicNotes, TEXT("") );
  478. _tcscpy( pSysInfo->m_szMusicNotesEnglish, TEXT("") );
  479. // Report any problems
  480. if (pMusicInfo == NULL || pMusicInfo->m_pMusicPortFirst == NULL)
  481. {
  482. LoadString(NULL, IDS_NOPORTS, szMessage, 500);
  483. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  484. LoadString(NULL, IDS_NOPORTS_ENGLISH, szMessage, 500);
  485. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  486. bProblem = TRUE;
  487. }
  488. else if (lstrlen(pMusicInfo->m_szGMFilePath) == 0)
  489. {
  490. LoadString(NULL, IDS_NOGMDLS, szMessage, 500);
  491. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  492. LoadString(NULL, IDS_NOGMDLS_ENGLISH, szMessage, 500);
  493. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  494. bProblem = TRUE;
  495. }
  496. else
  497. {
  498. WIN32_FIND_DATA findFileData;
  499. HANDLE hFind = FindFirstFile(pMusicInfo->m_szGMFilePath, &findFileData);
  500. if (hFind == INVALID_HANDLE_VALUE)
  501. {
  502. LoadString(NULL, IDS_GMDLSFILEMISSING, szMessage, 500);
  503. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  504. LoadString(NULL, IDS_GMDLSFILEMISSING_ENGLISH, szMessage, 500);
  505. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  506. bProblem = TRUE;
  507. }
  508. else
  509. {
  510. FindClose(hFind);
  511. }
  512. }
  513. if (pMusicInfo && pMusicInfo->m_pRegErrorFirst != NULL)
  514. {
  515. LoadString(NULL, IDS_REGISTRYPROBLEM, szMessage, 500);
  516. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  517. LoadString(NULL, IDS_REGISTRYPROBLEM_ENGLISH, szMessage, 500);
  518. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  519. bProblem = TRUE;
  520. }
  521. // Show test results or instructions to run test:
  522. if (pMusicInfo && pMusicInfo->m_testResult.m_bStarted)
  523. {
  524. LoadString(NULL, IDS_DMUSICRESULTS, szMessage, 500);
  525. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  526. _tcscat( pSysInfo->m_szMusicNotes, pMusicInfo->m_testResult.m_szDescription );
  527. _tcscat( pSysInfo->m_szMusicNotes, TEXT("\r\n") );
  528. LoadString(NULL, IDS_DMUSICRESULTS_ENGLISH, szMessage, 500);
  529. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  530. _tcscat( pSysInfo->m_szMusicNotesEnglish, pMusicInfo->m_testResult.m_szDescriptionEnglish );
  531. _tcscat( pSysInfo->m_szMusicNotesEnglish, TEXT("\r\n") );
  532. bProblem = TRUE;
  533. }
  534. else
  535. {
  536. LoadString(NULL, IDS_DMUSICINSTRUCTIONS, szMessage, 500);
  537. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  538. LoadString(NULL, IDS_DMUSICINSTRUCTIONS_ENGLISH, szMessage, 500);
  539. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  540. }
  541. if (!bProblem)
  542. {
  543. LoadString(NULL, IDS_NOPROBLEM, szMessage, 500);
  544. _tcscat( pSysInfo->m_szMusicNotes, szMessage );
  545. LoadString(NULL, IDS_NOPROBLEM_ENGLISH, szMessage, 500);
  546. _tcscat( pSysInfo->m_szMusicNotesEnglish, szMessage );
  547. }
  548. }