C++实现获取MAC地址与硬盘序列号方法

需积分: 5 20 下载量 62 浏览量 更新于2024-11-09 1 收藏 4KB ZIP 举报
资源摘要信息:"本文介绍如何使用C++编写代码以获取计算机的MAC地址和硬盘序列号。MAC地址是网络设备中用于唯一标识网络硬件接口的地址,而硬盘序列号是存储设备的唯一标识。在操作系统层面,可以通过特定的API或命令来获取这些信息。本示例代码将展示如何在Windows平台上通过调用Win32 API实现这一功能。 在Windows系统中,可以通过调用`GetAdaptersInfo`和`GetAdaptersAddress`函数来获取网络适配器的MAC地址。这两个函数都是在`iphlpapi.h`头文件中声明的。获取硬盘序列号则需要使用Windows Management Instrumentation (WMI),这通常涉及到查询Win32_DiskDrive类的实例属性。 以下是一个简化的示例代码片段,展示了如何在C++中实现获取MAC地址和硬盘序列号的基本逻辑。请注意,该代码可能需要管理员权限运行,以确保能够访问网络适配器和硬件信息。 ```cpp #include <iostream> #include <windows.h> #include <iphlpapi.h> #include <Iphlpapi.h> #include <netioapi.h> #include <objbase.h> #include <wbemidl.h> #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "ole32.lib") #pragma comment(lib, "netapi32.lib") int main() { // 初始化COM库 HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { std::cerr << "Failed to initialize COM library. Error code = 0x" << std::hex << hres << std::endl; return 1; // Program has failed. } // 使用WMI获取硬盘序列号 IWbemLocator *pLoc = NULL; hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (SUCCEEDED(hres)) { IWbemServices *pSvc = NULL; // Connect to the root\cimv2 namespace with the current user and obtain pointer pSvc hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace NULL, // User name NULL, // User password 0, // Locale NULL, // Security flags 0, // Authority 0, // Context object &pSvc // IWbemServices proxy ); if (FAILED(hres)) { std::cerr << "Could not connect to WMI server. Error code = 0x" << std::hex << hres << std::endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // 设置代理安全级别 hres = CoSetProxyBlanket( pSvc, // the proxy to set RPC_C_AUTHN_WINNT, // authentication service RPC_C_AUTHZ_NONE, // authorization service NULL, // server principal name RPC_C_AUTHN_LEVEL_DEFAULT, // authentication level RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level NULL, // client identity EOAC_NONE // proxy capabilities ); // 使用WMI查询硬盘序列号 IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_DiskDrive"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (SUCCEEDED(hres)) { // 获取硬盘序列号 IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } VARIANT vtProp; // Retrieve the Name property hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); std::wcout << "Disk Serial Number: " << vtProp.bstrVal << std::endl; VariantClear(&vtProp); pclsObj->Release(); } } else { std::cerr << "Query for disk info failed. Error code = 0x" << std::hex << hres << std::endl; } pSvc->Release(); } else { std::cerr << "Could not create IWbemLocator object. Err code = 0x" << std::hex << hres << std::endl; return 1; // Program has failed. } pLoc->Release(); CoUninitialize(); // 获取MAC地址的代码段 IP_ADAPTER_ADDRESSES* adapterAddresses = NULL; ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES); // 预先分配足够的空间 adapterAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen); DWORD dwRet = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapterAddresses, &outBufLen); if (dwRet == ERROR_BUFFER_OVERFLOW) { free(adapterAddresses); adapterAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen); dwRet = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapterAddresses, &outBufLen); } if (dwRet == NO_ERROR) { PIP_ADAPTER_ADDRESSES pAdapter = adapterAddresses; while (pAdapter) { std::cout << "MAC Address: "; for (int i = 0; i < pAdapter->PhysicalAddressLength; i++) { std::cout << std::hex << (int)pAdapter->PhysicalAddress[i]; if (i != pAdapter->PhysicalAddressLength - 1) std::cout << ":"; } std::cout << std::endl; pAdapter = pAdapter->Next; } } else { std::cerr << "Failed to get MAC Address(es) Error code: " << dwRet << std::endl; } if (adapterAddresses) free(adapterAddresses); return 0; } ``` 在上述代码中,首先使用`CoInitializeEx`函数初始化COM库,然后创建`IWbemLocator`实例以连接到WMI服务。通过`IWbemServices`接口执行WQL查询以获取硬盘序列号,并通过`IP_ADAPTER_ADDRESSES`结构获取MAC地址。 需要注意的是,为了编译和运行上述代码,需要配置相应的开发环境,并且链接到必要的库。同时,由于涉及到系统级别的调用,需要确保程序有足够的权限来访问系统信息。 此外,获取硬盘序列号的部分可能需要根据实际情况调整WMI查询语句以获取更详细的信息。上述代码仅为示例,实际使用时可能需要根据具体需求进行调整和优化。"