locked
Does WSALookupServiceBegin() behavior differently on Windows XP PC and WinMobile 6.1 device? RRS feed

  • Question

  • Hi there,

    I am using WSALookupServiceBegin() to start discovering any Bluetooth devices. On my XP PC, the WSALookupServiceBegin() succeeds and I can go further to use WSALookupServiceBegin() to retrieve all visible bluetooth devices. But on my WinMobile 6.1 device, the same code fails in WSALookupServiceBegin() and I am getting 10022 error code for "invalid parameter". I have included the code section below which is compiled both on PC and on device. I am not sure which part of my paramters is invalid, and why the same code works on PC but not on device. Would you mind taking a look at the code and let me know what might make the WSALookupServiceBegin() fail on the WinMobile device? Thanks a lot!

    Zhiheng Mao
    =======================================
    ULONG ulFlags = LUP_CONTAINERS | LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE;
    unsigned long ulPQSSize = sizeof(WSAQUERYSET);

    PWSAQUERYSET pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulPQSSize);
    if (pWSAQuerySet == NULL)
    {
          return false;
    }

    ZeroMemory(pWSAQuerySet, ulPQSSize);
    pWSAQuerySet->dwNameSpace = NS_BTH;
    pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);
    // I am searching for all bluetooth devices, regardless of their pWSAQuerySet->lpServiceClassId

    HANDLE hLookup=0;
    int iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);
    if (iResult != NO_ERROR || hLookup == NULL)
    {
       // I am getting 10022 from GetLastError()
       return false;
    }

    Wednesday, April 1, 2009 8:03 PM

Answers

  • Not really the answer you were looking for, but if you check btsearch sample in Windows Mobile 6 SDK, they allocate 5000 bytes from the get-go and don't seem to ever need a reallocation. It might be a bug, but the workaround seems to work. Also, notice that the pwsaResults->dwSize  is set to  sizeof(WSAQUERYSET) and not to the size of the entire buffer

     union {
      CHAR buf[5000];    // returned struct can be quite large
      SOCKADDR_BTH __unused; // properly align buffer to BT_ADDR requirements
     };

      pwsaResults = (LPWSAQUERYSET) buf;
      
      dwSize  = sizeof(buf);
      
      memset(pwsaResults,0,sizeof(WSAQUERYSET));
      pwsaResults->dwSize      = sizeof(WSAQUERYSET);
      // namespace MUST be NS_BTH for bluetooth queries
      pwsaResults->dwNameSpace = NS_BTH;
      pwsaResults->lpBlob      = NULL;
      
      // iterate through all found devices, returning name and address
      // (this sample only uses the name, but address could be used for
      // further queries)
      iResult = WSALookupServiceNext (hLookup,
       LUP_RETURN_NAME | LUP_RETURN_ADDR,
       &dwSize,
       pwsaResults);

    Alex Feinman. MVP .NET Compact Framework
    • Marked as answer by warrentang Monday, April 6, 2009 7:59 AM
    Monday, April 6, 2009 5:10 AM

All replies

  • Bluetooth provider called by WSALookupServiceBegin does not support any of the  LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE. You can see it in documentation for BthNsLookupServiceBegin. The proper way of doing this is to specify only LUP_CONTAINERS and then use the rest of the flags in the subsequent calls to WSALookupServiceNext.
    For more information see the remarks are of the WSALookupServiceBegin on a mobile platform
    Alex Feinman. MVP .NET Compact Framework
    Thursday, April 2, 2009 12:20 AM
  • Hi Alex,

    I removed all other flags in the ulFlags except the "LUP_CONTAINERS" and the WSALookupServiceBegin() works! Thank you so much for the suggestion!

    Now I am seeing another strange behaviour from WSALookupServiceNext(): it always thinks that the pWSAQuerySet->dwSize is not large enough. Before the first call, I set pWSAQuerySet->dwSize = ulPQSSize which is 60. WSALookupServiceNext() then returns WSAEFAULT which indicates that the buffer for QUERYSET was insufficient. However, the "ulPQSSize" passed out by this WSALookupServiceNext() call is still 60.

    So the code frees the old QUERYSET structure and allocates a new QUERYSET structure which is still 60 bytes large. The code then goes into an infinite loop by calling WSALookupServiceNext() and getting the same result over and over again, becuase the returned code from WSALookupServiceNext() is always WSAEFAULT and the "ulPQSSize" passed out is always 60.

    I am not sure what I am doing wrong here and would very much appreciate if you could please let me know how it should work. I have included the code section below. Thanks a lot!

    Zhiheng Mao
    =========================================

    ULONG ulFlags = LUP_CONTAINERS;
     
    unsigned long ulPQSSize = sizeof(WSAQUERYSET);
    PWSAQUERYSET pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulPQSSize);
    if (pWSAQuerySet == NULL)
    {
       // Unable to allocate memory for WSAQUERYSET
       return false; 
    }

    ZeroMemory(pWSAQuerySet, ulPQSSize);
    pWSAQuerySet->dwNameSpace = NS_BTH;
    pWSAQuerySet->dwSize = ulPQSSize;   // this is 60 initially
      
    HANDLE hLookup=0;
    int iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);
    if (iResult != NO_ERROR || hLookup == NULL)
    {
       // WSALookupServiceBegin failed
       return false; 
    }

    while (1)
    {
       ulFlags = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE;

       // If "ulPQSSize" is not large enough, it will be set by the WSALookupServiceNext()
       //    and new memory will be allocated accordingly.
       // So the subsequent call will have the proper memory size.
       //
       ZeroMemory(pWSAQuerySet, ulPQSSize);
       pWSAQuerySet->dwNameSpace = NS_BTH;
       pWSAQuerySet->dwSize = ulPQSSize;    // this is 60 initially

       if (WSALookupServiceNext(hLookup, ulFlags, &ulPQSSize, pWSAQuerySet) == NO_ERROR)
       {
          // Got it! Now use it.
          // ....
       }
       else
       {
          if ( WSA_E_NO_MORE == ( iResult = WSAGetLastError() ) )
         {
             // No more devices found
             break;
         }
         else if ( WSAEFAULT == iResult )
         {
             // The buffer for QUERYSET was insufficient.
             // In such case 3rd parameter "ulPQSSize" of function "WSALookupServiceNext()" receives
             // the required size.  So we can use this parameter to reallocate memory for QUERYSET.
             //
             // Zhiheng Mao: this is the strange part: ulPQSSize was 60 before the call, and it is still 60 after the call
             //             WSALookupServiceNext() should pass out the proper size for me to allocate for the next call.
             //             This makes the infinite loop becuase the returned code from WSALookupServiceNext() is
             //             always WSAEFAULT and the "ulPQSSize" passed out is always 60.
             //
             HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
             pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulPQSSize);
             if (pWSAQuerySet == NULL)
             {
                // Unable to allocate memory for WSAQUERYSET
                break;
             }
         }
         else
         {
             // unexpected error
             break;
         }
       }  // outer else
    } // while

    Friday, April 3, 2009 12:35 AM
  • Not really the answer you were looking for, but if you check btsearch sample in Windows Mobile 6 SDK, they allocate 5000 bytes from the get-go and don't seem to ever need a reallocation. It might be a bug, but the workaround seems to work. Also, notice that the pwsaResults->dwSize  is set to  sizeof(WSAQUERYSET) and not to the size of the entire buffer

     union {
      CHAR buf[5000];    // returned struct can be quite large
      SOCKADDR_BTH __unused; // properly align buffer to BT_ADDR requirements
     };

      pwsaResults = (LPWSAQUERYSET) buf;
      
      dwSize  = sizeof(buf);
      
      memset(pwsaResults,0,sizeof(WSAQUERYSET));
      pwsaResults->dwSize      = sizeof(WSAQUERYSET);
      // namespace MUST be NS_BTH for bluetooth queries
      pwsaResults->dwNameSpace = NS_BTH;
      pwsaResults->lpBlob      = NULL;
      
      // iterate through all found devices, returning name and address
      // (this sample only uses the name, but address could be used for
      // further queries)
      iResult = WSALookupServiceNext (hLookup,
       LUP_RETURN_NAME | LUP_RETURN_ADDR,
       &dwSize,
       pwsaResults);

    Alex Feinman. MVP .NET Compact Framework
    • Marked as answer by warrentang Monday, April 6, 2009 7:59 AM
    Monday, April 6, 2009 5:10 AM
  • Hi Alex,

    Making the buffer size large (to 5000) did solve the problem. Thanks a lot for your tips!

    Regards,

    Zhiheng Mao
    Wednesday, April 8, 2009 6:30 PM