Netbios
代码语言:javascript复制#include <windows.h>
#pragma comment(lib, "Netapi32.lib")
namespace
{
bool GetAdapterInfo(int adapterNum, std::string& macOUT)
{
NCB Ncb;
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBRESET; // 重置网卡,以便我们可以查询
Ncb.ncb_lana_num = adapterNum;
if (Netbios(&Ncb) != NRC_GOODRET)
return false;
// 准备取得接口卡的状态块
memset(&Ncb, sizeof(Ncb), 0);
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = adapterNum;
strcpy((char *) Ncb.ncb_callname, "*");
struct ASTAT
{
ADAPTER_STATUS adapt;
NAME_BUFFER nameBuff[30];
}adapter;
memset(&adapter,sizeof(adapter), 0);
Ncb.ncb_buffer = (unsigned char *)&adapter;
Ncb.ncb_length = sizeof(adapter);
if (Netbios(&Ncb) != 0)
return false;
char acMAC[32];
sprintf(acMAC, "X-X-X-X-X-X",
int (adapter.adapt.adapter_address[0]),
int (adapter.adapt.adapter_address[1]),
int (adapter.adapt.adapter_address[2]),
int (adapter.adapt.adapter_address[3]),
int (adapter.adapt.adapter_address[4]),
int (adapter.adapt.adapter_address[5]));
macOUT = acMAC;
return true;
}
}
bool GetMacByNetBIOS(std::string& macOUT)
{
// 取得网卡列表
LANA_ENUM adapterList;
NCB Ncb;
memset(&Ncb, 0, sizeof(NCB));
Ncb.ncb_command = NCBENUM;
Ncb.ncb_buffer = (unsigned char *)&adapterList;
Ncb.ncb_length = sizeof(adapterList);
Netbios(&Ncb);
// 取得MAC
for (int i = 0; i < adapterList.length; i)
{
if (GetAdapterInfo(adapterList.lana[i], macOUT))
return true;
}
return false;
}
DeviceIoControl
代码语言:javascript复制#include <stdio.h>
#include <locale.h>
#include <tchar.h>
#include <windows.h>
#include <shlwapi.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")
#include <devguid.h>
#pragma comment(lib, "uuid.lib")
#include <ntddndis.h>
#include <ndisguid.h>
#include <iptypes.h>
#include <regstr.h>
using DIDD_TYPE_BASE = SP_DEVICE_INTERFACE_DETAIL_DATA;
using DIDD_TYPE_CHAR = decltype(*static_cast<DIDD_TYPE_BASE *>(nullptr)->DevicePath);
static constexpr SIZE_T DIDD_SIZE_HEAD = offsetof(DIDD_TYPE_BASE, DevicePath);
static constexpr SIZE_T DIDD_SIZE_BODY = sizeof(DIDD_TYPE_CHAR) * MAX_PATH;
static constexpr SIZE_T DIDD_SIZE_FULL = DIDD_SIZE_HEAD DIDD_SIZE_BODY;
using DEVICE_INTERFACE_DETAIL_DATA = union DEVICE_INTERFACE_DETAIL_DATA {
inline SP_DEVICE_INTERFACE_DETAIL_DATA *operator->() { return &DetailData; }
inline SP_DEVICE_INTERFACE_DETAIL_DATA *operator &() { return &DetailData; }
SP_DEVICE_INTERFACE_DETAIL_DATA DetailData;
BYTE Buffer[DIDD_SIZE_FULL];
};
static void SetupDiOutputDeviceAddress(LPCTSTR DevicePath)
{
HANDLE hFile = CreateFile(DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE)
{
BOOL bResult = FALSE;
BYTE bAddress[MAX_ADAPTER_ADDRESS_LENGTH] = { 0 };
DWORD dwCtls[] = { OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS };
for (DWORD i = 0; i < ARRAYSIZE(dwCtls); i )
{
DWORD dwCode = dwCtls[i];
DWORD cbRead = 0;
bResult = DeviceIoControl(hFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwCode, sizeof(dwCode), bAddress, sizeof(bAddress), &cbRead, nullptr);
if (bResult)
{
wprintf(L"网卡地址 [X-X-X-X-X-X]n", bAddress[0], bAddress[1], bAddress[2], bAddress[3], bAddress[4], bAddress[5]);
break;
}
}
DWORD dwType = 0;
DWORD dwCode = OID_GEN_PHYSICAL_MEDIUM;
DWORD cbRead = 0;
bResult = DeviceIoControl(hFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwCode, sizeof(dwCode), &dwType, sizeof(dwType), &cbRead, nullptr);
CloseHandle(hFile);
if (bResult)
{
BOOL bWireless = FALSE;
switch (dwType) {
case NdisPhysicalMediumWirelessLan:
case NdisPhysicalMediumWirelessWan:
case NdisPhysicalMediumNative802_11:
case NdisPhysicalMediumBluetooth:
case NdisPhysicalMediumWiMax:
case NdisPhysicalMediumUWB:
bWireless = TRUE;
default:
wprintf(L"是否无线 [%d]n", bWireless);
break;
}
}
}
}
ipconfig /all 类似的还有 :getmac /v /fo list
代码语言:javascript复制bool GetMacByCmd(std::string& macOUT)
{
bool ret = false;
//初始化返回MAC地址缓冲区
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
//创建管道
HANDLE hReadPipe,hWritePipe;
if(CreatePipe(&hReadPipe, &hWritePipe, &sa, 0) == TRUE)
{
//控制命令行窗口信息
STARTUPINFO si;
//返回进程信息
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.wShowWindow = SW_HIDE; //隐藏命令行窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//创建获取命令行进程
if (CreateProcess(NULL, "ipconfig /all", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == TRUE)
{
WaitForSingleObject(pi.hProcess, 3000); // 设置超时时间,防止Vista、Win7等操作系统卡死
unsigned long count;
CloseHandle(hWritePipe);
std::string strBuffer(1024 * 10, '