|
|
//+---------------------------------------------------------------------------
//
// 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 *> LAN_CONNECTION_LIST; typedef list<LAN_CONNECTION *>::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<LPVOID *>(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<BYTE*>(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; }
|