WinHttpReadData in Win32 app dont work properly - c++

I use WinHTTP to get text from URL http://www.google.com/complete/search?output=toolbar&hl=vi&q=hoazzztf. The reponse text must be: <toplevel/> but I get the reponse like this:
Any idea? Thank!
(Reponse text may contains UTF-8 character)
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BOOL bResults = FALSE;
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
WinHttpSetTimeouts(hSession, 1000, 2000, 1000, 1000);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, L"www.google.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/complete/search?output=toolbar&hl=vi&q=hoazzztf",
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);
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults)
{
SetWindowText(hWnd, L"ERR-4");
break;
}
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
break;
}
// No more available data.
if (!dwSize)
break;
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
{
break;
}
// Read the Data.
ZeroMemory((LPVOID)pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
{
}
else
{
MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);
}
// 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);
}
// Report any errors.
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);

WinHttpReadData reads raw data, but you forced it to be an array of 2-byte WCHAR's. I think google uses utf-8 encoding on their pages, so you need to convert it first.
Another problem in your code is that you don't set terminating 0:
...
else
{
pszOutBuffer[ dwDownloaded ] = 0;
MessageBox(hWnd, pszOutBuffer, "", NULL);
}
Then, checking value returned by new is senseless, because new throws an exception in case of failure.

I fixed:
MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);
to:
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, NULL, 0);
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, wstr, wchars_num);

Related

POST Request in WinHttp c++

I'm trying to make a POST request in c++ with the WinHTTP api Click to the Microsoft Guide, the problem is that the example that is available in the microsoft webpage is a "GET" request so I came up with this code searching on the internet:
First we call the code:
HttpsWebRequestPost("example.com", "/api.php?action=UserLogin", "loginUsername=" + USERNAME + "&loginPassword=" + PASSWORD + "&url=/index.php?page=Portal");
Then:
#include <Windows.h>
#include <WinHttp.h>
#include <stdio.h>
#include <iostream> //getchar
#include <fstream>
#pragma comment(lib, "winhttp.lib")
using namespace std;
std::wstring get_utf16(const std::string &str, int codepage)
{
if (str.empty()) return std::wstring();
int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
std::wstring res(sz, 0);
MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
return res;
}
string HttpsWebRequestPost(string domain, string url, string dat)
{
//Extra
LPSTR data = const_cast<char *>(dat.c_str());;
DWORD data_len = strlen(data);
wstring sdomain = get_utf16(domain, CP_UTF8);
wstring surl = get_utf16(url, CP_UTF8);
string response;
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, sdomain.c_str(),
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", surl.c_str(),
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)data, data_len,
data_len, 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());
// 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", pszOutBuffer);
response = response + string(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 any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
return response;
}
But using WireShark I only get:
Hypertext Transfer Protocol
POST ***************** HTTP/1.1\r\n
Connection: Keep-Alive\r\n
User-Agent: WinHTTP Example/1.0\r\n
Content-Length: **\r\n
Host: ******\r\n
\r\n
Anyone can help meto fix this or know an easier method?
Thanks
In order for PHP (or any other post-processing language) to recognise POST data, add this:
LPCWSTR additionalHeaders = L"Content-Type: application/x-www-form-urlencoded\r\n";
DWORD headersLength = -1;
bResults = WinHttpSendRequest( hRequest,
additionalHeaders,
headersLength ,
(LPVOID)data,
data_len,
data_len,
0);
The rest of a code is functional, should work:
The following code works for me when I tried to post text in key(info) and value(this is some info) pair. The status code 200 returned at the end.
int main()
{
DWORD dwSize = 0;
LPVOID lpOutBuffer = NULL;
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);
std::wstring url{ L"http://app.pomdit.com:3010/uploadfile" };
URL_COMPONENTS components{};
components.dwStructSize = sizeof(components);
components.dwHostNameLength = (DWORD)-1;
components.dwUrlPathLength = (DWORD)-1;
if (!WinHttpCrackUrl(url.c_str(), static_cast<DWORD>(url.length()), 0, &components)) {
wprintf((L"WinHttpCrackUrl(): " + ErrorMessage(GetLastError())).c_str());
}
std::wstring hostName(components.lpszHostName ? std::wstring{ components.lpszHostName, components.dwHostNameLength } : L"localhost");
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, hostName.c_str(),
components.nPort, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", components.lpszUrlPath,
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
const WCHAR* ContentType =
L"Content-Type: multipart/form-data;boundary = 19024605111143684786787635207";
const char* MultipartRequestBody =
"--19024605111143684786787635207\r\n"
"Content-Disposition: form-data; name=\"info\"\r\n"
"\r\n"
"this is some info\r\n"
"--19024605111143684786787635207\r\n";
bResults = WinHttpSendRequest(hRequest, ContentType, wcslen(ContentType),
(LPVOID)MultipartRequestBody,
strlen(MultipartRequestBody),
strlen(MultipartRequestBody),
NULL);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
// First, use WinHttpQueryHeaders to obtain the size of the buffer.
if (bResults)
{
DWORD status{}, len = sizeof(status);
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &len, NULL);
if (bResults)
{
printf("Status code = %d.\n", status);
}
}
else
{
wprintf(L"WinHttpReceiveResponse(): %s\n", ErrorMessage(GetLastError()).c_str());
}
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
}

Prevent winHTTP From Writing to STDOUT

I've taken the following code from a previous SO post:
//Variables
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
std::vector <std::string> vFileContent;
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"stackoverflow.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"GET", L"/questions/ask/",
NULL, WINHTTP_NO_REFERER,
NULL,
NULL);
// 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());
// 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", pszOutBuffer);
// Data in vFileContent
vFileContent.push_back(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 any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
// Write vFileContent to file
std::ofstream out("./SO/ask.html",std::ios::app);
for (int i = 0; i < (int) vFileContent.size();i++)
out << vFileContent[i];
out.close();
When run it downloads the file and prints it's data. I looked through the code, and couldn't find where it was writing the data to STDOUT. Can someone tell me where it's coming from and how to prevent it?
The line:
printf("%s", ppszOutBuffer);
I believe is the reason here.

Winhttp request give error Error 87 has occurred. Could not close the hSession handle for post json request

hi i am implementing post json request with winhttp function. though no error in code but at time of execution i cant get proper output for it. it gives me error for it like Error 87 has occurred. Could not close the hSession handle. it means open and is not able to be close please give me suggestions how should i remove that error. here is my code
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
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"localhost",
INTERNET_DEFAULT_HTTPS_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"POST", L":8080/hellowword.jsp",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
TCHAR* szHeaders = _T("Content-Type:application/json\r\n");
TCHAR* szPostData = _T("{\"command\":\"remotecontrol\",\"method\":\"countmon.getgatestatus\",\"param\":\"2\"}");
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
szHeaders, _tcslen(szHeaders),
szPostData, _tcslen(szPostData)
,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);
system("pause");
return 0;
}

WCHAR to String, how do i do it?

String* Adder::downloadUrl(String* url)
{
DWORD dwSize = 0;
LPVOID lpOutBuffer = NULL;
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.google.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
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,
0, 0);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);
// First, use WinHttpQueryHeaders to obtain the size of the buffer.
if (bResults)
{
WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX, NULL,
&dwSize, WINHTTP_NO_HEADER_INDEX);
// Allocate memory for the buffer.
if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER )
{
lpOutBuffer = new WCHAR[dwSize/sizeof(WCHAR)];
// Now, use WinHttpQueryHeaders to retrieve the header.
bResults = WinHttpQueryHeaders( hRequest,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
lpOutBuffer, &dwSize,
WINHTTP_NO_HEADER_INDEX);
}
}
// Print the header contents.
if (bResults)
printf("Header contents: \n%S",lpOutBuffer);
// Free the allocated memory.
delete [] lpOutBuffer;
// 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);
String* retOne;
return retOne;
}
I want to get response as string i am using dll in C#, dont know vc++ at all, please suggest a way.
String* retOne //how to get response;
return retOne;
UPDATE
// Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr)
{
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
String* retOne = utf8_encode(lpOutBuffer);
Gives error: 'utf8_encode' : cannot convert parameter 1 from 'LPVOID' to 'const std::wstring
Please don't post comments suggesting use of .net libraries.
Looks like you need the WideCharToMultiByte function
Whats hard in this process is to understand the function WideCharToMultiByte.
Basically what you need to do in order to get the whole string (and avoid garbage as a result of not having a null terminating string) is first use:
int size_needed = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)lpOutBuffer, -1, NULL, 0, NULL, NULL);
char *stringMe = new char[size_needed + 1];
While size_needed will be the required buffer size for lpMultiByteStr in the WideCharToMultiByte function.
Afterwards you just need to use that function again, since now you have the complete size:
WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)lpOutBuffer, -1, stringMe, size_needed, NULL, NULL);
stringMe[size_needed + 1] = NULL;
Now you can also convert it to String:
std::string serverOutput(stringMe);
Try this:
String* retOne = utf8_encode(std::wstring(lpOutBuffer));
or
String* retOne = utf8_encode(std::wstring((WCHAR*)lpOutBuffer));

How to download a file with WinHTTP in C/C++?

I know how to download an html/txt page. For example :
//Variables
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
vector <string> vFileContent;
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"nytimes.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"GET", L"/ref/multimedia/podcasts.html",
NULL, WINHTTP_NO_REFERER,
NULL,
NULL);
// 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());
// 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", pszOutBuffer);
// Data in vFileContent
vFileContent.push_back(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 any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
// Write vFileContent to file
ofstream out("test.txt",ios::binary);
for (int i = 0; i < (int) vFileContent.size();i++)
out << vFileContent[i];
out.close();
When I try to download a picture, I get only the first lines of the file and no error message. The problem seems related to this parameter (ppwszAcceptTypes) in WinHttpOpenRequest Function.
link text
Merely opening the ofstream in binary mode does not change the way that the << operators work - they will always perfform formatted output. You need to use the stream's write() function, which does unformatted output.
Solution :
FILE * pFile; // NEW
pFile = fopen("file.bin", "w+b"); // NEW
if (bResults)
do
{
// Check for 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", pszOutBuffer);
fwrite(pszOutBuffer, (size_t)dwDownloaded, (size_t)1, pFile); // NEW
}
// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
}
} while (dwSize>0);
fclose (pFile); // NEW
Looks like this thread on MSDN is the same and has the solution
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/45ccd91c-6794-4f9b-8f4f-865c76cc146d