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.

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