Asynchronous WinINet - InternetConnect Error 1008

523 views Asked by At

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
1

There are 1 answers

0
Homberto On BEST ANSWER

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