0

ネットワーク 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;
}

Broadcom 802.11n ネットワーク アダプタである wsGuid = L"\\.\{8D36491D-C393-4D71-B10A-153C4FA69AEE}" でこのリストを取得しようとしています。

編集: Win7 ワークステーションで試しています。私はそれが非推奨であることを知っています(したがって、WlanGetNetworkBssList()を使用して新しいバージョンの移植性も追加しましたが、うまく機能しています)。(この同じ win7 ワークステーションで) 古いバージョンのデバッグ中にエラーが発生しました。おそらく問題は次のとおりです。コードが正しい場合、NDIS IOCTL は Win7 以降でも動作していますか?

4

1 に答える 1

2

このような OID は、OS と NIC ドライバー間の契約の一部です。それらは通常、アプリケーションがジャンプするためのものではありません。正しい解決策は、 のようなアプリケーション レベルの API を呼び出すことですWlanGetNetworkBssList

何が起こっているかというと、古い NDIS 5 ワイヤレス ドライバーがOID_802_11_BSSID_LISTOS との通信に使用されます。ただし、新しい NDIS 6 ドライバーは別のメカニズムを使用します。したがって、古い OID は、新しいミニポート ドライバーに送信されると失敗します。このようなドライバー モデルの変更は、アプリケーション API の背後で分離されます。

API が利用できない Windows XP で作業する必要がある場合は、他の手法をいじる必要があるかもしれません。しかし、その ioctl はクエリOID を発行し、一方はメソッドIOCTL_NDIS_QUERY_GLOBAL_STATSOIDであるため、役に立ちません。OID_802_11_BSSID_LIST

WMI クラスMSNdis_80211_BSSIListを調べてみることもできますが、私の記憶が正しければ、Windows XP の MOF 定義に問題があるため、未加工のバイトを NDIS 構造に手動でキャストする必要があります。

于 2014-02-06T02:01:52.407 に答える