2014-02-05 74 views
0

我試圖從網絡GUID獲得可用的接入點,但我總是得到DeviceIoControl()錯誤87(錯誤的參數)。這讓我發瘋了一段時間,因爲我不知道哪個參數錯了!我一直在谷歌搜索幾個小時,並找不到解決方案。代碼如下: 「\\。\ {8D36491D-C393-4D71-B10A-153C4FA69AEE}」DeviceIoControl錯誤87爲OID_802_11_BSSID_LIST

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這是博通802.11n網絡適配器。

編輯:我試着在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,並且在DeviceIoControl的第一次調用時我總是得到錯誤87。 – Miquel

回答

2

像這樣的OID是操作系統和NIC驅動之間的契約的一部分。它們通常不適合應用程序跳轉。正確的解決方案是調用應用程序級的API,如WlanGetNetworkBssList

發生了什麼事是舊的NDIS 5無線驅動程序將使用OID_802_11_BSSID_LIST與操作系統進行通信。但更新的NDIS 6驅動程序使用不同的機制。所以舊的OID在發送到一個更新的微型端口驅動程序時失敗。像這樣的驅動模型的變化被隔離在應用程序API之後。

如果您必須在無法使用API​​的Windows XP上工作,那麼您可能需要使用其他技術。但IOCTL_NDIS_QUERY_GLOBAL_STATS不會幫助,因爲該ioctl發出查詢 OID,而OID_802_11_BSSID_LIST方法 OID。

您可以嘗試戳一下WMI類MSNdis_80211_BSSIList,但如果我沒有記錯,Windows XP上的MOF定義存在一些問題,因此您需要手動將原始字節轉換爲NDIS結構。

相關問題