|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2001.
//
// File: S I P C F G . C P P
//
// Contents: The rendering of the UI for the network status monitor's state
// page. Most of them are ipconfig info
//
// Notes:
//
// Author: NSun Dec 2000
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "sminc.h"
#include "smpsh.h"
#include "smhelp.h"
#include "ncui.h"
#include "ncreg.h"
#include "ncperms.h"
#include "windutil.h"
extern "C" { #include <dhcpcapi.h>
extern DWORD DhcpStaticRefreshParams(IN LPWSTR Adapter); }
#include <dnsapi.h>
#include <nbtioctl.h>
#include "..\lanui\lanui.h"
#include "repair.h"
#define LOCAL_WINS_ADDRESS 0x7f000000 // 127.0.0.0
DWORD WINAPI IPAddrListenProc( LPVOID lpParameter // thread data
);
DWORD WINAPI IPAddrListenProc( LPVOID lpParameter // thread data
);
void DwordToIPAddrString(DWORD dw, tstring * pstr);
const WCHAR c_szTcpipInterfaces[] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; const WCHAR c_szAddressType[] = L"AddressType"; const WCHAR c_szActiveConfigurations[] = L"ActiveConfigurations"; const WCHAR c_szAlternate[] = L"Alternate_"; const WCHAR c_szNameServer[] = L"NameServer"; const WCHAR c_szDhcpNameServer[] = L"DhcpNameServer"; const WCHAR c_szNbtDevicePrefix[] = L"\\Device\\NetBT_Tcpip_";
////////////////////////////////////////////////////////////////////////////////////////
// Implementation CPspStatusMonitorIpcfg
//
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::~CPspStatusMonitorIpcfg(
//
// Purpose: constructor
//
CPspStatusMonitorIpcfg::CPspStatusMonitorIpcfg(VOID) : m_adwHelpIDs(NULL), m_ncmType(NCM_NONE), m_pConn(NULL), m_fDhcp(TRUE), m_dhcpAddrType(NORMAL_ADDR), m_fListenAddrChange(FALSE), m_fEnableOpButtons(TRUE), m_fIsFirstPage(FALSE) { TraceFileFunc(ttidStatMon);
ZeroMemory(&m_guidConnection, sizeof(m_guidConnection));
//Create events that are used to control the thread listening to
//address change notifications
m_hEventAddrListenThreadStopCommand = CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventAddrListenThreadStopNotify = CreateEvent(NULL, TRUE, FALSE, NULL); }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::~CPspStatusMonitorIpcfg(
//
// Purpose: destructor
//
CPspStatusMonitorIpcfg::~CPspStatusMonitorIpcfg(VOID) { if (m_hEventAddrListenThreadStopCommand) { CloseHandle(m_hEventAddrListenThreadStopCommand); }
if (m_hEventAddrListenThreadStopNotify) { CloseHandle(m_hEventAddrListenThreadStopNotify); }
CleanupPage(); }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::HrInitPage
//
// Purpose: Initialize the Network State page class before the page has been
// created
//
// Arguments: pnConnection - The connection associated with this monitor
// dwHelpIDs - The context sensitive help ID array
//
// Returns: Error code
//
HRESULT CPspStatusMonitorIpcfg::HrInitPage( INetConnection * pnConnection, const DWORD * adwHelpIDs) { TraceFileFunc(ttidStatMon);
HRESULT hr = S_OK;
Assert(pnConnection);
m_adwHelpIDs = adwHelpIDs;
NETCON_PROPERTIES* pProps; hr = pnConnection->GetProperties(&pProps); if (SUCCEEDED(hr)) { m_strConnectionName = pProps->pszwName; m_guidConnection = pProps->guidId; m_ncmType = pProps->MediaType; m_dlgAdvanced.InitDialog(m_guidConnection, g_aHelpIDs_IDD_DIALOG_ADV_IPCFG); FreeNetconProperties(pProps);
if (m_pConn) { m_pConn->Release(); }
m_pConn = pnConnection; ::AddRefObj(m_pConn); }
return hr; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::CleanupPage
//
// Purpose: Cleanup the INetConnection ref count we are holding
//
// Arguments: pnConnection - The connection associated with this monitor
// dwHelpIDs - The context sensitive help ID array
//
// Returns: Error code
//
VOID CPspStatusMonitorIpcfg::CleanupPage() { TraceFileFunc(ttidStatMon);
if (m_pConn) { m_pConn->Release(); m_pConn = NULL; } }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnInitDialog
//
// Purpose: Do the initialization required when the page has just been created
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled) { TraceFileFunc(ttidStatMon);
m_fEnableOpButtons = FHasPermission(NCPERM_Repair);
if (m_fIsFirstPage) { // get window handle to propertysheet
HWND hwndParent=GetParent(); Assert(hwndParent);
// center the property sheet on desktop
FCenterWindow (hwndParent, NULL); // hide the "ok" button
//
::ShowWindow(::GetDlgItem(hwndParent, IDOK), FALSE); }
//The initialization is in the OnActive method so that we will update the UI
//when the user active this page
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnActive
//
// Purpose: Refresh the UI and start listening to the address change notification
// when the page has just been created
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
RefreshUI();
if (m_hEventAddrListenThreadStopCommand && m_hEventAddrListenThreadStopNotify) { ResetEvent(m_hEventAddrListenThreadStopCommand); ResetEvent(m_hEventAddrListenThreadStopNotify); QueueUserWorkItem(IPAddrListenProc, this, WT_EXECUTELONGFUNCTION); m_fListenAddrChange = TRUE; }
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnKillActive
//
// Purpose: Do the operation required when the page is no longer the active one
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
//If the advanced dialog is there, we need to close it
//This happens when the connection is disabled or media disconnected when
//we still have the connection status dialog open.
HWND hwndAdv = m_dlgAdvanced.m_hWnd; if (hwndAdv) { ::SendMessage(hwndAdv, WM_CLOSE, 0, 0); }
//Stop listening to the address change
if (m_fListenAddrChange) { StopAddressListenThread(); m_fListenAddrChange = FALSE; }
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnDestroy
//
// Purpose: Do the operation required when the page is destroyed.
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { TraceFileFunc(ttidStatMon);
//If the advanced dialog is there, we need to close it
//This happens when the connection is disabled or media disconnected when
//we still have the connection status dialog open.
HWND hwndAdv = m_dlgAdvanced.m_hWnd; if (hwndAdv) { ::SendMessage(hwndAdv, WM_CLOSE, 0, 0); }
//Stop listening to the address change
if (m_fListenAddrChange) { StopAddressListenThread(); m_fListenAddrChange = FALSE; } CleanupPage();
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnUpdateDisplay
//
// Purpose: Handling the user defined PWM_UPDATE_IPCFG_DISPLAY message
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnUpdateDisplay(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { TraceFileFunc(ttidStatMon);
//The thread listening to address changes will post a PWM_UPDATE_IPCFG_DISPLAY
//message to us once the IP address is changed.
//We need refresh the UI.
RefreshUI(); return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnRepair
//
// Purpose: Repair the connection if the "Repair" button is pressed
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnRepair( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
tstring strMessage = L""; HRESULT hr = S_OK; HWND hwndPsh = GetParent(); Assert(hwndPsh);
{ CWaitCursor cursorWait; CLanConnectionUiDlg dlg; HWND hwndDlg = NULL;
//bring up the dialog to tell the user we're doing the fix
Assert(m_pConn); if (m_pConn) { dlg.SetConnection(m_pConn); hwndDlg = dlg.Create(hwndPsh);
PCWSTR szw = SzLoadIds(IDS_FIX_REPAIRING); ::SetDlgItemText(hwndDlg, IDC_TXT_Caption, szw); }
//do the fix
hr = HrTryToFix(m_guidConnection, strMessage);
if (NULL != hwndDlg) { ::DestroyWindow(hwndDlg); } }
//tell users the results
NcMsgBox(_Module.GetResourceInstance(), hwndPsh, IDS_FIX_CAPTION, IDS_FIX_MESSAGE, MB_OK, strMessage.c_str()); //We may get new settings. So need to refresh the UI.
RefreshUI();
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnDetails
//
// Purpose: Open the Advanced Ipconfig dialog if the "Advanced" button is pressed
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CPspStatusMonitorIpcfg::OnDetails( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
//Since the status dialog will be automatically closed if the connection becomes
//disconnected or disabled, we also need to force the Advanced dialog to close in
//such case.
//So We cannot launch the Advanced dialog as a modal dialog. Instead, we launch the
//dialog in another thread.
QueueUserWorkItem(AdvIpCfgProc, this, WT_EXECUTEDEFAULT); return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnContextMenu
//
// Purpose: When right click a control, bring up help
//
// Arguments: Standard command parameters
//
// Returns: Standard return
//
LRESULT CPspStatusMonitorIpcfg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
if (m_adwHelpIDs != NULL) { ::WinHelp(m_hWnd, c_szNetCfgHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)m_adwHelpIDs); } return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnHelp
//
// Purpose: When drag context help icon over a control, bring up help
//
// Arguments: Standard command parameters
//
// Returns: Standard return
//
LRESULT CPspStatusMonitorIpcfg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam); Assert(lphi);
if ((m_adwHelpIDs != NULL) && (HELPINFO_WINDOW == lphi->iContextType)) { ::WinHelp(static_cast<HWND>(lphi->hItemHandle), c_szNetCfgHelpFile, HELP_WM_HELP, (ULONG_PTR)m_adwHelpIDs); }
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::InitializeData
//
// Purpose: Cleanup the saved IP settings
//
// Arguments: None
//
// Returns: None
//
VOID CPspStatusMonitorIpcfg::InitializeData() { TraceFileFunc(ttidStatMon);
m_strIPAddress = L""; m_strSubnetMask = L""; m_strGateway = L""; m_fDhcp = TRUE; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::StopAddressListenThread
//
// Purpose: Stop the thread that listens to address changes
//
// Arguments: None
//
// Returns: None
//
VOID CPspStatusMonitorIpcfg::StopAddressListenThread() { TraceFileFunc(ttidStatMon);
if (m_hEventAddrListenThreadStopCommand && m_hEventAddrListenThreadStopNotify) { Assert(m_hEventAddrListenThreadStopNotify);
SetEvent(m_hEventAddrListenThreadStopCommand); WaitForSingleObject(m_hEventAddrListenThreadStopNotify, 5000); } }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::GetIPConfigInfo
//
// Purpose: Load the TCP/IP running settings of this connection
//
// Arguments: None
//
// Returns: error code
//
HRESULT CPspStatusMonitorIpcfg::GetIPConfigInfo() { TraceFileFunc(ttidStatMon);
HRESULT hr = S_OK; PIP_ADAPTER_INFO pAdapterInfo = NULL; DWORD dwOutBufLen = 0; DWORD dwRet = ERROR_SUCCESS; dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (dwRet == ERROR_BUFFER_OVERFLOW) { pAdapterInfo = (PIP_ADAPTER_INFO) CoTaskMemAlloc(dwOutBufLen); if (NULL == pAdapterInfo) return E_OUTOFMEMORY; } else if (ERROR_SUCCESS == dwRet) { return E_FAIL; } else { return HRESULT_FROM_WIN32(dwRet); } dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (ERROR_SUCCESS != dwRet) { CoTaskMemFree(pAdapterInfo); return HRESULT_FROM_WIN32(dwRet); } WCHAR wszGuid[c_cchGuidWithTerm]; ::StringFromGUID2(m_guidConnection, wszGuid, c_cchGuidWithTerm);
BOOL fFound = FALSE; PIP_ADAPTER_INFO pAdapterInfoEnum = pAdapterInfo; while (pAdapterInfoEnum) { USES_CONVERSION; if (lstrcmp(wszGuid, A2W(pAdapterInfoEnum->AdapterName)) == 0) { m_strIPAddress = A2W(pAdapterInfoEnum->IpAddressList.IpAddress.String); m_strSubnetMask = A2W(pAdapterInfoEnum->IpAddressList.IpMask.String); m_strGateway = A2W(pAdapterInfoEnum->GatewayList.IpAddress.String); m_fDhcp = pAdapterInfoEnum->DhcpEnabled; fFound = TRUE; break; } pAdapterInfoEnum = pAdapterInfoEnum->Next; }
CoTaskMemFree(pAdapterInfo);
if (!fFound) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } else { if (m_fDhcp) { hr = HrGetAutoNetSetting(wszGuid, &m_dhcpAddrType); } }
return hr; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::RefreshUI
//
// Purpose: refresh the UI
//
// Arguments: none
//
// Returns: none
//
VOID CPspStatusMonitorIpcfg::RefreshUI() { TraceFileFunc(ttidStatMon);
HRESULT hr = S_OK; BOOL fZeroIP = FALSE; InitializeData(); hr = GetIPConfigInfo(); if (FAILED(hr)) { ::SetWindowText(GetDlgItem(IDC_STATE_SOURCE), SzLoadString(_Module.GetResourceInstance(), IDS_ADDRESS_UNAVALABLE)); ::SetWindowText(GetDlgItem(IDC_STATE_IPADDR), SzLoadString(_Module.GetResourceInstance(), IDS_ADDRESS_UNAVALABLE)); ::SetWindowText(GetDlgItem(IDC_STATE_SUBNET), SzLoadString(_Module.GetResourceInstance(), IDS_ADDRESS_UNAVALABLE)); ::SetWindowText(GetDlgItem(IDC_STATE_GATEWAY), SzLoadString(_Module.GetResourceInstance(), IDS_ADDRESS_UNAVALABLE));
::EnableWindow(GetDlgItem(IDC_STATE_BTN_REPAIR), FALSE); ::EnableWindow(GetDlgItem(IDC_STATE_BTN_DETAIL), FALSE);
return; } else { ::EnableWindow(GetDlgItem(IDC_STATE_BTN_REPAIR), TRUE); ::EnableWindow(GetDlgItem(IDC_STATE_BTN_DETAIL), TRUE); }
fZeroIP = (m_strIPAddress == L"0.0.0.0"); ::SetWindowText(GetDlgItem(IDC_STATE_IPADDR), m_strIPAddress.c_str()); ::SetWindowText(GetDlgItem(IDC_STATE_SUBNET), m_strSubnetMask.c_str()); ::SetWindowText(GetDlgItem(IDC_STATE_GATEWAY), m_strGateway.c_str());
if (!m_fDhcp) { ::SetWindowText(GetDlgItem(IDC_STATE_SOURCE), SzLoadString(_Module.GetResourceInstance(), IDS_STATIC_CFG)); } else { UINT idString = IDS_DHCP; switch(m_dhcpAddrType) { case NORMAL_ADDR: idString = IDS_DHCP; break; case AUTONET_ADDR: idString = IDS_AUTONET; break; case ALTERNATE_ADDR: idString = IDS_ALTERNATE_ADDR; break; } ::SetWindowText(GetDlgItem(IDC_STATE_SOURCE), SzLoadString(_Module.GetResourceInstance(), idString)); }
if (fZeroIP) { ::SetWindowText(GetDlgItem(IDC_STATE_SOURCE), SzLoadString(_Module.GetResourceInstance(), IDS_INVALID_ADDR)); }
if (!m_fEnableOpButtons) { ::EnableWindow(GetDlgItem(IDC_STATE_BTN_REPAIR), FALSE); } }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::IPAddrListenProc
//
// Purpose: the call back proc to launch the thead to listen to address changes
//
// Arguments: lpParameter - the CPspStatusMonitroIpcfg instance
//
// Returns: 0
//
DWORD WINAPI CPspStatusMonitorIpcfg::IPAddrListenProc( LPVOID lpParameter // thread data
) { TraceFileFunc(ttidStatMon);
HANDLE hEvents[2]; OVERLAPPED NotifyAddrOverLapped; HANDLE hNotifyAddr = NULL; DWORD dwRet = 0; CPspStatusMonitorIpcfg * pDialog = (CPspStatusMonitorIpcfg*) lpParameter;
hEvents[0] = pDialog->m_hEventAddrListenThreadStopCommand; ZeroMemory(&NotifyAddrOverLapped, sizeof(OVERLAPPED)); NotifyAddrOverLapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (NotifyAddrOverLapped.hEvent) { if (ERROR_IO_PENDING == NotifyAddrChange(&hNotifyAddr, &NotifyAddrOverLapped)) { hEvents[1] = NotifyAddrOverLapped.hEvent;
do { dwRet = WaitForMultipleObjects( celems(hEvents), hEvents, FALSE, INFINITE);
if (WAIT_OBJECT_0 + 1 == dwRet) { ResetEvent(hEvents[1]); ::PostMessage(pDialog->m_hWnd, PWM_UPDATE_IPCFG_DISPLAY, 0, 0);
HWND hwndAdv = pDialog->m_dlgAdvanced.m_hWnd;
if (hwndAdv) { ::PostMessage(hwndAdv, PWM_UPDATE_IPCFG_DISPLAY, 0, 0); }
hNotifyAddr = NULL;
if (ERROR_IO_PENDING != NotifyAddrChange(&hNotifyAddr, &NotifyAddrOverLapped)) { TraceTag(ttidStatMon, "Could not register for IP address change notifications"); break; } } else { break; } }while (TRUE);
} else { TraceTag(ttidStatMon, "Could not register for IP address change notifications"); } }
if (hNotifyAddr) { CancelIo(hNotifyAddr); } SetEvent(pDialog->m_hEventAddrListenThreadStopNotify);
return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::AdvIpCfgProc
//
// Purpose: the call back proc to launch the advanced dialog in another thread
//
// Arguments: lpParameter - the CPspStatusMonitroIpcfg instance
//
// Returns: 0
//
DWORD WINAPI CPspStatusMonitorIpcfg::AdvIpCfgProc( LPVOID lpParameter // thread data
) { TraceFileFunc(ttidStatMon);
CPspStatusMonitorIpcfg * pMainDialog = (CPspStatusMonitorIpcfg*) lpParameter;
Assert(pMainDialog);
//disable the status propsheet
HWND hwndPsh = pMainDialog->GetParent(); Assert(hwndPsh); pMainDialog->m_dlgAdvanced.DoModal(hwndPsh);
return 0; }
///////////////////////////////////////////////////////////////////////
// Implementation of CAdvIpcfgDlg
//
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::CAdvIpcfgDlg
//
// Purpose: constructor
//
CAdvIpcfgDlg::CAdvIpcfgDlg() : m_hList(NULL), m_adwHelpIDs(NULL) { TraceFileFunc(ttidStatMon); }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::OnInitDialog
//
// Purpose: do the initialize required when the dialog is created
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CAdvIpcfgDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled ) { TraceFileFunc(ttidStatMon);
const UINT c_nColumns = 2;
LV_COLUMN lvCol = {0}; RECT rect; int iIndex = 0; int iParamColWidth = 0;
m_hList = GetDlgItem(IDC_LIST_IPCFG); ::GetClientRect(m_hList, &rect); iParamColWidth = (rect.right/c_nColumns); lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ; lvCol.fmt = LVCFMT_LEFT; // left-align column
lvCol.cx = iParamColWidth;
lvCol.pszText = (PWSTR) SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_PRAMETER); iIndex = ListView_InsertColumn(m_hList, iIndex, &lvCol); iIndex++;
lvCol.cx = rect.right - iParamColWidth; lvCol.pszText = (PWSTR) SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_VALUE); iIndex = ListView_InsertColumn(m_hList, iIndex, &lvCol);
ListView_SetExtendedListViewStyle(m_hList, LVS_EX_FULLROWSELECT); PopulateListControl();
return 0; }
VOID CAdvIpcfgDlg::AddToListControl(int iIndex, LPWSTR szFirst, LPWSTR szSecond) { TraceFileFunc(ttidStatMon);
LV_ITEM lvi = {0}; lvi.mask = LVIF_PARAM; lvi.lParam = 0;
lvi.iItem = iIndex; ListView_InsertItem(m_hList, &lvi); ListView_SetItemText(m_hList, iIndex, 0, szFirst);
ListView_SetItemText(m_hList, iIndex, 1, szSecond);
} //+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::PopulateListControl
//
// Purpose: load the connection running settings and show them up in
// the list control
//
// Arguments: none
//
// Returns: error code
//
HRESULT CAdvIpcfgDlg::PopulateListControl() { TraceFileFunc(ttidStatMon);
HRESULT hr = S_OK; PIP_ADAPTER_INFO pAdapterInfo = NULL; DWORD dwOutBufLen = 0; DWORD dwRet = ERROR_SUCCESS; tstring strDns = L""; WCHAR wszGuid[c_cchGuidWithTerm] = {0}; tstring strTemp = L""; tstring strTemp2 = L""; BOOL fDisplayDhcpItems = TRUE;
ListView_DeleteAllItems(m_hList); ::StringFromGUID2(m_guidConnection, wszGuid, c_cchGuidWithTerm);
//Get other settings
dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (dwRet == ERROR_BUFFER_OVERFLOW) { pAdapterInfo = (PIP_ADAPTER_INFO) CoTaskMemAlloc(dwOutBufLen); if (NULL == pAdapterInfo) return E_OUTOFMEMORY; } else if (ERROR_SUCCESS == dwRet) { return E_FAIL; } else { return HRESULT_FROM_WIN32(dwRet); } dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (ERROR_SUCCESS != dwRet) { CoTaskMemFree(pAdapterInfo); return HRESULT_FROM_WIN32(dwRet); } BOOL fFound = FALSE; PIP_ADAPTER_INFO pAdapterInfoEnum = pAdapterInfo; while (pAdapterInfoEnum) { USES_CONVERSION; if (lstrcmp(wszGuid, A2W(pAdapterInfoEnum->AdapterName)) == 0) { fFound = TRUE; break; } pAdapterInfoEnum = pAdapterInfoEnum->Next; }
if (!fFound) { CoTaskMemFree(pAdapterInfo); return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } int iTemp = 0; int iIndex = 0; struct tm * ptmLocalTime = NULL; WCHAR szBuf[8];
fDisplayDhcpItems = !!pAdapterInfoEnum->DhcpEnabled; if (fDisplayDhcpItems) { DHCP_ADDRESS_TYPE AddrType; if (SUCCEEDED(HrGetAutoNetSetting(wszGuid, &AddrType))) { fDisplayDhcpItems = (AUTONET_ADDR != AddrType && ALTERNATE_ADDR != AddrType); } } LV_ITEM lvi = {0}; lvi.mask = LVIF_PARAM; lvi.lParam = 0;
//Physical Address
strTemp = L""; for (UINT i = 0; i < pAdapterInfoEnum->AddressLength; i++) { if (i > 0) { strTemp += L"-"; } wsprintf(szBuf, L"%02X", pAdapterInfoEnum->Address[i]); strTemp += szBuf; }
AddToListControl(iIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_PH_ADDR), (LPWSTR)strTemp.c_str());
iIndex++;
//IP Address and subnet mask
iTemp = IPAddrToString(&pAdapterInfoEnum->IpAddressList, &strTemp, &strTemp2); //if the ip is zero, don't display DHCP items
if (L"0.0.0.0" == strTemp) { fDisplayDhcpItems = FALSE; }
iIndex += AddIPAddrToListControl(iIndex, &pAdapterInfoEnum->IpAddressList, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_IPADDR), (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_SUBNET), TRUE );
//Default Gateway
iTemp = IPAddrToString(&pAdapterInfoEnum->GatewayList, &strTemp); iIndex += AddIPAddrToListControl(iIndex, &pAdapterInfoEnum->GatewayList, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), (iTemp > 1) ? IDS_IPCFG_DEFGW_PL : IDS_IPCFG_DEFGW) ); //Dhcp Server
if (fDisplayDhcpItems) { IPAddrToString(&pAdapterInfoEnum->DhcpServer, &strTemp); AddToListControl(iIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_DHCP), (LPWSTR)strTemp.c_str()); iIndex++; }
//Lease Obtain time
if (fDisplayDhcpItems) { if (SUCCEEDED(FormatTime(pAdapterInfoEnum->LeaseObtained, strTemp))) { AddToListControl(iIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_LEASE_OBT), (LPWSTR)strTemp.c_str()); iIndex++; }
//Lease expire time
if (SUCCEEDED(FormatTime(pAdapterInfoEnum->LeaseExpires, strTemp))) { AddToListControl(iIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_LEASE_EXP), (LPWSTR)strTemp.c_str()); iIndex++; } } //Get the DNS servers
HKEY hkeyInterface = NULL; tstring strInterfaceKey = c_szTcpipInterfaces;
strInterfaceKey += wszGuid; hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strInterfaceKey.c_str(), KEY_QUERY_VALUE, &hkeyInterface); if (SUCCEEDED(hr)) { BOOL fStaticDns = TRUE; int iPos = 0; Assert(hkeyInterface);
hr = HrRegQueryString(hkeyInterface, c_szNameServer, &strTemp);
if (0 == strTemp.size() || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { HrRegQueryString(hkeyInterface, c_szDhcpNameServer, &strTemp);
fStaticDns = FALSE; }
//the static DNS server list is in the format "x.x.x.x,y.y.y.y" and
//the dhcp DNS server list is in the format "x.x.x.x y.y.y.y". We need to
//re-format them to the same style
//fFirst is used to identify whether this is the first DNS server
int fFirst = TRUE; while(tstring::npos != (iPos = strTemp.find(fStaticDns ? L',' :L' '))) { strDns = strTemp.substr(0, iPos); strTemp = strTemp.erase(0, iPos + 1);
AddToListControl(iIndex, fFirst ? (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_DNS_PL) : L"", (LPWSTR)strDns.c_str());; iIndex++; fFirst = FALSE; }
strDns = strTemp; AddToListControl(iIndex, fFirst ? (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_DNS) : L"", (LPWSTR)strDns.c_str());;
iIndex++;
RegCloseKey(hkeyInterface); }
iIndex += AddWinsServersToList(iIndex);
if (pAdapterInfo) { CoTaskMemFree(pAdapterInfo); }
return hr; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::OnClose
//
// Purpose: handle the WM_CLOSE message
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CAdvIpcfgDlg::OnClose( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled ) { TraceFileFunc(ttidStatMon);
EndDialog(IDCANCEL); return 0; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::OnOk
//
// Purpose: close the dialog when the OK button is pressed
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CAdvIpcfgDlg::OnOk( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled ) { TraceFileFunc(ttidStatMon);
EndDialog(IDOK); return 0; }
LRESULT CAdvIpcfgDlg::OnCancel( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled ) { TraceFileFunc(ttidStatMon);
EndDialog(IDCANCEL); return 0; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::OnUpdateDisplay
//
// Purpose: Handling the user defined PWM_UPDATE_IPCFG_DISPLAY message
//
// Arguments: Standard window messsage parameters
//
// Returns: Standard window message return value
//
LRESULT CAdvIpcfgDlg::OnUpdateDisplay(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { TraceFileFunc(ttidStatMon);
//The thread listening to address changes will post a PWM_UPDATE_IPCFG_DISPLAY
//message to us once the IP address is changed.
//We need refresh the UI.
PopulateListControl(); return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnContextMenu
//
// Purpose: When right click a control, bring up help
//
// Arguments: Standard command parameters
//
// Returns: Standard return
//
LRESULT CAdvIpcfgDlg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
if (m_adwHelpIDs != NULL) { ::WinHelp(m_hWnd, c_szNetCfgHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)m_adwHelpIDs); } return 0; }
//+---------------------------------------------------------------------------
//
// Member: CPspStatusMonitorIpcfg::OnHelp
//
// Purpose: When drag context help icon over a control, bring up help
//
// Arguments: Standard command parameters
//
// Returns: Standard return
//
LRESULT CAdvIpcfgDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam); Assert(lphi);
if ((m_adwHelpIDs != NULL) && (HELPINFO_WINDOW == lphi->iContextType)) { ::WinHelp(static_cast<HWND>(lphi->hItemHandle), c_szNetCfgHelpFile, HELP_WM_HELP, (ULONG_PTR)m_adwHelpIDs); }
return 0; }
LRESULT CAdvIpcfgDlg::OnListKeyDown(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { TraceFileFunc(ttidStatMon);
LPNMLVKEYDOWN pnmlv = (LPNMLVKEYDOWN) pnmh;
if (NULL == pnmlv) return 0;
if (IDC_LIST_IPCFG != idCtrl) return 0;
BOOL fControlDown = (GetKeyState(VK_CONTROL) < 0);
switch (pnmlv->wVKey) { case VK_INSERT: case 'c': case 'C': CopyListToClipboard(); break; }
return 0; }
VOID CAdvIpcfgDlg::CopyListToClipboard() { TraceFileFunc(ttidStatMon);
WCHAR szBuff[256] = {0}; int iIndex = -1; tstring str = L""; BOOL fFirst = TRUE;
while(-1 != (iIndex = ListView_GetNextItem(m_hList, iIndex, LVNI_ALL))) { szBuff[0] = 0; ListView_GetItemText(m_hList, iIndex, 0, szBuff, celems(szBuff) - 1);
if (0 == lstrlen(szBuff)) { str += L", "; } else { if (!fFirst) { str += L"\r\n"; } else { fFirst = FALSE; } str += szBuff; str += L": "; }
szBuff[0] = 0; ListView_GetItemText(m_hList, iIndex, 1, szBuff, celems(szBuff) -1); str += szBuff; }
int nLength = str.length() + 1; nLength *= sizeof(WCHAR);
HLOCAL hMem = LocalAlloc(LPTR, nLength);
if (hMem) { memcpy(hMem, str.c_str(), nLength); if (!OpenClipboard()) { LocalFree(hMem); } else { EmptyClipboard(); SetClipboardData(CF_UNICODETEXT, hMem); CloseClipboard(); } } }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::AddIPAddrToListControl
//
// Purpose: helper routine to add a list of IP address/mask pairs to the list control
//
// Arguments: iStartIndex [in] the starting index of the list control
// pszAddrDescription [in] the description of the address
// pszMaskDescription [in] the description of the mask, this can be null
// fShowDescriptionForMutliple [in] whether show the description for each entry if we have multiple entris
// pAddrList [in] the address/mask pair list
//
// Returns: number of IP addresses in the string
//
int CAdvIpcfgDlg::AddIPAddrToListControl(int iStartIndex, PIP_ADDR_STRING pAddrList, LPWSTR pszAddrDescription, LPWSTR pszMaskDescription, BOOL fShowDescriptionForMutliple ) { TraceFileFunc(ttidStatMon);
Assert(pAddrList); Assert(pszAddrDescription);
if (NULL == pAddrList || NULL == pszAddrDescription) return 0;
tstring strTmp = L""; BOOL fFirst = TRUE; int iIndex = iStartIndex; PIP_ADDR_STRING pCurrentAddr = NULL;
for (pCurrentAddr = pAddrList; NULL != pCurrentAddr; pCurrentAddr = pCurrentAddr->Next) { USES_CONVERSION;
strTmp = A2W(pCurrentAddr->IpAddress.String);
AddToListControl(iIndex, (fFirst || fShowDescriptionForMutliple) ? pszAddrDescription : L"", (LPWSTR) strTmp.c_str());
iIndex++;
if (pszMaskDescription) { strTmp = A2W(pCurrentAddr->IpMask.String); AddToListControl(iIndex, (fFirst || fShowDescriptionForMutliple) ? pszMaskDescription : L"", (LPWSTR) strTmp.c_str()); iIndex++; }
if (fFirst) { fFirst = FALSE; } }
return iIndex - iStartIndex; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::IPAddrToString
//
// Purpose: helper routine to convert IP_ADDR_STRING to a string
//
// Arguments: pAddrList - the IP_ADDR_STRING
// pstrAddr [out] the string contains the IP address
// pstrMask [out] the string contains the Mask
//
// Returns: number of IP addresses in the string
//
int CAdvIpcfgDlg::IPAddrToString( PIP_ADDR_STRING pAddrList, tstring * pstrAddr, tstring * pstrMask ) { TraceFileFunc(ttidStatMon);
int i = 0; PIP_ADDR_STRING pCurrentAddr = NULL;
if (pstrAddr) { *pstrAddr = L""; }
if (pstrMask) { *pstrMask = L""; }
for (pCurrentAddr = pAddrList; NULL != pCurrentAddr; pCurrentAddr = pCurrentAddr->Next) { USES_CONVERSION;
if (pstrAddr) { if (0 != i) { (*pstrAddr) += L", "; }
(*pstrAddr) += A2W(pCurrentAddr->IpAddress.String); }
if (pstrMask) { if (0 != i) { (*pstrMask) += L", "; }
(*pstrMask) += A2W(pCurrentAddr->IpMask.String);
}
i++; }
return i; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::AddWinsServersToList
//
// Purpose: Get the list of WINS servers from the NBT driver and add them
// into the list control
//
// Arguments: iStartIndex [in] - the starting index of the list control
// that we should use to add the WINS servers
//
// Returns: number of entris added to the list control
//
int CAdvIpcfgDlg::AddWinsServersToList(int iStartIndex) { TraceFileFunc(ttidStatMon);
int iIndex = iStartIndex; WCHAR wszGuid[c_cchGuidWithTerm] = {0}; ::StringFromGUID2(m_guidConnection, wszGuid, c_cchGuidWithTerm);
HANDLE hNbt = INVALID_HANDLE_VALUE; tWINS_NODE_INFO NodeInfo = {0}; int nCount = 0; tstring strTemp = L"";
if (FAILED(OpenNbt(wszGuid, &hNbt))) { AddToListControl(iStartIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_WINS), (LPWSTR)L""); return 1; }
do { NTSTATUS status = 0; DWORD dwSize = 0;
if (!DeviceIoControl(hNbt, IOCTL_NETBT_GET_WINS_ADDR, NULL, 0, (LPVOID)&NodeInfo, sizeof(NodeInfo), &dwSize, NULL)) { break; }
if( LOCAL_WINS_ADDRESS == NodeInfo.NameServerAddress || INADDR_ANY == NodeInfo.NameServerAddress || INADDR_BROADCAST == NodeInfo.NameServerAddress ) { break; }
BOOL fHaveSecondWins = !(LOCAL_WINS_ADDRESS == NodeInfo.BackupServer || INADDR_ANY == NodeInfo.BackupServer || INADDR_BROADCAST == NodeInfo.BackupServer); DwordToIPAddrString(NodeInfo.NameServerAddress, &strTemp); AddToListControl(iIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), fHaveSecondWins ? IDS_IPCFG_WINS_PL : IDS_IPCFG_WINS), (LPWSTR)strTemp.c_str()); iIndex++;
if (!fHaveSecondWins) { break; }
DwordToIPAddrString(NodeInfo.BackupServer, &strTemp); AddToListControl(iIndex, (LPWSTR)L"", (LPWSTR)strTemp.c_str()); iIndex++;
int NumOfServers = (NodeInfo.NumOtherServers <= MAX_NUM_OTHER_NAME_SERVERS) ? NodeInfo.NumOtherServers : MAX_NUM_OTHER_NAME_SERVERS;
for (int i = 0; i < NumOfServers; i++) { if( LOCAL_WINS_ADDRESS == NodeInfo.Others[i] || INADDR_ANY == NodeInfo.Others[i] || INADDR_BROADCAST == NodeInfo.Others[i] ) { break; }
DwordToIPAddrString(NodeInfo.Others[i], &strTemp); AddToListControl(iIndex, (LPWSTR)L"", (LPWSTR)strTemp.c_str()); iIndex++; }
} while (FALSE);
NtClose(hNbt);
int iRet = iIndex - iStartIndex;
//if somehow we didn't add any WINS entris to the list, we need to add an empty "WINS Server" entry to the list
if (0 == iRet) { AddToListControl(iStartIndex, (LPWSTR)SzLoadString(_Module.GetResourceInstance(), IDS_IPCFG_WINS), (LPWSTR)L""); iRet = 1; }
return iRet; }
//+---------------------------------------------------------------------------
//
// Member: CAdvIpcfgDlg::FormatTime
//
// Purpose: convert time_t to a string.
//
// Arguments: pAddrList - the IP_ADDR_STRING
// pstrAddr [out] the string contains the IP address
// pstrMask [out] the string contains the Mask
//
// Returns: error code
//
// Note: _wasctime has some localization problems. So we do the formatting ourselves
HRESULT CAdvIpcfgDlg::FormatTime(time_t t, tstring & str) { TraceFileFunc(ttidStatMon);
time_t timeCurrent = time(NULL); LONGLONG llTimeDiff = 0; FILETIME ftCurrent = {0}; FILETIME ftLocal = {0}; SYSTEMTIME SysTime; WCHAR szBuff[256] = {0};
str = L"";
GetSystemTimeAsFileTime(&ftCurrent);
llTimeDiff = (LONGLONG)t - (LONGLONG)timeCurrent;
llTimeDiff *= 10000000;
*((LONGLONG UNALIGNED64 *)&ftCurrent) += llTimeDiff;
if (!FileTimeToLocalFileTime(&ftCurrent, &ftLocal )) { return HRESULT_FROM_WIN32(GetLastError()); }
if (!FileTimeToSystemTime( &ftLocal, &SysTime )) { return HRESULT_FROM_WIN32(GetLastError()); }
if (0 == GetDateFormat(LOCALE_USER_DEFAULT, 0, &SysTime, NULL, szBuff, celems(szBuff))) { return HRESULT_FROM_WIN32(GetLastError()); }
str = szBuff; str += L" ";
ZeroMemory(szBuff, sizeof(szBuff)); if (0 == GetTimeFormat(LOCALE_USER_DEFAULT, 0, &SysTime, NULL, szBuff, celems(szBuff))) { return HRESULT_FROM_WIN32(GetLastError()); }
str += szBuff;
return S_OK; }
//+---------------------------------------------------------------------------
//
// Function: HrGetAutoNetSetting
//
// Purpose: Query the Autonet settings
//
// Arguments: pszGuid - guid of the connection
// pAddrType [out] - contains the type of the address
//
// Returns: error code
//
HRESULT HrGetAutoNetSetting(PWSTR pszGuid, DHCP_ADDRESS_TYPE * pAddrType) { TraceFileFunc(ttidStatMon);
Assert(pszGuid); Assert(pAddrType);
*pAddrType = UNKNOWN_ADDR;
HRESULT hr = S_OK; DWORD dwType = 0; HKEY hkeyInterface = NULL; tstring strInterfaceKey = c_szTcpipInterfaces; strInterfaceKey += pszGuid;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strInterfaceKey.c_str(), KEY_QUERY_VALUE, &hkeyInterface); if (SUCCEEDED(hr)) { Assert(hkeyInterface); hr = HrRegQueryDword(hkeyInterface, c_szAddressType, &dwType); if (SUCCEEDED(hr)) { if (0 == dwType) { *pAddrType = NORMAL_ADDR; } else { tstring strConfigurationName = c_szAlternate; strConfigurationName += pszGuid;
//assume default is AUTONET_ADDR
*pAddrType = AUTONET_ADDR;
// if ActiveConfigurations contain a string "Alternate_{Interface GUID}"
// then there is customized fall-back settings, otherwise Autonet
vector<tstring *> vstrTmp; hr = HrRegQueryColString( hkeyInterface, c_szActiveConfigurations, &vstrTmp); if (SUCCEEDED(hr)) { for (int i = 0; i < (int)vstrTmp.size(); i++) { if (strConfigurationName == *vstrTmp[i]) { *pAddrType = ALTERNATE_ADDR; break; } } DeleteColString(&vstrTmp); } else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK; } }
} else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { //if the value is not there, assume the default (No autonet)
*pAddrType = NORMAL_ADDR; hr = S_OK; }
RegSafeCloseKey(hkeyInterface); }
return hr; }
HRESULT HrGetAutoNetSetting(REFGUID pGuidId, DHCP_ADDRESS_TYPE * pAddrType) { TraceFileFunc(ttidStatMon);
Assert(pAddrType); *pAddrType = UNKNOWN_ADDR;
WCHAR wszGuid[MAX_PATH]; ::StringFromGUID2(pGuidId, wszGuid, MAX_PATH);
HRESULT hr = S_OK; PIP_ADAPTER_INFO pAdapterInfo = NULL; DWORD dwOutBufLen = 0; DWORD dwRet = ERROR_SUCCESS; dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (dwRet == ERROR_BUFFER_OVERFLOW) { pAdapterInfo = (PIP_ADAPTER_INFO) CoTaskMemAlloc(dwOutBufLen); if (NULL == pAdapterInfo) return E_OUTOFMEMORY; } else if (ERROR_SUCCESS == dwRet) { return E_FAIL; } else { return HRESULT_FROM_WIN32(dwRet); } dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen); if (ERROR_SUCCESS != dwRet) { CoTaskMemFree(pAdapterInfo); return HRESULT_FROM_WIN32(dwRet); } BOOL fFound = FALSE; PIP_ADAPTER_INFO pAdapterInfoEnum = pAdapterInfo; while (pAdapterInfoEnum) { USES_CONVERSION; if (lstrcmp(wszGuid, A2W(pAdapterInfoEnum->AdapterName)) == 0) { fFound = TRUE; break; } pAdapterInfoEnum = pAdapterInfoEnum->Next; } if (fFound) { if (pAdapterInfoEnum->DhcpEnabled) { hr = HrGetAutoNetSetting(wszGuid, pAddrType); } else { *pAddrType = STATIC_ADDR; hr = S_OK; } } else { hr = S_FALSE; }
CoTaskMemFree(pAdapterInfo); return hr; }
void DwordToIPAddrString(DWORD dw, tstring * pstr) { TraceFileFunc(ttidStatMon);
WCHAR szBuff[32] = {0}; Assert(pstr);
_itow((dw & 0xff000000) >> 24, szBuff, 10); *pstr = szBuff; *pstr += L".";
_itow((dw & 0x00ff0000) >> 16, szBuff, 10); *pstr += szBuff; *pstr += L".";
_itow((dw & 0x0000ff00) >> 8, szBuff, 10); *pstr += szBuff; *pstr += L".";
_itow(dw & 0x000000ff, szBuff, 10); *pstr += szBuff; }
|