libcurl HTTPS request and crash under VS 2008 - winapi

FIXED: Thanks Igor
Fix is at bottom.
I want to use VS 2008 to send intents to Android. Could not be a simpler request, I thought. Openssl is crashing though and it is curious as to why. Let's start with the code:
#include <stdio.h>
#include <conio.h>
#include <curl/curl.h>
#include <string>
#include <iostream>
using namespace std;
#pragma comment( lib, "ws2_32.lib" )
int main(void)
{
CURL *curl;
CURLcode res = CURL_LAST;
curl_global_init( CURL_GLOBAL_DEFAULT );
curl = curl_easy_init();
if(curl)
{
string website = "https://android.googleapis.com/gcm/send";
const char* headers [] = { "Content-Type: application/json", "Authorization:key=..." };
string json = "{ 'registration_ids':['...']}";//, 'data':'none'}";
curl_easy_setopt( curl, CURLOPT_URL, website.c_str() );
curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers );
//curl_easy_setopt( curl, CURLOPT_POSTFIELDS, json.c_str() ); << not currently needed
curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, FALSE ); // --insecure or -k
try
{
res = curl_easy_perform( curl ); << crashes here!
}
catch( ... ) {}
The rest of the code is really unimportant and this code is boilerplate. The crash point is at curl_easy_perform. The error is:
Unhandled exception at 0x61524ffb in HTTPS_sender01.exe: 0xC0000005:
Access violation reading location 0x68747541.
So this crashes deep in the curllib.dll and appears to be a call to openssl, but I can't be sure. However, if I comment out the option CURLOPT_SSL_VERIFYPEER, then this runs fine but the android server rejects me because of no certificate.
Downloading source has gotten me almost nowhere since that requires openssl and who knows where to download the correct version of that (I have found around 30 sites... all with different versions including GunWin32 and I have so many download folders now, I have no idea what to do). I also don't know which versions of libs to use for libcurl for vs 2008. After several days of looking at this, I thought that I'd ask for guidance or help.
Any thoughts on https for android from visual studio. BTW, I will need to port this to linux eventually, so any advice there might be helpful too.
libcurl is downloaded from here: http://www.dll-files.com. the includes and source are from 7.19.3. This lib came with a version of openssl... I copied the instructions from here... http://quantcorner.wordpress.com/2012/04/08/using-libcurl-with-visual-c-2010/
Also, I did try using the openssl cert from the libcurl... the opensource one, and Android.google rejected that:
curl_easy_setopt( curl, CURLOPT_CAPATH, "C:/projects/libraries/libcurl/curl-ca-bundle.crt");
FIX:
struct curl_slist *slist=NULL;
int numHeaders = sizeof( headers) / sizeof(headers[0]);
for( int i=0; i<numHeaders; i++ )
{
slist = curl_slist_append( slist, headers[i] );
}
curl_easy_setopt( curl, CURLOPT_HTTPHEADER, slist );

CURLOPT_HTTPHEADER option does not accept an array of char* pointers as you seem to believe, but curl_slist* pointer you obtained from curl_slist_append.

Related

How to Clear/Flush the DNS Cache in Win32 API's

I am looking for a way to programmatically clear/flush the local win32 dns cache (Equivalent of calling "ipconfig /flushdns").
There were ways to do this with a hidden API in winsock.dll but winsock.dll is no longer part of Windows and as such this method will no longer work.
Does anyone know how this should be done now?
Checked ipconfig.exe's dependencies using Dependency Walker
Found dnsapi.dll among them
Checked its exported functions, and found DnsFlushResolverCache
Shallowly browsed the web, and found its signature (only found references like this on official site: [MS.Docs]: Windows 8 API Sets), meaning it's not public, so software relying on it, is not robust)
Created a small test program
main00.c:
#include <stdio.h>
#include <Windows.h>
typedef BOOL (WINAPI *DnsFlushResolverCacheFuncPtr)();
int main() {
HMODULE dnsapi = LoadLibrary("dnsapi.dll");
if (dnsapi == NULL) {
printf("Failed loading module: %d\n", GetLastError());
return -1;
}
DnsFlushResolverCacheFuncPtr DnsFlushResolverCache = (DnsFlushResolverCacheFuncPtr)GetProcAddress(dnsapi, "DnsFlushResolverCache");
if (DnsFlushResolverCache == NULL) {
printf("Failed loading function: %d\n", GetLastError());
FreeLibrary(dnsapi);
return -2;
}
BOOL result = DnsFlushResolverCache();
if (result) {
printf("DnsFlushResolverCache succeeded\n");
} else {
printf("DnsFlushResolverCache succeeded: %d\n", GetLastError());
}
FreeLibrary(dnsapi);
return 0;
}
Output:
e:\Work\Dev\StackOverflow\q052007372>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64
e:\Work\Dev\StackOverflow\q052007372>dir /b
dnsapi_func_list.txt
main00.c
e:\Work\Dev\StackOverflow\q052007372>cl /nologo main00.c /link /OUT:main00.exe
main00.c
e:\Work\Dev\StackOverflow\q052007372>dir /b
dnsapi_func_list.txt
main00.c
main00.exe
main00.obj
e:\Work\Dev\StackOverflow\q052007372>main00.exe
DnsFlushResolverCache succeeded
Note: Even if the function call completed successfully, I am not sure how to check whether it did what it's supposed to do (or better: what its name suggests it should do, which seems to be what you need).
Let me know how it works.
Update #0
Thank you for the info #TimJohnson!! I was too in a rush to look at ipconfig /? ([MS.Docs]: ipconfig) output (which I had in another cmd window :d ) and notice the option :) . It does work (the cache is heavily updated, and I can see differences before and after running the program) !!!

Error 12003 FTP File Upload Error

Hello and good evening ,
This is centered for FTP File upload using C++. I have been trying to upload an FTP File and i get Error 12003 been searching out on the web, i havent seen anything useful.. seems annoying.
My code looks like this
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")
int main()
{
HINTERNET hInternet;
HINTERNET hFtpSession;
hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if(!hInternet)
{
printf("Error : %d\n",GetLastError());
}
hFtpSession = InternetConnect(hInternet, "myohyip8.5gbfree.com", INTERNET_DEFAULT_FTP_PORT, "myohyip8", "WxqHjNGv", INTERNET_SERVICE_FTP, 0, 0);
if(!hFtpSession)
{
printf("Error : %d\n",GetLastError());
}
if (!FtpPutFile(hFtpSession, "C:\\ivan.txt", "myivan.txt", FTP_TRANSFER_TYPE_BINARY, 0))
{
printf("Error : %d\n", GetLastError());
}
else{
printf("File Upload Successful :)\n");
}
InternetCloseHandle(hFtpSession);
InternetCloseHandle(hInternet);
system("PAUSE");
return 0;
}
This has been giving me worries, i dont have a single Idea on where to go from here , seems to me like a file system error.
The first thing I do when troubleshooting an ftp problem is to try getting a regular ftp program (e.g. filezilla, or whatever) to connect and perform the same operation on that same machine. If it can connect, you'll be able to see a log of the server conversation in that software that will give you good parameters to work with. If you cannot connect, you'll see in that same log what the problem might be.
Without using such software to be sure, my best guess is that have a problem trying to connect in regular mode and you should be in passive (essentially a firewall issue). You can pass in INTERNET_FLAG_PASSIVE in the 2nd to last parameter of your InternetConnect call. That will switch it to passive mode.
e.g.
hFtpSession = InternetConnect(hInternet, "myohyip8.5gbfree.com", INTERNET_DEFAULT_FTP_PORT, "myohyip8", "WxqHjNGv", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);

curl_easy_escape not working from C++ dll

I am having trouble using the curl_easy_escape function in a C++ dll. If I create a console application, curl_easy_escape works as expected.
cURL curl-7.28.1-devel-mingw32
Visual Studio 2010
Console Application (working as expected)
int _tmain(int argc, _TCHAR* argv[])
{
CURL *curl;
char *data1;
char *data2;
int data2len;
curl = curl_easy_init();
if (curl)
{
data1 = curl_easy_escape(curl, "this is a string with spaces", 0);
printf("\r\ndata1 = %s\r\n", data1);
data2 = curl_easy_unescape(curl, data1, 0, &data2len);
printf("\r\ndata2 = %s\r\n", data2);
curl_easy_cleanup(curl);
}
printf(“\r\nPress any key to continue\r\n”);
return 0;
Output
data1 = this%20is%20a%20string%20with%20spaces
data2 = this is a string with spaces
Press any key to continue
C++ DLL
Visual C++ > Win32 > Win32 Project
Application type = DLL (all other options as default)
Linker > Input > Additional Dependencies, added libcurl.lib
extern "C"
{
__declspec(dllexport) int * curl_test(char *sBuf)
{
CURL *curl;
curl = curl_easy_init();
if (curl)
{
// The following line does not work
//strcpy(sBuf, curl_easy_escape(curl, "this is a string with spaces", 0));
// This line does work
strcpy(sBuf, "this is a string with spaces");
curl_easy_cleanup(curl);
}
return 0;
}
}
The dll is used in a C program and calls curl_test with char ptr[256]. With curl_easy_escape in place, the LoadLibrary call fails:
Error: C interpreter run time error: Error -- File error : LoadLibrary(mydll.dll) failed : The specified procedure could not be found.
Note that this is on the LoadLibrary, so the curl_test function has not been called yet.
I suppose I can find some URL encode/decode functions, but would prefer to use what cURL already offers. I also have the same issue with the curl_easy_strerror function.
Could it be the ‘const char *’?
Update
Ideally I would like to use curl_easy_escape/curl_easy_unescape, but as a workaround I decided to implement my own URL encoding/decoding in C. I found efficient, well written encoding/decoding functions at http://www.geekhideout.com/urlcode.shtml

How do I use boost library with WDK environment

I wanna to compile my c plus plus project that using boost library with WDK rather than VisualStudio.
My computer's OS is Windows7-64bit, the WDK version is 7.6 and boost library version is 1.51
Once I compile my source code project, the WDK compiler will occure an error:
e:\lib\boost_1_51_0\boost\array.hpp(72) : error C2039: 'ptrdiff_t' : is not a member of 'std' .
Whole project's file contents are as follow:
File sources:
TARGETTYPE=PROGRAM
TARGETNAME=helloworld
UMENTRY=main
USE_MSVCRT=1
USE_NATIVE_EH=1
#
# use iostream package and STL
#
USE_IOSTREAM=1
USE_STL=1
STL_VER=70
#
# my boost library root directory
#
BOOST_INC_PATH=E:\lib\boost_1_51_0
INCLUDES=$(BOOST_INC_PATH)
TARGETLIBS=$(SDK_LIB_PATH)\user32.lib
SOURCES=HelloWorld.cpp
UMTYPE=console
UMBASE=0x4000000
File HelloWorld.cpp:
#include <iostream>
#include <vector>
#include <string>
#include <boost/array.hpp>
void InvokeVector()
{
//invoke STL's vector
std::vector<std::string> vec;
vec.push_back("Entry ");
vec.push_back("of ");
vec.push_back("Vector");
vec.push_back("……\n");
//print vec
for (int i=0; i<vec.size(); i++) {
std::cout<<vec.at(i);
}
}
void InvokeBoost()
{
//invoke Boost's array<T, N>
boost::array<int, 3> arr = {1, 2, 3};
for (int i=0; i<arr.size(); i++) {
std::cout<<"arr["<<i<<"]"<<"is" <<arr[i]<<std::endl;
}
}
int main()
{
// InvokeVector(); //run normally
InvokeBoost(); //it will occure an error
return 0;
}
Could you please teach me how to solve this problem? Any help will be greatly appreciated!
Short answer: No.
But you can port some.
It's well explained here : The NT Insider:Guest Article: C++ in an NT Driver
One of the main problems with C++ in the
kernel is that most of the "nice" features of the language are not
directly available in that mode. Some are easy to recreate and we will
see how to do that. However, some features should be forgotten such as
C++ exceptions, which are not the same as kernel exceptions.
Such features have to be forgotten simply because there is no support
for them in kernel mode. Translation: does not compile. If you have
the time and energy you may attempt to port them to kernel mode, but
frankly, exceptions are too slow for kernel mode. This will have an
impact on your C++ coding style, which is something you should keep in
mind.
longer answer - yes
just add
typedef int ptrdiff_t;
before pulling in boost headers and all will be well for basic boostness

boost library inside c++/cli.. exit with "code 0xC0020001: The string binding is invalid"

I am using the boost library for getting the current system time and my code works but visualt studio 2010 exits after the program.the debugger breaks while trying to free the non existing pointer. I know this is because of the boost native code.Since there is no error if I comment the boost portion of code.
Till now I tried using the #pragma as explained in MSDN but with no success.Can someone provide me some suggestions.? (I also tried GetSystemTime function to get the time but i cannot get the microsecond detail like boost.)
MY Code
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& stimeblock);
#pragma managed(pop)
int main()
{
c++/cli code
SDateTime stimestruct[1];
//call to the function having the boost code..
GetSystemDateTime(stimestruct[0]);
}
Function Definition
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& timeblock)
{
// SYSTEMTIME time;
// GetSystemTime(&time);
// WORD millis = (time.wSecond * 1000) + time.wMilliseconds;
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
std::tm pt_tm = to_tm(now);
std::cout << now << std::endl;
//std::cout << time.wYear<< time.wMonth<<time.wDay //<<time.wHour<<time.wMinute<<time.wSecond<<time.wMilliseconds << std::endl;
std::string timestring = to_iso_string(now);
std::string sYear = timestring.substr (0,4);
std::string sMonth = timestring.substr (4,2);
std::string sDay = timestring.substr (6,2);
std::string sHour = timestring.substr (9,2);
std::string sMinute = timestring.substr (11,2);
std::string sSecond = timestring.substr (13,2);
std::string sUSecond = timestring.substr (16);
istringstream isYear(sYear);
istringstream isMonth(sMonth);
istringstream isDay(sDay);
istringstream isHour(sHour);
istringstream isMinute(sMinute);
istringstream isSec(sSecond);
istringstream isUSec(sUSecond);
// use is like an input stream
int iYear,iMonth,iDay,iHour,iMinute,iSecond,iUSecond;
isYear >> iYear;
isMonth >>iMonth;
isDay >>iDay;
isHour >>iHour;
isMinute >>iMinute;
isSec >>iSecond;
isUSec >>iUSecond;
timeblock.uiYear = iYear;
timeblock.usiMonth = time.wMonth;
timeblock.usiDay = time.wDay;
timeblock.usiHour = time.wHour;
timeblock.usiMinute = time.wMinute;
timeblock.usiSec = time.wSecond;
timeblock.udiUSec = time.wMilliseconds;
// Display version information
}
I've seen this error caused by using a static variable in native code in a C++/CLI assembly.
The only workaround I found was to remove the static variable, e.g., by moving it to class or file scope.
However, if this static variable is in the boost code, doing so may not be easy/possible. In that case, you could create a separate C++ file that's compiled without /clr, use the boost function in that file, and link that into your C++/CLI assembly.
This error seems to be caused by the compiler generating incorrect code. I filed a bug with Microsoft, which was closed "won't fix", but the compiler team gave some other workarounds in their response.
Try using
#pragma managed(push, off)
#pragma managed(pop)
around the #include lines for all boost header files.
I'm on the same problem for a few days now.
this is the best workaround i have found. and also explains why this is happening.
look at the end (number 7 and 9)
hope this helps http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI

Resources