WinHttpQueryDataAvailable

 

Description

 

The WinHttpQueryDataAvailable function returns the amount of data, in bytes, available to be read with WinHttpReadData.

 

C/C++ Syntax

 

BOOL WinHttpQueryDataAvailable(

HINTERNET hRequest,

LPDWORD lpdwNumberOfBytesAvailable

);

 

PowerBASIC Syntax

 

FUNCTION WinHttpQueryDataAvailable ( _

BYVAL hRequest AS DWORD, _

BYREF lpdwNumberOfBytesAvailable AS DWORD _

) AS LONG

 

Parameters

 

hRequest

 

[in] A valid HINTERNET handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have completed before WinHttpQueryDataAvailable is called.

 

lpdwNumberOfBytesAvailable

 

[out, optional] A pointer to an unsigned long integer variable that receives the number of available bytes. When WinHTTP is used in asynchronous mode, always set this parameter to NULL and retrieve data in the callback function; not doing so can cause a memory fault.

 

Return Value

 

Returns TRUE if the function succeeds, or FALSE otherwise. To get extended error data, call GetLastError. Among the error codes returned are:

 

Error Codes

Description

ERROR_WINHTTP_CONNECTION_ERROR

The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it.

ERROR_WINHTTP_INCORRECT_HANDLE_STATE

The requested operation cannot complete because the handle supplied is not in the correct state.

ERROR_WINHTTP_INCORRECT_HANDLE_TYPE

The type of handle supplied is incorrect for this operation.

ERROR_WINHTTP_INTERNAL_ERROR

An internal error has occurred.

ERROR_WINHTTP_OPERATION_CANCELLED

The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.

ERROR_WINHTTP_TIMEOUT

The request has timed out.

ERROR_NOT_ENOUGH_MEMORY

Not enough memory was available to complete the requested operation. (Windows error code)

 

Remarks

 

Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function can operate either synchronously or asynchronously. If it returns FALSE, it failed and you can call GetLastError to get extended error information. If it returns TRUE, use the WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE completion to determine whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed.

 

Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesAvailable parameter to NULL and retrieve the bytes available in the callback function; otherwise, a memory fault can occur.

 

This function returns the number of bytes of data that are available to read immediately by a subsequent call to WinHttpReadData. If no data is available and the end of the file has not been reached, one of two things happens. If the session is synchronous, the request waits until data becomes available. If the session is asynchronous, the function returns TRUE, and when data becomes available, calls the callback function with WINHTTP_STATUS_CALLBACK_DATA_AVAILABLE and indicates the number of bytes immediately available to read by calling WinHttpReadData.

 

The amount of data that remains is not recalculated until all available data indicated by the call to WinHttpQueryDataAvailable is read.

 

Use the return value of WinHttpReadData to determine when a response has been completely read.

 

Important Do not use the return value of WinHttpQueryDataAvailable to determine whether the end of a response has been reached, because not all servers terminate responses properly, and an improperly terminated response causes WinHttpQueryDataAvailable to anticipate more data.

 

For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse must be made on the handle before WinHttpQueryDataAvailable can be used.

 

If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for available data:

 

WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE

WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED

WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE

 

Example Code [PowerBASIC]

 

The following example shows how to use secure transaction semantics to download a resource from an HTTPS server. The sample code initializes the WinHTTP API, selects a target HTTPS server, and then opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much data is available for download, then WinHttpReadData is used to read that data. This process repeats until the entire document has been retrieved and displayed.

 

#COMPILE EXE

#DIM ALL

#INCLUDE "WIN32API.INC"

#INCLUDE "WINHTTP.INC"

 

FUNCTION PBMAIN () AS LONG

 

 LOCAL dwSize AS DWORD

 LOCAL dwDownloaded AS DWORD

 LOCAL bResults AS LONG

 LOCAL hSession AS DWORD

 LOCAL hConnect AS DWORD

 LOCAL hRequest AS DWORD

 LOCAL strUserAgent AS STRING

 LOCAL strServerName AS STRING

 LOCAL strVerb AS STRING

 LOCAL strOutBuffer AS STRING

 

 dwSize = 4  ' size of a DWORD

 

 ' Use WinHttpOpen to obtain a session handle.

 strUserAgent = UCODE$("A WinHTTP Example Program/1.0" & $NUL)

 hSession = WinHttpOpen(STRPTR(strUserAgent), _

                        %WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, _

                        %WINHTTP_NO_PROXY_NAME, _

                        %WINHTTP_NO_PROXY_BYPASS, _

                        0)

 

 ' Specify an HTTP server.

 IF hSession THEN

    strServerName = UCODE$("www.microsoft.com" & $NUL)

    hConnect = WinHttpConnect(hSession, _

                              STRPTR(strServerName), _

                              %INTERNET_DEFAULT_HTTP_PORT, _

                              0)

 END IF

 

 

 ' Create an HTTP Request handle.

 IF hConnect THEN

    strVerb = UCODE$("GET" & $NUL)

    hRequest = WinHttpOpenRequest(hConnect, _

                                  STRPTR(strVerb), _

                                  %NULL,  _

                                  %NULL, _

                                  %WINHTTP_NO_REFERER, _

                                  BYVAL %WINHTTP_DEFAULT_ACCEPT_TYPES, _

                                  0)

 END IF

 

 ' Send a Request.

 ' Note: The Microsoft C example uses WINHTTP_FLAG_SECURE for the last

 ' parameter, but I have changed it to 0 because, otherwise, it returns

 ' error 12175 (ERROR_WINHTTP_SECURE_FAILURE)

 IF hRequest THEN

    bResults = WinHttpSendRequest(hRequest, _

                                  %WINHTTP_NO_ADDITIONAL_HEADERS, _

                                  0, _

                                  %WINHTTP_NO_REQUEST_DATA, _

                                  0, _

                                  0, _

                                  0)

 END IF

 

 ' End the request.

 IF bResults THEN

    bResults = WinHttpReceiveResponse(hRequest, %NULL)

 END IF

 

 ' Keep checking for data until there is nothing left.

 IF bResults THEN

    DO

       ' Check for available data.

       dwSize = 0

       IF ISFALSE WinHttpQueryDataAvailable(hRequest, dwSize) THEN

          PRINT "Error " GetLastError " in WinHttpQueryDataAvailable."

          EXIT DO

       ELSE

          ' Allocate space for the buffer.

          strOutBuffer = STRING$(dwSize + 1, $NUL)

          ' Read the data.

          IF ISFALSE WinHttpReadData(hRequest, STRPTR(strOutBuffer), _

                                     dwSize, dwDownloaded) THEN

             PRINT "Error " GetLastError " in WinHttpReadData."

          ELSE

             STDOUT strOutBuffer

          END IF

       END IF

    LOOP WHILE dwSize > 0

 END IF

 

 ' Report any errors.

 IF ISFALSE bResults THEN

    PRINT "Error " GetLastError " has occurred."

 END IF

 

 ' Close open handles.

 IF hRequest THEN WinHttpCloseHandle(hRequest)

 IF hConnect THEN WinHttpCloseHandle(hConnect)

 IF hSession THEN WinHttpCloseHandle(hSession)

 

 WAITKEY$

 

END FUNCTION

 

Example Code [C++]

 

DWORD dwSize = 0;

DWORD dwDownloaded = 0;

LPSTR pszOutBuffer;

BOOL  bResults = FALSE;

HINTERNET  hSession = NULL,

         hConnect = NULL,

         hRequest = NULL;

 

// Use WinHttpOpen to obtain a session handle.

hSession = WinHttpOpen( L"WinHTTP Example/1.0",

                      WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,

                      WINHTTP_NO_PROXY_NAME,

                      WINHTTP_NO_PROXY_BYPASS, 0);

 

// Specify an HTTP server.

if (hSession)

  hConnect = WinHttpConnect( hSession, L"www.microsoft.com",

                             INTERNET_DEFAULT_HTTPS_PORT, 0);

 

// Create an HTTP request handle.

if (hConnect)

  hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,

                                 NULL, WINHTTP_NO_REFERER,

                                 WINHTTP_DEFAULT_ACCEPT_TYPES,

                                 WINHTTP_FLAG_SECURE);

 

// Send a request.

if (hRequest)

  bResults = WinHttpSendRequest( hRequest,

                                 WINHTTP_NO_ADDITIONAL_HEADERS,

                                 0, WINHTTP_NO_REQUEST_DATA, 0,

                                 0, 0);

 

// End the request.

if (bResults)

  bResults = WinHttpReceiveResponse( hRequest, NULL);

 

// Continue to verify data until there is nothing left.

if (bResults)

  do

  {

 

      // Verify available data.

      dwSize = 0;

      if (!WinHttpQueryDataAvailable( hRequest, &dwSize))

          printf( "Error %u in WinHttpQueryDataAvailable.\n",

                  GetLastError());

 

      // Allocate space for the buffer.

      pszOutBuffer = new char[dwSize+1];

      if (!pszOutBuffer)

      {

          printf("Out of memory\n");

          dwSize=0;

      }

      else

      {

          // Read the Data.

          ZeroMemory(pszOutBuffer, dwSize+1);

 

          if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,

                                dwSize, &dwDownloaded))

              printf( "Error %u in WinHttpReadData.\n",

                      GetLastError());

          else

              cout << pszOutBuffer;

 

          // Free the memory allocated to the buffer.

          delete [] pszOutBuffer;

      }

 

  } while (dwSize>0);

 

 

// Report any errors.

if (!bResults)

  printf("Error %d has occurred.\n",GetLastError());

 

// Close open handles.

if (hRequest) WinHttpCloseHandle(hRequest);

if (hConnect) WinHttpCloseHandle(hConnect);

if (hSession) WinHttpCloseHandle(hSession);

 

Valid XHTML 1.0 Transitional