none
Compare NDIS_STRING case-insensitively at IRQL = DISPATCH_LEVEL? RRS feed

  • Question

  • I have a NDIS 6 filter driver. And I need to compare two NDIS_STRING in a case-insensitivemanner at IRQL = DISPATCH_LEVEL. I know the RtlEqualUnicodeString function can compare strings in a case-insensitive manner. But it's only callable at PASSIVE_LEVEL.

    So I have to write my own function using the basic memory copy way. And I found my function is not well functioned, because some of my users complain that this function returns FALSE when it's supposed to return TRUE. So there should be some bugs in my code. But I didn't find it by myself.

    BOOLEAN
    NPF_EqualAdapterName(
        PNDIS_STRING s1,
        PNDIS_STRING s2
        )
    {
        int i;
        BOOLEAN bResult;
        TRACE_ENTER();
    
        if (s1->Length != s2->Length)
        {
            IF_LOUD(DbgPrint("NPF_EqualAdapterName: length not the same, s1->Length = %d, s2->Length = %d\n", s1->Length, s2->Length);)
            TRACE_EXIT();
            return FALSE;
        }
    
        for (i = 0; i < s2->Length / 2; i ++)
        {
            if (s1->Buffer[i] >= L'A' && s1->Buffer[i] <= L'Z')
            {
                s1->Buffer[i] += (L'a' - L'A');
            }
            if (s2->Buffer[i] >= L'A' && s2->Buffer[i] <= L'Z')
            {
                s2->Buffer[i] += (L'a' - L'A');
            }
        }
    
        bResult = RtlEqualMemory(s1->Buffer, s2->Buffer, s2->Length);
        IF_LOUD(DbgPrint("NPF_EqualAdapterName: bResult = %d, s1 = %ws, s2 = %ws\n", i, bResult, s1->Buffer, s2->Buffer);)
        TRACE_EXIT();
        return bResult;
    }

    The entire code is here: https://github.com/nmap/npcap/blob/master/packetWin7/npf/npf/Openclos.c, if you want to know it.

    So my question is simply, is there any bugs in the above code? Thanks!

    Friday, March 25, 2016 6:00 AM

Answers

  • Write your own conversion function to take the GUID string and make it a GUID.  There are open source versions of this out on the web.  You should be able to retain the GUID for some of the items reducing the number of conversions.  The you can compare the memory of the GUID's for equality.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 25, 2016 1:24 PM

All replies

  • Why do you need to do this in the first place?  I have not examined all your code, but the typical approach for this is to have some sort of index or key for the adapter, not a name.  Comparing names is never a good idea in a performance path, and anything at DISPATCH_LEVEL needs to be high performance.

    As far as your algorithm, you realize it only works for English?  The reason the UNICODE operations cannot be done at DISPATCH_LEVEL is the UNICODE tables are paged, and are needed to handle all the mapping required.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 25, 2016 11:37 AM
  • The adapter names (e.g., s1 and s2) are some GUIDs like "{1CC605D7-B674-440B-9D58-3F68E0529B54}". They can be upper-case or lower-case. So they are definitely English.

    An idea of using an index or key would be storing the names in GUID structure instead of strings. I noticed that Windows has provided RtlStringFromGUID and RtlGUIDFromString functions. However, these two functions also only work at IRQL = PASSIVE_LEVEL.

    And much of my code just runs under DISPATCH_LEVEL. So I'm afraid storing in GUID is not a good idea.

    Friday, March 25, 2016 12:37 PM
  • Write your own conversion function to take the GUID string and make it a GUID.  There are open source versions of this out on the web.  You should be able to retain the GUID for some of the items reducing the number of conversions.  The you can compare the memory of the GUID's for equality.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 25, 2016 1:24 PM