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

//+---------------------------------------------------------------------------
//
// 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;
}