DeviceIoControl error 87 для OID_802_11_BSSID_LIST

0

Я пытаюсь получить доступные точки доступа из сетевого 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.

EDIT: Я пытаюсь работать в Win7. Я знаю, что он устарел (и поэтому я также добавил переносимость для более поздних версий с WlanGetNetworkBssList(), и он хорошо работает). Я получаю ошибку при отладке для более старых версий (на этой же рабочей станции win7), может быть, вопрос: если код верен, NDIS IOCTL он все еще работает в Win7 и позже?

  • 0
    Вместо этого вы должны использовать NDIS_802_11_BSSID_LIST_EX. 15 произвольно и слишком низко, фактическая структура намного больше.
  • 0
    @HansPassant спасибо, также пробовал с NDIS_802_11_BSSID_LIST_EX и тот же результат: ошибка 87. Что касается 15, если я не ошибаюсь, я должен получить ERROR_INSUFFICIENT_BUFFER или ERROR_MORE_DATA, пока я не достигну правильного размера буфера, не так ли? Во всяком случае, я пробовал с 20, 100, 1000, и я всегда получаю ошибку 87 при первом вызове DeviceIoControl.
Теги:
ndis
deviceiocontrol

1 ответ

2

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.

Вы можете попробовать MSNdis_80211_BSSIList класс WMI MSNdis_80211_BSSIList, но если я правильно помню, есть некоторые проблемы с определением MOF в Windows XP, и вам нужно вручную вручную передать необработанные байты в структуры NDIS.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню