Establishing GPRS Connection on Windows CE and Windows Mobile: Sample Codes

Sometimes developers asking for support have straightforward goals they want to achieve with the minimal amount of code, even if the "application" will work only on very specific scenarios. This was the case for a request I handled, where the goal was: connect the device via GPRS to Internet, when it’s not cradled to a desktop PC and WiFi is not available. As you may know connections in Windows Mobile are entirely handled by the Connection Manager, and developers are "encouraged" on using only Connection Manager APIs, as long as you want CM-aware applications to run as expected. For example, IE Mobile is a CM-aware application: if you open a GPRS connection through RAS APIs as documented in the Windows *CE* documentation (see here), then Connection Manager wouldn’t sense it and IE Mobile would request a new one. A well done article about this for mobile developers was written by Jim Wilson and is available here.

So, the "recommended" way on Windows Mobile is to invoke CM APIs, while on Windows CE you can use for example RAS APIs (CM is not available) – see below. Note that this code is meant to work when no other less expensive networks are available (ActiveSync\WMDC’s Desktop-Passthrough, WiFi).

#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include "connmgr.h"

GUID GetNetworkForURL (LPCTSTR url)
    DWORD dwIndex = 0;
    GUID rv;
    if (!SUCCEEDED (ConnMgrMapURL (url, &rv, &dwIndex)))
        rv = GUID_NULL;

    return rv;

HRESULT EstablishConnection (LPCTSTR url, DWORD retries, DWORD timeout, DWORD* dwStatus, HANDLE hConnection)
    ZeroMemory (&ConnectionInfo, sizeof (ConnectionInfo));
    ConnectionInfo.cbSize = sizeof (ConnectionInfo);

    ConnectionInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET; 
    ConnectionInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP; 
    ConnectionInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE; 
    ConnectionInfo.guidDestNet = GetNetworkForURL (url);

    return ConnMgrEstablishConnectionSync (&ConnectionInfo, &hConnection, timeout, dwStatus);

    // Called when there was an error while connecting
    // generally due to network connection not being available (no modem, no nic etc).
    HRESULT DoConnectingError(DWORD dwStatus)
        // we received an error to do with connecting.
        SHELLEXECUTEINFO sei = {0};
        TCHAR szExec[MAX_PATH];
        wsprintf( szExec, TEXT("-CMERROR 0x%x -report"), dwStatus );
        sei.cbSize = sizeof(sei);
        sei.hwnd = NULL;
        sei.lpFile = TEXT(":MSREMNET");
        sei.lpParameters = szExec;
        sei.nShow = SW_SHOWNORMAL;
        ShellExecuteEx( &sei );
        return E_FAIL;

int _tmain(int argc, _TCHAR* argv[])
    DWORD dwStatus = 0;
    HANDLE hConnection = NULL;

    LPCTSTR url = L""; //just to set Internet network - and no need for proxies
    HRESULT hr = EstablishConnection (url, 10, 25000, &dwStatus, hConnection);

    if ( FAILED( hr ) )

    ConnMgrReleaseConnection(hConnection, TRUE);
    return 0;


while on Windows CE-based devices:

BOOL ConnectGPRSonWindowsCE()
    HRASCONN hRASConnection = NULL;
    DWORD nRet;

    RASENTRYNAME TempEntryName;
    TempEntryName.dwSize = sizeof(RASENTRYNAME);
    unsigned long EntryBufferSize = sizeof(TempEntryName);
    unsigned long EntryWritten = 0;

    //ERROR_BUFFER_TOO_SMALL is expected
    nRet = RasEnumEntries( NULL, NULL, &TempEntryName, &EntryBufferSize, &EntryWritten );
        WCHAR strErr[255];
        wsprintf(strErr,L"RasEnumEntries failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;

    RASENTRYNAME *RasEntryNameArray = (RASENTRYNAME*)malloc(EntryBufferSize);
    RasEntryNameArray[0].dwSize = sizeof(RASENTRYNAME);
    nRet = RasEnumEntries( NULL, NULL, RasEntryNameArray, &EntryBufferSize, &EntryWritten );
    if (0 != nRet)
        WCHAR strErr[255];
        wsprintf(strErr,L"RasEnumEntries failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;

    int GPRSEntry = -1;

    RASENTRY RasEntry;
    memset( &RasEntry, 0, sizeof(RasEntry) );
    RasEntry.dwSize = sizeof(RasEntry);
    DWORD dwEntrySize = sizeof(RasEntry);
    unsigned char Buffer[4098];
    memset( Buffer, 0, sizeof(Buffer) );
    DWORD dwBufferSize = sizeof(Buffer);

    for ( unsigned long iEntry = 0; iEntry < EntryWritten; iEntry++ )
        // Check if the name has GPRS in it 
        // AND
        // if Local Phone Number contains "~GPRS!"
        nRet = RasGetEntryProperties(NULL, RasEntryNameArray[iEntry].szEntryName, &RasEntry,&dwEntrySize,NULL,NULL);
        if (0 != nRet)
            WCHAR strErr[255];
            wsprintf(strErr,L"RasGetEntryProperties failed: Error %d\n", nRet);
            MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
            return FALSE;

        if ((wcsstr(RasEntry.szLocalPhoneNumber,L"~GPRS!") != NULL) 
            (wcsstr(RasEntryNameArray[iEntry].szEntryName, L"GPRS") != NULL))
            //RAS entry is GPRS - exit 'for' loop
            GPRSEntry = iEntry;

    nRet = RasGetEntryProperties( NULL, RasEntryNameArray[GPRSEntry].szEntryName, &RasEntry, &dwEntrySize, Buffer, &dwBufferSize );
    if(0 != nRet)
        WCHAR strErr[255];
        wsprintf(strErr,L"RasGetEntryProperties failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;

    // Configure the RASDIALPARAMS structure
    RASDIALPARAMS RASDialParameters;
    memset( &RASDialParameters,0,sizeof( RASDIALPARAMS ) );
    RASDialParameters.szPhoneNumber[0] = NULL; //TEXT('\0');
    RASDialParameters.szCallbackNumber[0] = NULL; //TEXT('\0');
    RASDialParameters.dwSize = sizeof( RASDIALPARAMS );
    wcscpy( RASDialParameters.szEntryName, RasEntryNameArray[GPRSEntry].szEntryName);
    RASDialParameters.szUserName[0] = TEXT('\0');
    RASDialParameters.szPassword[0] = TEXT('\0');
    RASDialParameters.szDomain[0] = TEXT('\0');
    //wcscpy (RasDialParams.szUserName, szUserName); //This is optional    
    //wcscpy (RasDialParams.szPassword, szPassword); //This is optional
    //wcscpy (RasDialParams.szDomain, szDomain); //This is optional

    //try reuse GPRS connection
    BOOL bPassword = FALSE;
    nRet = RasGetEntryDialParams(NULL, &RASDialParameters, &bPassword);
    if (0 != nRet)
        WCHAR strErr[255];
        wsprintf(strErr,L"RasGetEntryDialParams failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;

    //free resources not on the stack
    free ((VOID*)RasEntryNameArray);
    //  Try to establish RAS connection.
    if ( RasDial( NULL, NULL, &RASDialParameters, 
            NULL, // Notifier type is NOT a window handle
            NULL, // Window receives notification message - none
            &hRASConnection ) != 0 )
        if ( hRASConnection != NULL )
            RasHangUp( hRASConnection );
        hRASConnection = NULL;
        MessageBox (/*hDlgWnd*/NULL, L"Could not connect using RAS", /*szTitle*/ L"GPRS Monitor", MB_OK);
        return FALSE;

    hRASConnection = NULL;
    return TRUE;

Comments (22)

  1. This post is somehow related to a previous one ( Establishing GPRS Connection on Windows CE and Windows

  2. Santosh Jha says:

    I have a related problem. I do not know if this is right forum to ask. If this is not the right forum, can you please direct me to right forum please?

    I am using Windows CE 4.2, and I wanted Bluetooth USB Dongle to connect to PC using ActiveSync.  Here are the things I did:

    1.  Include Bluetooth USB driver in Platform Bilder Project

    2. Included ASUI sample application in my CE platform

    3. Updated the registry accordingly.

    4. It creates RAS entry for Bluetooth, but when it calls RasDial, it returns with error code 608, device not found.

    5. On the PC side, I have ActiveSync setting, selecting the BT virtual COM port.

    Bluetooth stack on CE device is loaded, I can see the CE device from my laptop. But it does not see any service on CE device.

    Thanks for your help.

  3. Hi Santosh,

    The topic is a bit different (here I was talking about GPRS, you’re interested on Bluetooth and ActiveSync). You may ask to MSDN Forums, probably the best one for you is If you won’t find a solution, you may also open a request at Microsoft Technical Support.



  4. forzafaith says:

    Hi, I have some problems in connecting the windows CE 5.0 platform to a Siemens GPRS modem (mod. TC35). I followed the instructions on this site ( I have a serial connection between the platform and the modem. I insert a Vodafone SIM card in to the modem.

    I create a new dial up connection as shown on the site: baudrate 19200 (the modem supports util 115 kB), no parity, hw flow control..  then I insert the special modem command: +cgdcont=1, "IP", "internet". My phone number is *99***1#. So I doible click on my new connection and don’t insert username and pwd. When the platform tries to connect, on the screen appears the following error message: "the port is not available: another program may be using it. What should I do to let the platform and the modem work correctly? thanks.

  5. Hi Forzafaith, personally I suggest to touch base with the Windows CE’s OEM to see if your issue is OEM-specific: it may well be that the "another program" the error message is talking about is OEM’s. HTH.

  6. afriza says:

    Hi Raffael,

    How can I set the APN for the Dial-Up?

  7. Hi afriza,

    On Windows Mobile, you can use XML Provisioning and specifically the CM_GPRSEntries. On Windows CE, you should use RasSetEntryDialParams to set the RASDIALPARAMS structure you need later to retrieve through RasEnumEntries. You may start from



  8. afriza says:

    Hi Raffaele,

    I’ve taken a look at RasSetEntryDialParams() and RasSetEntryProperties() but I haven’t found any APN related variables, or did I missed out something here?


  9. Maybe because the sample code at the page I mentioned ( omitted such parts…

     // Insert code here to fill the RASENTRY structure.

     // …

     // Insert code here to fill up the RASDIALPARAMS structure.

     // …

    but this is where you can set the APN related variables. For example:

    RASENTRY RasEntry;

    RASIPADDR EmptyIP = {0,0,0,0};

    memset (&RasEntry, 0, sizeof(RASENTRY));

    RasEntry.dwSize = sizeof(RASENTRY);

    RasEntry.dwfOptions = 0;

    RasEntry.dwCountryID = 0;

    RasEntry.dwCountryCode = dwCountryCode;

    _tcscpy (RasEntry.szAreaCode, lpszAreaCode);

    _tcscpy (RasEntry.szLocalPhoneNumber, lpszPhoneNumber);

    RasEntry.dwAlternatesOffset = 0;

    RasEntry.ipaddr = EmptyIP;

    RasEntry.ipaddrDns = EmptyIP;

    RasEntry.ipaddrDnsAlt = EmptyIP;

    RasEntry.ipaddrWins = EmptyIP;

    RasEntry.ipaddrWinsAlt = EmptyIP;

    RasEntry.dwFrameSize = 1500;

    RasEntry.dwfNetProtocols = RASNP_Ip;

    RasEntry.dwFramingProtocol = RASFP_Ppp;

    _tcscpy (RasEntry.szScript, TEXT(""));

    _tcscpy (RasEntry.szAutoDialDll, TEXT(""));

    _tcscpy (RasEntry.szAutoDialFunc, TEXT(""));

    // _tcscpy (RasEntry.szDeviceType, RASDT_Modem);

    _tcscpy (RasEntry.szDeviceType, RASDT_Direct);

    _tcscpy (RasEntry.szDeviceName, lpszModemName);

    _tcscpy (RasEntry.szX25PadType, TEXT(""));

    _tcscpy (RasEntry.szX25Address, TEXT(""));

    _tcscpy (RasEntry.szX25Facilities, TEXT(""));

    _tcscpy (RasEntry.szX25UserData, TEXT(""));

    RasEntry.dwChannels = 1;

    RasEntry.dwReserved1 = 0;

    RasEntry.dwReserved2 = 0;

    RetVal = RasSetEntryProperties (





    NULL, //default DEVCFG parameters


  10. afriza says:

    Hi Raffaele,

    Thank you for your replies,

    maybe I misunderstood something, but what I want to set is something like "internet" value for Access Point Name ( APN, as described in the example in ).

    I think it corresponds to the GPRSInfoAccessPointName parameter in the XML Provisioning.

    However, I find no corresponding variable in RASENTRY ( ) nor in RASDIALPARAMS ( )

    previously I used to open a serial port and send AT command +cgdcont=1, "IP", "internet" to set the APN. I wonder if there is a better way using some APIs.

    Thank you again and regards,


  11. afriza says:

    Just for clarification, I am developing for Windows CE.

  12. You should set Extra dial-string modem commands, for example thru the registry under HKLMExtModems<ModemDriver>Init. I’m referring to a string like AT+CGDCONT=1,"IP","", I’m sorry I don’t have a sample code right now but you may be able to find it over the web now that you know what to look for. There will be more than one key, each separated by the literal string "<cr>".



  13. BPM80 says:

    i am java coder but i need to develop an app for my win ce6 device in .net.

    i tired this code, but i do something wrong.

    i only made a new project and inserted this code. i was able to compile and depoly to my device.

    here my output:

    Modul laden: RasConn.exe

    Modul laden: coredll.dll.0409.MUI

    Modul laden: MZFC0960.dll

    Modul laden: ddraw.dll

    Modul laden: fpcrt.dll

    Modul laden: ole32.dll

    Modul laden: rpcrt4.dll

    Modul laden: lpcrt.dll

    Modul laden: coredll.dll

    Das Programm "[0xB72007E] RasConn.exe" wurde mit Code -1 (0xffffffff) beendet.

    can u help me?

    here you can see why i need this:

    there is a firmware bug on my mobile device. so i am not able to make a connection with mobilkom austria.

    so i need an application to do this.



  14. Hi Markus, I’m sorry but didn’t understand precisely the issue. I imagine you know that the sample above is native language, not for .NET Compact Framework (so you should use Win32 templates). Also, make sure you’re targeting the right platform: Wiindows *Mobile* is different from Windows *CE* in terms of GPRS connectivity (the Connection Manager is available only on Mobile). Consider also opening a Service Request at Microsoft Technical Support: this may be an option, before the issue becomes too urgent. Viceversa, i.e. if not urgent, then we may also try continuing offline – just contact me thru



  15. BPM80 says:

    native means that i can use a Win32 template and can run on win ce6 too?

    I know that i have to use RAS and not CM.

    I used a ppc template.

  16. Feel free to continue offline as I mentioned in my previous answer.

    Doesn’t the manufacturer of the Windows CE 6.0-based device provide a "Private SDK" so that you can target it? Otherwise Visual Studio’s "templates" will use the wrong INCLUDE folder, i.e. the wrong header files – hence the same code may not be eligible to work on that platform.



  17. ed8500 says:

    Hi Raffaele,

    Do you happen to know if the RasDial function has a limit to the length of the username/password ? I have an application trying to access a private APN with a login of 25 chars (a few special ones, but all below the D128 in the ASCII table), and a password of 10 chars. It fails all the time. Accessing a public APN (without username/password) works just fine.

    BTW, I have the impression whatever goes wrong with RasDial, you get error 0x279 (port not available).

    Thanks in advance !

  18. ed8500 says:

    Oeps, forgot to mention my device runs CE 5.0 !

    Thanks !

  19. Hi Ed! 25 chars should be allowed: looking at doc for RASDIALPARAMS, the lenght for user credentials are based on UNLENPWLEN constants and in "C:Program Files (x86)Windows Mobile 6 SDKPocketPCIncludeArmv4ilmcons.h" you can see:

    #define UNLEN       256                 // Maximum user name length

    #define PWLEN       256                 // Maximum password length

    So the problem might be with something else.. and in any case it's strange that whatever goes wrong with RasDial, you get ERROR_PORT_NOT_AVAILABLE: you may check if the issue is reproduced only on the device you're targeting. If the problem is reproduced on other devices, you may probably open an incident to Microsoft Technical Support for deep troubleshooting… if you don't know hot to open a Service Request, you can read some details on another post of mine:…/get-help-now-a-vademecum-about-requesting-technical-support-from-microsoft.aspx.



  20. DavidPellicer says:

    Hi Raffaele,

    I'm developing a Ril for Windows CE. I'm able to pass the data test through a Gprs Ndis (WWAN based) connection. In Windows Mobile with almost the same Ril I can configure the gpr ndis connection with the CM, but in CE I don't have it. Can you give me some help about configuring a WWAN connection in the UI or programmaticly?

    Thank you!

  21. Hi David, please consider using your support contract and open a Service Request – I'm afraid blog-comments wouldn't be as effective in your case. If you've never tried Microsoft Technical Support, hopefully you can find interesting info in a non-technical post of mine:…/get-help-now-a-vademecum-about-requesting-technical-support-from-microsoft.aspx. Should you encounter problems on opening the request, contact me offline thru…/contact.aspx.



  22. nat says:

    my windows embedded ce v6.00 i find it difficult to connect i need help