Jeff Sanders Technical Blog

I am a Microsoft employee that has worked on all aspects of the Web Stack for a long time. I hope these blogs are useful to you! Use this information at your own risk.


<< Go Back

Winhttpwritedata Will Fail With Error_invalid_parameter If You Are Trying To Send More Data Than Specified In Winhttpsendrequest On Windows 7 By Design

- 13 Oct 2009

There are new checks in Windows 7 to prevent you from doing bad things with the WinHttp APIs.  In the sample code below, I do not get an error pre-Windows 7 but on Windows 7 the WinHttpWriteData call results in bResults being 0 and GetLastError() returns 87 (ERROR_INVALID_PARAMETER):

LPSTR pszData = “WinHttpWriteData Example”;

LPSTR pszMoreData = “WinHttpWriteData Example”;

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

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

Looking at a Network Monitor trace, you see something very strange in the HTTP traffic pre Windows 7:

You see a POST – Http: Request, POST /ReadAll.asp ContentLength:  24 and the text I sent: HTTPPayloadLine: WinHttpWriteData Example

and then the successful return code from the server -Http: Response, HTTP/1.1, Status Code = 200, URL: /ReadAll.asp

But the following bunch of Data in the next frame! – HtmlPayload: WinHttpWriteData Example

So the POST is being sent, then more data after the initial POST and 200 OK response from the server!

Looking at the headers, you can see the Content-Length is set to 24 (this is what you set in WinHttpSendRequest the dwTotalLength = strlen(pszData)), and that is why the server returns 200 (because as far as it is concerned you told it you were sending only 24 bytes of data and that was what your client had sent).  However the extra 24 bytes of data gets sent by the WinHttpWriteData call!

For Windows 7, a check was put in place internally to prevent you from making such a bad protocol violation.  Now WinHttpWriteData will return 0 and GetLastError() will indicate 87 which means that you have passed invalid data.  In this case the length of the data you intend to write exceeded what you set as the content length in WinHttpSendRequest!  The fix is for you to correct your buggy code and indicate the correct content length by setting the dwTotalLength parameter correctly in the call to WinHttpSendRequest.  In this case I can change the code to this:

 

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

Please drop me a comment if you found this helpful!

Reference: http://msdn.microsoft.com/en-us/library/aa384110(VS.85).aspx

<< Go Back