Recently I changed my WinINet code from synchronous mode to asynchronous. However, my program now crashes (Error, foo.exe has stopped working...) during operation. After some debugging, I figured out that the program was crashing right after InternetConnect()
sent INTERNET_STATUS_HANDLE_CREATED
to the callback function. After some more debugging, I found that two errors have been thrown: ERROR_NO_TOKEN (1008) - An attempt was made to reference a token that does not exist.
(from GetLastError()
) and Program Received Signal ?, Unknown Signal
(from GDB when I set a breakpoint on InternetConnect()
)
Here is some of my code:
void iNetStat(HINTERNET h, DWORD_PTR context, DWORD stat, LPVOID info, DWORD len) //Internet Status Callback Function
{
ErrorExit("E3"); //1008 (ErrorExit outputs a MessageBox with the GetLastError code
char* msg2;
switch(stat)
{
case INTERNET_STATUS_CLOSING_CONNECTION:
{
msg2=const_cast<char*>("Closing Connection");
break;
}
case INTERNET_STATUS_CONNECTED_TO_SERVER:
{
msg2=const_cast<char*>("Connected To Server");
break;
}
case INTERNET_STATUS_CONNECTING_TO_SERVER:
{
msg2=const_cast<char*>("Connecting To Server");
break;
}
case INTERNET_STATUS_CONNECTION_CLOSED:
{
msg2=const_cast<char*>("Connection Closed");
break;
}
case INTERNET_STATUS_HANDLE_CLOSING:
{
msg2=const_cast<char*>("Handle Closing");
break;
}
case INTERNET_STATUS_HANDLE_CREATED:
{
if(context==1)
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)info;
cc1.connect = (HINTERNET)pRes->dwResult;
msg2=const_cast<char*>("Internet Handle Created");
SetEvent(cc1.connectEvent);
}
else if(context==2)
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)info;
cc1.hOpen = (HINTERNET)pRes->dwResult;
msg2=const_cast<char*>("Request Handle Created");
SetEvent(cc1.hOpenEvent);
}
break;
}
case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
{
msg2=const_cast<char*>("Intermediate Response");
break;
}
case INTERNET_STATUS_NAME_RESOLVED:
{
msg2=const_cast<char*>("Name Resolved");
break;
}
case INTERNET_STATUS_RECEIVING_RESPONSE:
{
msg2=const_cast<char*>("Receiving Response");
break;
}
case INTERNET_STATUS_RESPONSE_RECEIVED:
{
msg2=const_cast<char*>("Response Received");
break;
}
case INTERNET_STATUS_REDIRECT:
{
msg2=const_cast<char*>("Redirect");
break;
}
case INTERNET_STATUS_REQUEST_COMPLETE:
{
::MessageBox(mainHWND, "ISTRC", "alert", MB_OK);
msg2=const_cast<char*>("Request Complete");
SetEvent(cc1.completeEvent);
Read(h);
break;
}
case INTERNET_STATUS_REQUEST_SENT:
{
msg2=const_cast<char*>("Request Sent");
break;
}
case INTERNET_STATUS_RESOLVING_NAME:
{
msg2=const_cast<char*>("Resolving Name");
break;
}
case INTERNET_STATUS_SENDING_REQUEST:
{
msg2=const_cast<char*>("Sending Request");
break;
}
case INTERNET_STATUS_STATE_CHANGE:
{
msg2=const_cast<char*>("State Change");
break;
}
default:
{
msg2=const_cast<char*>("Unknown Status Given");
}
}
SendMessageA(ClientArea, AM_CLIENTWINDOW_STARTTEXT_CHANGE, 1000, (LPARAM)(LPCTSTR)msg2);
}
char* msg1=const_cast<char*>("Connecting To Server....");
SendMessageA(ClientArea, AM_CLIENTWINDOW_STARTTEXT_CHANGE, 500, (LPARAM)(LPCTSTR)msg1);
std::string defstr;
std::stringstream vstrm;
std::string vstr;
cc1.connectEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
cc1.hOpenEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
cc1.completeEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
cc1.iOpen=InternetOpen("Mail App", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
if(cc1.iOpen==NULL)
{
ErrorExit("HINTERNET c");
return 0;
}
if(InternetSetStatusCallback(cc1.iOpen, (INTERNET_STATUS_CALLBACK)iNetStat)==INTERNET_INVALID_STATUS_CALLBACK)
{
ErrorExit("ISSC");
return 0;
}
ErrorExit("E1"); //0
cc1.connect=InternetConnect(cc1.iOpen,"dmailserver01.site40.net",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,1);
ErrorExit("E2"); //never_called
//HINTERNET ws=InternetOpenUrl(c, "dmailserver01.site40.net", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, context);
if(cc1.connect==NULL)
{
if(GetLastError()!=ERROR_IO_PENDING)
{
ErrorExit("HINTERNET ws");
return 0;
}
WaitForSingleObject(cc1.connectEvent, INFINITE);
}
std::string rtypestr="POST";
std::string versionstr="HTTP/1.1";
const char* fn="/connect.php";
const char* rtype=rtypestr.c_str();
const char* version=versionstr.c_str();
PCTSTR accept[]={"text/html", "application/xhtml+xml", "application/xml;q=0.9", "image/webp", NULL};
cc1.hOpen=HttpOpenRequestA(cc1.connect, rtype, fn, version, *accept, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 2);
if(cc1.hOpen==NULL)
{
if(GetLastError() != ERROR_IO_PENDING)
{
ErrorExit("HINTERNET h");
return 0;
}
WaitForSingleObject(cc1.hOpenEvent, INFINITE);
}
BOOL res=HttpSendRequestA(cc1.hOpen, NULL, 0, NULL, 0);
WaitForSingleObject(cc1.completeEvent, INFINITE);
if(res==false)
{
ErrorExit("res");
return 0;
}
//InternetCloseHandle(h);
//InternetCloseHandle(ws);
//InternetCloseHandle(c);
Any help is appreciated! ~Hom
Info:
IDE: Orwell Dev-C++
Compiler: TDM-GCC 4.8.1 32-bit
OS: Windows 8.1 32-bit
To those in the future:
1) Make sure your IntenetStatusCallback function is void CALLBACK, not just void.
2) Do not WaitForSingleObject the request completion event (If you set one).