//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: N M D I A G P . C P P // // Contents: Diagnostics for the netman process // // Notes: // // Author: danielwe 23 Mar 1999 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "enuml.h" #include "diag.h" #include "kkenet.h" #include "ncnetcon.h" #include "ncreg.h" #include "ncsetup.h" #include "ncstring.h" #include "netcon.h" #include "ntddndis.h" struct LAN_CONNECTION { GUID guidId; tstring strName; NETCON_STATUS Status; tstring strDeviceName; DWORD dwMediaState; ULONG ulDevNodeStatus; ULONG ulDevNodeProblem; tstring strPnpName; }; typedef list LAN_CONNECTION_LIST; typedef list::iterator LAN_CONNECTION_LIST_ITERATOR; HRESULT HrInitializeConMan(INetConnectionManager **ppConMan) { HRESULT hr; hr = CoCreateInstance(CLSID_LanConnectionManager, NULL, CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD, IID_INetConnectionManager, reinterpret_cast(ppConMan)); return hr; } HRESULT HrUninitializeConMan(INetConnectionManager *pConMan) { ReleaseObj(pConMan); return S_OK; } HRESULT HrEnumerateLanConnections(INetConnectionManager *pConMan, LAN_CONNECTION_LIST &listCon) { HRESULT hr = S_OK; CIterNetCon ncIter(pConMan, NCME_DEFAULT); INetConnection * pconn; while (SUCCEEDED(hr) && (S_OK == (ncIter.HrNext(&pconn)))) { NETCON_PROPERTIES * pProps; hr = pconn->GetProperties(&pProps); if (SUCCEEDED(hr)) { LAN_CONNECTION * pLanCon; BOOL fMediaConnected; WCHAR szwInstance[_MAX_PATH]; pLanCon = new LAN_CONNECTION; if (pLanCon) { pLanCon->guidId = pProps->guidId; pLanCon->strName = pProps->pszwName; pLanCon->Status = pProps->Status; pLanCon->strDeviceName = pProps->pszwDeviceName; if (SUCCEEDED(hr = HrQueryLanMediaState(&pProps->guidId, &fMediaConnected))) { pLanCon->dwMediaState = fMediaConnected ? NdisMediaStateConnected : NdisMediaStateDisconnected; } else { pLanCon->dwMediaState = hr; } hr = HrPnpInstanceIdFromGuid(&pProps->guidId, szwInstance, celems(szwInstance)); if (SUCCEEDED(hr)) { DEVINST devinst; pLanCon->strPnpName = szwInstance; if (CR_SUCCESS == CM_Locate_DevNode(&devinst, szwInstance, CM_LOCATE_DEVNODE_NORMAL)) { ULONG ulStatus; ULONG ulProblem; CONFIGRET cfgRet; cfgRet = CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblem, devinst, 0, NULL); if (CR_SUCCESS == cfgRet) { pLanCon->ulDevNodeProblem = ulProblem; pLanCon->ulDevNodeStatus = ulStatus; } } } listCon.push_back(pLanCon); } FreeNetconProperties(pProps); } ReleaseObj(pconn); } return hr; } HRESULT HrFindLanConnection(INetConnectionManager *pConMan, PCWSTR szLanConnection, INetConnection **ppcon) { HRESULT hr = S_OK; CIterNetCon ncIter(pConMan, NCME_DEFAULT); INetConnection * pconn; *ppcon = NULL; while (SUCCEEDED(hr) && (S_OK == (ncIter.HrNext(&pconn)))) { NETCON_PROPERTIES * pProps; hr = pconn->GetProperties(&pProps); if (SUCCEEDED(hr)) { if (!lstrcmpiW(pProps->pszwName, szLanConnection)) { *ppcon = pconn; break; } else { ReleaseObj(pconn); } } } if (SUCCEEDED(hr)) { if (*ppcon == NULL) { hr = S_FALSE; } } return hr; } extern const WCHAR c_szRegValueNetCfgInstanceId[]; VOID CmdShowAllDevices(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan) { HRESULT hr; DWORD dwIndex = 0; SP_DEVINFO_DATA deid = {0}; HDEVINFO hdi = NULL; WCHAR szBuffer [MAX_PATH]; hr = HrSetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, &hdi); while (SUCCEEDED(hr = HrSetupDiEnumDeviceInfo(hdi, dwIndex, &deid))) { HKEY hkey; dwIndex++; hr = HrSetupDiOpenDevRegKey(hdi, &deid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ, &hkey); if (SUCCEEDED(hr)) { ULONG ulProblem; ULONG ulStatus; PWSTR pszName; hr = HrSetupDiGetDeviceName(hdi, &deid, &pszName); if (SUCCEEDED(hr)) { g_pDiagCtx->Printf(ttidNcDiag, "Device name: %S\n", pszName); delete [] reinterpret_cast(pszName); } (VOID) CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblem, deid.DevInst, 0, NULL); tstring strStatus; SzFromCmStatus(ulStatus, &strStatus); g_pDiagCtx->Printf(ttidNcDiag, "Device CM Status: (0x%08X) %S\n", ulStatus, strStatus.c_str()); g_pDiagCtx->Printf(ttidNcDiag, "Device CM Problem: (0x%08X) %S\n", ulProblem, SzFromCmProb(ulProblem)); g_pDiagCtx->Printf(ttidNcDiag, "Lan capable: "); if (S_OK == HrIsLanCapableAdapterFromHkey(hkey)) { g_pDiagCtx->Printf(ttidNcDiag, "Yes\n"); } else { g_pDiagCtx->Printf(ttidNcDiag, "No\n"); } HRESULT hr = S_OK; WCHAR szGuid[c_cchGuidWithTerm] = {0}; DWORD cbBuf = sizeof(szGuid); hr = HrRegQuerySzBuffer(hkey, c_szRegValueNetCfgInstanceId, szGuid, &cbBuf); g_pDiagCtx->Printf(ttidNcDiag, "Valid NetCfg device: "); if (S_OK == hr) { g_pDiagCtx->Printf(ttidNcDiag, "Yes\n"); } else { g_pDiagCtx->Printf(ttidNcDiag, "No\n"); } g_pDiagCtx->Printf(ttidNcDiag, "NetCfg instance ID: %S\n", szGuid); hr = HrSetupDiGetDeviceInstanceId(hdi, &deid, szBuffer, sizeof(szBuffer), NULL); if (SUCCEEDED(hr)) { g_pDiagCtx->Printf(ttidNcDiag, "PnP instance ID: %S\n", szBuffer); } DWORD dwChars; tstring strChars; if (SUCCEEDED(HrRegQueryDword(hkey, L"Characteristics", &dwChars))) { SzFromCharacteristics(dwChars, &strChars); g_pDiagCtx->Printf(ttidNcDiag, "Characteristics: (0x%08X) %S\n", dwChars, strChars.c_str()); } hr = HrSetupDiGetDeviceRegistryProperty (hdi, &deid, SPDRP_LOCATION_INFORMATION, NULL, (BYTE*)szBuffer, sizeof (szBuffer), NULL); if (S_OK == hr) { g_pDiagCtx->Printf(ttidNcDiag, "Location: %S\n", szBuffer); } if ((NCF_PHYSICAL & dwChars) && *szGuid) { ULONGLONG MacAddr; hr = HrGetNetCardAddr (szGuid, &MacAddr); if (S_OK == hr) { g_pDiagCtx->Printf(ttidNcDiag, "Mac Address: 0x%012.12I64X\n", MacAddr); } } GUID guid; BOOL fMediaConnected; DWORD dwMediaState; IIDFromString(szGuid, &guid); if (SUCCEEDED(hr = HrQueryLanMediaState(&guid, &fMediaConnected))) { dwMediaState = fMediaConnected ? NdisMediaStateConnected : NdisMediaStateDisconnected; } else { dwMediaState = hr; } g_pDiagCtx->Printf(ttidNcDiag, "NDIS media status: "); switch (dwMediaState) { case NdisMediaStateConnected: g_pDiagCtx->Printf(ttidNcDiag, "Connected\n"); break; case NdisMediaStateDisconnected: g_pDiagCtx->Printf(ttidNcDiag, "Disconnected\n"); break; default: g_pDiagCtx->Printf(ttidNcDiag, "Error 0x%08X\n", dwMediaState); break; } RegCloseKey(hkey); } g_pDiagCtx->Printf(ttidNcDiag, "------------------------------------------------------------------------------------\n"); } SetupDiDestroyDeviceInfoListSafe(hdi); } VOID CmdShowLanConnections(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan) { HRESULT hr = S_OK; LAN_CONNECTION_LIST listCon; LAN_CONNECTION_LIST_ITERATOR iterListCon; hr = HrEnumerateLanConnections(pConMan, listCon); if (SUCCEEDED(hr)) { g_pDiagCtx->Printf(ttidNcDiag, "Current LAN connections\n\n"); g_pDiagCtx->Printf(ttidNcDiag, "%-20S%-50S%-20S%\n", L"Connection Name", L"Device Name", L"Status"); g_pDiagCtx->Printf(ttidNcDiag, "----------------------------------------------------------------------------------------\n"); for (iterListCon = listCon.begin(); iterListCon != listCon.end(); iterListCon++) { LAN_CONNECTION * pLanCon; pLanCon = *iterListCon; g_pDiagCtx->Printf(ttidNcDiag, "%-20S%-50S%-20S%\n", pLanCon->strName.c_str(), pLanCon->strDeviceName.c_str(), SzFromNetconStatus(pLanCon->Status)); } } } VOID CmdShowLanDetails(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan) { HRESULT hr = S_OK; LAN_CONNECTION_LIST listCon; LAN_CONNECTION_LIST_ITERATOR iterListCon; BOOL fFound = FALSE; hr = HrEnumerateLanConnections(pConMan, listCon); if (SUCCEEDED(hr)) { for (iterListCon = listCon.begin(); iterListCon != listCon.end(); iterListCon++) { LAN_CONNECTION * pLanCon; pLanCon = *iterListCon; if (!lstrcmpiW(pLanCon->strName.c_str(), pOptions->szLanConnection)) { WCHAR szwGuid[c_cchGuidWithTerm]; StringFromGUID2(pLanCon->guidId, szwGuid, c_cchGuidWithTerm); g_pDiagCtx->Printf(ttidNcDiag, "Details for %S:\n", pOptions->szLanConnection); g_pDiagCtx->Printf(ttidNcDiag, "------------------------------------------\n\n"); g_pDiagCtx->Printf(ttidNcDiag, "Device name: %S\n", pLanCon->strDeviceName.c_str()); g_pDiagCtx->Printf(ttidNcDiag, "Device GUID: %S\n", szwGuid); g_pDiagCtx->Printf(ttidNcDiag, "PnP Instance ID: %S\n", pLanCon->strPnpName.c_str()); g_pDiagCtx->Printf(ttidNcDiag, "Netman Status: %S\n", SzFromNetconStatus(pLanCon->Status)); g_pDiagCtx->Printf(ttidNcDiag, "NDIS media status: "); switch (pLanCon->dwMediaState) { case NdisMediaStateConnected: g_pDiagCtx->Printf(ttidNcDiag, "Connected\n"); break; case NdisMediaStateDisconnected: g_pDiagCtx->Printf(ttidNcDiag, "Disconnected\n"); break; default: g_pDiagCtx->Printf(ttidNcDiag, "Error 0x%08X\n", pLanCon->dwMediaState); break; } tstring strStatus; SzFromCmStatus(pLanCon->ulDevNodeStatus, &strStatus); g_pDiagCtx->Printf(ttidNcDiag, "CM DevNode Status: (0x%08X) %S\n", pLanCon->ulDevNodeStatus, strStatus.c_str()); g_pDiagCtx->Printf(ttidNcDiag, "CM DevNode Problem: (0x%08X) %S\n", pLanCon->ulDevNodeProblem, SzFromCmProb(pLanCon->ulDevNodeProblem)); fFound = TRUE; // No need to keep looping break; } } } if (!fFound) { g_pDiagCtx->Printf(ttidNcDiag, "Could not find match for connection name: %S\n", pOptions->szLanConnection); } } VOID CmdLanChangeState(DIAG_OPTIONS *pOptions, INetConnectionManager *pConMan) { HRESULT hr = S_OK; INetConnection * pcon = NULL; hr = HrFindLanConnection(pConMan, pOptions->szLanConnection, &pcon); if (S_OK == hr) { NETCON_PROPERTIES * pProps; hr = pcon->GetProperties(&pProps); if (SUCCEEDED(hr)) { if (pOptions->fConnect) { if (pProps->Status != NCS_CONNECTED) { pcon->Connect(); } else { g_pDiagCtx->Printf(ttidNcDiag, "%S is already connected.\n", pOptions->szLanConnection); } } else { if (pProps->Status != NCS_DISCONNECTED) { pcon->Disconnect(); } else { g_pDiagCtx->Printf(ttidNcDiag, "%S is already disconnected.\n", pOptions->szLanConnection); } } FreeNetconProperties(pProps); } } else if (S_FALSE == hr) { g_pDiagCtx->Printf(ttidNcDiag, "Could not find match for connection name: %S\n", pOptions->szLanConnection); } } EXTERN_C VOID WINAPI NetManDiagFromCommandArgs (DIAG_OPTIONS *pOptions) { Assert (pOptions); Assert (pOptions->pDiagCtx); g_pDiagCtx = pOptions->pDiagCtx; INetConnectionManager * pConMan; HrInitializeConMan(&pConMan); switch (pOptions->Command) { case CMD_SHOW_LAN_CONNECTIONS: CmdShowLanConnections(pOptions, pConMan); break; case CMD_SHOW_ALL_DEVICES: CmdShowAllDevices(pOptions, pConMan); break; case CMD_SHOW_LAN_DETAILS: CmdShowLanDetails(pOptions, pConMan); break; case CMD_LAN_CHANGE_STATE: CmdLanChangeState(pOptions, pConMan); break; default: break; } HrUninitializeConMan(pConMan); g_pDiagCtx = NULL; }