Send POST data via HttpOpenRequestA - c++

I'm trying to send my PC Name to my local server and save it in a file.
There is my code:
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <cstring>
#include <Lmcons.h>
#include <unistd.h>
#include <stdlib.h>
#include <WinInet.h>
#include <bits/stdc++.h>
#pragma comment( lib,"Wininet.lib")
using namespace std;
int main() {
TCHAR name [ UNLEN + 1 ];
DWORD size = UNLEN + 1;
static CHAR hdrs[] = "Content-Type: application/x-www-form-urlencoded";
if (GetUserName( (TCHAR*)name, &size ));
static CHAR frmdata[] = "data=", name;
HINTERNET hSession = InternetOpenA("http generic", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET hConnect = InternetConnect(hSession, "127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", "/test/index.php", NULL, NULL, NULL, 0, 1);
HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
}
I've tried use static CHAR frmdata[] = "data=" + name; also but not works.
This is the error that I receive:
error: invalid operands of types 'const char [6]' and 'TCHAR [257] {aka char [257]}' to binary 'operator+'|

You can't concatenate char[] arrays like you are trying to do. Allocate a separate buffer of sufficient size and copy the input strings into it, eg:
#include <windows.h>
#include <Lmcons.h>
#include <WinInet.h>
#include <cstring>
//#include <cstdio>
using namespace std;
#pragma comment( lib, "Wininet.lib")
int main()
{
static char hdrs[] = "Content-Type: application/x-www-form-urlencoded";
char name[UNLEN + 1] = {};
DWORD size = UNLEN + 1;
GetUserNameA(name, &size);
char frmdata[5 + UNLEN + 1] = {};
strcpy(frmdata, "data=");
strcat(frmdata, name);
// alternatively:
// sprintf(frmdata, "data=%s", name);
HINTERNET hSession = InternetOpenA("http generic", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hSession) {
// error handling...
}
HINTERNET hConnect = InternetConnectA(hSession, "127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if (!hConnect) {
// error handling...
}
HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", "/test/index.php", NULL, NULL, NULL, 0, 1);
if (!hRequest) {
// error handling...
}
if (!HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata))) {
// error handling...
}
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
return 0;
}
Alternatively, you can use a single buffer, just make it larger, and have GetUserNameA() populate a portion of it, then you don't need to make a copy afterwards, eg:
int main()
{
...
char frmdata[5 + UNLEN + 1] = "data=";
DWORD size = UNLEN + 1;
GetUserNameA(&frmdata[5], &size);
...
}

You need to concatenate, which std::string can do for you. You should also use the same base character type to avoid the need for additional conversions.
char name [ UNLEN + 1 ];
DWORD size = UNLEN + 1;
GetUserNameA( name, &size );
std::string frmdata;
frmdata += "data=";
frmdata += name;
...
HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata.data(), (DWORD)frmdata.size());
In case you want to transport unicode data (use std::wstring in that case) you will need to convert your data string to proper utf-8 (lookup WideCharToMultiByte).

Related

Problem with InternetOpenA (undefined reference to `___imp_InternetOpenA` [duplicate]

I want make C++ program where send .txt file with information to my PC. I surch so much in internet but cant find method that works.
When I uusing Dev C++ give me this errors:
...: undefined reference to __imp_InternetOpenA'
...: undefined reference to__imp_InternetConnectA'
...: undefined reference to __imp_FtpPutFileA'
...: undefined reference to__imp_HttpOpenRequestA'
Here are three examples where I find, but all return this error.
<pre>
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib,"wininet.lib")
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
using namespace std;
int main()
{
// Local variables
char filename[] = "file"; //Filename to be loaded
char filepath[] = "d:\\a.jpg"; //Filename to be loaded
char type[] = "image/jpeg";
char boundary[] = "--BOUNDARY---"; //Header boundary
char nameForm[] = "formname"; //Input form name
char iaddr[] = "localhost"; //IP address
char url[] = "/http/file.php"; //URL
char hdrs[512]={'-'}; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen ( filepath , "rb" );
if (pFile==NULL)
{
printf("ERROR_OPEN_FILE");
getchar();
return ERROR_OPEN_FILE;
}
printf("OPEN_FILE\n");
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL)
{
printf("ERROR_MEMORY");
getchar();
return ERROR_OPEN_FILE;
}
printf("MEMORY_ALLOCATED\t \"%d\" \n",&lSize);
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize)
{
printf("ERROR_SIZE");
getchar();
return ERROR_OPEN_FILE;
}
printf("SIZE_OK\n");
// terminate
fclose (pFile);
printf("FILE_CLOSE\n");
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%
----------
s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n",buffer,type);
sprintf(buffer,"%s%s",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WINDOWS",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL)
{
printf("ERROR_INTERNET_OPEN");
getchar();
return ERROR_OPEN_FILE;
}
printf("INTERNET_OPENED\n");
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL)
{
printf("ERROR_INTERNET_CONN");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_CONNECTED\n");
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T(url),NULL, NULL, NULL,INTERNET_FLAG_RELOAD, 1);
if(hRequest==NULL)
{
printf("ERROR_INTERNET_REQ");
getchar();
}
printf("INTERNET_REQ_OPEN\n");
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent)
{
printf("ERROR_INTERNET_SEND");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_SEND_OK\n");
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
getchar();
return 0;
}
<pre>
#include <winsock2.h>
#include <wininet.h>
#include <tchar.h>
#include <iostream>
#include <stdlib.h>
#include <windows.h>
//#pragma comment(lib,"wininet.lib")
using namespace std;
int main()
{
static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\test.txt\"\nContent-Type: text/plain\n\nfile contents here\n-----------------------------7d82751e2bc0858--";
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858";
HINTERNET hSession = InternetOpen("MyAgent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL)
{
cout<<"Error: InternetOpen";
}
HINTERNET hConnect = InternetConnect(hSession, _T("localhost"),INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL)
{
cout<<"Error: InternetConnect";
}
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T("upload.php"), NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL)
{
cout<<"Error: HttpOpenRequest";
}
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
if(!sent)
{
cout<<"Error: HttpSendRequest";
}
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <iostream>
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
using namespace std;
int main()
{
// Local variables
static char filename[] = "test.txt"; //Filename to be loaded
static char type[] = "image/jpg";
static char boundary[] = "pippo"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "test.php"; //URL
char hdrs[255]; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen ( filename , "rb" );
if (pFile==NULL) return ERROR_OPEN_FILE;
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL) return ERROR_MEMORY;
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize) return ERROR_SIZE;
// terminate
fclose (pFile);
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);
sprintf(buffer,"%s%s\r\n",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL) return ERROR_INTERNET_OPEN;
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL) return ERROR_INTERNET_CONN;
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent) return ERROR_INTERNET_SEND;
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
</pre>
I had many errors like this on my first C++ program. It is a problem with linking against the WinINet library. If you are using MinGW add "-lwininet" (without quotes) to the additional commandling arguments and it should be fixed. I don't know what to to do if you use VC++. Also, make sure the location of the WinINet library is in the linker's search paths.
With CMake you simply need
target_link_libraries( MY_TARGET
ws2_32)

Pipes doesn't work in WinApi on Windows 7 but works on Windows 10

I made a server and a client in winapi.
Client sends an number and a base and the server returns the number in that base.
My problem that it works in Windows 10, but it doesn't work in Windows 7 and I don't understand why. Some help?
Client:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <windows.h>
#include <string>
#define BUFFSIZE 512
using namespace std;
int main()
{
LPDWORD bytesRead = 0;
char res[50];
int num, base;
LPCTSTR Roura = TEXT("\\\\.\\pipe\\pipeline");
HANDLE h = CreateFile(Roura, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
while (true) {
for (int i = 0; i < 50; i++) {
res[i] = 0;
}
printf("Number: ");
cin >> num;
WriteFile(h, &num, sizeof(int), NULL, NULL);
if (num == 0) {
CloseHandle(h);
return 0;
}
printf("Base: ");
cin >> base;
WriteFile(h, &base, sizeof(int), NULL, NULL);
ReadFile(h, res, BUFFSIZE, bytesRead, NULL);
cout << res << endl;
}
return 0;
}
Server:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <windows.h>
#include <string>
#define _CRT_SECURE_NO_WARNINGS
#define BUFFSIZE 512
using namespace std;
int main()
{
int num, base;
LPDWORD bytesRead = 0;
char result[50];
char end[] = {"\0"};
LPCTSTR Roura = TEXT("\\\\.\\pipe\\pipeline");
HANDLE h = CreateNamedPipe(Roura, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, BUFFSIZE, BUFFSIZE, 0, NULL);
assert(h != INVALID_HANDLE_VALUE);
if (!ConnectNamedPipe(h, NULL)) return -1;
while (true) {
ReadFile(h, &num, BUFFSIZE, bytesRead, NULL);
if (num == 0) {
CloseHandle(h);
return 0;
}
ReadFile(h, &base, BUFFSIZE, bytesRead, NULL);
_itoa(num, result, base);
WriteFile(h, result, strlen(result), NULL, NULL);
}
return 0;
}
#define BUFFSIZE 512
int num, base;
LPDWORD bytesRead = 0;
ReadFile(h, &num, BUFFSIZE, bytesRead, NULL);
this code complete of errors. need use
int num, base;
DWORD bytesRead;
ReadFile(h, &num, sizeof(num), &bytesRead, NULL);
instead. crash faster of all by bytesRead== 0
when
If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL.
however this true on win7, but on say win10 - system let have lpNumberOfBytesRead == 0 - so no crash here
also this
WriteFile(h, &num, sizeof(int), NULL, NULL);
again - here already only 1 error compare ReadFile call
If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.
why ?
that it works in Windows 10, but it doesn't work in Windows 7
this is because begin from win 8.1 (if I not mistake) code of ReadFile/WriteFile check lpNumberOfBytes parameter and if it ==0 not assign to it actual number of bytes read or written. but on windows 7 system not do this check and unconditionally write data by 0 address

Slightly different SHA256 on windows and linux

The code below generates SHA256 hash on Windows. As you can see it produces the hash from text "doublecheck" (5/NK+1ZAwTjzTY1PjZm0xcPRDf6KMQhmE4SVQnPOQ3M=)
I've created the code in the linux which should produce same hash, but it is different. (5/NK+1ZAwTjzTY1PjZm0xcPRDf6KMQhmE4SVQnPOQ3O/enx3tzCun78sgwQIOK6fv1T6eLc=)
Could anybody help me to fix any of those codes to get the same hashes?
Windows code:
#include "stdafx.h"
#include "Hash2.h"
#include <Wincrypt.h>
#pragma comment(lib, "Crypt32.lib")
DWORD BufSize;
#define BUF_SIZE 256
TCHAR Buf[BUF_SIZE];
CStringA BinaryToBase64(__in const byte * pbBinary, __in DWORD cbBinary)
{
ATLASSERT(pbBinary != NULL);
if (pbBinary == NULL)
AtlThrow(E_POINTER);
ATLASSERT(cbBinary != 0);
if (cbBinary == 0)
AtlThrow(E_INVALIDARG);
DWORD cchBase64;
if (!CryptBinaryToStringA(pbBinary, cbBinary, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &cchBase64))
{
AtlThrowLastWin32();
}
CStringA strBase64;
LPSTR pszBase64 = strBase64.GetBuffer(cchBase64);
ATLASSERT(pszBase64 != NULL);
if (!CryptBinaryToStringA(pbBinary, cbBinary, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, pszBase64, &cchBase64))
AtlThrowLastWin32();
strBase64.ReleaseBuffer();
return strBase64;
}
// creates sha256 hash from string
LPCSTR CreateHash(LPCSTR tohash)
{
HCRYPTPROV hProv;
HCRYPTHASH hash;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hash))
{
int sz = strlen(tohash);
if (CryptHashData(hash, (BYTE *)tohash, sz, 0))
{
ZeroMemory(&Buf, sizeof(Buf));
BufSize = sizeof(Buf);
if (!CryptGetHashParam(hash, HP_HASHVAL, (BYTE *)&Buf, &BufSize, 0))
AtlThrowLastWin32();
}
else
AtlThrowLastWin32();
if (!CryptDestroyHash(hash))
AtlThrowLastWin32();
}
else
AtlThrowLastWin32();
if (!CryptReleaseContext(hProv, 0))
AtlThrowLastWin32();
}
else
AtlThrowLastWin32();
CStringA stemp = BinaryToBase64(reinterpret_cast<BYTE *>(Buf), BufSize).Trim();
int sizeOfString = (stemp.GetLength() + 1);
LPSTR retVal = new char[sizeOfString];
strcpy_s(retVal, sizeOfString, stemp);
return retVal;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
LPCSTR text = "doublecheck";
LPCSTR hash = CreateHash(text);
printf("\"%s\" hashed = %s", text, hash);
//output: "doublecheck" hashed = 5/NK+1ZAwTjzTY1PjZm0xcPRDf6KMQhmE4SVQnPOQ3M=
getchar();
}
Linux code:
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
int Base64Encode(const char* message, char** buffer) { //Encodes a string to base64
BIO *bio, *b64;
FILE* stream;
int encodedSize = 4*ceil((double)strlen(message)/3);
*buffer = (char *)malloc(encodedSize+1);
stream = fmemopen(*buffer, encodedSize+1, "w");
b64 = BIO_new(BIO_f_base64());
bio = BIO_new_fp(stream, BIO_NOCLOSE);
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
// edit: bad code BIO_write(bio, message, strlen(message));
BIO_write(bio, message, SHA256_DIGEST_LENGTH); // edit: correction
BIO_flush(bio);
BIO_free_all(bio);
fclose(stream);
return (0); //success
}
int main() {
unsigned char digest[SHA256_DIGEST_LENGTH];
const char* string = "doublecheck";
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, string, strlen(string));
SHA256_Final(digest, &ctx);
printf("SHA256 digest: %s\n", digest);
char* base64EncodeOutput;
Base64Encode((char*)digest, &base64EncodeOutput);
printf("Output (base64): %s\n", base64EncodeOutput);
// now the output here is: 5/NK+1ZAwTjzTY1PjZm0xcPRDf6KMQhmE4SVQnPOQ3M=
return 0;
}

How to fix this error: undefined reference to `__imp_InternetOpenA'

I want make C++ program where send .txt file with information to my PC. I surch so much in internet but cant find method that works.
When I uusing Dev C++ give me this errors:
...: undefined reference to __imp_InternetOpenA'
...: undefined reference to__imp_InternetConnectA'
...: undefined reference to __imp_FtpPutFileA'
...: undefined reference to__imp_HttpOpenRequestA'
Here are three examples where I find, but all return this error.
<pre>
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib,"wininet.lib")
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
using namespace std;
int main()
{
// Local variables
char filename[] = "file"; //Filename to be loaded
char filepath[] = "d:\\a.jpg"; //Filename to be loaded
char type[] = "image/jpeg";
char boundary[] = "--BOUNDARY---"; //Header boundary
char nameForm[] = "formname"; //Input form name
char iaddr[] = "localhost"; //IP address
char url[] = "/http/file.php"; //URL
char hdrs[512]={'-'}; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen ( filepath , "rb" );
if (pFile==NULL)
{
printf("ERROR_OPEN_FILE");
getchar();
return ERROR_OPEN_FILE;
}
printf("OPEN_FILE\n");
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL)
{
printf("ERROR_MEMORY");
getchar();
return ERROR_OPEN_FILE;
}
printf("MEMORY_ALLOCATED\t \"%d\" \n",&lSize);
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize)
{
printf("ERROR_SIZE");
getchar();
return ERROR_OPEN_FILE;
}
printf("SIZE_OK\n");
// terminate
fclose (pFile);
printf("FILE_CLOSE\n");
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%
----------
s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n",buffer,type);
sprintf(buffer,"%s%s",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WINDOWS",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL)
{
printf("ERROR_INTERNET_OPEN");
getchar();
return ERROR_OPEN_FILE;
}
printf("INTERNET_OPENED\n");
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL)
{
printf("ERROR_INTERNET_CONN");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_CONNECTED\n");
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T(url),NULL, NULL, NULL,INTERNET_FLAG_RELOAD, 1);
if(hRequest==NULL)
{
printf("ERROR_INTERNET_REQ");
getchar();
}
printf("INTERNET_REQ_OPEN\n");
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent)
{
printf("ERROR_INTERNET_SEND");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_SEND_OK\n");
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
getchar();
return 0;
}
<pre>
#include <winsock2.h>
#include <wininet.h>
#include <tchar.h>
#include <iostream>
#include <stdlib.h>
#include <windows.h>
//#pragma comment(lib,"wininet.lib")
using namespace std;
int main()
{
static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\test.txt\"\nContent-Type: text/plain\n\nfile contents here\n-----------------------------7d82751e2bc0858--";
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858";
HINTERNET hSession = InternetOpen("MyAgent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL)
{
cout<<"Error: InternetOpen";
}
HINTERNET hConnect = InternetConnect(hSession, _T("localhost"),INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL)
{
cout<<"Error: InternetConnect";
}
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T("upload.php"), NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL)
{
cout<<"Error: HttpOpenRequest";
}
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
if(!sent)
{
cout<<"Error: HttpSendRequest";
}
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <iostream>
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
using namespace std;
int main()
{
// Local variables
static char filename[] = "test.txt"; //Filename to be loaded
static char type[] = "image/jpg";
static char boundary[] = "pippo"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "test.php"; //URL
char hdrs[255]; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen ( filename , "rb" );
if (pFile==NULL) return ERROR_OPEN_FILE;
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL) return ERROR_MEMORY;
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize) return ERROR_SIZE;
// terminate
fclose (pFile);
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);
sprintf(buffer,"%s%s\r\n",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL) return ERROR_INTERNET_OPEN;
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL) return ERROR_INTERNET_CONN;
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent) return ERROR_INTERNET_SEND;
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
</pre>
I had many errors like this on my first C++ program. It is a problem with linking against the WinINet library. If you are using MinGW add "-lwininet" (without quotes) to the additional commandling arguments and it should be fixed. I don't know what to to do if you use VC++. Also, make sure the location of the WinINet library is in the linker's search paths.
With CMake you simply need
target_link_libraries( MY_TARGET
ws2_32)

C++ FTP writing to file is not working

I wrote this code that is SUPPOSED to write to a file on an ftp server, but it doesn't work. The file stays 0 bytes. There are also no errors. Here's my code:
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
int main()
{
int error=0;
char buffer[256];
char *text="Hello world.";
HINTERNET hOpen=InternetOpen("",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,INTERNET_FLAG_PASSIVE);
InternetGetLastResponseInfo((LPDWORD)error,(LPSTR)buffer,(LPDWORD)256);
printf("hOpen:%d:%s\n",error,buffer);
HINTERNET hConnect=InternetConnect(hOpen,"diabloip.host22.com",INTERNET_DEFAULT_FTP_PORT,"MY_USER_NAME","MY_PASSWORD",INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,0);
InternetGetLastResponseInfo((LPDWORD)error,(LPSTR)buffer,(LPDWORD)256);
printf("hConnect:%d:%s\n",error,buffer);
HINTERNET hFile=FtpOpenFile(hConnect,"diabloip.host22.com/public_html/log.txt",GENERIC_WRITE,FTP_TRANSFER_TYPE_ASCII,0);
InternetGetLastResponseInfo((LPDWORD)error,(LPSTR)buffer,(LPDWORD)256);
printf("hFile:%d:%s\n",error,buffer);
InternetWriteFile(hFile,text,strlen(text),NULL);
return 0;
}
The problem is passing NULL as the last parameter to InternetWriteFile. It is not an optional parameter and if you had error checking for that call as the rest you'd see GetLastError returns 87, or ERROR_INVALID_PARAMETER.
This works correctly and cleans up some of the other issues with incorrect parameters and the excessive casting that masks the issues.
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#pragma comment(lib, "wininet.lib")
void PrintStatus(const char* title)
{
DWORD error = 0;
DWORD sz = 256;
char buffer[256];
InternetGetLastResponseInfo(&error, buffer, &sz);
printf("%s:%u:%s\n", title, error, buffer);
}
int main()
{
const char *text = "Hello world.";
HINTERNET hOpen = InternetOpen("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_PASSIVE);
PrintStatus("hOpen");
HINTERNET hConnect = InternetConnect(hOpen, "localhost", INTERNET_DEFAULT_FTP_PORT, "test", "test", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
PrintStatus("hConnect");
HINTERNET hFile = FtpOpenFile(hConnect, "log.txt", GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
PrintStatus("hFile");
DWORD wb = 0;
BOOL Success = InternetWriteFile(hFile, text, strlen(text), &wb);
if(!Success)
{
DWORD err = GetLastError();
printf("InternetWriteFile - Error = %u\n", err);
}
PrintStatus("InternetWriteFile");
InternetCloseHandle(hOpen);
return 0;
}