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.

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