WinHttpQueryDataAvailable 関数 (winhttp.h)

WinHttpQueryDataAvailable 関数は、WinHttpReadData で読み取ることができるデータの量をバイト単位で返します。

構文

WINHTTPAPI BOOL WinHttpQueryDataAvailable(
  [in]  HINTERNET hRequest,
  [out] LPDWORD   lpdwNumberOfBytesAvailable
);

パラメーター

[in] hRequest

WinHttpOpenRequest によって返される有効な HINTERNET ハンドル。 WinHttpReceiveResponse は、このハンドルに対して呼び出され、 WinHttpQueryDataAvailable が呼び出される前に完了している必要があります。

[out] lpdwNumberOfBytesAvailable

使用可能なバイト数を受け取る符号なし long 整数変数へのポインター。 WinHTTP を非同期モードで使用する場合は、常にこのパラメーターを NULL に設定し、コールバック関数でデータを取得します。これを行わないと、メモリ エラーが発生する可能性があります。

戻り値

関数が成功した場合は TRUE 、それ以外の場合 は FALSE を 返します。 拡張エラー データを取得するには、 GetLastError を呼び出します。 返されるエラー コードの中には、次のエラー コードがあります。

エラー コード 説明
ERROR_WINHTTP_CONNECTION_ERROR
サーバーとの接続がリセットまたは終了されたか、互換性のない SSL プロトコルが検出されました。 たとえば、WinHTTP バージョン 5.1 では、クライアントで明示的に有効にしない限り、SSL2 はサポートされません。
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
指定されたハンドルが正しい状態でないため、要求された操作を完了できません。
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
指定されたハンドルの種類がこの操作に対して正しくありません。
ERROR_WINHTTP_INTERNAL_ERROR
内部エラーが発生しました。
ERROR_WINHTTP_OPERATION_CANCELLED
通常、操作が完了する前に要求が操作されていたハンドルが閉じられたため、操作は取り消されました。
ERROR_WINHTTP_TIMEOUT
要求がタイムアウトしました。
ERROR_NOT_ENOUGH_MEMORY
要求された操作を完了するのに十分なメモリが使用できませんでした。 (Windows エラー コード)

解説

WinHTTP が非同期モードで使用されている場合 (つまり、WinHttpOpen でWINHTTP_FLAG_ASYNCが設定されている場合)、この関数は同期的または非同期的に動作できます。 FALSE が返された場合は失敗し、GetLastError を呼び出して拡張エラー情報を取得できます。 TRUE を返す場合は、WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE入力候補を使用して、この関数が成功したかどうかとパラメーターの値を判断します。 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR完了は、操作が非同期的に完了したが失敗したことを示します。

警告 WinHTTP を非同期モードで使用する場合は、常に lpdwNumberOfBytesAvailable パラメーターを NULL に設定し、コールバック関数で使用可能なバイト数を取得します。そうしないと、メモリ エラーが発生する可能性があります。
 
この関数は、 WinHttpReadData の後続の呼び出しによってすぐに読み取れるデータのバイト数を返します。 使用可能なデータがなく、ファイルの末尾に到達していない場合は、2 つのうちの 1 つが発生します。 セッションが同期の場合、要求はデータが使用可能になるまで待機します。 セッションが非同期の場合、関数は TRUE を返し、データが使用可能になると、WINHTTP_STATUS_CALLBACK_DATA_AVAILABLEを使用してコールバック関数を呼び出し、 WinHttpReadData を呼び出してすぐに読み取れるバイト数を示します。

残っているデータの量は、 WinHttpQueryDataAvailable の呼び出しによって示されるすべての使用可能なデータが読み取られるまで再計算されません。

応答が完全に読み取られたタイミングを判断するには、 WinHttpReadData の戻り値を使用します。

大事なWinHttpQueryDataAvailable の戻り値を使用して、応答の終了に達したかどうかを判断しないでください。すべてのサーバーが応答を適切に終了するわけではありません。また、応答が不適切に終了すると、WinHttpQueryDataAvailable はより多くのデータが予測されるためです。
 
WinHttpOpenRequest 関数によって作成され、WinHttpSendRequest によって送信される HINTERNET ハンドルの場合は、WinHttpQueryDataAvailable を使用する前に、ハンドルで WinHttpReceiveResponse の呼び出しを行う必要があります。

状態コールバック関数が WinHttpSetStatusCallback と共にインストールされている場合、WinHttpSetStatusCallback の dwNotificationFlags パラメーターに設定されている次の通知の通知は、使用可能なデータのチェックの進行状況を示します。

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
メモ Windows XP と Windows 2000 の詳細については、「 ランタイム要件」を参照してください。
 

例

次の例は、セキュリティで保護されたトランザクション セマンティクスを使用して、HTTPS サーバーからリソースをダウンロードする方法を示しています。 サンプル コードでは、WinHTTP API を初期化し、ターゲット HTTPS サーバーを選択してから、このセキュリティで保護されたリソースの要求を開いて送信します。
WinHttpQueryDataAvailable は、ダウンロードできるデータの量を決定するために要求ハンドルと共に使用され、そのデータの読み取りには WinHttpReadData が使用されます。 このプロセスは、ドキュメント全体が取得されて表示されるまで繰り返されます。

重要

可能な限り迅速にデータが必要な場合 (つまり、受信したデータを処理して解析します)、 WinHttpQueryDataAvailable と WinHttpReadData を呼び出す必要があります。 可能な限り迅速に応答全体をダウンロードしようとしている場合は、 WinHttpReadData が完了する前にバッファーがいっぱいになるため、 WinHttpReadData を直接呼び出します。

また、次のコード例では、すべてのループイテレーションに を割り当てます。 パフォーマンスが重要な運用コードの場合は、適切なサイズのバッファー (おそらく 1 メガバイト) から始めて、必要に応じてサイズを変更できます。 実際には、 WinHttpQueryDataAvailable は 8 キロバイト以下を返します。


    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
                    printf( "%s\n", 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);

要件

   
サポートされている最小のクライアント Windows XP、Windows 2000 Professional sp3 [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows Server 2003、Windows 2000 Server SP3 [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー winhttp.h
Library Winhttp.lib
[DLL] Winhttp.dll
再頒布可能パッケージ Windows XP および Windows 2000 で WinHTTP 5.0 およびインターネット エクスプローラー 5.01 以降。

関連項目

Microsoft Windows HTTP サービス (WinHTTP) について

WinHTTP バージョン

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpReadData

WinHttpSendRequest