Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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