[Windows CE] Using Ras C#

If we will ask somebody experienced questions like:”What should we use to establish dial up connection on Windows”, i`m totally sure that 90% of asked will answer use RAS library!

If some somebody will ask me what do to establish GPRS connection on Windows Mobile i answer use Connection Manager API, but there is nothing regarding Connection Manager API on Windows CE, but we can use RAS API!

If you developing on C++ or C thats not a problem, but what to do if your project on C#? I googled and found that opennet cf got ras components, but it aint free(!), so we need to create our own :)

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace CERas
{
/// <summary>
/// CERAS
/// </summary>
public class CERAS : IDisposable
{
#region Constants
private const int ENTRY_SIZE = 1464;
#endregion

#region P/Invoke
[DllImport("coredll.dll")]
public static extern uint RasDial(
IntPtr dialExtensions,
IntPtr phoneBookPath,
IntPtr rasDialParam,
uint notifierType,
IntPtr notifier,
ref IntPtr pRasConn);

[DllImport("coredll.dll")]
public static extern uint RasHangUp(IntPtr pRasConn);
#endregion

#region Private Declarations
private IntPtr rasConn_ = IntPtr.Zero; //Connection Handle
private uint result_ = 0;
private IntPtr rasEntry_ = IntPtr.Zero; //Entry Container
private string connName_ = ""; //connection name
private string userName_ = ""; //user name (could be empty string)
private string password_ = ""; // password (could be empty string)
#endregion

#region Properties
//property, sets or gets connection name
public string ConnectionName
{
get
{
return connName_;
}
set
{
if (value != connName_)
{
connName_ = value;
}
}
}

//property, sets or gets connection login
public string Login
{
get
{
return userName_;
}

set
{
if (value != userName_)
{
userName_ = value;
}
}
}

//property, sets or gets connection password
public string Password
{
get
{
return password_;
}
set
{
if (value != password_)
{
password_ = value;
}
}
}

//property, checks if connection established
public bool Established
{
get
{
return ((rasConn_ != IntPtr.Zero) && (result_ == 0));
}
}
#endregion

#region Public Methods
//Constructor
public CERAS()
{
rasConn_ = IntPtr.Zero;
result_ = 0;
rasEntry_ = Marshal.AllocHGlobal(ENTRY_SIZE); //Allocating 1464 bytes (size of Entry structure)
if (rasEntry_ == IntPtr.Zero)
{
throw new Exception("Error cannot get Allocate memory");
}
}

// Destructor
public void Dispose()
{
Marshal.FreeHGlobal(rasEntry_); //Free allocated memory
}

//Establishing connection, it will block thread that called this method
public bool Connect()
{
if (rasConn_ != IntPtr.Zero)
{
Disconnect();
}

FillEntry();
try
{
result_ = RasDial(IntPtr.Zero, IntPtr.Zero, rasEntry_, 0, IntPtr.Zero, ref rasConn_);
}
catch
{
//exception
}

if (result_ != 0)
{
Disconnect(); //we need call disconnect even if connection was not established
return false;
}
return true;
}

//Closing internet connection
public void Disconnect()
{
if (rasConn_ != IntPtr.Zero)
{
RasHangUp(rasConn_);
rasConn_ = IntPtr.Zero;
result_ = 0;
System.Threading.Thread.Sleep(3000); //read msdn, it says that we need wail like 3 seconds to release connection(!)
}
else
{
result_ = 0;
}
}
#endregion

#region Private Methods
//Clearing Entry Structure
private void ClearPtr()
{
//I`m totally sure that there should be easier way
for (int i = 0; i < ENTRY_SIZE; i++)
{
Marshal.WriteByte((IntPtr)(rasEntry_.ToInt32() + i), 0);
}
}

//Filling Entry structure
private void FillEntry()
{
ClearPtr();
IntPtr pCurrent = rasEntry_;
Marshal.WriteInt32(pCurrent, ENTRY_SIZE);

pCurrent = (IntPtr)(pCurrent.ToInt32() + 4);
foreach (byte b in Encoding.Unicode.GetBytes(connName_))
{
Marshal.WriteByte(pCurrent, b);
pCurrent = (IntPtr)(pCurrent.ToInt32() + 1);
}

pCurrent = (IntPtr)(rasEntry_.ToInt32() + 0x192);
foreach (byte b in Encoding.Unicode.GetBytes(userName_))
{
Marshal.WriteByte(pCurrent, b);
pCurrent = (IntPtr)(pCurrent.ToInt32() + 1);
}

pCurrent = (IntPtr)(rasEntry_.ToInt32() + 0x394);
foreach (byte b in Encoding.Unicode.GetBytes(password_))
{
Marshal.WriteByte(pCurrent, b);
pCurrent = (IntPtr)(pCurrent.ToInt32() + 1);
}
}
#endregion
}
}

Yau can download sources from here

BTW it should work on win mobile too :)

19 Responses to “[Windows CE] Using Ras C#”

Pages: « 2 [1] Show All

  1. 10
    admin Says:

    try to call rasdial as below
    RasDial(IntPtr.Zero, IntPtr.Zero, rasEntry_, 0xFFFFFFFF, hWnd_, ref rasConn_);

    where hWnd_ is Hande of your main form

  2. 9
    Prajwal Says:

    Hi,

    Thank you for the reply.

    See i am able to dial up a connection manually ie., Creating a new connection and setting the parameters along with the dialing properties like baudrate to 9600 bps, flow control to none and even the APN command +CGDCONT=1,”IP”,”airtelgprs.com” etc and right click on the connection and connect. This works absolutely fine.

    But my problem is to dial up the connection using the same connection i created manually specified above by programatically..

  3. 8
    admin Says:

    Sorry, but its dificult to understand what exactly wrong with your connection. i Got Sim300 and it works, may be problem in created entry? APN? initialization string? so on…

  4. 7
    Prajwal Says:

    Hi,

    Please can any body help me in establishing the Ras dial up connection on Win CE 5.0

    Thanks

  5. 6
    Prajwal Says:

    Hi Alex,

    Thank you for your kind information.

    I tried the code given by you. The message box also shows
    Connection result: True Is Established: True.

    But when i tried browsing in IE, i was not able.

    After triggering the Ras dial up application i right clicked on the connection which i created manually, in the context menu i get status in place of Connect or Disconnect.

    When i clicked on the Status i get nothing. Next time when i right click on the same connection i see connect option in the context menu.

    Thanks you.

    Regards,
    Prajwal

  6. 5
    admin Says:

    Hello Prajwal,

    the problem is that you forgot to set entry name, password and login, so code should be like this:

    try
    {
    CERas.CERAS objCE = new CERas.CERAS();
    objCE.ConnectionName = “_your_connection_name_”;
    objCE.Login = “”;
    objCE.Password = “”;
    bool val = objCE.Connect();
    MessageBox.Show(”Connection result: ” + val.ToString() + ” Is Established: ” + objCE.Established.ToString());
    }
    catch (Exception ex)
    {

    MessageBox.Show(ex.Message.ToString());
    }

  7. 4
    Prajwal Says:

    Hi,

    I am trying to do a dial up connection programatically on Win CE 5. I am using the above code to dial up in C#. But i am not able to make a dial up connection. When i display the result of Connect() method, i get False a bool value. I am able to make the dial up connection manually i.e., Creating new connection, setting connection properties and dialing up.
    Following is my code to connect in c#

    try
    {
    CERas.CERAS objCE = new CERas.CERAS();
    bool val = objCE.Connect();
    MessageBox.Show(”Connection result: ” + val.ToString() + ” Is Established: ” + objCE.Established.ToString());
    }
    catch (Exception ex)
    {

    MessageBox.Show(ex.Message.ToString());
    }

    Please any one out here help me…
    Thanks in advance.

  8. 3
    fanyy-b Says:

    thanks a lot, I searched this for 1 week and here is working solution, finally. Thanks again

    Fany

  9. 2
    [Windows Mobile] Connection Manager API C# | Alex Mogurenko`s Blog Says:

    […] posts ago i wrote about using RAS to establish internet connection in that post i mentioned about Connection Manager API. Full description you can find on MSDN, but […]

  10. 1
    Herbert Schroder Says:

    Thank you Thank you Thank you
    Will test it 2night
    If this works your’e an absolute life saver.
    I’ll have to convert to vb.net as the rest of the project uses vb.net
    Thank you Thank you Thank you

    Regards
    Herbert

Pages: « 2 [1] Show All

Leave a Reply