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.

4998 lines
171 KiB

  1. /****************************************************************************
  2. *
  3. * File: main.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Mike Anderson (manders@microsoft.com)
  6. * Purpose: Main file for DxDiag.
  7. *
  8. * (C) Copyright 1998 Microsoft Corp. All rights reserved.
  9. *
  10. * DxDiag Command-line options:
  11. * <none> : Run with graphical user interface
  12. * -ghost : Show Ghost Display Devices option (this flag must come next)
  13. * -bugreport : GUI, go straight to bug report page/dialog
  14. * -saveonly : GUI, just choose where to save text file, save, then exit
  15. * -d : No GUI, generate comma-separated-values (csv) file
  16. * -p : No GUI, generate text file named dxdiag.txt
  17. * <path> : No GUI, generate text file named <path>
  18. *
  19. ****************************************************************************/
  20. #define STRICT
  21. #include <tchar.h>
  22. #include <Windows.h>
  23. #include <basetsd.h>
  24. #include <process.h>
  25. #include <commctrl.h>
  26. #include <richedit.h>
  27. #include <commdlg.h>
  28. #include <stdio.h>
  29. #include <shellapi.h>
  30. #include <mmsystem.h>
  31. #include <wbemidl.h>
  32. #include <objbase.h>
  33. #include <d3d.h>
  34. #include <dsound.h>
  35. #include <dmerror.h>
  36. #include <dplay.h>
  37. #include <shlobj.h>
  38. #include <shfolder.h>
  39. #include "resource.h"
  40. #include "reginfo.h"
  41. #include "sysinfo.h"
  42. #include "fileinfo.h"
  43. #include "dispinfo.h"
  44. #include "sndinfo.h"
  45. #include "musinfo.h"
  46. #include "showinfo.h"
  47. #include "inptinfo.h"
  48. #include "netinfo.h"
  49. #include "testdd.h"
  50. #include "testagp.h"
  51. #include "testd3d8.h"
  52. #include "testsnd.h"
  53. #include "testmus.h"
  54. #include "testnet.h"
  55. #include "save.h"
  56. #include "ghost.h"
  57. #define WM_COMMAND_REAL (WM_APP+2)
  58. #define WM_QUERYSKIP (WM_APP+3)
  59. #define WM_QUERYSKIP_REAL (WM_APP+4)
  60. #define WM_NETMEETINGWARN (WM_APP+5)
  61. #define WM_NETMEETINGWARN_REAL (WM_APP+6)
  62. #define WM_REPORTERROR (WM_APP+7)
  63. #define WM_REPORTERROR_REAL (WM_APP+8)
  64. #define WM_APP_PROGRESS (WM_APP+10)
  65. struct UI_MSG_NODE
  66. {
  67. UINT message;
  68. WPARAM wparam;
  69. LPARAM lparam;
  70. UI_MSG_NODE* pNext;
  71. };
  72. struct DXFILE_SORT_INFO
  73. {
  74. LONG nSortDirection;
  75. DWORD dwColumnToSort;
  76. };
  77. // This is the only global function in this file:
  78. BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE);
  79. static BOOL OldWindowsVersion(VOID);
  80. static VOID ReportError(LONG idsDescription, HRESULT hr = S_OK);
  81. static VOID ReportErrorReal(LONG idsDescription, HRESULT hr);
  82. static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  83. static INT_PTR CALLBACK PageDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  84. static HRESULT CreateTabs(HWND hwndTabs);
  85. static HRESULT CleanupPage(HWND hwndTabs, INT iPage);
  86. static HRESULT SetupPage(HWND hwndTabs, INT iPage);
  87. static HRESULT SetupHelpPage(HWND hwndTabs);
  88. static VOID ShowBullets(VOID);
  89. static VOID HideBullets(VOID);
  90. static HRESULT SetupDxFilesPage(VOID);
  91. static HRESULT SetupDisplayPage(LONG iDisplay);
  92. static HRESULT SetupSoundPage(LONG iSound);
  93. static HRESULT SetupMusicPage(VOID);
  94. static HRESULT SetupInputPage(VOID);
  95. static HRESULT SetupInputDevices9x(VOID);
  96. static HRESULT SetupInputDevicesNT(VOID);
  97. static HRESULT SetupNetworkPage(VOID);
  98. static HRESULT SetupStillStuckPage(VOID);
  99. static HRESULT CreateFileInfoColumns(HWND hwndList, BOOL bDrivers);
  100. static HRESULT CreateMusicColumns(HWND hwndList);
  101. static HRESULT AddFileInfo(HWND hwndList, FileInfo* pFileInfoFirst, BOOL bDrivers = FALSE);
  102. static HRESULT AddMusicPortInfo(HWND hwndList, MusicInfo* pMusicInfo);
  103. static HRESULT ScanSystem(VOID);
  104. static VOID SaveInfo(VOID);
  105. static VOID ToggleDDAccel(VOID);
  106. static VOID ToggleD3DAccel(VOID);
  107. static VOID ToggleAGPSupport(VOID);
  108. static VOID ToggleDMAccel(VOID);
  109. static VOID ReportBug(VOID);
  110. static INT_PTR CALLBACK BugDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  111. static VOID SaveAndSendBug(TCHAR* szPath);
  112. static VOID OverrideDDRefresh(VOID);
  113. static INT_PTR CALLBACK OverrideRefreshDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  114. static VOID ShowHelp(VOID);
  115. static VOID RestoreDrivers(VOID);
  116. static BOOL BCanRestoreDrivers(VOID);
  117. static VOID HandleSndSliderChange(INT nScrollCode, INT nPos);
  118. static VOID TroubleShoot( BOOL bTroubleShootSound );
  119. static BOOL QueryCrashProtection( TCHAR* strKey, TCHAR* strValue, int nSkipQuestionID, DWORD dwCurrentStep );
  120. static VOID EnterCrashProtection( TCHAR* strKey, TCHAR* strValue, DWORD dwCurrentStep );
  121. static VOID LeaveCrashProtection( TCHAR* strKey, TCHAR* strValue, DWORD dwCurrentStep );
  122. static VOID TestD3D(HWND hwndMain, DisplayInfo* pDisplayInfo);
  123. static BOOL GetTxtPath( TCHAR* strTxtPath );
  124. static VOID SetTxtPath( TCHAR* strTxtPath );
  125. static UINT WINAPI UIThreadProc( LPVOID lpParameter );
  126. static BOOL s_bGUI = FALSE;
  127. static BOOL s_bGhost = FALSE;
  128. static BOOL s_bBugReport = FALSE;
  129. static BOOL s_bSaveOnly = FALSE;
  130. static HWND s_hwndMain = NULL;
  131. static HWND s_hwndCurPage = NULL;
  132. static HHOOK s_hHook = NULL;
  133. static LONG s_lwCurPage = -1;
  134. static LONG s_iPageDisplayFirst = -1;
  135. static LONG s_iPageSoundFirst = -1;
  136. static LONG s_iPageMusic = -1;
  137. static LONG s_iPageInput = -1;
  138. static LONG s_iPageNetwork = -1;
  139. static LONG s_iPageStillStuck = -1;
  140. static HIMAGELIST s_himgList = NULL;
  141. static SysInfo s_sysInfo;
  142. static FileInfo* s_pDxWinComponentsFileInfoFirst = NULL;
  143. static FileInfo* s_pDxComponentsFileInfoFirst = NULL;
  144. static DisplayInfo* s_pDisplayInfoFirst = NULL;
  145. static LONG s_numDisplayInfo = 0;
  146. static SoundInfo* s_pSoundInfoFirst = NULL;
  147. static LONG s_numSoundInfo = 0;
  148. static MusicInfo* s_pMusicInfo = NULL;
  149. static InputInfo* s_pInputInfo = NULL;
  150. static NetInfo* s_pNetInfo = NULL;
  151. static ShowInfo* s_pShowInfo = NULL;
  152. static CRITICAL_SECTION s_cs;
  153. static DWORD s_dwMainThreadID = 0;
  154. static HANDLE s_hUIThread = NULL;
  155. static HANDLE s_hQuerySkipEvent = NULL;
  156. static DWORD s_nSkipComponent = 0;
  157. static BOOL s_bQuerySkipAllow = FALSE;
  158. static UI_MSG_NODE* s_pUIMsgHead = NULL;
  159. static HANDLE s_hUIMsgEvent = NULL;
  160. static BOOL s_bScanDone = FALSE;
  161. static DXFILE_SORT_INFO s_sortInfo;
  162. static HINSTANCE g_hInst = NULL;
  163. static BOOL s_bUseSystemInfo = TRUE;
  164. static BOOL s_bUseDisplay = TRUE;
  165. static BOOL s_bUseDSound = TRUE;
  166. static BOOL s_bUseDMusic = TRUE;
  167. static BOOL s_bUseDInput = TRUE;
  168. static BOOL s_bUseDPlay = TRUE;
  169. static BOOL s_bUseDShow = TRUE;
  170. class CWMIHelper
  171. {
  172. public:
  173. CWMIHelper();
  174. ~CWMIHelper();
  175. };
  176. CWMIHelper g_WMIHelper;
  177. IWbemServices* g_pIWbemServices;
  178. /****************************************************************************
  179. *
  180. * WinMain - Entry point for DxDiag program
  181. *
  182. * Command-line options:
  183. * <none> : Run with graphical user interface
  184. * -ghost : Show Ghost Display Devices option (this flag must come next)
  185. * -bugreport : GUI, go straight to bug report page/dialog
  186. * -saveonly : GUI, just choose where to save text file, save, then exit
  187. * -l : No GUI, generate shortcut to DxDiag, then exit
  188. * -d : No GUI, generate comma-separated-values (csv) file
  189. * -p : No GUI, generate text file named dxdiag.txt
  190. * <path> : No GUI, generate text file named <path>
  191. *
  192. ****************************************************************************/
  193. INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
  194. LPSTR lpCmdLine, INT nCmdShow)
  195. {
  196. HRESULT hr;
  197. HINSTANCE hinstRichEdit = NULL;
  198. g_hInst = hinstance;
  199. s_hQuerySkipEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  200. s_hUIMsgEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  201. InitializeCriticalSection( &s_cs );
  202. #ifdef UNICODE
  203. if (!BIsPlatformNT())
  204. {
  205. // Unicode version only runs on WinNT.
  206. // Can't use ReportError because it calls Unicode APIs
  207. CHAR szDescription[MAX_PATH];
  208. CHAR szMessage[MAX_PATH];
  209. CHAR szFmt2[MAX_PATH];
  210. CHAR szTitle[MAX_PATH];
  211. LoadStringA(NULL, IDS_UNICODEREQUIRESNT, szDescription, MAX_PATH);
  212. LoadStringA(NULL, IDS_ERRORFMT2, szFmt2, MAX_PATH);
  213. LoadStringA(NULL, IDS_ERRORTITLE, szTitle, MAX_PATH);
  214. wsprintfA(szMessage, szFmt2, szDescription);
  215. MessageBoxA(s_hwndMain, szMessage, szTitle, MB_OK);
  216. return 1;
  217. }
  218. #endif
  219. TCHAR* pszCmdLine = GetCommandLine();
  220. // Skip past program name (first token in command line).
  221. if (*pszCmdLine == TEXT('"')) // Check for and handle quoted program name
  222. {
  223. pszCmdLine++;
  224. // Scan, and skip over, subsequent characters until another
  225. // double-quote or a null is encountered
  226. while (*pszCmdLine && (*pszCmdLine != TEXT('"')))
  227. pszCmdLine++;
  228. // If we stopped on a double-quote (usual case), skip over it.
  229. if (*pszCmdLine == TEXT('"'))
  230. pszCmdLine++;
  231. }
  232. else // First token wasn't a quote
  233. {
  234. while (*pszCmdLine > TEXT(' '))
  235. pszCmdLine++;
  236. }
  237. // Skip past any white space preceeding the second token.
  238. while (*pszCmdLine && (*pszCmdLine <= TEXT(' ')))
  239. pszCmdLine++;
  240. // Check for ghost flag (which must appear before any
  241. // other flags except -media due to this implementation)
  242. if (_tcsstr(pszCmdLine, TEXT("-ghost")) != NULL)
  243. {
  244. s_bGhost = TRUE;
  245. pszCmdLine += lstrlen(TEXT("-ghost"));
  246. // Skip past any white space
  247. while (*pszCmdLine && (*pszCmdLine <= TEXT(' ')))
  248. pszCmdLine++;
  249. }
  250. // Check command line to determine whether to run in GUI mode
  251. if (lstrcmp(pszCmdLine, TEXT("")) == 0)
  252. s_bGUI = TRUE;
  253. if (lstrcmp(pszCmdLine, TEXT("-bugreport")) == 0)
  254. {
  255. s_bGUI = TRUE;
  256. s_bBugReport = TRUE;
  257. }
  258. if (lstrcmp(pszCmdLine, TEXT("-saveonly")) == 0)
  259. {
  260. s_bGUI = TRUE;
  261. s_bSaveOnly = TRUE;
  262. }
  263. // Check for pre-Win95 or pre-NT5
  264. if (OldWindowsVersion())
  265. {
  266. ReportError(IDS_OLDWINDOWSVERSION);
  267. return 1;
  268. }
  269. if (s_bBugReport || s_bSaveOnly)
  270. {
  271. // Save a text file using GUI and exit
  272. // ******* GetSystemInfo (SI:1) ********
  273. if( s_bUseSystemInfo )
  274. {
  275. s_bUseSystemInfo = QueryCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, IDS_SI, 1 );
  276. if( s_bUseSystemInfo )
  277. {
  278. EnterCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  279. GetSystemInfo(&s_sysInfo);
  280. LeaveCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  281. }
  282. }
  283. // ******* GetBasicDisplayInfo (DD:1) ********
  284. if( s_bUseDisplay )
  285. {
  286. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 1 );
  287. if( s_bUseDisplay )
  288. {
  289. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  290. if (FAILED(hr = GetBasicDisplayInfo(&s_pDisplayInfoFirst)))
  291. ReportError(IDS_NOBASICDISPLAYINFO, hr);
  292. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  293. }
  294. }
  295. // ******* GetBasicSoundInfo (DS:1) ********
  296. if( s_bUseDSound )
  297. {
  298. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 1 );
  299. if( s_bUseDSound )
  300. {
  301. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  302. if (FAILED(hr = GetBasicSoundInfo(&s_pSoundInfoFirst)))
  303. ReportError(IDS_NOBASICSOUNDINFO, hr); // (but keep running)
  304. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  305. }
  306. }
  307. // ******* GetBasicMusicInfo (DM:1) ********
  308. if( s_bUseDMusic )
  309. {
  310. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 1 );
  311. if( s_bUseDMusic )
  312. {
  313. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  314. if (FAILED(hr = GetBasicMusicInfo(&s_pMusicInfo)))
  315. ReportError(IDS_NOBASICMUSICINFO, hr); // (but keep running)
  316. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  317. }
  318. }
  319. // ******* ScanSystem ********
  320. ScanSystem();
  321. if (s_bBugReport)
  322. {
  323. DialogBox(hinstance, MAKEINTRESOURCE(IDD_BUGINFO), NULL, BugDialogProc);
  324. }
  325. else // s_bSaveOnly
  326. {
  327. SaveInfo();
  328. TCHAR szTitle[MAX_PATH];
  329. TCHAR szMessage[MAX_PATH];
  330. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  331. LoadString(NULL, IDS_SAVEDONE, szMessage, MAX_PATH);
  332. MessageBox(NULL, szMessage, szTitle, MB_OK);
  333. }
  334. }
  335. else if (!s_bGUI)
  336. {
  337. // Save a text file with no GUI and exit
  338. TCHAR szPath[MAX_PATH];
  339. // ******* GetSystemInfo (SI:1) ********
  340. if( s_bUseSystemInfo )
  341. {
  342. s_bUseSystemInfo = QueryCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, IDS_SI, 1 );
  343. if( s_bUseSystemInfo )
  344. {
  345. EnterCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  346. GetSystemInfo(&s_sysInfo);
  347. LeaveCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  348. }
  349. }
  350. // ******* GetBasicDisplayInfo (DD:1) ********
  351. if( s_bUseDisplay )
  352. {
  353. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 1 );
  354. if( s_bUseDisplay )
  355. {
  356. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  357. if (FAILED(hr = GetBasicDisplayInfo(&s_pDisplayInfoFirst)))
  358. ReportError(IDS_NOBASICDISPLAYINFO, hr);
  359. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  360. }
  361. }
  362. // ******* GetBasicSoundInfo (DS:1) ********
  363. if( s_bUseDSound )
  364. {
  365. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 1 );
  366. if( s_bUseDSound )
  367. {
  368. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  369. if (FAILED(hr = GetBasicSoundInfo(&s_pSoundInfoFirst)))
  370. ReportError(IDS_NOBASICSOUNDINFO, hr); // (but keep running)
  371. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  372. }
  373. }
  374. // ******* GetBasicMusicInfo (DM:1) ********
  375. if( s_bUseDMusic )
  376. {
  377. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 1 );
  378. if( s_bUseDMusic )
  379. {
  380. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  381. if (FAILED(hr = GetBasicMusicInfo(&s_pMusicInfo)))
  382. ReportError(IDS_NOBASICMUSICINFO, hr); // (but keep running)
  383. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  384. }
  385. }
  386. // ******* ScanSystem ********
  387. ScanSystem();
  388. if (_tcsicmp(pszCmdLine, TEXT("-d")) == 0)
  389. {
  390. wsprintf(szPath, TEXT("%s_%02d%02d%d_%02d%02d_Config.csv"),
  391. s_sysInfo.m_szMachine, s_sysInfo.m_time.wMonth,
  392. s_sysInfo.m_time.wDay, s_sysInfo.m_time.wYear,
  393. s_sysInfo.m_time.wHour, s_sysInfo.m_time.wMinute);
  394. if (FAILED(hr = SaveAllInfoCsv(szPath, &s_sysInfo,
  395. s_pDxComponentsFileInfoFirst,
  396. s_pDisplayInfoFirst, s_pSoundInfoFirst, s_pInputInfo)))
  397. {
  398. ReportError(IDS_PROBLEMSAVING, hr);
  399. goto LCleanup;
  400. }
  401. }
  402. else
  403. {
  404. if (_tcsicmp(pszCmdLine, TEXT("-p")) == 0)
  405. lstrcpy(szPath, TEXT("DxDiag.txt"));
  406. else
  407. lstrcpy(szPath, pszCmdLine);
  408. if (FAILED(hr = SaveAllInfo(szPath, &s_sysInfo,
  409. s_pDxWinComponentsFileInfoFirst, s_pDxComponentsFileInfoFirst,
  410. s_pDisplayInfoFirst, s_pSoundInfoFirst, s_pMusicInfo,
  411. s_pInputInfo, s_pNetInfo, s_pShowInfo )))
  412. {
  413. ReportError(IDS_PROBLEMSAVING, hr);
  414. goto LCleanup;
  415. }
  416. }
  417. }
  418. else
  419. {
  420. // Do full Windows GUI
  421. UINT dwUIThreadID;
  422. s_dwMainThreadID = GetCurrentThreadId();
  423. // Do scanning that must be done before the main dialog comes up:
  424. // ******* GetSystemInfo (SI:1) ********
  425. if( s_bUseSystemInfo )
  426. {
  427. s_bUseSystemInfo = QueryCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, IDS_SI, 1 );
  428. if( s_bUseSystemInfo )
  429. {
  430. EnterCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  431. GetSystemInfo(&s_sysInfo);
  432. LeaveCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 1 );
  433. }
  434. }
  435. // ******* GetBasicDisplayInfo (DD:1) ********
  436. if( s_bUseDisplay )
  437. {
  438. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 1 );
  439. if( s_bUseDisplay )
  440. {
  441. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  442. if (FAILED(hr = GetBasicDisplayInfo(&s_pDisplayInfoFirst)))
  443. ReportError(IDS_NOBASICDISPLAYINFO, hr);
  444. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 1 );
  445. }
  446. }
  447. // ******* GetBasicSoundInfo (DS:1) ********
  448. if( s_bUseDSound )
  449. {
  450. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 1 );
  451. if( s_bUseDSound )
  452. {
  453. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  454. if (FAILED(hr = GetBasicSoundInfo(&s_pSoundInfoFirst)))
  455. ReportError(IDS_NOBASICSOUNDINFO, hr); // (but keep running)
  456. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  457. }
  458. }
  459. // ******* GetBasicMusicInfo (DM:1) ********
  460. if( s_bUseDMusic )
  461. {
  462. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 1 );
  463. if( s_bUseDMusic )
  464. {
  465. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  466. if (FAILED(hr = GetBasicMusicInfo(&s_pMusicInfo)))
  467. ReportError(IDS_NOBASICMUSICINFO, hr); // (but keep running)
  468. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  469. }
  470. }
  471. if( NULL == s_hUIThread )
  472. {
  473. // Create the UI thread
  474. s_hUIThread = (HANDLE) _beginthreadex( NULL, 0, UIThreadProc, NULL, 0, &dwUIThreadID );
  475. // Wait for either s_hwndMain is set or the UI thread to exit
  476. for(;;)
  477. {
  478. // Stop of the s_hwndMain is set
  479. if( s_hwndMain )
  480. break;
  481. // Stop if the UI thread is gone
  482. if( WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  483. break;
  484. Sleep(50);
  485. }
  486. }
  487. if( WAIT_TIMEOUT == WaitForSingleObject( s_hUIThread, 0 ) )
  488. {
  489. ScanSystem();
  490. s_bScanDone = TRUE;
  491. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  492. // Done scaning, so wait for the UI thread to exit
  493. WaitForSingleObject( s_hUIThread, INFINITE );
  494. }
  495. CloseHandle( s_hUIThread );
  496. }
  497. LCleanup:
  498. CloseHandle( s_hQuerySkipEvent );
  499. CloseHandle( s_hUIMsgEvent );
  500. DeleteCriticalSection( &s_cs );
  501. // Clean up:
  502. if (s_pDxComponentsFileInfoFirst != NULL)
  503. DestroyFileList(s_pDxComponentsFileInfoFirst);
  504. if (s_pDisplayInfoFirst != NULL)
  505. DestroyDisplayInfo(s_pDisplayInfoFirst);
  506. if (s_pSoundInfoFirst != NULL)
  507. DestroySoundInfo(s_pSoundInfoFirst);
  508. if (s_pMusicInfo != NULL)
  509. DestroyMusicInfo(s_pMusicInfo);
  510. if (s_pNetInfo != NULL)
  511. DestroyNetInfo(s_pNetInfo);
  512. if (s_pInputInfo != NULL)
  513. DestroyInputInfo(s_pInputInfo);
  514. if (s_pShowInfo != NULL)
  515. DestroyShowInfo(s_pShowInfo);
  516. ReleaseDigiSignData();
  517. return 0;
  518. }
  519. //-----------------------------------------------------------------------------
  520. // Name: UIThreadProc
  521. // Desc:
  522. //-----------------------------------------------------------------------------
  523. UINT WINAPI UIThreadProc( LPVOID lpParameter )
  524. {
  525. UNREFERENCED_PARAMETER( lpParameter );
  526. HICON hicon;
  527. HINSTANCE hinstRichEdit = NULL;
  528. HWND hMainDlg;
  529. MSG msg;
  530. hinstRichEdit = LoadLibrary(TEXT("RICHED32.DLL"));
  531. if (hinstRichEdit == NULL)
  532. {
  533. ReportError(IDS_NORICHED32);
  534. goto LCleanup;
  535. }
  536. InitCommonControls();
  537. s_himgList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 1, 0);
  538. if (s_himgList == NULL)
  539. {
  540. ReportError(IDS_NOIMAGELIST);
  541. goto LCleanup;
  542. }
  543. hicon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_CAUTION));
  544. if (hicon == NULL)
  545. {
  546. ReportError(IDS_NOICON);
  547. goto LCleanup;
  548. }
  549. ImageList_AddIcon(s_himgList, hicon);
  550. {
  551. // BUG 21632: Warn user if DirectX version is newer than DxDiag version
  552. // (Note: don't check down to the build number, just major.minor.revision)
  553. if( !BIsWinNT() )
  554. {
  555. DWORD dwMajorDX = 0, dwMinorDX = 0, dwRevisionDX = 0, dwBuildDX = 0;
  556. DWORD dwMajorDXD = 0, dwMinorDXD = 0, dwRevisionDXD = 0, dwBuildDXD = 0;
  557. if( _stscanf(s_sysInfo.m_szDirectXVersion, TEXT("%d.%d.%d.%d"), &dwMajorDX, &dwMinorDX, &dwRevisionDX, &dwBuildDX) != 4 )
  558. {
  559. dwMajorDX = 0;
  560. dwMinorDX = 0;
  561. dwRevisionDX = 0;
  562. dwBuildDX = 0;
  563. }
  564. if( _stscanf(s_sysInfo.m_szDxDiagVersion, TEXT("%d.%d.%d.%d"), &dwMajorDXD, &dwMinorDXD, &dwRevisionDXD, &dwBuildDXD) != 4 )
  565. {
  566. dwMajorDXD = 0;
  567. dwMinorDXD = 0;
  568. dwRevisionDXD = 0;
  569. dwBuildDXD = 0;
  570. }
  571. if (dwMajorDX > dwMajorDXD ||
  572. dwMajorDX == dwMajorDXD && dwMinorDX > dwMinorDXD ||
  573. dwMajorDX == dwMajorDXD && dwMinorDX == dwMinorDXD && dwRevisionDX > dwRevisionDXD)
  574. {
  575. TCHAR szFmt[MAX_PATH];
  576. TCHAR szMessage[MAX_PATH];
  577. TCHAR szTitle[MAX_PATH];
  578. LoadString(NULL, IDS_DXDIAGISOLDFMT, szFmt, MAX_PATH);
  579. wsprintf(szMessage, szFmt, s_sysInfo.m_szDirectXVersion, s_sysInfo.m_szDxDiagVersion);
  580. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  581. MessageBox(NULL, szMessage, szTitle, MB_OK);
  582. }
  583. }
  584. }
  585. // Display the main dialog box.
  586. hMainDlg = CreateDialog( g_hInst, MAKEINTRESOURCE(IDD_MAINDIALOG),
  587. NULL, DialogProc );
  588. // Windows messages are available
  589. DWORD dwResult;
  590. BOOL bDone;
  591. bDone = FALSE;
  592. for(;;)
  593. {
  594. dwResult = MsgWaitForMultipleObjects( 1, &s_hUIMsgEvent, FALSE,
  595. INFINITE, QS_ALLEVENTS | QS_ALLINPUT | QS_ALLPOSTMESSAGE );
  596. switch( dwResult )
  597. {
  598. case WAIT_OBJECT_0:
  599. {
  600. if( s_pUIMsgHead )
  601. {
  602. UI_MSG_NODE* pCurNode = s_pUIMsgHead;
  603. UINT message = pCurNode->message;
  604. WPARAM wparam = pCurNode->wparam;
  605. LPARAM lparam = pCurNode->lparam;;
  606. s_pUIMsgHead = s_pUIMsgHead->pNext;
  607. delete pCurNode;
  608. if( s_pUIMsgHead )
  609. SetEvent( s_hUIMsgEvent );
  610. switch( message )
  611. {
  612. case WM_QUERYSKIP:
  613. message = WM_QUERYSKIP_REAL;
  614. break;
  615. case WM_NETMEETINGWARN:
  616. message = WM_NETMEETINGWARN_REAL;
  617. break;
  618. case WM_COMMAND:
  619. message = WM_COMMAND_REAL;
  620. break;
  621. case WM_REPORTERROR:
  622. message = WM_REPORTERROR_REAL;
  623. break;
  624. }
  625. SendMessage( hMainDlg, message, wparam, lparam );
  626. }
  627. break;
  628. }
  629. case WAIT_OBJECT_0 + 1:
  630. {
  631. while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  632. {
  633. if( msg.message == WM_QUIT )
  634. bDone = TRUE;
  635. if( !IsDialogMessage( hMainDlg, &msg ) )
  636. {
  637. TranslateMessage( &msg );
  638. DispatchMessage( &msg );
  639. }
  640. }
  641. break;
  642. }
  643. }
  644. if( bDone )
  645. break;
  646. }
  647. DestroyWindow( hMainDlg );
  648. LCleanup:
  649. while( s_pUIMsgHead )
  650. {
  651. UI_MSG_NODE* pDelete = s_pUIMsgHead;
  652. s_pUIMsgHead = s_pUIMsgHead->pNext;
  653. delete pDelete;
  654. }
  655. // Clean up:
  656. if (s_himgList != NULL)
  657. ImageList_Destroy(s_himgList);
  658. if (hinstRichEdit != NULL)
  659. FreeLibrary(hinstRichEdit);
  660. return 0;
  661. }
  662. /****************************************************************************
  663. *
  664. * OldWindowsVersion - Returns TRUE if running NT before NT5 or pre-Win95.
  665. * Exception: NT4 is allowed if -bugreport was specified.
  666. *
  667. ****************************************************************************/
  668. BOOL OldWindowsVersion(VOID)
  669. {
  670. OSVERSIONINFO OSVersionInfo;
  671. OSVersionInfo.dwOSVersionInfoSize = sizeof OSVersionInfo;
  672. GetVersionEx(&OSVersionInfo);
  673. if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  674. {
  675. if (OSVersionInfo.dwMajorVersion == 4)
  676. {
  677. if (s_bBugReport)
  678. return FALSE; // NT4 supported if "-bugreport" by DxMedia request
  679. if (s_bSaveOnly)
  680. return FALSE; // NT4 supported if "-saveonly" specified
  681. // Ask if user wants to run in saveonly mode:
  682. TCHAR szTitle[MAX_PATH];
  683. TCHAR szMessage[MAX_PATH];
  684. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  685. LoadString(NULL, IDS_NT4SAVEONLY, szMessage, MAX_PATH);
  686. if (IDYES == MessageBox(NULL, szMessage, szTitle, MB_YESNO))
  687. {
  688. s_bSaveOnly = TRUE;
  689. s_bGUI = TRUE;
  690. return FALSE;
  691. }
  692. }
  693. if (OSVersionInfo.dwMajorVersion < 5)
  694. return TRUE; // NT4 and earlier not supported
  695. }
  696. else
  697. {
  698. if (OSVersionInfo.dwMajorVersion < 4)
  699. return TRUE; // Pre-Win95 not supported
  700. }
  701. return FALSE; // Win95 or later, or NT5 or later
  702. }
  703. //-----------------------------------------------------------------------------
  704. // Name: ReportError
  705. // Desc:
  706. //-----------------------------------------------------------------------------
  707. VOID ReportError(LONG idsDescription, HRESULT hr)
  708. {
  709. if( s_hwndMain )
  710. PostMessage( s_hwndMain, WM_REPORTERROR, (WPARAM) idsDescription, (LPARAM) hr );
  711. else
  712. ReportErrorReal( idsDescription, hr );
  713. }
  714. //-----------------------------------------------------------------------------
  715. // Name: ReportErrorReal
  716. // Desc:
  717. //-----------------------------------------------------------------------------
  718. VOID ReportErrorReal(LONG idsDescription, HRESULT hr)
  719. {
  720. TCHAR szDescription[MAX_PATH];
  721. TCHAR szMessage[MAX_PATH];
  722. TCHAR szFmt1[MAX_PATH];
  723. TCHAR szFmt2[MAX_PATH];
  724. TCHAR szTitle[MAX_PATH];
  725. TCHAR szErrorDesc[MAX_PATH];
  726. LoadString(NULL, idsDescription, szDescription, MAX_PATH);
  727. LoadString(NULL, IDS_ERRORFMT1, szFmt1, MAX_PATH);
  728. LoadString(NULL, IDS_ERRORFMT2, szFmt2, MAX_PATH);
  729. LoadString(NULL, IDS_ERRORTITLE, szTitle, MAX_PATH);
  730. if (FAILED(hr))
  731. {
  732. BTranslateError(hr, szErrorDesc);
  733. wsprintf(szMessage, szFmt1, szDescription, hr, szErrorDesc);
  734. }
  735. else
  736. {
  737. wsprintf(szMessage, szFmt2, szDescription);
  738. }
  739. if (s_bGUI)
  740. MessageBox(s_hwndMain, szMessage, szTitle, MB_OK);
  741. else
  742. _tprintf(szMessage);
  743. }
  744. typedef BOOL (WINAPI* PfnCoSetProxyBlanket)(
  745. IUnknown *pProxy,
  746. DWORD dwAuthnSvc,
  747. DWORD dwAuthzSvc,
  748. OLECHAR *pServerPrincName,
  749. DWORD dwAuthnLevel,
  750. DWORD dwImpLevel,
  751. RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
  752. DWORD dwCapabilities );
  753. /****************************************************************************
  754. *
  755. * CWMIHelper - Inits DCOM and g_pIWbemServices
  756. *
  757. ****************************************************************************/
  758. CWMIHelper::CWMIHelper(VOID)
  759. {
  760. HRESULT hr;
  761. IWbemLocator* pIWbemLocator = NULL;
  762. BSTR pNamespace = NULL;
  763. HINSTANCE hinstOle32 = NULL;
  764. CoInitialize( 0 );
  765. hr = CoCreateInstance( CLSID_WbemLocator,
  766. NULL,
  767. CLSCTX_INPROC_SERVER,
  768. IID_IWbemLocator,
  769. (LPVOID*) &pIWbemLocator);
  770. if( FAILED(hr) || pIWbemLocator == NULL )
  771. goto LCleanup;
  772. // Using the locator, connect to WMI in the given namespace.
  773. pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
  774. hr = pIWbemLocator->ConnectServer( pNamespace, NULL, NULL, 0L,
  775. 0L, NULL, NULL, &g_pIWbemServices );
  776. if( FAILED(hr) || g_pIWbemServices == NULL )
  777. goto LCleanup;
  778. hinstOle32 = LoadLibrary( TEXT("ole32.dll") );
  779. if( hinstOle32 )
  780. {
  781. PfnCoSetProxyBlanket pfnCoSetProxyBlanket = NULL;
  782. pfnCoSetProxyBlanket = (PfnCoSetProxyBlanket)GetProcAddress( hinstOle32, "CoSetProxyBlanket" );
  783. if (pfnCoSetProxyBlanket != NULL)
  784. {
  785. // Switch security level to IMPERSONATE.
  786. hr = pfnCoSetProxyBlanket( g_pIWbemServices, // proxy
  787. RPC_C_AUTHN_WINNT, // authentication service
  788. RPC_C_AUTHZ_NONE, // authorization service
  789. NULL, // server principle name
  790. RPC_C_AUTHN_LEVEL_CALL, // authentication level
  791. RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
  792. NULL, // identity of the client
  793. EOAC_NONE ); // capability flags
  794. // If CoSetProxyBlanket, just leave it be and see if it works.
  795. }
  796. }
  797. LCleanup:
  798. if( hinstOle32 )
  799. FreeLibrary(hinstOle32);
  800. if(pNamespace)
  801. SysFreeString(pNamespace);
  802. if(pIWbemLocator)
  803. pIWbemLocator->Release();
  804. }
  805. /****************************************************************************
  806. *
  807. * ~CWMIHelper - Cleanup WMI
  808. *
  809. ****************************************************************************/
  810. CWMIHelper::~CWMIHelper(VOID)
  811. {
  812. if(g_pIWbemServices)
  813. g_pIWbemServices->Release();
  814. CoUninitialize();
  815. }
  816. /****************************************************************************
  817. *
  818. * DXFilesCompareFunc - Compares items on DirectX files pages
  819. *
  820. ****************************************************************************/
  821. int CALLBACK DXFilesCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lSortMethod)
  822. {
  823. FileInfo* pFileInfo1 = (FileInfo*) lParam1;
  824. FileInfo* pFileInfo2 = (FileInfo*) lParam2;
  825. switch( s_sortInfo.dwColumnToSort )
  826. {
  827. case 0:
  828. return (s_sortInfo.nSortDirection * (_tcscmp( pFileInfo1->m_szName,
  829. pFileInfo2->m_szName )));
  830. case 1:
  831. return (s_sortInfo.nSortDirection * (_tcscmp( pFileInfo1->m_szVersion,
  832. pFileInfo2->m_szVersion )));
  833. case 2:
  834. return (s_sortInfo.nSortDirection * (_tcscmp( pFileInfo1->m_szAttributes,
  835. pFileInfo2->m_szAttributes )));
  836. case 3:
  837. return (s_sortInfo.nSortDirection * (_tcscmp( pFileInfo1->m_szLanguageLocal,
  838. pFileInfo2->m_szLanguageLocal )));
  839. case 4:
  840. return ( s_sortInfo.nSortDirection * CompareFileTime( &pFileInfo1->m_FileTime,
  841. &pFileInfo2->m_FileTime ) );
  842. case 5:
  843. if( pFileInfo1->m_numBytes > pFileInfo2->m_numBytes )
  844. return (s_sortInfo.nSortDirection * 1);
  845. if( pFileInfo1->m_numBytes < pFileInfo2->m_numBytes )
  846. return (s_sortInfo.nSortDirection * -1);
  847. return 0;
  848. }
  849. return 0;
  850. }
  851. /****************************************************************************
  852. *
  853. * MsgHook
  854. *
  855. ****************************************************************************/
  856. LRESULT FAR PASCAL MsgHook(int nCode, WPARAM wParam, LPARAM lParam)
  857. {
  858. LPMSG pMsg = (LPMSG) lParam;
  859. if( pMsg &&
  860. pMsg->message == WM_KEYDOWN &&
  861. pMsg->wParam == VK_TAB &&
  862. GetKeyState(VK_CONTROL) < 0)
  863. {
  864. // Handle a ctrl-tab or ctrl-shift-tab
  865. if( GetKeyState(VK_SHIFT) < 0 )
  866. PostMessage( s_hwndMain, WM_COMMAND, IDC_PREV_TAB, 0 );
  867. else
  868. PostMessage( s_hwndMain, WM_COMMAND, IDC_NEXT_TAB, 0 );
  869. // Stop further processing, otherwise it will also be handled
  870. // as a plain tab key pressed by the internal IsDialogBox() call.
  871. pMsg->message = WM_NULL;
  872. pMsg->lParam = 0;
  873. pMsg->wParam = 0;
  874. }
  875. return CallNextHookEx( s_hHook, nCode, wParam, lParam);
  876. }
  877. /****************************************************************************
  878. *
  879. * DialogProc
  880. *
  881. ****************************************************************************/
  882. INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  883. {
  884. HWND hwndTabs = GetDlgItem(hwnd, IDC_TAB);
  885. switch (msg)
  886. {
  887. case WM_INITDIALOG:
  888. {
  889. SetForegroundWindow( hwnd );
  890. s_hwndMain = hwnd;
  891. s_hHook = SetWindowsHookEx( WH_GETMESSAGE, MsgHook,
  892. NULL, GetCurrentThreadId() );
  893. HINSTANCE hinst = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
  894. HICON hicon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_APP));
  895. SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)hicon);
  896. SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM)hicon);
  897. CreateTabs(hwndTabs);
  898. SetupPage(hwndTabs, 0);
  899. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  900. if( s_sysInfo.m_bNetMeetingRunning )
  901. PostMessage( s_hwndMain, WM_NETMEETINGWARN, 0, 0 );
  902. s_sortInfo.nSortDirection = 1;
  903. s_sortInfo.dwColumnToSort = -1;
  904. }
  905. return TRUE;
  906. case WM_APP_PROGRESS:
  907. {
  908. if( s_lwCurPage == 0 )
  909. {
  910. HWND hProgress = GetDlgItem( s_hwndCurPage, IDC_LOAD_PROGRESS );
  911. if( !s_bScanDone )
  912. {
  913. ShowWindow( hProgress, SW_SHOW );
  914. SendMessage( hProgress, PBM_DELTAPOS, 10, 0 );
  915. UpdateWindow( s_hwndMain );
  916. UpdateWindow( s_hwndCurPage );
  917. }
  918. else
  919. {
  920. ShowWindow( hProgress, SW_HIDE );
  921. EnableWindow( GetDlgItem(hwnd, IDNEXT), TRUE );
  922. EnableWindow( GetDlgItem(hwnd, IDSAVE), TRUE );
  923. }
  924. }
  925. }
  926. break;
  927. case WM_REPORTERROR:
  928. case WM_NETMEETINGWARN:
  929. case WM_COMMAND:
  930. case WM_QUERYSKIP:
  931. {
  932. UI_MSG_NODE* pMsg = new UI_MSG_NODE;
  933. if( NULL == pMsg )
  934. return TRUE;
  935. ZeroMemory( pMsg, sizeof(UI_MSG_NODE) );
  936. pMsg->message = msg;
  937. pMsg->lparam = lparam;
  938. pMsg->wparam = wparam;
  939. UI_MSG_NODE* pEnum = s_pUIMsgHead;
  940. UI_MSG_NODE* pPrev = NULL;
  941. while( pEnum )
  942. {
  943. pPrev = pEnum;
  944. pEnum = pEnum->pNext;
  945. }
  946. if( pPrev )
  947. pPrev->pNext = pMsg;
  948. else
  949. s_pUIMsgHead = pMsg;
  950. SetEvent( s_hUIMsgEvent );
  951. return TRUE;
  952. }
  953. case WM_REPORTERROR_REAL:
  954. {
  955. ReportErrorReal( (LONG) wparam, (HRESULT) lparam );
  956. return TRUE;
  957. }
  958. case WM_NETMEETINGWARN_REAL:
  959. {
  960. TCHAR strMessage[MAX_PATH];
  961. TCHAR strTitle[MAX_PATH];
  962. LoadString(NULL, IDS_APPFULLNAME, strTitle, MAX_PATH);
  963. LoadString(NULL, IDS_NETMEETINGWARN, strMessage, MAX_PATH);
  964. MessageBox( s_hwndMain, strMessage, strTitle, MB_OK|MB_ICONWARNING );
  965. return TRUE;
  966. }
  967. case WM_QUERYSKIP_REAL:
  968. {
  969. EnableWindow( s_hwndMain, FALSE );
  970. TCHAR szTitle[MAX_PATH];
  971. TCHAR szMessage[MAX_PATH];
  972. TCHAR szFmt[MAX_PATH];
  973. TCHAR szMessageComponent[MAX_PATH];
  974. LoadString(0, IDS_APPFULLNAME, szTitle, MAX_PATH);
  975. LoadString(0, IDS_SKIP, szFmt, MAX_PATH);
  976. LoadString(0, s_nSkipComponent, szMessageComponent, MAX_PATH);
  977. wsprintf( szMessage, szFmt, szMessageComponent, szMessageComponent );
  978. // Ask the user and store result it s_bQuerySkipAllow
  979. if( IDYES == MessageBox( s_hwndMain, szMessage, szTitle, MB_YESNO) )
  980. s_bQuerySkipAllow = FALSE;
  981. else
  982. s_bQuerySkipAllow = TRUE;
  983. EnableWindow( s_hwndMain, TRUE );
  984. // Set the event, triggering the main thread to wake up
  985. SetEvent( s_hQuerySkipEvent );
  986. }
  987. return TRUE;
  988. case WM_COMMAND_REAL:
  989. {
  990. WORD wID = LOWORD(wparam);
  991. INT numTabs;
  992. INT iTabCur;
  993. DisplayInfo* pDisplayInfo = NULL;
  994. SoundInfo* pSoundInfo = NULL;
  995. switch(wID)
  996. {
  997. case IDEXIT:
  998. PostQuitMessage( 0 );
  999. break;
  1000. case IDC_NEXT_TAB:
  1001. case IDNEXT:
  1002. case IDC_PREV_TAB:
  1003. if( FALSE == s_bScanDone )
  1004. {
  1005. MessageBeep( MB_ICONEXCLAMATION );
  1006. return TRUE;
  1007. }
  1008. numTabs = TabCtrl_GetItemCount(hwndTabs);
  1009. iTabCur = TabCtrl_GetCurFocus(hwndTabs);
  1010. if( wID == IDC_PREV_TAB )
  1011. iTabCur += numTabs - 1;
  1012. else
  1013. iTabCur++;
  1014. iTabCur %= numTabs;
  1015. TabCtrl_SetCurFocus(hwndTabs, iTabCur );
  1016. break;
  1017. case IDSAVE:
  1018. SaveInfo();
  1019. break;
  1020. case IDC_APPHELP:
  1021. ShowHelp();
  1022. break;
  1023. case IDC_RESTOREDRIVERS:
  1024. RestoreDrivers();
  1025. break;
  1026. case IDC_TESTDD:
  1027. iTabCur = TabCtrl_GetCurFocus(hwndTabs);
  1028. for (pDisplayInfo = s_pDisplayInfoFirst; iTabCur > s_iPageDisplayFirst; iTabCur--)
  1029. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext;
  1030. TestDD(s_hwndMain, pDisplayInfo);
  1031. SetupDisplayPage(TabCtrl_GetCurFocus(hwndTabs) - s_iPageDisplayFirst);
  1032. break;
  1033. case IDC_TESTD3D:
  1034. iTabCur = TabCtrl_GetCurFocus(hwndTabs);
  1035. for (pDisplayInfo = s_pDisplayInfoFirst; iTabCur > s_iPageDisplayFirst; iTabCur--)
  1036. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext;
  1037. TestD3D(s_hwndMain, pDisplayInfo);
  1038. SetupDisplayPage(TabCtrl_GetCurFocus(hwndTabs) - s_iPageDisplayFirst);
  1039. break;
  1040. case IDC_TESTSND:
  1041. iTabCur = TabCtrl_GetCurFocus(hwndTabs);
  1042. for (pSoundInfo = s_pSoundInfoFirst; iTabCur > s_iPageSoundFirst; iTabCur--)
  1043. pSoundInfo = pSoundInfo->m_pSoundInfoNext;
  1044. TestSnd(s_hwndMain, pSoundInfo);
  1045. SetupSoundPage(TabCtrl_GetCurFocus(hwndTabs) - s_iPageSoundFirst);
  1046. break;
  1047. case IDC_PORTLISTCOMBO:
  1048. if (HIWORD(wparam) == CBN_SELCHANGE)
  1049. {
  1050. LONG iItemPicked = (LONG)SendMessage(GetDlgItem(s_hwndCurPage, IDC_PORTLISTCOMBO), CB_GETCURSEL, 0, 0);
  1051. LONG iItem = 0;
  1052. MusicPort* pMusicPort;
  1053. for (pMusicPort = s_pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL; pMusicPort = pMusicPort->m_pMusicPortNext)
  1054. {
  1055. if (pMusicPort->m_bOutputPort)
  1056. {
  1057. if (iItem == iItemPicked)
  1058. {
  1059. s_pMusicInfo->m_guidMusicPortTest = pMusicPort->m_guid;
  1060. break;
  1061. }
  1062. iItem++;
  1063. }
  1064. }
  1065. }
  1066. break;
  1067. case IDC_TESTMUSIC:
  1068. if (s_pMusicInfo != NULL)
  1069. TestMusic(s_hwndMain, s_pMusicInfo);
  1070. SetupMusicPage();
  1071. break;
  1072. case IDC_TESTPLAY:
  1073. {
  1074. if( s_sysInfo.m_dwDirectXVersionMajor < 8 )
  1075. {
  1076. TCHAR szMessage[MAX_PATH];
  1077. TCHAR szTitle[MAX_PATH];
  1078. LoadString(0, IDS_APPFULLNAME, szTitle, MAX_PATH);
  1079. LoadString(0, IDS_TESTNEEDSDX8, szMessage, MAX_PATH);
  1080. MessageBox(s_hwndMain, szMessage, szTitle, MB_OK);
  1081. }
  1082. else
  1083. {
  1084. if (s_pNetInfo != NULL)
  1085. TestNetwork(s_hwndMain, s_pNetInfo);
  1086. SetupNetworkPage();
  1087. }
  1088. break;
  1089. }
  1090. case IDC_DISABLEDD:
  1091. ToggleDDAccel();
  1092. break;
  1093. case IDC_DISABLED3D:
  1094. ToggleD3DAccel();
  1095. break;
  1096. case IDC_DISABLEAGP:
  1097. ToggleAGPSupport();
  1098. break;
  1099. case IDC_DISABLEDM:
  1100. ToggleDMAccel();
  1101. break;
  1102. case IDC_REPORTBUG:
  1103. ReportBug();
  1104. break;
  1105. case IDC_TROUBLESHOOT:
  1106. TroubleShoot( FALSE );
  1107. break;
  1108. case IDC_TROUBLESHOOTSOUND:
  1109. TroubleShoot( TRUE );
  1110. break;
  1111. case IDC_MSINFO:
  1112. {
  1113. HKEY hkey;
  1114. TCHAR szMsInfo[MAX_PATH];
  1115. DWORD cbData = MAX_PATH;
  1116. DWORD dwType;
  1117. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1118. TEXT("Software\\Microsoft\\Shared Tools\\MSInfo"), 0, KEY_READ, &hkey))
  1119. {
  1120. RegQueryValueEx(hkey, TEXT("Path"), 0, &dwType, (LPBYTE)szMsInfo, &cbData);
  1121. HINSTANCE hinstResult = ShellExecute( s_hwndMain, NULL, szMsInfo, NULL,
  1122. NULL, SW_SHOWNORMAL );
  1123. if( (INT_PTR)hinstResult < 32 )
  1124. ReportError(IDS_NOMSINFO);
  1125. }
  1126. else
  1127. {
  1128. ReportError(IDS_NOMSINFO);
  1129. }
  1130. }
  1131. break;
  1132. case IDC_OVERRIDE:
  1133. OverrideDDRefresh();
  1134. break;
  1135. case IDC_GHOST:
  1136. AdjustGhostDevices(s_hwndMain, s_pDisplayInfoFirst);
  1137. break;
  1138. }
  1139. return TRUE;
  1140. }
  1141. case WM_NOTIFY:
  1142. {
  1143. INT id = (INT)wparam;
  1144. NMHDR* pnmh = (LPNMHDR)lparam;
  1145. UINT code = pnmh->code;
  1146. if (code == TCN_SELCHANGING)
  1147. {
  1148. if( !s_bScanDone )
  1149. {
  1150. MessageBeep( MB_ICONEXCLAMATION );
  1151. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
  1152. return TRUE;
  1153. }
  1154. CleanupPage(hwndTabs, TabCtrl_GetCurFocus(hwndTabs));
  1155. return TRUE;
  1156. }
  1157. if (code == TCN_SELCHANGE)
  1158. SetupPage(hwndTabs, TabCtrl_GetCurFocus(hwndTabs));
  1159. // If a "DX files" column was clicked
  1160. if (code == LVN_COLUMNCLICK && s_lwCurPage == 1)
  1161. {
  1162. NMLISTVIEW* pnmv = (LPNMLISTVIEW) lparam;
  1163. // Figure out if we want to reverse sort
  1164. if( s_sortInfo.dwColumnToSort == (DWORD) pnmv->iSubItem )
  1165. s_sortInfo.nSortDirection = -s_sortInfo.nSortDirection;
  1166. else
  1167. s_sortInfo.nSortDirection = 1;
  1168. // Set the column to sort, and sort
  1169. s_sortInfo.dwColumnToSort = pnmv->iSubItem;
  1170. ListView_SortItems( GetDlgItem(s_hwndCurPage, IDC_LIST),
  1171. DXFilesCompareFunc, 0 );
  1172. }
  1173. }
  1174. return TRUE;
  1175. case WM_HSCROLL:
  1176. if ((HWND)lparam == GetDlgItem(s_hwndCurPage, IDC_SNDACCELSLIDER))
  1177. HandleSndSliderChange(LOWORD(wparam), HIWORD(wparam));
  1178. return TRUE;
  1179. case WM_CLOSE:
  1180. PostQuitMessage(0);
  1181. return TRUE;
  1182. case WM_DESTROY:
  1183. UnhookWindowsHookEx( s_hHook );
  1184. return TRUE;
  1185. }
  1186. return FALSE;
  1187. }
  1188. /****************************************************************************
  1189. *
  1190. * CreateTabs
  1191. *
  1192. ****************************************************************************/
  1193. HRESULT CreateTabs(HWND hwndTabs)
  1194. {
  1195. TC_ITEM tie;
  1196. INT i = 0;
  1197. TCHAR sz[MAX_PATH];
  1198. TCHAR szFmt[MAX_PATH];
  1199. DisplayInfo* pDisplayInfo;
  1200. SoundInfo* pSoundInfo;
  1201. tie.mask = TCIF_TEXT | TCIF_IMAGE;
  1202. tie.iImage = -1;
  1203. LoadString(NULL, IDS_HELPTAB, sz, MAX_PATH);
  1204. tie.pszText = sz;
  1205. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1206. return E_FAIL;
  1207. LoadString(NULL, IDS_DXFILESTAB, sz, MAX_PATH);
  1208. tie.pszText = sz;
  1209. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1210. return E_FAIL;
  1211. // Create tabs for each display:
  1212. s_iPageDisplayFirst = 2;
  1213. for (pDisplayInfo = s_pDisplayInfoFirst; pDisplayInfo != NULL;
  1214. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext)
  1215. {
  1216. if (pDisplayInfo == s_pDisplayInfoFirst && pDisplayInfo->m_pDisplayInfoNext == NULL)
  1217. {
  1218. LoadString(NULL, IDS_ONEDISPLAYTAB, sz, MAX_PATH);
  1219. }
  1220. else
  1221. {
  1222. LoadString(NULL, IDS_MULTIDISPLAYTAB, szFmt, MAX_PATH);
  1223. wsprintf(sz, szFmt, s_numDisplayInfo + 1);
  1224. }
  1225. tie.pszText = sz;
  1226. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1227. return E_FAIL;
  1228. s_numDisplayInfo++;
  1229. }
  1230. // Create tabs for each sound device:
  1231. s_iPageSoundFirst = s_iPageDisplayFirst + s_numDisplayInfo;
  1232. for (pSoundInfo = s_pSoundInfoFirst; pSoundInfo != NULL;
  1233. pSoundInfo = pSoundInfo->m_pSoundInfoNext)
  1234. {
  1235. if (pSoundInfo == s_pSoundInfoFirst && pSoundInfo->m_pSoundInfoNext == NULL)
  1236. {
  1237. LoadString(NULL, IDS_ONESOUNDTAB, sz, MAX_PATH);
  1238. }
  1239. else
  1240. {
  1241. LoadString(NULL, IDS_MULTISOUNDTAB, szFmt, MAX_PATH);
  1242. wsprintf(sz, szFmt, s_numSoundInfo + 1);
  1243. }
  1244. tie.pszText = sz;
  1245. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1246. return E_FAIL;
  1247. s_numSoundInfo++;
  1248. }
  1249. // Create tab for music device, if DMusic is available:
  1250. if (s_pMusicInfo != NULL && s_pMusicInfo->m_bDMusicInstalled)
  1251. {
  1252. s_iPageMusic = s_iPageSoundFirst + s_numSoundInfo;
  1253. LoadString(NULL, IDS_MUSICTAB, sz, MAX_PATH);
  1254. tie.pszText = sz;
  1255. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1256. return E_FAIL;
  1257. }
  1258. if (s_iPageMusic > 0)
  1259. s_iPageInput = s_iPageMusic + 1;
  1260. else
  1261. s_iPageInput = s_iPageSoundFirst + s_numSoundInfo;
  1262. LoadString(NULL, IDS_INPUTTAB, sz, MAX_PATH);
  1263. tie.pszText = sz;
  1264. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1265. return E_FAIL;
  1266. s_iPageNetwork = s_iPageInput + 1;
  1267. LoadString(NULL, IDS_NETWORKTAB, sz, MAX_PATH);
  1268. tie.pszText = sz;
  1269. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1270. return E_FAIL;
  1271. s_iPageStillStuck = s_iPageNetwork + 1;
  1272. LoadString(NULL, IDS_STILLSTUCKTAB, sz, MAX_PATH);
  1273. tie.pszText = sz;
  1274. if (TabCtrl_InsertItem(hwndTabs, i++, &tie) == -1)
  1275. return E_FAIL;
  1276. return S_OK;
  1277. }
  1278. /****************************************************************************
  1279. *
  1280. * SetupPage
  1281. *
  1282. ****************************************************************************/
  1283. HRESULT SetupPage(HWND hwndTabs, INT iPage)
  1284. {
  1285. HRESULT hr;
  1286. s_lwCurPage = iPage;
  1287. // Only enable "Next Page" button if not on last page:
  1288. HWND hwndNextButton = GetDlgItem(s_hwndMain, IDNEXT);
  1289. if (!s_bScanDone || iPage == TabCtrl_GetItemCount(hwndTabs) - 1)
  1290. EnableWindow(hwndNextButton, FALSE);
  1291. else
  1292. EnableWindow(hwndNextButton, TRUE);
  1293. EnableWindow(GetDlgItem(s_hwndMain, IDSAVE), s_bScanDone);
  1294. RECT rc;
  1295. WORD idDialog;
  1296. GetClientRect(hwndTabs, &rc);
  1297. TabCtrl_AdjustRect(hwndTabs, FALSE, &rc);
  1298. if (iPage == 0)
  1299. idDialog = IDD_HELPPAGE;
  1300. else if (iPage == 1)
  1301. idDialog = IDD_DXFILESPAGE;
  1302. else if (iPage >= s_iPageDisplayFirst && iPage < s_iPageDisplayFirst + s_numDisplayInfo)
  1303. idDialog = IDD_DISPLAYPAGE;
  1304. else if (iPage >= s_iPageSoundFirst && iPage < s_iPageSoundFirst + s_numSoundInfo)
  1305. idDialog = IDD_SOUNDPAGE;
  1306. else if (iPage == s_iPageMusic)
  1307. idDialog = IDD_MUSICPAGE;
  1308. else if (iPage == s_iPageInput)
  1309. idDialog = IDD_INPUTPAGE;
  1310. else if (iPage == s_iPageNetwork)
  1311. idDialog = IDD_NETWORKPAGE;
  1312. else if (iPage == s_iPageStillStuck)
  1313. idDialog = IDD_STILLSTUCKPAGE;
  1314. else
  1315. return S_OK;
  1316. HINSTANCE hinst = (HINSTANCE)GetWindowLongPtr(hwndTabs, GWLP_HINSTANCE);
  1317. s_hwndCurPage = CreateDialog(hinst, MAKEINTRESOURCE(idDialog),
  1318. s_hwndMain, PageDialogProc);
  1319. SetWindowPos(s_hwndCurPage, NULL, rc.left, rc.top, rc.right - rc.left,
  1320. rc.bottom - rc.top, 0);
  1321. if (iPage == 0)
  1322. {
  1323. if (FAILED(hr = SetupHelpPage(hwndTabs)))
  1324. return hr;
  1325. }
  1326. else if (iPage == 1)
  1327. {
  1328. if (FAILED(hr = SetupDxFilesPage()))
  1329. return hr;
  1330. }
  1331. else if (iPage >= s_iPageDisplayFirst && iPage < s_iPageDisplayFirst + s_numDisplayInfo)
  1332. {
  1333. if (FAILED(hr = SetupDisplayPage(iPage - s_iPageDisplayFirst)))
  1334. return hr;
  1335. }
  1336. else if (iPage >= s_iPageSoundFirst && iPage < s_iPageSoundFirst + s_numSoundInfo)
  1337. {
  1338. if (FAILED(hr = SetupSoundPage(iPage - s_iPageSoundFirst)))
  1339. return hr;
  1340. }
  1341. else if (iPage == s_iPageMusic)
  1342. {
  1343. if (FAILED(hr = SetupMusicPage()))
  1344. return hr;
  1345. }
  1346. else if (iPage == s_iPageInput)
  1347. {
  1348. if (FAILED(hr = SetupInputPage()))
  1349. return hr;
  1350. }
  1351. else if (iPage == s_iPageNetwork)
  1352. {
  1353. if (FAILED(hr = SetupNetworkPage()))
  1354. return hr;
  1355. }
  1356. else if (iPage == s_iPageStillStuck)
  1357. {
  1358. if (FAILED(hr = SetupStillStuckPage()))
  1359. return hr;
  1360. }
  1361. // Make sure keyboard focus is somewhere
  1362. if (GetFocus() == NULL)
  1363. SetFocus(GetDlgItem(s_hwndMain, IDSAVE));
  1364. ShowWindow(s_hwndCurPage, SW_SHOW);
  1365. return S_OK;
  1366. }
  1367. /****************************************************************************
  1368. *
  1369. * PageDialogProc
  1370. *
  1371. ****************************************************************************/
  1372. INT_PTR CALLBACK PageDialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  1373. {
  1374. switch (msg)
  1375. {
  1376. case WM_INITDIALOG:
  1377. return FALSE;
  1378. case WM_COMMAND:
  1379. case WM_HSCROLL:
  1380. case WM_NOTIFY:
  1381. // Pass the message up to the main dialog proc
  1382. SendMessage(s_hwndMain, msg, wparam, lparam);
  1383. return TRUE;
  1384. }
  1385. return FALSE;
  1386. }
  1387. /****************************************************************************
  1388. *
  1389. * CleanupPage
  1390. *
  1391. ****************************************************************************/
  1392. HRESULT CleanupPage(HWND hwndTabs, INT iPage)
  1393. {
  1394. if (s_hwndCurPage != NULL)
  1395. {
  1396. DestroyWindow(s_hwndCurPage);
  1397. s_hwndCurPage = NULL;
  1398. }
  1399. return S_OK;
  1400. }
  1401. /****************************************************************************
  1402. *
  1403. * SetupHelpPage
  1404. *
  1405. ****************************************************************************/
  1406. HRESULT SetupHelpPage(HWND hwndTabs)
  1407. {
  1408. TCHAR szCopyrightFmt[MAX_PATH];
  1409. TCHAR szUnicode[MAX_PATH];
  1410. TCHAR szCopyright[MAX_PATH];
  1411. LoadString(NULL, IDS_COPYRIGHTFMT, szCopyrightFmt, MAX_PATH);
  1412. #ifdef UNICODE
  1413. LoadString(NULL, IDS_UNICODE, szUnicode, MAX_PATH);
  1414. #else
  1415. lstrcpy(szUnicode, TEXT(""));
  1416. #endif
  1417. wsprintf(szCopyright, szCopyrightFmt, s_sysInfo.m_szDxDiagVersion, szUnicode);
  1418. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DATE), s_sysInfo.m_szTimeLocal);
  1419. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_COMPUTERNAME), s_sysInfo.m_szMachine);
  1420. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_OS), s_sysInfo.m_szOSEx);
  1421. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_LANGUAGE), s_sysInfo.m_szLanguagesLocal);
  1422. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_PROCESSOR), s_sysInfo.m_szProcessor);
  1423. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_MEMORY), s_sysInfo.m_szPhysicalMemory);
  1424. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_PAGEFILE), s_sysInfo.m_szPageFile);
  1425. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DIRECTXVERSION), s_sysInfo.m_szDirectXVersionLong);
  1426. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_COPYRIGHT), szCopyright);
  1427. HWND hProgress = GetDlgItem( s_hwndCurPage, IDC_LOAD_PROGRESS );
  1428. SendMessage( hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 17 * 10) );
  1429. SendMessage( hProgress, PBM_SETPOS, 0, 0 );
  1430. ShowWindow( hProgress, !s_bScanDone ? SW_SHOW : SW_HIDE );
  1431. return S_OK;
  1432. }
  1433. /****************************************************************************
  1434. *
  1435. * ShowBullets - Show bullets and 1/4-inch indents in notes box
  1436. *
  1437. ****************************************************************************/
  1438. VOID ShowBullets(VOID)
  1439. {
  1440. PARAFORMAT pf;
  1441. ZeroMemory(&pf, sizeof(pf));
  1442. pf.cbSize = sizeof(pf);
  1443. pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
  1444. pf.wNumbering = PFN_BULLET;
  1445. pf.dxOffset = 1440 / 4; // a twip is 1440th of an inch, I want a 1/4-inch indent
  1446. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETPARAFORMAT, 0, (LPARAM)&pf);
  1447. }
  1448. /****************************************************************************
  1449. *
  1450. * HideBullets
  1451. *
  1452. ****************************************************************************/
  1453. VOID HideBullets(VOID)
  1454. {
  1455. PARAFORMAT pf;
  1456. ZeroMemory(&pf, sizeof(pf));
  1457. pf.cbSize = sizeof(pf);
  1458. pf.dwMask = PFM_NUMBERING;
  1459. pf.wNumbering = 0;
  1460. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETPARAFORMAT, 0, (LPARAM)&pf);
  1461. }
  1462. /****************************************************************************
  1463. *
  1464. * SetupDxFilesPage
  1465. *
  1466. ****************************************************************************/
  1467. HRESULT SetupDxFilesPage(VOID)
  1468. {
  1469. HRESULT hr;
  1470. HWND hwndList = GetDlgItem(s_hwndCurPage, IDC_LIST);
  1471. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  1472. if (FAILED(hr = (CreateFileInfoColumns(hwndList, FALSE))))
  1473. return hr;
  1474. ShowBullets();
  1475. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1476. EM_REPLACESEL, FALSE, (LPARAM)s_sysInfo.m_szDXFileNotes);
  1477. // Disable bullets so last line doesn't have an empty bullet
  1478. HideBullets();
  1479. if (FAILED(hr = (AddFileInfo(hwndList, s_pDxComponentsFileInfoFirst))))
  1480. return hr;
  1481. // Autosize all columns to fit header/text tightly:
  1482. INT iColumn = 0;
  1483. INT iWidthHeader;
  1484. INT iWidthText;
  1485. while (TRUE)
  1486. {
  1487. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  1488. break;
  1489. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  1490. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  1491. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  1492. if (iWidthText < iWidthHeader)
  1493. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  1494. iColumn++;
  1495. }
  1496. // Delete the bogus column that was created
  1497. ListView_DeleteColumn(hwndList, iColumn - 1);
  1498. return S_OK;
  1499. }
  1500. /****************************************************************************
  1501. *
  1502. * SetupDisplayPage
  1503. *
  1504. ****************************************************************************/
  1505. HRESULT SetupDisplayPage(LONG iDisplay)
  1506. {
  1507. DisplayInfo* pDisplayInfo;
  1508. TCHAR sz[MAX_PATH];
  1509. pDisplayInfo = s_pDisplayInfoFirst;
  1510. while (iDisplay > 0)
  1511. {
  1512. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext;
  1513. iDisplay--;
  1514. }
  1515. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_ADAPTER), pDisplayInfo->m_szDescription);
  1516. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_MANUFACTURER), pDisplayInfo->m_szManufacturer);
  1517. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_CHIPTYPE), pDisplayInfo->m_szChipType);
  1518. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DACTYPE), pDisplayInfo->m_szDACType);
  1519. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISPLAYMEMORY), pDisplayInfo->m_szDisplayMemory);
  1520. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISPLAYMODE), pDisplayInfo->m_szDisplayMode);
  1521. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_MONITOR), pDisplayInfo->m_szMonitorName);
  1522. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERNAME), pDisplayInfo->m_szDriverName);
  1523. wsprintf(sz, TEXT("%s (%s)"), pDisplayInfo->m_szDriverVersion, pDisplayInfo->m_szDriverLanguageLocal);
  1524. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERVERSION), sz);
  1525. if (pDisplayInfo->m_bDriverSignedValid)
  1526. {
  1527. if (pDisplayInfo->m_bDriverSigned)
  1528. LoadString(NULL, IDS_YES, sz, MAX_PATH);
  1529. else
  1530. LoadString(NULL, IDS_NO, sz, MAX_PATH);
  1531. }
  1532. else
  1533. LoadString(NULL, IDS_NA, sz, MAX_PATH);
  1534. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERSIGNED), sz);
  1535. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_MINIVDD), pDisplayInfo->m_szMiniVdd);
  1536. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_VDD), pDisplayInfo->m_szVdd);
  1537. // Diagnose display again since the state may have changed
  1538. // ******* DiagnoseDisplay ********
  1539. DiagnoseDisplay(&s_sysInfo, s_pDisplayInfoFirst);
  1540. if (pDisplayInfo->m_bDDAccelerationEnabled)
  1541. {
  1542. if( pDisplayInfo->m_bNoHardware )
  1543. {
  1544. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEDD), FALSE);
  1545. }
  1546. else
  1547. {
  1548. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEDD), TRUE);
  1549. }
  1550. LoadString(NULL, IDS_DISABLEDD, sz, MAX_PATH);
  1551. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEDD), sz);
  1552. }
  1553. else
  1554. {
  1555. LoadString(NULL, IDS_ENABLEDD, sz, MAX_PATH);
  1556. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEDD), sz);
  1557. }
  1558. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DDSTATUS), pDisplayInfo->m_szDDStatus );
  1559. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TESTDD), TRUE);
  1560. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TESTD3D), TRUE);
  1561. if (pDisplayInfo->m_b3DAccelerationExists)
  1562. {
  1563. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLED3D), TRUE);
  1564. if (pDisplayInfo->m_b3DAccelerationEnabled)
  1565. {
  1566. LoadString(NULL, IDS_DISABLED3D, sz, MAX_PATH);
  1567. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLED3D), sz);
  1568. }
  1569. else
  1570. {
  1571. LoadString(NULL, IDS_ENABLED3D, sz, MAX_PATH);
  1572. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLED3D), sz);
  1573. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TESTD3D), FALSE);
  1574. }
  1575. }
  1576. else
  1577. {
  1578. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLED3D), FALSE);
  1579. LoadString(NULL, IDS_DISABLED3D, sz, MAX_PATH);
  1580. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLED3D), sz);
  1581. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TESTD3D), FALSE);
  1582. }
  1583. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_D3DSTATUS), pDisplayInfo->m_szD3DStatus);
  1584. // Set AGP button text to enabled or disabled
  1585. if (pDisplayInfo->m_bAGPEnabled)
  1586. LoadString(NULL, IDS_DISABLEAGP, sz, MAX_PATH);
  1587. else
  1588. LoadString(NULL, IDS_ENABLEAGP, sz, MAX_PATH);
  1589. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEAGP), sz);
  1590. // If we are sure that AGP support doesn't exist, show "not avail" for
  1591. // status, and disable button
  1592. if ( (pDisplayInfo->m_bAGPExistenceValid && !pDisplayInfo->m_bAGPExists) ||
  1593. (!pDisplayInfo->m_bDDAccelerationEnabled) )
  1594. {
  1595. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEAGP), FALSE);
  1596. }
  1597. else
  1598. {
  1599. // Otherwise, Show enabled/disabled status and enable button
  1600. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEAGP), TRUE);
  1601. }
  1602. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_AGPSTATUS), pDisplayInfo->m_szAGPStatus);
  1603. // Setup notes area. Clear all text
  1604. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETSEL, 0, -1);
  1605. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1606. EM_REPLACESEL, FALSE, (LPARAM)"");
  1607. ShowBullets();
  1608. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1609. EM_REPLACESEL, FALSE, (LPARAM)pDisplayInfo->m_szNotes);
  1610. // Disable bullets so last line doesn't have an empty bullet
  1611. HideBullets();
  1612. return S_OK;
  1613. }
  1614. /****************************************************************************
  1615. *
  1616. * SetupSoundPage
  1617. *
  1618. ****************************************************************************/
  1619. HRESULT SetupSoundPage(LONG iSound)
  1620. {
  1621. SoundInfo* pSoundInfo;
  1622. TCHAR sz[MAX_PATH];
  1623. if( s_pSoundInfoFirst == NULL )
  1624. return S_OK;
  1625. pSoundInfo = s_pSoundInfoFirst;
  1626. while (iSound > 0)
  1627. {
  1628. pSoundInfo = pSoundInfo->m_pSoundInfoNext;
  1629. iSound--;
  1630. }
  1631. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DESCRIPTION), pSoundInfo->m_szDescription);
  1632. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERNAME), pSoundInfo->m_szDriverName);
  1633. if (lstrlen(pSoundInfo->m_szDriverName) > 0)
  1634. wsprintf(sz, TEXT("%s (%s)"), pSoundInfo->m_szDriverVersion, pSoundInfo->m_szDriverLanguageLocal);
  1635. else
  1636. lstrcpy(sz, TEXT(""));
  1637. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERVERSION), sz);
  1638. if (lstrlen(pSoundInfo->m_szDriverName) > 0)
  1639. {
  1640. if (pSoundInfo->m_bDriverSignedValid)
  1641. {
  1642. if (pSoundInfo->m_bDriverSigned)
  1643. LoadString(NULL, IDS_YES, sz, MAX_PATH);
  1644. else
  1645. LoadString(NULL, IDS_NO, sz, MAX_PATH);
  1646. }
  1647. else
  1648. LoadString(NULL, IDS_NA, sz, MAX_PATH);
  1649. }
  1650. else
  1651. lstrcpy(sz, TEXT(""));
  1652. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DRIVERSIGNED), sz);
  1653. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DEVICETYPE), pSoundInfo->m_szType);
  1654. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DEVICEID), pSoundInfo->m_szDeviceID);
  1655. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_MANUFACTURERID), pSoundInfo->m_szManufacturerID);
  1656. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_PRODUCTID), pSoundInfo->m_szProductID);
  1657. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_OTHERFILES), pSoundInfo->m_szOtherDrivers);
  1658. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_PROVIDER), pSoundInfo->m_szProvider);
  1659. if (pSoundInfo->m_lwAccelerationLevel == -1)
  1660. {
  1661. // Acceleration level cannot be read, so hide controls
  1662. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_SNDACCELLABEL), SW_HIDE);
  1663. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_SNDACCELDESC), SW_HIDE);
  1664. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_SNDACCELSLIDER), SW_HIDE);
  1665. }
  1666. else
  1667. {
  1668. // Acceleration level can be read, so set up controls
  1669. HWND hwndSlider = GetDlgItem(s_hwndCurPage, IDC_SNDACCELSLIDER);
  1670. SendMessage(hwndSlider, TBM_SETRANGE, TRUE, MAKELONG(0, 3));
  1671. SendMessage(hwndSlider, TBM_SETTICFREQ, 1, 0);
  1672. SendMessage(hwndSlider, TBM_SETPOS, TRUE, pSoundInfo->m_lwAccelerationLevel);
  1673. switch (pSoundInfo->m_lwAccelerationLevel)
  1674. {
  1675. case 0:
  1676. LoadString(NULL, IDS_NOSNDACCELERATION, sz, MAX_PATH);
  1677. break;
  1678. case 1:
  1679. LoadString(NULL, IDS_BASICSNDACCELERATION, sz, MAX_PATH);
  1680. break;
  1681. case 2:
  1682. LoadString(NULL, IDS_STANDARDSNDACCELERATION, sz, MAX_PATH);
  1683. break;
  1684. case 3:
  1685. LoadString(NULL, IDS_FULLSNDACCELERATION, sz, MAX_PATH);
  1686. break;
  1687. default:
  1688. lstrcpy(sz, TEXT(""));
  1689. break;
  1690. }
  1691. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_SNDACCELDESC), sz);
  1692. }
  1693. // Diagnose sound again since the state may have changed
  1694. DiagnoseSound(s_pSoundInfoFirst);
  1695. ShowBullets();
  1696. // Setup notes area. Clear all text
  1697. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETSEL, 0, -1);
  1698. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1699. EM_REPLACESEL, FALSE, (LPARAM)"");
  1700. ShowBullets();
  1701. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1702. EM_REPLACESEL, FALSE, (LPARAM)pSoundInfo->m_szNotes);
  1703. // Disable bullets so last line doesn't have an empty bullet
  1704. HideBullets();
  1705. return S_OK;
  1706. }
  1707. /****************************************************************************
  1708. *
  1709. * SetupMusicPage
  1710. *
  1711. ****************************************************************************/
  1712. HRESULT SetupMusicPage(VOID)
  1713. {
  1714. HRESULT hr;
  1715. HWND hwndList = GetDlgItem(s_hwndCurPage, IDC_LIST);
  1716. TCHAR sz[MAX_PATH];
  1717. // Set up HW enable/disable text/button:
  1718. if (s_pMusicInfo->m_bAccelerationExists)
  1719. {
  1720. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEDM), TRUE);
  1721. if (s_pMusicInfo->m_bAccelerationEnabled)
  1722. {
  1723. LoadString(NULL, IDS_ACCELENABLED, sz, MAX_PATH);
  1724. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DMSTATUS), sz);
  1725. LoadString(NULL, IDS_DISABLEDM, sz, MAX_PATH);
  1726. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEDM), sz);
  1727. }
  1728. else
  1729. {
  1730. LoadString(NULL, IDS_ACCELDISABLED, sz, MAX_PATH);
  1731. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DMSTATUS), sz);
  1732. LoadString(NULL, IDS_ENABLEDM, sz, MAX_PATH);
  1733. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEDM), sz);
  1734. }
  1735. }
  1736. else
  1737. {
  1738. LoadString(NULL, IDS_ACCELUNAVAIL, sz, MAX_PATH);
  1739. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DMSTATUS), sz);
  1740. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_DISABLEDM), FALSE);
  1741. LoadString(NULL, IDS_DISABLEDM, sz, MAX_PATH);
  1742. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_DISABLEDM), sz);
  1743. }
  1744. // Setup notes area. Clear all text
  1745. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETSEL, 0, -1);
  1746. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1747. EM_REPLACESEL, FALSE, (LPARAM)"");
  1748. // ******* DiagnoseMusic ********
  1749. DiagnoseMusic(&s_sysInfo, s_pMusicInfo);
  1750. ShowBullets();
  1751. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1752. EM_REPLACESEL, FALSE, (LPARAM)s_sysInfo.m_szMusicNotes);
  1753. // Disable bullets so last line doesn't have an empty bullet
  1754. HideBullets();
  1755. // If column 1 doesn't exist yet, create columns, fill in port info, etc.
  1756. LVCOLUMN lv;
  1757. ZeroMemory(&lv, sizeof(lv));
  1758. lv.mask = LVCF_WIDTH;
  1759. if (FALSE == ListView_GetColumn(hwndList, 1, &lv))
  1760. {
  1761. // Show GM path and version
  1762. if (s_pMusicInfo != NULL)
  1763. {
  1764. if (lstrlen(s_pMusicInfo->m_szGMFileVersion) > 0)
  1765. {
  1766. TCHAR szFmt[MAX_PATH];
  1767. LoadString(NULL, IDS_GMFILEFMT, szFmt, MAX_PATH);
  1768. wsprintf(sz, szFmt, s_pMusicInfo->m_szGMFilePath,
  1769. s_pMusicInfo->m_szGMFileVersion);
  1770. }
  1771. else
  1772. {
  1773. lstrcpy(sz, s_pMusicInfo->m_szGMFilePath);
  1774. }
  1775. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_GMPATH), sz);
  1776. }
  1777. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  1778. if (FAILED(hr = (CreateMusicColumns(hwndList))))
  1779. return hr;
  1780. ListView_DeleteAllItems( hwndList );
  1781. if (FAILED(hr = (AddMusicPortInfo(hwndList, s_pMusicInfo))))
  1782. return hr;
  1783. // Autosize all columns to fit header/text tightly:
  1784. INT iColumn = 0;
  1785. INT iWidthHeader;
  1786. INT iWidthText;
  1787. while (TRUE)
  1788. {
  1789. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  1790. break;
  1791. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  1792. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  1793. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  1794. if (iWidthText < iWidthHeader)
  1795. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  1796. iColumn++;
  1797. }
  1798. // Delete the bogus column that was created
  1799. ListView_DeleteColumn(hwndList, iColumn - 1);
  1800. // Fill in output port combo list:
  1801. MusicPort* pMusicPort;
  1802. LONG iPort = 0;
  1803. LONG iPortTestCur = 0;
  1804. SendMessage(GetDlgItem(s_hwndCurPage, IDC_PORTLISTCOMBO), CB_RESETCONTENT, 0, 0);
  1805. for (pMusicPort = s_pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL;
  1806. pMusicPort = pMusicPort->m_pMusicPortNext)
  1807. {
  1808. if (pMusicPort->m_bOutputPort)
  1809. {
  1810. SendMessage(GetDlgItem(s_hwndCurPage, IDC_PORTLISTCOMBO), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)pMusicPort->m_szDescription);
  1811. if (pMusicPort->m_guid == s_pMusicInfo->m_guidMusicPortTest)
  1812. iPortTestCur = iPort;
  1813. iPort++;
  1814. }
  1815. }
  1816. SendMessage(GetDlgItem(s_hwndCurPage, IDC_PORTLISTCOMBO), CB_SETCURSEL, iPortTestCur, 0);
  1817. }
  1818. return S_OK;
  1819. }
  1820. /****************************************************************************
  1821. *
  1822. * SetupInputPage
  1823. *
  1824. ****************************************************************************/
  1825. HRESULT SetupInputPage(VOID)
  1826. {
  1827. HRESULT hr;
  1828. TCHAR sz[MAX_PATH];
  1829. // Setup notes area. Clear all text
  1830. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETSEL, 0, -1);
  1831. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1832. EM_REPLACESEL, FALSE, (LPARAM)"");
  1833. ShowBullets();
  1834. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  1835. EM_REPLACESEL, FALSE, (LPARAM)s_sysInfo.m_szInputNotes);
  1836. // Disable bullets so last line doesn't have an empty bullet
  1837. HideBullets();
  1838. if (BIsPlatformNT())
  1839. {
  1840. if (FAILED(hr = SetupInputDevicesNT()))
  1841. return hr;
  1842. }
  1843. else
  1844. {
  1845. if (FAILED(hr = SetupInputDevices9x()))
  1846. return hr;
  1847. }
  1848. // Second list: drivers
  1849. HWND hwndList;
  1850. LV_COLUMN col;
  1851. LONG iSubItem = 0;
  1852. LV_ITEM item;
  1853. InputDriverInfo* pInputDriverInfo;
  1854. hwndList = GetDlgItem(s_hwndCurPage, IDC_DRIVERLIST);
  1855. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  1856. iSubItem = 0;
  1857. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1858. col.fmt = LVCFMT_LEFT;
  1859. col.cx = 100;
  1860. LoadString(NULL, IDS_REGISTRYKEY, sz, MAX_PATH);
  1861. col.pszText = sz;
  1862. col.cchTextMax = 100;
  1863. col.iSubItem = iSubItem;
  1864. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1865. return E_FAIL;
  1866. iSubItem++;
  1867. LoadString(NULL, IDS_ACTIVE, sz, MAX_PATH);
  1868. col.pszText = sz;
  1869. col.iSubItem = iSubItem;
  1870. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1871. return E_FAIL;
  1872. iSubItem++;
  1873. LoadString(NULL, IDS_DEVICEID, sz, MAX_PATH);
  1874. col.pszText = sz;
  1875. col.iSubItem = iSubItem;
  1876. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1877. return E_FAIL;
  1878. iSubItem++;
  1879. LoadString(NULL, IDS_MATCHINGDEVID, sz, MAX_PATH);
  1880. col.pszText = sz;
  1881. col.iSubItem = iSubItem;
  1882. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1883. return E_FAIL;
  1884. iSubItem++;
  1885. LoadString(NULL, IDS_DRIVER16, sz, MAX_PATH);
  1886. col.pszText = sz;
  1887. col.iSubItem = iSubItem;
  1888. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1889. return E_FAIL;
  1890. iSubItem++;
  1891. LoadString(NULL, IDS_DRIVER32, sz, MAX_PATH);
  1892. col.pszText = sz;
  1893. col.iSubItem = iSubItem;
  1894. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1895. return E_FAIL;
  1896. iSubItem++;
  1897. // Add a bogus column so SetColumnWidth doesn't do strange
  1898. // things with the last real column
  1899. col.fmt = LVCFMT_RIGHT;
  1900. col.pszText = TEXT("");
  1901. col.iSubItem = iSubItem;
  1902. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1903. return E_FAIL;
  1904. iSubItem++;
  1905. if( s_pInputInfo == NULL )
  1906. return S_OK;
  1907. for (pInputDriverInfo = s_pInputInfo->m_pInputDriverInfoFirst; pInputDriverInfo != NULL;
  1908. pInputDriverInfo = pInputDriverInfo->m_pInputDriverInfoNext)
  1909. {
  1910. iSubItem = 0;
  1911. item.mask = LVIF_TEXT | LVIF_STATE;
  1912. item.iItem = ListView_GetItemCount(hwndList);
  1913. item.stateMask = 0xffff;
  1914. item.cchTextMax = 100;
  1915. if (pInputDriverInfo->m_bProblem)
  1916. item.state = (1 << 12);
  1917. else
  1918. item.state = 0;
  1919. item.iSubItem = iSubItem++;
  1920. item.pszText = pInputDriverInfo->m_szRegKey;
  1921. if (-1 == ListView_InsertItem(hwndList, &item))
  1922. return E_FAIL;
  1923. item.mask = LVIF_TEXT;
  1924. item.iSubItem = iSubItem++;
  1925. if (pInputDriverInfo->m_bActive)
  1926. LoadString(NULL, IDS_YES, sz, MAX_PATH);
  1927. else
  1928. LoadString(NULL, IDS_NO, sz, MAX_PATH);
  1929. item.pszText = sz;
  1930. if (FALSE == ListView_SetItem(hwndList, &item))
  1931. return E_FAIL;
  1932. item.iSubItem = iSubItem++;
  1933. item.pszText = pInputDriverInfo->m_szDeviceID;
  1934. if (FALSE == ListView_SetItem(hwndList, &item))
  1935. return E_FAIL;
  1936. item.iSubItem = iSubItem++;
  1937. item.pszText = pInputDriverInfo->m_szMatchingDeviceID;
  1938. if (FALSE == ListView_SetItem(hwndList, &item))
  1939. return E_FAIL;
  1940. item.iSubItem = iSubItem++;
  1941. item.pszText = pInputDriverInfo->m_szDriver16;
  1942. if (FALSE == ListView_SetItem(hwndList, &item))
  1943. return E_FAIL;
  1944. item.iSubItem = iSubItem++;
  1945. item.pszText = pInputDriverInfo->m_szDriver32;
  1946. if (FALSE == ListView_SetItem(hwndList, &item))
  1947. return E_FAIL;
  1948. }
  1949. // Autosize all columns to fit header/text tightly:
  1950. INT iColumn = 0;
  1951. INT iWidthHeader;
  1952. INT iWidthText;
  1953. while (TRUE)
  1954. {
  1955. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  1956. break;
  1957. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  1958. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  1959. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  1960. if (iWidthText < iWidthHeader)
  1961. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  1962. iColumn++;
  1963. }
  1964. // Delete the bogus column that was created
  1965. ListView_DeleteColumn(hwndList, iColumn - 1);
  1966. return S_OK;
  1967. }
  1968. /****************************************************************************
  1969. *
  1970. * SetupInputDevices9x
  1971. *
  1972. ****************************************************************************/
  1973. HRESULT SetupInputDevices9x(VOID)
  1974. {
  1975. HWND hwndList = GetDlgItem(s_hwndCurPage, IDC_LIST);
  1976. LV_COLUMN col;
  1977. LONG iSubItem = 0;
  1978. LV_ITEM item;
  1979. InputDeviceInfo* pInputDeviceInfo;
  1980. TCHAR sz[MAX_PATH];
  1981. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  1982. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1983. col.fmt = LVCFMT_LEFT;
  1984. col.cx = 100;
  1985. LoadString(NULL, IDS_DEVICENAME, sz, MAX_PATH);
  1986. col.pszText = sz;
  1987. col.cchTextMax = 100;
  1988. col.iSubItem = iSubItem;
  1989. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1990. return E_FAIL;
  1991. iSubItem++;
  1992. LoadString(NULL, IDS_USAGE, sz, MAX_PATH);
  1993. col.pszText = sz;
  1994. col.iSubItem = iSubItem;
  1995. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  1996. return E_FAIL;
  1997. iSubItem++;
  1998. LoadString(NULL, IDS_DRIVERNAME, sz, MAX_PATH);
  1999. col.pszText = sz;
  2000. col.iSubItem = iSubItem;
  2001. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2002. return E_FAIL;
  2003. iSubItem++;
  2004. LoadString(NULL, IDS_VERSION, sz, MAX_PATH);
  2005. col.pszText = sz;
  2006. col.iSubItem = iSubItem;
  2007. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2008. return E_FAIL;
  2009. iSubItem++;
  2010. LoadString(NULL, IDS_ATTRIBUTES, sz, MAX_PATH);
  2011. col.pszText = sz;
  2012. col.iSubItem = iSubItem;
  2013. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2014. return E_FAIL;
  2015. iSubItem++;
  2016. LoadString(NULL, IDS_SIGNED, sz, MAX_PATH);
  2017. col.pszText = sz;
  2018. col.iSubItem = iSubItem;
  2019. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2020. return E_FAIL;
  2021. iSubItem++;
  2022. LoadString(NULL, IDS_LANGUAGE, sz, MAX_PATH);
  2023. col.pszText = sz;
  2024. col.iSubItem = iSubItem;
  2025. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2026. return E_FAIL;
  2027. iSubItem++;
  2028. col.fmt = LVCFMT_RIGHT;
  2029. LoadString(NULL, IDS_DATE, sz, MAX_PATH);
  2030. col.pszText = sz;
  2031. col.iSubItem = iSubItem;
  2032. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2033. return E_FAIL;
  2034. iSubItem++;
  2035. col.fmt = LVCFMT_RIGHT;
  2036. LoadString(NULL, IDS_SIZE, sz, MAX_PATH);
  2037. col.pszText = sz;
  2038. col.iSubItem = iSubItem;
  2039. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2040. return E_FAIL;
  2041. iSubItem++;
  2042. // Add a bogus column so SetColumnWidth doesn't do strange
  2043. // things with the last real column
  2044. col.fmt = LVCFMT_RIGHT;
  2045. col.pszText = TEXT("");
  2046. col.iSubItem = iSubItem;
  2047. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2048. return E_FAIL;
  2049. iSubItem++;
  2050. for (pInputDeviceInfo = s_pInputInfo->m_pInputDeviceInfoFirst; pInputDeviceInfo != NULL;
  2051. pInputDeviceInfo = pInputDeviceInfo->m_pInputDeviceInfoNext)
  2052. {
  2053. iSubItem = 0;
  2054. item.mask = LVIF_TEXT | LVIF_STATE;
  2055. item.iItem = ListView_GetItemCount(hwndList);
  2056. item.stateMask = 0xffff;
  2057. item.cchTextMax = 100;
  2058. if (pInputDeviceInfo->m_bProblem)
  2059. item.state = (1 << 12);
  2060. else
  2061. item.state = 0;
  2062. item.iSubItem = iSubItem++;
  2063. item.pszText = pInputDeviceInfo->m_szDeviceName;
  2064. if (-1 == ListView_InsertItem(hwndList, &item))
  2065. return E_FAIL;
  2066. item.mask = LVIF_TEXT;
  2067. item.iSubItem = iSubItem++;
  2068. item.pszText = pInputDeviceInfo->m_szSettings;
  2069. if (FALSE == ListView_SetItem(hwndList, &item))
  2070. return E_FAIL;
  2071. item.iSubItem = iSubItem++;
  2072. item.pszText = pInputDeviceInfo->m_szDriverName;
  2073. if (FALSE == ListView_SetItem(hwndList, &item))
  2074. return E_FAIL;
  2075. item.iSubItem = iSubItem++;
  2076. item.pszText = pInputDeviceInfo->m_szDriverVersion;
  2077. if (FALSE == ListView_SetItem(hwndList, &item))
  2078. return E_FAIL;
  2079. item.iSubItem = iSubItem++;
  2080. item.pszText = pInputDeviceInfo->m_szDriverAttributes;
  2081. if (FALSE == ListView_SetItem(hwndList, &item))
  2082. return E_FAIL;
  2083. item.iSubItem = iSubItem++;
  2084. if (pInputDeviceInfo->m_bDriverSignedValid)
  2085. {
  2086. if (pInputDeviceInfo->m_bDriverSigned)
  2087. LoadString(NULL, IDS_YES, sz, MAX_PATH);
  2088. else
  2089. LoadString(NULL, IDS_NO, sz, MAX_PATH);
  2090. }
  2091. else
  2092. LoadString(NULL, IDS_NA, sz, MAX_PATH);
  2093. item.pszText = sz;
  2094. if (FALSE == ListView_SetItem(hwndList, &item))
  2095. return E_FAIL;
  2096. item.iSubItem = iSubItem++;
  2097. item.pszText = pInputDeviceInfo->m_szDriverLanguageLocal;
  2098. if (FALSE == ListView_SetItem(hwndList, &item))
  2099. return E_FAIL;
  2100. item.iSubItem = iSubItem++;
  2101. item.pszText = pInputDeviceInfo->m_szDriverDateLocal;
  2102. if (FALSE == ListView_SetItem(hwndList, &item))
  2103. return E_FAIL;
  2104. item.iSubItem = iSubItem++;
  2105. wsprintf(sz, TEXT("%d"), pInputDeviceInfo->m_numBytes);
  2106. item.pszText = sz;
  2107. if (FALSE == ListView_SetItem(hwndList, &item))
  2108. return E_FAIL;
  2109. }
  2110. // Autosize all columns to fit header/text tightly:
  2111. INT iColumn = 0;
  2112. INT iWidthHeader;
  2113. INT iWidthText;
  2114. while (TRUE)
  2115. {
  2116. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  2117. break;
  2118. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  2119. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  2120. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  2121. if (iWidthText < iWidthHeader)
  2122. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  2123. iColumn++;
  2124. }
  2125. // Delete the bogus column that was created
  2126. ListView_DeleteColumn(hwndList, iColumn - 1);
  2127. return S_OK;
  2128. }
  2129. /****************************************************************************
  2130. *
  2131. * SetupInputDevicesNT
  2132. *
  2133. ****************************************************************************/
  2134. HRESULT SetupInputDevicesNT(VOID)
  2135. {
  2136. HWND hwndList = GetDlgItem(s_hwndCurPage, IDC_LIST);
  2137. LV_COLUMN col;
  2138. LONG iSubItem = 0;
  2139. LV_ITEM item;
  2140. InputDeviceInfoNT* pInputDeviceInfoNT;
  2141. TCHAR sz[MAX_PATH];
  2142. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  2143. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2144. col.fmt = LVCFMT_LEFT;
  2145. col.cx = 100;
  2146. LoadString(NULL, IDS_DEVICENAME, sz, MAX_PATH);
  2147. col.pszText = sz;
  2148. col.cchTextMax = 100;
  2149. col.iSubItem = iSubItem;
  2150. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2151. return E_FAIL;
  2152. iSubItem++;
  2153. LoadString(NULL, IDS_PROVIDER, sz, MAX_PATH);
  2154. col.pszText = sz;
  2155. col.iSubItem = iSubItem;
  2156. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2157. return E_FAIL;
  2158. iSubItem++;
  2159. LoadString(NULL, IDS_DEVICEID, sz, MAX_PATH);
  2160. col.pszText = sz;
  2161. col.iSubItem = iSubItem;
  2162. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2163. return E_FAIL;
  2164. iSubItem++;
  2165. LoadString(NULL, IDS_STATUS, sz, MAX_PATH);
  2166. col.pszText = sz;
  2167. col.iSubItem = iSubItem;
  2168. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2169. return E_FAIL;
  2170. iSubItem++;
  2171. LoadString(NULL, IDS_PORTNAME, sz, MAX_PATH);
  2172. col.pszText = sz;
  2173. col.iSubItem = iSubItem;
  2174. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2175. return E_FAIL;
  2176. iSubItem++;
  2177. LoadString(NULL, IDS_PORTPROVIDER, sz, MAX_PATH);
  2178. col.pszText = sz;
  2179. col.iSubItem = iSubItem;
  2180. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2181. return E_FAIL;
  2182. iSubItem++;
  2183. LoadString(NULL, IDS_PORTID, sz, MAX_PATH);
  2184. col.pszText = sz;
  2185. col.iSubItem = iSubItem;
  2186. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2187. return E_FAIL;
  2188. iSubItem++;
  2189. LoadString(NULL, IDS_PORTSTATUS, sz, MAX_PATH);
  2190. col.pszText = sz;
  2191. col.iSubItem = iSubItem;
  2192. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2193. return E_FAIL;
  2194. iSubItem++;
  2195. // Add a bogus column so SetColumnWidth doesn't do strange
  2196. // things with the last real column
  2197. col.fmt = LVCFMT_RIGHT;
  2198. col.pszText = TEXT("");
  2199. col.iSubItem = iSubItem;
  2200. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2201. return E_FAIL;
  2202. iSubItem++;
  2203. if( s_pInputInfo == NULL )
  2204. return S_OK;
  2205. for (pInputDeviceInfoNT = s_pInputInfo->m_pInputDeviceInfoNTFirst; pInputDeviceInfoNT != NULL;
  2206. pInputDeviceInfoNT = pInputDeviceInfoNT->m_pInputDeviceInfoNTNext)
  2207. {
  2208. iSubItem = 0;
  2209. item.mask = LVIF_TEXT | LVIF_STATE;
  2210. item.iItem = ListView_GetItemCount(hwndList);
  2211. item.stateMask = 0xffff;
  2212. item.cchTextMax = 100;
  2213. if (pInputDeviceInfoNT->m_bProblem)
  2214. item.state = (1 << 12);
  2215. else
  2216. item.state = 0;
  2217. item.iSubItem = iSubItem++;
  2218. item.pszText = pInputDeviceInfoNT->m_szName;
  2219. if (-1 == ListView_InsertItem(hwndList, &item))
  2220. return E_FAIL;
  2221. item.mask = LVIF_TEXT;
  2222. item.iSubItem = iSubItem++;
  2223. item.pszText = pInputDeviceInfoNT->m_szProvider;
  2224. if (FALSE == ListView_SetItem(hwndList, &item))
  2225. return E_FAIL;
  2226. item.iSubItem = iSubItem++;
  2227. item.pszText = pInputDeviceInfoNT->m_szId;
  2228. if (FALSE == ListView_SetItem(hwndList, &item))
  2229. return E_FAIL;
  2230. wsprintf(sz, TEXT("0x%x, 0x%x"), pInputDeviceInfoNT->m_dwStatus, pInputDeviceInfoNT->m_dwProblem);
  2231. item.iSubItem = iSubItem++;
  2232. item.pszText = sz;
  2233. if (FALSE == ListView_SetItem(hwndList, &item))
  2234. return E_FAIL;
  2235. item.iSubItem = iSubItem++;
  2236. item.pszText = pInputDeviceInfoNT->m_szPortName;
  2237. if (FALSE == ListView_SetItem(hwndList, &item))
  2238. return E_FAIL;
  2239. item.iSubItem = iSubItem++;
  2240. item.pszText = pInputDeviceInfoNT->m_szPortProvider;
  2241. if (FALSE == ListView_SetItem(hwndList, &item))
  2242. return E_FAIL;
  2243. item.iSubItem = iSubItem++;
  2244. item.pszText = pInputDeviceInfoNT->m_szPortId;
  2245. if (FALSE == ListView_SetItem(hwndList, &item))
  2246. return E_FAIL;
  2247. wsprintf(sz, TEXT("0x%x, 0x%x"), pInputDeviceInfoNT->m_dwPortStatus, pInputDeviceInfoNT->m_dwPortProblem);
  2248. item.iSubItem = iSubItem++;
  2249. item.pszText = sz;
  2250. if (FALSE == ListView_SetItem(hwndList, &item))
  2251. return E_FAIL;
  2252. }
  2253. // Autosize all columns to fit header/text tightly:
  2254. INT iColumn = 0;
  2255. INT iWidthHeader;
  2256. INT iWidthText;
  2257. while (TRUE)
  2258. {
  2259. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  2260. break;
  2261. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  2262. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  2263. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  2264. if (iWidthText < iWidthHeader)
  2265. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  2266. iColumn++;
  2267. }
  2268. // Delete the bogus column that was created
  2269. ListView_DeleteColumn(hwndList, iColumn - 1);
  2270. return S_OK;
  2271. }
  2272. /****************************************************************************
  2273. *
  2274. * SetupNetworkPage
  2275. *
  2276. ****************************************************************************/
  2277. HRESULT SetupNetworkPage(VOID)
  2278. {
  2279. TCHAR sz[MAX_PATH];
  2280. // Diagnose net info again since the state may have changed
  2281. // ******* DiagnoseNetInfo ********
  2282. DiagnoseNetInfo(&s_sysInfo, s_pNetInfo);
  2283. // Setup notes area. Clear all text
  2284. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES), EM_SETSEL, 0, -1);
  2285. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  2286. EM_REPLACESEL, FALSE, (LPARAM)"");
  2287. ShowBullets();
  2288. SendMessage(GetDlgItem(s_hwndCurPage, IDC_NOTES),
  2289. EM_REPLACESEL, FALSE, (LPARAM)s_sysInfo.m_szNetworkNotes);
  2290. // Disable bullets so last line doesn't have an empty bullet
  2291. HideBullets();
  2292. if( s_pNetInfo == NULL )
  2293. return S_OK;
  2294. // If column 1 doesn't exist yet, create columns, fill in port info, etc.
  2295. HWND hwndList = GetDlgItem(s_hwndCurPage, IDC_DPSPLIST);
  2296. LVCOLUMN lv;
  2297. ZeroMemory(&lv, sizeof(lv));
  2298. lv.mask = LVCF_WIDTH;
  2299. if (FALSE == ListView_GetColumn(hwndList, 1, &lv))
  2300. {
  2301. // Set up service provider list
  2302. LV_COLUMN col;
  2303. LONG iSubItem = 0;
  2304. LV_ITEM item;
  2305. NetSP* pNetSP;
  2306. NetApp* pNetApp;
  2307. // First list: service providers
  2308. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  2309. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2310. col.fmt = LVCFMT_LEFT;
  2311. col.cx = 100;
  2312. LoadString(NULL, IDS_NAME, sz, MAX_PATH);
  2313. col.pszText = sz;
  2314. col.cchTextMax = 100;
  2315. col.iSubItem = iSubItem;
  2316. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2317. return E_FAIL;
  2318. iSubItem++;
  2319. LoadString(NULL, IDS_REGISTRY, sz, MAX_PATH);
  2320. col.pszText = sz;
  2321. col.iSubItem = iSubItem;
  2322. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2323. return E_FAIL;
  2324. iSubItem++;
  2325. LoadString(NULL, IDS_FILE, sz, MAX_PATH);
  2326. col.pszText = sz;
  2327. col.iSubItem = iSubItem;
  2328. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2329. return E_FAIL;
  2330. iSubItem++;
  2331. LoadString(NULL, IDS_VERSION, sz, MAX_PATH);
  2332. col.pszText = sz;
  2333. col.iSubItem = iSubItem;
  2334. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2335. return E_FAIL;
  2336. iSubItem++;
  2337. // Add a bogus column so SetColumnWidth doesn't do strange
  2338. // things with the last real column
  2339. col.fmt = LVCFMT_RIGHT;
  2340. col.pszText = TEXT("");
  2341. col.iSubItem = iSubItem;
  2342. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2343. return E_FAIL;
  2344. iSubItem++;
  2345. for (pNetSP = s_pNetInfo->m_pNetSPFirst; pNetSP != NULL;
  2346. pNetSP = pNetSP->m_pNetSPNext)
  2347. {
  2348. iSubItem = 0;
  2349. item.mask = LVIF_TEXT | LVIF_STATE;
  2350. item.iItem = ListView_GetItemCount(hwndList);
  2351. item.stateMask = 0xffff;
  2352. item.cchTextMax = 100;
  2353. if (pNetSP->m_bProblem)
  2354. item.state = (1 << 12);
  2355. else
  2356. item.state = 0;
  2357. item.iSubItem = iSubItem++;
  2358. item.pszText = pNetSP->m_szName;
  2359. if (-1 == ListView_InsertItem(hwndList, &item))
  2360. return E_FAIL;
  2361. item.mask = LVIF_TEXT;
  2362. item.iSubItem = iSubItem++;
  2363. if (pNetSP->m_bRegistryOK)
  2364. LoadString(NULL, IDS_OK, sz, MAX_PATH);
  2365. else
  2366. LoadString(NULL, IDS_ERROR, sz, MAX_PATH);
  2367. item.pszText = sz;
  2368. if (FALSE == ListView_SetItem(hwndList, &item))
  2369. return E_FAIL;
  2370. item.iSubItem = iSubItem++;
  2371. item.pszText = pNetSP->m_szFile;
  2372. if (FALSE == ListView_SetItem(hwndList, &item))
  2373. return E_FAIL;
  2374. item.iSubItem = iSubItem++;
  2375. item.pszText = pNetSP->m_szVersion;
  2376. if (FALSE == ListView_SetItem(hwndList, &item))
  2377. return E_FAIL;
  2378. }
  2379. // Autosize all columns to fit header/text tightly:
  2380. INT iColumn = 0;
  2381. INT iWidthHeader;
  2382. INT iWidthText;
  2383. while (TRUE)
  2384. {
  2385. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  2386. break;
  2387. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  2388. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  2389. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  2390. if (iWidthText < iWidthHeader)
  2391. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  2392. iColumn++;
  2393. }
  2394. // Delete the bogus column that was created
  2395. ListView_DeleteColumn(hwndList, iColumn - 1);
  2396. // Second list: lobbyable apps
  2397. hwndList = GetDlgItem(s_hwndCurPage, IDC_DPALIST);
  2398. ListView_SetImageList(hwndList, s_himgList, LVSIL_STATE);
  2399. iSubItem = 0;
  2400. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2401. col.fmt = LVCFMT_LEFT;
  2402. col.cx = 100;
  2403. LoadString(NULL, IDS_NAME, sz, MAX_PATH);
  2404. col.pszText = sz;
  2405. col.cchTextMax = 100;
  2406. col.iSubItem = iSubItem;
  2407. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2408. return E_FAIL;
  2409. iSubItem++;
  2410. LoadString(NULL, IDS_REGISTRY, sz, MAX_PATH);
  2411. col.pszText = sz;
  2412. col.iSubItem = iSubItem;
  2413. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2414. return E_FAIL;
  2415. iSubItem++;
  2416. LoadString(NULL, IDS_FILE, sz, MAX_PATH);
  2417. col.pszText = sz;
  2418. col.iSubItem = iSubItem;
  2419. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2420. return E_FAIL;
  2421. iSubItem++;
  2422. LoadString(NULL, IDS_VERSION, sz, MAX_PATH);
  2423. col.pszText = sz;
  2424. col.iSubItem = iSubItem;
  2425. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2426. return E_FAIL;
  2427. iSubItem++;
  2428. LoadString(NULL, IDS_GUID, sz, MAX_PATH);
  2429. col.pszText = sz;
  2430. col.iSubItem = iSubItem;
  2431. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2432. return E_FAIL;
  2433. iSubItem++;
  2434. // Add a bogus column so SetColumnWidth doesn't do strange
  2435. // things with the last real column
  2436. col.fmt = LVCFMT_RIGHT;
  2437. col.pszText = TEXT("");
  2438. col.iSubItem = iSubItem;
  2439. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2440. return E_FAIL;
  2441. iSubItem++;
  2442. for (pNetApp = s_pNetInfo->m_pNetAppFirst; pNetApp != NULL;
  2443. pNetApp = pNetApp->m_pNetAppNext)
  2444. {
  2445. iSubItem = 0;
  2446. item.mask = LVIF_TEXT | LVIF_STATE;
  2447. item.iItem = ListView_GetItemCount(hwndList);
  2448. item.stateMask = 0xffff;
  2449. item.cchTextMax = 100;
  2450. if (pNetApp->m_bProblem)
  2451. item.state = (1 << 12);
  2452. else
  2453. item.state = 0;
  2454. item.iSubItem = iSubItem++;
  2455. item.pszText = pNetApp->m_szName;
  2456. if (-1 == ListView_InsertItem(hwndList, &item))
  2457. return E_FAIL;
  2458. item.mask = LVIF_TEXT;
  2459. item.iSubItem = iSubItem++;
  2460. if (pNetApp->m_bRegistryOK)
  2461. LoadString(NULL, IDS_OK, sz, MAX_PATH);
  2462. else
  2463. LoadString(NULL, IDS_ERROR, sz, MAX_PATH);
  2464. item.pszText = sz;
  2465. if (FALSE == ListView_SetItem(hwndList, &item))
  2466. return E_FAIL;
  2467. item.iSubItem = iSubItem++;
  2468. item.pszText = pNetApp->m_szExeFile;
  2469. if (FALSE == ListView_SetItem(hwndList, &item))
  2470. return E_FAIL;
  2471. item.iSubItem = iSubItem++;
  2472. item.pszText = pNetApp->m_szExeVersion;
  2473. if (FALSE == ListView_SetItem(hwndList, &item))
  2474. return E_FAIL;
  2475. item.iSubItem = iSubItem++;
  2476. item.pszText = pNetApp->m_szGuid;
  2477. if (FALSE == ListView_SetItem(hwndList, &item))
  2478. return E_FAIL;
  2479. }
  2480. // Autosize all columns to fit header/text tightly:
  2481. iColumn = 0;
  2482. iWidthHeader;
  2483. iWidthText;
  2484. while (TRUE)
  2485. {
  2486. if (FALSE == ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE_USEHEADER))
  2487. break;
  2488. iWidthHeader = ListView_GetColumnWidth(hwndList, iColumn);
  2489. ListView_SetColumnWidth(hwndList, iColumn, LVSCW_AUTOSIZE);
  2490. iWidthText = ListView_GetColumnWidth(hwndList, iColumn);
  2491. if (iWidthText < iWidthHeader)
  2492. ListView_SetColumnWidth(hwndList, iColumn, iWidthHeader);
  2493. iColumn++;
  2494. }
  2495. // Delete the bogus column that was created
  2496. ListView_DeleteColumn(hwndList, iColumn - 1);
  2497. }
  2498. return S_OK;
  2499. }
  2500. /****************************************************************************
  2501. *
  2502. * SetupStillStuckPage
  2503. *
  2504. ****************************************************************************/
  2505. HRESULT SetupStillStuckPage(VOID)
  2506. {
  2507. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOT), FALSE );
  2508. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOTSOUND), FALSE );
  2509. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_MSINFO), FALSE );
  2510. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_RESTOREDRIVERS), FALSE );
  2511. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_REPORTBUG), FALSE );
  2512. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_GHOST), FALSE );
  2513. // Hide "Troubleshooter" text/button if help file not found
  2514. BOOL bFound;
  2515. TCHAR szHelpPath[MAX_PATH];
  2516. TCHAR szHelpLeaf[MAX_PATH];
  2517. TCHAR szTroubleshooter[MAX_PATH];
  2518. GetWindowsDirectory(szHelpPath, MAX_PATH);
  2519. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  2520. lstrcat(szHelpPath, szHelpLeaf);
  2521. if( BIsWin98() || BIsWin95() )
  2522. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  2523. else if( BIsWinME() )
  2524. LoadString(NULL, IDS_TROUBLESHOOTER_WINME, szTroubleshooter, MAX_PATH);
  2525. else if( BIsWin2k() || BIsWhistler() )
  2526. LoadString(NULL, IDS_TROUBLESHOOTER_WIN2K, szTroubleshooter, MAX_PATH);
  2527. bFound = FALSE;
  2528. lstrcat(szHelpPath, TEXT("\\"));
  2529. lstrcat(szHelpPath, szTroubleshooter);
  2530. if (GetFileAttributes(szHelpPath) != 0xffffffff)
  2531. {
  2532. bFound = TRUE;
  2533. }
  2534. else if( BIsWin98() || BIsWin95() )
  2535. {
  2536. GetWindowsDirectory(szHelpPath, MAX_PATH);
  2537. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  2538. lstrcat(szHelpPath, szHelpLeaf);
  2539. lstrcat(szHelpPath, TEXT("\\"));
  2540. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98, szTroubleshooter, MAX_PATH);
  2541. lstrcat(szHelpPath, szTroubleshooter);
  2542. if (GetFileAttributes(szHelpPath) != 0xffffffff)
  2543. bFound = TRUE;
  2544. }
  2545. if( bFound )
  2546. {
  2547. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOT), SW_SHOW);
  2548. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOT), TRUE);
  2549. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOTTEXT), SW_SHOW);
  2550. }
  2551. // Hide "Sound Troubleshooter" text/button if help file not found
  2552. GetWindowsDirectory(szHelpPath, MAX_PATH);
  2553. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  2554. lstrcat(szHelpPath, szHelpLeaf);
  2555. if( BIsWin98() || BIsWin95() )
  2556. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  2557. else if( BIsWinME() )
  2558. LoadString(NULL, IDS_TROUBLESHOOTER_WINME, szTroubleshooter, MAX_PATH);
  2559. else if( BIsWin2k() || BIsWhistler() )
  2560. LoadString(NULL, IDS_TROUBLESHOOTER_WIN2K, szTroubleshooter, MAX_PATH);
  2561. bFound = FALSE;
  2562. lstrcat(szHelpPath, TEXT("\\"));
  2563. lstrcat(szHelpPath, szTroubleshooter);
  2564. if (GetFileAttributes(szHelpPath) != 0xffffffff)
  2565. {
  2566. bFound = TRUE;
  2567. }
  2568. else if( BIsWin98() || BIsWin95() )
  2569. {
  2570. GetWindowsDirectory(szHelpPath, MAX_PATH);
  2571. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  2572. lstrcat(szHelpPath, szHelpLeaf);
  2573. lstrcat(szHelpPath, TEXT("\\"));
  2574. LoadString(NULL, IDS_SOUNDTROUBLESHOOTER_WIN98, szTroubleshooter, MAX_PATH);
  2575. lstrcat(szHelpPath, szTroubleshooter);
  2576. if (GetFileAttributes(szHelpPath) != 0xffffffff)
  2577. bFound = TRUE;
  2578. }
  2579. if( bFound )
  2580. {
  2581. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOTSOUND), SW_SHOW);
  2582. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOTSOUND), TRUE);
  2583. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_TROUBLESHOOTSOUNDTEXT), SW_SHOW);
  2584. }
  2585. // Hide "MSInfo" text/button if msinfo32.exe not found
  2586. HKEY hkey;
  2587. TCHAR szMsInfo[MAX_PATH];
  2588. DWORD cbData = MAX_PATH;
  2589. DWORD dwType;
  2590. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2591. TEXT("Software\\Microsoft\\Shared Tools\\MSInfo"), 0, KEY_READ, &hkey))
  2592. {
  2593. RegQueryValueEx(hkey, TEXT("Path"), 0, &dwType, (LPBYTE)szMsInfo, &cbData);
  2594. if (GetFileAttributes(szMsInfo) != 0xffffffff)
  2595. {
  2596. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_MSINFO), SW_SHOW);
  2597. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_MSINFO), TRUE);
  2598. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_MSINFOTEXT), SW_SHOW);
  2599. }
  2600. RegCloseKey(hkey);
  2601. }
  2602. // Hide "Restore" text/button if dxsetup.exe not found
  2603. if (BCanRestoreDrivers())
  2604. {
  2605. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_RESTOREDRIVERS), SW_SHOW);
  2606. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_RESTOREDRIVERSTEXT), SW_SHOW);
  2607. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_RESTOREDRIVERS), TRUE);
  2608. }
  2609. // Only show "Report" text/button if magic registry key is set
  2610. BOOL bReport = FALSE;
  2611. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2612. TEXT("Software\\Microsoft\\DirectX Diagnostic Tool"), 0, KEY_READ, &hkey))
  2613. {
  2614. cbData = sizeof(bReport);
  2615. RegQueryValueEx(hkey, TEXT("Allow Bug Report"), 0, &dwType, (LPBYTE)&bReport, &cbData);
  2616. if (bReport)
  2617. {
  2618. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_REPORTBUG), SW_SHOW);
  2619. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_REPORTBUG), TRUE);
  2620. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_REPORTBUGTEXT), SW_SHOW);
  2621. }
  2622. RegCloseKey(hkey);
  2623. }
  2624. // Only show "Adjust Ghost Devices" text/button if s_bGhost is set and not NT
  2625. if (s_bGhost && !BIsPlatformNT())
  2626. {
  2627. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_GHOST), SW_SHOW);
  2628. EnableWindow(GetDlgItem(s_hwndCurPage, IDC_GHOST), TRUE);
  2629. ShowWindow(GetDlgItem(s_hwndCurPage, IDC_GHOSTTEXT), SW_SHOW);
  2630. }
  2631. return S_OK;
  2632. }
  2633. /****************************************************************************
  2634. *
  2635. * CreateFileInfoColumns
  2636. *
  2637. ****************************************************************************/
  2638. HRESULT CreateFileInfoColumns(HWND hwndList, BOOL bDrivers)
  2639. {
  2640. LV_COLUMN col;
  2641. LONG iSubItem = 0;
  2642. TCHAR sz[MAX_PATH];
  2643. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2644. col.fmt = LVCFMT_LEFT;
  2645. col.cx = 100;
  2646. LoadString(NULL, IDS_NAME, sz, MAX_PATH);
  2647. col.pszText = sz;
  2648. col.cchTextMax = 100;
  2649. col.iSubItem = iSubItem;
  2650. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2651. return E_FAIL;
  2652. iSubItem++;
  2653. LoadString(NULL, IDS_VERSION, sz, MAX_PATH);
  2654. col.pszText = sz;
  2655. col.iSubItem = iSubItem;
  2656. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2657. return E_FAIL;
  2658. iSubItem++;
  2659. if (bDrivers)
  2660. {
  2661. LoadString(NULL, IDS_SIGNED, sz, MAX_PATH);
  2662. col.pszText = sz;
  2663. col.iSubItem = iSubItem;
  2664. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2665. return E_FAIL;
  2666. iSubItem++;
  2667. }
  2668. else
  2669. {
  2670. LoadString(NULL, IDS_ATTRIBUTES, sz, MAX_PATH);
  2671. col.pszText = sz;
  2672. col.iSubItem = iSubItem;
  2673. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2674. return E_FAIL;
  2675. iSubItem++;
  2676. }
  2677. LoadString(NULL, IDS_LANGUAGE, sz, MAX_PATH);
  2678. col.pszText = sz;
  2679. col.iSubItem = iSubItem;
  2680. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2681. return E_FAIL;
  2682. iSubItem++;
  2683. col.fmt = LVCFMT_RIGHT;
  2684. LoadString(NULL, IDS_DATE, sz, MAX_PATH);
  2685. col.pszText = sz;
  2686. col.iSubItem = iSubItem;
  2687. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2688. return E_FAIL;
  2689. iSubItem++;
  2690. col.fmt = LVCFMT_RIGHT;
  2691. LoadString(NULL, IDS_SIZE, sz, MAX_PATH);
  2692. col.pszText = sz;
  2693. col.iSubItem = iSubItem;
  2694. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2695. return E_FAIL;
  2696. iSubItem++;
  2697. // Add a bogus column so SetColumnWidth doesn't do strange
  2698. // things with the last real column
  2699. col.fmt = LVCFMT_RIGHT;
  2700. col.pszText = TEXT("");
  2701. col.iSubItem = iSubItem;
  2702. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2703. return E_FAIL;
  2704. iSubItem++;
  2705. return S_OK;
  2706. }
  2707. /****************************************************************************
  2708. *
  2709. * AddFileInfo
  2710. *
  2711. ****************************************************************************/
  2712. HRESULT AddFileInfo(HWND hwndList, FileInfo* pFileInfoFirst, BOOL bDrivers)
  2713. {
  2714. FileInfo* pFileInfo;
  2715. LV_ITEM item;
  2716. LONG iSubItem;
  2717. TCHAR sz[MAX_PATH];
  2718. for (pFileInfo = pFileInfoFirst; pFileInfo != NULL;
  2719. pFileInfo = pFileInfo->m_pFileInfoNext)
  2720. {
  2721. // Don't list missing files unless they're a "problem"
  2722. if (!pFileInfo->m_bExists && !pFileInfo->m_bProblem)
  2723. continue;
  2724. // manbugs 16765: don't list obsolete files
  2725. if (pFileInfo->m_bObsolete)
  2726. continue;
  2727. iSubItem = 0;
  2728. item.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  2729. item.iItem = ListView_GetItemCount(hwndList);
  2730. item.stateMask = 0xffff;
  2731. item.cchTextMax = 100;
  2732. item.lParam = (LPARAM) pFileInfo;
  2733. if (pFileInfo->m_bProblem)
  2734. item.state = (1 << 12);
  2735. else
  2736. item.state = 0;
  2737. item.iSubItem = iSubItem++;
  2738. item.pszText = pFileInfo->m_szName;
  2739. if (-1 == ListView_InsertItem(hwndList, &item))
  2740. return E_FAIL;
  2741. item.mask = LVIF_TEXT;
  2742. item.iSubItem = iSubItem++;
  2743. item.pszText = pFileInfo->m_szVersion;
  2744. if (FALSE == ListView_SetItem(hwndList, &item))
  2745. return E_FAIL;
  2746. if (bDrivers)
  2747. {
  2748. item.iSubItem = iSubItem++;
  2749. if (lstrcmpi(TEXT(".drv"), _tcsrchr(pFileInfo->m_szName, '.')) == 0)
  2750. {
  2751. if (pFileInfo->m_bSigned)
  2752. LoadString(NULL, IDS_YES, sz, MAX_PATH);
  2753. else
  2754. LoadString(NULL, IDS_NO, sz, MAX_PATH);
  2755. }
  2756. else
  2757. {
  2758. LoadString(NULL, IDS_NA, sz, MAX_PATH);
  2759. }
  2760. item.pszText = sz;
  2761. if (FALSE == ListView_SetItem(hwndList, &item))
  2762. return E_FAIL;
  2763. }
  2764. else
  2765. {
  2766. item.iSubItem = iSubItem++;
  2767. item.pszText = pFileInfo->m_szAttributes;
  2768. if (FALSE == ListView_SetItem(hwndList, &item))
  2769. return E_FAIL;
  2770. }
  2771. item.iSubItem = iSubItem++;
  2772. item.pszText = pFileInfo->m_szLanguageLocal;
  2773. if (FALSE == ListView_SetItem(hwndList, &item))
  2774. return E_FAIL;
  2775. item.iSubItem = iSubItem++;
  2776. item.pszText = pFileInfo->m_szDatestampLocal;
  2777. if (FALSE == ListView_SetItem(hwndList, &item))
  2778. return E_FAIL;
  2779. item.iSubItem = iSubItem++;
  2780. wsprintf(sz, TEXT("%d"), pFileInfo->m_numBytes);
  2781. item.pszText = sz;
  2782. if (FALSE == ListView_SetItem(hwndList, &item))
  2783. return E_FAIL;
  2784. }
  2785. return S_OK;
  2786. }
  2787. /****************************************************************************
  2788. *
  2789. * CreateMusicColumns
  2790. *
  2791. ****************************************************************************/
  2792. HRESULT CreateMusicColumns(HWND hwndList)
  2793. {
  2794. LV_COLUMN col;
  2795. LONG iSubItem = 0;
  2796. TCHAR sz[MAX_PATH];
  2797. col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2798. col.fmt = LVCFMT_LEFT;
  2799. col.cx = 100;
  2800. LoadString(NULL, IDS_DESCRIPTION, sz, MAX_PATH);
  2801. col.pszText = sz;
  2802. col.cchTextMax = 100;
  2803. col.iSubItem = iSubItem;
  2804. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2805. return E_FAIL;
  2806. iSubItem++;
  2807. LoadString(NULL, IDS_TYPE, sz, MAX_PATH);
  2808. col.pszText = sz;
  2809. col.iSubItem = iSubItem;
  2810. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2811. return E_FAIL;
  2812. iSubItem++;
  2813. LoadString(NULL, IDS_KERNELMODE, sz, MAX_PATH);
  2814. col.fmt = LVCFMT_RIGHT;
  2815. col.pszText = sz;
  2816. col.iSubItem = iSubItem;
  2817. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2818. return E_FAIL;
  2819. iSubItem++;
  2820. LoadString(NULL, IDS_INOUT, sz, MAX_PATH);
  2821. col.pszText = sz;
  2822. col.iSubItem = iSubItem;
  2823. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2824. return E_FAIL;
  2825. iSubItem++;
  2826. LoadString(NULL, IDS_DLS, sz, MAX_PATH);
  2827. col.fmt = LVCFMT_RIGHT;
  2828. col.pszText = sz;
  2829. col.iSubItem = iSubItem;
  2830. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2831. return E_FAIL;
  2832. iSubItem++;
  2833. LoadString(NULL, IDS_EXTERNAL, sz, MAX_PATH);
  2834. col.fmt = LVCFMT_RIGHT;
  2835. col.pszText = sz;
  2836. col.iSubItem = iSubItem;
  2837. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2838. return E_FAIL;
  2839. iSubItem++;
  2840. LoadString(NULL, IDS_DEFAULTPORT, sz, MAX_PATH);
  2841. col.fmt = LVCFMT_RIGHT;
  2842. col.pszText = sz;
  2843. col.iSubItem = iSubItem;
  2844. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2845. return E_FAIL;
  2846. iSubItem++;
  2847. // Add a bogus column so SetColumnWidth doesn't do strange
  2848. // things with the last real column
  2849. col.fmt = LVCFMT_RIGHT;
  2850. col.pszText = TEXT("");
  2851. col.iSubItem = iSubItem;
  2852. if (-1 == ListView_InsertColumn(hwndList, iSubItem, &col))
  2853. return E_FAIL;
  2854. iSubItem++;
  2855. return S_OK;
  2856. }
  2857. /****************************************************************************
  2858. *
  2859. * AddMusicPortInfo
  2860. *
  2861. ****************************************************************************/
  2862. HRESULT AddMusicPortInfo(HWND hwndList, MusicInfo* pMusicInfo)
  2863. {
  2864. MusicPort* pMusicPort;
  2865. LV_ITEM item;
  2866. LONG iSubItem;
  2867. TCHAR sz[MAX_PATH];
  2868. for (pMusicPort = pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL;
  2869. pMusicPort = pMusicPort->m_pMusicPortNext)
  2870. {
  2871. iSubItem = 0;
  2872. item.mask = LVIF_TEXT | LVIF_STATE;
  2873. item.iItem = ListView_GetItemCount(hwndList);
  2874. item.stateMask = 0xffff;
  2875. item.cchTextMax = 100;
  2876. /* if (pMusicPortInfo->m_bProblem)
  2877. item.state = (1 << 12);
  2878. else
  2879. */ item.state = 0;
  2880. item.iSubItem = iSubItem++;
  2881. item.pszText = pMusicPort->m_szDescription;
  2882. if (-1 == ListView_InsertItem(hwndList, &item))
  2883. return E_FAIL;
  2884. item.mask = LVIF_TEXT;
  2885. item.iSubItem = iSubItem++;
  2886. LoadString(NULL, pMusicPort->m_bSoftware ? IDS_SOFTWARE : IDS_HARDWARE, sz, MAX_PATH);
  2887. item.pszText = sz;
  2888. if (FALSE == ListView_SetItem(hwndList, &item))
  2889. return E_FAIL;
  2890. item.iSubItem = iSubItem++;
  2891. LoadString(NULL, pMusicPort->m_bKernelMode ? IDS_YES : IDS_NO, sz, MAX_PATH);
  2892. item.pszText = sz;
  2893. if (FALSE == ListView_SetItem(hwndList, &item))
  2894. return E_FAIL;
  2895. item.iSubItem = iSubItem++;
  2896. LoadString(NULL, pMusicPort->m_bOutputPort ? IDS_OUTPUT : IDS_INPUT, sz, MAX_PATH);
  2897. item.pszText = sz;
  2898. if (FALSE == ListView_SetItem(hwndList, &item))
  2899. return E_FAIL;
  2900. item.iSubItem = iSubItem++;
  2901. LoadString(NULL, pMusicPort->m_bUsesDLS ? IDS_YES : IDS_NO, sz, MAX_PATH);
  2902. item.pszText = sz;
  2903. if (FALSE == ListView_SetItem(hwndList, &item))
  2904. return E_FAIL;
  2905. item.iSubItem = iSubItem++;
  2906. LoadString(NULL, pMusicPort->m_bExternal ? IDS_YES : IDS_NO, sz, MAX_PATH);
  2907. item.pszText = sz;
  2908. if (FALSE == ListView_SetItem(hwndList, &item))
  2909. return E_FAIL;
  2910. item.iSubItem = iSubItem++;
  2911. LoadString(NULL, pMusicPort->m_bDefaultPort ? IDS_YES : IDS_NO, sz, MAX_PATH);
  2912. item.pszText = sz;
  2913. if (FALSE == ListView_SetItem(hwndList, &item))
  2914. return E_FAIL;
  2915. }
  2916. return S_OK;
  2917. }
  2918. /****************************************************************************
  2919. *
  2920. * ScanSystem
  2921. *
  2922. ****************************************************************************/
  2923. HRESULT ScanSystem(VOID)
  2924. {
  2925. HRESULT hr;
  2926. TCHAR szPath[MAX_PATH];
  2927. // ******* GetComponentFiles (SI:2) ********
  2928. if( s_bUseSystemInfo )
  2929. {
  2930. s_bUseSystemInfo = QueryCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, IDS_SI, 2 );
  2931. if( s_bUseSystemInfo )
  2932. {
  2933. EnterCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 2 );
  2934. // ******* GetComponentFiles in Windows Dir ********
  2935. // First, check for DirectX files incorrectly stored in the Windows folder:
  2936. GetWindowsDirectory(szPath, MAX_PATH);
  2937. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_DXGRAPHICS_COMPONENTFILES)))
  2938. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2939. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_DPLAY_COMPONENTFILES)))
  2940. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2941. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_DINPUT_COMPONENTFILES)))
  2942. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2943. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_DXAUDIO_COMPONENTFILES)))
  2944. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2945. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_DXMISC_COMPONENTFILES)))
  2946. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2947. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxWinComponentsFileInfoFirst, TRUE, IDS_BDA_COMPONENTFILES)))
  2948. ReportError(IDS_BDA_COMPONENTFILES, hr);
  2949. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  2950. // ******* GetComponentFiles in Sys Dir ********
  2951. GetSystemDirectory(szPath, MAX_PATH);
  2952. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DXGRAPHICS_COMPONENTFILES)))
  2953. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2954. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DPLAY_COMPONENTFILES)))
  2955. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2956. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DINPUT_COMPONENTFILES)))
  2957. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2958. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DXAUDIO_COMPONENTFILES)))
  2959. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2960. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DXMISC_COMPONENTFILES)))
  2961. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2962. if (GetDxSetupFolder(szPath))
  2963. {
  2964. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DXSETUP_COMPONENTFILES)))
  2965. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2966. }
  2967. GetSystemDirectory(szPath, MAX_PATH);
  2968. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_DXMEDIA_COMPONENTFILES)))
  2969. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  2970. if (FAILED(hr = GetComponentFiles(szPath, &s_pDxComponentsFileInfoFirst, FALSE, IDS_BDA_COMPONENTFILES)))
  2971. ReportError(IDS_BDA_COMPONENTFILES, hr);
  2972. LeaveCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 2 );
  2973. }
  2974. }
  2975. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  2976. // Stop if the UI thread is gone
  2977. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  2978. return S_FALSE;
  2979. // ******* GetExtraDisplayInfo (DD:2) ********
  2980. if( s_bUseDisplay )
  2981. {
  2982. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 2 );
  2983. if( s_bUseDisplay )
  2984. {
  2985. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 2 );
  2986. if (FAILED(hr = GetExtraDisplayInfo(s_pDisplayInfoFirst)))
  2987. ReportError(IDS_NOEXTRADISPLAYINFO, hr);
  2988. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 2 );
  2989. }
  2990. }
  2991. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  2992. // Stop if the UI thread is gone
  2993. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  2994. return S_FALSE;
  2995. // ******* GetDDrawDisplayInfo (DD:3) ********
  2996. if( s_bUseDisplay )
  2997. {
  2998. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 3 );
  2999. if( !s_bGUI )
  3000. {
  3001. // If there's no gui, then check to see if we are 16 or less colors
  3002. // If we are then don't use DirectDraw otherwise it will pop up a warning box
  3003. HDC hDC = GetDC( NULL );
  3004. if( hDC )
  3005. {
  3006. int nBitsPerPixel = GetDeviceCaps( hDC, BITSPIXEL );
  3007. ReleaseDC( NULL, hDC );
  3008. if( nBitsPerPixel < 8 )
  3009. s_bUseDisplay = FALSE;
  3010. }
  3011. }
  3012. if( s_bUseDisplay )
  3013. {
  3014. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3015. if(FAILED(hr = GetDDrawDisplayInfo(s_pDisplayInfoFirst)))
  3016. ReportError(IDS_NOEXTRADISPLAYINFO, hr);
  3017. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3018. }
  3019. }
  3020. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3021. // Stop if the UI thread is gone
  3022. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3023. return S_FALSE;
  3024. // ******* GetExtraSoundInfo (DS:2) ********
  3025. if( s_bUseDSound )
  3026. {
  3027. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 2 );
  3028. if( s_bUseDSound )
  3029. {
  3030. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 2 );
  3031. if (FAILED(hr = GetExtraSoundInfo(s_pSoundInfoFirst)))
  3032. ReportError(IDS_NOEXTRASOUNDINFO, hr);
  3033. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 2 );
  3034. }
  3035. }
  3036. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3037. // Stop if the UI thread is gone
  3038. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3039. return S_FALSE;
  3040. // ******* GetDSSoundInfo (DS:3) ********
  3041. if( s_bUseDSound )
  3042. {
  3043. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 3 );
  3044. if( s_bUseDSound )
  3045. {
  3046. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 3 );
  3047. if (FAILED(hr = GetDSSoundInfo(s_pSoundInfoFirst)))
  3048. ReportError(IDS_NOEXTRASOUNDINFO, hr);
  3049. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 3 );
  3050. }
  3051. }
  3052. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3053. // Stop if the UI thread is gone
  3054. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3055. return S_FALSE;
  3056. // ******* GetExtraMusicInfo (DM:2) *******
  3057. if( s_bUseDMusic )
  3058. {
  3059. if (s_pMusicInfo != NULL && s_pMusicInfo->m_bDMusicInstalled)
  3060. {
  3061. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 2 );
  3062. if( s_bUseDMusic )
  3063. {
  3064. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 2 );
  3065. if (FAILED(hr = GetExtraMusicInfo(s_pMusicInfo)))
  3066. ReportError(IDS_NOBASICMUSICINFO, hr);
  3067. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 2 );
  3068. }
  3069. if (s_pMusicInfo->m_pMusicPortFirst != NULL)
  3070. s_pMusicInfo->m_guidMusicPortTest = s_pMusicInfo->m_pMusicPortFirst->m_guid;
  3071. }
  3072. }
  3073. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3074. // Stop if the UI thread is gone
  3075. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3076. return S_FALSE;
  3077. // ******* GetInputInfo (DI:1) ********
  3078. if( s_bUseDInput )
  3079. {
  3080. s_bUseDInput = QueryCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, IDS_DI, 1 );
  3081. if( s_bUseDInput )
  3082. {
  3083. EnterCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, 1 );
  3084. if (FAILED(hr = GetInputInfo(&s_pInputInfo)))
  3085. ReportError(IDS_NOINPUTINFO, hr);
  3086. LeaveCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, 1 );
  3087. }
  3088. }
  3089. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3090. // Stop if the UI thread is gone
  3091. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3092. return S_FALSE;
  3093. // ******* GetInputDriverInfo (DI:2) ********
  3094. if( s_bUseDInput )
  3095. {
  3096. s_bUseDInput = QueryCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, IDS_DI, 2 );
  3097. if( s_bUseDInput )
  3098. {
  3099. EnterCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, 2 );
  3100. if (FAILED(hr = GetInputDriverInfo(s_pInputInfo)))
  3101. ReportError(IDS_NOINPUTDRIVERINFO, hr);
  3102. LeaveCrashProtection( DXD_IN_DI_KEY, DXD_IN_DI_VALUE, 2 );
  3103. }
  3104. }
  3105. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3106. // Stop if the UI thread is gone
  3107. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3108. return S_FALSE;
  3109. // ******* GetNetInfo (DP:1) ********
  3110. if( s_bUseDPlay )
  3111. {
  3112. s_bUseDPlay = QueryCrashProtection( DXD_IN_DP_KEY, DXD_IN_DP_VALUE, IDS_DP, 1 );
  3113. if( s_bUseDPlay )
  3114. {
  3115. EnterCrashProtection( DXD_IN_DP_KEY, DXD_IN_DP_VALUE, 1 );
  3116. if (FAILED(hr = GetNetInfo(&s_sysInfo, &s_pNetInfo)))
  3117. ReportError(IDS_NONETINFO, hr);
  3118. LeaveCrashProtection( DXD_IN_DP_KEY, DXD_IN_DP_VALUE, 1 );
  3119. }
  3120. }
  3121. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3122. // Stop if the UI thread is gone
  3123. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3124. return S_FALSE;
  3125. // ******* GetBasicShowInfo (SI:3) ********
  3126. if( s_bUseDShow )
  3127. {
  3128. s_bUseDShow = QueryCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, IDS_SI, 3 );
  3129. if( s_bUseDShow )
  3130. {
  3131. EnterCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 3 );
  3132. if (FAILED(hr = GetBasicShowInfo(&s_pShowInfo)))
  3133. ReportError(IDS_COMPONENTFILESPROBLEM, hr);
  3134. LeaveCrashProtection( DXD_IN_SI_KEY, DXD_IN_SI_VALUE, 3 );
  3135. }
  3136. }
  3137. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3138. // Stop if the UI thread is gone
  3139. if( s_hUIThread != NULL && WAIT_TIMEOUT != WaitForSingleObject( s_hUIThread, 0 ) )
  3140. return S_FALSE;
  3141. // ******* DiagnoseDxFiles ********
  3142. DiagnoseDxFiles(&s_sysInfo, s_pDxComponentsFileInfoFirst,
  3143. s_pDxWinComponentsFileInfoFirst);
  3144. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3145. // ******* DiagnoseDisplay ********
  3146. DiagnoseDisplay(&s_sysInfo, s_pDisplayInfoFirst);
  3147. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3148. // ******* DiagnoseSound ********
  3149. DiagnoseSound(s_pSoundInfoFirst);
  3150. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3151. // ******* DiagnoseInput ********
  3152. DiagnoseInput(&s_sysInfo, s_pInputInfo);
  3153. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3154. // ******* DiagnoseMusic ********
  3155. DiagnoseMusic(&s_sysInfo, s_pMusicInfo);
  3156. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3157. // ******* DiagnoseNetInfo ********
  3158. DiagnoseNetInfo(&s_sysInfo, s_pNetInfo);
  3159. SendMessage( s_hwndMain, WM_APP_PROGRESS, 0, 0 );
  3160. return S_OK;
  3161. }
  3162. /****************************************************************************
  3163. *
  3164. * SaveInfo
  3165. *
  3166. ****************************************************************************/
  3167. VOID SaveInfo(VOID)
  3168. {
  3169. HRESULT hr;
  3170. OPENFILENAME ofn;
  3171. TCHAR szFile[MAX_PATH];
  3172. TCHAR szFilter[MAX_PATH];
  3173. TCHAR szExt[MAX_PATH];
  3174. TCHAR* pch = NULL;
  3175. LoadString(NULL, IDS_FILTER, szFilter, MAX_PATH);
  3176. // Filter strings are weird because they contain nulls.
  3177. // The string loaded from a resource has # where nulls
  3178. // should be inserted.
  3179. for (pch = szFilter; *pch != TEXT('\0'); pch++)
  3180. {
  3181. if (*pch == TEXT('#'))
  3182. *pch = TEXT('\0');
  3183. }
  3184. LoadString(NULL, IDS_DEFAULTFILENAME, szFile, MAX_PATH);
  3185. LoadString(NULL, IDS_DEFAULTEXT, szExt, MAX_PATH);
  3186. ZeroMemory(&ofn, sizeof(ofn));
  3187. ofn.lStructSize = sizeof(ofn);
  3188. ofn.hwndOwner = s_hwndMain;
  3189. ofn.lpstrFilter = szFilter;
  3190. ofn.lpstrFile = szFile;
  3191. ofn.nMaxFile = MAX_PATH;
  3192. ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
  3193. ofn.lpstrDefExt = szExt;
  3194. TCHAR szInitialPath[MAX_PATH];
  3195. if( FALSE == GetTxtPath( szInitialPath ) )
  3196. ofn.lpstrInitialDir = NULL;
  3197. else
  3198. ofn.lpstrInitialDir = szInitialPath;
  3199. if (GetSaveFileName(&ofn))
  3200. {
  3201. lstrcpy( szInitialPath, ofn.lpstrFile );
  3202. TCHAR* strLastSlash = _tcsrchr(szInitialPath, '\\' );
  3203. if( NULL != strLastSlash )
  3204. {
  3205. *strLastSlash = 0;
  3206. SetTxtPath( szInitialPath );
  3207. }
  3208. if (FAILED(hr = SaveAllInfo(ofn.lpstrFile, &s_sysInfo,
  3209. s_pDxWinComponentsFileInfoFirst, s_pDxComponentsFileInfoFirst,
  3210. s_pDisplayInfoFirst, s_pSoundInfoFirst, s_pMusicInfo,
  3211. s_pInputInfo, s_pNetInfo, s_pShowInfo)))
  3212. {
  3213. }
  3214. }
  3215. }
  3216. /****************************************************************************
  3217. *
  3218. * ToggleDDAccel
  3219. *
  3220. ****************************************************************************/
  3221. VOID ToggleDDAccel(VOID)
  3222. {
  3223. HRESULT hr;
  3224. TCHAR szTitle[MAX_PATH];
  3225. TCHAR szMessage[MAX_PATH];
  3226. BOOL bEnabled = IsDDHWAccelEnabled();
  3227. HKEY hkey;
  3228. DWORD dwData;
  3229. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3230. if (bEnabled)
  3231. LoadString(NULL, IDS_DISABLEDDWARNING, szMessage, MAX_PATH);
  3232. else
  3233. LoadString(NULL, IDS_ENABLEDDWARNING, szMessage, MAX_PATH);
  3234. if (IDOK == MessageBox(s_hwndMain, szMessage, szTitle, MB_OKCANCEL))
  3235. {
  3236. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3237. TEXT("SOFTWARE\\Microsoft\\DirectDraw"), 0, KEY_ALL_ACCESS, &hkey))
  3238. {
  3239. if (bEnabled) // if acceleration enabled
  3240. dwData = TRUE; // force emulation
  3241. else
  3242. dwData = FALSE; // disable emulation
  3243. if (ERROR_SUCCESS != RegSetValueEx(hkey, TEXT("EmulationOnly"), NULL,
  3244. REG_DWORD, (BYTE *)&dwData, sizeof(dwData)))
  3245. {
  3246. // TODO: report error
  3247. RegCloseKey(hkey);
  3248. return;
  3249. }
  3250. RegCloseKey(hkey);
  3251. }
  3252. else
  3253. {
  3254. // TODO: report error
  3255. return;
  3256. }
  3257. }
  3258. // update all DisplayInfo to reflect new state:
  3259. // ******* GetExtraDisplayInfo (DD:2) ********
  3260. if( s_bUseDisplay )
  3261. {
  3262. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 2 );
  3263. if( s_bUseDisplay )
  3264. {
  3265. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 2 );
  3266. if (FAILED(hr = GetExtraDisplayInfo(s_pDisplayInfoFirst)))
  3267. ReportError(IDS_NOEXTRADISPLAYINFO, hr);
  3268. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 2 );
  3269. }
  3270. }
  3271. // ******* GetDDrawDisplayInfo (DD:3) ********
  3272. if( s_bUseDisplay )
  3273. {
  3274. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 3 );
  3275. if( s_bUseDisplay )
  3276. {
  3277. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3278. if(FAILED(hr = GetDDrawDisplayInfo(s_pDisplayInfoFirst)))
  3279. ReportError(IDS_NOEXTRADISPLAYINFO, hr);
  3280. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3281. }
  3282. }
  3283. SetupDisplayPage(s_lwCurPage - s_iPageDisplayFirst); // refresh page
  3284. }
  3285. /****************************************************************************
  3286. *
  3287. * ToggleD3DAccel
  3288. *
  3289. ****************************************************************************/
  3290. VOID ToggleD3DAccel(VOID)
  3291. {
  3292. TCHAR szTitle[MAX_PATH];
  3293. TCHAR szMessage[MAX_PATH];
  3294. BOOL bEnabled = IsD3DHWAccelEnabled();
  3295. HKEY hkey;
  3296. DWORD dwData;
  3297. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3298. if (bEnabled)
  3299. LoadString(NULL, IDS_DISABLED3DWARNING, szMessage, MAX_PATH);
  3300. else
  3301. LoadString(NULL, IDS_ENABLED3DWARNING, szMessage, MAX_PATH);
  3302. if (IDOK == MessageBox(s_hwndMain, szMessage, szTitle, MB_OKCANCEL))
  3303. {
  3304. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3305. TEXT("SOFTWARE\\Microsoft\\Direct3D\\Drivers"), 0, KEY_ALL_ACCESS, &hkey))
  3306. {
  3307. if (bEnabled) // if acceleration enabled
  3308. dwData = TRUE; // force emulation
  3309. else
  3310. dwData = FALSE; // disable emulation
  3311. if (ERROR_SUCCESS != RegSetValueEx(hkey, TEXT("SoftwareOnly"), NULL,
  3312. REG_DWORD, (BYTE *)&dwData, sizeof(dwData)))
  3313. {
  3314. // TODO: report error
  3315. RegCloseKey(hkey);
  3316. return;
  3317. }
  3318. RegCloseKey(hkey);
  3319. // update all DisplayInfo to reflect new state:
  3320. DisplayInfo* pDisplayInfo;
  3321. for (pDisplayInfo = s_pDisplayInfoFirst; pDisplayInfo != NULL;
  3322. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext)
  3323. {
  3324. pDisplayInfo->m_b3DAccelerationEnabled = !bEnabled;
  3325. }
  3326. }
  3327. else
  3328. {
  3329. // TODO: report error
  3330. return;
  3331. }
  3332. }
  3333. SetupDisplayPage(s_lwCurPage - s_iPageDisplayFirst); // refresh page
  3334. }
  3335. /****************************************************************************
  3336. *
  3337. * ToggleAGPSupport
  3338. *
  3339. ****************************************************************************/
  3340. VOID ToggleAGPSupport(VOID)
  3341. {
  3342. HRESULT hr;
  3343. TCHAR szTitle[MAX_PATH];
  3344. TCHAR szMessage[MAX_PATH];
  3345. BOOL bEnabled = IsAGPEnabled();
  3346. HKEY hkey;
  3347. DWORD dwData;
  3348. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3349. if (bEnabled)
  3350. LoadString(NULL, IDS_DISABLEAGPWARNING, szMessage, MAX_PATH);
  3351. else
  3352. LoadString(NULL, IDS_ENABLEAGPWARNING, szMessage, MAX_PATH);
  3353. if (IDOK == MessageBox(s_hwndMain, szMessage, szTitle, MB_OKCANCEL))
  3354. {
  3355. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3356. TEXT("SOFTWARE\\Microsoft\\DirectDraw"), 0, KEY_ALL_ACCESS, &hkey))
  3357. {
  3358. if (bEnabled) // if AGP enabled
  3359. dwData = TRUE; // disable
  3360. else
  3361. dwData = FALSE; // enable
  3362. if (ERROR_SUCCESS != RegSetValueEx(hkey, TEXT("DisableAGPSupport"), NULL,
  3363. REG_DWORD, (BYTE *)&dwData, sizeof(dwData)))
  3364. {
  3365. // TODO: report error
  3366. RegCloseKey(hkey);
  3367. return;
  3368. }
  3369. RegCloseKey(hkey);
  3370. // update all DisplayInfo to reflect new state:
  3371. DisplayInfo* pDisplayInfo;
  3372. for (pDisplayInfo = s_pDisplayInfoFirst; pDisplayInfo != NULL;
  3373. pDisplayInfo = pDisplayInfo->m_pDisplayInfoNext)
  3374. {
  3375. pDisplayInfo->m_bAGPEnabled = !bEnabled;
  3376. }
  3377. }
  3378. else
  3379. {
  3380. // TODO: report error
  3381. return;
  3382. }
  3383. }
  3384. // ******* GetDDrawDisplayInfo (DD:3) ********
  3385. if( s_bUseDisplay )
  3386. {
  3387. s_bUseDisplay = QueryCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, IDS_DD, 3 );
  3388. if( s_bUseDisplay )
  3389. {
  3390. EnterCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3391. if(FAILED(hr = GetDDrawDisplayInfo(s_pDisplayInfoFirst)))
  3392. ReportError(IDS_NOEXTRADISPLAYINFO, hr);
  3393. LeaveCrashProtection( DXD_IN_DD_KEY, DXD_IN_DD_VALUE, 3 );
  3394. }
  3395. }
  3396. SetupDisplayPage(s_lwCurPage - s_iPageDisplayFirst); // refresh page
  3397. }
  3398. /****************************************************************************
  3399. *
  3400. * ToggleDMAccel
  3401. *
  3402. ****************************************************************************/
  3403. VOID ToggleDMAccel(VOID)
  3404. {
  3405. HRESULT hr;
  3406. TCHAR szTitle[MAX_PATH];
  3407. TCHAR szMessage[MAX_PATH];
  3408. BOOL bEnabled = s_pMusicInfo->m_bAccelerationEnabled;
  3409. HKEY hkey;
  3410. DWORD dwData;
  3411. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3412. if (bEnabled)
  3413. LoadString(NULL, IDS_DISABLEDMWARNING, szMessage, MAX_PATH);
  3414. else
  3415. LoadString(NULL, IDS_ENABLEDMWARNING, szMessage, MAX_PATH);
  3416. if (IDOK == MessageBox(s_hwndMain, szMessage, szTitle, MB_OKCANCEL))
  3417. {
  3418. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3419. TEXT("SOFTWARE\\Microsoft\\DirectMusic"), 0, KEY_ALL_ACCESS, &hkey))
  3420. {
  3421. if (bEnabled) // if acceleration enabled
  3422. {
  3423. dwData = TRUE; // force emulation
  3424. if (ERROR_SUCCESS != RegSetValueEx(hkey, TEXT("DisableHWAcceleration"), NULL,
  3425. REG_DWORD, (BYTE *)&dwData, sizeof(dwData)))
  3426. {
  3427. // TODO: report error
  3428. RegCloseKey(hkey);
  3429. return;
  3430. }
  3431. }
  3432. else
  3433. {
  3434. if (ERROR_SUCCESS != RegDeleteValue( hkey, TEXT("DisableHWAcceleration") ))
  3435. {
  3436. // TODO: report error
  3437. RegCloseKey(hkey);
  3438. return;
  3439. }
  3440. }
  3441. RegCloseKey(hkey);
  3442. }
  3443. else
  3444. {
  3445. // TODO: report error
  3446. return;
  3447. }
  3448. }
  3449. // update all MusicInfo to reflect new state:
  3450. if (s_pMusicInfo != NULL)
  3451. DestroyMusicInfo(s_pMusicInfo);
  3452. // ******* GetBasicMusicInfo (DM:1) ********
  3453. if( s_bUseDMusic )
  3454. {
  3455. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 1 );
  3456. if( s_bUseDMusic )
  3457. {
  3458. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  3459. if (FAILED(hr = GetBasicMusicInfo(&s_pMusicInfo)))
  3460. ReportError(IDS_NOBASICMUSICINFO, hr);
  3461. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 1 );
  3462. }
  3463. }
  3464. // ******* GetExtraMusicInfo (DM:2) *******
  3465. if( s_bUseDMusic )
  3466. {
  3467. s_bUseDMusic = QueryCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, IDS_DM, 2 );
  3468. if( s_bUseDMusic )
  3469. {
  3470. EnterCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 2 );
  3471. if (FAILED(hr = GetExtraMusicInfo(s_pMusicInfo)))
  3472. ReportError(IDS_NOBASICMUSICINFO, hr);
  3473. LeaveCrashProtection( DXD_IN_DM_KEY, DXD_IN_DM_VALUE, 2 );
  3474. }
  3475. }
  3476. if (s_pMusicInfo->m_pMusicPortFirst != NULL)
  3477. s_pMusicInfo->m_guidMusicPortTest = s_pMusicInfo->m_pMusicPortFirst->m_guid;
  3478. SetupMusicPage(); // refresh page
  3479. }
  3480. /****************************************************************************
  3481. *
  3482. * BugDialogProc
  3483. *
  3484. ****************************************************************************/
  3485. INT_PTR CALLBACK BugDialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  3486. {
  3487. switch (msg)
  3488. {
  3489. case WM_INITDIALOG:
  3490. {
  3491. TCHAR szFilename[MAX_PATH];
  3492. if( FALSE == GetTxtPath( szFilename ) )
  3493. {
  3494. GetTempPath( MAX_PATH, szFilename );
  3495. lstrcat( szFilename, TEXT("DxDiag.txt"));
  3496. }
  3497. else
  3498. {
  3499. lstrcat( szFilename, TEXT("\\DxDiag.txt"));
  3500. }
  3501. SetWindowText(GetDlgItem(hwnd, IDC_PATH), szFilename);
  3502. return FALSE;
  3503. }
  3504. case WM_COMMAND:
  3505. {
  3506. WORD wID = LOWORD(wparam);
  3507. switch(wID)
  3508. {
  3509. case IDC_BROWSE:
  3510. {
  3511. OPENFILENAME ofn;
  3512. TCHAR szFile[MAX_PATH];
  3513. GetDlgItemText( hwnd, IDC_PATH, szFile, MAX_PATH );
  3514. ZeroMemory(&ofn, sizeof(ofn));
  3515. ofn.lStructSize = sizeof(ofn);
  3516. ofn.hwndOwner = hwnd;
  3517. ofn.lpstrFilter = TEXT("Text File (*.txt)\0*.txt\0\0");
  3518. ofn.lpstrFile = szFile;
  3519. ofn.nMaxFile = MAX_PATH;
  3520. ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
  3521. ofn.lpstrDefExt = TEXT(".txt");
  3522. if (GetSaveFileName(&ofn))
  3523. SetWindowText(GetDlgItem(hwnd, IDC_PATH), ofn.lpstrFile);
  3524. break;
  3525. }
  3526. case IDOK:
  3527. {
  3528. TCHAR szPath[MAX_PATH];
  3529. GetWindowText(GetDlgItem(hwnd, IDC_PATH), szPath, MAX_PATH);
  3530. SaveAndSendBug(szPath);
  3531. TCHAR* strLastSlash = _tcsrchr(szPath, '\\' );
  3532. if( NULL != strLastSlash )
  3533. {
  3534. *strLastSlash = 0;
  3535. SetTxtPath( szPath );
  3536. }
  3537. EndDialog(hwnd, 0);
  3538. break;
  3539. }
  3540. case IDCANCEL:
  3541. EndDialog(hwnd, 0);
  3542. break;
  3543. }
  3544. return TRUE;
  3545. }
  3546. }
  3547. return FALSE;
  3548. }
  3549. /****************************************************************************
  3550. *
  3551. * ReportBug
  3552. *
  3553. ****************************************************************************/
  3554. VOID ReportBug(VOID)
  3555. {
  3556. HINSTANCE hinst = (HINSTANCE)GetWindowLongPtr(s_hwndMain, GWLP_HINSTANCE);
  3557. // Run the dialog box:
  3558. DialogBox(hinst, MAKEINTRESOURCE(IDD_BUGINFO), s_hwndMain, BugDialogProc);
  3559. }
  3560. /****************************************************************************
  3561. *
  3562. * SaveAndSendBug
  3563. *
  3564. ****************************************************************************/
  3565. VOID SaveAndSendBug(TCHAR* szPath)
  3566. {
  3567. HRESULT hr;
  3568. // Save the DxDiag.txt at szPath
  3569. if (FAILED(hr = SaveAllInfo(szPath, &s_sysInfo,
  3570. s_pDxWinComponentsFileInfoFirst, s_pDxComponentsFileInfoFirst,
  3571. s_pDisplayInfoFirst, s_pSoundInfoFirst, s_pMusicInfo,
  3572. s_pInputInfo, s_pNetInfo, NULL)))
  3573. {
  3574. ReportError(IDS_PROBLEMSAVING, hr);
  3575. return;
  3576. }
  3577. // Launch the betaplace web page
  3578. ShellExecute( NULL, NULL,
  3579. TEXT("http://www.betaplace.com/"),
  3580. NULL, NULL, SW_SHOWNORMAL );
  3581. }
  3582. /****************************************************************************
  3583. *
  3584. * OverrideDDRefresh
  3585. *
  3586. ****************************************************************************/
  3587. VOID OverrideDDRefresh(VOID)
  3588. {
  3589. HINSTANCE hinst = (HINSTANCE)GetWindowLongPtr(s_hwndMain, GWLP_HINSTANCE);
  3590. DialogBox(hinst, MAKEINTRESOURCE(IDD_OVERRIDEDD), s_hwndMain,
  3591. OverrideRefreshDialogProc);
  3592. }
  3593. /****************************************************************************
  3594. *
  3595. * OverrideRefreshDialogProc
  3596. *
  3597. ****************************************************************************/
  3598. INT_PTR CALLBACK OverrideRefreshDialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  3599. {
  3600. HWND hwndTabs = GetDlgItem(hwnd, IDC_TAB);
  3601. HKEY hkey;
  3602. ULONG ulType = 0;
  3603. DWORD dwRefresh;
  3604. DWORD cbData;
  3605. switch (msg)
  3606. {
  3607. case WM_INITDIALOG:
  3608. dwRefresh = 0;
  3609. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3610. TEXT("Software\\Microsoft\\DirectDraw"), 0, KEY_READ, &hkey))
  3611. {
  3612. cbData = sizeof(DWORD);
  3613. RegQueryValueEx(hkey, TEXT("ForceRefreshRate"), 0, &ulType, (LPBYTE)&dwRefresh, &cbData);
  3614. }
  3615. if (dwRefresh == 0)
  3616. {
  3617. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_DEFAULTREFRESH);
  3618. }
  3619. else
  3620. {
  3621. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_OVERRIDEREFRESH);
  3622. SetDlgItemInt(hwnd, IDC_OVERRIDEREFRESHVALUE, dwRefresh, FALSE);
  3623. }
  3624. return TRUE;
  3625. case WM_COMMAND:
  3626. {
  3627. WORD wID = LOWORD(wparam);
  3628. BOOL bDontEnd = FALSE;
  3629. switch(wID)
  3630. {
  3631. case IDOK:
  3632. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3633. TEXT("Software\\Microsoft\\DirectDraw"), 0, KEY_ALL_ACCESS, &hkey))
  3634. {
  3635. DWORD dwButtonState;
  3636. dwButtonState = (DWORD)SendMessage(GetDlgItem(hwnd, IDC_DEFAULTREFRESH), BM_GETCHECK, 0, 0);
  3637. if (dwButtonState == BST_CHECKED)
  3638. {
  3639. RegDeleteValue(hkey, TEXT("ForceRefreshRate"));
  3640. }
  3641. else
  3642. {
  3643. BOOL bTranslated;
  3644. UINT ui = GetDlgItemInt(hwnd, IDC_OVERRIDEREFRESHVALUE, &bTranslated, TRUE);
  3645. if (bTranslated && ui >= 40 && ui <= 120)
  3646. RegSetValueEx(hkey, TEXT("ForceRefreshRate"), 0, REG_DWORD, (LPBYTE)&ui, sizeof(DWORD));
  3647. else
  3648. {
  3649. TCHAR sz[MAX_PATH];
  3650. TCHAR szTitle[MAX_PATH];
  3651. SetDlgItemText(hwnd, IDC_OVERRIDEREFRESHVALUE, TEXT(""));
  3652. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_DEFAULTREFRESH);
  3653. LoadString(NULL, IDS_BADREFRESHVALUE, sz, MAX_PATH);
  3654. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3655. MessageBox(hwnd, sz, szTitle, MB_OK);
  3656. bDontEnd = TRUE;
  3657. }
  3658. }
  3659. RegCloseKey(hkey);
  3660. }
  3661. else
  3662. {
  3663. }
  3664. if (!bDontEnd)
  3665. EndDialog(hwnd, IDOK);
  3666. break;
  3667. case IDCANCEL:
  3668. EndDialog(hwnd, IDCANCEL);
  3669. break;
  3670. case IDC_OVERRIDEREFRESHVALUE:
  3671. if (HIWORD(wparam) == EN_SETFOCUS)
  3672. {
  3673. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_OVERRIDEREFRESH);
  3674. }
  3675. else if (HIWORD(wparam) == EN_KILLFOCUS)
  3676. {
  3677. TCHAR szEdit[MAX_PATH];
  3678. BOOL bTranslated;
  3679. if (GetDlgItemText(hwnd, IDC_OVERRIDEREFRESHVALUE, szEdit, 100) == 0)
  3680. {
  3681. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_DEFAULTREFRESH);
  3682. }
  3683. else
  3684. {
  3685. UINT ui = GetDlgItemInt(hwnd, IDC_OVERRIDEREFRESHVALUE, &bTranslated, TRUE);
  3686. if (!bTranslated || ui < 40 || ui > 120)
  3687. {
  3688. TCHAR sz[MAX_PATH];
  3689. TCHAR szTitle[MAX_PATH];
  3690. LoadString(NULL, IDS_BADREFRESHVALUE, sz, MAX_PATH);
  3691. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  3692. MessageBox(hwnd, sz, szTitle, MB_OK);
  3693. SetDlgItemText(hwnd, IDC_OVERRIDEREFRESHVALUE, TEXT(""));
  3694. CheckRadioButton(hwnd, IDC_DEFAULTREFRESH, IDC_OVERRIDEREFRESH, IDC_DEFAULTREFRESH);
  3695. }
  3696. }
  3697. }
  3698. break;
  3699. }
  3700. }
  3701. return TRUE;
  3702. }
  3703. return FALSE;
  3704. }
  3705. /****************************************************************************
  3706. *
  3707. * ShowHelp - Look for dxdiag.chm in <windows>\help first, then try the
  3708. * same dir as the exe.
  3709. *
  3710. ****************************************************************************/
  3711. VOID ShowHelp(VOID)
  3712. {
  3713. TCHAR szHelpDir[MAX_PATH];
  3714. TCHAR szHelpFile[MAX_PATH];
  3715. TCHAR szHelpLeaf[MAX_PATH];
  3716. TCHAR szTestPath[MAX_PATH];
  3717. // Since we use HTML help, complain if at least IE5 is not found
  3718. BOOL bIE5Found = FALSE;
  3719. HKEY hkey;
  3720. TCHAR szVersion[MAX_PATH];
  3721. DWORD dwType;
  3722. DWORD cbData;
  3723. DWORD dwMajor;
  3724. DWORD dwMinor;
  3725. DWORD dwRevision;
  3726. DWORD dwBuild;
  3727. lstrcpy(szVersion, TEXT(""));
  3728. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3729. TEXT("Software\\Microsoft\\Internet Explorer"), 0, KEY_READ, &hkey))
  3730. {
  3731. cbData = 100;
  3732. RegQueryValueEx(hkey, TEXT("Version"), 0, &dwType, (LPBYTE)szVersion, &cbData);
  3733. RegCloseKey(hkey);
  3734. if (lstrlen(szVersion) > 0)
  3735. {
  3736. _stscanf(szVersion, TEXT("%d.%d.%d.%d"), &dwMajor, &dwMinor, &dwRevision, &dwBuild);
  3737. if (dwMajor >= 5)
  3738. bIE5Found = TRUE;
  3739. }
  3740. }
  3741. if (!bIE5Found)
  3742. {
  3743. ReportError(IDS_HELPNEEDSIE5);
  3744. return;
  3745. }
  3746. LoadString(NULL, IDS_HELPFILE, szHelpFile, MAX_PATH);
  3747. GetWindowsDirectory(szHelpDir, MAX_PATH);
  3748. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  3749. lstrcat(szHelpDir, szHelpLeaf);
  3750. lstrcpy(szTestPath, szHelpDir);
  3751. lstrcat(szTestPath, TEXT("\\"));
  3752. lstrcat(szTestPath, szHelpFile);
  3753. if (GetFileAttributes(szTestPath) == 0xffffffff)
  3754. {
  3755. // File not in windows\help, so try exe's dir:
  3756. GetModuleFileName(NULL, szHelpDir, MAX_PATH);
  3757. TCHAR* pstr = _tcsrchr(szHelpDir, TEXT('\\'));
  3758. if( pstr )
  3759. *pstr = TEXT('\0');
  3760. }
  3761. HINSTANCE hInstResult = ShellExecute( s_hwndMain, NULL, szHelpFile,
  3762. NULL, szHelpDir, SW_SHOWNORMAL ) ;
  3763. if( (INT_PTR)hInstResult < 32 )
  3764. ReportError(IDS_NOHELP);
  3765. }
  3766. /****************************************************************************
  3767. *
  3768. * BTranslateError
  3769. *
  3770. ****************************************************************************/
  3771. BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish)
  3772. {
  3773. LONG ids;
  3774. switch (hr)
  3775. {
  3776. case E_INVALIDARG: ids = bEnglish ? IDS_INVALIDARG_ENGLISH : IDS_INVALIDARG; break;
  3777. case E_FAIL: ids = bEnglish ? IDS_FAIL_ENGLISH : IDS_FAIL; break;
  3778. case E_UNEXPECTED: ids = bEnglish ? IDS_UNEXPECTED_ENGLISH : IDS_UNEXPECTED; break;
  3779. case E_NOTIMPL: ids = bEnglish ? IDS_NOTIMPL_ENGLISH : IDS_NOTIMPL; break;
  3780. case E_OUTOFMEMORY: ids = bEnglish ? IDS_OUTOFMEMORY_ENGLISH : IDS_OUTOFMEMORY; break;
  3781. case E_NOINTERFACE: ids = bEnglish ? IDS_NOINTERFACE_ENGLISH : IDS_NOINTERFACE; break;
  3782. case REGDB_E_CLASSNOTREG: ids = bEnglish ? IDS_REGDB_E_CLASSNOTREG_ENGLISH : IDS_REGDB_E_CLASSNOTREG; break;
  3783. case DDERR_INVALIDMODE: ids = bEnglish ? IDS_INVALIDMODE_ENGLISH : IDS_INVALIDMODE; break;
  3784. case DDERR_INVALIDPIXELFORMAT: ids = bEnglish ? IDS_INVALIDPIXELFORMAT_ENGLISH : IDS_INVALIDPIXELFORMAT; break;
  3785. case DDERR_CANTCREATEDC: ids = bEnglish ? IDS_CANTCREATEDC_ENGLISH : IDS_CANTCREATEDC; break;
  3786. case DDERR_NOTFOUND: ids = bEnglish ? IDS_NOTFOUND_ENGLISH : IDS_NOTFOUND; break;
  3787. case DDERR_NODIRECTDRAWSUPPORT: ids = bEnglish ? IDS_NODIRECTDRAWSUPPORT_ENGLISH : IDS_NODIRECTDRAWSUPPORT; break;
  3788. case DDERR_NO3D: ids = bEnglish ? IDS_NO3D_ENGLISH : IDS_NO3D; break;
  3789. case D3DERR_INVALID_DEVICE: ids = bEnglish ? IDS_INVALID_DEVICE_ENGLISH : IDS_INVALID_DEVICE; break;
  3790. case D3DERR_INITFAILED: ids = bEnglish ? IDS_INITFAILED_ENGLISH : IDS_INITFAILED; break;
  3791. case D3DERR_MATERIAL_CREATE_FAILED: ids = bEnglish ? IDS_MATERIAL_CREATE_FAILED_ENGLISH : IDS_MATERIAL_CREATE_FAILED; break;
  3792. case D3DERR_LIGHT_SET_FAILED: ids = bEnglish ? IDS_LIGHT_SET_FAILED_ENGLISH : IDS_LIGHT_SET_FAILED; break;
  3793. case DDERR_OUTOFVIDEOMEMORY: ids = bEnglish ? IDS_OUT_OF_VIDEO_MEMORY_ENGLISH : IDS_OUT_OF_VIDEO_MEMORY; break;
  3794. #define D3DERR_NOTAVAILABLE 0x8876086a
  3795. case D3DERR_NOTAVAILABLE: ids = bEnglish ? IDS_D3DERR_NOTAVAILABLE_ENGLISH : IDS_D3DERR_NOTAVAILABLE; break;
  3796. case DSERR_CONTROLUNAVAIL: ids = bEnglish ? IDS_CONTROLUNAVAIL_ENGLISH : IDS_CONTROLUNAVAIL; break;
  3797. case DSERR_BADFORMAT: ids = bEnglish ? IDS_BADFORMAT_ENGLISH : IDS_BADFORMAT; break;
  3798. case DSERR_BUFFERLOST: ids = bEnglish ? IDS_BUFFERLOST_ENGLISH : IDS_BUFFERLOST; break;
  3799. case DSERR_NODRIVER: ids = bEnglish ? IDS_NODRIVER_ENGLISH : IDS_NODRIVER; break;
  3800. case DSERR_ALLOCATED: ids = bEnglish ? IDS_ALLOCATED_ENGLISH : IDS_ALLOCATED; break;
  3801. case DMUS_E_DRIVER_FAILED: ids = bEnglish ? IDS_DRIVER_FAILED_ENGLISH : IDS_DRIVER_FAILED; break;
  3802. case DMUS_E_PORTS_OPEN: ids = bEnglish ? IDS_PORTS_OPEN_ENGLISH : IDS_PORTS_OPEN; break;
  3803. case DMUS_E_DEVICE_IN_USE: ids = bEnglish ? IDS_DEVICE_IN_USE_ENGLISH : IDS_DEVICE_IN_USE; break;
  3804. case DMUS_E_INSUFFICIENTBUFFER: ids = bEnglish ? IDS_INSUFFICIENTBUFFER_ENGLISH : IDS_INSUFFICIENTBUFFER; break;
  3805. case DMUS_E_CHUNKNOTFOUND: ids = bEnglish ? IDS_CHUNKNOTFOUND_ENGLISH : IDS_CHUNKNOTFOUND; break;
  3806. case DMUS_E_BADINSTRUMENT: ids = bEnglish ? IDS_BADINSTRUMENT_ENGLISH : IDS_BADINSTRUMENT; break;
  3807. case DMUS_E_CANNOTREAD: ids = bEnglish ? IDS_CANNOTREAD_ENGLISH : IDS_CANNOTREAD; break;
  3808. case DMUS_E_LOADER_BADPATH: ids = bEnglish ? IDS_LOADER_BADPATH_ENGLISH : IDS_LOADER_BADPATH; break;
  3809. case DMUS_E_LOADER_FAILEDOPEN: ids = bEnglish ? IDS_LOADER_FAILEDOPEN_ENGLISH : IDS_LOADER_FAILEDOPEN; break;
  3810. case DMUS_E_LOADER_FORMATNOTSUPPORTED: ids = bEnglish ? IDS_LOADER_FORMATNOTSUPPORTED_ENGLISH : IDS_LOADER_FORMATNOTSUPPORTED; break;
  3811. case DMUS_E_LOADER_OBJECTNOTFOUND: ids = bEnglish ? IDS_OBJECTNOTFOUND_ENGLISH : IDS_OBJECTNOTFOUND; break;
  3812. case DPERR_ACCESSDENIED: ids = bEnglish ? IDS_DPERR_ACCESSDENIED_ENGLISH : IDS_DPERR_ACCESSDENIED; break;
  3813. case DPERR_CANTADDPLAYER: ids = bEnglish ? IDS_DPERR_CANTADDPLAYER_ENGLISH : IDS_DPERR_CANTADDPLAYER; break;
  3814. case DPERR_CANTCREATESESSION: ids = bEnglish ? IDS_DPERR_CANTCREATESESSION_ENGLISH : IDS_DPERR_CANTCREATESESSION; break;
  3815. case DPERR_EXCEPTION: ids = bEnglish ? IDS_DPERR_EXCEPTION_ENGLISH : IDS_DPERR_EXCEPTION; break;
  3816. case DPERR_INVALIDOBJECT: ids = bEnglish ? IDS_DPERR_INVALIDOBJECT_ENGLISH : IDS_DPERR_INVALIDOBJECT; break;
  3817. case DPERR_NOCONNECTION: ids = bEnglish ? IDS_DPERR_NOCONNECTION_ENGLISH : IDS_DPERR_NOCONNECTION; break;
  3818. case DPERR_TIMEOUT: ids = bEnglish ? IDS_DPERR_TIMEOUT_ENGLISH : IDS_DPERR_TIMEOUT; break;
  3819. case DPERR_BUSY: ids = bEnglish ? IDS_DPERR_BUSY_ENGLISH : IDS_DPERR_BUSY; break;
  3820. case DPERR_CONNECTIONLOST: ids = bEnglish ? IDS_DPERR_CONNECTIONLOST_ENGLISH : IDS_DPERR_CONNECTIONLOST; break;
  3821. case DPERR_NOSERVICEPROVIDER: ids = bEnglish ? IDS_DPERR_NOSERVICEPROVIDER_ENGLISH : IDS_DPERR_NOSERVICEPROVIDER; break;
  3822. case DPERR_UNAVAILABLE: ids = bEnglish ? IDS_DPERR_UNAVAILABLE_ENGLISH : IDS_DPERR_UNAVAILABLE; break;
  3823. default: ids = bEnglish ? IDS_UNKNOWNERROR_ENGLISH : IDS_UNKNOWNERROR; break;
  3824. }
  3825. LoadString(NULL, ids, psz, 200);
  3826. if (ids != IDS_UNKNOWNERROR && ids != IDS_UNKNOWNERROR_ENGLISH)
  3827. return TRUE;
  3828. else
  3829. return FALSE;
  3830. }
  3831. /****************************************************************************
  3832. *
  3833. * RestoreDrivers
  3834. *
  3835. ****************************************************************************/
  3836. VOID RestoreDrivers(VOID)
  3837. {
  3838. TCHAR szDir[MAX_PATH];
  3839. if (GetProgramFilesFolder(szDir))
  3840. {
  3841. lstrcat(szDir, TEXT("\\DirectX\\Setup"));
  3842. HINSTANCE hInstResult = ShellExecute( s_hwndMain, NULL, TEXT("DxSetup.exe"),
  3843. NULL, szDir, SW_SHOWNORMAL ) ;
  3844. if( (INT_PTR)hInstResult < 32 )
  3845. ReportError(IDS_NODXSETUP);
  3846. }
  3847. }
  3848. /****************************************************************************
  3849. *
  3850. * BCanRestoreDrivers - Returns whether backed-up drivers can be restored.
  3851. * This function checks for the presence of dxsetup.exe where it should
  3852. * be, and the existence of files in either <system>\dxbackup\display or
  3853. * <system>\dxbackup\media.
  3854. *
  3855. ****************************************************************************/
  3856. BOOL BCanRestoreDrivers(VOID)
  3857. {
  3858. TCHAR szPath[MAX_PATH];
  3859. if (!GetProgramFilesFolder(szPath))
  3860. return FALSE;
  3861. lstrcat(szPath, TEXT("\\DirectX\\Setup\\DxSetup.exe"));
  3862. if (GetFileAttributes(szPath) == 0xffffffff)
  3863. return FALSE;
  3864. if (!GetSystemDirectory(szPath, MAX_PATH))
  3865. return FALSE;
  3866. lstrcat(szPath, TEXT("\\dxbackup\\display"));
  3867. if (GetFileAttributes(szPath) != 0xffffffff)
  3868. return TRUE;
  3869. if (!GetSystemDirectory(szPath, MAX_PATH))
  3870. return FALSE;
  3871. lstrcat(szPath, TEXT("\\dxbackup\\media"));
  3872. if (GetFileAttributes(szPath) != 0xffffffff)
  3873. return TRUE;
  3874. return FALSE;
  3875. }
  3876. /****************************************************************************
  3877. *
  3878. * HandleSndSliderChange
  3879. *
  3880. ****************************************************************************/
  3881. VOID HandleSndSliderChange(INT nScrollCode, INT nPos)
  3882. {
  3883. TCHAR sz[MAX_PATH];
  3884. if (nScrollCode != SB_THUMBTRACK && nScrollCode != SB_THUMBPOSITION)
  3885. nPos = (INT)SendMessage(GetDlgItem(s_hwndCurPage, IDC_SNDACCELSLIDER), TBM_GETPOS, 0, 0);
  3886. if (nScrollCode == SB_THUMBTRACK ||
  3887. nScrollCode == SB_LEFT ||
  3888. nScrollCode == SB_RIGHT ||
  3889. nScrollCode == SB_LINELEFT ||
  3890. nScrollCode == SB_LINERIGHT ||
  3891. nScrollCode == SB_PAGELEFT ||
  3892. nScrollCode == SB_PAGERIGHT)
  3893. {
  3894. switch (nPos)
  3895. {
  3896. case 0:
  3897. LoadString(NULL, IDS_NOSNDACCELERATION, sz, MAX_PATH);
  3898. break;
  3899. case 1:
  3900. LoadString(NULL, IDS_BASICSNDACCELERATION, sz, MAX_PATH);
  3901. break;
  3902. case 2:
  3903. LoadString(NULL, IDS_STANDARDSNDACCELERATION, sz, MAX_PATH);
  3904. break;
  3905. case 3:
  3906. LoadString(NULL, IDS_FULLSNDACCELERATION, sz, MAX_PATH);
  3907. break;
  3908. default:
  3909. lstrcpy(sz, TEXT(""));
  3910. break;
  3911. }
  3912. SetWindowText(GetDlgItem(s_hwndCurPage, IDC_SNDACCELDESC), sz);
  3913. }
  3914. if (nScrollCode != SB_THUMBTRACK && nScrollCode != SB_ENDSCROLL &&
  3915. s_pSoundInfoFirst != NULL )
  3916. {
  3917. HRESULT hr;
  3918. SoundInfo* pSoundInfo = s_pSoundInfoFirst;
  3919. LONG iSound = s_lwCurPage - s_iPageSoundFirst;
  3920. while (iSound > 0)
  3921. {
  3922. pSoundInfo = pSoundInfo->m_pSoundInfoNext;
  3923. iSound--;
  3924. }
  3925. if (nPos != pSoundInfo->m_lwAccelerationLevel)
  3926. {
  3927. if (FAILED(hr = ChangeAccelerationLevel(pSoundInfo, nPos)))
  3928. {
  3929. // TODO: report error
  3930. }
  3931. DestroySoundInfo(s_pSoundInfoFirst);
  3932. pSoundInfo = NULL;
  3933. s_pSoundInfoFirst = NULL;
  3934. // ******* GetBasicSoundInfo (DS:1) ********
  3935. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 1 );
  3936. if( s_bUseDSound )
  3937. {
  3938. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  3939. if (FAILED(hr = GetBasicSoundInfo(&s_pSoundInfoFirst)))
  3940. ReportError(IDS_NOBASICSOUNDINFO, hr);
  3941. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 1 );
  3942. }
  3943. // ******* GetExtraSoundInfo (DS:2) ********
  3944. if( s_bUseDSound )
  3945. {
  3946. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 2 );
  3947. if( s_bUseDSound )
  3948. {
  3949. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 2 );
  3950. if (FAILED(hr = GetExtraSoundInfo(s_pSoundInfoFirst)))
  3951. ReportError(IDS_NOEXTRASOUNDINFO, hr);
  3952. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 2 );
  3953. }
  3954. }
  3955. // ******* GetDSSoundInfo (DS:3) ********
  3956. if( s_bUseDSound )
  3957. {
  3958. s_bUseDSound = QueryCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, IDS_DS, 3 );
  3959. if( s_bUseDSound )
  3960. {
  3961. EnterCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 3 );
  3962. if (FAILED(hr = GetDSSoundInfo(s_pSoundInfoFirst)))
  3963. ReportError(IDS_NOEXTRASOUNDINFO, hr);
  3964. LeaveCrashProtection( DXD_IN_DS_KEY, DXD_IN_DS_VALUE, 3 );
  3965. }
  3966. }
  3967. SetupSoundPage( s_lwCurPage - s_iPageSoundFirst );
  3968. }
  3969. }
  3970. }
  3971. /****************************************************************************
  3972. *
  3973. * TroubleShoot
  3974. *
  3975. ****************************************************************************/
  3976. VOID TroubleShoot( BOOL bTroubleShootSound )
  3977. {
  3978. TCHAR szHelpDir[MAX_PATH];
  3979. TCHAR szHelpLeaf[MAX_PATH];
  3980. TCHAR szHelpExe[MAX_PATH];
  3981. TCHAR szTroubleshooter[MAX_PATH];
  3982. TCHAR szSubInfo[MAX_PATH];
  3983. GetWindowsDirectory(szHelpDir, MAX_PATH);
  3984. LoadString(NULL, IDS_HELPDIRLEAF, szHelpLeaf, MAX_PATH);
  3985. LoadString(NULL, IDS_HELPEXE, szHelpExe, MAX_PATH);
  3986. lstrcat(szHelpDir, szHelpLeaf);
  3987. if( bTroubleShootSound )
  3988. {
  3989. if( BIsWin98() || BIsWin95() )
  3990. {
  3991. TCHAR szHelpPath[MAX_PATH];
  3992. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  3993. lstrcpy(szHelpPath, szHelpDir);
  3994. lstrcat(szHelpPath, TEXT("\\"));
  3995. lstrcat(szHelpPath, szTroubleshooter);
  3996. if (GetFileAttributes(szHelpPath) == 0xffffffff)
  3997. {
  3998. LoadString(NULL, IDS_SOUNDTROUBLESHOOTER_WIN98, szTroubleshooter, MAX_PATH);
  3999. lstrcpy( szSubInfo, TEXT("") );
  4000. }
  4001. else
  4002. {
  4003. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  4004. LoadString(NULL, IDS_TSSOUNDSUBINFO_WIN98SE, szSubInfo, MAX_PATH);
  4005. }
  4006. }
  4007. else if( BIsWinME() )
  4008. {
  4009. LoadString(NULL, IDS_TROUBLESHOOTER_WINME_HCP, szHelpExe, MAX_PATH);
  4010. LoadString(NULL, IDS_TSSOUNDSUBINFO_WINME_HCP, szSubInfo, MAX_PATH);
  4011. lstrcat(szHelpExe, szSubInfo);
  4012. lstrcpy(szTroubleshooter, TEXT("") );
  4013. lstrcpy(szSubInfo, TEXT("") );
  4014. }
  4015. else if( BIsWin2k() )
  4016. {
  4017. LoadString(NULL, IDS_TROUBLESHOOTER_WIN2K, szTroubleshooter, MAX_PATH);
  4018. LoadString(NULL, IDS_TSSOUNDSUBINFO_WIN2K, szSubInfo, MAX_PATH);
  4019. }
  4020. else // if( BIsWhistler() )
  4021. {
  4022. lstrcpy( szHelpExe, TEXT("hcp://help/tshoot/tssound.htm") );
  4023. lstrcpy( szTroubleshooter, TEXT("") );
  4024. lstrcpy( szSubInfo, TEXT("") );
  4025. }
  4026. }
  4027. else
  4028. {
  4029. if( BIsWin98() || BIsWin95() )
  4030. {
  4031. TCHAR szHelpPath[MAX_PATH];
  4032. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  4033. lstrcpy(szHelpPath, szHelpDir);
  4034. lstrcat(szHelpPath, TEXT("\\"));
  4035. lstrcat(szHelpPath, szTroubleshooter);
  4036. if (GetFileAttributes(szHelpPath) == 0xffffffff)
  4037. {
  4038. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98, szTroubleshooter, MAX_PATH);
  4039. lstrcpy( szSubInfo, TEXT("") );
  4040. }
  4041. else
  4042. {
  4043. LoadString(NULL, IDS_TROUBLESHOOTER_WIN98SE, szTroubleshooter, MAX_PATH);
  4044. LoadString(NULL, IDS_TSSUBINFO_WIN98SE, szSubInfo, MAX_PATH);
  4045. }
  4046. }
  4047. else if( BIsWinME() )
  4048. {
  4049. LoadString(NULL, IDS_TROUBLESHOOTER_WINME_HCP, szHelpExe, MAX_PATH);
  4050. LoadString(NULL, IDS_TSSUBINFO_WINME_HCP, szSubInfo, MAX_PATH);
  4051. lstrcat(szHelpExe, szSubInfo);
  4052. lstrcpy(szTroubleshooter, TEXT("") );
  4053. lstrcpy(szSubInfo, TEXT("") );
  4054. }
  4055. else if( BIsWin2k() )
  4056. {
  4057. LoadString(NULL, IDS_TROUBLESHOOTER_WIN2K, szTroubleshooter, MAX_PATH);
  4058. LoadString(NULL, IDS_TSSUBINFO_WIN2K, szSubInfo, MAX_PATH);
  4059. }
  4060. else // if( BIsWhistler() )
  4061. {
  4062. lstrcpy( szHelpExe, TEXT("hcp://help/tshoot/tsgame.htm") );
  4063. lstrcpy( szTroubleshooter, TEXT("") );
  4064. lstrcpy( szSubInfo, TEXT("") );
  4065. }
  4066. }
  4067. lstrcat(szTroubleshooter, szSubInfo);
  4068. HINSTANCE hInstResult = ShellExecute( s_hwndMain, NULL, szHelpExe,
  4069. szTroubleshooter,
  4070. szHelpDir, SW_SHOWNORMAL ) ;
  4071. if( (INT_PTR)hInstResult < 32 )
  4072. ReportError(IDS_NOTROUBLESHOOTER);
  4073. }
  4074. /****************************************************************************
  4075. *
  4076. * QueryCrashProtection
  4077. *
  4078. ****************************************************************************/
  4079. BOOL QueryCrashProtection( TCHAR* strKey, TCHAR* strValue,
  4080. int nSkipComponent, DWORD dwCurrentStep )
  4081. {
  4082. HKEY hkey = NULL;
  4083. BOOL bAllowCall = TRUE;
  4084. // Open the key
  4085. if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, KEY_ALL_ACCESS, &hkey) )
  4086. {
  4087. DWORD dwType = 0;
  4088. DWORD dwCrashedOnStep = 0;
  4089. DWORD cbData = sizeof(dwCrashedOnStep);
  4090. // Query the key for the value of where the last crash occurred
  4091. if( ERROR_SUCCESS == RegQueryValueEx( hkey, strValue, 0, &dwType,
  4092. (BYTE*)&dwCrashedOnStep, &cbData) )
  4093. {
  4094. // If we are at or beyond the crash step, then ask the user
  4095. // to continue or not
  4096. if( dwCurrentStep >= dwCrashedOnStep )
  4097. {
  4098. if( !s_bGUI )
  4099. {
  4100. // If there's no gui, don't ask just don't use it
  4101. bAllowCall = FALSE;
  4102. }
  4103. else
  4104. {
  4105. // If the UI is alive then have it ask the user,
  4106. // otherwise do it ourselves
  4107. if( s_hwndMain && s_hUIThread )
  4108. {
  4109. // Mark down which component we're skipping in s_nSkipComponent,
  4110. // and then post a WM_QUERYSKIP message to the UI thread
  4111. // it will process this message, ask the user, and signal the
  4112. // s_hQuerySkipEvent event.
  4113. s_nSkipComponent = nSkipComponent;
  4114. PostMessage( s_hwndMain, WM_QUERYSKIP, 0, 0 );
  4115. HANDLE aWait[2];
  4116. DWORD dwResult;
  4117. aWait[0] = s_hQuerySkipEvent;
  4118. aWait[1] = s_hUIThread;
  4119. // Its possible that the UI thread exited before it processed the
  4120. // WM_QUERYSKIP message, so wait for either the event and thread exiting
  4121. dwResult = WaitForMultipleObjects( 2, aWait, FALSE, INFINITE );
  4122. // If the event was signaled, then get the result from s_bQuerySkipAllow,
  4123. // otherwise skip this call (the main code will exit if it sees the UI thread gone)
  4124. if( dwResult == WAIT_OBJECT_0 )
  4125. bAllowCall = s_bQuerySkipAllow;
  4126. else
  4127. bAllowCall = FALSE;
  4128. }
  4129. else
  4130. {
  4131. // If there's is no gui, ask if to use it now
  4132. TCHAR szTitle[MAX_PATH];
  4133. TCHAR szMessage[MAX_PATH];
  4134. TCHAR szFmt[MAX_PATH];
  4135. TCHAR szMessageComponent[MAX_PATH];
  4136. LoadString(0, IDS_APPFULLNAME, szTitle, MAX_PATH);
  4137. LoadString(0, IDS_SKIP, szFmt, MAX_PATH);
  4138. LoadString(0, nSkipComponent, szMessageComponent, MAX_PATH);
  4139. wsprintf( szMessage, szFmt, szMessageComponent, szMessageComponent );
  4140. if( IDYES == MessageBox( s_hwndMain, szMessage, szTitle, MB_YESNO) )
  4141. bAllowCall = FALSE;
  4142. }
  4143. }
  4144. }
  4145. }
  4146. RegCloseKey(hkey);
  4147. }
  4148. return bAllowCall;
  4149. }
  4150. /****************************************************************************
  4151. *
  4152. * EnterCrashProtection
  4153. *
  4154. ****************************************************************************/
  4155. VOID EnterCrashProtection( TCHAR* strKey, TCHAR* strValue, DWORD dwCurrentStep )
  4156. {
  4157. HKEY hkey = NULL;
  4158. BOOL bSetValue = FALSE;
  4159. DWORD dwDisposition;
  4160. // Write reg key indicating we are inside the crash protection
  4161. if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_LOCAL_MACHINE, strKey, 0,
  4162. NULL, REG_OPTION_NON_VOLATILE,
  4163. KEY_ALL_ACCESS, NULL, &hkey, &dwDisposition) )
  4164. {
  4165. DWORD dwType = 0;
  4166. DWORD dwCrashedOnStep = 0;
  4167. DWORD cbData = sizeof(dwCrashedOnStep);
  4168. // Query the key for the value of where the last crash occurred
  4169. if( ERROR_SUCCESS == RegQueryValueEx( hkey, strValue, 0, &dwType,
  4170. (BYTE*)&dwCrashedOnStep, &cbData) )
  4171. {
  4172. // If we are beyond whats currently in the reg, then update the value
  4173. if( dwCurrentStep > dwCrashedOnStep )
  4174. bSetValue = TRUE;
  4175. }
  4176. else
  4177. {
  4178. // If the value doesn't exist current, then create it
  4179. bSetValue = TRUE;
  4180. }
  4181. if( bSetValue )
  4182. {
  4183. RegSetValueEx( hkey, strValue, 0, REG_DWORD,
  4184. (BYTE*)&dwCurrentStep, sizeof(dwCurrentStep));
  4185. }
  4186. RegCloseKey(hkey);
  4187. }
  4188. }
  4189. /****************************************************************************
  4190. *
  4191. * LeaveCrashProtection
  4192. *
  4193. ****************************************************************************/
  4194. VOID LeaveCrashProtection( TCHAR* strKey, TCHAR* strValue, DWORD dwCurrentStep )
  4195. {
  4196. HKEY hkey = NULL;
  4197. // Remove reg key since we're done with the crash protection
  4198. if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, strKey, 0,
  4199. KEY_ALL_ACCESS, &hkey))
  4200. {
  4201. DWORD dwType = 0;
  4202. DWORD dwCrashedOnStep = 0;
  4203. DWORD cbData = sizeof(dwCrashedOnStep);
  4204. // Query the key for the value of where the last crash occurred
  4205. if( ERROR_SUCCESS == RegQueryValueEx( hkey, strValue, 0, &dwType,
  4206. (BYTE*)&dwCrashedOnStep, &cbData) )
  4207. {
  4208. // If we are at or beyond that crash step, then delete the key
  4209. if( dwCurrentStep >= dwCrashedOnStep )
  4210. {
  4211. RegDeleteValue(hkey, strValue);
  4212. }
  4213. }
  4214. RegCloseKey(hkey);
  4215. }
  4216. }
  4217. /****************************************************************************
  4218. *
  4219. * TestD3D
  4220. *
  4221. ****************************************************************************/
  4222. VOID TestD3D(HWND hwndMain, DisplayInfo* pDisplayInfo)
  4223. {
  4224. TCHAR sz[MAX_PATH];
  4225. TCHAR szTitle[MAX_PATH];
  4226. LoadString(NULL, IDS_STARTD3DTEST, sz, MAX_PATH);
  4227. LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH);
  4228. if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
  4229. return;
  4230. // Erase old D3D7 test results
  4231. ZeroMemory(&pDisplayInfo->m_testResultD3D7, sizeof(TestResult));
  4232. pDisplayInfo->m_testResultD3D7.m_bStarted = TRUE;
  4233. // Erase old D3D8 test results
  4234. ZeroMemory(&pDisplayInfo->m_testResultD3D8, sizeof(TestResult));
  4235. pDisplayInfo->m_testResultD3D8.m_bStarted = TRUE;
  4236. if( FALSE == BIsIA64() )
  4237. {
  4238. // First test (D3D7)
  4239. LoadString(NULL, IDS_D3DTEST1, sz, MAX_PATH);
  4240. if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL))
  4241. {
  4242. pDisplayInfo->m_testResultD3D7.m_bCancelled = TRUE;
  4243. goto LEnd;
  4244. }
  4245. // Run D3D7 test
  4246. TestD3Dv7( TRUE, hwndMain, pDisplayInfo );
  4247. if( pDisplayInfo->m_testResultD3D7.m_bCancelled ||
  4248. pDisplayInfo->m_testResultD3D7.m_iStepThatFailed != 0 )
  4249. goto LEnd;
  4250. }
  4251. // Second test (D3D8)
  4252. LoadString(NULL, IDS_D3DTEST2, sz, MAX_PATH);
  4253. if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL))
  4254. {
  4255. pDisplayInfo->m_testResultD3D8.m_bCancelled = TRUE;
  4256. goto LEnd;
  4257. }
  4258. // Run D3D8 test
  4259. TestD3Dv8( TRUE, hwndMain, pDisplayInfo );
  4260. if( pDisplayInfo->m_testResultD3D8.m_bCancelled ||
  4261. pDisplayInfo->m_testResultD3D8.m_iStepThatFailed != 0 )
  4262. goto LEnd;
  4263. LEnd:
  4264. // Default to displaying results of D3D8 tests
  4265. pDisplayInfo->m_dwTestToDisplayD3D = 8;
  4266. if (pDisplayInfo->m_testResultD3D7.m_bCancelled || pDisplayInfo->m_testResultD3D8.m_bCancelled)
  4267. {
  4268. LoadString(NULL, IDS_TESTSCANCELLED, sz, MAX_PATH);
  4269. lstrcpy(pDisplayInfo->m_testResultD3D7.m_szDescription, sz);
  4270. lstrcpy(pDisplayInfo->m_testResultD3D8.m_szDescription, sz);
  4271. LoadString(NULL, IDS_TESTSCANCELLED_ENGLISH, sz, MAX_PATH);
  4272. lstrcpy(pDisplayInfo->m_testResultD3D7.m_szDescriptionEnglish, sz);
  4273. lstrcpy(pDisplayInfo->m_testResultD3D8.m_szDescriptionEnglish, sz);
  4274. }
  4275. else
  4276. {
  4277. if( pDisplayInfo->m_testResultD3D7.m_iStepThatFailed == 0 )
  4278. {
  4279. LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, MAX_PATH);
  4280. lstrcpy(pDisplayInfo->m_testResultD3D7.m_szDescriptionEnglish, sz);
  4281. LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, MAX_PATH);
  4282. lstrcpy(pDisplayInfo->m_testResultD3D7.m_szDescription, sz);
  4283. }
  4284. if( pDisplayInfo->m_testResultD3D8.m_iStepThatFailed == 0 )
  4285. {
  4286. LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, MAX_PATH);
  4287. lstrcpy(pDisplayInfo->m_testResultD3D8.m_szDescription, sz);
  4288. LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, MAX_PATH);
  4289. lstrcpy(pDisplayInfo->m_testResultD3D8.m_szDescriptionEnglish, sz);
  4290. }
  4291. if( pDisplayInfo->m_testResultD3D7.m_iStepThatFailed != 0 ||
  4292. pDisplayInfo->m_testResultD3D8.m_iStepThatFailed != 0 )
  4293. {
  4294. TCHAR szDesc[MAX_PATH];
  4295. TCHAR szError[MAX_PATH];
  4296. TestResult* pFailedTestResult = NULL;
  4297. if( pDisplayInfo->m_testResultD3D7.m_iStepThatFailed != 0 )
  4298. {
  4299. pFailedTestResult = &pDisplayInfo->m_testResultD3D7;
  4300. pDisplayInfo->m_dwTestToDisplayD3D = 7;
  4301. }
  4302. else
  4303. {
  4304. pFailedTestResult = &pDisplayInfo->m_testResultD3D8;
  4305. pDisplayInfo->m_dwTestToDisplayD3D = 8;
  4306. }
  4307. if (0 == LoadString(NULL, IDS_FIRSTD3DTESTERROR + pFailedTestResult->m_iStepThatFailed - 1,
  4308. szDesc, MAX_PATH))
  4309. {
  4310. LoadString(NULL, IDS_UNKNOWNERROR, sz, MAX_PATH);
  4311. lstrcpy(szDesc, sz);
  4312. }
  4313. LoadString(NULL, IDS_FAILUREFMT, sz, MAX_PATH);
  4314. BTranslateError(pFailedTestResult->m_hr, szError);
  4315. wsprintf(pFailedTestResult->m_szDescription, sz,
  4316. pFailedTestResult->m_iStepThatFailed,
  4317. szDesc, pFailedTestResult->m_hr, szError);
  4318. // Nonlocalized version:
  4319. if (0 == LoadString(NULL, IDS_FIRSTD3DTESTERROR_ENGLISH + pFailedTestResult->m_iStepThatFailed - 1,
  4320. szDesc, MAX_PATH))
  4321. {
  4322. LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, MAX_PATH);
  4323. lstrcpy(szDesc, sz);
  4324. }
  4325. LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, MAX_PATH);
  4326. BTranslateError(pFailedTestResult->m_hr, szError, TRUE);
  4327. wsprintf(pFailedTestResult->m_szDescriptionEnglish, sz,
  4328. pFailedTestResult->m_iStepThatFailed,
  4329. szDesc, pFailedTestResult->m_hr, szError);
  4330. }
  4331. }
  4332. }
  4333. /****************************************************************************
  4334. *
  4335. * GetTxtPath
  4336. *
  4337. ****************************************************************************/
  4338. BOOL GetTxtPath( TCHAR* strTxtPath )
  4339. {
  4340. HKEY hkey = NULL;
  4341. BOOL bFound = FALSE;
  4342. DWORD ulType;
  4343. DWORD cbData;
  4344. // Get default user info from registry
  4345. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectX Diagnostic Tool"),
  4346. 0, KEY_READ, &hkey))
  4347. {
  4348. cbData = MAX_PATH;
  4349. if( ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("TxtPath"), 0, &ulType, (LPBYTE)strTxtPath, &cbData ) )
  4350. bFound = TRUE;
  4351. RegCloseKey(hkey);
  4352. }
  4353. if( !bFound )
  4354. {
  4355. HKEY hkeyFolder;
  4356. // Same as SHGetSpecialFolderPath( hwnd, szFilename, CSIDL_DESKTOPDIRECTORY, FALSE );
  4357. if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
  4358. 0, KEY_READ, &hkeyFolder) )
  4359. {
  4360. cbData = MAX_PATH;
  4361. if (ERROR_SUCCESS == RegQueryValueEx( hkeyFolder, TEXT("Desktop"), 0, &ulType, (LPBYTE)strTxtPath, &cbData ) )
  4362. bFound = TRUE;
  4363. RegCloseKey( hkeyFolder );
  4364. }
  4365. }
  4366. return bFound;
  4367. }
  4368. /****************************************************************************
  4369. *
  4370. * SetTxtPath
  4371. *
  4372. ****************************************************************************/
  4373. VOID SetTxtPath( TCHAR* strTxtPath )
  4374. {
  4375. HKEY hkey = NULL;
  4376. // Try to save user info into registry
  4377. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectX Diagnostic Tool"),
  4378. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
  4379. {
  4380. RegSetValueEx(hkey, TEXT("TxtPath"), 0, REG_SZ, (BYTE*)strTxtPath, sizeof(TCHAR)*(lstrlen(strTxtPath) + 1));
  4381. RegCloseKey(hkey);
  4382. }
  4383. }