Inserting RAS Entry

F

Felipe T.

Im having a bad time working with RAS APIs. Im working in a personal Library
to implement RAS funcionality.
Iv managed to solve most of my needs, but for now...Im stucked with a
NotSupportedException with EnumDevices...

Well, anyway, i just need to insert a RAS Entry in the RAS list...

Anyone can help?
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi Felipe,


RAS is a big problem to implement, basically cause the structs are very
complex, I started almost a year ago to try to do it, but I did not finish
it, I use a dll that somebody from this group sent me, it was implemented on
C. Below you will find my progress for a RASDialer class, I haven;t touch
the code for over a year and it was never ever terminated but it can give
you a good start at least, it contain an implementation of EnumDevices that
I think to remember that it worked.

You will see that I did a class for each struct on RAS, they have variables
with the same name found on the original struct plus two methods, GetBytes()
that put the struct on a byte array to pass it ot unmanaged code, and
FromBytes() that is used to get the raw data from unmanaged code and create
the class in managed code.


So without further ado this is the code
I hope it helps you
Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

//****************************** CODE START **********
public class RASDialer
{
public string GenerateEmail( DataRow orderrow)
{
return "";

}

public static System.Text.Encoding encoder = new
System.Text.ASCIIEncoding();

public const string SourceDLL = "rasapi32.dll";
#region Constants
#if PPC
const int RAS_CHAR_SIZE = 2;
const int MAX_PATH = 56;

const int RAS_MaxEntryName =20;
const int RAS_MaxDeviceName = 32;
const int RAS_MaxPhoneNumber =128;
const int RAS_MaxCallbackNumber =128;
#else
const int RAS_CHAR_SIZE = 1;
const int MAX_PATH = 260;

const int RAS_MaxEntryName = 256;
const int RAS_MaxDeviceName = 128;
const int RAS_MaxPhoneNumber = 128;
const int RAS_MaxCallbackNumber = 128;

const int UNLEN = 256;
const int PWLEN = 256;
const int DNLEN = 15;


#endif

const int RASCS_PAUSED = 0x1000;
const int RASCS_DONE = 0x2000;



const int RAS_MaxDeviceType =16;
const int RAS_MaxParamKey =32;
const int RAS_MaxParamValue =128;
const int RAS_MaxIpAddress =15;
const int RAS_MaxIpxAddress =21;

#endregion

public class RASDIALPARAMS
{
public const int RAS_RASDIALPARAMS_SIZE = 1052;
public char[] szEntryName = new char[ RAS_MaxEntryName + 1];
public char[] szPhoneNumber = new char[ RAS_MaxPhoneNumber + 1];
public char[] szCallbackNumber = new char[ RAS_MaxCallbackNumber + 1];
public char[] szUserName = new char[ UNLEN + 1];
public char[] szPassword = new char[ PWLEN + 1];
public char[] szDomain = new char[ DNLEN + 1];

public byte[] GetBytes(){ return null;} // to be done
public void FromBytes( byte[] buffer){} // to be done
public void FromBytes( byte[] buffer, int startindex){} // to be done

}
public class RASENTRYNAME
{
public const int RAS_RASETRYNAME_SIZE = 264;

public Int32 dwSize;
public char[] szEntryName = new char[ RAS_MaxEntryName + 1];

public byte[] GetBytes()
{
int iNext =0;
byte[] buffer = new byte[RAS_RASETRYNAME_SIZE];
Array.Copy( BitConverter.GetBytes( dwSize), 0, buffer, iNext,
Marshal.SizeOf( typeof(int)));
iNext +=Marshal.SizeOf( typeof(int));
encoder.GetBytes( szEntryName, 0, RAS_MaxEntryName + 1, buffer, iNext);

return buffer;
}
public void FromBytes( byte[] buffer)
{
FromBytes( buffer, 0);

}
public void FromBytes( byte[] buffer, int startindex){
int iLength = 0;
int iNext = startindex;
iLength = Marshal.SizeOf(typeof(int));
dwSize = BitConverter.ToInt32(buffer, iNext);
iNext += iLength;
iLength = (RAS_MaxEntryName + 1) * RAS_CHAR_SIZE;
szEntryName = encoder.GetChars(buffer, iNext, iLength);

}
}

public class RASDEVINFO
{
public const int RAS_RASDEVINFO_SIZE= 152;

public Int32 dwSize;
public char[] szDeviceType = new char[ RAS_MaxDeviceType + 1];
public char[] szDeviceName = new char[ RAS_MaxDeviceName + 1];

public byte[] GetBytes()
{
int iNext =0;
byte[] buffer = new byte[RAS_RASDEVINFO_SIZE];
Array.Copy( BitConverter.GetBytes( dwSize), 0, buffer, iNext,
Marshal.SizeOf( typeof(int)));
iNext +=Marshal.SizeOf( typeof(int));
encoder.GetBytes( szDeviceType, 0, RAS_MaxDeviceType + 1, buffer,
iNext);
iNext +=Marshal.SizeOf( (RAS_MaxDeviceType + 1)* RAS_CHAR_SIZE );
encoder.GetBytes( szDeviceName, 0, RAS_MaxDeviceName + 1, buffer,
iNext);

return buffer;
}
public void FromBytes( byte[] buffer)
{
FromBytes( buffer, 0);
}
public void FromBytes( byte[] buffer, int startindex)
{
int iLength = 0;
int iNext = startindex;
iLength = Marshal.SizeOf(typeof(int));
dwSize = BitConverter.ToInt32(buffer, iNext);
iNext += iLength;
iLength = (RAS_MaxDeviceType + 1) * RAS_CHAR_SIZE;
szDeviceType = encoder.GetChars(buffer, iNext, iLength);
iNext += iLength;
iLength = (RAS_MaxDeviceName + 1) * RAS_CHAR_SIZE;
szDeviceName = encoder.GetChars(buffer, iNext, iLength);
}
}


[ DllImport(SourceDLL, EntryPoint="RasEnumDevices") ]
private static extern int _EnumDevices(
IntPtr rasPtr,
ref int rasLength,
ref int rasNum
);

[ DllImport(SourceDLL, EntryPoint="RasEnumEntries") ]
private static extern int _EnumEntries(
IntPtr ignored,
IntPtr ignoredToo,
IntPtr rasEntries,
ref int bufferSize,
ref int numEntries
);


public static string[] EnumEntries()
{
IntPtr rasPtr = IntPtr.Zero;
int rasLength = 0;
int rasNum = 0;
int size = RASENTRYNAME.RAS_RASETRYNAME_SIZE;
//Alloc one entry only
rasPtr = Marshal.AllocHGlobal( RASENTRYNAME.RAS_RASETRYNAME_SIZE);
Marshal.Copy( BitConverter.GetBytes( size ), 0, rasPtr , 4);
int x = _EnumEntries( IntPtr.Zero, IntPtr.Zero, rasPtr, ref rasLength,
ref rasNum);

rasPtr = Marshal.AllocHGlobal( rasLength);
Marshal.Copy( BitConverter.GetBytes( size ), 0, rasPtr , 4);
x = _EnumEntries( IntPtr.Zero, IntPtr.Zero, rasPtr, ref rasLength, ref
rasNum);
byte[] buffer = new byte[rasLength];
Marshal.Copy(rasPtr, buffer, 0, rasLength);
Marshal.FreeHGlobal( rasPtr);

return null;
}


public static RASDEVINFO[] EnumDevices()
{
IntPtr rasPtr = IntPtr.Zero;
int rasLength = 0;
int rasNum = 0;
int rasStructSize = RASDEVINFO.RAS_RASDEVINFO_SIZE;
rasPtr = Marshal.AllocHGlobal( rasStructSize);
Marshal.Copy( BitConverter.GetBytes( rasStructSize ), 0, rasPtr , 4);
int x = _EnumDevices( rasPtr, ref rasLength, ref rasNum);
if ( rasNum == 0 )
{
Marshal.FreeHGlobal( rasPtr);
return null;
}
if ( x != 0){
Marshal.FreeHGlobal( rasPtr);
rasPtr = Marshal.AllocHGlobal( rasLength);
Marshal.Copy( BitConverter.GetBytes( rasStructSize ), 0, rasPtr , 4);
Marshal.Copy( BitConverter.GetBytes( rasStructSize ), 0, rasPtr , 4);
x = _EnumDevices( rasPtr, ref rasLength, ref rasNum);
}
byte[] deviceInfo = new Byte[rasLength];
Marshal.Copy(rasPtr, deviceInfo, 0, rasLength);
Marshal.FreeHGlobal( rasPtr);

RASDEVINFO[] rasDevInfo = new RASDEVINFO[rasNum];
int iNext = 0;
for(int i=0; i<rasNum; i++)
{
rasDevInfo = new RASDEVINFO();
rasDevInfo.FromBytes( deviceInfo, iNext);
byte[] t = rasDevInfo.GetBytes();
iNext += RASDEVINFO.RAS_RASDEVINFO_SIZE;
}
return rasDevInfo;
}
public static string[] EnumDevicesAsString()
{
RASDEVINFO[] rasDevInfo = EnumDevices();
string[] entries = new string[ rasDevInfo.GetUpperBound(0)+1];

for ( int i = 0; i < rasDevInfo.GetUpperBound(0)+1; i++ )
{
entries = new string(rasDevInfo.szDeviceName);
}

return entries;
}
}
//****************************** CODE END **********
 
C

Chris Stephens

Hi Felipe,


We manage our RAS entrys by using calls to the ras api via a dll writtin in
evc, here are a few snippets from the dll that might be of use.....


DWORD WINAPI MProRASEnumDev(LPWSTR lpstr, DWORD &count)
{
DWORD lpcb = 0 , lpcDevices, nRet, dw;
WCHAR szTmp[255];
LPRASDEVINFOW lpRasDevInfo = NULL;

RasEnumDevices(lpRasDevInfo, &lpcb, &lpcDevices);

lpRasDevInfo = (LPRASDEVINFOW) GlobalAlloc(GPTR, lpcb);
lpRasDevInfo->dwSize = sizeof(RASDEVINFOW);

nRet = RasEnumDevices(lpRasDevInfo, &lpcb, &lpcDevices);

count = lpcDevices;

wcscpy(szTmp,_T(""));
if (nRet ==0)
{
for (dw = 0; dw < lpcDevices; dw++)
{
wcscat(szTmp, lpRasDevInfo->szDeviceName);
if (dw != lpcDevices)
wcscat(szTmp,_T(","));

lpRasDevInfo++;
}
wcscpy(lpstr,szTmp);
}

return nRet;
}

DWORD WINAPI MProRASCreateEntry(LPWSTR lpszName,
LPWSTR lpszLogin,
LPWSTR lpszPassword,
LPWSTR lpszPhoneNumber,
DWORD dwCountryCode,
LPWSTR lpszAreaCode,
LPWSTR lpszDeviceName)
{
DWORD dwSize, dwDevInfo, dwError;
RASENTRY RasEntry;
RASDIALPARAMS RasDialParams;
dwDevInfo = 128;
dwError = 0;

if (dwError = RasValidateEntryName(NULL, lpszName))
{
return dwError;
}

memset(&RasEntry,0,sizeof(RASENTRY));
dwSize = sizeof(RASENTRY);
RasEntry.dwSize = dwSize;

if (dwError = RasGetEntryProperties(NULL, _T(""),&RasEntry, &dwSize, NULL,
NULL))
{
return dwError;
}

// Fill the RASENTRY structure
_tcscpy(RasEntry.szAreaCode, lpszAreaCode);
RasEntry.dwCountryCode = (DWORD) dwCountryCode;
_tcscpy(RasEntry.szLocalPhoneNumber, lpszPhoneNumber);
_tcscpy(RasEntry.szDeviceType, RASDT_Modem);
_tcscpy(RasEntry.szDeviceName, lpszDeviceName);
RasEntry.dwfOptions = 520; //RASEO_DialAsLocalCall;

// Create a new phone-book entry.

if (dwError = RasSetEntryProperties(NULL, lpszName,
&RasEntry,sizeof(RASENTRY), NULL,0))
{
return dwError;
}

// Initialize a RASDIALPARAMS structure
memset(&RasDialParams,0,sizeof(RASDIALPARAMS));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
_tcscpy(RasDialParams.szEntryName, lpszName);

// Fill up the RASDIALPARAMS structure
_tcscpy(RasDialParams.szPhoneNumber, lpszPhoneNumber);
_tcscpy(RasDialParams.szUserName, lpszLogin);
_tcscpy(RasDialParams.szPassword, lpszPassword);

// Change the connection data
if (dwError = RasSetEntryDialParams(NULL, &RasDialParams, FALSE))
{
return dwError;
}

return dwError;
}


.... and then in our c# app we call them like....


int x = I8RAS_DLL.MProRASCreateEntry(new StringBuilder(m_entryName),

new StringBuilder(m_login),

new StringBuilder(m_password),

new StringBuilder(m_phoneNumber),

m_countryCode,

new StringBuilder(m_areaCode),

new StringBuilder(m_deviceName));

m_exists = (x ==0);

Hope this helps!



Chris
 
F

Felipe T.

Thx Guys,
One thing i must also say...The structures r complex indeed...
Well, ill try a bit more. If i came up with a solution, ill post it here.

Thx 4 the code.
Cya.
 
C

Chris J.T. Auld [MVP]

Take a look at
http://www.intelliprog.com/netcf/ras.html


Cheers
Chris
--
****Please Reply To The Newsgroup So All Can Benefit From Discussion****
-------------------------------------------
Kognition Consulting Limited - Thought Meets Technology
Chris J.T. Auld - Managing Director
Microsoft MVP (Windows Mobile Devices)
Phone: +64 3 453 0064
Mobile: +64 21 500 239
Email: (e-mail address removed)
 
F

Felipe T.

Yah, i forgot this component...I saw it when i was beginning to work with
Net CF...If it works perfectly, its not that much expensive for the work it
does 4 me...I think ill try it.

Thx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top