|
-
Aug 9th, 2021, 02:48 AM
#1
Thread Starter
Fanatic Member
[RESOLVED] Convert RAS APIs from ANSI to Unicode
Last edited by Mith; Aug 9th, 2021 at 04:16 AM.
Reason: new infos, project update
-
Aug 9th, 2021, 03:06 AM
#2
Thread Starter
Fanatic Member
Re: Convert RAS APIs from ANSI to Unicode
i found the correct size for the RASCONN95_W structure with this code:
Code:
For I = 412 To 999
lpRasconn(0).dwSize = I
lpCb = lpRasconn(0).dwSize * 256
lErr = RasEnumConnectionsWide(lpRasconn(0), lpCb, lConnections)
If lErr = 0 Then Stop
Next I
The correct size is 816.
-
Aug 9th, 2021, 03:44 AM
#3
Re: Convert RAS APIs from ANSI to Unicode
JFYI, here is the struct definition in the SDK
Code:
/* Identifies an active RAS connection. (See RasEnumConnections)
*/
#define RASCONNW struct tagRASCONNW
RASCONNW
{
DWORD dwSize;
HRASCONN hrasconn;
WCHAR szEntryName[ RAS_MaxEntryName + 1 ];
#if (WINVER >= 0x400)
WCHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
WCHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
#endif
#if (WINVER >= 0x401)
WCHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
#endif
#if (WINVER >= 0x500)
GUID guidEntry;
#endif
#if (WINVER >= 0x501)
DWORD dwFlags;
LUID luid;
#endif
#if (WINVER >= 0x600)
GUID guidCorrelationId;
#endif
};
. . . which can be trimmed down to match your VB6 declare to something like this
Code:
#define RASCONN95 struct tagRASCONN95
RASCONN95
{
DWORD dwSize;
HRASCONN hrasconn;
WCHAR szEntryName[ RAS_MaxEntryName + 1 ];
#if (WINVER >= 0x400)
WCHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
WCHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
#endif
};
. . . and then using some code like this
Code:
printf("sizeof(RASCONN95)=%d\n", sizeof(RASCONN95));
. . . delivers another value
Code:
sizeof(RASCONN95)=814
cheers,
</wqw>
-
Aug 9th, 2021, 04:18 AM
#4
Thread Starter
Fanatic Member
Re: Convert RAS APIs from ANSI to Unicode
 Originally Posted by wqweto
J
Code:
printf("sizeof(RASCONN95)=%d\n", sizeof(RASCONN95));
. . . delivers another value
Code:
sizeof(RASCONN95)=814
cheers,
</wqw>
Strange, the API RasEnumConnectionsWide works only with a size of 816...see my post #2
-
Aug 9th, 2021, 04:29 AM
#5
Thread Starter
Fanatic Member
Re: Convert RAS APIs from ANSI to Unicode
btw, i simplified the ANSI-function to dial the connection.
now i use the type structure RASDIALPARAMS directly with the API RasDial:
Code:
Private Const RAS_MaxEntryName = 256
Private Const RAS_MaxPhoneNumber = 128
Private Const RAS_MaxCallbackNumber = RAS_MaxPhoneNumber
Private Const UNLEN = 256
Private Const PWLEN = 256
Private Const DNLEN = 12
Private Type RASDIALPARAMS
dwSize As Long
szEntryName(RAS_MaxEntryName) As Byte
szPhoneNumber(RAS_MaxPhoneNumber) As Byte
szCallbackNumber(RAS_MaxCallbackNumber) As Byte
szUserName(UNLEN) As Byte
szPassword(PWLEN) As Byte
szDomain(DNLEN) As Byte
End Type
Private Declare Function RasDial Lib "rasapi32.dll" Alias "RasDialA" _
(lpRasDialExtensions As Any, _
ByVal lpszPhonebook As String, _
lpRasDialParams As Any, _
ByVal dwNotifierType As Long, _
ByVal hwndNotifier As Long, _
lphRasConn As Long) As Long
Private Sub RAS_Connect()
Dim lErr As Long
Dim lngHConn As Long
Dim sConnectionName As String
Dim rp As RASDIALPARAMS
sConnectionName = cboRAS.List(cboRAS.ListIndex)
CopyStringToByte rp.szEntryName(0), sConnectionName, Len(sConnectionName)
rp.dwSize = Len(rp) + 6 '1052
lErr = RasDial(ByVal 0&, vbNullString, rp, 0&, 0&, lngHConn)
If lErr <> 0 Then
MsgBox "RasDial: " & GetRasErrorMsg(lErr), vbExclamation
Exit Sub
Else
MsgBox "'" & sConnectionName & "' connected!", vbInformation
End If
End Sub
i tried to convert the code above to UNICODE but the API RasDialWide always returns 632 "ERROR_INVALID_SIZE":
Code:
Private Type RASDIALPARAMS_W
dwSize As Long
szEntryName(RAS_MaxEntryName * 2) As Byte
szPhoneNumber(RAS_MaxPhoneNumber * 2) As Byte
szCallbackNumber(RAS_MaxCallbackNumber * 2) As Byte
szUserName(UNLEN * 2) As Byte
szPassword(PWLEN * 2) As Byte
szDomain(DNLEN * 2) As Byte
End Type
Private Declare Function RasDialWide Lib "rasapi32.dll" Alias "RasDialW" _
(lpRasDialExtensions As Any, _
ByVal lpszPhonebook As Long, _
lpRasDialParams As Any, _
ByVal dwNotifierType As Long, _
ByVal hwndNotifier As Long, _
lphRasConn As Long) As Long
Private Sub RAS_Connect_UNICODE()
Dim lErr As Long
Dim lngHConn As Long
Dim sConnectionName As String
Dim rp As RASDIALPARAMS_W
Dim I As Long
sConnectionName = cboRAS.List(cboRAS.ListIndex)
CopyStringToByte rp.szEntryName(0), sConnectionName, Len(sConnectionName)
rp.dwSize = LenB(rp) + 6 '1052
lErr = RasDialWide(ByVal 0&, StrPtr(vbNullString), rp, 0&, 0&, lngHConn)
If lErr <> 0 Then
MsgBox "RasDial: " & GetRasErrorMsg(lErr), vbExclamation
Exit Sub
Else
MsgBox "'" & sConnectionName & "' connected!", vbInformation
End If
End Sub
I tried to catch the correct size with a For-Next-Loop but i dont get the correct size:
Code:
For I = 500 To 4000
rp.dwSize = I
lErr = RasDialWide(ByVal 0&, StrPtr(vbNullString), rp, 0&, 0&, lngHConn)
If lErr = 0 Then Stop
Next I
Maybe the type structure is wrong or the API declaration?
-
Aug 9th, 2021, 06:16 AM
#6
Re: Convert RAS APIs from ANSI to Unicode
Your string buffers sizes are off-by-one -- should be sized to RAS_MaxEntryName + 1, RAS_MaxDeviceType + 1 and RAS_MaxDeviceName + 1 to match array sizes in SDK struct.
Here is a somewhat more convenient fixed-string equivalent of the UDT in VB6
Code:
Private Type RASCONN95_W
dwSize As Long
hRasConn As Long
szEntryName As String * 257 ' (RAS_MaxEntryName+1)
szDeviceType As String * 17 ' (RAS_MaxDeviceType+1)
szDeviceName As String * 129 ' (RAS_MaxDeviceName+1)
End Type
This way LenB(RASCONN95_W) = 816 in VB6 which is correct because it is 814 from above C/C++ code *padded* to DWORD boundary. Btw, C/C++ is using padded size for array of RASCONN95_W too.
The only thing to heed is that you have to use ByVal VarPtr at callsite to prevent Unicode<->ANSI converstion with fixed-length strings, so the original code should work now
Code:
lpRasconn(0).dwSize = LenB(lpRasconn(0)) '=816
lpCb = lpRasconn(0).dwSize * (UBound(lpRasconn) + 1) '=816*256=208896
lErr = RasEnumConnectionsWide(ByVal VarPtr(lpRasconn(0)), lpCb, lConnections)
Not tested as I don't have any RAS (dial-up/VPN) connections setup.
cheers,
</wqw>
-
Aug 9th, 2021, 07:55 AM
#7
Thread Starter
Fanatic Member
Re: Convert RAS APIs from ANSI to Unicode
 Originally Posted by wqweto
Your string buffers sizes are off-by-one -- should be sized to RAS_MaxEntryName + 1, RAS_MaxDeviceType + 1 and RAS_MaxDeviceName + 1 to match array sizes in SDK struct.
No need for "+1". I don't use strings at the type struct:
Code:
Private Type RASCONN95
dwSize As Long
hRasConn As Long
szEntryName(RAS_MaxEntryName) As Byte
szDeviceType(RAS_MaxDeviceType) As Byte
szDeviceName(RAS_MaxDeviceName) As Byte
End Type
The ANSI & UNICODE version of RasEnumConnections already works fine!
I have problems to convert the ANSI Type RASDIALPARAMS and the API RasDial:
Code:
Private Type RASDIALPARAMS
dwSize As Long
szEntryName(RAS_MaxEntryName) As Byte
szPhoneNumber(RAS_MaxPhoneNumber) As Byte
szCallbackNumber(RAS_MaxCallbackNumber) As Byte
szUserName(UNLEN) As Byte
szPassword(PWLEN) As Byte
szDomain(DNLEN) As Byte
End Type
Private Declare Function RasDial Lib "rasapi32.dll" Alias "RasDialA" _
(lpRasDialExtensions As Any, _
ByVal lpszPhonebook As String, _
lpRasDialParams As Any, _
ByVal dwNotifierType As Long, _
ByVal hwndNotifier As Long, _
lphRasConn As Long) As Long
My unicode version looks like this:
Code:
Private Type RASDIALPARAMS_W
dwSize As Long
szEntryName(RAS_MaxEntryName * 2) As Byte
szPhoneNumber(RAS_MaxPhoneNumber * 2) As Byte
szCallbackNumber(RAS_MaxCallbackNumber * 2) As Byte
szUserName(UNLEN * 2) As Byte
szPassword(PWLEN * 2) As Byte
szDomain(DNLEN * 2) As Byte
End Type
Private Declare Function RasDialWide Lib "rasapi32.dll" Alias "RasDialW" _
(lpRasDialExtensions As Any, _
ByVal lpszPhonebook As Long, _
lpRasDialParams As Any, _
ByVal dwNotifierType As Long, _
ByVal hwndNotifier As Long, _
lphRasConn As Long) As Long
Calling the API RasDialWide always returns the error 632 "ERROR_INVALID_SIZE" and i dont know whats wrong: the API declaration? the struct declaration? or the calculated size for the struct?
-
Aug 9th, 2021, 08:10 AM
#8
Re: Convert RAS APIs from ANSI to Unicode
Here is the RASDIALPARAMSW
Code:
/* Describes connection establishment parameters. (See RasDial)
*/
#define RASDIALPARAMSW struct tagRASDIALPARAMSW
RASDIALPARAMSW
{
DWORD dwSize;
WCHAR szEntryName[ RAS_MaxEntryName + 1 ];
WCHAR szPhoneNumber[ RAS_MaxPhoneNumber + 1 ];
WCHAR szCallbackNumber[ RAS_MaxCallbackNumber + 1 ];
WCHAR szUserName[ UNLEN + 1 ];
WCHAR szPassword[ PWLEN + 1 ];
WCHAR szDomain[ DNLEN + 1 ];
#if (WINVER >= 0x401)
DWORD dwSubEntry;
ULONG_PTR dwCallbackId;
#endif
#if (WINVER >= 0x601)
DWORD dwIfIndex;
#endif
#if (WINVER >= 0x602)
LPWSTR szEncPassword;
#endif
};
You cannot just leave the arrays in VB6 type with smaller sizes. You have to declare these with correct size i.e. szEntryName(RAS_MaxEntryName * 2 + 2) As Byte, etc.
Btw, C/C++ compiled code against Windows SDK gives this
Code:
sizeof(RASDIALPARAMS95)=2094
cheers,
</wqw>
-
Aug 9th, 2021, 09:48 AM
#9
Thread Starter
Fanatic Member
Re: Convert RAS APIs from ANSI to Unicode
i got it now!
the correct type declaration is:
Code:
Private Type RASDIALPARAMS_W
dwSize As Long
szEntryName(RAS_MaxEntryName * 2 + 1) As Byte
szPhoneNumber(RAS_MaxPhoneNumber * 2 + 1) As Byte
szCallbackNumber(RAS_MaxCallbackNumber * 2 + 1) As Byte
szUserName(UNLEN * 2 + 1) As Byte
szPassword(PWLEN * 2 + 1) As Byte
szDomain(DNLEN * 2 + 1) As Byte
End Type
i only need +1 because the Array starts with Zero!
...and the correct size for the API call is 2096 !
Now everything works!
Thanks you for your help to point me in the right direction!
-
Aug 9th, 2021, 11:32 AM
#10
Re: Convert RAS APIs from ANSI to Unicode
My bad! Arrays in VB6 should be dimensionsed 0 to Size - 1 -- doh!
Final 2096 size must be 2094 with DWORD padding.
cheers,
</wqw>
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|