WinHttpReadData 関数 (winhttp.h)

WinHttpReadData 関数は、WinHttpOpenRequest 関数によって開かれたハンドルからデータを読み取ります。

「 WinHttpReadDataEx」も参照してください。

構文

WINHTTPAPI BOOL WinHttpReadData(
  [in]  HINTERNET hRequest,
  [out] LPVOID    lpBuffer,
  [in]  DWORD     dwNumberOfBytesToRead,
  [out] LPDWORD   lpdwNumberOfBytesRead
);

パラメーター

[in] hRequest

WinHttpOpenRequest の以前の呼び出しから返された有効な HINTERNET ハンドル。 WinHttpReceiveResponse または WinHttpQueryDataAvailable は、このハンドルに対して呼び出されている必要があり、 WinHttpReadData が呼び出される前に完了している必要があります。 WinHttpReceiveResponse の完了後すぐに WinHttpReadData を呼び出すとバッファー コピーのコストは回避されますが、これを行うには、アプリケーションが読み取りに固定長バッファーを使用する必要があります。

[out] lpBuffer

読み取られたデータを受け取るバッファーへのポインター。 WinHttpReadData が完了するまで、このバッファーが有効なままであることを確認します。

[in] dwNumberOfBytesToRead

読み取るバイト数を含む符号なし long 整数値。

[out] lpdwNumberOfBytesRead

読み取られたバイト数を受け取る符号なし long 整数変数へのポインター。 WinHttpReadData は、作業またはエラー チェックを行う前に、この値を 0 に設定します。 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_RESPONSE_DRAIN_OVERFLOW
受信応答が内部 WinHTTP サイズ制限を超えたときに返されます。
ERROR_WINHTTP_TIMEOUT
要求がタイムアウトしました。
ERROR_NOT_ENOUGH_MEMORY
要求された操作を完了するのに十分なメモリが使用できませんでした。 (Windows エラー コード)

注釈

Windows Vista および Windows Server 2008 以降では、WinHttp を使用すると、アプリケーションはサーバーに送信されるデータに対してチャンク転送エンコードを実行できます。 Transfer-Encoding ヘッダーが WinHttp 応答に存在する場合、 WinHttpReadData は、アプリケーションにデータを渡す前にチャンク情報を削除します。

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

警告 WinHTTP を非同期モードで使用する場合は、常に lpdwNumberOfBytesRead パラメーターを NULL に設定し、コールバック関数で読み取られたバイト数を取得します。そうしないと、メモリ エラーが発生する可能性があります。
 
読み取りバッファーが非常に小さい場合、 WinHttpReadData は同期的に完了する可能性があります。 WINHTTP_CALLBACK_STATUS_READ_COMPLETE完了によって WinHttpReadData の別の呼び出しがトリガーされると、スタック オーバーフローが発生する可能性があります。 一般に、サイズに匹敵する読み取りバッファー、または WinHTTP で使用される内部読み取りバッファー (8 KB) よりも大きい読み取りバッファーを使用することをお勧めします。

WinHttpReadData を同期的に使用していて、戻り値が TRUE で、読み取られたバイト数が 0 の場合、転送は完了し、ハンドルで読み取るバイト数はこれ以上ありません。 これは、ローカル ファイル内のファイルの末尾に到達することに似ています。 関数を非同期的に使用している場合は、応答の末尾が見つかったときに dwStatusInformationLength パラメーターを 0 に設定して、WINHTTP_CALLBACK_STATUS_READ_COMPLETE コールバックが呼び出されます。

WinHttpReadData は、応答から使用できるデータがなくなったまで、 lpBuffer が指すバッファーを埋めようとします。 サーバーから十分なデータが到着していない場合、バッファーは入力されません。

WinHttpOpenRequest 関数によって作成され、WinHttpSendRequest によって送信される HINTERNET ハンドルの場合、WinHttpReadData を使用するには、そのハンドルで WinHttpReceiveResponse の呼び出しを行う必要があります。

WinHttpReadData で取得された 1 バイト文字は、マルチバイト文字に変換されません。

読み取りバッファーが非常に小さい場合、 WinHttpReadData が同期的に完了し、 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 完了によって WinHttpReadData への別の呼び出しがトリガーされると、スタック オーバーフローが発生する可能性があります。 8 キロバイト以上のサイズの読み取りバッファーを使用することをお勧めします。

サーバーから十分なデータが到着していない場合、 WinHttpReadData は lpBuffer が指すバッファー全体を埋めるわけではありません。 バッファーは、最初の読み取り時に HTTP ヘッダーを保持するのに少なくとも十分な大きさである必要があります。また、HTML でエンコードされたディレクトリ エントリを読み取る場合は、少なくとも 1 つの完全なエントリを保持するのに十分な大きさである必要があります。

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

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
メモ Windows XP および Windows 2000 の場合は、WinHttp スタート ページの 「ランタイム要件 」セクションを参照してください。
 

例

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

    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);

    // Keep checking for data until there is nothing left.
    if (bResults)
    {
        do 
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) 
            {
                printf( "Error %u in WinHttpQueryDataAvailable.\n",
                        GetLastError());
                break;
            }
            
            // No more available data.
            if (!dwSize)
                break;

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                break;
            }
            
            // Read the Data.
            ZeroMemory(pszOutBuffer, dwSize+1);

            if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                  dwSize, &dwDownloaded))
            {                                  
                printf( "Error %u in WinHttpReadData.\n", GetLastError());
            }
            else
            {
                printf("%s", pszOutBuffer);
            }
        
            // Free the memory allocated to the buffer.
            delete [] pszOutBuffer;

            // This condition should never be reached since WinHttpQueryDataAvailable
            // reported that there are bits to read.
            if (!dwDownloaded)
                break;
                
        } while (dwSize > 0);
    }
    else
    {
        // Report any errors.
        printf( "Error %d has occurred.\n", GetLastError() );
    }

    // Close any 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

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData