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.

1028 lines
37 KiB

  1. /****************************************************************************
  2. *
  3. * File: netinfo.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Mike Anderson (manders@microsoft.com)
  6. * Purpose: Gather information about DirectPlay
  7. *
  8. * (C) Copyright 1998 Microsoft Corp. All rights reserved.
  9. *
  10. ****************************************************************************/
  11. #include <tchar.h>
  12. #include <Windows.h>
  13. #include <multimon.h>
  14. #include <stdio.h>
  15. #include <dplobby.h>
  16. #include "resource.h"
  17. #include "reginfo.h"
  18. #include "sysinfo.h"
  19. #include "dispinfo.h" // for TestResult
  20. #include "fileinfo.h" // for GetFileVersion
  21. #include "netinfo.h"
  22. static HRESULT NewNetSP(NetInfo* pNetInfo, NetSP** ppNetSPNew);
  23. static VOID DeleteNetSP(NetInfo* pNetInfo, NetSP* pNetSP);
  24. static HRESULT NewNetApp(NetInfo* pNetInfo, NetApp** ppNetAppNew);
  25. static HRESULT GetDX7ServiceProviders(NetInfo* pNetInfo);
  26. static HRESULT GetDX8ServiceProviders(NetInfo* pNetInfo);
  27. static HRESULT GetDX7LobbyableApps(NetInfo* pNetInfo);
  28. static HRESULT GetDX8LobbyableApps(NetInfo* pNetInfo);
  29. static BOOL ConvertStringToGUID(const WCHAR* strBuffer, GUID* lpguid);
  30. /****************************************************************************
  31. *
  32. * GetNetInfo
  33. *
  34. ****************************************************************************/
  35. HRESULT GetNetInfo(SysInfo* pSysInfo, NetInfo** ppNetInfo)
  36. {
  37. HRESULT hr = S_OK;
  38. NetInfo* pNetInfo;
  39. pNetInfo = new NetInfo;
  40. if (pNetInfo == NULL)
  41. return E_OUTOFMEMORY;
  42. *ppNetInfo = pNetInfo;
  43. ZeroMemory(pNetInfo, sizeof(NetInfo));
  44. if( FALSE == BIsIA64() )
  45. {
  46. if (FAILED(hr = GetDX7ServiceProviders(pNetInfo)))
  47. return hr;
  48. if (FAILED(hr = GetDX7LobbyableApps(pNetInfo)))
  49. return hr;
  50. }
  51. if( pSysInfo->m_dwDirectXVersionMajor >= 8 )
  52. {
  53. if (FAILED(hr = GetDX8ServiceProviders(pNetInfo)))
  54. return hr;
  55. if (FAILED(hr = GetDX8LobbyableApps(pNetInfo)))
  56. return hr;
  57. }
  58. return hr;
  59. }
  60. /****************************************************************************
  61. *
  62. * NewNetSP
  63. *
  64. ****************************************************************************/
  65. HRESULT NewNetSP(NetInfo* pNetInfo, NetSP** ppNetSPNew)
  66. {
  67. NetSP* pNetSPNew;
  68. pNetSPNew = new NetSP;
  69. if (pNetSPNew == NULL)
  70. return E_OUTOFMEMORY;
  71. ZeroMemory(pNetSPNew, sizeof(NetSP));
  72. if (pNetInfo->m_pNetSPFirst == NULL)
  73. {
  74. pNetInfo->m_pNetSPFirst = pNetSPNew;
  75. }
  76. else
  77. {
  78. NetSP* pNetSP;
  79. for (pNetSP = pNetInfo->m_pNetSPFirst;
  80. pNetSP->m_pNetSPNext != NULL;
  81. pNetSP = pNetSP->m_pNetSPNext)
  82. {
  83. }
  84. pNetSP->m_pNetSPNext = pNetSPNew;
  85. }
  86. pNetSPNew->m_bRegistryOK = TRUE; // so far
  87. *ppNetSPNew = pNetSPNew;
  88. return S_OK;
  89. }
  90. /****************************************************************************
  91. *
  92. * DeleteNetSP
  93. *
  94. ****************************************************************************/
  95. VOID DeleteNetSP(NetInfo* pNetInfo, NetSP* pNetSP)
  96. {
  97. NetSP* pNetSPPrev = NULL;
  98. NetSP* pNetSPCur;
  99. for (pNetSPCur = pNetInfo->m_pNetSPFirst;
  100. pNetSPCur != NULL;
  101. pNetSPCur = pNetSPCur->m_pNetSPNext)
  102. {
  103. if (pNetSPCur == pNetSP)
  104. {
  105. if (pNetSPPrev == NULL)
  106. pNetInfo->m_pNetSPFirst = pNetSPCur->m_pNetSPNext;
  107. else
  108. pNetSPPrev->m_pNetSPNext = pNetSPCur->m_pNetSPNext;
  109. delete pNetSPCur;
  110. return;
  111. }
  112. pNetSPPrev = pNetSPCur;
  113. }
  114. }
  115. /****************************************************************************
  116. *
  117. * NewNetApp
  118. *
  119. ****************************************************************************/
  120. HRESULT NewNetApp(NetInfo* pNetInfo, NetApp** ppNetAppNew)
  121. {
  122. NetApp* pNetAppNew;
  123. pNetAppNew = new NetApp;
  124. if (pNetAppNew == NULL)
  125. return E_OUTOFMEMORY;
  126. ZeroMemory(pNetAppNew, sizeof(NetApp));
  127. if (pNetInfo->m_pNetAppFirst == NULL)
  128. {
  129. pNetInfo->m_pNetAppFirst = pNetAppNew;
  130. }
  131. else
  132. {
  133. NetApp* pNetApp;
  134. for (pNetApp = pNetInfo->m_pNetAppFirst;
  135. pNetApp->m_pNetAppNext != NULL;
  136. pNetApp = pNetApp->m_pNetAppNext)
  137. {
  138. }
  139. pNetApp->m_pNetAppNext = pNetAppNew;
  140. }
  141. pNetAppNew->m_bRegistryOK = TRUE; // so far
  142. *ppNetAppNew = pNetAppNew;
  143. return S_OK;
  144. }
  145. /****************************************************************************
  146. *
  147. * GetDX7ServiceProviders
  148. *
  149. ****************************************************************************/
  150. HRESULT GetDX7ServiceProviders(NetInfo* pNetInfo)
  151. {
  152. HRESULT hr;
  153. HKEY hkey = NULL;
  154. HKEY hkey2 = NULL;
  155. DWORD dwIndex;
  156. DWORD dwBufferLen;
  157. BOOL bTCPIPFound = FALSE;
  158. BOOL bIPXFound = FALSE;
  159. BOOL bModemFound = FALSE;
  160. BOOL bSerialFound = FALSE;
  161. TCHAR szName[MAX_PATH+1];
  162. NetSP* pNetSPNew;
  163. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectPlay\\Service Providers"), 0, KEY_READ, &hkey))
  164. {
  165. dwIndex = 0;
  166. while (ERROR_SUCCESS == RegEnumKey(hkey, dwIndex, szName, MAX_PATH+1))
  167. {
  168. // Note: I'm not putting the following keyname strings into resources because
  169. // they're supposed to be in English regardless of user's system (at least on DX6
  170. // and higher--see another note below). If I put them into resources, they're
  171. // more likely to get inadvertently localized.
  172. if (lstrcmpi(szName, TEXT("Internet TCP/IP Connection For DirectPlay")) == 0)
  173. bTCPIPFound = TRUE;
  174. else if (lstrcmpi(szName, TEXT("IPX Connection For DirectPlay")) == 0)
  175. bIPXFound = TRUE;
  176. else if (lstrcmpi(szName, TEXT("Modem Connection For DirectPlay")) == 0)
  177. bModemFound = TRUE;
  178. else if (lstrcmpi(szName, TEXT("Serial Connection For DirectPlay")) == 0)
  179. bSerialFound = TRUE;
  180. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  181. {
  182. RegCloseKey(hkey);
  183. return hr;
  184. }
  185. pNetSPNew->m_dwDXVer = 7;
  186. // The following line is the right thing to do on DX5, but in DX6 the
  187. // name will get overwritten by the "DescriptionW" / "DescriptionA" string.
  188. lstrcpy(pNetSPNew->m_szName, szName);
  189. lstrcpy(pNetSPNew->m_szNameEnglish, szName);
  190. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, szName, 0, KEY_READ, &hkey2))
  191. {
  192. // Get (localized) connection name, if it exists
  193. TCHAR szDescription[200];
  194. lstrcpy(szDescription, TEXT(""));
  195. dwBufferLen = 200;
  196. RegQueryValueEx(hkey2,
  197. // 25080: Always use DescriptionW because it's more localized
  198. // than DescriptionA is.
  199. TEXT("DescriptionW"),
  200. 0, NULL, (LPBYTE)szDescription, &dwBufferLen);
  201. if (lstrlen(szDescription) > 0)
  202. lstrcpy(pNetSPNew->m_szName, szDescription);
  203. dwBufferLen = 100;
  204. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("Guid"), 0, NULL, (LPBYTE)pNetSPNew->m_szGuid, &dwBufferLen))
  205. {
  206. // On DX5, the names of the registry keys for "Internet TCP/IP Connection
  207. // For DirectPlay", etc. were localized, so we need to check GUIDs to avoid
  208. // incorrectly thinking that some standard service providers are missing:
  209. if (!bTCPIPFound &&
  210. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{36E95EE0-8577-11cf-960C-0080C7534E82}")) == 0)
  211. {
  212. bTCPIPFound = TRUE;
  213. }
  214. if (!bIPXFound &&
  215. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{685BC400-9D2C-11cf-A9CD-00AA006886E3}")) == 0)
  216. {
  217. bIPXFound = TRUE;
  218. }
  219. if (!bModemFound &&
  220. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{44EAA760-CB68-11cf-9C4E-00A0C905425E}")) == 0)
  221. {
  222. bModemFound = TRUE;
  223. }
  224. if (!bSerialFound &&
  225. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{0F1D6860-88D9-11cf-9C4E-00A0C905425E}")) == 0)
  226. {
  227. bSerialFound = TRUE;
  228. }
  229. // If a non-English DX5 system was upgraded to DX6, it will have BOTH localized
  230. // and non-localized keynames for each service provider. The DX6 ones have
  231. // "DescriptionA" and "DescriptionW" strings
  232. // If a SP with this GUID has already been enumerated, replace it with the current
  233. // one if the current one has a description. Otherwise forget about the current
  234. // one.
  235. NetSP* pNetSPSearch;
  236. BOOL bFound = FALSE;
  237. for (pNetSPSearch = pNetInfo->m_pNetSPFirst; pNetSPSearch != NULL; pNetSPSearch = pNetSPSearch->m_pNetSPNext)
  238. {
  239. if (pNetSPSearch == pNetSPNew)
  240. continue;
  241. if (lstrcmp(pNetSPSearch->m_szGuid, pNetSPNew->m_szGuid) == 0)
  242. {
  243. bFound = TRUE;
  244. break;
  245. }
  246. }
  247. if (bFound)
  248. {
  249. if (lstrlen(szDescription) > 0)
  250. {
  251. // Current SP is better, nuke old one
  252. DeleteNetSP(pNetInfo, pNetSPSearch);
  253. }
  254. else
  255. {
  256. // Old SP is (probably) better, nuke current one
  257. DeleteNetSP(pNetInfo, pNetSPNew);
  258. goto LDoneWithSubKey;
  259. }
  260. }
  261. }
  262. else
  263. {
  264. pNetSPNew->m_bRegistryOK = FALSE;
  265. }
  266. TCHAR szPath[MAX_PATH];
  267. TCHAR* pszFile;
  268. dwBufferLen = MAX_PATH;
  269. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("Path"), 0, NULL, (LPBYTE)szPath, &dwBufferLen))
  270. {
  271. // On Win9x, szPath is full path. On NT, it's leaf only.
  272. pszFile = _tcsrchr(szPath, TEXT('\\'));
  273. if (pszFile == NULL)
  274. {
  275. lstrcpy(pNetSPNew->m_szFile, szPath);
  276. GetSystemDirectory(pNetSPNew->m_szPath, MAX_PATH);
  277. lstrcat(pNetSPNew->m_szPath, TEXT("\\"));
  278. lstrcat(pNetSPNew->m_szPath, szPath);
  279. }
  280. else
  281. {
  282. lstrcpy(pNetSPNew->m_szPath, szPath);
  283. lstrcpy(pNetSPNew->m_szFile, pszFile + 1); // skip backslash
  284. }
  285. WIN32_FIND_DATA findFileData;
  286. HANDLE hFind = FindFirstFile(pNetSPNew->m_szPath, &findFileData);
  287. if (hFind == INVALID_HANDLE_VALUE)
  288. {
  289. pNetSPNew->m_bFileMissing = TRUE;
  290. LoadString(NULL, IDS_FILEMISSING, pNetSPNew->m_szVersion, 50);
  291. LoadString(NULL, IDS_FILEMISSING_ENGLISH, pNetSPNew->m_szVersionEnglish, 50);
  292. }
  293. else
  294. {
  295. FindClose(hFind);
  296. GetFileVersion(pNetSPNew->m_szPath, pNetSPNew->m_szVersion,
  297. NULL, NULL, NULL);
  298. GetFileVersion(pNetSPNew->m_szPath, pNetSPNew->m_szVersionEnglish,
  299. NULL, NULL, NULL);
  300. }
  301. }
  302. else
  303. {
  304. pNetSPNew->m_bRegistryOK = FALSE;
  305. }
  306. LDoneWithSubKey:
  307. RegCloseKey(hkey2);
  308. }
  309. else
  310. {
  311. pNetSPNew->m_bRegistryOK = FALSE;
  312. }
  313. dwIndex++;
  314. }
  315. RegCloseKey(hkey);
  316. }
  317. if (!bTCPIPFound)
  318. {
  319. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  320. return hr;
  321. lstrcpy(pNetSPNew->m_szName, TEXT("Internet TCP/IP Connection For DirectPlay"));
  322. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("Internet TCP/IP Connection For DirectPlay"));
  323. pNetSPNew->m_bRegistryOK = FALSE;
  324. }
  325. if (!bIPXFound)
  326. {
  327. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  328. return hr;
  329. lstrcpy(pNetSPNew->m_szName, TEXT("IPX Connection For DirectPlay"));
  330. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("IPX Connection For DirectPlay"));
  331. pNetSPNew->m_bRegistryOK = FALSE;
  332. }
  333. if (!bModemFound)
  334. {
  335. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  336. return hr;
  337. lstrcpy(pNetSPNew->m_szName, TEXT("Modem Connection For DirectPlay"));
  338. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("Modem Connection For DirectPlay"));
  339. pNetSPNew->m_bRegistryOK = FALSE;
  340. }
  341. if (!bSerialFound)
  342. {
  343. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  344. return hr;
  345. lstrcpy(pNetSPNew->m_szName, TEXT("Serial Connection For DirectPlay"));
  346. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("Serial Connection For DirectPlay"));
  347. pNetSPNew->m_bRegistryOK = FALSE;
  348. }
  349. return S_OK;
  350. }
  351. /****************************************************************************
  352. *
  353. * GetDX8ServiceProviders
  354. *
  355. ****************************************************************************/
  356. HRESULT GetDX8ServiceProviders(NetInfo* pNetInfo)
  357. {
  358. HRESULT hr;
  359. HKEY hkey = NULL;
  360. HKEY hkey2 = NULL;
  361. HKEY hkeyDLL = NULL;
  362. DWORD dwIndex;
  363. DWORD dwBufferLen;
  364. BOOL bTCPIPFound = FALSE;
  365. BOOL bIPXFound = FALSE;
  366. BOOL bModemFound = FALSE;
  367. BOOL bSerialFound = FALSE;
  368. TCHAR szName[MAX_PATH+1];
  369. NetSP* pNetSPNew;
  370. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectPlay8\\Service Providers"), 0, KEY_READ, &hkey))
  371. {
  372. dwIndex = 0;
  373. while (ERROR_SUCCESS == RegEnumKey(hkey, dwIndex, szName, MAX_PATH+1))
  374. {
  375. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  376. {
  377. RegCloseKey(hkey);
  378. return hr;
  379. }
  380. pNetSPNew->m_dwDXVer = 8;
  381. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, szName, 0, KEY_READ, &hkey2))
  382. {
  383. TCHAR szDescription[200];
  384. lstrcpy(szDescription, TEXT(""));
  385. TCHAR szEnglishDescription[200];
  386. dwBufferLen = 200;
  387. if (ERROR_SUCCESS == RegQueryValueEx( hkey2, TEXT("Friendly Name"), 0, NULL, (LPBYTE)szDescription, &dwBufferLen) )
  388. {
  389. }
  390. else
  391. {
  392. pNetSPNew->m_bRegistryOK = FALSE;
  393. }
  394. lstrcpy(szEnglishDescription, szDescription);
  395. dwBufferLen = 100;
  396. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("GUID"), 0, NULL, (LPBYTE)pNetSPNew->m_szGuid, &dwBufferLen))
  397. {
  398. WCHAR strBuffer[MAX_PATH];
  399. #ifdef _UNICODE
  400. wcscpy( strBuffer, pNetSPNew->m_szGuid );
  401. #else
  402. MultiByteToWideChar( CP_ACP, 0, pNetSPNew->m_szGuid, -1,
  403. strBuffer, _tcslen(pNetSPNew->m_szGuid) );
  404. #endif
  405. ConvertStringToGUID( strBuffer, &pNetSPNew->m_guid );
  406. }
  407. else
  408. {
  409. pNetSPNew->m_bRegistryOK = FALSE;
  410. }
  411. TCHAR szRegKey[200];
  412. wsprintf( szRegKey, TEXT("CLSID\\%s\\InprocServer32"), pNetSPNew->m_szGuid );
  413. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, szRegKey, 0, KEY_READ, &hkeyDLL))
  414. {
  415. if (ERROR_SUCCESS == RegQueryValueEx(hkeyDLL, NULL, 0, NULL, (LPBYTE)pNetSPNew->m_szFile, &dwBufferLen))
  416. {
  417. GetSystemDirectory(pNetSPNew->m_szPath, MAX_PATH);
  418. lstrcat(pNetSPNew->m_szPath, TEXT("\\"));
  419. lstrcat(pNetSPNew->m_szPath, pNetSPNew->m_szFile);
  420. WIN32_FIND_DATA findFileData;
  421. HANDLE hFind = FindFirstFile(pNetSPNew->m_szPath, &findFileData);
  422. if (hFind == INVALID_HANDLE_VALUE)
  423. {
  424. pNetSPNew->m_bFileMissing = TRUE;
  425. LoadString(NULL, IDS_FILEMISSING, pNetSPNew->m_szVersion, 50);
  426. LoadString(NULL, IDS_FILEMISSING_ENGLISH, pNetSPNew->m_szVersionEnglish, 50);
  427. }
  428. else
  429. {
  430. FindClose(hFind);
  431. GetFileVersion(pNetSPNew->m_szPath, pNetSPNew->m_szVersion,
  432. NULL, NULL, NULL);
  433. GetFileVersion(pNetSPNew->m_szPath, pNetSPNew->m_szVersionEnglish,
  434. NULL, NULL, NULL);
  435. }
  436. }
  437. else
  438. {
  439. pNetSPNew->m_bRegistryOK = FALSE;
  440. }
  441. RegCloseKey(hkeyDLL);
  442. }
  443. else
  444. {
  445. pNetSPNew->m_bRegistryOK = FALSE;
  446. }
  447. if (!bTCPIPFound &&
  448. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{EBFE7BA0-628D-11D2-AE0F-006097B01411}")) == 0)
  449. {
  450. if( lstrcmpi(pNetSPNew->m_szFile, TEXT("dpnwsock.dll") ) != 0)
  451. pNetSPNew->m_bRegistryOK = FALSE;
  452. lstrcpy( szEnglishDescription, TEXT("DirectPlay8 TCP/IP Service Provider") );
  453. bTCPIPFound = TRUE;
  454. }
  455. if (!bIPXFound &&
  456. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{53934290-628D-11D2-AE0F-006097B01411}")) == 0)
  457. {
  458. if( lstrcmpi(pNetSPNew->m_szFile, TEXT("dpnwsock.dll") ) != 0)
  459. pNetSPNew->m_bRegistryOK = FALSE;
  460. lstrcpy( szEnglishDescription, TEXT("DirectPlay8 IPX Service Provider") );
  461. bIPXFound = TRUE;
  462. }
  463. if (!bModemFound &&
  464. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{6D4A3650-628D-11D2-AE0F-006097B01411}")) == 0)
  465. {
  466. if( lstrcmpi(pNetSPNew->m_szFile, TEXT("dpnmodem.dll") ) != 0)
  467. pNetSPNew->m_bRegistryOK = FALSE;
  468. lstrcpy( szEnglishDescription, TEXT("DirectPlay8 Modem Service Provider") );
  469. bModemFound = TRUE;
  470. }
  471. if (!bSerialFound &&
  472. lstrcmpi(pNetSPNew->m_szGuid, TEXT("{743B5D60-628D-11D2-AE0F-006097B01411}")) == 0)
  473. {
  474. if( lstrcmpi(pNetSPNew->m_szFile, TEXT("dpnmodem.dll") ) != 0)
  475. pNetSPNew->m_bRegistryOK = FALSE;
  476. lstrcpy( szEnglishDescription, TEXT("DirectPlay8 Serial Service Provider") );
  477. bSerialFound = TRUE;
  478. }
  479. lstrcpy(pNetSPNew->m_szName, szDescription);
  480. lstrcpy(pNetSPNew->m_szNameEnglish, szEnglishDescription);
  481. RegCloseKey(hkey2);
  482. }
  483. else
  484. {
  485. pNetSPNew->m_bRegistryOK = FALSE;
  486. }
  487. dwIndex++;
  488. }
  489. RegCloseKey(hkey);
  490. }
  491. if (!bTCPIPFound)
  492. {
  493. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  494. return hr;
  495. lstrcpy(pNetSPNew->m_szName, TEXT("DirectPlay8 TCP/IP Service Provider"));
  496. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("DirectPlay8 TCP/IP Service Provider"));
  497. pNetSPNew->m_bRegistryOK = FALSE;
  498. }
  499. if (!bIPXFound)
  500. {
  501. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  502. return hr;
  503. lstrcpy(pNetSPNew->m_szName, TEXT("DirectPlay8 IPX Service Provider"));
  504. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("DirectPlay8 IPX Service Provider"));
  505. pNetSPNew->m_bRegistryOK = FALSE;
  506. }
  507. if (!bModemFound)
  508. {
  509. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  510. return hr;
  511. lstrcpy(pNetSPNew->m_szName, TEXT("DirectPlay8 Modem Service Provider"));
  512. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("DirectPlay8 Modem Service Provider"));
  513. pNetSPNew->m_bRegistryOK = FALSE;
  514. }
  515. if (!bSerialFound)
  516. {
  517. if (FAILED(hr = NewNetSP(pNetInfo, &pNetSPNew)))
  518. return hr;
  519. lstrcpy(pNetSPNew->m_szName, TEXT("DirectPlay8 Serial Service Provider"));
  520. lstrcpy(pNetSPNew->m_szNameEnglish, TEXT("DirectPlay8 Serial Service Provider"));
  521. pNetSPNew->m_bRegistryOK = FALSE;
  522. }
  523. return S_OK;
  524. }
  525. /****************************************************************************
  526. *
  527. * GetDX7LobbyableApps
  528. *
  529. ****************************************************************************/
  530. HRESULT GetDX7LobbyableApps(NetInfo* pNetInfo)
  531. {
  532. HRESULT hr;
  533. HKEY hkey = NULL;
  534. HKEY hkey2 = NULL;
  535. DWORD dwIndex;
  536. DWORD dwBufferLen;
  537. TCHAR szName[MAX_PATH+1];
  538. NetApp* pNetAppNew;
  539. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectPlay\\Applications"), 0, KEY_READ, &hkey))
  540. {
  541. dwIndex = 0;
  542. while (ERROR_SUCCESS == RegEnumKey(hkey, dwIndex, szName, MAX_PATH+1))
  543. {
  544. BOOL bSkip = FALSE;
  545. // Bug 37989: skip any dplay app that has the DPLAPP_NOENUM flag set.
  546. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, szName, 0, KEY_READ, &hkey2))
  547. {
  548. dwBufferLen = MAX_PATH;
  549. DWORD dwFlags = 0;
  550. dwBufferLen = sizeof(DWORD);
  551. DWORD dwType = 0;
  552. RegQueryValueEx(hkey2, TEXT("dwFlags"), 0, &dwType, (LPBYTE)&dwFlags, &dwBufferLen);
  553. if( (dwFlags & DPLAPP_NOENUM) != 0 )
  554. bSkip = TRUE;
  555. RegCloseKey(hkey2);
  556. }
  557. if( bSkip )
  558. {
  559. dwIndex++;
  560. continue;
  561. }
  562. if (FAILED(hr = NewNetApp(pNetInfo, &pNetAppNew)))
  563. {
  564. RegCloseKey(hkey);
  565. return hr;
  566. }
  567. lstrcpy(pNetAppNew->m_szName, szName);
  568. pNetAppNew->m_dwDXVer = 7;
  569. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, szName, 0, KEY_READ, &hkey2))
  570. {
  571. dwBufferLen = MAX_PATH;
  572. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("Path"), 0, NULL, (LPBYTE)pNetAppNew->m_szExePath, &dwBufferLen))
  573. {
  574. }
  575. else
  576. {
  577. pNetAppNew->m_bRegistryOK = FALSE;
  578. }
  579. dwBufferLen = 100;
  580. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("File"), 0, NULL, (LPBYTE)pNetAppNew->m_szExeFile, &dwBufferLen))
  581. {
  582. lstrcat(pNetAppNew->m_szExePath, TEXT("\\"));
  583. lstrcat(pNetAppNew->m_szExePath, pNetAppNew->m_szExeFile);
  584. WIN32_FIND_DATA findFileData;
  585. HANDLE hFind = FindFirstFile(pNetAppNew->m_szExePath, &findFileData);
  586. if (hFind == INVALID_HANDLE_VALUE)
  587. {
  588. pNetAppNew->m_bFileMissing = TRUE;
  589. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szExeVersion, 50);
  590. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szExeVersionEnglish, 50);
  591. }
  592. else
  593. {
  594. FindClose(hFind);
  595. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szExeVersion,
  596. NULL, NULL, NULL);
  597. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szExeVersionEnglish,
  598. NULL, NULL, NULL);
  599. }
  600. }
  601. else
  602. {
  603. pNetAppNew->m_bRegistryOK = FALSE;
  604. }
  605. dwBufferLen = 100;
  606. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("Guid"), 0, NULL, (LPBYTE)pNetAppNew->m_szGuid, &dwBufferLen))
  607. {
  608. }
  609. else
  610. {
  611. pNetAppNew->m_bRegistryOK = FALSE;
  612. }
  613. RegCloseKey(hkey2);
  614. }
  615. else
  616. {
  617. pNetAppNew->m_bRegistryOK = FALSE;
  618. }
  619. dwIndex++;
  620. }
  621. RegCloseKey(hkey);
  622. }
  623. return S_OK;
  624. }
  625. /****************************************************************************
  626. *
  627. * GetDX8LobbyableApps
  628. *
  629. ****************************************************************************/
  630. HRESULT GetDX8LobbyableApps(NetInfo* pNetInfo)
  631. {
  632. HRESULT hr;
  633. HKEY hkey = NULL;
  634. HKEY hkey2 = NULL;
  635. DWORD dwIndex;
  636. DWORD dwBufferLen;
  637. TCHAR szGuid[MAX_PATH+1];
  638. NetApp* pNetAppNew;
  639. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectPlay8\\Applications"), 0, KEY_READ, &hkey))
  640. {
  641. dwIndex = 0;
  642. while (ERROR_SUCCESS == RegEnumKey(hkey, dwIndex, szGuid, MAX_PATH+1))
  643. {
  644. if (FAILED(hr = NewNetApp(pNetInfo, &pNetAppNew)))
  645. {
  646. RegCloseKey(hkey);
  647. return hr;
  648. }
  649. lstrcpy(pNetAppNew->m_szGuid, szGuid);
  650. pNetAppNew->m_dwDXVer = 8;
  651. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, szGuid, 0, KEY_READ, &hkey2))
  652. {
  653. dwBufferLen = MAX_PATH;
  654. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("ExecutablePath"), 0, NULL, (LPBYTE)pNetAppNew->m_szExePath, &dwBufferLen))
  655. {
  656. }
  657. else
  658. {
  659. pNetAppNew->m_bRegistryOK = FALSE;
  660. }
  661. dwBufferLen = 100;
  662. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("ExecutableFilename"), 0, NULL, (LPBYTE)pNetAppNew->m_szExeFile, &dwBufferLen))
  663. {
  664. lstrcat(pNetAppNew->m_szExePath, TEXT("\\"));
  665. lstrcat(pNetAppNew->m_szExePath, pNetAppNew->m_szExeFile);
  666. WIN32_FIND_DATA findFileData;
  667. HANDLE hFind = FindFirstFile(pNetAppNew->m_szExePath, &findFileData);
  668. if (hFind == INVALID_HANDLE_VALUE)
  669. {
  670. pNetAppNew->m_bFileMissing = TRUE;
  671. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szExeVersion, 50);
  672. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szExeVersionEnglish, 50);
  673. }
  674. else
  675. {
  676. FindClose(hFind);
  677. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szExeVersion,
  678. NULL, NULL, NULL);
  679. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szExeVersionEnglish,
  680. NULL, NULL, NULL);
  681. }
  682. }
  683. else
  684. {
  685. pNetAppNew->m_bRegistryOK = FALSE;
  686. }
  687. dwBufferLen = MAX_PATH;
  688. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("LauncherPath"), 0, NULL, (LPBYTE)pNetAppNew->m_szLauncherPath, &dwBufferLen))
  689. {
  690. }
  691. else
  692. {
  693. pNetAppNew->m_bRegistryOK = FALSE;
  694. }
  695. dwBufferLen = 100;
  696. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("LauncherFilename"), 0, NULL, (LPBYTE)pNetAppNew->m_szLauncherFile, &dwBufferLen))
  697. {
  698. lstrcat(pNetAppNew->m_szLauncherPath, TEXT("\\"));
  699. lstrcat(pNetAppNew->m_szLauncherPath, pNetAppNew->m_szLauncherFile);
  700. WIN32_FIND_DATA findFileData;
  701. HANDLE hFind = FindFirstFile(pNetAppNew->m_szLauncherPath, &findFileData);
  702. if (hFind == INVALID_HANDLE_VALUE)
  703. {
  704. pNetAppNew->m_bFileMissing = TRUE;
  705. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szLauncherVersion, 50);
  706. LoadString(NULL, IDS_FILEMISSING, pNetAppNew->m_szLauncherVersionEnglish, 50);
  707. }
  708. else
  709. {
  710. FindClose(hFind);
  711. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szLauncherVersion,
  712. NULL, NULL, NULL);
  713. GetFileVersion(pNetAppNew->m_szExePath, pNetAppNew->m_szLauncherVersionEnglish,
  714. NULL, NULL, NULL);
  715. }
  716. }
  717. else
  718. {
  719. pNetAppNew->m_bRegistryOK = FALSE;
  720. }
  721. dwBufferLen = 100;
  722. if (ERROR_SUCCESS == RegQueryValueEx(hkey2, TEXT("ApplicationName"), 0, NULL, (LPBYTE)pNetAppNew->m_szName, &dwBufferLen))
  723. {
  724. }
  725. else
  726. {
  727. pNetAppNew->m_bRegistryOK = FALSE;
  728. }
  729. RegCloseKey(hkey2);
  730. }
  731. else
  732. {
  733. pNetAppNew->m_bRegistryOK = FALSE;
  734. }
  735. dwIndex++;
  736. }
  737. RegCloseKey(hkey);
  738. }
  739. return S_OK;
  740. }
  741. /****************************************************************************
  742. *
  743. * DestroyNetInfo
  744. *
  745. ****************************************************************************/
  746. VOID DestroyNetInfo(NetInfo* pNetInfo)
  747. {
  748. if( pNetInfo )
  749. {
  750. NetSP* pNetSP;
  751. NetSP* pNetSPNext;
  752. for (pNetSP = pNetInfo->m_pNetSPFirst; pNetSP != NULL;
  753. pNetSP = pNetSPNext)
  754. {
  755. pNetSPNext = pNetSP->m_pNetSPNext;
  756. delete pNetSP;
  757. }
  758. NetApp* pNetApp;
  759. NetApp* pNetAppNext;
  760. for (pNetApp = pNetInfo->m_pNetAppFirst; pNetApp != NULL;
  761. pNetApp = pNetAppNext)
  762. {
  763. pNetAppNext = pNetApp->m_pNetAppNext;
  764. delete pNetApp;
  765. }
  766. delete pNetInfo;
  767. }
  768. }
  769. /****************************************************************************
  770. *
  771. * DiagnoseNetInfo
  772. *
  773. ****************************************************************************/
  774. VOID DiagnoseNetInfo(SysInfo* pSysInfo, NetInfo* pNetInfo)
  775. {
  776. NetSP* pNetSP;
  777. NetApp* pNetApp;
  778. TCHAR szMessage[500];
  779. TCHAR szFmt[500];
  780. BOOL bProblem = FALSE;
  781. BOOL bShouldReinstall = FALSE;
  782. _tcscpy( pSysInfo->m_szNetworkNotes, TEXT("") );
  783. _tcscpy( pSysInfo->m_szNetworkNotesEnglish, TEXT("") );
  784. // Report any problems
  785. if( pNetInfo != NULL )
  786. {
  787. for (pNetSP = pNetInfo->m_pNetSPFirst; pNetSP != NULL; pNetSP = pNetSP->m_pNetSPNext)
  788. {
  789. if (!pNetSP->m_bRegistryOK)
  790. {
  791. LoadString(NULL, IDS_SPREGISTRYERRORFMT, szFmt, 500);
  792. wsprintf(szMessage, szFmt, pNetSP->m_szName);
  793. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  794. LoadString(NULL, IDS_SPREGISTRYERRORFMT_ENGLISH, szFmt, 500);
  795. wsprintf(szMessage, szFmt, pNetSP->m_szName);
  796. _tcscat(pSysInfo->m_szNetworkNotesEnglish, szMessage);
  797. pNetSP->m_bProblem = TRUE;
  798. bProblem = TRUE;
  799. bShouldReinstall = TRUE;
  800. }
  801. else if (pNetSP->m_bFileMissing)
  802. {
  803. LoadString(NULL, IDS_FILEMISSING, pNetSP->m_szVersion, 50);
  804. LoadString(NULL, IDS_SPFILEMISSINGFMT, szFmt, 500);
  805. wsprintf(szMessage, szFmt, pNetSP->m_szFile, pNetSP->m_szName);
  806. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  807. LoadString(NULL, IDS_FILEMISSING_ENGLISH, pNetSP->m_szVersion, 50);
  808. LoadString(NULL, IDS_SPFILEMISSINGFMT_ENGLISH, szFmt, 500);
  809. wsprintf(szMessage, szFmt, pNetSP->m_szFile, pNetSP->m_szName);
  810. _tcscat(pSysInfo->m_szNetworkNotesEnglish, szMessage);
  811. pNetSP->m_bProblem = TRUE;
  812. bShouldReinstall = TRUE;
  813. bProblem = TRUE;
  814. }
  815. }
  816. for (pNetApp = pNetInfo->m_pNetAppFirst; pNetApp != NULL; pNetApp = pNetApp->m_pNetAppNext)
  817. {
  818. if (!pNetApp->m_bRegistryOK)
  819. {
  820. LoadString(NULL, IDS_APPREGISTRYERRORFMT, szFmt, 500);
  821. wsprintf(szMessage, szFmt, pNetApp->m_szName);
  822. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  823. LoadString(NULL, IDS_APPREGISTRYERRORFMT_ENGLISH, szFmt, 500);
  824. wsprintf(szMessage, szFmt, pNetApp->m_szName);
  825. _tcscat(pSysInfo->m_szNetworkNotesEnglish, szMessage);
  826. pNetApp->m_bProblem = TRUE;
  827. bProblem = TRUE;
  828. }
  829. /* 26298: Don't scare users with this warning...it's usually harmless:
  830. else if (pNetApp->m_bFileMissing)
  831. {
  832. LoadString(NULL, IDS_FILEMISSING, pNetApp->m_szVersion, 50);
  833. LoadString(NULL, IDS_APPFILEMISSINGFMT, szFmt, 500);
  834. wsprintf(szMessage, szFmt, pNetApp->m_szFile, pNetApp->m_szName);
  835. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  836. pNetApp->m_bProblem = TRUE;
  837. bProblem = TRUE;
  838. }
  839. */
  840. }
  841. }
  842. else
  843. {
  844. bProblem = TRUE;
  845. bShouldReinstall = TRUE;
  846. }
  847. if( bShouldReinstall )
  848. {
  849. BOOL bTellUser = FALSE;
  850. // Figure out if the user can install DirectX
  851. if( BIsPlatform9x() )
  852. bTellUser = TRUE;
  853. else if( BIsWin2k() && pSysInfo->m_dwDirectXVersionMajor >= 8 )
  854. bTellUser = TRUE;
  855. if( bTellUser )
  856. {
  857. LoadString(NULL, IDS_REINSTALL_DX, szMessage, 500);
  858. _tcscat( pSysInfo->m_szNetworkNotes, szMessage);
  859. LoadString(NULL, IDS_REINSTALL_DX_ENGLISH, szMessage, 500);
  860. _tcscat( pSysInfo->m_szNetworkNotesEnglish, szMessage);
  861. }
  862. }
  863. if (!bProblem)
  864. {
  865. LoadString(NULL, IDS_NOPROBLEM, szMessage, 500);
  866. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  867. LoadString(NULL, IDS_NOPROBLEM_ENGLISH, szMessage, 500);
  868. _tcscat(pSysInfo->m_szNetworkNotesEnglish, szMessage);
  869. }
  870. // Show test results or instructions to run test:
  871. if (pNetInfo && pNetInfo->m_testResult.m_bStarted)
  872. {
  873. LoadString(NULL, IDS_DPLAYRESULTS, szMessage, 500);
  874. _tcscat( pSysInfo->m_szNetworkNotes, szMessage );
  875. _tcscat( pSysInfo->m_szNetworkNotes, pNetInfo->m_testResult.m_szDescription );
  876. _tcscat( pSysInfo->m_szNetworkNotes, TEXT("\r\n") );
  877. LoadString(NULL, IDS_DPLAYRESULTS_ENGLISH, szMessage, 500);
  878. _tcscat( pSysInfo->m_szNetworkNotesEnglish, szMessage );
  879. _tcscat( pSysInfo->m_szNetworkNotesEnglish, pNetInfo->m_testResult.m_szDescriptionEnglish );
  880. _tcscat( pSysInfo->m_szNetworkNotesEnglish, TEXT("\r\n") );
  881. }
  882. else
  883. {
  884. LoadString(NULL, IDS_DPLAYINSTRUCTIONS, szMessage, 500);
  885. _tcscat(pSysInfo->m_szNetworkNotes, szMessage);
  886. LoadString(NULL, IDS_DPLAYINSTRUCTIONS_ENGLISH, szMessage, 500);
  887. _tcscat(pSysInfo->m_szNetworkNotesEnglish, szMessage);
  888. }
  889. }
  890. /****************************************************************************
  891. *
  892. * ConvertStringToGUID
  893. *
  894. ****************************************************************************/
  895. BOOL ConvertStringToGUID(const WCHAR* strBuffer, GUID* lpguid)
  896. {
  897. UINT aiTmp[10];
  898. if( swscanf( strBuffer, L"{%8X-%4X-%4X-%2X%2X-%2X%2X%2X%2X%2X%2X}",
  899. &lpguid->Data1,
  900. &aiTmp[0], &aiTmp[1],
  901. &aiTmp[2], &aiTmp[3],
  902. &aiTmp[4], &aiTmp[5],
  903. &aiTmp[6], &aiTmp[7],
  904. &aiTmp[8], &aiTmp[9] ) != 11 )
  905. {
  906. ZeroMemory(lpguid, sizeof(GUID));
  907. return FALSE;
  908. }
  909. else
  910. {
  911. lpguid->Data2 = (USHORT) aiTmp[0];
  912. lpguid->Data3 = (USHORT) aiTmp[1];
  913. lpguid->Data4[0] = (BYTE) aiTmp[2];
  914. lpguid->Data4[1] = (BYTE) aiTmp[3];
  915. lpguid->Data4[2] = (BYTE) aiTmp[4];
  916. lpguid->Data4[3] = (BYTE) aiTmp[5];
  917. lpguid->Data4[4] = (BYTE) aiTmp[6];
  918. lpguid->Data4[5] = (BYTE) aiTmp[7];
  919. lpguid->Data4[6] = (BYTE) aiTmp[8];
  920. lpguid->Data4[7] = (BYTE) aiTmp[9];
  921. return TRUE;
  922. }
  923. }