WinHttpWriteData 関数 (winhttp.h)

WinHttpWriteData 関数は、要求データを HTTP サーバーに書き込みます。

構文

WINHTTPAPI BOOL WinHttpWriteData(
  [in]  HINTERNET hRequest,
  [in]  LPCVOID   lpBuffer,
  [in]  DWORD     dwNumberOfBytesToWrite,
  [out] LPDWORD   lpdwNumberOfBytesWritten
);

パラメーター

[in] hRequest

WinHttpOpenRequest によって返される有効な HINTERNET ハンドル。 この関数を呼び出す前に、 WinHttpSendRequest が完了するまで待ちます。

[in] lpBuffer

サーバーに送信されるデータを含むバッファーへのポインター。 このバッファーは、 WinHttpWriteData が完了するまで有効なままであることを確認してください。

[in] dwNumberOfBytesToWrite

ファイルに書き込むバイト数を含む符号なし long 整数値。

[out] lpdwNumberOfBytesWritten

バッファーに書き込まれたバイト数を受け取る符号なし長整数変数へのポインター。 WinHttpWriteData 関数は、作業またはエラー チェックを実行する前に、この値を 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_TIMEOUT
要求がタイムアウトしました。
ERROR_NOT_ENOUGH_MEMORY
要求された操作を完了するのに十分なメモリが使用できませんでした。 (Windows エラー コード)

解説

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

警告 WinHTTP を非同期的に使用する場合は、常に lpdwNumberOfBytesWritten パラメーターを NULL に設定し、コールバック関数で書き込まれたバイトを取得します。そうしないと、メモリ エラーが発生する可能性があります。
 
アプリケーションがデータを送信しているときに、 WinHttpReceiveResponse を呼び出してデータ転送を終了できます。 WinHttpCloseHandle が呼び出されると、データ転送は中止されます。

状態コールバック関数が WinHttpSetStatusCallback と共にインストールされている場合、WinHttpSetStatusCallbackdwNotificationFlags パラメーターに設定されている次の通知の通知は、サーバーへのデータ送信の進行状況を示します。

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_WRITTEN
  • WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
  • WINHTTP_CALLBACK_STATUS_REQUEST_SENT
  • WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
NTLM またはネゴシエート認証を使用してチャレンジするプロキシまたはサーバーにデータを POST (または PUT) しようとすると、2 つの問題が発生する可能性があります。 最初に、これらのプロキシまたはサーバーは 401/407 チャレンジを送信し、すべてのデータを POST する前に接続を閉じることがあります。その場合、 WinHttpWriteData は失敗するだけでなく、WinHTTP は認証チャレンジを処理できません。 NTLM とネゴシエートでは、すべての認証ハンドシェイクを同じソケット接続で交換する必要があるため、接続が途中で切断された場合、認証は失敗します。

第 2 に、NTLM とネゴシエートでは、認証を完了するために複数のハンドシェイクが必要になる場合があります。これにより、認証区間ごとにデータを再 POST する必要があります。 これは、大規模なデータアップロードでは非常に非効率的な場合があります。

これら 2 つの問題を回避するには、1 つの解決策として、最初に認証 v-dir にHEADなどのべき等のウォームアップ要求を送信し、この要求に関連付けられている認証チャレンジを処理し、次に POST データのみを送信します。 同じソケットが POST の処理に再利用されている限り、それ以上の認証の課題は発生せず、すべてのデータを一度にアップロードできます。 認証されたソケットは、同じセッション内の後続の要求に対してのみ再利用できるため、ソケットが競合する同時実行要求とプールされていない限り、POST は同じソケットに出力する必要があります。

メモ Windows XP と Windows 2000 については、WinHTTP スタート ページの 「ランタイム要件 」セクションを参照してください。
 

この例では、HTTP サーバーにデータを書き込むコードを示します。 この例で指定したサーバー名 (www.wingtiptoys.com) は架空のものであり、書き込みアクセス権を持つサーバーの名前に置き換える必要があります。

    PCSTR pszData = "WinHttpWriteData Example";
    DWORD dwBytesWritten = 0;
    BOOL  bResults = FALSE;
    HINTERNET hSession = NULL,
              hConnect = NULL,
              hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(  L"A WinHTTP Example Program/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.wingtiptoys.com",
                                   INTERNET_DEFAULT_HTTP_PORT, 0);

    // Create an HTTP Request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest( hConnect, L"PUT", 
                                       L"/writetst.txt", 
                                       NULL, WINHTTP_NO_REFERER, 
                                       WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                       0);

    // Send a Request.
    if (hRequest) 
        bResults = WinHttpSendRequest( hRequest, 
                                       WINHTTP_NO_ADDITIONAL_HEADERS,
                                       0, WINHTTP_NO_REQUEST_DATA, 0, 
                                       (DWORD)strlen(pszData), 0);

    // Write data to the server.
    if (bResults)
        bResults = WinHttpWriteData( hRequest, pszData, 
                                     (DWORD)strlen(pszData), 
                                     &dwBytesWritten);

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse( hRequest, NULL);

    // Report any errors.
    if (!bResults)
        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 Services (WinHTTP) について

WinHTTP バージョン

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest