Microsoft KB Archive/246689

= How To Use WSAIoctl with SIO_GET_QOS =

Article ID: 246689

Article Last Modified on 2/22/2007

-

APPLIES TO


 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Professional Edition
 * Microsoft Windows 98 Standard Edition

-



This article was previously published under Q246689



SUMMARY
The version of the GQoS on Windows 2000 is version 4 (GQoSv4). The version of the GQoS on Windows 98 and Microsoft Windows 98 Second Edition is version 1 (GQoSv1). The WSAEnumProtocols function can be used to determine the version of the GQoS.

Using WSAIoctl with the SIO_GET_QOS control code can be different because GQoSv4 and GQoSv1 differ in how the API can and must be called. The differences are as follows:
 * GQoSv4 allows you to query the system to determine how large an output buffer you need in order to retrieve the QOS structure(s) whereas with GQoSv1 you must pass in a large enough buffer.
 * GQoSv4 requires the output buffer to be contiguous whereas GQoSv1 does not.
 * GQoSv4 requires that the supplied output buffer be large enough to contain all the Quality of Service (QOS) data (specifically the variable length provider-specific data in addition to the fixed size flowspec data); otherwise, none of the information will be returned, whereas GQoSv1 returns the portion of the provider-specific data (complete provider-specific QOS objects only) that can fit in the supplied provider-specific buffer.
 * GQoSv1 requires that the output buffer be initialized so that the provider-specific pointer in the QOS structure points to valid memory, whereas GQoSv4 treats the buffer strictly as an output-only parameter (as it should).

As background, the WSAIoctl function is called with the SIO_GET_QOS control code to retrieve one or more QOS structures from the system. Typically this is done in response to the receipt of an FD_QOS as a result of using either the WSAAsyncSelect or WSAEventSelect function. A high performance server application that utilizes Quality of Service most likely would not call either WSAAsyncSelect or WSAEventSelect but would instead call WSAIoctl(SIO_GET_QOS) in an overlapped manner, perhaps even by using I/O Completion Ports (IOCP).



MORE INFORMATION
The following code snippet demonstrates a technique that can be used to call WSAIoctl with the SIO_GET_QOS control code on either GQoSv1 or GQoSv4, and takes into account the differences outlined earlier: DWORD  dwBytesReturned=0; DWORD  status; DWORD  dwBufferLen; CHAR   *pBuf = NULL; QOS    *pTempQos = NULL; QOS    *pQos = NULL;

if (GQOSv1) // For GQOSv1 we must pick a buffer size dwBufferLen = 2048; else {       // For GQOSv4 we can query the system to determine // how large a buffer we need to pass in. dwBufferLen = 0; status = WSAIoctl(sd, SIO_GET_QOS, NULL, 0,                   &dwBufferLen, sizeof(dwBufferLen),                    &dwBytesReturned, NULL, NULL); if (SOCKET_ERROR == status) {           DWORD dwErr = WSAGetLastError; if (WSAEWOULDBLOCK == dwErr) {               // nothing to do                return(FALSE); }           else if (WSAENOBUFS != dwErr) {               // some sort of error not related to passing a                // large enough buffer printf("WSAIoctl(SIO_GET_QOS)-query: %d\n",dwErr); return(FALSE); }           }        }

// For Windows 98 dwBufferLen has been set above, for // Windows 2000 we queried the OS for the proper buffer size printf("dwBufferlen for pQos = %d\n", dwBufferLen); if (!(pBuf = (CHAR *)malloc(dwBufferLen))) {       printf("malloc: %d\n", GetLastError); return(FALSE); }

// GQOSv1 workaround - not needed for GQOSv4, but doesn't   // hurt. GQOSv1 needs the provider specific buffer to point // to valid memory, whereas GQOSv4 simply needs a contiguous // block of memory. Therefore we allocate a contiguous block of   // memory cast it to a QOS structure and then set the provider // specific buffer pointer to just beyond the QOS structure // proper. GQOSv1 needs this whereas GQOSv4 ignores this. // GQOSv1 should not care, because this is strictly an output // buffer, GQOSv4 corrects this problem. pTempQos = (QOS *)pBuf; pTempQos->ProviderSpecific.buf = pBuf + sizeof(QOS); pTempQos->ProviderSpecific.len = dwBufferLen - sizeof(QOS); // end GQOSv1 workaround

status = WSAIoctl(sd, SIO_GET_QOS, NULL, 0,                  pBuf, dwBufferLen, &dwBytesReturned,                   NULL, NULL); if (SOCKET_ERROR == status) {       DWORD dwErr = WSAGetLastError; free((char *)pBuf); if (WSAEWOULDBLOCK != dwErr) {           printf("WSAIoctl(SIO_GET_QOS) %d\n", dwErr); }       return(FALSE); }   pQos = (QOS *)pBuf;

Keywords: kbdswnet2003swept kbapi kbgqos kbhowto kbnetwork KB246689

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.