Programmatically making an Internet connection in Windows Mobile in C++

Although a lot of people seem to be finding my Twitter widget for Windows Mobile useful, it seems that there are also a few people who noticed that it was hacked together in a few hours overnight!

One of the more noticed issues was the fact that the widget reused the mobile’s existing Internet connection.

It was described in emails such as:

Some times I have to invoke a data session with PIE or another networked app before it will let me send a twit. Anyway to make it start it’s own network session if one doesn’t already exist?

and in tweets such as

ooh i'm liking cetwit. But not you, twittoday

oh and a side note to data apps everywhere: if you want a connection, REQUEST IT YOURSELF. I have better things to do than holding your hand

The issue is that when you use the web services APIs, this is all handled for you. But I rolled my own HTTP POST code using the wininet API. And these low-level calls aren’t so helpful.

It wasn’t a problem for me, because my phone is always connected anyway. But enough people have mentioned it, so I figured it was worth looking into!

If anyone is interested in how you start a connection programmatically in C++, read on.

#include "initguid.h"
#include "connmgr.h"

...

BOOL ConnectToNetwork(int timeoutsecs)
{
  // handle to connection to start
  HANDLE hConnection = NULL;

  // stores return value identifying status of connection attempt
  DWORD dwStatus;

  // initialise connection info structure
  CONNMGR_CONNECTIONINFO pConnectionInfo;
  ZeroMemory(&pConnectionInfo, sizeof(CONNMGR_CONNECTIONINFO));
   
  // set structure size
  pConnectionInfo.cbSize = sizeof(CONNMGR_CONNECTIONINFO);

  // set priority to identify that a user initiated this request
  // and the GUI is waiting on the creation of the connection
  pConnectionInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;

  // identify the network to connect to
  pConnectionInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
  pConnectionInfo.guidDestNet = IID_DestNetInternet;

  // specify that other applications can use this connection
  pConnectionInfo.bExclusive = FALSE;

  // specify that a connection should be made
  pConnectionInfo.bDisabled = FALSE;

  // request connection
  HRESULT hr = ConnMgrEstablishConnectionSync(&pConnectionInfo, 
                                              &hConnection,
                                              timeoutsecs * 1000, 
                                              &dwStatus);

  if (hr == S_OK)
  {
    return TRUE;
  }
  else 
  {
    switch (dwStatus)
    {
    case CONNMGR_STATUS_DISCONNECTED:
      MessageBox(NULL,TEXT("The connection has been disconnected"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_WAITINGFORPATH:
      MessageBox(NULL,TEXT("A path to the destination exists but is not presently available"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_WAITINGFORRESOURCE:
      MessageBox(NULL,TEXT("Another client is using resources that this connection requires"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_WAITINGFORPHONE:
      MessageBox(NULL,TEXT("Connection cannot be made while call in progress"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_NOPATHTODESTINATION:
      MessageBox(NULL,TEXT("No path to the destination could be found"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_CONNECTIONFAILED:
      MessageBox(NULL,TEXT("The connection failed and cannot be reestablished"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    case CONNMGR_STATUS_CONNECTIONCANCELED:
      MessageBox(NULL,TEXT("The user aborted the connection"),TEXT("Connection Manager"),MB_ICONERROR);
      break;    
    case CONNMGR_STATUS_WAITINGCONNECTION:
      MessageBox(NULL,TEXT("The device is attempting to connect"),TEXT("Connection Manager"),MB_ICONERROR);
      break;          
    case CONNMGR_STATUS_WAITINGCONNECTIONABORT:
      MessageBox(NULL,TEXT("The device is aborting the connection attempt"),TEXT("Connection Manager"),MB_ICONERROR);
      break;          
    case CONNMGR_STATUS_WAITINGDISCONNECTION:
      MessageBox(NULL,TEXT("The connection is being brought down"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    default:
      MessageBox(NULL,TEXT("The connection attempt failed"),TEXT("Connection Manager"),MB_ICONERROR);
      break;
    }
    return FALSE;
  }
}

There is still more that needs to be done to TwitToday before I can really call it a finished app… but it’s getting closer!

Tags: , , , , ,

8 Responses to “Programmatically making an Internet connection in Windows Mobile in C++”

  1. So is TwitToday now managing its own internet connection?

  2. dale says:

    yup – from v0.5

  3. Adrian says:

    Don’t forget to checkout ConnMgrQueryDetailedStatus – WM5 only – it was years before I came across this one!

    Adrian

  4. […] from adding the ability to initiate an internet connection, my Twitter widget for Windows Mobile Today screens is still virtually the same code as I wrote in […]

  5. Guru says:

    This is cool piece of code… Thanks!!!

  6. Walsh says:

    Agreed. (with Guru )

    This is the only code I could find so far that does this. Would be so kind as to tell me how I can implement this in my C# project ?

  7. Bruce says:

    Great piece of code.
    I didnt knew about your app, but i needed a way to initiate connection on my own app. Thanks !