WMI MSNdis_80211_ServiceSetIdentifier query returns garbage

Hello,

I am using the below code in order to retrieve information about the WLAN network environment. Unfortunately only the first result in the ManagementObjectCollection seems to contain valid information. The other objects seem to contain garbage. Does retrieval anybody know of any issues with WMI and the MSNdis_80211_ServiceSetIdentifier retrieval

ManagementClass mc = new ManagementClass("root\\WMI", "MSNdis_80211_ServiceSetIdentifier", null);

ManagementObjectCollection moc = mc.GetInstances();

foreach (ManagementObject mo in moc)

{

string wlanCard = (string)mo["InstanceName"];

bool active = (bool)mo["Active"];

byte[] ssid = (byte[])mo["Ndis80211SsId"];

string ssidString = Encoding.ASCII.GetString(ssid);

Console.WriteLine("{0}\r\n{1}\r\n{2}", wlanCard.Trim(), active, ssidString.Trim());

Console.WriteLine();

}



Answer this question

WMI MSNdis_80211_ServiceSetIdentifier query returns garbage

  • lewix

    I am getting more and more convinced that this is a WMI bug in WinXP. Browsing on the net I found other people having the very same issue and nobody found a solution for it.

    I have a simple Visual Basic Script that demonstrates the issue. If someone is interested please let me know. I can e-mail it.


  • Karl Matless

    I met the same problem. Here my code:

    IWbemLocator *pLoc = NULL;
    IWbemServices *pSvc = NULL;

    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------
    HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) return hres;

    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
    if (FAILED(hres)) return hres;

    hres = pLoc->ConnectServer((L"root\\wmi"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    if (FAILED(hres)) {
    pLoc->Release();
    return hres;
    }

    // Set the proxy so that impersonation of the client occurs.
    // Step 5: --------------------------------------------------
    // Set security levels for the proxy ------------------------
    hres = CoSetProxyBlanket(
    pSvc, // Indicates the proxy to set
    RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
    RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
    NULL, // Server principal name
    RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
    RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    NULL, // client identity
    EOAC_NONE // proxy capabilities
    );
    if (FAILED(hres)) {
    pLoc->Release();
    return hres;
    }
    IEnumWbemClassObject* pList = NULL;
    //hres = pSvc->CreateInstanceEnum( L"MSNdis_80211_ServiceSetIdentifier", WBEM_FLAG_RETURN_IMMEDIATELY|WBEM_FLAG_FORWARD_ONLY, NULL, &pList);
    hres = pSvc->CreateInstanceEnum( L"MSNdis_80211_BSSIList", WBEM_FLAG_FORWARD_ONLY, NULL, &pList);
    if (FAILED(hres)) {
    pSvc->Release();
    pLoc->Release();
    return hres;
    }

    IWbemClassObject* pSSID = NULL;
    ULONG arg = 0;
    if (pList->Next( WBEM_INFINITE, 1, &pSSID, &arg ) != WBEM_S_NO_ERROR) {
    pList->Release();
    pSvc->Release();
    pLoc->Release();
    return S_FALSE;
    }

    CComVariant variantSSIDList;

    //if (pSSID->Get(L"Ndis80211SsId", 0, &var, NULL, NULL) == WBEM_S_NO_ERROR) {
    if (pSSID->Get(L"Ndis80211BSSIList", 0, &variantSSIDList, NULL, NULL) == WBEM_S_NO_ERROR && (variantSSIDList.vt != VT_NULL)) {
    // Calculate the number of elements
    long lUpper = 0;
    long lLower = 0;
    hres = SafeArrayGetUBound(V_ARRAY(&variantSSIDList), 1, &lUpper);
    hres = SafeArrayGetLBound(V_ARRAY(&variantSSIDList), 1, &lLower);

    long lNumOfElems = lUpper - lLower + 1;

    // Gain access to the SAFEARRAY
    LPUNKNOWN HUGEP *punkArray = 0;
    hres = SafeArrayAccessData(V_ARRAY(&variantSSIDList),
    (void**)&punkArray);

    for (int nIndex = 0; nIndex < lNumOfElems; nIndex++)
    {
    CComQIPtr<IWbemClassObject> spSummaryObject = punkArray[nIndex];

    _variant_t varSsId;
    _variant_t varSsIdLength;
    _variant_t varRssi;
    varSsId.Clear();
    varSsIdLength.Clear();
    varRssi.Clear();
    hres = spSummaryObject->Get(CComBSTR(_T("Ndis80211SsId")), 0,
    &varSsId, 0, 0);
    hres = spSummaryObject->Get(CComBSTR(_T("Ndis80211SsIdLength")), 0,
    &varSsIdLength, 0, 0);
    // hr = spSummaryObject->Get(CComBSTR(_T("Ndis80211Rssi")), 0,
    // &varRssi, 0, 0);

    CString SsId;
    for (int x=0; x<varSsIdLength.lVal; x++)
    {
    SsId.Insert(x, (CHAR) *((char *)varSsId.parray->pvData + x));
    }
    //pAvailableAPs->Add(SsId); // Add the SSID into array
    }
    hres = SafeArrayUnaccessData(V_ARRAY(&variantSSIDList));
    }

    pSSID->Release();
    pList->Release();
    pLoc->Release();
    pSvc->Release();
    CoUninitialize();
    return hres;

    The first varSsIdLength shows correct value and I got the network name. But the second one ( notice I have a loop ) doesn't show any valid value. The varSsIdLength shows horrible value which can make this code crash.

    Please help me to check what's wrong in the code.


  • TommY_R

    All MSNdis_80211_* classes in the Root\WMI namespace should provide you in read-only most of 802.11 WL information. However, this is information is the reflection of the driver provides. Therefore, if the information you are looking for is not in there, the question must be addressed in the networking area (look at the NETSH command) and its set of API available from .NET to retrieve the information you are looking for.

    HTH

    /Alain



  • sasllc

    No, there is no solution. The WMI is buggy on this respect and can not be used for that purpose.

  • EricSmith

    Not to see what you mean by garbage. Here is what I see on my machine. What is the garbage


    instance of MSNdis_80211_ServiceSetIdentifier
    {
    Active = TRUE;
    InstanceName = "HP WLAN 802.11a/b/g W500";
    Ndis80211SsId = {8, 0, 0, 0, 77, 83, 70, 84, 87, 76, 65, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    };

    instance of MSNdis_80211_ServiceSetIdentifier
    {
    Active = TRUE;
    InstanceName = "HP WLAN 802.11a/b/g W500 - Virtual Machine Network Services Driver";
    Ndis80211SsId = {8, 0, 0, 0, 77, 83, 70, 84, 87, 76, 65, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    };

    instance of MSNdis_80211_ServiceSetIdentifier
    {
    Active = TRUE;
    InstanceName = "HP WLAN 802.11a/b/g W500 - Packet Scheduler Miniport";
    Ndis80211SsId = {8, 0, 0, 0, 77, 83, 70, 84, 87, 76, 65, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    };



  • OLAP_Guy

    Alain, The garbage in my example is the 4 bytes at the beginning of the Ndis80211SsId. Using your example the garbage is highlighted red:

    instance of MSNdis_80211_ServiceSetIdentifier
    {
    Active = TRUE;
    InstanceName = "HP WLAN 802.11a/b/g W500 - Virtual Machine Network Services Driver";
    Ndis80211SsId = {8, 0, 0, 0, 77, 83, 70, 84, 87, 76, 65, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    };

    However, I have to admit that my initial example wasn't very clear. Let me show you a different example:

    Code:

    ManagementClass mc = new ManagementClass("root\\WMI", "MSNdis_80211_BSSIList", null);

    ManagementObjectCollection moc = mc.GetInstances();

    foreach (ManagementObject mo in moc)

    {

    string wlanCard = (string)mo["InstanceName"];

    Console.WriteLine(wlanCard);

    ManagementBaseObject[] bssiList = (ManagementBaseObject[])mo["Ndis80211BSSIList"];

    foreach (ManagementBaseObject bssi in bssiList)

    {

    byte[] ssid = (byte[])bssi["Ndis80211SsId"];

    string ssidString = Encoding.ASCII.GetString(ssid);

    Console.WriteLine(" " + ssidString);

    }

    Console.WriteLine("########################");

    }

    Result (with garbage in red):

    MSNdis_80211_BSSIList
    {
    InstanceName = "Dell TrueMobile 1300 WLAN Mini-PCI Karte";
    Ndis80211SsId = {97,43,97,32,70,114,97,110,107,102,117,114,116,0,0,0,0,0,0,0};
    Ndis80211SsId = {71,0,0,0,100,0,113,4,0,13,97,43,97,32,70,114,97,110,107,102};
    Ndis80211SsId = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    Ndis80211SsId = {100,0,17,4,0,4,83,68,83,76,1,8,130,132,139,150,36,48,72,108};
    Ndis80211SsId = {32,0,0,0,100,0,0,0,0,0,0,0,48,145,37,0,16,0,0,0};
    }
    MSNdis_80211_BSSIList
    {
    InstanceName = "Dell TrueMobile 1300 WLAN Mini-PCI Karte - Virtual Machine Network Services Driver";
    Ndis80211SsId = {97,43,97,32,70,114,97,110,107,102,117,114,116,0,0,0,0,0,0,0};
    Ndis80211SsId = {71,0,0,0,100,0,113,4,0,13,97,43,97,32,70,114,97,110,107,102};
    Ndis80211SsId = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    Ndis80211SsId = {100,0,17,4,0,4,83,68,83,76,1,8,130,132,139,150,36,48,72,108};
    Ndis80211SsId = {32,0,0,0,100,0,0,0,0,0,0,0,48,145,37,0,16,0,0,0};
    }
    MSNdis_80211_BSSIList
    {
    InstanceName = "Dell TrueMobile 1300 WLAN Mini-PCI Karte - Deterministic Network Enhancer Miniport";
    Ndis80211SsId = {97,43,97,32,70,114,97,110,107,102,117,114,116,0,0,0,0,0,0,0};
    Ndis80211SsId = {71,0,0,0,100,0,113,4,0,13,97,43,97,32,70,114,97,110,107,102};
    Ndis80211SsId = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    Ndis80211SsId = {100,0,17,4,0,4,83,68,83,76,1,8,130,132,139,150,36,48,72,108};
    Ndis80211SsId = {32,0,0,0,100,0,0,0,0,0,0,0,48,145,37,0,16,0,0,0};
    }
    MSNdis_80211_BSSIList
    {
    InstanceName = "Dell TrueMobile 1300 WLAN Mini-PCI Karte - Packet Scheduler Miniport";
    Ndis80211SsId = {97,43,97,32,70,114,97,110,107,102,117,114,116,0,0,0,0,0,0,0};
    Ndis80211SsId = {71,0,0,0,100,0,113,4,0,13,97,43,97,32,70,114,97,110,107,102};
    Ndis80211SsId = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    Ndis80211SsId = {100,0,17,4,0,4,83,68,83,76,1,8,130,132,139,150,36,48,72,108};
    Ndis80211SsId = {32,0,0,0,100,0,0,0,0,0,0,0,48,145,37,0,16,0,0,0};
    }


  • blajano

    I am unable to execute the code from the first post of this thread. Whenever I try I get a "not supported" runtime error. Anyone know why this is happening

  • -Anton Lapounov

    Here is the result of the below script. Note that everything starting in the second result line is garbage.

    Result

    MAC:0.3.C9.54.A4.58. RSSI:-78 dBm
    MAC:0.0.0.0.33.0. RSSI:-580904942 dBm
    MAC:0.0.0.0.0.0. RSSI:1 dBm
    MAC:8.C.12.18.24.30. RSSI:0 dBm
    MAC:1.0.0.0.82.84. RSSI:403478155 dBm

    ' VBScript source code
    On Error Resume Next

    Set fso = CreateObject("Scripting.FileSystemObject")

    Set Wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!root/wmi")

    set scan = wmi.Get("MSNDis_80211_BssIdListScan")
    set scanInst = scan.SpawnInstance_
    scanInst.Active = True
    scanInst.UnusedParameter = 0
    scanInst.Put_

    Set nicSet = Wmi.InstancesOf("MSNdis_80211_BSSIList")
    For Each nic In nicSet
    obset = nic.Ndis80211BSSIList
    Next

    Text= ""
    For Each ob In obset
    macAddr = ob.Ndis80211MacAddress
    RSSI = ob.Ndis80211Rssi
    macAddrStr = ""
    For t = 0 To 5
    macAddrStr = macAddrStr + Hex(macAddr(t)) + "."
    Next
    Text = Text & "MAC:" & macAddrStr & " RSSI:" & RSSI & " dBm" & vbCrLf
    next

    Set file = fso.OpenTextFile("wlan.txt", 2, True)
    file.WriteLine(Text)
    file.Close()


  • Basha

    Any solution to the original problem I have the same problem with garbage returned when using WMI (MSNdis_80211) queries.


  • Michael K. Barnett

    Thank you very much for your reply Alain!

    I am not sure if I understand correctly. How can I be sure that the information is not provided from the driver When querying for example the MSNdis_80211_BSSIList I get an array of four MSNdis_80211_BSSIList objects, In my case:

    1: Dell TrueMobile 1300 WLAN Mini-PCI Karte
    2: Dell TrueMobile 1300 WLAN Mini-PCI Karte - Virtual Machine Network Services Driver
    3: Dell TrueMobile 1300 WLAN Mini-PCI Karte - Deterministic Network Enhancer Miniport
    4: Dell TrueMobile 1300 WLAN Mini-PCI Karte - Packet Scheduler Miniport


    This works perfectly fine.

    When I go into the details of one of the MSNdis_80211_BSSIList objects I get the WLAN networks currently received. In my case it is 7 networks. Querying for more information, e.g. Ndis80211SsId, Ndis80211SsIdLength, Ndis80211Rssi etc. results in correct data only for the first network in the array. The other six networks result in garbage information (e.g. the Ndis80211SsIdLength returns 451673 ...).

    If this is caused by the driver of the WLAN card, how can I identify in WMI that I get erroneuous information

    Thanks,
    Dietmar


  • WMI MSNdis_80211_ServiceSetIdentifier query returns garbage