T
Tibby
I've gotten RAS to work with a C++ dll, but due to my limited
knowledge of C++, I'm running into some memory problems. So, I'm
giving this another shot using VB.NET, since I have a greater
understanding of how the RAS API actually works, and a greater
appreciation for it.
Anyway, I'm stuck on the RasDial function, which is returning error
632, "The Structure Size is incorrect". Now, here' s the C++
Prototype of the RasDialParams Structure:
typedef struct _RASDIALPARAMS {
DWORD dwSize;
TCHAR szEntryName[RAS_MaxEntryName + 1];
TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1];
TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1];
TCHAR szUserName[UNLEN + 1];
TCHAR szPassword[PWLEN + 1];
TCHAR szDomain[DNLEN + 1] ;
#if (WINVER >= 0x401)
DWORD dwSubEntry;
ULONG_PTR dwCallbackId;
#endif
} RASDIALPARAMS;
Here's my decleration of the structure:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure RASDIALPARAMS
Public dwSize As Int32
Public szEntryName As String
Public szPhoneNumber As String
Public szCallbackNumber As String
Public szUserName As String
Public szPassword As String
Public szDomain As String
Public swSubEntry As Int32
Public dwCallbackId As Int32
End Structure
And here's the C++ way of setting/defining the structure:
rdParams.dwSize = sizeof(RASDIALPARAMS);
rdParams.szEntryName[0]= '\0';
rdParams.szCallbackNumber[0] = '\0';
rdParams.szPhoneNumber[0]= '\0';
rdParams.szUserName[0]= '\0';
rdParams.szPassword[0]= '\0';
rdParams.szDomain[0] = '\0';
and here's mine:
With rdParams
.dwSize = Marshal.SizeOf(rdParams)
.szEntryName = Nothing
.szCallbackNumber = Nothing
.szDomain = Nothing
.szPhoneNumber = PhoneNumber
.szPassword = Password
.szUserName = userName
End With
So, how do I get mine to not return the error 632? I've have searched
hihg and low for this, and can't seem to figure it out, and here, if
this helps, I have a C# decleration of the structure, and before
anyone comments, Loederz .Net Reflector is out of the question, the
zip file is goofed.
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
internal class RASDIALPARAMS
{
public int
dwSize=Marshal.SizeOf(typeof(RASDIALPARAMS));
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName+1)]
public string szEntryName=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxPhoneNumber+1)]
public string szPhoneNumber=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxCallbackNumber+1)]
public string szCallbackNumber=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.UNLEN+1)]
public string szUserName=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.PWLEN+1)]
public string szPassword=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.DNLEN+1)]
public string szDomain=null;
public int dwSubEntry=0;
public int dwCallbackId=0;
}
And here the Constants to go with it:
internal enum RasFieldSizeConstants
{
RAS_MaxDeviceType =16,
RAS_MaxPhoneNumber =128,
RAS_MaxIpAddress =15,
RAS_MaxIpxAddress =21,
#if WINVER4
RAS_MaxEntryName =256,
RAS_MaxDeviceName =128,
RAS_MaxCallbackNumber =RAS_MaxPhoneNumber,
#else
RAS_MaxEntryName =20,
RAS_MaxDeviceName =32,
RAS_MaxCallbackNumber =48,
#endif
RAS_MaxAreaCode =10,
RAS_MaxPadType =32,
RAS_MaxX25Address =200,
RAS_MaxFacilities =200,
RAS_MaxUserData =200,
RAS_MaxReplyMessage =1024,
RAS_MaxDnsSuffix =256,
UNLEN =256,
PWLEN =256,
DNLEN =15
}
Now, i;ve noticed it's declared here as a class, and I'm wondering if
I do the same in VB will it work correctly?
Here's my modified Code:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Class RASDIALPARAMS
Public dwSize As Int32
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxEntryName) + 1)>
_
Public szEntryName As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxPhoneNumber) +
1)> _
Public szPhoneNumber As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxCallbackNumber) +
1)> _
Public szCallbackNumber As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.UNLEN) + 1)> _
Public szUserName As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.PWLEN) + 1)> _
Public szPassword As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.DNLEN) + 1)> _
Public szDomain As String = Nothing
Public swSubEntry As Int32 = 0
Public dwCallbackId As Int32 = 0
End Class
Nope, it returns error code 87. Very strange indeed, so, let me
layout some more code and prototypes for you...
I've included the above enum of constants, FYI
Prototype for RasDial in C++:
DWORD RasDial(
LPRASDIALEXTENSIONS lpRasDialExtensions,
// pointer to function extensions data
LPCTSTR lpszPhonebook, // pointer to full path and file
// name of phone-book file
LPRASDIALPARAMS lpRasDialParams,
// pointer to calling parameters data
DWORD dwNotifierType, // specifies type of RasDial event handler
LPVOID lpvNotifier, // specifies a handler for RasDial events
LPHRASCONN lphRasConn // pointer to variable to receive
// connection handle
);
My P/invoke Declare:
<DllImport("rasapi32.dll")> Public Shared Function RasDial(ByVal
lpRasDialExtensions As IntPtr, ByVal lpszPhonebook As IntPtr, ByRef
lpRasDialParams As RASDIALPARAMS, ByVal dwNotifierType As Int32, ByVal
lpvNotifier As Object, ByRef lphRasConn As IntPtr) As Int32
End Function
Now, I have a delegate for lpvNotifier Callback, which is for
RasDialFunc1:
Public Delegate Sub RasDialFunc1(ByVal hrasconn As IntPtr, ByVal
unMsg As UInt32, ByVal rascs As RASCONNSTATE, ByVal dwError As Int32,
ByVal dwExtendedError As Int32)
And here's my calling of RasDial:
Dim retval As Int32 = RasDial(IntPtr.Zero, IntPtr.Zero, rdParams, 1,
New RasDialFunc1(AddressOf CallBack), Handle)
And Retval always returns 87 with the modified code, guess I got the
SizeOf structure crap figured out.
Now, in looking up RAS Error 87 on google, here's what I found:
A function call to the RasDial() API from a 16-bit Windows-based
application that is running
in Windows 95 fails with error 87 in Windows 95 if the
hWndNotifier parameter of the RasDial()
API is initialized to a NULL value. An application should always
provide a window handle for
this parameter even if it will not be processing the messages
posted by the RAS DLLs to this
window. Specifying a NULL value for window handle in the
RasDial() API call is common for a
Visual Basic application. In such a scenario, the application
makes repetitive calls to
RasGetConnectStatus() to get the status of the connection.
However, calling RasDial() in this
fashion causes it to fail on Windows 95 with error 87. Microsoft
has confirmed this to be a bug
in the Microsoft products listed at the beginning of this
article. Microsoft is researching this
problem and will post new information in the Microsoft Knowledge
Base as it becomes available.
Doesn't make too much sense to me since I'm developing this for
2000/XP, but, after a little more searching, nothing even close. So,
I'm at an impass, and after all this babbling, maybe a bone could be
thrown my way, and god knows I'm not the only person out here that
could use this code
Thanks again,
Tibby
knowledge of C++, I'm running into some memory problems. So, I'm
giving this another shot using VB.NET, since I have a greater
understanding of how the RAS API actually works, and a greater
appreciation for it.
Anyway, I'm stuck on the RasDial function, which is returning error
632, "The Structure Size is incorrect". Now, here' s the C++
Prototype of the RasDialParams Structure:
typedef struct _RASDIALPARAMS {
DWORD dwSize;
TCHAR szEntryName[RAS_MaxEntryName + 1];
TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1];
TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1];
TCHAR szUserName[UNLEN + 1];
TCHAR szPassword[PWLEN + 1];
TCHAR szDomain[DNLEN + 1] ;
#if (WINVER >= 0x401)
DWORD dwSubEntry;
ULONG_PTR dwCallbackId;
#endif
} RASDIALPARAMS;
Here's my decleration of the structure:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure RASDIALPARAMS
Public dwSize As Int32
Public szEntryName As String
Public szPhoneNumber As String
Public szCallbackNumber As String
Public szUserName As String
Public szPassword As String
Public szDomain As String
Public swSubEntry As Int32
Public dwCallbackId As Int32
End Structure
And here's the C++ way of setting/defining the structure:
rdParams.dwSize = sizeof(RASDIALPARAMS);
rdParams.szEntryName[0]= '\0';
rdParams.szCallbackNumber[0] = '\0';
rdParams.szPhoneNumber[0]= '\0';
rdParams.szUserName[0]= '\0';
rdParams.szPassword[0]= '\0';
rdParams.szDomain[0] = '\0';
and here's mine:
With rdParams
.dwSize = Marshal.SizeOf(rdParams)
.szEntryName = Nothing
.szCallbackNumber = Nothing
.szDomain = Nothing
.szPhoneNumber = PhoneNumber
.szPassword = Password
.szUserName = userName
End With
So, how do I get mine to not return the error 632? I've have searched
hihg and low for this, and can't seem to figure it out, and here, if
this helps, I have a C# decleration of the structure, and before
anyone comments, Loederz .Net Reflector is out of the question, the
zip file is goofed.
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
internal class RASDIALPARAMS
{
public int
dwSize=Marshal.SizeOf(typeof(RASDIALPARAMS));
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName+1)]
public string szEntryName=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxPhoneNumber+1)]
public string szPhoneNumber=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxCallbackNumber+1)]
public string szCallbackNumber=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.UNLEN+1)]
public string szUserName=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.PWLEN+1)]
public string szPassword=null;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.DNLEN+1)]
public string szDomain=null;
public int dwSubEntry=0;
public int dwCallbackId=0;
}
And here the Constants to go with it:
internal enum RasFieldSizeConstants
{
RAS_MaxDeviceType =16,
RAS_MaxPhoneNumber =128,
RAS_MaxIpAddress =15,
RAS_MaxIpxAddress =21,
#if WINVER4
RAS_MaxEntryName =256,
RAS_MaxDeviceName =128,
RAS_MaxCallbackNumber =RAS_MaxPhoneNumber,
#else
RAS_MaxEntryName =20,
RAS_MaxDeviceName =32,
RAS_MaxCallbackNumber =48,
#endif
RAS_MaxAreaCode =10,
RAS_MaxPadType =32,
RAS_MaxX25Address =200,
RAS_MaxFacilities =200,
RAS_MaxUserData =200,
RAS_MaxReplyMessage =1024,
RAS_MaxDnsSuffix =256,
UNLEN =256,
PWLEN =256,
DNLEN =15
}
Now, i;ve noticed it's declared here as a class, and I'm wondering if
I do the same in VB will it work correctly?
Here's my modified Code:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Class RASDIALPARAMS
Public dwSize As Int32
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxEntryName) + 1)>
_
Public szEntryName As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxPhoneNumber) +
1)> _
Public szPhoneNumber As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.RAS_MaxCallbackNumber) +
1)> _
Public szCallbackNumber As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.UNLEN) + 1)> _
Public szUserName As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.PWLEN) + 1)> _
Public szPassword As String = Nothing
<MarshalAs(UnmanagedType.ByValTStr, _
SizeConst:=CInt(RasFieldSizeConstants.DNLEN) + 1)> _
Public szDomain As String = Nothing
Public swSubEntry As Int32 = 0
Public dwCallbackId As Int32 = 0
End Class
Nope, it returns error code 87. Very strange indeed, so, let me
layout some more code and prototypes for you...
I've included the above enum of constants, FYI
Prototype for RasDial in C++:
DWORD RasDial(
LPRASDIALEXTENSIONS lpRasDialExtensions,
// pointer to function extensions data
LPCTSTR lpszPhonebook, // pointer to full path and file
// name of phone-book file
LPRASDIALPARAMS lpRasDialParams,
// pointer to calling parameters data
DWORD dwNotifierType, // specifies type of RasDial event handler
LPVOID lpvNotifier, // specifies a handler for RasDial events
LPHRASCONN lphRasConn // pointer to variable to receive
// connection handle
);
My P/invoke Declare:
<DllImport("rasapi32.dll")> Public Shared Function RasDial(ByVal
lpRasDialExtensions As IntPtr, ByVal lpszPhonebook As IntPtr, ByRef
lpRasDialParams As RASDIALPARAMS, ByVal dwNotifierType As Int32, ByVal
lpvNotifier As Object, ByRef lphRasConn As IntPtr) As Int32
End Function
Now, I have a delegate for lpvNotifier Callback, which is for
RasDialFunc1:
Public Delegate Sub RasDialFunc1(ByVal hrasconn As IntPtr, ByVal
unMsg As UInt32, ByVal rascs As RASCONNSTATE, ByVal dwError As Int32,
ByVal dwExtendedError As Int32)
And here's my calling of RasDial:
Dim retval As Int32 = RasDial(IntPtr.Zero, IntPtr.Zero, rdParams, 1,
New RasDialFunc1(AddressOf CallBack), Handle)
And Retval always returns 87 with the modified code, guess I got the
SizeOf structure crap figured out.
Now, in looking up RAS Error 87 on google, here's what I found:
A function call to the RasDial() API from a 16-bit Windows-based
application that is running
in Windows 95 fails with error 87 in Windows 95 if the
hWndNotifier parameter of the RasDial()
API is initialized to a NULL value. An application should always
provide a window handle for
this parameter even if it will not be processing the messages
posted by the RAS DLLs to this
window. Specifying a NULL value for window handle in the
RasDial() API call is common for a
Visual Basic application. In such a scenario, the application
makes repetitive calls to
RasGetConnectStatus() to get the status of the connection.
However, calling RasDial() in this
fashion causes it to fail on Windows 95 with error 87. Microsoft
has confirmed this to be a bug
in the Microsoft products listed at the beginning of this
article. Microsoft is researching this
problem and will post new information in the Microsoft Knowledge
Base as it becomes available.
Doesn't make too much sense to me since I'm developing this for
2000/XP, but, after a little more searching, nothing even close. So,
I'm at an impass, and after all this babbling, maybe a bone could be
thrown my way, and god knows I'm not the only person out here that
could use this code
Thanks again,
Tibby