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.

517 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N M D I A G P . C P P
  7. //
  8. // Contents: Diagnostics for the netman process
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 23 Mar 1999
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "enuml.h"
  18. #include "diag.h"
  19. #include "kkenet.h"
  20. #include "ncnetcon.h"
  21. #include "ncreg.h"
  22. #include "ncsetup.h"
  23. #include "ncstring.h"
  24. #include "netcon.h"
  25. #include "ntddndis.h"
  26. struct LAN_CONNECTION
  27. {
  28. GUID guidId;
  29. tstring strName;
  30. NETCON_STATUS Status;
  31. tstring strDeviceName;
  32. DWORD dwMediaState;
  33. ULONG ulDevNodeStatus;
  34. ULONG ulDevNodeProblem;
  35. tstring strPnpName;
  36. };
  37. typedef list<LAN_CONNECTION *> LAN_CONNECTION_LIST;
  38. typedef list<LAN_CONNECTION *>::iterator LAN_CONNECTION_LIST_ITERATOR;
  39. HRESULT HrInitializeConMan(INetConnectionManager **ppConMan)
  40. {
  41. HRESULT hr;
  42. hr = CoCreateInstance(CLSID_LanConnectionManager, NULL,
  43. CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  44. IID_INetConnectionManager,
  45. reinterpret_cast<LPVOID *>(ppConMan));
  46. return hr;
  47. }
  48. HRESULT HrUninitializeConMan(INetConnectionManager *pConMan)
  49. {
  50. ReleaseObj(pConMan);
  51. return S_OK;
  52. }
  53. HRESULT HrEnumerateLanConnections(INetConnectionManager *pConMan,
  54. LAN_CONNECTION_LIST &listCon)
  55. {
  56. HRESULT hr = S_OK;
  57. CIterNetCon ncIter(pConMan, NCME_DEFAULT);
  58. INetConnection * pconn;
  59. while (SUCCEEDED(hr) &&
  60. (S_OK == (ncIter.HrNext(&pconn))))
  61. {
  62. NETCON_PROPERTIES * pProps;
  63. hr = pconn->GetProperties(&pProps);
  64. if (SUCCEEDED(hr))
  65. {
  66. LAN_CONNECTION * pLanCon;
  67. BOOL fMediaConnected;
  68. WCHAR szwInstance[_MAX_PATH];
  69. pLanCon = new LAN_CONNECTION;
  70. if (pLanCon)
  71. {
  72. pLanCon->guidId = pProps->guidId;
  73. pLanCon->strName = pProps->pszwName;
  74. pLanCon->Status = pProps->Status;
  75. pLanCon->strDeviceName = pProps->pszwDeviceName;
  76. if (SUCCEEDED(hr = HrQueryLanMediaState(&pProps->guidId,
  77. &fMediaConnected)))
  78. {
  79. pLanCon->dwMediaState = fMediaConnected ?
  80. NdisMediaStateConnected : NdisMediaStateDisconnected;
  81. }
  82. else
  83. {
  84. pLanCon->dwMediaState = hr;
  85. }
  86. hr = HrPnpInstanceIdFromGuid(&pProps->guidId, szwInstance,
  87. celems(szwInstance));
  88. if (SUCCEEDED(hr))
  89. {
  90. DEVINST devinst;
  91. pLanCon->strPnpName = szwInstance;
  92. if (CR_SUCCESS == CM_Locate_DevNode(&devinst,
  93. szwInstance,
  94. CM_LOCATE_DEVNODE_NORMAL))
  95. {
  96. ULONG ulStatus;
  97. ULONG ulProblem;
  98. CONFIGRET cfgRet;
  99. cfgRet = CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblem,
  100. devinst, 0, NULL);
  101. if (CR_SUCCESS == cfgRet)
  102. {
  103. pLanCon->ulDevNodeProblem = ulProblem;
  104. pLanCon->ulDevNodeStatus = ulStatus;
  105. }
  106. }
  107. }
  108. listCon.push_back(pLanCon);
  109. }
  110. FreeNetconProperties(pProps);
  111. }
  112. ReleaseObj(pconn);
  113. }
  114. return hr;
  115. }
  116. HRESULT HrFindLanConnection(INetConnectionManager *pConMan,
  117. PCWSTR szLanConnection,
  118. INetConnection **ppcon)
  119. {
  120. HRESULT hr = S_OK;
  121. CIterNetCon ncIter(pConMan, NCME_DEFAULT);
  122. INetConnection * pconn;
  123. *ppcon = NULL;
  124. while (SUCCEEDED(hr) &&
  125. (S_OK == (ncIter.HrNext(&pconn))))
  126. {
  127. NETCON_PROPERTIES * pProps;
  128. hr = pconn->GetProperties(&pProps);
  129. if (SUCCEEDED(hr))
  130. {
  131. if (!lstrcmpiW(pProps->pszwName, szLanConnection))
  132. {
  133. *ppcon = pconn;
  134. break;
  135. }
  136. else
  137. {
  138. ReleaseObj(pconn);
  139. }
  140. }
  141. }
  142. if (SUCCEEDED(hr))
  143. {
  144. if (*ppcon == NULL)
  145. {
  146. hr = S_FALSE;
  147. }
  148. }
  149. return hr;
  150. }
  151. extern const WCHAR c_szRegValueNetCfgInstanceId[];
  152. VOID CmdShowAllDevices(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan)
  153. {
  154. HRESULT hr;
  155. DWORD dwIndex = 0;
  156. SP_DEVINFO_DATA deid = {0};
  157. HDEVINFO hdi = NULL;
  158. WCHAR szBuffer [MAX_PATH];
  159. hr = HrSetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL,
  160. DIGCF_PRESENT, &hdi);
  161. while (SUCCEEDED(hr = HrSetupDiEnumDeviceInfo(hdi,
  162. dwIndex,
  163. &deid)))
  164. {
  165. HKEY hkey;
  166. dwIndex++;
  167. hr = HrSetupDiOpenDevRegKey(hdi, &deid, DICS_FLAG_GLOBAL, 0,
  168. DIREG_DRV, KEY_READ, &hkey);
  169. if (SUCCEEDED(hr))
  170. {
  171. ULONG ulProblem;
  172. ULONG ulStatus;
  173. PWSTR pszName;
  174. hr = HrSetupDiGetDeviceName(hdi, &deid, &pszName);
  175. if (SUCCEEDED(hr))
  176. {
  177. g_pDiagCtx->Printf(ttidNcDiag, "Device name: %S\n", pszName);
  178. delete [] reinterpret_cast<BYTE*>(pszName);
  179. }
  180. (VOID) CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblem,
  181. deid.DevInst, 0, NULL);
  182. tstring strStatus;
  183. SzFromCmStatus(ulStatus, &strStatus);
  184. g_pDiagCtx->Printf(ttidNcDiag, "Device CM Status: (0x%08X) %S\n", ulStatus,
  185. strStatus.c_str());
  186. g_pDiagCtx->Printf(ttidNcDiag, "Device CM Problem: (0x%08X) %S\n", ulProblem,
  187. SzFromCmProb(ulProblem));
  188. g_pDiagCtx->Printf(ttidNcDiag, "Lan capable: ");
  189. if (S_OK == HrIsLanCapableAdapterFromHkey(hkey))
  190. {
  191. g_pDiagCtx->Printf(ttidNcDiag, "Yes\n");
  192. }
  193. else
  194. {
  195. g_pDiagCtx->Printf(ttidNcDiag, "No\n");
  196. }
  197. HRESULT hr = S_OK;
  198. WCHAR szGuid[c_cchGuidWithTerm] = {0};
  199. DWORD cbBuf = sizeof(szGuid);
  200. hr = HrRegQuerySzBuffer(hkey, c_szRegValueNetCfgInstanceId,
  201. szGuid, &cbBuf);
  202. g_pDiagCtx->Printf(ttidNcDiag, "Valid NetCfg device: ");
  203. if (S_OK == hr)
  204. {
  205. g_pDiagCtx->Printf(ttidNcDiag, "Yes\n");
  206. }
  207. else
  208. {
  209. g_pDiagCtx->Printf(ttidNcDiag, "No\n");
  210. }
  211. g_pDiagCtx->Printf(ttidNcDiag, "NetCfg instance ID: %S\n", szGuid);
  212. hr = HrSetupDiGetDeviceInstanceId(hdi, &deid, szBuffer,
  213. sizeof(szBuffer), NULL);
  214. if (SUCCEEDED(hr))
  215. {
  216. g_pDiagCtx->Printf(ttidNcDiag, "PnP instance ID: %S\n", szBuffer);
  217. }
  218. DWORD dwChars;
  219. tstring strChars;
  220. if (SUCCEEDED(HrRegQueryDword(hkey, L"Characteristics", &dwChars)))
  221. {
  222. SzFromCharacteristics(dwChars, &strChars);
  223. g_pDiagCtx->Printf(ttidNcDiag, "Characteristics: (0x%08X) %S\n", dwChars,
  224. strChars.c_str());
  225. }
  226. hr = HrSetupDiGetDeviceRegistryProperty (hdi, &deid,
  227. SPDRP_LOCATION_INFORMATION, NULL, (BYTE*)szBuffer,
  228. sizeof (szBuffer), NULL);
  229. if (S_OK == hr)
  230. {
  231. g_pDiagCtx->Printf(ttidNcDiag, "Location: %S\n", szBuffer);
  232. }
  233. if ((NCF_PHYSICAL & dwChars) && *szGuid)
  234. {
  235. ULONGLONG MacAddr;
  236. hr = HrGetNetCardAddr (szGuid, &MacAddr);
  237. if (S_OK == hr)
  238. {
  239. g_pDiagCtx->Printf(ttidNcDiag, "Mac Address: 0x%012.12I64X\n", MacAddr);
  240. }
  241. }
  242. GUID guid;
  243. BOOL fMediaConnected;
  244. DWORD dwMediaState;
  245. IIDFromString(szGuid, &guid);
  246. if (SUCCEEDED(hr = HrQueryLanMediaState(&guid,
  247. &fMediaConnected)))
  248. {
  249. dwMediaState = fMediaConnected ?
  250. NdisMediaStateConnected : NdisMediaStateDisconnected;
  251. }
  252. else
  253. {
  254. dwMediaState = hr;
  255. }
  256. g_pDiagCtx->Printf(ttidNcDiag, "NDIS media status: ");
  257. switch (dwMediaState)
  258. {
  259. case NdisMediaStateConnected:
  260. g_pDiagCtx->Printf(ttidNcDiag, "Connected\n");
  261. break;
  262. case NdisMediaStateDisconnected:
  263. g_pDiagCtx->Printf(ttidNcDiag, "Disconnected\n");
  264. break;
  265. default:
  266. g_pDiagCtx->Printf(ttidNcDiag, "Error 0x%08X\n", dwMediaState);
  267. break;
  268. }
  269. RegCloseKey(hkey);
  270. }
  271. g_pDiagCtx->Printf(ttidNcDiag, "------------------------------------------------------------------------------------\n");
  272. }
  273. SetupDiDestroyDeviceInfoListSafe(hdi);
  274. }
  275. VOID CmdShowLanConnections(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan)
  276. {
  277. HRESULT hr = S_OK;
  278. LAN_CONNECTION_LIST listCon;
  279. LAN_CONNECTION_LIST_ITERATOR iterListCon;
  280. hr = HrEnumerateLanConnections(pConMan, listCon);
  281. if (SUCCEEDED(hr))
  282. {
  283. g_pDiagCtx->Printf(ttidNcDiag, "Current LAN connections\n\n");
  284. g_pDiagCtx->Printf(ttidNcDiag, "%-20S%-50S%-20S%\n", L"Connection Name", L"Device Name", L"Status");
  285. g_pDiagCtx->Printf(ttidNcDiag, "----------------------------------------------------------------------------------------\n");
  286. for (iterListCon = listCon.begin(); iterListCon != listCon.end(); iterListCon++)
  287. {
  288. LAN_CONNECTION * pLanCon;
  289. pLanCon = *iterListCon;
  290. g_pDiagCtx->Printf(ttidNcDiag, "%-20S%-50S%-20S%\n",
  291. pLanCon->strName.c_str(),
  292. pLanCon->strDeviceName.c_str(),
  293. SzFromNetconStatus(pLanCon->Status));
  294. }
  295. }
  296. }
  297. VOID CmdShowLanDetails(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan)
  298. {
  299. HRESULT hr = S_OK;
  300. LAN_CONNECTION_LIST listCon;
  301. LAN_CONNECTION_LIST_ITERATOR iterListCon;
  302. BOOL fFound = FALSE;
  303. hr = HrEnumerateLanConnections(pConMan, listCon);
  304. if (SUCCEEDED(hr))
  305. {
  306. for (iterListCon = listCon.begin(); iterListCon != listCon.end(); iterListCon++)
  307. {
  308. LAN_CONNECTION * pLanCon;
  309. pLanCon = *iterListCon;
  310. if (!lstrcmpiW(pLanCon->strName.c_str(), pOptions->szLanConnection))
  311. {
  312. WCHAR szwGuid[c_cchGuidWithTerm];
  313. StringFromGUID2(pLanCon->guidId, szwGuid, c_cchGuidWithTerm);
  314. g_pDiagCtx->Printf(ttidNcDiag, "Details for %S:\n", pOptions->szLanConnection);
  315. g_pDiagCtx->Printf(ttidNcDiag, "------------------------------------------\n\n");
  316. g_pDiagCtx->Printf(ttidNcDiag, "Device name: %S\n", pLanCon->strDeviceName.c_str());
  317. g_pDiagCtx->Printf(ttidNcDiag, "Device GUID: %S\n", szwGuid);
  318. g_pDiagCtx->Printf(ttidNcDiag, "PnP Instance ID: %S\n", pLanCon->strPnpName.c_str());
  319. g_pDiagCtx->Printf(ttidNcDiag, "Netman Status: %S\n", SzFromNetconStatus(pLanCon->Status));
  320. g_pDiagCtx->Printf(ttidNcDiag, "NDIS media status: ");
  321. switch (pLanCon->dwMediaState)
  322. {
  323. case NdisMediaStateConnected:
  324. g_pDiagCtx->Printf(ttidNcDiag, "Connected\n");
  325. break;
  326. case NdisMediaStateDisconnected:
  327. g_pDiagCtx->Printf(ttidNcDiag, "Disconnected\n");
  328. break;
  329. default:
  330. g_pDiagCtx->Printf(ttidNcDiag, "Error 0x%08X\n", pLanCon->dwMediaState);
  331. break;
  332. }
  333. tstring strStatus;
  334. SzFromCmStatus(pLanCon->ulDevNodeStatus, &strStatus);
  335. g_pDiagCtx->Printf(ttidNcDiag, "CM DevNode Status: (0x%08X) %S\n",
  336. pLanCon->ulDevNodeStatus, strStatus.c_str());
  337. g_pDiagCtx->Printf(ttidNcDiag, "CM DevNode Problem: (0x%08X) %S\n",
  338. pLanCon->ulDevNodeProblem,
  339. SzFromCmProb(pLanCon->ulDevNodeProblem));
  340. fFound = TRUE;
  341. // No need to keep looping
  342. break;
  343. }
  344. }
  345. }
  346. if (!fFound)
  347. {
  348. g_pDiagCtx->Printf(ttidNcDiag, "Could not find match for connection name: %S\n",
  349. pOptions->szLanConnection);
  350. }
  351. }
  352. VOID CmdLanChangeState(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan)
  353. {
  354. HRESULT hr = S_OK;
  355. INetConnection * pcon = NULL;
  356. hr = HrFindLanConnection(pConMan, pOptions->szLanConnection, &pcon);
  357. if (S_OK == hr)
  358. {
  359. NETCON_PROPERTIES * pProps;
  360. hr = pcon->GetProperties(&pProps);
  361. if (SUCCEEDED(hr))
  362. {
  363. if (pOptions->fConnect)
  364. {
  365. if (pProps->Status != NCS_CONNECTED)
  366. {
  367. pcon->Connect();
  368. }
  369. else
  370. {
  371. g_pDiagCtx->Printf(ttidNcDiag, "%S is already connected.\n",
  372. pOptions->szLanConnection);
  373. }
  374. }
  375. else
  376. {
  377. if (pProps->Status != NCS_DISCONNECTED)
  378. {
  379. pcon->Disconnect();
  380. }
  381. else
  382. {
  383. g_pDiagCtx->Printf(ttidNcDiag, "%S is already disconnected.\n",
  384. pOptions->szLanConnection);
  385. }
  386. }
  387. FreeNetconProperties(pProps);
  388. }
  389. }
  390. else if (S_FALSE == hr)
  391. {
  392. g_pDiagCtx->Printf(ttidNcDiag, "Could not find match for connection name: %S\n",
  393. pOptions->szLanConnection);
  394. }
  395. }
  396. EXTERN_C
  397. VOID
  398. WINAPI
  399. NetManDiagFromCommandArgs (DIAG_OPTIONS *pOptions)
  400. {
  401. Assert (pOptions);
  402. Assert (pOptions->pDiagCtx);
  403. g_pDiagCtx = pOptions->pDiagCtx;
  404. INetConnectionManager * pConMan;
  405. HrInitializeConMan(&pConMan);
  406. switch (pOptions->Command)
  407. {
  408. case CMD_SHOW_LAN_CONNECTIONS:
  409. CmdShowLanConnections(pOptions, pConMan);
  410. break;
  411. case CMD_SHOW_ALL_DEVICES:
  412. CmdShowAllDevices(pOptions, pConMan);
  413. break;
  414. case CMD_SHOW_LAN_DETAILS:
  415. CmdShowLanDetails(pOptions, pConMan);
  416. break;
  417. case CMD_LAN_CHANGE_STATE:
  418. CmdLanChangeState(pOptions, pConMan);
  419. break;
  420. default:
  421. break;
  422. }
  423. HrUninitializeConMan(pConMan);
  424. g_pDiagCtx = NULL;
  425. }