我正在尝试从网络GUID获取可用的访问点,但是我总是收到DeviceIoControl()的错误87(错误的参数)。这让我发疯了一段时间,因为我不知道哪个参数错了!我已经搜寻了几个小时,找不到解决方案。代码如下:
PNDIS_802_11_BSSID_LIST getBssidList(wstring wsGuid, HANDLE & hNetAdapter, DWORD & dwMemSize) {
DWORD dwBytesReturned = 0;
DWORD oid = OID_802_11_BSSID_LIST;
PNDIS_802_11_BSSID_LIST pBssList;
wsGuid= L"\\\\.\\" + wsGuid;
hNetAdapter = CreateFileW(wsGuid.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, INVALID_HANDLE_VALUE) ;
if (hNetAdapter == INVALID_HANDLE_VALUE) {
return NULL;
}
// allocate temporary memory to check the number of AP entries
dwMemSize = sizeof(NDIS_802_11_BSSID_LIST) * 15;
pBssList = (NDIS_802_11_BSSID_LIST *) VirtualAlloc(NULL, dwMemSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
memset(pBssList, 0, dwMemSize);
// call get AP list
while (!DeviceIoControl(hNetAdapter, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid), (ULONG *) pBssList, dwMemSize, &dwBytesReturned, NULL)) {
DWORD error = 0;
error = GetLastError();
if (error == ERROR_GEN_FAILURE || // Returned by some Intel cards.
error == ERROR_INSUFFICIENT_BUFFER ||
error == ERROR_MORE_DATA ||
error == NDIS_STATUS_INVALID_LENGTH ||
error == NDIS_STATUS_BUFFER_TOO_SHORT ) {
// free memory allocation and realloc
VirtualFree(pBssList, dwMemSize, MEM_RELEASE | MEM_DECOMMIT);
if (dwBytesReturned > dwMemSize) {
dwMemSize = dwBytesReturned;
} else {
dwMemSize *= 2;
}
pBssList = (NDIS_802_11_BSSID_LIST *) VirtualAlloc(NULL, dwMemSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
memset(pBssList, 0, dwMemSize);
} else {
// free memory allocation
VirtualFree(pBssList, dwMemSize, MEM_RELEASE | MEM_DECOMMIT);
CloseHandle(hNetAdapter);
pBssList = NULL;
break;
}
}
return pBssList;
}
我正在尝试使用wsGuid = L“ \\。\ {8D36491D-C393-4D71-B10A-153C4FA69AEE}”获得此列表,它是Broadcom 802.11n网络适配器。
编辑:我正在Win7工作中尝试它。我知道它已被弃用(因此我还为WlanGetNetworkBssList()添加了更高版本的可移植性,并且运行良好)。调试旧版本(在同一Win7工作站中)时出现错误,问题可能是:如果代码正确,NDIS IOCTL是否仍在Win7及更高版本中工作?
最佳答案
像这样的OID是OS和NIC驱动程序之间合同的一部分。它们通常不适合应用程序跳入。正确的解决方案是调用应用程序级别的API,例如WlanGetNetworkBssList
。
发生的情况是,较早的NDIS 5无线驱动程序将使用OID_802_11_BSSID_LIST
与操作系统进行通信。但是更新的NDIS 6驱动程序使用不同的机制。因此,旧的OID在发送到更新的微型端口驱动程序时会失败。像这样的驱动程序模型中的更改被隔离在应用程序API之后。
如果必须在Windows XP上工作,而该API不可用,那么您可能需要尝试其他技术。但是IOCTL_NDIS_QUERY_GLOBAL_STATS
没有帮助,因为该ioctl发出查询OID,而OID_802_11_BSSID_LIST
是方法OID。
您可以尝试戳WMI类MSNdis_80211_BSSIList
,但是如果我没记错的话,Windows XP上的MOF定义存在一些问题,因此您需要手动将原始字节转换为NDIS结构。
关于c++ - OID_802_11_BSSID_LIST的DeviceIoControl错误87,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21584439/