mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
1457 lines
40 KiB
C
1457 lines
40 KiB
C
/*
|
|
* PROJECT: ReactOS ipconfig utility
|
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
|
* PURPOSE: Display IP info for net adapters
|
|
* COPYRIGHT: Copyright 2005-2006 Ged Murphy <[email protected]>
|
|
*/
|
|
/*
|
|
* TODO:
|
|
* implement registerdns, showclassid, setclassid
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define WIN32_NO_STATUS
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <winnls.h>
|
|
#include <winreg.h>
|
|
#include <iphlpapi.h>
|
|
#include <ndk/rtlfuncs.h>
|
|
#include <inaddr.h>
|
|
#include <windns.h>
|
|
#include <windns_undoc.h>
|
|
#include <dhcpcsdk.h>
|
|
#include <dhcpcapi.h>
|
|
#include <strsafe.h>
|
|
#include <conutils.h>
|
|
|
|
#include "resource.h"
|
|
|
|
typedef struct _RECORDTYPE
|
|
{
|
|
WORD wRecordType;
|
|
PCWSTR pszRecordName;
|
|
} RECORDTYPE, *PRECORDTYPE;
|
|
|
|
#define GUID_LEN 40
|
|
|
|
HINSTANCE hInstance;
|
|
HANDLE ProcessHeap;
|
|
|
|
RECORDTYPE TypeArray[] =
|
|
{
|
|
{DNS_TYPE_ZERO, L"ZERO"},
|
|
{DNS_TYPE_A, L"A"},
|
|
{DNS_TYPE_NS, L"NS"},
|
|
{DNS_TYPE_MD, L"MD"},
|
|
{DNS_TYPE_MF, L"MF"},
|
|
{DNS_TYPE_CNAME, L"CNAME"},
|
|
{DNS_TYPE_SOA, L"SOA"},
|
|
{DNS_TYPE_MB, L"MB"},
|
|
{DNS_TYPE_MG, L"MG"},
|
|
{DNS_TYPE_MR, L"MR"},
|
|
{DNS_TYPE_NULL, L"NULL"},
|
|
{DNS_TYPE_WKS, L"WKS"},
|
|
{DNS_TYPE_PTR, L"PTR"},
|
|
{DNS_TYPE_HINFO, L"HINFO"},
|
|
{DNS_TYPE_MINFO, L"MINFO"},
|
|
{DNS_TYPE_MX, L"MX"},
|
|
{DNS_TYPE_TEXT, L"TXT"},
|
|
{DNS_TYPE_RP, L"RP"},
|
|
{DNS_TYPE_AFSDB, L"AFSDB"},
|
|
{DNS_TYPE_X25, L"X25"},
|
|
{DNS_TYPE_ISDN, L"ISDN"},
|
|
{DNS_TYPE_RT, L"RT"},
|
|
{DNS_TYPE_NSAP, L"NSAP"},
|
|
{DNS_TYPE_NSAPPTR, L"NSAPPTR"},
|
|
{DNS_TYPE_SIG, L"SIG"},
|
|
{DNS_TYPE_KEY, L"KEY"},
|
|
{DNS_TYPE_PX, L"PX"},
|
|
{DNS_TYPE_GPOS, L"GPOS"},
|
|
{DNS_TYPE_AAAA, L"AAAA"},
|
|
{DNS_TYPE_LOC, L"LOC"},
|
|
{DNS_TYPE_NXT, L"NXT"},
|
|
{DNS_TYPE_EID, L"EID"},
|
|
{DNS_TYPE_NIMLOC, L"NIMLOC"},
|
|
{DNS_TYPE_SRV, L"SRV"},
|
|
{DNS_TYPE_ATMA, L"ATMA"},
|
|
{DNS_TYPE_NAPTR, L"NAPTR"},
|
|
{DNS_TYPE_KX, L"KX"},
|
|
{DNS_TYPE_CERT, L"CERT"},
|
|
{DNS_TYPE_A6, L"A6"},
|
|
{DNS_TYPE_DNAME, L"DNAME"},
|
|
{DNS_TYPE_SINK, L"SINK"},
|
|
{DNS_TYPE_OPT, L"OPT"},
|
|
{DNS_TYPE_UINFO, L"UINFO"},
|
|
{DNS_TYPE_UID, L"UID"},
|
|
{DNS_TYPE_GID, L"GID"},
|
|
{DNS_TYPE_UNSPEC, L"UNSPEC"},
|
|
{DNS_TYPE_ADDRS, L"ADDRS"},
|
|
{DNS_TYPE_TKEY, L"TKEY"},
|
|
{DNS_TYPE_TSIG, L"TSIG"},
|
|
{DNS_TYPE_IXFR, L"IXFR"},
|
|
{DNS_TYPE_AXFR, L"AXFR"},
|
|
{DNS_TYPE_MAILB, L"MAILB"},
|
|
{DNS_TYPE_MAILA, L"MAILA"},
|
|
{DNS_TYPE_ALL, L"ALL"},
|
|
{0, NULL}
|
|
};
|
|
|
|
PCWSTR
|
|
GetRecordTypeName(WORD wType)
|
|
{
|
|
static WCHAR szType[8];
|
|
INT i;
|
|
|
|
for (i = 0; ; i++)
|
|
{
|
|
if (TypeArray[i].pszRecordName == NULL)
|
|
break;
|
|
|
|
if (TypeArray[i].wRecordType == wType)
|
|
return TypeArray[i].pszRecordName;
|
|
}
|
|
|
|
_swprintf(szType, L"%hu", wType);
|
|
|
|
return szType;
|
|
}
|
|
|
|
/* print MAC address */
|
|
PCSTR PrintMacAddr(PBYTE Mac)
|
|
{
|
|
static CHAR MacAddr[20];
|
|
|
|
sprintf(MacAddr, "%02X-%02X-%02X-%02X-%02X-%02X",
|
|
Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]);
|
|
|
|
return MacAddr;
|
|
}
|
|
|
|
/* convert time_t to localized string */
|
|
_Ret_opt_z_ PWSTR timeToStr(_In_ time_t TimeStamp)
|
|
{
|
|
struct tm* ptm;
|
|
SYSTEMTIME SystemTime;
|
|
INT DateCchSize, TimeCchSize, TotalCchSize, i;
|
|
PWSTR DateTimeString, psz;
|
|
|
|
/* Convert Unix time to SYSTEMTIME */
|
|
/* localtime_s may be preferred if available */
|
|
ptm = localtime(&TimeStamp);
|
|
if (!ptm)
|
|
{
|
|
return NULL;
|
|
}
|
|
SystemTime.wYear = ptm->tm_year + 1900;
|
|
SystemTime.wMonth = ptm->tm_mon + 1;
|
|
SystemTime.wDay = ptm->tm_mday;
|
|
SystemTime.wHour = ptm->tm_hour;
|
|
SystemTime.wMinute = ptm->tm_min;
|
|
SystemTime.wSecond = ptm->tm_sec;
|
|
|
|
/* Get total size in characters required of buffer */
|
|
DateCchSize = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &SystemTime, NULL, NULL, 0);
|
|
if (!DateCchSize)
|
|
{
|
|
return NULL;
|
|
}
|
|
TimeCchSize = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, NULL, 0);
|
|
if (!TimeCchSize)
|
|
{
|
|
return NULL;
|
|
}
|
|
/* Two terminating null are included, the first one will be replaced by space */
|
|
TotalCchSize = DateCchSize + TimeCchSize;
|
|
|
|
/* Allocate buffer and format datetime string */
|
|
DateTimeString = (PWSTR)HeapAlloc(ProcessHeap, 0, TotalCchSize * sizeof(WCHAR));
|
|
if (!DateTimeString)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* Get date string */
|
|
i = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &SystemTime, NULL, DateTimeString, TotalCchSize);
|
|
if (i)
|
|
{
|
|
/* Append space and move pointer */
|
|
DateTimeString[i - 1] = L' ';
|
|
psz = DateTimeString + i;
|
|
TotalCchSize -= i;
|
|
|
|
/* Get time string */
|
|
if (GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, psz, TotalCchSize))
|
|
{
|
|
return DateTimeString;
|
|
}
|
|
}
|
|
|
|
HeapFree(ProcessHeap, 0, DateTimeString);
|
|
return NULL;
|
|
}
|
|
|
|
VOID
|
|
DoFormatMessage(
|
|
_In_ LONG ErrorCode)
|
|
{
|
|
if (ErrorCode == 0)
|
|
ErrorCode = GetLastError();
|
|
|
|
ConMsgPuts(StdOut,
|
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ErrorCode,
|
|
LANG_USER_DEFAULT);
|
|
}
|
|
|
|
PWSTR
|
|
GetUnicodeAdapterName(
|
|
_In_ PSTR pszAnsiName)
|
|
{
|
|
PWSTR pszUnicodeName;
|
|
size_t i, len;
|
|
|
|
len = strlen(pszAnsiName);
|
|
pszUnicodeName = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
|
if (pszUnicodeName == NULL)
|
|
return NULL;
|
|
|
|
for (i = 0; i < len; i++)
|
|
pszUnicodeName[i] = (WCHAR)pszAnsiName[i];
|
|
pszUnicodeName[i] = UNICODE_NULL;
|
|
|
|
return pszUnicodeName;
|
|
}
|
|
|
|
VOID
|
|
GetAdapterFriendlyName(
|
|
_In_ PSTR lpClass,
|
|
_In_ DWORD cchFriendlyNameLength,
|
|
_Out_ PWSTR pszFriendlyName)
|
|
{
|
|
HKEY hKey = NULL;
|
|
CHAR Path[256];
|
|
PCSTR PrePath = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
|
|
PCSTR PostPath = "\\Connection";
|
|
size_t PathSize;
|
|
DWORD dwType;
|
|
DWORD dwDataSize;
|
|
|
|
/* don't overflow the buffer */
|
|
PathSize = strlen(PrePath) + strlen(lpClass) + strlen(PostPath) + 1;
|
|
if (PathSize > _countof(Path))
|
|
return;
|
|
|
|
sprintf(Path, "%s%s%s", PrePath, lpClass, PostPath);
|
|
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
|
Path,
|
|
0,
|
|
KEY_READ,
|
|
&hKey) == ERROR_SUCCESS)
|
|
{
|
|
dwDataSize = cchFriendlyNameLength * sizeof(WCHAR);
|
|
RegQueryValueExW(hKey,
|
|
L"Name",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)pszFriendlyName,
|
|
&dwDataSize);
|
|
}
|
|
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
VOID
|
|
GetInterfaceFriendlyName(
|
|
_In_ PCWSTR lpDeviceName,
|
|
_In_ DWORD cchFriendlyNameLength,
|
|
_Out_ PWSTR pszFriendlyName)
|
|
{
|
|
HKEY hKey = NULL;
|
|
WCHAR Path[256];
|
|
PCWSTR PrePath = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
|
|
PCWSTR PostPath = L"\\Connection";
|
|
PCWSTR DevicePrefix = L"\\DEVICE\\TCPIP_";
|
|
size_t PathSize;
|
|
DWORD dwType;
|
|
DWORD dwDataSize;
|
|
|
|
size_t dwPrefixLength = wcslen(DevicePrefix);
|
|
|
|
/* don't overflow the buffer */
|
|
PathSize = wcslen(PrePath) + wcslen(lpDeviceName) - dwPrefixLength + wcslen(PostPath) + 1;
|
|
if (PathSize > _countof(Path))
|
|
return;
|
|
|
|
_swprintf(Path, L"%s%s%s", PrePath, &lpDeviceName[dwPrefixLength], PostPath);
|
|
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
Path,
|
|
0,
|
|
KEY_READ,
|
|
&hKey) == ERROR_SUCCESS)
|
|
{
|
|
dwDataSize = cchFriendlyNameLength * sizeof(WCHAR);
|
|
RegQueryValueExW(hKey,
|
|
L"Name",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)pszFriendlyName,
|
|
&dwDataSize);
|
|
}
|
|
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintAdapterDescription(PSTR lpClass)
|
|
{
|
|
HKEY hBaseKey = NULL;
|
|
HKEY hClassKey = NULL;
|
|
PSTR lpKeyClass = NULL;
|
|
PSTR lpConDesc = NULL;
|
|
PWSTR lpPath = NULL;
|
|
WCHAR szPrePath[] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\";
|
|
DWORD dwType;
|
|
DWORD dwDataSize;
|
|
INT i;
|
|
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
szPrePath,
|
|
0,
|
|
KEY_READ,
|
|
&hBaseKey) != ERROR_SUCCESS)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 0; ; i++)
|
|
{
|
|
size_t PathSize;
|
|
LONG Status;
|
|
WCHAR szName[10];
|
|
DWORD NameLen = 9;
|
|
|
|
if ((Status = RegEnumKeyExW(hBaseKey,
|
|
i,
|
|
szName,
|
|
&NameLen,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != ERROR_SUCCESS)
|
|
{
|
|
if (Status == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
DoFormatMessage(Status);
|
|
lpConDesc = NULL;
|
|
goto CLEANUP;
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
|
|
PathSize = wcslen(szPrePath) + wcslen(szName) + 1;
|
|
lpPath = (PWSTR)HeapAlloc(ProcessHeap,
|
|
0,
|
|
PathSize * sizeof(WCHAR));
|
|
if (lpPath == NULL)
|
|
goto CLEANUP;
|
|
|
|
_swprintf(lpPath, L"%s%s", szPrePath, szName);
|
|
|
|
//MessageBox(NULL, lpPath, NULL, 0);
|
|
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
lpPath,
|
|
0,
|
|
KEY_READ,
|
|
&hClassKey) != ERROR_SUCCESS)
|
|
{
|
|
goto CLEANUP;
|
|
}
|
|
|
|
HeapFree(ProcessHeap, 0, lpPath);
|
|
lpPath = NULL;
|
|
|
|
if (RegQueryValueExA(hClassKey,
|
|
"NetCfgInstanceId",
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwDataSize) == ERROR_SUCCESS)
|
|
{
|
|
lpKeyClass = (PSTR)HeapAlloc(ProcessHeap,
|
|
0,
|
|
dwDataSize);
|
|
if (lpKeyClass == NULL)
|
|
goto CLEANUP;
|
|
|
|
if (RegQueryValueExA(hClassKey,
|
|
"NetCfgInstanceId",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)lpKeyClass,
|
|
&dwDataSize) != ERROR_SUCCESS)
|
|
{
|
|
HeapFree(ProcessHeap, 0, lpKeyClass);
|
|
lpKeyClass = NULL;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
continue;
|
|
|
|
if (!strcmp(lpClass, lpKeyClass))
|
|
{
|
|
HeapFree(ProcessHeap, 0, lpKeyClass);
|
|
lpKeyClass = NULL;
|
|
|
|
if (RegQueryValueExA(hClassKey,
|
|
"DriverDesc",
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwDataSize) == ERROR_SUCCESS)
|
|
{
|
|
lpConDesc = (PSTR)HeapAlloc(ProcessHeap,
|
|
0,
|
|
dwDataSize);
|
|
if (lpConDesc != NULL)
|
|
{
|
|
if (RegQueryValueExA(hClassKey,
|
|
"DriverDesc",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)lpConDesc,
|
|
&dwDataSize) == ERROR_SUCCESS)
|
|
{
|
|
printf("%s", lpConDesc);
|
|
}
|
|
|
|
HeapFree(ProcessHeap, 0, lpConDesc);
|
|
lpConDesc = NULL;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
if (hBaseKey != NULL)
|
|
RegCloseKey(hBaseKey);
|
|
if (hClassKey != NULL)
|
|
RegCloseKey(hClassKey);
|
|
if (lpPath != NULL)
|
|
HeapFree(ProcessHeap, 0, lpPath);
|
|
if (lpKeyClass != NULL)
|
|
HeapFree(ProcessHeap, 0, lpKeyClass);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintNodeType(
|
|
_In_ UINT NodeType)
|
|
{
|
|
switch (NodeType)
|
|
{
|
|
case BROADCAST_NODETYPE:
|
|
ConResPrintf(StdOut, IDS_NODETYPEBCAST);
|
|
break;
|
|
|
|
case PEER_TO_PEER_NODETYPE:
|
|
ConResPrintf(StdOut, IDS_NODETYPEP2P);
|
|
break;
|
|
|
|
case MIXED_NODETYPE:
|
|
ConResPrintf(StdOut, IDS_NODETYPEMIXED);
|
|
break;
|
|
|
|
case HYBRID_NODETYPE:
|
|
ConResPrintf(StdOut, IDS_NODETYPEHYBRID);
|
|
break;
|
|
|
|
default :
|
|
ConResPrintf(StdOut, IDS_NODETYPEUNKNOWN);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintAdapterTypeAndName(
|
|
PIP_ADAPTER_INFO pAdapterInfo)
|
|
{
|
|
WCHAR szFriendlyName[MAX_PATH];
|
|
|
|
GetAdapterFriendlyName(pAdapterInfo->AdapterName, MAX_PATH, szFriendlyName);
|
|
|
|
switch (pAdapterInfo->Type)
|
|
{
|
|
case MIB_IF_TYPE_OTHER:
|
|
ConResPrintf(StdOut, IDS_OTHER, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_ETHERNET:
|
|
ConResPrintf(StdOut, IDS_ETH, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_TOKENRING:
|
|
ConResPrintf(StdOut, IDS_TOKEN, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_FDDI:
|
|
ConResPrintf(StdOut, IDS_FDDI, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_PPP:
|
|
ConResPrintf(StdOut, IDS_PPP, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_LOOPBACK:
|
|
ConResPrintf(StdOut, IDS_LOOP, szFriendlyName);
|
|
break;
|
|
|
|
case MIB_IF_TYPE_SLIP:
|
|
ConResPrintf(StdOut, IDS_SLIP, szFriendlyName);
|
|
break;
|
|
|
|
case IF_TYPE_IEEE80211:
|
|
ConResPrintf(StdOut, IDS_WIFI, szFriendlyName);
|
|
break;
|
|
|
|
default:
|
|
ConResPrintf(StdOut, IDS_UNKNOWNADAPTER, szFriendlyName);
|
|
break;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ShowInfo(
|
|
BOOL bShowHeader,
|
|
BOOL bAll)
|
|
{
|
|
MIB_IFROW mibEntry;
|
|
PIP_ADAPTER_INFO pAdapterInfo = NULL;
|
|
PIP_ADAPTER_INFO pAdapter = NULL;
|
|
ULONG adaptOutBufLen = 0;
|
|
PFIXED_INFO pFixedInfo = NULL;
|
|
ULONG netOutBufLen = 0;
|
|
PIP_PER_ADAPTER_INFO pPerAdapterInfo = NULL;
|
|
ULONG ulPerAdapterInfoLength = 0;
|
|
PSTR pszDomainName = NULL;
|
|
DWORD dwDomainNameSize = 0;
|
|
ULONG ret = 0;
|
|
|
|
GetComputerNameExA(ComputerNameDnsDomain,
|
|
NULL,
|
|
&dwDomainNameSize);
|
|
if (dwDomainNameSize > 0)
|
|
{
|
|
pszDomainName = HeapAlloc(ProcessHeap,
|
|
0,
|
|
dwDomainNameSize * sizeof(CHAR));
|
|
if (pszDomainName != NULL)
|
|
GetComputerNameExA(ComputerNameDnsDomain,
|
|
pszDomainName,
|
|
&dwDomainNameSize);
|
|
}
|
|
|
|
/* call GetAdaptersInfo to obtain the adapter info */
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret == ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
|
|
if (pAdapterInfo == NULL)
|
|
goto done;
|
|
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ret != ERROR_NO_DATA)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
/* call GetNetworkParams to obtain the network info */
|
|
if (GetNetworkParams(pFixedInfo, &netOutBufLen) == ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
pFixedInfo = (FIXED_INFO *)HeapAlloc(ProcessHeap, 0, netOutBufLen);
|
|
if (pFixedInfo == NULL)
|
|
{
|
|
goto done;
|
|
}
|
|
if (GetNetworkParams(pFixedInfo, &netOutBufLen) != NO_ERROR)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
|
|
pAdapter = pAdapterInfo;
|
|
|
|
if (bShowHeader)
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
if (bAll)
|
|
{
|
|
ConResPrintf(StdOut, IDS_HOSTNAME, pFixedInfo->HostName);
|
|
ConResPrintf(StdOut, IDS_PRIMARYDNSSUFFIX, (pszDomainName != NULL) ? pszDomainName : "");
|
|
|
|
PrintNodeType(pFixedInfo->NodeType);
|
|
|
|
if (pFixedInfo->EnableRouting)
|
|
ConResPrintf(StdOut, IDS_IPROUTINGYES);
|
|
else
|
|
ConResPrintf(StdOut, IDS_IPROUTINGNO);
|
|
|
|
if (pAdapter && pAdapter->HaveWins)
|
|
ConResPrintf(StdOut, IDS_WINSPROXYYES);
|
|
else
|
|
ConResPrintf(StdOut, IDS_WINSPROXYNO);
|
|
|
|
if (pszDomainName != NULL && pszDomainName[0] != 0)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSSUFFIXLIST, pszDomainName);
|
|
ConResPrintf(StdOut, IDS_EMPTYLINE, pFixedInfo->DomainName);
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSSUFFIXLIST, pFixedInfo->DomainName);
|
|
}
|
|
}
|
|
|
|
while (pAdapter)
|
|
{
|
|
BOOLEAN bConnected = TRUE;
|
|
|
|
mibEntry.dwIndex = pAdapter->Index;
|
|
GetIfEntry(&mibEntry);
|
|
|
|
PrintAdapterTypeAndName(pAdapter);
|
|
|
|
if (GetPerAdapterInfo(pAdapter->Index, pPerAdapterInfo, &ulPerAdapterInfoLength) == ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
pPerAdapterInfo = (PIP_PER_ADAPTER_INFO)HeapAlloc(ProcessHeap, 0, ulPerAdapterInfoLength);
|
|
if (pPerAdapterInfo != NULL)
|
|
{
|
|
GetPerAdapterInfo(pAdapter->Index, pPerAdapterInfo, &ulPerAdapterInfoLength);
|
|
}
|
|
}
|
|
|
|
/* check if the adapter is connected to the media */
|
|
if (mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED && mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL)
|
|
{
|
|
bConnected = FALSE;
|
|
ConResPrintf(StdOut, IDS_MEDIADISCONNECTED);
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_CONNECTIONDNSSUFFIX, pFixedInfo->DomainName);
|
|
}
|
|
|
|
if (bAll)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DESCRIPTION);
|
|
PrintAdapterDescription(pAdapter->AdapterName);
|
|
printf("\n");
|
|
|
|
ConResPrintf(StdOut, IDS_PHYSICALADDRESS, PrintMacAddr(pAdapter->Address));
|
|
|
|
if (bConnected)
|
|
{
|
|
if (pAdapter->DhcpEnabled)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPYES);
|
|
|
|
if (pPerAdapterInfo != NULL)
|
|
{
|
|
if (pPerAdapterInfo->AutoconfigEnabled)
|
|
ConResPrintf(StdOut, IDS_AUTOCONFIGYES);
|
|
else
|
|
ConResPrintf(StdOut, IDS_AUTOCONFIGNO);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNO);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bConnected)
|
|
{
|
|
HeapFree(ProcessHeap, 0, pPerAdapterInfo);
|
|
pPerAdapterInfo = NULL;
|
|
pAdapter = pAdapter->Next;
|
|
continue;
|
|
}
|
|
|
|
ConResPrintf(StdOut, IDS_IPADDRESS, pAdapter->IpAddressList.IpAddress.String);
|
|
ConResPrintf(StdOut, IDS_SUBNETMASK, pAdapter->IpAddressList.IpMask.String);
|
|
|
|
if (strcmp(pAdapter->GatewayList.IpAddress.String, "0.0.0.0"))
|
|
ConResPrintf(StdOut, IDS_DEFAULTGATEWAY, pAdapter->GatewayList.IpAddress.String);
|
|
else
|
|
ConResPrintf(StdOut, IDS_DEFAULTGATEWAY, "");
|
|
|
|
if (bAll)
|
|
{
|
|
PIP_ADDR_STRING pIPAddr;
|
|
|
|
if (pAdapter->DhcpEnabled)
|
|
ConResPrintf(StdOut, IDS_DHCPSERVER, pAdapter->DhcpServer.IpAddress.String);
|
|
|
|
ConResPrintf(StdOut, IDS_DNSSERVERS, pFixedInfo->DnsServerList.IpAddress.String);
|
|
pIPAddr = pFixedInfo->DnsServerList.Next;
|
|
while (pIPAddr)
|
|
{
|
|
ConResPrintf(StdOut, IDS_EMPTYLINE, pIPAddr->IpAddress.String);
|
|
pIPAddr = pIPAddr->Next;
|
|
}
|
|
|
|
if (pAdapter->HaveWins)
|
|
{
|
|
ConResPrintf(StdOut, IDS_PRIMARYWINSSERVER, pAdapter->PrimaryWinsServer.IpAddress.String);
|
|
ConResPrintf(StdOut, IDS_SECONDARYWINSSERVER, pAdapter->SecondaryWinsServer.IpAddress.String);
|
|
}
|
|
|
|
if (pAdapter->DhcpEnabled && strcmp(pAdapter->DhcpServer.IpAddress.String, "255.255.255.255"))
|
|
{
|
|
PWSTR DateTimeString;
|
|
DateTimeString = timeToStr(pAdapter->LeaseObtained);
|
|
ConResPrintf(StdOut, IDS_LEASEOBTAINED, DateTimeString ? DateTimeString : L"N/A");
|
|
if (DateTimeString)
|
|
{
|
|
HeapFree(ProcessHeap, 0, DateTimeString);
|
|
}
|
|
DateTimeString = timeToStr(pAdapter->LeaseExpires);
|
|
ConResPrintf(StdOut, IDS_LEASEEXPIRES, DateTimeString ? DateTimeString : L"N/A");
|
|
if (DateTimeString)
|
|
{
|
|
HeapFree(ProcessHeap, 0, DateTimeString);
|
|
}
|
|
}
|
|
}
|
|
|
|
HeapFree(ProcessHeap, 0, pPerAdapterInfo);
|
|
pPerAdapterInfo = NULL;
|
|
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
|
|
done:
|
|
if (pszDomainName)
|
|
HeapFree(ProcessHeap, 0, pszDomainName);
|
|
if (pFixedInfo)
|
|
HeapFree(ProcessHeap, 0, pFixedInfo);
|
|
if (pAdapterInfo)
|
|
HeapFree(ProcessHeap, 0, pAdapterInfo);
|
|
}
|
|
|
|
static
|
|
BOOL
|
|
MatchWildcard(
|
|
_In_ PWSTR pszExpression,
|
|
_In_ PWSTR pszName)
|
|
{
|
|
WCHAR *pCharE, *pCharN, charE, charN;
|
|
|
|
if (pszExpression == NULL)
|
|
return TRUE;
|
|
|
|
if (pszName == NULL)
|
|
return FALSE;
|
|
|
|
pCharE = pszExpression;
|
|
pCharN = pszName;
|
|
while (*pCharE != UNICODE_NULL)
|
|
{
|
|
charE = towlower(*pCharE);
|
|
charN = towlower(*pCharN);
|
|
|
|
if (charE == L'*')
|
|
{
|
|
if (*(pCharE + 1) != charN)
|
|
pCharN++;
|
|
else
|
|
pCharE++;
|
|
}
|
|
else if (charE == L'?')
|
|
{
|
|
pCharE++;
|
|
pCharN++;
|
|
}
|
|
else if (charE == charN)
|
|
{
|
|
pCharE++;
|
|
pCharN++;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
Release(
|
|
PWSTR pszAdapterName)
|
|
{
|
|
PIP_ADAPTER_INFO pAdapterInfo = NULL;
|
|
PIP_ADAPTER_INFO pAdapter = NULL;
|
|
ULONG adaptOutBufLen = 0;
|
|
ULONG ret = 0;
|
|
WCHAR szFriendlyName[MAX_PATH];
|
|
WCHAR szUnicodeAdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
|
|
MIB_IFROW mibEntry;
|
|
BOOL bFoundAdapter = FALSE;
|
|
DWORD dwVersion;
|
|
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
/* call GetAdaptersInfo to obtain the adapter info */
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
DoFormatMessage(ret);
|
|
return;
|
|
}
|
|
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
|
|
if (pAdapterInfo == NULL)
|
|
{
|
|
DoFormatMessage(ERROR_NOT_ENOUGH_MEMORY);
|
|
return;
|
|
}
|
|
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
|
|
DhcpCApiInitialize(&dwVersion);
|
|
|
|
pAdapter = pAdapterInfo;
|
|
|
|
while (pAdapter)
|
|
{
|
|
GetAdapterFriendlyName(pAdapter->AdapterName, MAX_PATH, szFriendlyName);
|
|
|
|
if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
|
|
{
|
|
bFoundAdapter = TRUE;
|
|
|
|
mibEntry.dwIndex = pAdapter->Index;
|
|
GetIfEntry(&mibEntry);
|
|
|
|
if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
|
|
mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
|
|
{
|
|
if (pAdapter->DhcpEnabled)
|
|
{
|
|
if (strcmp(pAdapter->IpAddressList.IpAddress.String, "0.0.0.0"))
|
|
{
|
|
mbstowcs(szUnicodeAdapterName, pAdapter->AdapterName, strlen(pAdapter->AdapterName) + 1);
|
|
|
|
/* Call DhcpReleaseParameters to release the IP address on the specified adapter. */
|
|
ret = DhcpReleaseParameters(szUnicodeAdapterName);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPRELEASEERROR, szFriendlyName);
|
|
DoFormatMessage(ret);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPRELEASED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOTENABLED, szFriendlyName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOTCONNECTED, szFriendlyName);
|
|
}
|
|
}
|
|
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
|
|
DhcpCApiCleanup();
|
|
|
|
if (bFoundAdapter == FALSE)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOADAPTER);
|
|
}
|
|
else
|
|
{
|
|
ShowInfo(FALSE, FALSE);
|
|
}
|
|
|
|
done:
|
|
if (pAdapterInfo)
|
|
HeapFree(ProcessHeap, 0, pAdapterInfo);
|
|
}
|
|
|
|
VOID
|
|
Renew(
|
|
PWSTR pszAdapterName)
|
|
{
|
|
PIP_ADAPTER_INFO pAdapterInfo = NULL;
|
|
PIP_ADAPTER_INFO pAdapter = NULL;
|
|
ULONG adaptOutBufLen = 0;
|
|
ULONG ret = 0;
|
|
WCHAR szFriendlyName[MAX_PATH];
|
|
WCHAR szUnicodeAdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
|
|
MIB_IFROW mibEntry;
|
|
BOOL bFoundAdapter = FALSE;
|
|
DWORD dwVersion;
|
|
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
/* call GetAdaptersInfo to obtain the adapter info */
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
DoFormatMessage(ret);
|
|
return;
|
|
}
|
|
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
|
|
if (pAdapterInfo == NULL)
|
|
{
|
|
DoFormatMessage(ERROR_NOT_ENOUGH_MEMORY);
|
|
return;
|
|
}
|
|
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
|
|
DhcpCApiInitialize(&dwVersion);
|
|
|
|
pAdapter = pAdapterInfo;
|
|
|
|
while (pAdapter)
|
|
{
|
|
GetAdapterFriendlyName(pAdapter->AdapterName, MAX_PATH, szFriendlyName);
|
|
|
|
if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
|
|
{
|
|
bFoundAdapter = TRUE;
|
|
|
|
mibEntry.dwIndex = pAdapter->Index;
|
|
GetIfEntry(&mibEntry);
|
|
|
|
if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
|
|
mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
|
|
{
|
|
if (pAdapter->DhcpEnabled)
|
|
{
|
|
mbstowcs(szUnicodeAdapterName, pAdapter->AdapterName, strlen(pAdapter->AdapterName) + 1);
|
|
|
|
/* Call DhcpAcquireParameters to renew the IP address on the specified adapter. */
|
|
ret = DhcpAcquireParameters(szUnicodeAdapterName);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPRENEWERROR, szFriendlyName);
|
|
DoFormatMessage(ret);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOTENABLED, szFriendlyName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOTCONNECTED, szFriendlyName);
|
|
}
|
|
}
|
|
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
|
|
DhcpCApiCleanup();
|
|
|
|
if (bFoundAdapter == FALSE)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOADAPTER);
|
|
}
|
|
else
|
|
{
|
|
ShowInfo(FALSE, FALSE);
|
|
}
|
|
|
|
done:
|
|
if (pAdapterInfo)
|
|
HeapFree(ProcessHeap, 0, pAdapterInfo);
|
|
}
|
|
|
|
VOID
|
|
FlushDns(VOID)
|
|
{
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
if (DnsFlushResolverCache())
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSFLUSHSUCCESS);
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSFLUSHERROR);
|
|
DoFormatMessage(GetLastError());
|
|
}
|
|
}
|
|
|
|
VOID
|
|
RegisterDns(VOID)
|
|
{
|
|
/* FIXME */
|
|
printf("\nSorry /registerdns is not implemented yet\n");
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DisplayDnsRecord(
|
|
PWSTR pszName,
|
|
WORD wType)
|
|
{
|
|
PDNS_RECORDW pQueryResults = NULL, pThisRecord, pNextRecord;
|
|
WCHAR szBuffer[48];
|
|
IN_ADDR Addr4;
|
|
IN6_ADDR Addr6;
|
|
DNS_STATUS Status;
|
|
|
|
ConResPrintf(StdOut, IDS_DNSNAME, pszName);
|
|
ConResPrintf(StdOut, IDS_DNSLINE);
|
|
|
|
pQueryResults = NULL;
|
|
Status = DnsQuery_W(pszName,
|
|
wType,
|
|
DNS_QUERY_NO_WIRE_QUERY,
|
|
NULL,
|
|
(PDNS_RECORD *)&pQueryResults,
|
|
NULL);
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
if (Status == DNS_ERROR_RCODE_NAME_ERROR)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSNONAME);
|
|
}
|
|
else if (Status == DNS_INFO_NO_RECORDS)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DNSNORECORD, GetRecordTypeName(wType));
|
|
}
|
|
return;
|
|
}
|
|
|
|
pThisRecord = pQueryResults;
|
|
while (pThisRecord != NULL)
|
|
{
|
|
pNextRecord = pThisRecord->pNext;
|
|
|
|
ConResPrintf(StdOut, IDS_DNSRECORDNAME, pThisRecord->pName);
|
|
ConResPrintf(StdOut, IDS_DNSRECORDTYPE, pThisRecord->wType);
|
|
ConResPrintf(StdOut, IDS_DNSRECORDTTL, pThisRecord->dwTtl);
|
|
ConResPrintf(StdOut, IDS_DNSRECORDLENGTH, pThisRecord->wDataLength);
|
|
|
|
switch (pThisRecord->Flags.S.Section)
|
|
{
|
|
case DnsSectionQuestion:
|
|
ConResPrintf(StdOut, IDS_DNSSECTIONQUESTION);
|
|
break;
|
|
|
|
case DnsSectionAnswer:
|
|
ConResPrintf(StdOut, IDS_DNSSECTIONANSWER);
|
|
break;
|
|
|
|
case DnsSectionAuthority:
|
|
ConResPrintf(StdOut, IDS_DNSSECTIONAUTHORITY);
|
|
break;
|
|
|
|
case DnsSectionAdditional:
|
|
ConResPrintf(StdOut, IDS_DNSSECTIONADDITIONAL);
|
|
break;
|
|
}
|
|
|
|
switch (pThisRecord->wType)
|
|
{
|
|
case DNS_TYPE_A:
|
|
Addr4.S_un.S_addr = pThisRecord->Data.A.IpAddress;
|
|
RtlIpv4AddressToStringW(&Addr4, szBuffer);
|
|
ConResPrintf(StdOut, IDS_DNSTYPEA, szBuffer);
|
|
break;
|
|
|
|
case DNS_TYPE_NS:
|
|
ConResPrintf(StdOut, IDS_DNSTYPENS, pThisRecord->Data.NS.pNameHost);
|
|
break;
|
|
|
|
case DNS_TYPE_CNAME:
|
|
ConResPrintf(StdOut, IDS_DNSTYPECNAME, pThisRecord->Data.CNAME.pNameHost);
|
|
break;
|
|
|
|
case DNS_TYPE_SOA:
|
|
ConResPrintf(StdOut, IDS_DNSTYPESOA1,
|
|
pThisRecord->Data.SOA.pNamePrimaryServer,
|
|
pThisRecord->Data.SOA.pNameAdministrator,
|
|
pThisRecord->Data.SOA.dwSerialNo);
|
|
ConResPrintf(StdOut, IDS_DNSTYPESOA2,
|
|
pThisRecord->Data.SOA.dwRefresh,
|
|
pThisRecord->Data.SOA.dwRetry,
|
|
pThisRecord->Data.SOA.dwExpire,
|
|
pThisRecord->Data.SOA.dwDefaultTtl);
|
|
break;
|
|
|
|
case DNS_TYPE_PTR:
|
|
ConResPrintf(StdOut, IDS_DNSTYPEPTR, pThisRecord->Data.PTR.pNameHost);
|
|
break;
|
|
|
|
case DNS_TYPE_MX:
|
|
ConResPrintf(StdOut, IDS_DNSTYPEMX,
|
|
pThisRecord->Data.MX.pNameExchange,
|
|
pThisRecord->Data.MX.wPreference,
|
|
pThisRecord->Data.MX.Pad);
|
|
break;
|
|
|
|
case DNS_TYPE_AAAA:
|
|
RtlCopyMemory(&Addr6, &pThisRecord->Data.AAAA.Ip6Address, sizeof(Addr6));
|
|
RtlIpv6AddressToStringW(&Addr6, szBuffer);
|
|
ConResPrintf(StdOut, IDS_DNSTYPEAAAA, szBuffer);
|
|
break;
|
|
|
|
case DNS_TYPE_ATMA:
|
|
ConResPrintf(StdOut, IDS_DNSTYPEATMA);
|
|
break;
|
|
|
|
case DNS_TYPE_SRV:
|
|
ConResPrintf(StdOut, IDS_DNSTYPESRV,
|
|
pThisRecord->Data.SRV.pNameTarget,
|
|
pThisRecord->Data.SRV.wPriority,
|
|
pThisRecord->Data.SRV.wWeight,
|
|
pThisRecord->Data.SRV.wPort);
|
|
break;
|
|
}
|
|
ConPuts(StdOut, L"\n\n");
|
|
|
|
pThisRecord = pNextRecord;
|
|
}
|
|
|
|
DnsRecordListFree((PDNS_RECORD)pQueryResults, DnsFreeRecordList);
|
|
}
|
|
|
|
VOID
|
|
DisplayDns(VOID)
|
|
{
|
|
PDNS_CACHE_ENTRY DnsEntry = NULL, pThisEntry, pNextEntry;
|
|
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
if (!DnsGetCacheDataTable(&DnsEntry))
|
|
{
|
|
DoFormatMessage(GetLastError());
|
|
return;
|
|
}
|
|
|
|
if (DnsEntry == NULL)
|
|
return;
|
|
|
|
pThisEntry = DnsEntry;
|
|
while (pThisEntry != NULL)
|
|
{
|
|
pNextEntry = pThisEntry->pNext;
|
|
|
|
if (pThisEntry->wType1 != DNS_TYPE_ZERO)
|
|
DisplayDnsRecord(pThisEntry->pszName, pThisEntry->wType1);
|
|
|
|
if (pThisEntry->wType2 != DNS_TYPE_ZERO)
|
|
DisplayDnsRecord(pThisEntry->pszName, pThisEntry->wType2);
|
|
|
|
if (pThisEntry->pszName)
|
|
LocalFree(pThisEntry->pszName);
|
|
LocalFree(pThisEntry);
|
|
|
|
pThisEntry = pNextEntry;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ShowClassId(
|
|
PWSTR pszAdapterName)
|
|
{
|
|
printf("\nSorry /showclassid adapter is not implemented yet\n");
|
|
}
|
|
|
|
VOID
|
|
SetClassId(
|
|
PWSTR pszAdapterName,
|
|
PWSTR pszClassId)
|
|
{
|
|
PIP_ADAPTER_INFO pAdapterInfo = NULL;
|
|
PIP_ADAPTER_INFO pAdapter = NULL, pFoundAdapter = NULL;
|
|
ULONG adaptOutBufLen = 0;
|
|
ULONG ret = 0;
|
|
WCHAR szFriendlyName[MAX_PATH];
|
|
WCHAR szKeyName[256];
|
|
WCHAR szUnicodeAdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
|
|
MIB_IFROW mibEntry;
|
|
HKEY hKey;
|
|
DHCP_PNP_EVENT PnpEvent;
|
|
|
|
ConResPrintf(StdOut, IDS_HEADER);
|
|
|
|
/* call GetAdaptersInfo to obtain the adapter info */
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
DoFormatMessage(ret);
|
|
return;
|
|
}
|
|
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
|
|
if (pAdapterInfo == NULL)
|
|
{
|
|
DoFormatMessage(ERROR_NOT_ENOUGH_MEMORY);
|
|
return;
|
|
}
|
|
|
|
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
|
|
if (ret != NO_ERROR)
|
|
{
|
|
DoFormatMessage(0);
|
|
goto done;
|
|
}
|
|
|
|
pAdapter = pAdapterInfo;
|
|
while (pAdapter)
|
|
{
|
|
GetAdapterFriendlyName(pAdapter->AdapterName, MAX_PATH, szFriendlyName);
|
|
|
|
if (MatchWildcard(pszAdapterName, szFriendlyName))
|
|
{
|
|
mibEntry.dwIndex = pAdapter->Index;
|
|
GetIfEntry(&mibEntry);
|
|
|
|
if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
|
|
mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
|
|
{
|
|
pFoundAdapter = pAdapter;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
|
|
if (pFoundAdapter)
|
|
{
|
|
_swprintf(szKeyName,
|
|
L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%S",
|
|
pFoundAdapter->AdapterName);
|
|
|
|
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
szKeyName,
|
|
0,
|
|
KEY_WRITE,
|
|
&hKey);
|
|
if (ret != ERROR_SUCCESS)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPSETIDERROR, szFriendlyName);
|
|
DoFormatMessage(ret);
|
|
goto done;
|
|
}
|
|
|
|
if (pszClassId == NULL)
|
|
pszClassId = L"";
|
|
|
|
ret = RegSetValueExW(hKey,
|
|
L"DhcpClassId",
|
|
0, REG_SZ,
|
|
(PBYTE)pszClassId,
|
|
(DWORD)((wcslen(pszClassId) + 1) * sizeof(WCHAR)));
|
|
RegCloseKey(hKey);
|
|
if (ret != ERROR_SUCCESS)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPSETIDERROR, szFriendlyName);
|
|
DoFormatMessage(ret);
|
|
goto done;
|
|
}
|
|
|
|
mbstowcs(szUnicodeAdapterName, pFoundAdapter->AdapterName, strlen(pFoundAdapter->AdapterName) + 1);
|
|
|
|
ZeroMemory(&PnpEvent, sizeof(PnpEvent));
|
|
PnpEvent.Unknown5 = 1;
|
|
|
|
ret = DhcpHandlePnPEvent(0,
|
|
1,
|
|
szUnicodeAdapterName,
|
|
&PnpEvent,
|
|
0);
|
|
if (ret != ERROR_SUCCESS)
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPSETIDERROR, szFriendlyName);
|
|
DoFormatMessage(ret);
|
|
goto done;
|
|
}
|
|
|
|
ConResPrintf(StdOut, IDS_DHCPSETIDSUCCESS, szFriendlyName);
|
|
}
|
|
else
|
|
{
|
|
ConResPrintf(StdOut, IDS_DHCPNOADAPTER);
|
|
}
|
|
|
|
done:
|
|
if (pAdapterInfo)
|
|
HeapFree(ProcessHeap, 0, pAdapterInfo);
|
|
}
|
|
|
|
VOID
|
|
Usage(
|
|
_In_ BOOL Error)
|
|
{
|
|
if (Error)
|
|
ConResPrintf(StdOut, IDS_CMDLINEERROR);
|
|
ConResPrintf(StdOut, IDS_USAGE);
|
|
}
|
|
|
|
int wmain(int argc, wchar_t *argv[])
|
|
{
|
|
BOOL DoUsage=FALSE;
|
|
BOOL DoAll=FALSE;
|
|
BOOL DoRelease=FALSE;
|
|
BOOL DoRenew=FALSE;
|
|
BOOL DoFlushdns=FALSE;
|
|
BOOL DoRegisterdns=FALSE;
|
|
BOOL DoDisplaydns=FALSE;
|
|
BOOL DoShowclassid=FALSE;
|
|
BOOL DoSetclassid=FALSE;
|
|
|
|
/* Initialize the Console Standard Streams */
|
|
ConInitStdStreams();
|
|
|
|
hInstance = GetModuleHandle(NULL);
|
|
ProcessHeap = GetProcessHeap();
|
|
|
|
/* Parse command line for options we have been given. */
|
|
if ((argc > 1) && (argv[1][0] == L'/' || argv[1][0] == L'-'))
|
|
{
|
|
if (!_wcsicmp(&argv[1][1], L"?"))
|
|
{
|
|
DoUsage = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"ALL", wcslen(&argv[1][1])))
|
|
{
|
|
DoAll = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"RELEASE", wcslen(&argv[1][1])))
|
|
{
|
|
DoRelease = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"RENEW", wcslen(&argv[1][1])))
|
|
{
|
|
DoRenew = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"FLUSHDNS", wcslen(&argv[1][1])))
|
|
{
|
|
DoFlushdns = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"FLUSHREGISTERDNS", wcslen(&argv[1][1])))
|
|
{
|
|
DoRegisterdns = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"DISPLAYDNS", wcslen(&argv[1][1])))
|
|
{
|
|
DoDisplaydns = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"SHOWCLASSID", wcslen(&argv[1][1])))
|
|
{
|
|
DoShowclassid = TRUE;
|
|
}
|
|
else if (!_wcsnicmp(&argv[1][1], L"SETCLASSID", wcslen(&argv[1][1])))
|
|
{
|
|
DoSetclassid = TRUE;
|
|
}
|
|
}
|
|
|
|
switch (argc)
|
|
{
|
|
case 1: /* Default behaviour if no options are given*/
|
|
ShowInfo(TRUE, FALSE);
|
|
break;
|
|
case 2: /* Process all the options that take no parameters */
|
|
if (DoUsage)
|
|
Usage(FALSE);
|
|
else if (DoAll)
|
|
ShowInfo(TRUE, TRUE);
|
|
else if (DoRelease)
|
|
Release(NULL);
|
|
else if (DoRenew)
|
|
Renew(NULL);
|
|
else if (DoFlushdns)
|
|
FlushDns();
|
|
else if (DoRegisterdns)
|
|
RegisterDns();
|
|
else if (DoDisplaydns)
|
|
DisplayDns();
|
|
else
|
|
Usage(TRUE);
|
|
break;
|
|
case 3: /* Process all the options that can have 1 parameter */
|
|
if (DoRelease)
|
|
Release(argv[2]);
|
|
else if (DoRenew)
|
|
Renew(argv[2]);
|
|
else if (DoShowclassid)
|
|
ShowClassId(argv[2]);
|
|
else if (DoSetclassid)
|
|
SetClassId(argv[2], NULL);
|
|
else
|
|
Usage(TRUE);
|
|
break;
|
|
case 4: /* Process all the options that can have 2 parameters */
|
|
if (DoSetclassid)
|
|
SetClassId(argv[2], argv[3]);
|
|
else
|
|
Usage(TRUE);
|
|
break;
|
|
default:
|
|
Usage(TRUE);
|
|
}
|
|
|
|
return 0;
|
|
}
|