Article ID: 250461
Article Last Modified on 2/28/2007
APPLIES TO
- Microsoft Windows 2000 Server
- Microsoft Windows 2000 Advanced Server
- Microsoft Windows 2000 Professional Edition
This article was previously published under Q250461
SYMPTOMS
When you are doing a namespace query for the SVCID_HOSTNAME globally unique identifier (GUID) and use the WSALookupServiceNext Winsock API to dynamically determine the buffer size required for the WSAQUERYSET, the subsequent call to WSALookupServiceNext with the allocated buffer returns incomplete data and should not be relied upon.
RESOLUTION
To work around this problem, you can allocate an appropriately sized buffer before you make the first call to WSALookupServiceNext.
STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.
MORE INFORMATION
The following code exhibits the bug on Windows 2000, whereas on Windows NT 4.0 this code works as expected.
If you uncomment the lines noted in the code, the call works because the buffer is allocated beforehand.
#include <stdio.h> // Standard I/O #include <winsock2.h> // winsock 2.0 #include <svcguid.h> // guids int main(int argc, char * argv[]) { WSADATA wsaData; DWORD dwResult; HANDLE hLookup = 0; WSAQUERYSET lpRestrictions; GUID guid = SVCID_HOSTNAME; dwResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (dwResult != 0) { printf("Cannot startup Winsock: %d\n", dwResult); exit(1); } ZeroMemory(&lpRestrictions, sizeof(WSAQUERYSET)); lpRestrictions.dwSize = sizeof(WSAQUERYSET); lpRestrictions.lpServiceClassId = &guid; dwResult = WSALookupServiceBegin(&lpRestrictions, LUP_RETURN_NAME, &hLookup); if (dwResult != SOCKET_ERROR) { DWORD dwLength = 0; WSAQUERYSET * pqs = NULL; // // picking an arbitrary value works fine // // UNCOMMENT below for success on Windows 2000 // // pqs = (WSAQUERYSET *) malloc(sizeof(WSAQUERYSET) + 100); // dwLength = sizeof(WSAQUERYSET) + 100; // do { if (WSALookupServiceNext(hLookup, 0, &dwLength, pqs) != 0) dwResult = WSAGetLastError(); else dwResult = 0; if (dwResult == WSAEFAULT) { if (pqs) free(pqs); pqs = (WSAQUERYSET *) malloc(dwLength); if (!pqs) { printf("Could not allocate memory: %d\n", GetLastError()); exit(2); } else continue; } // output it since we have it now if ((dwResult == 0) && (pqs)) printf("%s\n", pqs->lpszServiceInstanceName); } while ((dwResult != WSA_E_NO_MORE) && (dwResult != WSAENOMORE)); // clean-up free(pqs); WSALookupServiceEnd(hLookup); } else { printf("Error on WSALookupServiceBegin: %d\n", WSAGetLastError()); exit(3); } WSACleanup(); return 0; }
Keywords: kbapi kbbug kbnetwork kbwinsock KB250461