Я пытаюсь получить доступные точки доступа из сетевого идентификатора GUID, но всегда получаю ошибку 87 (неправильный параметр) для DeviceIoControl (). На какое-то время это сводит меня с ума, так как я не знаю, какой из параметров неправильный! Я часами гуглю и не могу найти решение. Код следующий:
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 являются частью договора между ОС и драйвером 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
, но, если я правильно помню, есть некоторая проблема с определением MOF в Windows XP, и поэтому вам придется вручную приводить необработанные байты к структурам NDIS.
Других решений пока нет …