How to fix this error: undefined reference to `__imp_InternetOpenA' - c++

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)

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)

Send POST data via HttpOpenRequestA

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).

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;
}

Upload Image File in C++

I am new to C++ environment. I try to upload a image file to PHP server in C++. But it does not send the full file. Only I get uploaded image file size is 1 KB.
I got a post in SO like mine. But I don't know how to convert image binary to base64 string. I tried with another solution memcpy, it also doesn't work.
Upload file via POST
My C++ Code:
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <tchar.h>
#include <Urlmon.h>
#pragma comment (lib, "Urlmon.lib")
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <tchar.h>
#include <stdio.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 cv;
using namespace std;
int main()
{
// Local variables
static char *filename = "test.jpg"; //Filename to be loaded
static char *filepath = "test.jpg"; //Filename to be loaded
static char *type = "text/jpeg";
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858";
static char boundary[] = "-----------------------------7d82751e2bc0858"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "server"; //IP address
static char url[] = "uploader.php";
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
char *pos; // used in the loop
// 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);
rewind (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(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, "%sContent-Length: %d\r\n", buffer, lSize);
sprintf(buffer, "%s\r\n%s\r\n", buffer, content);
/**
sprintf(buffer, "%s\r\n", buffer);
memcpy(buffer + strlen(buffer),content,lSize);
sprintf(buffer, "%s\r\n", buffer);
*/
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");
printf("\r\n%s\r\n",buffer);
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
}
Output:
OPEN_FILE
MEMORY_ALLOCATED "44358"
SIZE_OK
FILE_CLOSE
INTERNET_OPENED
INTERNET_CONNECTED
INTERNET_REQ_OPEN
INTERNET_SEND_OK
-----------------------------7d82751e2bc0858
Content-Disposition: form-data; name="uploadedfile"; filename="test.jpg"
Content-Type: text/jpeg
ÿØÿà
-----------------------------7d82751e2bc0858--
Thanks
If you keep to the binary route
//allocate memory to contain the whole file + HEADER
buffer = (char*)malloc(sizeof(char)*lSize + 2048);
int chars=0;
//print header
chars+=sprintf(buffer+chars, "%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n", boundary, nameForm, filename);
chars+=sprintf(buffer+chars, "Content-Type: %s\r\n", type);
chars+=sprintf(buffer+chars, "Content-Length: %d\r\n", lSize);
chars+=sprintf(buffer+chars, "\r\n");
memcpy(buffer + chars,content,lSize);
chars+=lSize;
chars+=sprintf(buffer+chars, "\r\n");
chars+=sprintf(buffer+chars, "%s--\r\n", boundary);
But in any case my recommendation is for your to look at any of the many libraries that exists that implements HTTP communication (libCURL is a good place to start)
Some additional notes:
instead of
BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
do
BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, chars);
as strlen(buffer) will stop at the first null character.
and Whent you're printing the result to std out, it will be treated as string.... and end with the first null.

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;
}