C++ WinHttp get response header and body - c++

I'm currently trying to write a class to make sending simple requests easier for me.
In the end I'd like it to be usable somewhat like this:
int _tmain(int argc, _TCHAR* argv[])
{
HttpRequest Request(L"Example UserAgent/1.0",L"",L"");
Request.SendRequest(L"google.com",L"GET",NULL);
if (Request.responseHeader)
printf("%s",Request.responseHeader);
if (Request.responseBody)
printf("%s",Request.responseBody);
getchar();
return 0;
}
But for now it doesn't work at all. I have no idea how I could get the response header and I'm failing writing the response header to a public member of my class.
Yeah I'm really bad at C++ especially when it's about the winapi.
Well I hope you can help me out.
Here is my code so far:
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")
class HttpRequest {
private:
DWORD dwSize;
DWORD dwDownloaded;
LPSTR pszOutBuffer;
BOOL bResults;
HINTERNET hSession;
HINTERNET hConnect;
HINTERNET hRequest;
LPCWSTR _userAgent;
//LPCWSTR _proxyIp;
//LPCWSTR _proxyPort;
size_t bodySize;
public:
HttpRequest(LPCWSTR, LPCWSTR, LPCWSTR);
void SendRequest(LPCWSTR, LPCWSTR, LPVOID);
LPSTR responseHeader[1000000];
LPSTR responseBody[1000000];
};
HttpRequest::HttpRequest(LPCWSTR userAgent, LPCWSTR proxyIp, LPCWSTR proxyPort) {
_userAgent = userAgent;
//_proxyIp = proxyIp;
//_proxyPort = proxyPort;
hSession = WinHttpOpen( userAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
}
void HttpRequest::SendRequest(LPCWSTR url, LPCWSTR method, LPVOID body) {
bodySize = 0;
if (hSession)
hConnect = WinHttpConnect( hSession, url, INTERNET_DEFAULT_HTTPS_PORT, 0 );
else
printf("session handle failed\n");
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, method, NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE );
else
printf("connect handle failed\n");
if (hRequest)
bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, body, 0, 0, 0 );
else
printf("request handle failed\n");
if( bResults )
bResults = WinHttpReceiveResponse( hRequest, NULL );
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 );
responseBody[bodySize++] = 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 );
}

Use WinHttpQueryHeaders() to access the response headers. Use the WINHTTP_QUERY_RAW_HEADERS(_CRLF) flag to specify that you want to retrieve all of the available headers.
You also need to change your class to dynamically allocate its responseHeader and responseBody members. You are wasting a lot of memory, as well as limiting the response size you can handle, by using static arrays.
Try this:
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#include <string>
#include <vector>
#pragma comment(lib, "winhttp.lib")
class HttpRequest
{
private:
std::wstring _userAgent;
//std::wstring _proxyIp;
//std::wstring _proxyPort;
public:
HttpRequest(const std::wstring&, const std::wstring&, const std::wstring&);
bool SendRequest(const std::wstring&, const std::wstring&, void*, DWORD);
std::wstring responseHeader;
std::vector<BYTE> responseBody;
};
HttpRequest::HttpRequest(const std::wstring &userAgent, const std::wstring &proxyIp, const std::wstring &proxyPort) :
_userAgent(userAgent)
//,_proxyIp(proxyIp)
//,_proxyPort(proxyPort)
{
}
bool HttpRequest::SendRequest(const std::wstring &url, const std::wstring &method, void *body, DWORD bodySize)
{
DWORD dwSize;
DWORD dwDownloaded;
DWORD headerSize = 0;
BOOL bResults = FALSE;
HINTERNET hSession;
HINTERNET hConnect;
HINTERNET hRequest;
responseHeader.resize(0);
responseBody.resize(0);
hSession = WinHttpOpen( _userAgent.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
if (hSession)
hConnect = WinHttpConnect( hSession, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0 );
else
printf("session handle failed\n");
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, method.c_str(), NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE );
else
printf("connect handle failed\n");
if (hRequest)
bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, body, bodySize, 0, 0 );
else
printf("request handle failed\n");
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL );
if (bResults)
{
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, WINHTTP_NO_OUTPUT_BUFFER, &headerSize, WINHTTP_NO_HEADER_INDEX);
if ((!bResults) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
responseHeader.resize(headerSize / sizeof(wchar_t));
if (responseHeader.empty())
{
bResults = TRUE;
}
else
{
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, &responseHeader[0], &headerSize, WINHTTP_NO_HEADER_INDEX);
if( !bResults ) headerSize = 0;
responseHeader.resize(headerSize / sizeof(wchar_t));
}
}
}
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
bResults = WinHttpQueryDataAvailable( hRequest, &dwSize );
if (!bResults)
{
printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError( ) );
break;
}
if (dwSize == 0)
break;
do
{
// Allocate space for the buffer.
DWORD dwOffset = responseBody.size();
responseBody.resize(dwOffset+dwSize);
// Read the data.
bResults = WinHttpReadData( hRequest, &responseBody[dwOffset], dwSize, &dwDownloaded );
if (!bResults)
{
printf( "Error %u in WinHttpReadData.\n", GetLastError( ) );
dwDownloaded = 0;
}
responseBody.resize(dwOffset+dwDownloaded);
if (dwDownloaded == 0)
break;
dwSize -= dwDownloaded;
}
while (dwSize > 0);
}
while (true);
}
// 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 bResults;
}
int _tmain(int argc, _TCHAR* argv[])
{
HttpRequest Request(L"Example UserAgent/1.0",L"",L"");
if (Request.SendRequest(L"google.com",L"GET",NULL,0))
{
printf("%ls",Request.responseHeader.c_str());
if (!Request.responseBody.empty())
printf("%*s",Request.responseBody.size(),(char*)&Request.responseBody[0]);
}
getchar();
return 0;
}

Related

send multipart/form-data using httpsendrequest

I'm trying to send multipart/form-data using httpsendrequest in c++ but it doesn't seem to work. I'm using the RFC standard for boundary and this is the code I have. I'm sending simple data, plain but trying to use multipart/form-data so I can understand how boundaries work but it doesn't send. This is the code that I've got so far.
#define _WIN32_WINNT 0x600
#include <stdio.h>
#include <wininet.h>
#define BUFLEN 1024
static LPCTSTR acceptTypes[] = {"*/*", NULL};
static const char *postData = "submit=submit&cool=hawk";
static char headers[] = TEXT("Content-Type: multipart/form-data; boundary=abcde\r\n"
"--abcde\r\n"
"Content-Disposition: form-data; name=\"cool\"\r\n"
"testval\r\n"
"--abcde\r\n");
int main()
{
HINTERNET hSession, hConnect, hFile;
if( ( hSession = InternetOpen(
"myapp",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0
) ) == NULL )
{
printf("Couldn't start session. Error %ld\n", GetLastError());
exit(1);
}
printf("Session started\n");
if( ( hConnect = InternetConnect(
hSession,
"localhost",
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
0
) ) == NULL )
{
printf("Unable to connect to server. Error %ld\n", GetLastError());
exit(1);
}
printf("Connected to server\n");
if( ( hFile = HttpOpenRequest(
hConnect,
"POST",
"/test/index.php",
NULL,
NULL,
acceptTypes,
INTERNET_FLAG_RELOAD,
0
) ) == NULL )
{
printf("Unable to open request. Error %ld\n", GetLastError());
exit(1);
}
printf("Opening request..Opened\n");
unsigned long dataLen = strlen(postData)+1;
bool res = HttpSendRequest(
hFile,
headers,
-1,
(char*)postData,
dataLen
);
if( !res )
{
printf("Unable to send request. Error %ld\n", GetLastError());
exit(1);
}
printf("Request sent\n");
// char *szBuffer = (char*)malloc(sizeof(char)*BUFLEN);
char szBuffer[BUFLEN];
DWORD dwRead = 0;
memset(&szBuffer, '\0', sizeof(szBuffer));
while( InternetReadFile(hFile, szBuffer, sizeof(szBuffer), &dwRead) && dwRead )
{
printf("%s", szBuffer);
}
return 0;
}

How to determine if an account belongs to Administrators group programmatically?

My Windows has several accounts like "test1", "test2" and "test3" that belong to the Administrators group. I am developing an application program and I want that program to know if itself is run under an account that belong to the Administrators group by designing a boolean function: isCurrentUserAdminMember(), the isCurrentUserAdminMember() funtion should only return TRUE if the process is run by "test1", "test2", "test3" or the built-in Administrator account no matter whether the process is elevated.
I found some code in http://www.codeproject.com/Articles/320748/Haephrati-Elevating-during-runtime as below, but it seems only to check if the current process is elevated as an Administrator. I don't care if the process is elevated, I just want to know if the start account of the process is a member of Administrators group. And I hope the determination itself is not privilege required. Is that possible? thanks.
BOOL IsAppRunningAsAdminMode()
{
BOOL fIsRunAsAdmin = FALSE;
DWORD dwError = ERROR_SUCCESS;
PSID pAdministratorsGroup = NULL;
// Allocate and initialize a SID of the administrators group.
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdministratorsGroup))
{
dwError = GetLastError();
goto Cleanup;
}
// Determine whether the SID of administrators group is enabled in
// the primary access token of the process.
if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
{
dwError = GetLastError();
goto Cleanup;
}
Cleanup:
// Centralized cleanup for all allocated resources.
if (pAdministratorsGroup)
{
FreeSid(pAdministratorsGroup);
pAdministratorsGroup = NULL;
}
// Throw the error if something failed in the function.
if (ERROR_SUCCESS != dwError)
{
throw dwError;
}
return fIsRunAsAdmin;
}
At last, we achieved the goal to check the Administrators group membership as the code below, however it is USELESS as the answer and comment said, just leave here for reference in case anybody needs it for other use.
// PermTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "iostream"
using namespace std;
#include "windows.h"
#include <lm.h>
#pragma comment(lib, "netapi32.lib")
BOOL IsUserInGroup(const wchar_t* groupe)
{
BOOL result = FALSE;
SID_NAME_USE snu;
WCHAR szDomain[256];
DWORD dwSidSize = 0;
DWORD dwSize = sizeof szDomain / sizeof * szDomain;
if ((LookupAccountNameW(NULL, groupe, 0, &dwSidSize, szDomain, &dwSize, &snu) == 0)
&& (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
{
SID* pSid = (SID*)malloc(dwSidSize);
if (LookupAccountNameW(NULL, groupe, pSid, &dwSidSize, szDomain, &dwSize, &snu))
{
BOOL b;
if (CheckTokenMembership(NULL, pSid, &b))
{
if (b == TRUE)
{
result = TRUE;
}
}
else
{
result = FALSE;
}
}
//Si tout vas bien (la presque totalitée des cas), on delete notre pointeur
//avec le bon operateur.
free(pSid);
}
return result;
}
void getUserInfo(WCHAR *domainName, WCHAR *userName)
{
LPUSER_INFO_3 pBuf = NULL;
int j = 0;
DWORD nStatus = NetUserGetInfo(domainName, userName, 3, (LPBYTE *) &pBuf);
LPUSER_INFO_2 pBuf2 = NULL;
pBuf2 = (LPUSER_INFO_2) pBuf;
if (pBuf)
{
wprintf(L"User account name: %s\\%s\n", domainName, pBuf2->usri2_name);
wprintf(L"Privilege level: %d\n\n", pBuf2->usri2_priv);
}
// wprintf(L"\tPassword: %s\n", pBuf2->usri2_password);
// wprintf(L"\tPassword age (seconds): %d\n",
// pBuf2->usri2_password_age);
// wprintf(L"Privilege level: %d\n\n", pBuf2->usri2_priv);
// #define USER_PRIV_GUEST 0
// #define USER_PRIV_USER 1
// #define USER_PRIV_ADMIN 2
// wprintf(L"\tHome directory: %s\n", pBuf2->usri2_home_dir);
// wprintf(L"\tComment: %s\n", pBuf2->usri2_comment);
// wprintf(L"\tFlags (in hex): %x\n", pBuf2->usri2_flags);
// wprintf(L"\tScript path: %s\n", pBuf2->usri2_script_path);
// wprintf(L"\tAuth flags (in hex): %x\n",
// pBuf2->usri2_auth_flags);
// wprintf(L"\tFull name: %s\n", pBuf2->usri2_full_name);
// wprintf(L"\tUser comment: %s\n", pBuf2->usri2_usr_comment);
// wprintf(L"\tParameters: %s\n", pBuf2->usri2_parms);
// wprintf(L"\tWorkstations: %s\n", pBuf2->usri2_workstations);
// wprintf
// (L"\tLast logon (seconds since January 1, 1970 GMT): %d\n",
// pBuf2->usri2_last_logon);
// wprintf
// (L"\tLast logoff (seconds since January 1, 1970 GMT): %d\n",
// pBuf2->usri2_last_logoff);
// wprintf
// (L"\tAccount expires (seconds since January 1, 1970 GMT): %d\n",
// pBuf2->usri2_acct_expires);
// wprintf(L"\tMax storage: %d\n", pBuf2->usri2_max_storage);
// wprintf(L"\tUnits per week: %d\n",
// pBuf2->usri2_units_per_week);
// wprintf(L"\tLogon hours:");
// for (j = 0; j < 21; j++)
// {
// printf(" %x", (BYTE) pBuf2->usri2_logon_hours[j]);
// }
// wprintf(L"\n");
// wprintf(L"\tBad password count: %d\n",
// pBuf2->usri2_bad_pw_count);
// wprintf(L"\tNumber of logons: %d\n",
// pBuf2->usri2_num_logons);
// wprintf(L"\tLogon server: %s\n", pBuf2->usri2_logon_server);
// wprintf(L"\tCountry code: %d\n", pBuf2->usri2_country_code);
// wprintf(L"\tCode page: %d\n", pBuf2->usri2_code_page);
}
#include <comdef.h>
#define MAX_NAME 256
BOOL GetLogonFromToken (HANDLE hToken, _bstr_t& strUser, _bstr_t& strdomain)
{
DWORD dwSize = MAX_NAME;
BOOL bSuccess = FALSE;
DWORD dwLength = 0;
strUser = "";
strdomain = "";
PTOKEN_USER ptu = NULL;
//Verify the parameter passed in is not NULL.
if (NULL == hToken)
goto Cleanup;
if (!GetTokenInformation(
hToken, // handle to the access token
TokenUser, // get information about the token's groups
(LPVOID) ptu, // pointer to PTOKEN_USER buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (ptu == NULL)
goto Cleanup;
}
if (!GetTokenInformation(
hToken, // handle to the access token
TokenUser, // get information about the token's groups
(LPVOID) ptu, // pointer to PTOKEN_USER buffer
dwLength, // size of buffer
&dwLength // receives required buffer size
))
{
goto Cleanup;
}
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
if( !LookupAccountSidA( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) )
{
DWORD dwResult = GetLastError();
if( dwResult == ERROR_NONE_MAPPED )
strcpy (lpName, "NONE_MAPPED" );
else
{
printf("LookupAccountSid Error %u\n", GetLastError());
}
}
else
{
// printf( "Current user is %s\\%s\n",
// lpDomain, lpName );
strUser = lpName;
strdomain = lpDomain;
bSuccess = TRUE;
}
Cleanup:
if (ptu != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
return bSuccess;
}
HRESULT GetUserFromProcess( _bstr_t& strUser, _bstr_t& strdomain)
{
//HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,procId);
HANDLE hProcess = GetCurrentProcess();
if(hProcess == NULL)
return E_FAIL;
HANDLE hToken = NULL;
if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) )
{
CloseHandle( hProcess );
return E_FAIL;
}
BOOL bres = GetLogonFromToken (hToken, strUser, strdomain);
CloseHandle( hToken );
CloseHandle( hProcess );
return bres?S_OK:E_FAIL;
}
int _tmain(int argc, _TCHAR* argv[])
{
//cout << IsUserInGroup(L"administrators");
getUserInfo(L"adtest.net", L"Administrator");
getUserInfo(NULL, L"Administrator");
getUserInfo(NULL, L"test");
getUserInfo(NULL, L"test2");
getUserInfo(NULL, L"testnormal");
_bstr_t username;
_bstr_t domain;
GetUserFromProcess(username, domain);
cout << "Current account running this program is: " << endl << domain << "\\" << username << endl;
getchar();
return 0;
}
You can do this by opening your process token (OpenProcessToken, listing the SIDs using GetTokenInformation and comparing each SID to the Administrators SID.
Microsoft have sample code here: Searching for a SID in an Access Token in C++
However, this is rarely a useful thing to do. Even if the user is not a member of the Administrators group, they can still elevate by providing an administrative username and password, so you should not (for example) only offer elevation if the user is in the Administrators group.
bool IsMemberOfGroup(const char *pszGroupName){
bool bFound = false;
HANDLE hToken=INVALID_HANDLE_VALUE;
BOOL bSuccess = OpenProcessToken( GetCurrentProcess(),
TOKEN_QUERY,//|TOKEN_QUERY_SOURCE,
&hToken);
if ( bSuccess )
{
DWORD dwSizeToken=0;
DWORD dwSizeName=0;
DWORD dwSizeReferencedDomainName = 0;
// Get group information:
GetTokenInformation(hToken, TokenGroups, NULL, dwSizeToken, &dwSizeToken);
{
const int MAX_NAME = 256;
char *psName = new char[MAX_NAME];
char *psDomain = new char[MAX_NAME];
char *pBuf = new char[dwSizeToken+10];
TOKEN_GROUPS *pGroupInfo = (TOKEN_GROUPS *)pBuf;
bSuccess = GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSizeToken, &dwSizeToken);
if ( bSuccess )
{
// find the group name we are looking for
for ( UINT uiGroupNdx = 0; uiGroupNdx < pGroupInfo->GroupCount && !bFound; uiGroupNdx++ )
{
SID_NAME_USE SidType;
dwSizeName = MAX_NAME;
dwSizeReferencedDomainName = MAX_NAME;
bSuccess = LookupAccountSid(NULL, // local system,
pGroupInfo->Groups[uiGroupNdx].Sid,
psName,
&dwSizeName,
psDomain,
&dwSizeReferencedDomainName,
&SidType);
if ( bSuccess )
{
if ( SidTypeGroup == SidType )
{
if ( !lstrcmpi(pszGroupName, psName) )
{
bFound = true;
}
}
}
}
}
delete [] pBuf;
delete [] psName;
delete [] psDomain;
}
CloseHandle(hToken);
}
return bFound;
}

msdn upload image with winhttp c++

I have been trying this the whole day but no luck i want to upload an image file to a php file which i have created but when ever i try to do that winhttpsendrequest throws 183 error that means cannot send file that is already sent please can someone point out where i am wrong
c++ code:
int _tmain(int argc, _TCHAR* argv[]) {
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
BOOL bResults = FALSE;
FILE *pFile;
long lSize;
char *buffer;
size_t result;
pFile = fopen("blog.jpg", "rb");
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
buffer = (char *) malloc(sizeof(char) * lSize);
result = fread(buffer, 1, lSize, pFile);
fclose(pFile);
hSession = WinHttpOpen( L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession)
hConnect = WinHttpConnect(hSession, L"localhost",
INTERNET_DEFAULT_HTTP_PORT, 0);
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", L"locker/upload.php",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_REFRESH);
static WCHAR frmdata[2048] = L"Connection: keep-alive\r\nContent-Type: multipart/form-data; -----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"file\"; filename=\"blog.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
bResults = WinHttpSendRequest(hRequest,
frmdata, wcslen(frmdata), buffer,
lSize, wcslen(frmdata)+lSize, 0);
if (bResults) {
/*
DWORD dwBytesWritten = 0;
bResults = WinHttpWriteData(hRequest, buffer,
lSize,
&dwBytesWritten);
if (bResults) {
printf_s("Data: %d", dwBytesWritten);
}
*/
} else {
printf_s("SendReq: %d", GetLastError());
}
free(buffer);
if (hRequest) { WinHttpCloseHandle(hRequest); }
if (hConnect) { WinHttpCloseHandle(hConnect); }
if (hSession) { WinHttpCloseHandle(hSession); }
getchar();
return 0;
}
php code:
if (isset($_FILES["file"])) {
$target_path = "uploads/";
$target_path = $target_path . basename( $_FILES['file']['name']);
if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['file']['name']). " has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
}
Keshav Nair.
try to this code:
CHAR postData[1024];
CHAR postData2[1024];
ZeroMemory(&postData,1024);
ZeroMemory(&postData2,1024);
WinHttpAddRequestHeaders(hRequest,L"Content-Type: multipart/form-data; boundary=----OiRBxC0fjdSEpqhd",-1L,WINHTTP_ADDREQ_FLAG_ADD);
wsprintfA(postData,"%s","----OiRBxC0fjdSEpqhd\r\nContent-Disposition: form-data; name=\"file\"; filename=\"blog.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n");
wsprintfA(postData2,"%s","\r\n----OiRBxC0fjdSEpqhd\r\nContent-Disposition: form-data; name=\"submit\"\r\n\r\nSubmit\r\n----OiRBxC0fjdSEpqhd--\r\n");
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
lstrlenA(postData)+lstrlenA(postData2)+lSize, NULL);
if (bResults)
{
bResults=WinHttpWriteData(hRequest,LPCVOID)postData,lstrlenA(postData),NULL);
bResults = WinHttpWriteData(hRequest, buffer, lSize, &dwBytesWritten);
bResults=WinHttpWriteData(hRequest,(LPCVOID)postData2,lstrlenA(postData2),NULL);
}
WinHttpWriteData:
POST data - postData, postData2 must be 8 bit encoding.

Calling SetupDiEnumDeviceInfo causes a subsequent CreateFile to return ERROR_SHARING_VIOLATION

In the following code the call to SetupDiEnumDeviceInfo() causes the subsequent CreateFile to return ERROR_SHARING_VIOLATION instead of opening the file. I was able to pinpoint the line by commenting out the other pieces of code until I hit one line that would cause the CreateFile to fail.
String SerialATDT::getComPortId()
{
#if 1
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
String comPort = "";
// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_MODEM,
0, // Enumerator
0,
DIGCF_PRESENT );
if (hDevInfo == INVALID_HANDLE_VALUE)
{
// Insert error handling here.
return "";
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
int offset = 0;
while ( SetupDiEnumDeviceInfo(hDevInfo, offset++, &DeviceInfoData) )
{
DWORD DataT;
#if 1
//
// Call function with null to begin with,
// then use the returned buffer size (doubled)
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
// Double the returned buffersize to correct
// for underlying legacy CM functions that
// return an incorrect buffersize value on
// DBCS/MBCS systems.
//
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_FRIENDLYNAME,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
// Change the buffer size.
if (buffer) LocalFree(buffer);
// Double the size to avoid problems on
// W2k MBCS systems per KB 888609.
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize * 2);
}
else
{
// Insert error handling here.
break;
}
}
// Look for identifying info in the name
if ( mComPortIdentifier.size() > 0 ) {
const char *temp = strstr(buffer, mComPortIdentifier.c_str());
if ( temp == 0 ) {
continue;
}
}
// Now find out the port number
DWORD nSize=0 ;
TCHAR buf[MAX_PATH];
if ( SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, buf, MAX_PATH, &nSize) )
{
HKEY devKey = SetupDiOpenDevRegKey(hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
DWORD size = 0;
DWORD type;
RegQueryValueEx(devKey, TEXT("PortName"), NULL, NULL, NULL, & size);
BYTE* buff = new BYTE[size];
String result;
if( RegQueryValueEx(devKey, TEXT("PortName"), NULL, &type, buff, & size) == ERROR_SUCCESS ) {
comPort = (char*)buff;
if ( comPort.size() > 0 ) {
RegCloseKey(devKey);
break;
}
}
RegCloseKey(devKey);
delete [] buff;
}
#else
comPort = "COM44";
#endif
}
// Cleanup
SetupDiDestroyDeviceInfoList (hDevInfo);
if (buffer) {
LocalFree(buffer);
}
if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS &&
GetLastError() != ERROR_INVALID_HANDLE )
{
TRACE_L("ATDT error after free %ld", GetLastError() );
// Insert error handling here.
return "";
}
return comPort;
#else
return "COM44";
#endif
}
bool SerialATDT::getComPort(HANDLE *hFile)
{
String comPort = getComPortId();
*hFile = INVALID_HANDLE_VALUE;
if ( comPort.size() > 0 ) {
String comPortStr;
comPortStr.Format("\\\\.\\%s", comPort.c_str());
*hFile = ::CreateFile( comPortStr.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( *hFile == INVALID_HANDLE_VALUE ) {
TRACE_L("AT file open error %ld", GetLastError());
}
}
return *hFile != INVALID_HANDLE_VALUE;
}
I have been looking but have not found a reason why the DeviceInfoData needs to be cleared (nor have I found a method to do it). Has anybody run into this before?

C++ NPAPI WinHttpConnect failed

Now i know the problem is hConnect not successfully initialize through the debugger, and i wonder why,thanks
its the javascript code caller
t=function(){
var type = "GET",
host = "183.60.139.201",
port = 80,
uri = "/",
useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US)",
headers = "";
getdata = "",
postdata = "";
resolveTimeout = 10000;
connectTimeout = 10000;
sendTimeout = 10000;
receiveTimeout = 10000;
return test.http( type
,host
,port
,uri
,useragent
,headers
,getdata
,postdata
,resolveTimeout
,connectTimeout
,sendTimeout
,receiveTimeout
);
}
t();
its C++ source
#include "plugin.h"
#include "simplehttp.h"
#pragma comment(lib, "winhttp.lib")
#include <windows.h>
#include <winhttp.h>
#include <string>
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
using namespace std;
bool HttpRequest(ScriptablePluginObject* obj, const NPVariant* args,
unsigned int argCount, NPVariant* result){
string type = "GET";
string host = "";
unsigned int port = INTERNET_DEFAULT_HTTP_PORT;
string uri ="/";
string useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US)";
string additionalheaders = "";
string getdata = "";
string postdata = "";
__asm {
int 3
}
unsigned int resolveTimeout = 10000;
unsigned int connectTimeout = 10000;
unsigned int sendTimeout = 10000;
unsigned int receiveTimeout = 10000;
for( int i=0;i<argCount;i++){
NPVariant arg = args[i];
switch (i){
case 0:
type = arg.value.stringValue.UTF8Characters;
break;
case 1:
host = arg.value.stringValue.UTF8Characters;
break;
case 2:
port = arg.value.intValue;
break;
case 3:
uri = arg.value.stringValue.UTF8Characters;
break;
case 4:
useragent = arg.value.stringValue.UTF8Characters;
break;
case 5:
additionalheaders = arg.value.stringValue.UTF8Characters;
break;
case 6:
getdata = arg.value.stringValue.UTF8Characters;
break;
case 7:
postdata = arg.value.stringValue.UTF8Characters;
break;
case 8:
resolveTimeout = arg.value.intValue;
break;
case 9:
connectTimeout = arg.value.intValue;
break;
case 10:
sendTimeout = arg.value.intValue;
break;
case 11:
receiveTimeout = arg.value.intValue;
break;
}
}
BOOL usePost = (type == "POST" && postdata != "");
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
string page = "";
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = WinHttpOpen( s2ws(useragent).c_str(),
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
if (!WinHttpSetTimeouts( hSession, resolveTimeout, connectTimeout, sendTimeout, receiveTimeout)){
goto endHttpRequest;
};
if(hSession){
LPCWSTR tes = s2ws(host).c_str();
hConnect = WinHttpConnect( hSession,
tes,
port,
0);
}else{
goto endHttpRequest;
}
if(hConnect){ // FAILED HERE!!!!
if(!usePost){
hRequest = WinHttpOpenRequest( hConnect,
s2ws(type).c_str(),
s2ws(uri.append(getdata)).c_str(),
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_REFRESH);
}else{
hRequest = WinHttpOpenRequest( hConnect,
s2ws(type).c_str(),
s2ws(uri).c_str(),
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_REFRESH);
}
}else{
goto endHttpRequest;
}
if(hRequest)
bResults = WinHttpAddRequestHeaders( hRequest,
L"Cookie:",
-1,
WINHTTP_ADDREQ_FLAG_REPLACE);
if(hRequest)
bResults = WinHttpAddRequestHeaders( hRequest,
s2ws(additionalheaders).c_str(),
-1,
WINHTTP_ADDREQ_FLAG_ADD);
if(hRequest)
{
if(usePost){
bResults = WinHttpAddRequestHeaders( hRequest,
L"Content-Type: application/x-www-form-urlencoded",
-1,
WINHTTP_ADDREQ_FLAG_ADD);
bResults = WinHttpAddRequestHeaders( hRequest,
L"Content-Length: "+ postdata.size(),
-1,
WINHTTP_ADDREQ_FLAG_ADD);
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
(LPVOID)postdata.c_str(),
postdata.size(),
postdata.size(),
0);
}else{
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
WINHTTP_NO_REQUEST_DATA,
0,
0,
0);
}
}
if(bResults){
bResults = WinHttpReceiveResponse(hRequest,NULL);
}else{
goto endHttpRequest;
}
if(bResults){
do{
dwSize = 0;
if(!WinHttpQueryDataAvailable( hRequest,&dwSize)){
return false;
}
pszOutBuffer = new char[dwSize+1];
if(!pszOutBuffer){
dwSize = 0;
return false;
}else{
ZeroMemory(pszOutBuffer,dwSize+1);
if(!WinHttpReadData( hRequest,
(LPVOID)pszOutBuffer,
dwSize,
&dwDownloaded)){
return false;
}else{
page.append(pszOutBuffer);
}
delete [] pszOutBuffer;
}
}while(dwSize>0);
}
endHttpRequest:
char* npOutString = (char *)npnfuncs->memalloc(page.size()+1);
strcpy(npOutString,page.c_str());
STRINGZ_TO_NPVARIANT(npOutString,*result);
if( hRequest ) WinHttpCloseHandle( hRequest );
if( hConnect ) WinHttpCloseHandle( hConnect );
if( hSession ) WinHttpCloseHandle( hSession );
return true;
};
I've seen this error in python, the solution was to pass the url string in utf-16 encoding.
try using wstring uri;
The wide version then you don't need to convert it.