line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Manipulating RAS/DUN-Entry Properties, outbound dialing |
2
|
|
|
|
|
|
|
# Mike Blazer |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Win32::RASE; |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
|
|
484
|
use vars qw($VERSION $LOCAL_ID $LOCAL_CODE $LOCAL_AREA $WINVER |
7
|
|
|
|
|
|
|
@ISA @EXPORT %RASCS $Time_HiRes_loaded $LastError $IsWindow |
8
|
|
|
|
|
|
|
$RasDial $RasEnumConnections $RasHangUp $RasRenameEntry $RasDeleteEntry |
9
|
|
|
|
|
|
|
$RasEnumEntries $RasEnumDevices $RasGetConnectStatus $RasGetEntryProperties |
10
|
|
|
|
|
|
|
$RasSetEntryProperties $RasDialDlg $RasGetEntryDialParams $RasSetEntryDialParams |
11
|
|
|
|
|
|
|
$RasGetCountryInfo $RasCreateEntry $RasEditEntry |
12
|
|
|
|
|
|
|
$RasGetErrorString $lineGetTranslateCaps $RasGetProjectionInfo |
13
|
|
|
|
|
|
|
%TAPIEnumeration @RASCS_vars @RASEO_vars $PHONEBOOK |
14
|
|
|
|
|
|
|
$lineInitialize $lineShutdown $lineSetCurrentLocation |
15
|
|
|
|
|
|
|
%RasDevEnumeration |
16
|
1
|
|
|
1
|
|
1251
|
); |
|
1
|
|
|
|
|
3
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
require 5.000; |
19
|
|
|
|
|
|
|
require Win32::API; |
20
|
1
|
|
|
1
|
|
8
|
use strict "vars"; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
21
|
1
|
|
|
1
|
|
7
|
use Carp; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
152
|
|
22
|
1
|
|
|
1
|
|
925
|
use enum 1.014; |
|
1
|
|
|
|
|
1427
|
|
|
1
|
|
|
|
|
6
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
require Exporter; |
25
|
|
|
|
|
|
|
@ISA= qw( Exporter ); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
@RASCS_vars = qw( |
28
|
|
|
|
|
|
|
RASCS_OpenPort |
29
|
|
|
|
|
|
|
RASCS_PortOpened |
30
|
|
|
|
|
|
|
RASCS_ConnectDevice |
31
|
|
|
|
|
|
|
RASCS_DeviceConnected |
32
|
|
|
|
|
|
|
RASCS_AllDevicesConnected |
33
|
|
|
|
|
|
|
RASCS_Authenticate |
34
|
|
|
|
|
|
|
RASCS_AuthNotify |
35
|
|
|
|
|
|
|
RASCS_AuthRetry |
36
|
|
|
|
|
|
|
RASCS_AuthCallback |
37
|
|
|
|
|
|
|
RASCS_AuthChangePassword |
38
|
|
|
|
|
|
|
RASCS_AuthProject |
39
|
|
|
|
|
|
|
RASCS_AuthLinkSpeed |
40
|
|
|
|
|
|
|
RASCS_AuthAck |
41
|
|
|
|
|
|
|
RASCS_ReAuthenticate |
42
|
|
|
|
|
|
|
RASCS_Authenticated |
43
|
|
|
|
|
|
|
RASCS_PrepareForCallback |
44
|
|
|
|
|
|
|
RASCS_WaitForModemReset |
45
|
|
|
|
|
|
|
RASCS_WaitForCallback |
46
|
|
|
|
|
|
|
RASCS_Projected |
47
|
|
|
|
|
|
|
RASCS_StartAuthentication |
48
|
|
|
|
|
|
|
RASCS_CallbackComplete |
49
|
|
|
|
|
|
|
RASCS_LogonNetwork |
50
|
|
|
|
|
|
|
RASCS_SubEntryConnected |
51
|
|
|
|
|
|
|
RASCS_SubEntryDisconnected |
52
|
|
|
|
|
|
|
RASCS_Interactive |
53
|
|
|
|
|
|
|
RASCS_PAUSED |
54
|
|
|
|
|
|
|
RASCS_RetryAuthentication |
55
|
|
|
|
|
|
|
RASCS_CallbackSetByCaller |
56
|
|
|
|
|
|
|
RASCS_PasswordExpired |
57
|
|
|
|
|
|
|
RASCS_Connected |
58
|
|
|
|
|
|
|
RASCS_DONE |
59
|
|
|
|
|
|
|
RASCS_Disconnected |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
|
62
|
1
|
|
|
|
|
5
|
use enum qw( |
63
|
|
|
|
|
|
|
:RASCS_=0 |
64
|
|
|
|
|
|
|
OpenPort |
65
|
|
|
|
|
|
|
PortOpened |
66
|
|
|
|
|
|
|
ConnectDevice |
67
|
|
|
|
|
|
|
DeviceConnected |
68
|
|
|
|
|
|
|
AllDevicesConnected |
69
|
|
|
|
|
|
|
Authenticate |
70
|
|
|
|
|
|
|
AuthNotify |
71
|
|
|
|
|
|
|
AuthRetry |
72
|
|
|
|
|
|
|
AuthCallback |
73
|
|
|
|
|
|
|
AuthChangePassword |
74
|
|
|
|
|
|
|
AuthProject |
75
|
|
|
|
|
|
|
AuthLinkSpeed |
76
|
|
|
|
|
|
|
AuthAck |
77
|
|
|
|
|
|
|
ReAuthenticate |
78
|
|
|
|
|
|
|
Authenticated |
79
|
|
|
|
|
|
|
PrepareForCallback |
80
|
|
|
|
|
|
|
WaitForModemReset |
81
|
|
|
|
|
|
|
WaitForCallback |
82
|
|
|
|
|
|
|
Projected |
83
|
|
|
|
|
|
|
StartAuthentication |
84
|
|
|
|
|
|
|
CallbackComplete |
85
|
|
|
|
|
|
|
LogonNetwork |
86
|
|
|
|
|
|
|
SubEntryConnected |
87
|
|
|
|
|
|
|
SubEntryDisconnected |
88
|
|
|
|
|
|
|
Interactive=4096 |
89
|
|
|
|
|
|
|
PAUSED=4096 |
90
|
|
|
|
|
|
|
RetryAuthentication |
91
|
|
|
|
|
|
|
CallbackSetByCaller |
92
|
|
|
|
|
|
|
PasswordExpired |
93
|
|
|
|
|
|
|
Connected=8192 |
94
|
|
|
|
|
|
|
DONE=8192 |
95
|
|
|
|
|
|
|
Disconnected |
96
|
1
|
|
|
1
|
|
107
|
); |
|
1
|
|
|
|
|
1
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# %RASCS to provide short text explaining numeric value |
99
|
|
|
|
|
|
|
for my $v(@RASCS_vars) { |
100
|
|
|
|
|
|
|
next if $v =~ /(PAUSED|DONE)$/; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
($RASCS{eval $v} = $v) =~ s/^RASCS_//; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
|
106
|
1
|
|
|
|
|
7
|
use enum @RASEO_vars = qw( |
107
|
|
|
|
|
|
|
BITMASK: |
108
|
|
|
|
|
|
|
RASEO_UseCountryAndAreaCodes |
109
|
|
|
|
|
|
|
RASEO_SpecificIpAddr |
110
|
|
|
|
|
|
|
RASEO_SpecificNameServers |
111
|
|
|
|
|
|
|
RASEO_IpHeaderCompression |
112
|
|
|
|
|
|
|
RASEO_RemoteDefaultGateway |
113
|
|
|
|
|
|
|
RASEO_DisableLcpExtensions |
114
|
|
|
|
|
|
|
RASEO_TerminalBeforeDial |
115
|
|
|
|
|
|
|
RASEO_TerminalAfterDial |
116
|
|
|
|
|
|
|
RASEO_ModemLights |
117
|
|
|
|
|
|
|
RASEO_SwCompression |
118
|
|
|
|
|
|
|
RASEO_RequireEncryptedPw |
119
|
|
|
|
|
|
|
RASEO_RequireMsEncryptedPw |
120
|
|
|
|
|
|
|
RASEO_RequireDataEncryption |
121
|
|
|
|
|
|
|
RASEO_NetworkLogon |
122
|
|
|
|
|
|
|
RASEO_UseLogonCredentials |
123
|
|
|
|
|
|
|
RASEO_PromoteAlternates |
124
|
|
|
|
|
|
|
RASEO_SecureLocalFiles |
125
|
1
|
|
|
1
|
|
4004
|
); |
|
1
|
|
|
|
|
2
|
|
126
|
|
|
|
|
|
|
shift @RASEO_vars; |
127
|
|
|
|
|
|
|
|
128
|
1
|
|
|
|
|
5
|
use enum qw( |
129
|
|
|
|
|
|
|
MAX_PATH=260 |
130
|
|
|
|
|
|
|
:RAS_ |
131
|
|
|
|
|
|
|
MaxDeviceType=16 |
132
|
|
|
|
|
|
|
MaxPhoneNumber=128 |
133
|
|
|
|
|
|
|
MaxIpAddress=15 |
134
|
|
|
|
|
|
|
MaxIpxAddress=21 |
135
|
1
|
|
|
1
|
|
1188
|
); |
|
1
|
|
|
|
|
1
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
BEGIN { |
138
|
|
|
|
|
|
|
# build number might have problems with some older NTs |
139
|
|
|
|
|
|
|
# says: |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# WINVER values in this file: |
142
|
|
|
|
|
|
|
# WINVER < 0x400 = Windows NT 3.5, Windows NT 3.51 |
143
|
|
|
|
|
|
|
# WINVER = 0x400 = Windows 95, Windows NT SUR (default) |
144
|
|
|
|
|
|
|
# i.e. 4.0 Shell Update Release |
145
|
|
|
|
|
|
|
# WINVER > 0x400 = Windows NT SUR enhancements (nobody knows what's this) |
146
|
1
|
|
|
1
|
|
458
|
$WINVER = (Win32::GetOSVersion)[3]; |
147
|
1
|
|
|
|
|
41
|
$WINVER &= 0xFFFF if Win32::IsWin95; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
1
|
50
|
|
|
|
7
|
use enum $WINVER >= 0x400 ? |
151
|
|
|
|
|
|
|
qw( :RAS_ |
152
|
|
|
|
|
|
|
MaxEntryName=256 |
153
|
|
|
|
|
|
|
MaxDeviceName=128 |
154
|
|
|
|
|
|
|
MaxCallbackNumber=128 |
155
|
|
|
|
|
|
|
) : |
156
|
|
|
|
|
|
|
qw( :RAS_ |
157
|
|
|
|
|
|
|
MaxEntryName=20 |
158
|
|
|
|
|
|
|
MaxDeviceName=32 |
159
|
|
|
|
|
|
|
MaxCallbackNumber=48 |
160
|
1
|
|
|
1
|
|
6
|
); |
|
1
|
|
|
|
|
2
|
|
161
|
|
|
|
|
|
|
|
162
|
1
|
|
|
|
|
6
|
use enum qw( |
163
|
|
|
|
|
|
|
:RAS_ |
164
|
|
|
|
|
|
|
MaxAreaCode=10 |
165
|
|
|
|
|
|
|
MaxPadType=32 |
166
|
|
|
|
|
|
|
MaxX25Address=200 |
167
|
|
|
|
|
|
|
MaxFacilities=200 |
168
|
|
|
|
|
|
|
MaxUserData=200 |
169
|
1
|
|
|
1
|
|
276
|
); |
|
1
|
|
|
|
|
2
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# RASENTRY 'dwProtocols' bit flags. |
172
|
1
|
|
|
1
|
|
457
|
use enum qw( BITMASK:RASNP_ NetBEUI Ipx Ip); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# RASENTRY 'dwFramingProtocols' bit flags. |
175
|
1
|
|
|
1
|
|
280
|
use enum qw( BITMASK:RASFP_ Ppp Slip Ras); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
5
|
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# RASENTRY 'szDeviceType' default strings. |
178
|
1
|
|
|
1
|
|
5324
|
use enum qw( :RASDT_ Modem=modem Isdn=isdn X25=x25); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
176
|
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# from lmcons.h |
181
|
1
|
|
|
|
|
4
|
use enum qw( |
182
|
|
|
|
|
|
|
UNLEN=256 |
183
|
|
|
|
|
|
|
PWLEN=256 |
184
|
|
|
|
|
|
|
DNLEN=15 |
185
|
|
|
|
|
|
|
PST_MODEM=6 |
186
|
1
|
|
|
1
|
|
674
|
); |
|
1
|
|
|
|
|
9
|
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# SpeakerVolume for MODEMSETTINGS |
190
|
1
|
|
|
1
|
|
352
|
use enum qw( :MDMVOL_=0 LOW MEDIUM HIGH ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# SpeakerMode for MODEMSETTINGS |
193
|
1
|
|
|
1
|
|
243
|
use enum qw( :MDMSPKR_=0 OFF DIAL ON CALLSETUP); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# Modem Options |
196
|
1
|
|
|
|
|
5
|
use enum qw( BITMASK:MDM_ COMPRESSION ERROR_CONTROL FORCED_EC |
197
|
|
|
|
|
|
|
CELLULAR FLOWCONTROL_HARD FLOWCONTROL_SOFT CCITT_OVERRIDE |
198
|
|
|
|
|
|
|
SPEED_ADJUST TONE_DIAL BLIND_DIAL V23_OVERRIDE |
199
|
1
|
|
|
1
|
|
317
|
); |
|
1
|
|
|
|
|
2
|
|
200
|
|
|
|
|
|
|
|
201
|
1
|
|
|
|
|
5
|
use enum qw( |
202
|
|
|
|
|
|
|
RASP_Amb=0x10000 |
203
|
|
|
|
|
|
|
RASP_PppNbf=0x803F |
204
|
|
|
|
|
|
|
RASP_PppIpx=0x802B |
205
|
|
|
|
|
|
|
RASP_PppIp=0x8021 |
206
|
|
|
|
|
|
|
RASP_PppLcp=0xC021 |
207
|
|
|
|
|
|
|
RASP_Slip=0x20000 |
208
|
1
|
|
|
1
|
|
768
|
); |
|
1
|
|
|
|
|
2
|
|
209
|
|
|
|
|
|
|
|
210
|
1
|
|
|
|
|
4
|
use enum qw( |
211
|
|
|
|
|
|
|
BITMASK: |
212
|
|
|
|
|
|
|
TERMINAL_PRE |
213
|
|
|
|
|
|
|
TERMINAL_POST |
214
|
|
|
|
|
|
|
MANUAL_DIAL |
215
|
|
|
|
|
|
|
LAUNCH_LIGHTS |
216
|
1
|
|
|
1
|
|
526
|
); |
|
1
|
|
|
|
|
2
|
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
@EXPORT = (qw( |
220
|
|
|
|
|
|
|
RasEnumConnections RasHangUp HangUp |
221
|
|
|
|
|
|
|
RasGetConnectStatus RasDial RasDialDlg |
222
|
|
|
|
|
|
|
RasGetProjectionInfo |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
TAPICountryName TAPICountryCode IsCountryID |
225
|
|
|
|
|
|
|
TAPISetCurrentLocation |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
RasCreateEntryDlg RasEditEntryDlg RasEnumDevices |
228
|
|
|
|
|
|
|
RasRenameEntry RasDeleteEntry RasEnumEntries IsEntry |
229
|
|
|
|
|
|
|
RasGetEntryDialParams RasSetEntryDialParams RasGetUserPwd |
230
|
|
|
|
|
|
|
RasGetEntryProperties RasSetEntryProperties |
231
|
|
|
|
|
|
|
RasPrintEntryProperties RasChangePhoneNumber RasCopyEntry |
232
|
|
|
|
|
|
|
RasCreateEntry RasEnumDevicesByType |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
RasGetEntryDevProperties RasPrintEntryDevProperties |
235
|
|
|
|
|
|
|
), @RASCS_vars, @RASEO_vars); |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
$VERSION = "1.01"; |
238
|
|
|
|
|
|
|
|
239
|
1
|
|
|
1
|
|
399
|
use constant DWORD_NULL => pack("L",0); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
297
|
|
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub CRUNCH (@) { |
242
|
0
|
|
|
0
|
|
|
local $_; |
243
|
0
|
|
|
|
|
|
for (@_) { s/\0.*$//s } |
|
0
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
sub TRIM_LR ($) { |
247
|
0
|
|
|
0
|
|
|
$_[0] =~ s/^ *(.*?) *$/$1/s; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub DWORD_ALIGN ($) { |
251
|
0
|
0
|
|
0
|
|
|
$_[0] = $_[0] + 4 - $_[0] % 4 if $_[0] % 4; |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# for precise loops |
255
|
|
|
|
|
|
|
BEGIN{ |
256
|
1
|
|
|
1
|
|
61
|
eval "require Time::HiRes"; |
257
|
1
|
50
|
|
|
|
2030
|
unless ($@) { |
258
|
1
|
|
|
|
|
5
|
import Time::HiRes qw(sleep time); |
259
|
1
|
|
|
|
|
200
|
$Time_HiRes_loaded = 1; |
260
|
|
|
|
|
|
|
} |
261
|
1
|
|
|
|
|
13010
|
undef $@; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
TAPIlineGetTranslateCaps(); |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub new (@) { |
270
|
0
|
|
|
0
|
|
|
my ($ret, $dll); |
271
|
0
|
|
|
|
|
|
($dll = $_[0])=~ s/(\.dll)?$/.dll/i; |
272
|
0
|
0
|
|
|
|
|
$ret = new Win32::API(@_) or croak "Win32::RASE: $_[1] not found in $dll\n"; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub RASERROR ($) { |
276
|
0
|
|
|
0
|
|
|
my $ret = shift; |
277
|
0
|
|
|
|
|
|
my $sub = (caller(1))[3]; |
278
|
|
|
|
|
|
|
|
279
|
0
|
|
|
|
|
|
croak "$sub: ".FormatMessage($ret)."\n"; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub RASCROAK ($) { |
283
|
0
|
|
|
0
|
|
|
my $sub = (caller(1))[3]; |
284
|
|
|
|
|
|
|
|
285
|
0
|
|
|
|
|
|
croak "$sub: ".shift()."\n"; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 NAME |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Win32::RASE - managing dialup entries and network connections on Win32 |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 SYNOPSIS |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
use Win32::RASE; |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head1 ABSTRACT |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
This module implements the client part of Win32 RAS API. |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
It is named RASE(RAS-entry) because it was originally designed |
302
|
|
|
|
|
|
|
to create/delete/change/manage RAS/DUN entries. Now it implements |
303
|
|
|
|
|
|
|
synchronous dialing, hang up and the wide range of RAS/DUN |
304
|
|
|
|
|
|
|
entry manipulations. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
The current version of Win32::RASE is available at: |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
http://www.dux.ru/guest/fno/perl/ |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 DESCRIPTION |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
This module is a collection of subroutines. As their names are very long |
313
|
|
|
|
|
|
|
and specific and almost each corresponds to a Win32 API call I decided |
314
|
|
|
|
|
|
|
to export a lot of them by default. Everything is exported except those |
315
|
|
|
|
|
|
|
subs that are claimed as non-exported. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
OK, you can C it instead of C |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
B |
320
|
|
|
|
|
|
|
All functions (if the other behavior is not stated explicitly) |
321
|
|
|
|
|
|
|
return TRUE on success, FALSE on error |
322
|
|
|
|
|
|
|
to conform the handy calling rule |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
RESULT = function(PARAMS) or die MESSAGE; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
where RESULT could be scalar or list either. Note that "||" is not |
327
|
|
|
|
|
|
|
the same thing as "or". |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
The following logic is used: almost all functions croak on obvious programmer's |
330
|
|
|
|
|
|
|
errors like invalid entry-name or such. |
331
|
|
|
|
|
|
|
But they return FALSE and set LastError on internal API errors. |
332
|
|
|
|
|
|
|
It is made to give the programmer a chance to complete all actions and may be |
333
|
|
|
|
|
|
|
to trap some errors without exiting the program. |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
For example if some phonebook file is corrupted you have a chance |
336
|
|
|
|
|
|
|
to try another one etc. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=over 4 |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
The following two functions are available after any other function was executed. |
342
|
|
|
|
|
|
|
They are both non-exported to provide feel and look of Win32-Perl built-in |
343
|
|
|
|
|
|
|
functions with the same names. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item GetLastError ( ) |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Returns 0 or the last encountered RAS, TAPI or Windows error number. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
$lastErr = Win32::RASE::GetLastError(); |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
Usually you should call this function after some other function |
352
|
|
|
|
|
|
|
returned C. In case of Windows error it returns the same value as |
353
|
|
|
|
|
|
|
C. Unlike the built-in one it always returns 0 |
354
|
|
|
|
|
|
|
if the last called function finished successfully. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
You can use it for example like this: |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
some_function(); |
359
|
|
|
|
|
|
|
Win32::RASE::GetLastError and die Win32::RASE::FormatMessage; |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
or implicitly |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
some_function() or die Win32::RASE::FormatMessage; |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=cut |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
#================ |
368
|
|
|
|
|
|
|
sub GetLastError () { |
369
|
|
|
|
|
|
|
#================ |
370
|
0
|
0
|
|
0
|
|
|
$LastError||0; |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=item FormatMessage ( ) |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Converts the supplied RAS, TAPI or Win32 error number (e.g. |
376
|
|
|
|
|
|
|
returned by C) to a descriptive string. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
$message = Win32::RASE::FormatMessage($err_num); |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
Without the parameter assumes that the result of |
381
|
|
|
|
|
|
|
C was sent. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=cut |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
#================ |
386
|
|
|
|
|
|
|
sub FormatMessage (;$) { |
387
|
|
|
|
|
|
|
#================ |
388
|
0
|
|
0
|
0
|
|
|
my ($errnum, $buf) = (shift || GetLastError(), "\0"x1024); |
389
|
|
|
|
|
|
|
|
390
|
0
|
0
|
|
|
|
|
$errnum =~ /^\-?\d+$/ or |
391
|
|
|
|
|
|
|
RASCROAK "non-numeric value `$errnum'"; |
392
|
|
|
|
|
|
|
|
393
|
0
|
0
|
0
|
|
|
|
if ($errnum >= 600 && $errnum <= 750) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
394
|
0
|
|
0
|
|
|
|
$RasGetErrorString ||= new("rasapi32", "RasGetErrorString", [I,P,N], N); |
395
|
|
|
|
|
|
|
|
396
|
0
|
|
|
|
|
|
my $ret = $RasGetErrorString->Call($errnum, $buf, length $buf); |
397
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
|
|
|
CRUNCH($buf); |
400
|
0
|
|
|
|
|
|
return "($errnum) $buf"; |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
} elsif ($errnum == 751) { |
403
|
0
|
|
|
|
|
|
return "(751) ERROR_INVALID_CALLBACK_NUMBER"; |
404
|
|
|
|
|
|
|
} elsif ($errnum == 752) { |
405
|
0
|
|
|
|
|
|
return "(752) ERROR_SCRIPT_SYNTAX"; |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# TAPI LINEERR_* constants |
408
|
|
|
|
|
|
|
} elsif ($errnum & 0x80000000) { |
409
|
0
|
|
|
|
|
|
return "TAPI-error 0x".(sprintf "%8.8X",$errnum); |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# TAPI PHONEERR_* constants |
412
|
|
|
|
|
|
|
} elsif ($errnum & 0x90000000) { |
413
|
0
|
|
|
|
|
|
return "TAPI-error 0x".(sprintf "%8.8X",$errnum); |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# TAPI TAPIERR_* constants |
416
|
|
|
|
|
|
|
} elsif ($errnum > 0xFFFF0000) { |
417
|
0
|
|
|
|
|
|
return "TAPI-error 0x".(sprintf "%8.8X",$errnum); |
418
|
|
|
|
|
|
|
} |
419
|
|
|
|
|
|
|
|
420
|
0
|
|
|
|
|
|
"($errnum) ".Win32::FormatMessage($errnum); |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=item IsWindow ( ) |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
This function is non-exported for not to corrupt some other GUI related |
427
|
|
|
|
|
|
|
synonym. |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
Win32::RASE::IsWindow( $hwnd ); |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
Returns TRUE if $hwnd identifies an existing window, otherwise FALSE. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
This function is handy to use before the functions that display a dialog box - |
434
|
|
|
|
|
|
|
to verify the parent window. |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
=cut |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
#================ |
439
|
|
|
|
|
|
|
sub IsWindow ($) { |
440
|
|
|
|
|
|
|
#================ |
441
|
0
|
|
|
0
|
|
|
my $hwnd = shift; |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
# to free dll right after the call (Dlg-functions are rare) |
444
|
0
|
|
|
|
|
|
my $IsWindow = new("user32", "IsWindow", [N], N); |
445
|
0
|
|
|
|
|
|
$IsWindow->Call($hwnd); |
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=pod |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=back |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
B< =====================================> |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
B< PHONEBOOK RELATED FUNCTIONS> |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
B< =====================================> |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
Note that by default all functions in this section work |
459
|
|
|
|
|
|
|
with the default phonebook (on Windows NT). |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
The registry key C<"HKEY_CURRENT_USER\Software\Microsoft\RAS Phonebook"> |
462
|
|
|
|
|
|
|
has a dword subkey "PhonebookMode" which could have 3 values: |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
0 - the "system" phonebook is in use. |
465
|
|
|
|
|
|
|
This is probably %SYSTEMROOT%\system32\ras\rasphone.pbk |
466
|
|
|
|
|
|
|
1 - the "user" phonebook is in use. |
467
|
|
|
|
|
|
|
This one is located in %SYSTEMROOT%\system32\ras\ |
468
|
|
|
|
|
|
|
here is the value of "PersonalPhonebookFile" subkey |
469
|
|
|
|
|
|
|
that is located under the same key. |
470
|
|
|
|
|
|
|
2 - the "alternate" phonebook is in use. |
471
|
|
|
|
|
|
|
The full path to the alternate phonebook could be found in the |
472
|
|
|
|
|
|
|
"AlternatePhonebookPath" subkey under the same key. |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
This version of C provides no way to change these registry |
475
|
|
|
|
|
|
|
settings. If C<"HKEY_CURRENT_USER\Software\Microsoft\RAS Phonebook\PhonebookMode"> |
476
|
|
|
|
|
|
|
is equal to 0 C will use the "system" phonebook, in case 1 - |
477
|
|
|
|
|
|
|
the "user" phonebook, in case 2 - the "alternate" phonebook. |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
The user can use the main Dial-Up Networking dialog box to create personal |
480
|
|
|
|
|
|
|
phonebook files or change defaults (registry settings). The Win32 API does |
481
|
|
|
|
|
|
|
not currently provide support for creating a phonebook file. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
B |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
At any time you can set a global variable B<$Win32::RASE::PHONEBOOK> to the full path |
486
|
|
|
|
|
|
|
of your phonebook file, and this phonebook will be in use until |
487
|
|
|
|
|
|
|
B<$Win32::RASE::PHONEBOOK> is changed. Setting this variable to 0 or C |
488
|
|
|
|
|
|
|
returns us to registry defined phonebook(s). |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
B Dial-up networking stores phonebook entries in the registry |
491
|
|
|
|
|
|
|
rather than in a phonebook file. Windows 9x does not support personal |
492
|
|
|
|
|
|
|
phonebook files. So B<$Win32::RASE::PHONEBOOK> has no meaning and must |
493
|
|
|
|
|
|
|
always be C. |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
All functions treat entry-names as case-sensitive because RAS functions |
496
|
|
|
|
|
|
|
are kinda semi-case-sensitive. Some of them fail when entry was given |
497
|
|
|
|
|
|
|
with case-changes. But at the same time C API call |
498
|
|
|
|
|
|
|
(in C) fails to create both QWERTY and QwErTy, it renames |
499
|
|
|
|
|
|
|
instead. Ou-h-h MS, MS... |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
The moral is: don't use names that differ only in upper/lower case. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
There also is a danger in using multiple processes that are calling |
504
|
|
|
|
|
|
|
RAS APIs that update the phonebook. Microsoft reported this problem |
505
|
|
|
|
|
|
|
has been corrected in Service Pack 3. |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
http://support.microsoft.com/support/ntserver/serviceware/nts40/E9MSKWBJI.ASP |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
B: there are no ways to use Multilink |
510
|
|
|
|
|
|
|
programmatically on Win95/98. So, the current version of the module does not |
511
|
|
|
|
|
|
|
support it for WinNT also. For more info read: |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/q198/7/77.asp |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Entry names for Windows CE cannot exceed 20 characters. |
516
|
|
|
|
|
|
|
http://msdn.microsoft.com/library/wincesdk/wcecomm/ras_24.htm |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
A similiar problem is reported for the InternetMail Service (IMS) on |
519
|
|
|
|
|
|
|
MS BackOffice Small Business Server version 4.5 and Windows NT Server version 4.0 |
520
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/Q217/9/37.asp |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
So, the entries with long names may be unusable by the other applications. |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=over 4 |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=item RasCreateEntryDlg ( ) |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
This function displays a dialog box in which the user types information |
529
|
|
|
|
|
|
|
about the phonebook entry. |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
RasCreateEntryDlg( [$hwnd] ); |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
$hwnd - handle to the parent window of the dialog box. Optional. |
534
|
|
|
|
|
|
|
If you are using Win32::GUI this would be $Window->{handle} |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
As this is a synchronous operation and waits for user input it provides no |
537
|
|
|
|
|
|
|
way to find out whether the new entry was created or not. You should use |
538
|
|
|
|
|
|
|
C to understand what has happened. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
Here and everywhere in the functions that display a dialog box - if C<$hwnd> |
541
|
|
|
|
|
|
|
is omitted or does not identify an existing window a dialog box is centered |
542
|
|
|
|
|
|
|
on the screen. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=cut |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
#================ |
547
|
|
|
|
|
|
|
sub RasCreateEntryDlg (;$) { |
548
|
|
|
|
|
|
|
#================ |
549
|
0
|
|
|
0
|
|
|
my $hwnd = shift; |
550
|
0
|
|
|
|
|
|
$LastError = 0; |
551
|
|
|
|
|
|
|
|
552
|
0
|
0
|
0
|
|
|
|
$hwnd = 0 if $hwnd && !IsWindow($hwnd); |
553
|
|
|
|
|
|
|
|
554
|
0
|
|
0
|
|
|
|
$RasCreateEntry ||= new("rasapi32", "RasCreatePhonebookEntry", [N,P], N); |
555
|
|
|
|
|
|
|
|
556
|
0
|
|
0
|
|
|
|
my $ret = $RasCreateEntry->Call($hwnd||0, $PHONEBOOK||0); |
|
|
|
0
|
|
|
|
|
557
|
|
|
|
|
|
|
|
558
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
559
|
0
|
|
|
|
|
|
1; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=item RasEditEntryDlg ( ) |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
This function displays a dialog box in which the user types information |
565
|
|
|
|
|
|
|
about the phonebook entry. For a programmatical way to edit an existing |
566
|
|
|
|
|
|
|
entry take a look at C. |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
RasEditEntryDlg( $entry [, $hwnd] ); |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
$entry - existing phonebook entry to edit. |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
$hwnd - handle to the parent window of the dialog box. Optional. |
573
|
|
|
|
|
|
|
If you are using Win32::GUI this would be $Window->{handle} |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
This is a synchronous operation and waits for user input. |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
578
|
|
|
|
|
|
|
You should call C before to verify C<$entry>. |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
=cut |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
#================ |
583
|
|
|
|
|
|
|
sub RasEditEntryDlg ($;$) { |
584
|
|
|
|
|
|
|
#================ |
585
|
0
|
|
|
0
|
|
|
my ($entry, $hwnd) = @_; |
586
|
0
|
|
|
|
|
|
$LastError = 0; |
587
|
|
|
|
|
|
|
|
588
|
0
|
0
|
0
|
|
|
|
$hwnd = 0 if $hwnd && !IsWindow($hwnd); |
589
|
|
|
|
|
|
|
|
590
|
0
|
0
|
|
|
|
|
IsEntry($entry) or RASCROAK "`$entry' entry not found"; |
591
|
|
|
|
|
|
|
|
592
|
0
|
|
0
|
|
|
|
$RasEditEntry ||= new("rasapi32", "RasEditPhonebookEntry", [N,P,P], N); |
593
|
|
|
|
|
|
|
|
594
|
0
|
|
0
|
|
|
|
my $ret = $RasEditEntry->Call($hwnd||0, $PHONEBOOK||0, $entry); |
|
|
|
0
|
|
|
|
|
595
|
|
|
|
|
|
|
|
596
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
597
|
0
|
|
|
|
|
|
1; |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=item RasRenameEntry ( ) |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
RasRenameEntry( $oldname, $newname ); |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
Croaks if C<$oldname> does not exist or C<$newname> already exists. |
605
|
|
|
|
|
|
|
You should call C or C before to verify both. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=cut |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
#================ |
610
|
|
|
|
|
|
|
sub RasRenameEntry ($$) { |
611
|
|
|
|
|
|
|
#================ |
612
|
0
|
|
|
0
|
|
|
my ($old, $new) = @_; |
613
|
0
|
|
|
|
|
|
$LastError = 0; |
614
|
|
|
|
|
|
|
|
615
|
0
|
0
|
|
|
|
|
IsEntry($old) or RASCROAK "`$old' entry not found"; |
616
|
0
|
0
|
|
|
|
|
IsEntry($new) and RASCROAK "`$new' entry already exists"; |
617
|
|
|
|
|
|
|
|
618
|
0
|
|
0
|
|
|
|
$RasRenameEntry ||= new("rasapi32", "RasRenameEntry", [P,P,P], N); |
619
|
|
|
|
|
|
|
|
620
|
0
|
|
0
|
|
|
|
my $ret = $RasRenameEntry->Call($PHONEBOOK||0, $old, $new); |
621
|
|
|
|
|
|
|
|
622
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
623
|
0
|
|
|
|
|
|
1; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
=item RasDeleteEntry ( ) |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
RasDeleteEntry( $entry ); |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
631
|
|
|
|
|
|
|
You should call C or C before to verify C<$entry>. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=cut |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
#================ |
636
|
|
|
|
|
|
|
sub RasDeleteEntry ($) { |
637
|
|
|
|
|
|
|
#================ |
638
|
0
|
|
|
0
|
|
|
my $entry = shift; |
639
|
0
|
|
|
|
|
|
$LastError = 0; |
640
|
|
|
|
|
|
|
|
641
|
0
|
0
|
|
|
|
|
IsEntry($entry) or RASCROAK "`$entry' entry not found"; |
642
|
|
|
|
|
|
|
|
643
|
0
|
|
0
|
|
|
|
$RasDeleteEntry ||= new("rasapi32", "RasDeleteEntry", [P,P], N); |
644
|
|
|
|
|
|
|
|
645
|
0
|
|
0
|
|
|
|
my $ret = $RasDeleteEntry->Call($PHONEBOOK||0, $entry); |
646
|
|
|
|
|
|
|
|
647
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
648
|
0
|
|
|
|
|
|
1; |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=item RasEnumEntries ( ) |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
@entries = RasEnumEntries(); |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
This function lists all entry names in the phonebook. |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
As this function is heavily used internally it croaks on errors - for |
658
|
|
|
|
|
|
|
example if non-existing phonebook name is given. So, FALSE result means |
659
|
|
|
|
|
|
|
that the selected phonebook is empty. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
Command line syntax: |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
perl -MWin32::RASE -e "$,=q{, };print RasEnumEntries" |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
=cut |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
#================ |
668
|
|
|
|
|
|
|
sub RasEnumEntries () { |
669
|
|
|
|
|
|
|
#================ |
670
|
0
|
|
|
0
|
|
|
$LastError = 0; |
671
|
0
|
|
0
|
|
|
|
$RasEnumEntries ||= new("rasapi32", "RasEnumEntries", [P,P,P,P,P], N); |
672
|
|
|
|
|
|
|
|
673
|
0
|
|
|
|
|
|
my $dwSize = RAS_MaxEntryName+1+4; DWORD_ALIGN($dwSize); |
|
0
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
|
675
|
0
|
|
|
|
|
|
my $RASENTRYNAME = pack "La".(20*$dwSize-4), ($dwSize, ""); |
676
|
|
|
|
|
|
|
|
677
|
0
|
|
|
|
|
|
my ($lpcb, $lpcEntries) = (pack("L",length $RASENTRYNAME), DWORD_NULL); |
678
|
|
|
|
|
|
|
|
679
|
0
|
|
0
|
|
|
|
my $ret = $RasEnumEntries->Call(0, $PHONEBOOK||0, |
680
|
|
|
|
|
|
|
$RASENTRYNAME, $lpcb, $lpcEntries); |
681
|
|
|
|
|
|
|
|
682
|
0
|
0
|
|
|
|
|
if ($ret) { |
683
|
0
|
|
|
|
|
|
my $cb = unpack "L",$lpcb; |
684
|
0
|
|
|
|
|
|
$RASENTRYNAME = pack "La".($cb-4), ($dwSize, ""); |
685
|
|
|
|
|
|
|
|
686
|
0
|
0
|
0
|
|
|
|
$ret = $RasEnumEntries->Call(0, $PHONEBOOK||0, |
687
|
|
|
|
|
|
|
$RASENTRYNAME, $lpcb, $lpcEntries) and RASERROR($ret); |
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
0
|
|
|
|
|
|
my @entries; |
691
|
|
|
|
|
|
|
|
692
|
0
|
|
|
|
|
|
for my $i(1..unpack "L",$lpcEntries) { |
693
|
0
|
|
|
|
|
|
my $buffer = substr $RASENTRYNAME, ($dwSize*($i-1)), $dwSize; |
694
|
|
|
|
|
|
|
|
695
|
0
|
|
|
|
|
|
my ($dwSize1, $szEntryName) = unpack "La".($dwSize-4), $buffer; |
696
|
|
|
|
|
|
|
|
697
|
0
|
|
|
|
|
|
CRUNCH($szEntryName); |
698
|
0
|
|
|
|
|
|
push @entries, $szEntryName; |
699
|
|
|
|
|
|
|
} |
700
|
0
|
|
|
|
|
|
@entries; |
701
|
|
|
|
|
|
|
} |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=item IsEntry ( ) |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
IsEntry ( $entry ); |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
$entry - name of the RAS/DUN entry |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
Returns TRUE if C<$entry> was found in the phonebook, |
710
|
|
|
|
|
|
|
otherwise FALSE. |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
B It treats entry-names as case-sensitive (see above). |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=cut |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
#================ |
717
|
|
|
|
|
|
|
sub IsEntry ($) { |
718
|
|
|
|
|
|
|
#================ |
719
|
0
|
|
|
0
|
|
|
my $entry = shift; |
720
|
0
|
|
|
|
|
|
$LastError = 0; |
721
|
0
|
|
|
|
|
|
grep {$_ eq $entry} RasEnumEntries(); |
|
0
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
} |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=item RasGetEntryDialParams ( ) |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
This function retrieves the connection information saved by the last successful |
727
|
|
|
|
|
|
|
call to the C or C function for a specified |
728
|
|
|
|
|
|
|
phonebook entry. |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
($UserName, $Password, $Domain, $CallbackNumber) = |
731
|
|
|
|
|
|
|
RasGetEntryDialParams($entry); |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
734
|
|
|
|
|
|
|
$UserName - user's user name ;-) |
735
|
|
|
|
|
|
|
$Password - yes, it's that secure |
736
|
|
|
|
|
|
|
$Domain - domain on which authentication is to occur |
737
|
|
|
|
|
|
|
$CallbackNumber - callback phone number |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=cut |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
#================ |
744
|
|
|
|
|
|
|
sub RasGetEntryDialParams ($) { |
745
|
|
|
|
|
|
|
#================ |
746
|
|
|
|
|
|
|
# domain in addr form because DNLEN = 15 |
747
|
|
|
|
|
|
|
# alternate $szPhoneNumber seems like is not stored in phonebook |
748
|
|
|
|
|
|
|
# because RasSetEntryDialParams() does not set it |
749
|
0
|
|
|
0
|
|
|
my ($szEntryName, $szPhoneNumber, $szUserName, |
750
|
|
|
|
|
|
|
$szPassword, $szDomain, $szCallbackNumber) = shift; |
751
|
0
|
|
|
|
|
|
local $_; |
752
|
0
|
|
|
|
|
|
$LastError = 0; |
753
|
|
|
|
|
|
|
|
754
|
0
|
0
|
|
|
|
|
IsEntry($szEntryName) or RASCROAK "`$szEntryName' entry not found"; |
755
|
|
|
|
|
|
|
|
756
|
0
|
|
0
|
|
|
|
$RasGetEntryDialParams ||= new("rasapi32", "RasGetEntryDialParams", [P,P,P], N); |
757
|
|
|
|
|
|
|
|
758
|
0
|
0
|
|
|
|
|
my $dwSize = 4 + RAS_MaxEntryName + 1 + RAS_MaxPhoneNumber + 1 + |
759
|
|
|
|
|
|
|
RAS_MaxCallbackNumber + 1 + UNLEN + 1 + PWLEN + 1 + DNLEN + 1 + |
760
|
|
|
|
|
|
|
(Win32::IsWinNT && $WINVER >= 0x401 ? 4+4 : 0); |
761
|
|
|
|
|
|
|
|
762
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
763
|
|
|
|
|
|
|
|
764
|
0
|
|
|
|
|
|
my $RASDIALPARAMS = |
765
|
|
|
|
|
|
|
pack "La".(RAS_MaxEntryName + 1), ($dwSize, $szEntryName); |
766
|
|
|
|
|
|
|
|
767
|
0
|
|
|
|
|
|
$RASDIALPARAMS .= "\0"x($dwSize - length $RASDIALPARAMS); |
768
|
|
|
|
|
|
|
|
769
|
0
|
|
|
|
|
|
my $lpfPassword = DWORD_NULL; |
770
|
0
|
|
|
|
|
|
my $ret; |
771
|
0
|
|
0
|
|
|
|
$ret = $RasGetEntryDialParams->Call($PHONEBOOK||0, |
772
|
|
|
|
|
|
|
$RASDIALPARAMS, $lpfPassword); |
773
|
|
|
|
|
|
|
|
774
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
775
|
|
|
|
|
|
|
|
776
|
0
|
|
|
|
|
|
my $fPassword = unpack "L", $lpfPassword; |
777
|
|
|
|
|
|
|
|
778
|
0
|
|
|
|
|
|
($szCallbackNumber, $szUserName, $szPassword, $szDomain) = |
779
|
|
|
|
|
|
|
unpack "a".(RAS_MaxCallbackNumber + 1)."a".(UNLEN + 1). |
780
|
|
|
|
|
|
|
"a".(PWLEN + 1)."a".(DNLEN + 1), |
781
|
|
|
|
|
|
|
substr($RASDIALPARAMS, 4 + RAS_MaxEntryName + 1 + RAS_MaxPhoneNumber + 1); |
782
|
|
|
|
|
|
|
|
783
|
0
|
|
|
|
|
|
CRUNCH($szUserName, $szPassword, $szDomain, $szCallbackNumber); |
784
|
0
|
0
|
|
|
|
|
undef $szPassword unless $fPassword; |
785
|
|
|
|
|
|
|
|
786
|
0
|
|
|
|
|
|
($szUserName, $szPassword, $szDomain, $szCallbackNumber); |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
=item RasGetUserPwd ( ) |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
The short variant of previous. |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
($UserName, $Password) = RasGetUserPwd($entry); |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
Command line syntax: |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
perl -MWin32::RASE -e "print ((RasGetUserPwd('NEV1'))[0])" |
800
|
|
|
|
|
|
|
perl -MWin32::RASE -e "@_=RasGetUserPwd('NEV1');print qq{@_}" |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=cut |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
#================ |
805
|
|
|
|
|
|
|
sub RasGetUserPwd ($) { |
806
|
|
|
|
|
|
|
#================ |
807
|
0
|
|
|
0
|
|
|
$LastError = 0; |
808
|
0
|
0
|
|
|
|
|
my @a = RasGetEntryDialParams(shift) or return; |
809
|
0
|
|
|
|
|
|
@a[0,1]; |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=item RasSetEntryDialParams ( ) |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
This function changes the connection information for a specified |
815
|
|
|
|
|
|
|
phonebook entry. |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
RasSetEntryDialParams($entry, $UserName, $Password, $Domain, |
818
|
|
|
|
|
|
|
$CallbackNumber, $fRemovePassword); |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
All parameters except C<$entry> are optional. C or omitted |
821
|
|
|
|
|
|
|
parameters are considered to be "" - this means that no changes will |
822
|
|
|
|
|
|
|
be made to this parameter. |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
825
|
|
|
|
|
|
|
$UserName - user name |
826
|
|
|
|
|
|
|
$Password - password for the user specified by $UserName. |
827
|
|
|
|
|
|
|
If $UserName is an empty string, the password is not changed. |
828
|
|
|
|
|
|
|
If $Password is an empty string and $fRemovePassword is FALSE, |
829
|
|
|
|
|
|
|
the password is set to the empty string. If $fRemovePassword is |
830
|
|
|
|
|
|
|
TRUE, the password stored in this phonebook entry for the user |
831
|
|
|
|
|
|
|
specified by $UserName is removed regardless of the contents |
832
|
|
|
|
|
|
|
of the $Password string. |
833
|
|
|
|
|
|
|
$Domain - domain on which authentication is to occur. |
834
|
|
|
|
|
|
|
15 chars limitation. |
835
|
|
|
|
|
|
|
$CallbackNumber - callback phone number |
836
|
|
|
|
|
|
|
$fRemovePassword - (above) 0 if undefined/omitted |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
This is another excerpt from the API docs: |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
B You can use $Password to send a new password to the remote server |
842
|
|
|
|
|
|
|
when you restart a RasDial() connection from a RASCS_PasswordExpired paused state. |
843
|
|
|
|
|
|
|
When changing a password on an entry that calls Microsoft Networks, you should |
844
|
|
|
|
|
|
|
limit the new password to 14 characters in length to avoid down-level |
845
|
|
|
|
|
|
|
compatibility problems. |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
=cut |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
#================ |
852
|
|
|
|
|
|
|
sub RasSetEntryDialParams ($;$$$$$) { |
853
|
|
|
|
|
|
|
#================ |
854
|
|
|
|
|
|
|
# domain in addr form because DNLEN = 15 |
855
|
|
|
|
|
|
|
# alternate $szPhoneNumber is not set |
856
|
|
|
|
|
|
|
# each empty/undef value here means "don't change old value". |
857
|
|
|
|
|
|
|
|
858
|
0
|
|
|
0
|
|
|
my ($szEntryName, $szUserName, $szPassword, |
859
|
|
|
|
|
|
|
$szDomain, $szCallbackNumber, $fRemovePassword) = @_; |
860
|
0
|
|
|
|
|
|
my $szPhoneNumber; |
861
|
0
|
|
|
|
|
|
local $_; |
862
|
0
|
|
|
|
|
|
$LastError = 0; |
863
|
|
|
|
|
|
|
|
864
|
0
|
0
|
|
|
|
|
IsEntry($szEntryName) or RASCROAK "`$szEntryName' entry not found"; |
865
|
|
|
|
|
|
|
|
866
|
0
|
|
0
|
|
|
|
$RasSetEntryDialParams ||= new("rasapi32", "RasSetEntryDialParams", [P,P,N], N); |
867
|
|
|
|
|
|
|
|
868
|
0
|
0
|
|
|
|
|
my $dwSize = 4 + RAS_MaxEntryName + 1 + RAS_MaxPhoneNumber + 1 + |
869
|
|
|
|
|
|
|
RAS_MaxCallbackNumber + 1 + UNLEN + 1 + PWLEN + 1 + DNLEN + 1 + |
870
|
|
|
|
|
|
|
(Win32::IsWinNT && $WINVER >= 0x401 ? 4+4 : 0); |
871
|
|
|
|
|
|
|
|
872
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
873
|
|
|
|
|
|
|
|
874
|
0
|
|
0
|
|
|
|
my $RASDIALPARAMS = |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
875
|
|
|
|
|
|
|
pack "La".(RAS_MaxEntryName + 1)."a".(RAS_MaxPhoneNumber + 1). |
876
|
|
|
|
|
|
|
"a".(RAS_MaxCallbackNumber + 1)."a".(UNLEN + 1). |
877
|
|
|
|
|
|
|
"a".(PWLEN + 1)."a".(DNLEN + 1) |
878
|
|
|
|
|
|
|
, |
879
|
|
|
|
|
|
|
($dwSize, $szEntryName||"", $szPhoneNumber||"", $szCallbackNumber||"", |
880
|
|
|
|
|
|
|
$szUserName||"", $szPassword||"", $szDomain||""); |
881
|
|
|
|
|
|
|
|
882
|
0
|
|
|
|
|
|
$RASDIALPARAMS .= "\0"x($dwSize - length $RASDIALPARAMS); |
883
|
|
|
|
|
|
|
|
884
|
0
|
|
0
|
|
|
|
my $ret = $RasSetEntryDialParams->Call($PHONEBOOK||0, |
|
|
|
0
|
|
|
|
|
885
|
|
|
|
|
|
|
$RASDIALPARAMS, $fRemovePassword||0); |
886
|
|
|
|
|
|
|
|
887
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
888
|
0
|
|
|
|
|
|
1; |
889
|
|
|
|
|
|
|
} |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=item RasGetEntryProperties ( ) |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
This function retrieves the properties of a phonebook entry. |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
$props = RasGetEntryProperties($entry); |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
898
|
|
|
|
|
|
|
$props - pointer to hash |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
The description of the %$props hash is common for this function and |
902
|
|
|
|
|
|
|
C. |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
KEY VALUE |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
name - copy of $entry |
908
|
|
|
|
|
|
|
Flags - numeric flag value, combination of RASEO_* flags. |
909
|
|
|
|
|
|
|
You don't need to use it directly, it's here for |
910
|
|
|
|
|
|
|
information purpose only. In RasSetEntryProperties() |
911
|
|
|
|
|
|
|
it is ignored if present, you should manipulate |
912
|
|
|
|
|
|
|
mnemonic flags as described below, with the |
913
|
|
|
|
|
|
|
'newFlags' key. |
914
|
|
|
|
|
|
|
FlagsReadable - $props->{FlagsReadable} refers to array of |
915
|
|
|
|
|
|
|
"mnemonic flags" that are affecting the behavior |
916
|
|
|
|
|
|
|
of the other properties. |
917
|
|
|
|
|
|
|
Not used by RasSetEntryProperties(). |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
Manipulating these flags is described in C section. |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
ipaddr - constant ip-address, ignored unless "SpecificIpAddr" |
922
|
|
|
|
|
|
|
is present in the array of "mnemonic flags" |
923
|
|
|
|
|
|
|
ipaddrDns - primary DNS server |
924
|
|
|
|
|
|
|
ipaddrDnsAlt - secondary(backup) DNS server |
925
|
|
|
|
|
|
|
ipaddrWins - IP address of the primary WINS server |
926
|
|
|
|
|
|
|
ipaddrWinsAlt - secondary WINS server |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
C, C, C, C are |
929
|
|
|
|
|
|
|
ignored unless "SpecificNameServers" is present in the array of "mnemonic flags" |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
All IP-addresses are in xxx.xxx.xxx.xxx decimal form without leading zeros |
932
|
|
|
|
|
|
|
in each part(octet). For example: 195.100.0.28 |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
The common rule here is that empty or blank values will produce 0.0.0.0 |
935
|
|
|
|
|
|
|
(as well as "0.0.0.0" itself). |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
CountryID - |
938
|
|
|
|
|
|
|
CountryName - |
939
|
|
|
|
|
|
|
CountryCode - |
940
|
|
|
|
|
|
|
AreaCode - |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
(Country ID-Name-Code and AreaCode are described in the |
943
|
|
|
|
|
|
|
C section except that here they are describing |
944
|
|
|
|
|
|
|
the computer you want to dial to.) |
945
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
In C |
947
|
|
|
|
|
|
|
C would be ignored. C not matching C |
948
|
|
|
|
|
|
|
would give error. You could easily give only one of these two values. C |
949
|
|
|
|
|
|
|
would be counted properly if C is given (described in |
950
|
|
|
|
|
|
|
C section). But if you'll give C |
951
|
|
|
|
|
|
|
C would be set equal to C that is sometimes incorrect |
952
|
|
|
|
|
|
|
but does not affect the dialup connection. |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
You can also check the correctness of the C with the |
955
|
|
|
|
|
|
|
C function. |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
LocalPhoneNumber - phone number without country/area parts |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
Script - script file's path. |
960
|
|
|
|
|
|
|
On Win95 this is DialUp Scripting Tool script. |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
Windows NT: To indicate a SWITCH.INF script name, set the first character |
963
|
|
|
|
|
|
|
of the name to "[". |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
C function may have a problem |
966
|
|
|
|
|
|
|
saving the full script path (NT, fixed in the Service Pack 4). |
967
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/Q160/1/90.asp |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
DeviceType - one of the following string constants |
970
|
|
|
|
|
|
|
(case-insensitive): |
971
|
|
|
|
|
|
|
"modem" A modem accessed through a COM port |
972
|
|
|
|
|
|
|
"isdn" An ISDN card with corresponding NDISWAN driver installed |
973
|
|
|
|
|
|
|
"x25" An X.25 card with corresponding NDISWAN driver installed |
974
|
|
|
|
|
|
|
"x25" type is not implemented in RasSetEntryProperties() |
975
|
|
|
|
|
|
|
in this version of the module |
976
|
|
|
|
|
|
|
"vpn" A Microsoft VPN Adapter |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
You can read a note about VPN and PPTP in the C section. |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
DeviceName - name of a TAPI device to use with this phonebook entry |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
NetProtocols - network protocols to negotiate. |
983
|
|
|
|
|
|
|
$props->{NetProtocols} refers to the array that can |
984
|
|
|
|
|
|
|
contain one or more of the strings |
985
|
|
|
|
|
|
|
(case insensitive in RasSetEntryProperties()): |
986
|
|
|
|
|
|
|
"NetBEUI" NetBIOS End User Interface standard |
987
|
|
|
|
|
|
|
"Ipx" IPX/SPX Compartible |
988
|
|
|
|
|
|
|
"Ip" TCP/IP |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
FramingProtocol - framing protocol used by the server. |
991
|
|
|
|
|
|
|
One of the following strings: |
992
|
|
|
|
|
|
|
"PPP", "Slip", "RAS" |
993
|
|
|
|
|
|
|
(case insensitive in RasSetEntryProperties()) |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
B |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
Subentries(multilink dialing) are currently not supported as well as X.25-related |
998
|
|
|
|
|
|
|
parameters. Current version of Win32::RASE also does not allow you to change |
999
|
|
|
|
|
|
|
'DeviceType' and 'DeviceName' elements. This will be added in some future. |
1000
|
|
|
|
|
|
|
Right now any changes in these fields will not affect the |
1001
|
|
|
|
|
|
|
C execution. |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
B don't misuse this function, in list context it returns |
1004
|
|
|
|
|
|
|
unreadable things for internal needs. |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
For an easy way to change just the phone-number take a look at the |
1009
|
|
|
|
|
|
|
C section. |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=cut |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
#================ |
1014
|
|
|
|
|
|
|
sub RasGetEntryProperties ($) { |
1015
|
|
|
|
|
|
|
#================ |
1016
|
0
|
|
|
0
|
|
|
my $entry = shift; |
1017
|
0
|
|
|
|
|
|
$LastError = 0; |
1018
|
|
|
|
|
|
|
|
1019
|
0
|
0
|
|
|
|
|
IsEntry($entry) or RASCROAK "`$entry' entry not found"; |
1020
|
|
|
|
|
|
|
|
1021
|
0
|
|
0
|
|
|
|
$RasGetEntryProperties ||= new("rasapi32", "RasGetEntryProperties", [P,P,P,P,P,P], N); |
1022
|
|
|
|
|
|
|
|
1023
|
0
|
|
|
|
|
|
my ($RASENTRY, $dwSize) = InitializeRASENTRY(); |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
# first call to find $lpdwDeviceInfoSize |
1026
|
0
|
|
|
|
|
|
my ($lpdwEntryInfoSize, $lpbDeviceInfo, $lpdwDeviceInfoSize) = |
1027
|
|
|
|
|
|
|
# (pack("L",$dwSize), "\0"x1024, pack("L",1024)); |
1028
|
|
|
|
|
|
|
(pack("L",$dwSize), 0, DWORD_NULL); |
1029
|
|
|
|
|
|
|
|
1030
|
0
|
|
0
|
|
|
|
my $ret = $RasGetEntryProperties->Call($PHONEBOOK||0, $entry, $RASENTRY, |
1031
|
|
|
|
|
|
|
$lpdwEntryInfoSize, $lpbDeviceInfo, $lpdwDeviceInfoSize); |
1032
|
|
|
|
|
|
|
#print "get_ret1:$ret\n"; |
1033
|
|
|
|
|
|
|
# $ret and ($LastError = $ret, return); |
1034
|
|
|
|
|
|
|
|
1035
|
0
|
|
|
|
|
|
my $dwDeviceInfoSize = unpack "L",$lpdwDeviceInfoSize; |
1036
|
|
|
|
|
|
|
#print "\$dwDeviceInfoSize: $dwDeviceInfoSize\n"; |
1037
|
|
|
|
|
|
|
|
1038
|
0
|
|
|
|
|
|
$lpbDeviceInfo = "\0"x$dwDeviceInfoSize; |
1039
|
|
|
|
|
|
|
|
1040
|
0
|
|
0
|
|
|
|
$ret = $RasGetEntryProperties->Call($PHONEBOOK||0, $entry, $RASENTRY, |
1041
|
|
|
|
|
|
|
$lpdwEntryInfoSize, $lpbDeviceInfo, $lpdwDeviceInfoSize); |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
#print "get_ret2:$ret\n"; |
1044
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
#print "DeviceInfo length:".length($lpbDeviceInfo)."\n"; |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
#if ($lpdwDeviceInfoSize) { |
1049
|
|
|
|
|
|
|
#print hexizer($lpbDeviceInfo),"\n"; |
1050
|
|
|
|
|
|
|
#} |
1051
|
|
|
|
|
|
|
#sub hexizer { |
1052
|
|
|
|
|
|
|
# local $_ = uc unpack "H*", shift; |
1053
|
|
|
|
|
|
|
# s/(..)/$1 /g; |
1054
|
|
|
|
|
|
|
# s/.{48}/$&\n/g; $_; |
1055
|
|
|
|
|
|
|
#} |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
|
1058
|
0
|
0
|
|
|
|
|
wantarray ? ($RASENTRY, $lpbDeviceInfo) : |
1059
|
|
|
|
|
|
|
RasBuildEntryProperties($entry, $RASENTRY, $lpbDeviceInfo); |
1060
|
|
|
|
|
|
|
} |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
#=========================== |
1063
|
|
|
|
|
|
|
sub InitializeRASENTRY () { |
1064
|
|
|
|
|
|
|
#=========================== |
1065
|
|
|
|
|
|
|
# creates empty RASENTRY |
1066
|
|
|
|
|
|
|
|
1067
|
0
|
0
|
|
0
|
|
|
my $dwSize = 4*13 + 4*((Win32::IsWinNT && $WINVER >= 0x401) ? 10 : 3) + |
1068
|
|
|
|
|
|
|
(RAS_MaxAreaCode+1) + (RAS_MaxPhoneNumber+1) + 3*MAX_PATH + |
1069
|
|
|
|
|
|
|
(RAS_MaxDeviceType+1) + (RAS_MaxDeviceName+1) + |
1070
|
|
|
|
|
|
|
(RAS_MaxPadType+1) + (RAS_MaxX25Address+1) + |
1071
|
|
|
|
|
|
|
(RAS_MaxFacilities+1) + (RAS_MaxUserData+1); |
1072
|
|
|
|
|
|
|
|
1073
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
1074
|
0
|
|
|
|
|
|
my $dwAlternateOffset = $dwSize; |
1075
|
|
|
|
|
|
|
|
1076
|
0
|
|
|
|
|
|
my $RASENTRY = pack "La".($dwSize-4), ($dwSize, ""); |
1077
|
0
|
|
|
|
|
|
substr($RASENTRY, |
1078
|
|
|
|
|
|
|
(4*4 + RAS_MaxAreaCode+1+RAS_MaxPhoneNumber+1), 4) = |
1079
|
|
|
|
|
|
|
pack "L", $dwAlternateOffset; |
1080
|
|
|
|
|
|
|
|
1081
|
0
|
|
|
|
|
|
($RASENTRY, $dwSize); |
1082
|
|
|
|
|
|
|
} |
1083
|
|
|
|
|
|
|
#==================== |
1084
|
|
|
|
|
|
|
sub RasBuildEntryProperties ($$$) { |
1085
|
|
|
|
|
|
|
#==================== |
1086
|
0
|
|
|
0
|
|
|
my ($entry, $tagRASENTRY, $lpbDeviceInfo) = @_; |
1087
|
0
|
|
|
|
|
|
my (@attr, @attrNP, $attrFP); |
1088
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
my ( |
1090
|
0
|
|
|
|
|
|
$dwSize, |
1091
|
|
|
|
|
|
|
$dwfOptions, # +4 |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
$dwCountryID, # +8 |
1094
|
|
|
|
|
|
|
$dwCountryCode, # +12 |
1095
|
|
|
|
|
|
|
$szAreaCode, # +16 |
1096
|
|
|
|
|
|
|
$szLocalPhoneNumber, |
1097
|
|
|
|
|
|
|
$dwAlternateOffset, |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
$ipaddr, |
1100
|
|
|
|
|
|
|
$ipaddrDns, |
1101
|
|
|
|
|
|
|
$ipaddrDnsAlt, |
1102
|
|
|
|
|
|
|
$ipaddrWins, |
1103
|
|
|
|
|
|
|
$ipaddrWinsAlt, |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
$dwFrameSize, |
1106
|
|
|
|
|
|
|
$dwfNetProtocols, |
1107
|
|
|
|
|
|
|
$dwFramingProtocol, |
1108
|
|
|
|
|
|
|
$szScript, |
1109
|
|
|
|
|
|
|
$szAutodialDll, |
1110
|
|
|
|
|
|
|
$szAutodialFunc, |
1111
|
|
|
|
|
|
|
$szDeviceType, |
1112
|
|
|
|
|
|
|
$szDeviceName, |
1113
|
|
|
|
|
|
|
# $szX25PadType, |
1114
|
|
|
|
|
|
|
# $szX25Address, |
1115
|
|
|
|
|
|
|
# $szX25Facilities, |
1116
|
|
|
|
|
|
|
# $szX25UserData, |
1117
|
|
|
|
|
|
|
# $dwChannels, |
1118
|
|
|
|
|
|
|
# $dwReserved1, |
1119
|
|
|
|
|
|
|
# $dwReserved2, |
1120
|
|
|
|
|
|
|
# $dwSubEntries, |
1121
|
|
|
|
|
|
|
# $dwDialMode, |
1122
|
|
|
|
|
|
|
# $dwDialExtraPercent, |
1123
|
|
|
|
|
|
|
# $dwDialExtraSampleSeconds, |
1124
|
|
|
|
|
|
|
# $dwHangUpExtraPercent, |
1125
|
|
|
|
|
|
|
# $dwHangUpExtraSampleSeconds, |
1126
|
|
|
|
|
|
|
# $dwIdleDisconnectSeconds, |
1127
|
|
|
|
|
|
|
) = unpack "LLLLa".(RAS_MaxAreaCode+1)."a".(RAS_MaxPhoneNumber+1). |
1128
|
|
|
|
|
|
|
"La4a4a4a4a4LLLa".(MAX_PATH)."a".(MAX_PATH)."a".(MAX_PATH). |
1129
|
|
|
|
|
|
|
"a".(RAS_MaxDeviceType+1)."a".(RAS_MaxDeviceName+1) |
1130
|
|
|
|
|
|
|
# ."a".(RAS_MaxPadType+1) ."a".(RAS_MaxX25Address+1). |
1131
|
|
|
|
|
|
|
# "a".(RAS_MaxFacilities+1)."a".(RAS_MaxUserData+1) |
1132
|
|
|
|
|
|
|
# .(($WINVER >= 0x401) ? "LLLLLLLLLL" : "LLL") |
1133
|
|
|
|
|
|
|
, $tagRASENTRY; |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
|
1137
|
0
|
0
|
|
|
|
|
$dwfNetProtocols & RASNP_NetBEUI and push @attrNP, "NetBEUI"; |
1138
|
0
|
0
|
|
|
|
|
$dwfNetProtocols & RASNP_Ipx and push @attrNP, "Ipx"; |
1139
|
0
|
0
|
|
|
|
|
$dwfNetProtocols & RASNP_Ip and push @attrNP, "Ip"; |
1140
|
|
|
|
|
|
|
|
1141
|
0
|
0
|
|
|
|
|
$dwFramingProtocol eq RASFP_Ppp and $attrFP = "PPP"; |
1142
|
0
|
0
|
|
|
|
|
$dwFramingProtocol eq RASFP_Slip and $attrFP = "Slip"; |
1143
|
0
|
0
|
|
|
|
|
$dwFramingProtocol eq RASFP_Ras and $attrFP = "RAS"; |
1144
|
|
|
|
|
|
|
|
1145
|
0
|
|
|
|
|
|
CRUNCH($szAreaCode, $szLocalPhoneNumber, $szScript, |
1146
|
|
|
|
|
|
|
# $szAutodialDll, $szAutodialFunc, |
1147
|
|
|
|
|
|
|
$szDeviceType,$szDeviceName); |
1148
|
|
|
|
|
|
|
|
1149
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
1150
|
|
|
|
|
|
|
|
1151
|
0
|
0
|
|
|
|
|
my $props = { |
1152
|
|
|
|
|
|
|
name => $entry, |
1153
|
|
|
|
|
|
|
ipaddr => (join '.',map ord, split//,$ipaddr), |
1154
|
|
|
|
|
|
|
ipaddrDns => (join '.',map ord, split//,$ipaddrDns), |
1155
|
|
|
|
|
|
|
ipaddrDnsAlt => (join '.',map ord, split//,$ipaddrDnsAlt), |
1156
|
|
|
|
|
|
|
ipaddrWins => (join '.',map ord, split//,$ipaddrWins), |
1157
|
|
|
|
|
|
|
ipaddrWinsAlt => (join '.',map ord, split//,$ipaddrWinsAlt), |
1158
|
|
|
|
|
|
|
CountryID => $dwCountryID, |
1159
|
|
|
|
|
|
|
CountryName => (exists($TAPIEnumeration{$dwCountryID}) ? |
1160
|
|
|
|
|
|
|
$TAPIEnumeration{$dwCountryID}->[0] : ""), |
1161
|
|
|
|
|
|
|
CountryCode => $dwCountryCode, |
1162
|
|
|
|
|
|
|
AreaCode => $szAreaCode, |
1163
|
|
|
|
|
|
|
LocalPhoneNumber => $szLocalPhoneNumber, |
1164
|
|
|
|
|
|
|
Script => $szScript, |
1165
|
|
|
|
|
|
|
# AutodialDll => $szAutodialDll, |
1166
|
|
|
|
|
|
|
# AutodialFunc => $szAutodialFunc, |
1167
|
|
|
|
|
|
|
DeviceType => $szDeviceType, |
1168
|
|
|
|
|
|
|
DeviceName => $szDeviceName, |
1169
|
|
|
|
|
|
|
Flags => $dwfOptions, |
1170
|
|
|
|
|
|
|
FlagsReadable => [], |
1171
|
|
|
|
|
|
|
NetProtocols => \@attrNP, |
1172
|
|
|
|
|
|
|
FramingProtocol => $attrFP, |
1173
|
|
|
|
|
|
|
}; |
1174
|
|
|
|
|
|
|
|
1175
|
0
|
|
|
|
|
|
for my $i(@RASEO_vars) { |
1176
|
0
|
0
|
|
|
|
|
push(@{ $props->{FlagsReadable} }, $i) if $dwfOptions & eval($i); |
|
0
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
} |
1178
|
|
|
|
|
|
|
|
1179
|
0
|
|
|
|
|
|
$props; |
1180
|
|
|
|
|
|
|
} |
1181
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
=item RasPrintEntryProperties ( ) |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
This function provides nice printing of a phonebook entry properties. |
1185
|
|
|
|
|
|
|
For debugging, for fun etc. |
1186
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
RasPrintEntryProperties( $entry ); |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. |
1192
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
=cut |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
#==================== |
1196
|
|
|
|
|
|
|
sub RasPrintEntryProperties ($) { |
1197
|
|
|
|
|
|
|
#==================== |
1198
|
0
|
|
|
0
|
|
|
my $entry = shift; |
1199
|
0
|
|
|
|
|
|
$LastError = 0; |
1200
|
|
|
|
|
|
|
|
1201
|
0
|
0
|
|
|
|
|
my $props = RasGetEntryProperties($entry) or return; |
1202
|
|
|
|
|
|
|
|
1203
|
0
|
|
|
|
|
|
print "RAS/DUN entry: $entry\n\n"; |
1204
|
|
|
|
|
|
|
|
1205
|
0
|
|
|
|
|
|
for my $p(sort keys %$props) { |
1206
|
0
|
0
|
|
|
|
|
next if $p eq "name"; |
1207
|
0
|
0
|
|
|
|
|
if (! ref $props->{$p}) { |
1208
|
0
|
|
|
|
|
|
printf "%18s: %s\n", $p, $props->{$p}; |
1209
|
|
|
|
|
|
|
} else { |
1210
|
0
|
0
|
|
|
|
|
printf "%18s: %s\n", $p, @{$props->{$p}} ? $props->{$p}->[0] : ""; |
|
0
|
|
|
|
|
|
|
1211
|
0
|
|
|
|
|
|
map {printf "%18s %s\n", "",$_} @{$props->{$p}}[1..$#{$props->{$p}}]; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
} |
1213
|
|
|
|
|
|
|
} |
1214
|
0
|
|
|
|
|
|
1; |
1215
|
|
|
|
|
|
|
} |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
=item RasGetEntryDevProperties ( ) |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
This function retrieves the properties of a device used by the phonebook entry |
1220
|
|
|
|
|
|
|
if this entry uses MS Unimodem compartible TSP (Telephone Service Provider) or |
1221
|
|
|
|
|
|
|
in other words - Unimodem compartible driver, on Win95 - always. |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
$props = RasGetEntryDevProperties($entry); |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
1227
|
|
|
|
|
|
|
$props - pointer to hash |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
(Sorry, the description might not be clear enough, just print your |
1230
|
|
|
|
|
|
|
properties with the C and it'd be much easier.) |
1231
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
The description of the C<%$props> hash is common for this function and |
1233
|
|
|
|
|
|
|
C (not implemented yet). |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
It's much likely that only a small part of the described data is |
1236
|
|
|
|
|
|
|
really usefull. Look at the Win32 SDK/MS Platform SDK |
1237
|
|
|
|
|
|
|
(TAPI Prorammer's Reference - "comm/datamodem", "COMMCONFIG", "DCB", |
1238
|
|
|
|
|
|
|
"MODEMSETTINGS" sections) for more info. |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
|
1241
|
|
|
|
|
|
|
KEY VALUE |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
name - copy of $entry |
1244
|
|
|
|
|
|
|
DeviceName - name of a TAPI device to use with this phonebook entry |
1245
|
|
|
|
|
|
|
DeviceType - described in the RasGetEntryProperties() section |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
Options - numeric flag value, combination of the Option flags |
1248
|
|
|
|
|
|
|
that appear on the Unimodem Option page. |
1249
|
|
|
|
|
|
|
This member can be a combination of these values: |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
TERMINAL_PRE (1) - Displays the pre-terminal screen. |
1252
|
|
|
|
|
|
|
TERMINAL_POST (2) - Displays the post-terminal screen. |
1253
|
|
|
|
|
|
|
MANUAL_DIAL (4) - Dials the phone manually, if capable of doing so |
1254
|
|
|
|
|
|
|
LAUNCH_LIGHTS (8) - Displays the modem tray icon. |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
Only the LAUNCH_LIGHTS value is set by default |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
OptionsReadable - an array ref, a readable representation of those |
1260
|
|
|
|
|
|
|
Options, that are switched on. The array consists of zero or more |
1261
|
|
|
|
|
|
|
strings |
1262
|
|
|
|
|
|
|
"TERMINAL_PRE", "TERMINAL_POST", "MANUAL_DIAL", "LAUNCH_LIGHTS" |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
WaitBong - Number of seconds (in two seconds granularity) to |
1265
|
|
|
|
|
|
|
replace the wait for credit tone (default - 10 s) |
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
CallSetupFailTimer - the maximum number of seconds the modem should |
1268
|
|
|
|
|
|
|
wait, after dialing is completed, for an indication that a |
1269
|
|
|
|
|
|
|
modem-to-modem connection has been established. If a connection |
1270
|
|
|
|
|
|
|
is not established in this interval, the call is assumed to have |
1271
|
|
|
|
|
|
|
failed. This member is equivalent to register S7 in Hayes |
1272
|
|
|
|
|
|
|
compatible modems. |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
InactivityTimeout - the maximum number of seconds of inactivity |
1275
|
|
|
|
|
|
|
allowed after a connection is established. If no data is either |
1276
|
|
|
|
|
|
|
transmitted or received for this period of time, the call is |
1277
|
|
|
|
|
|
|
automatically terminated. |
1278
|
|
|
|
|
|
|
This time-out is used to avoid excessive long distance charges |
1279
|
|
|
|
|
|
|
or online service charges if an application unexpectedly locks up |
1280
|
|
|
|
|
|
|
or the user leaves. |
1281
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
SpeakerVolume - one of the following values: "LOW", "MEDIUM", "HIGH" |
1283
|
|
|
|
|
|
|
Note that actual volumes are hardware-specific. |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
SpeakerMode - one of the following values: |
1286
|
|
|
|
|
|
|
"OFF" - The speaker is always off |
1287
|
|
|
|
|
|
|
"CALLSETUP" - The speaker is on until a connection is established |
1288
|
|
|
|
|
|
|
"ON" - The speaker is always on |
1289
|
|
|
|
|
|
|
"DIAL" - The speaker is on until a connection is established, |
1290
|
|
|
|
|
|
|
except that it is off while the modem is actually dialing |
1291
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
PreferredModemOptions - a numeric flag value. Specifies the modem |
1293
|
|
|
|
|
|
|
options requested by the application. The local and remote modems |
1294
|
|
|
|
|
|
|
negotiate modem options during call setup; this member specifies |
1295
|
|
|
|
|
|
|
the initial negotiating position of the local modem. A combination |
1296
|
|
|
|
|
|
|
of bit flags. |
1297
|
|
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
PreferredModemOptionsReadable - refers to array of strings that |
1299
|
|
|
|
|
|
|
represent bit flags of the previous. Contains zero or more of the |
1300
|
|
|
|
|
|
|
following strings: |
1301
|
|
|
|
|
|
|
"COMPRESSION", "ERROR_CONTROL", "FORCED_EC", |
1302
|
|
|
|
|
|
|
"CELLULAR", "FLOWCONTROL_HARD", "FLOWCONTROL_SOFT", |
1303
|
|
|
|
|
|
|
"CCITT_OVERRIDE", "SPEED_ADJUST", |
1304
|
|
|
|
|
|
|
"TONE_DIAL", "BLIND_DIAL", "V23_OVERRIDE" |
1305
|
|
|
|
|
|
|
|
1306
|
|
|
|
|
|
|
Comments: |
1307
|
|
|
|
|
|
|
CCITT_OVERRIDE - When set, CCITT modulations are enabled for V.21 |
1308
|
|
|
|
|
|
|
and V.22 or V.23.When clear, bell modulations |
1309
|
|
|
|
|
|
|
are enabled for 103 and 212A. |
1310
|
|
|
|
|
|
|
V23_OVERRIDE - When set, CCITT modulations are enabled for V.23. |
1311
|
|
|
|
|
|
|
When clear, CCITT modulations are enabled for |
1312
|
|
|
|
|
|
|
V.21 and V.22. |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
For V.23 to be set, both CCITT_OVERRIDE and V23_OVERRIDE must be set. |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
NegotiatedModemOptions - a numeric flag value. Specifies the modem |
1317
|
|
|
|
|
|
|
options that are actually in effect. This member is filled in |
1318
|
|
|
|
|
|
|
after a connection is established and the local and remote |
1319
|
|
|
|
|
|
|
modems negotiate modem options. This value is read only. |
1320
|
|
|
|
|
|
|
(On my Win95 - always 0). |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
NegotiatedModemOptionsReadable - the same ref to array of the readable |
1323
|
|
|
|
|
|
|
strings as PreferredModemOptionsReadable, |
1324
|
|
|
|
|
|
|
but for NegotiatedModemOptions. |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
NegotiatedDCERate - Specifies the DCE rate that is in effect. |
1327
|
|
|
|
|
|
|
This member is filled in after a connection is established and |
1328
|
|
|
|
|
|
|
the local and remote modems negotiate modem modulations. |
1329
|
|
|
|
|
|
|
Also read-only. |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
DCE - Open Software Foundation (OSF) Distributed Computing Environment. |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
The DCB structure defines the control setting for a serial communications device. |
1334
|
|
|
|
|
|
|
The following keys are members of the DCB structure. |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
DCB_BaudRate - Specifies the baud rate at which the communications |
1337
|
|
|
|
|
|
|
device operates. This member can be one of the following values: |
1338
|
|
|
|
|
|
|
110, 300, 600, 1200, 2400, 4800, 9600, 14400, 38400, |
1339
|
|
|
|
|
|
|
56000, 57600, 115200, 128000, 256000 |
1340
|
|
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
DCB_Flags - numeric flag value, concatenation of many DCB flags. |
1342
|
|
|
|
|
|
|
You don't need to use it directly, it's here for |
1343
|
|
|
|
|
|
|
information purpose only. |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
DCB_FlagsReadable - an array ref. The array consists of the 13 string |
1346
|
|
|
|
|
|
|
values. Each string is in the form "flagname:value". |
1347
|
|
|
|
|
|
|
The values are in most cases 0/1. The flags names are: |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
fBinary - Specifies whether binary mode is enabled. |
1350
|
|
|
|
|
|
|
The Win32 API does not support nonbinary mode transfers, so this |
1351
|
|
|
|
|
|
|
member should be 1. Trying to use 0 will not work. |
1352
|
|
|
|
|
|
|
Under Windows 3.1, if this member is 0, nonbinary mode is |
1353
|
|
|
|
|
|
|
enabled, and the character specified by the DBC_EofChar member |
1354
|
|
|
|
|
|
|
is recognized on input and remembered as the end of data. (0/1) |
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
fParity - Specifies whether parity checking is enabled (0/1) |
1357
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
fOutxCtsFlow - Specifies whether the CTS (clear-to-send) signal |
1359
|
|
|
|
|
|
|
is monitored for output flow control. If this member is 1 and CTS |
1360
|
|
|
|
|
|
|
is turned off, output is suspended until CTS is sent again. (0/1) |
1361
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
fOutxDsrFlow - Specifies whether the DSR (data-set-ready) signal |
1363
|
|
|
|
|
|
|
is monitored for output flow control. If this member is 1 and DSR |
1364
|
|
|
|
|
|
|
is turned off, output is suspended until DSR is sent again. (0/1) |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
fDtrControl - Specifies the DTR (data-terminal-ready) |
1367
|
|
|
|
|
|
|
flow control. |
1368
|
|
|
|
|
|
|
This member can be one of the following values: |
1369
|
|
|
|
|
|
|
0 - Disables the DTR line when the device is opened and leaves it |
1370
|
|
|
|
|
|
|
disabled |
1371
|
|
|
|
|
|
|
1 - Enables the DTR line when the device is opened and leaves it on |
1372
|
|
|
|
|
|
|
2 - Enables DTR handshaking |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
fDsrSensitivity - Specifies whether the communications driver is |
1375
|
|
|
|
|
|
|
sensitive to the state of the DSR signal. If this member is 1, |
1376
|
|
|
|
|
|
|
the driver ignores any bytes received, unless the DSR modem input |
1377
|
|
|
|
|
|
|
line is high. (0/1) |
1378
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
fTXContinueOnXoff - Specifies whether transmission stops when the |
1380
|
|
|
|
|
|
|
input buffer is full and the driver has transmitted the |
1381
|
|
|
|
|
|
|
DCB_XoffChar character. |
1382
|
|
|
|
|
|
|
If this member is 1, transmission continues after the input |
1383
|
|
|
|
|
|
|
buffer has come within DCB_XoffLim bytes of being full and the |
1384
|
|
|
|
|
|
|
driver has transmitted the DCB_XoffChar character to stop |
1385
|
|
|
|
|
|
|
receiving bytes. |
1386
|
|
|
|
|
|
|
If this member is 0, transmission does not continue until the |
1387
|
|
|
|
|
|
|
input buffer is within DCB_XonLim bytes of being empty and the |
1388
|
|
|
|
|
|
|
driver has transmitted the DCB_XonChar character to resume |
1389
|
|
|
|
|
|
|
reception. (0/1) |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
fOutX - Specifies whether XON/XOFF flow control is used |
1392
|
|
|
|
|
|
|
during transmission. If this member is 1, transmission stops when |
1393
|
|
|
|
|
|
|
the DCB_XoffChar character is received and starts again when the |
1394
|
|
|
|
|
|
|
DCB_XonChar character is received. (0/1) |
1395
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
fInX - Specifies whether XON/XOFF flow control is used |
1397
|
|
|
|
|
|
|
during reception. If this member is 1, the DCB_XoffChar character |
1398
|
|
|
|
|
|
|
is sent when the input buffer comes within DCB_XoffLim bytes of |
1399
|
|
|
|
|
|
|
being full, and the DCB_XonChar character is sent when the input |
1400
|
|
|
|
|
|
|
buffer comes within DCB_XonLim bytes of being empty. (0/1) |
1401
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
fErrorChar - Specifies whether bytes received with parity |
1403
|
|
|
|
|
|
|
errors are replaced with the character specified by the |
1404
|
|
|
|
|
|
|
DCB_ErrorChar member. |
1405
|
|
|
|
|
|
|
If this member is 1 and the fParity member is 1, replacement |
1406
|
|
|
|
|
|
|
occurs. (0/1) |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
fNull - pecifies whether null bytes are discarded. |
1409
|
|
|
|
|
|
|
If this member is 1, null bytes are discarded when received.(0/1) |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
fRtsControl - Specifies the RTS (request-to-send) flow control. |
1412
|
|
|
|
|
|
|
This member can be one of the following values: |
1413
|
|
|
|
|
|
|
0 - Disables the RTS line when the device is opened and leaves |
1414
|
|
|
|
|
|
|
it disabled. |
1415
|
|
|
|
|
|
|
1 - Enables the RTS line when the device is opened and leaves |
1416
|
|
|
|
|
|
|
it on. |
1417
|
|
|
|
|
|
|
2 - Enables RTS handshaking. The driver raises the RTS line when |
1418
|
|
|
|
|
|
|
the "type-ahead" (input) buffer is less than one-half full |
1419
|
|
|
|
|
|
|
and lowers the RTS line when the buffer is more than |
1420
|
|
|
|
|
|
|
three-quarters full. |
1421
|
|
|
|
|
|
|
3 - Specifies that the RTS line will be high if bytes are |
1422
|
|
|
|
|
|
|
available for transmission. After all buffered bytes have |
1423
|
|
|
|
|
|
|
been sent, the RTS line will be low. |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
fAbortOnError - Specifies whether read and write operations are |
1426
|
|
|
|
|
|
|
terminated if an error occurs. If this member is 1, the driver |
1427
|
|
|
|
|
|
|
terminates all read and write operations with an error status if |
1428
|
|
|
|
|
|
|
an error occurs. (0/1) |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
DCB_XonLim - Specifies the minimum number of bytes allowed in the |
1431
|
|
|
|
|
|
|
input buffer before the XON character is sent. |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
DCB_XoffLim - Specifies the maximum number of bytes allowed in the |
1434
|
|
|
|
|
|
|
input buffer before the XOFF character is sent. The maximum |
1435
|
|
|
|
|
|
|
number of bytes allowed is calculated by subtracting this value |
1436
|
|
|
|
|
|
|
from the size, in bytes, of the input buffer. |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
DCB_ByteSize - Specifies the number of bits in the bytes transmitted |
1439
|
|
|
|
|
|
|
and received. |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
DCB_Parity - Specifies the parity scheme to be used. This member |
1442
|
|
|
|
|
|
|
can be one of the following values: |
1443
|
|
|
|
|
|
|
"No parity", "Odd", "Even", "Mark", "Space" |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
DCB_StopBits - Specifies the number of stop bits to be used. |
1446
|
|
|
|
|
|
|
This member can be one of the following values: |
1447
|
|
|
|
|
|
|
0 - 1 stop bit |
1448
|
|
|
|
|
|
|
1 - 1.5 stop bits |
1449
|
|
|
|
|
|
|
2 - 2 stop bits |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
DCB_XonChar - Specifies the value of the XON character for both |
1452
|
|
|
|
|
|
|
transmission and reception. |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
DCB_XoffChar - Specifies the value of the XOFF character for both |
1455
|
|
|
|
|
|
|
transmission and reception. |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
DCB_ErrorChar - Specifies the value of the character used to replace |
1458
|
|
|
|
|
|
|
bytes received with a parity error. |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
DCB_EofChar - Specifies the value of the character used to signal |
1461
|
|
|
|
|
|
|
the end of data. |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
DCB_EvtChar - Specifies the value of the character used to signal |
1464
|
|
|
|
|
|
|
an event. |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
Manipulating these flags is described in C section. |
1468
|
|
|
|
|
|
|
(not implemented yet). |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
The function croaks if C<$entry> does not exist. |
1471
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
=cut |
1474
|
|
|
|
|
|
|
|
1475
|
|
|
|
|
|
|
#================================== |
1476
|
|
|
|
|
|
|
sub RasGetEntryDevProperties ($) { |
1477
|
|
|
|
|
|
|
#================================== |
1478
|
0
|
|
|
0
|
|
|
my $entry = shift; |
1479
|
0
|
|
|
|
|
|
local $_; |
1480
|
0
|
|
|
|
|
|
$LastError = 0; |
1481
|
|
|
|
|
|
|
|
1482
|
0
|
0
|
|
|
|
|
my ($RASENTRY, $lpbDeviceInfo) = RasGetEntryProperties($entry) or return; |
1483
|
0
|
|
|
|
|
|
my $props = RasBuildEntryProperties($entry, $RASENTRY, $lpbDeviceInfo); |
1484
|
|
|
|
|
|
|
|
1485
|
0
|
|
|
|
|
|
my $devOptions = { |
1486
|
|
|
|
|
|
|
name => $entry, |
1487
|
|
|
|
|
|
|
DeviceName => $props->{DeviceName}, |
1488
|
|
|
|
|
|
|
DeviceType => $props->{DeviceType}, |
1489
|
|
|
|
|
|
|
}; |
1490
|
0
|
0
|
|
|
|
|
return unless $lpbDeviceInfo; |
1491
|
|
|
|
|
|
|
# MS Unimodem driver |
1492
|
0
|
|
|
|
|
|
my ($DEVCFGHDR, $COMMCONFIG) = |
1493
|
|
|
|
|
|
|
(substr($lpbDeviceInfo, 0,12), substr($lpbDeviceInfo, 12)); |
1494
|
|
|
|
|
|
|
|
1495
|
0
|
|
|
|
|
|
my ($dwSize1, |
1496
|
|
|
|
|
|
|
$dwVersion, |
1497
|
|
|
|
|
|
|
$fwOptions, |
1498
|
|
|
|
|
|
|
$wWaitBong) = unpack "LLSS", $DEVCFGHDR; |
1499
|
|
|
|
|
|
|
|
1500
|
0
|
0
|
|
|
|
|
return unless $dwVersion == 0x10003; # Unimodem |
1501
|
|
|
|
|
|
|
#open O,">out";binmode O;print O $COMMCONFIG;close O; |
1502
|
|
|
|
|
|
|
#exit; |
1503
|
|
|
|
|
|
|
|
1504
|
0
|
|
|
|
|
|
my ($dwSize2, |
1505
|
|
|
|
|
|
|
$wVersion, |
1506
|
|
|
|
|
|
|
$wReserved, |
1507
|
|
|
|
|
|
|
$DCB, |
1508
|
|
|
|
|
|
|
$dwProviderSubType, |
1509
|
|
|
|
|
|
|
$dwProviderOffset, |
1510
|
|
|
|
|
|
|
$dwProviderSize, |
1511
|
|
|
|
|
|
|
) = unpack "LSS a28 LLL", $COMMCONFIG; |
1512
|
|
|
|
|
|
|
|
1513
|
0
|
0
|
|
|
|
|
return unless $dwProviderSubType == PST_MODEM; |
1514
|
|
|
|
|
|
|
|
1515
|
0
|
|
|
|
|
|
$devOptions->{WaitBong} = $wWaitBong; |
1516
|
0
|
|
|
|
|
|
$devOptions->{Options} = $fwOptions; |
1517
|
0
|
|
|
|
|
|
$devOptions->{OptionsReadable} = []; |
1518
|
|
|
|
|
|
|
|
1519
|
0
|
|
|
|
|
|
for (qw( TERMINAL_PRE TERMINAL_POST MANUAL_DIAL LAUNCH_LIGHTS )) { |
1520
|
|
|
|
|
|
|
|
1521
|
0
|
|
|
|
|
|
(eval "$_") & $fwOptions and |
1522
|
0
|
0
|
|
|
|
|
push @{$devOptions->{OptionsReadable}}, $_; |
1523
|
|
|
|
|
|
|
} |
1524
|
|
|
|
|
|
|
|
1525
|
0
|
|
|
|
|
|
my $MODEMSETTINGS = substr $COMMCONFIG, $dwProviderOffset, $dwProviderSize; |
1526
|
|
|
|
|
|
|
|
1527
|
0
|
|
|
|
|
|
my ( $dwActualSize, # size of returned data, in bytes |
1528
|
|
|
|
|
|
|
$dwRequiredSize, # total size of structure |
1529
|
|
|
|
|
|
|
$dwDevSpecificOffset, # offset of provider-defined data |
1530
|
|
|
|
|
|
|
$dwDevSpecificSize, # size of provider-defined data |
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
# Static local options (read/write) |
1533
|
|
|
|
|
|
|
$dwCallSetupFailTimer, # call setup timeout, in seconds |
1534
|
|
|
|
|
|
|
$dwInactivityTimeout, # inactivity timeout, in tenths of seconds |
1535
|
|
|
|
|
|
|
$dwSpeakerVolume, # speaker volume level |
1536
|
|
|
|
|
|
|
$dwSpeakerMode, # speaker mode |
1537
|
|
|
|
|
|
|
$dwPreferredModemOptions, # bitmap specifying preferred options |
1538
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
# negotiated options (read only) for current or last call |
1540
|
|
|
|
|
|
|
$dwNegotiatedModemOptions, # bitmap specifying actual options |
1541
|
|
|
|
|
|
|
$dwNegotiatedDCERate, # DCE rate, in bits per second |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
# Variable portion for proprietary expansion |
1544
|
|
|
|
|
|
|
# BYTE abVariablePortion[1] |
1545
|
|
|
|
|
|
|
) = unpack "LLLLLLLLLLL", $MODEMSETTINGS; |
1546
|
|
|
|
|
|
|
|
1547
|
0
|
|
|
|
|
|
$devOptions->{CallSetupFailTimer} = $dwCallSetupFailTimer; |
1548
|
0
|
|
|
|
|
|
$devOptions->{InactivityTimeout} = $dwInactivityTimeout; |
1549
|
0
|
|
|
|
|
|
$devOptions->{SpeakerVolume} = (qw(LOW MEDIUM HIGH))[$dwSpeakerVolume]; |
1550
|
0
|
|
|
|
|
|
$devOptions->{SpeakerMode} = (qw(OFF DIAL ON CALLSETUP))[$dwSpeakerMode]; |
1551
|
0
|
|
|
|
|
|
$devOptions->{PreferredModemOptions} = $dwPreferredModemOptions; |
1552
|
0
|
|
|
|
|
|
$devOptions->{PreferredModemOptionsReadable} = []; |
1553
|
0
|
|
|
|
|
|
$devOptions->{NegotiatedModemOptions} = $dwNegotiatedModemOptions; |
1554
|
0
|
|
|
|
|
|
$devOptions->{NegotiatedModemOptionsReadable} = []; |
1555
|
0
|
|
|
|
|
|
$devOptions->{NegotiatedDCERate} = $dwNegotiatedDCERate; |
1556
|
|
|
|
|
|
|
|
1557
|
0
|
|
|
|
|
|
for (qw(COMPRESSION ERROR_CONTROL FORCED_EC |
1558
|
|
|
|
|
|
|
CELLULAR FLOWCONTROL_HARD FLOWCONTROL_SOFT CCITT_OVERRIDE |
1559
|
|
|
|
|
|
|
SPEED_ADJUST TONE_DIAL BLIND_DIAL V23_OVERRIDE)) { |
1560
|
|
|
|
|
|
|
|
1561
|
0
|
|
|
|
|
|
(eval "MDM_$_") & $dwPreferredModemOptions and |
1562
|
0
|
0
|
|
|
|
|
push @{$devOptions->{PreferredModemOptionsReadable}}, $_; |
1563
|
|
|
|
|
|
|
|
1564
|
0
|
|
|
|
|
|
(eval "MDM_$_") & $dwNegotiatedModemOptions and |
1565
|
0
|
0
|
|
|
|
|
push @{$devOptions->{NegotiatedModemOptionsReadable}}, $_; |
1566
|
|
|
|
|
|
|
} |
1567
|
|
|
|
|
|
|
|
1568
|
0
|
|
|
|
|
|
my ( $DCBlength, |
1569
|
|
|
|
|
|
|
$BaudRate, # current baud rate |
1570
|
|
|
|
|
|
|
$Flags, |
1571
|
|
|
|
|
|
|
$wReserved2, # not currently used |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
$XonLim, # transmit XON threshold |
1574
|
|
|
|
|
|
|
$XoffLim, # transmit XOFF threshold |
1575
|
|
|
|
|
|
|
$ByteSize, # number of bits/byte, 4-8 |
1576
|
|
|
|
|
|
|
$Parity, # 0-4=no,odd,even,mark,space |
1577
|
|
|
|
|
|
|
$StopBits, # 0,1,2 = 1, 1.5, 2 |
1578
|
|
|
|
|
|
|
$XonChar, # Tx and Rx XON character |
1579
|
|
|
|
|
|
|
$XoffChar, # Tx and Rx XOFF character |
1580
|
|
|
|
|
|
|
$ErrorChar, # error replacement character |
1581
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
$EofChar, # end of input character |
1583
|
|
|
|
|
|
|
$EvtChar, # received event character |
1584
|
|
|
|
|
|
|
$wReserved1, |
1585
|
|
|
|
|
|
|
) = unpack "LLLSSSCCCaaaaaS", $DCB; |
1586
|
|
|
|
|
|
|
|
1587
|
0
|
|
|
|
|
|
my @temp = ( |
1588
|
|
|
|
|
|
|
"fBinary:1", # binary mode, no EOF check |
1589
|
|
|
|
|
|
|
"fParity:1", # enable parity checking |
1590
|
|
|
|
|
|
|
"fOutxCtsFlow:1", # CTS output flow control |
1591
|
|
|
|
|
|
|
"fOutxDsrFlow:1", # DSR output flow control |
1592
|
|
|
|
|
|
|
"fDtrControl:2", # DTR flow control type |
1593
|
|
|
|
|
|
|
"fDsrSensitivity:1", # DSR sensitivity |
1594
|
|
|
|
|
|
|
|
1595
|
|
|
|
|
|
|
"fTXContinueOnXoff:1", # XOFF continues Tx |
1596
|
|
|
|
|
|
|
"fOutX:1", # XON/XOFF out flow control |
1597
|
|
|
|
|
|
|
"fInX:1", # XON/XOFF in flow control |
1598
|
|
|
|
|
|
|
"fErrorChar:1", # enable error replacement |
1599
|
|
|
|
|
|
|
"fNull:1", # enable null stripping |
1600
|
|
|
|
|
|
|
"fRtsControl:2", # RTS flow control |
1601
|
|
|
|
|
|
|
"fAbortOnError:1", # abort reads/writes on error |
1602
|
|
|
|
|
|
|
# "fDummy2:17", # reserved |
1603
|
|
|
|
|
|
|
); |
1604
|
|
|
|
|
|
|
|
1605
|
0
|
|
|
|
|
|
my $BFlags = reverse unpack "B32",reverse pack "L",$Flags; |
1606
|
|
|
|
|
|
|
#print "$BFlags\n"; |
1607
|
0
|
|
|
|
|
|
my $pos = 0; |
1608
|
|
|
|
|
|
|
|
1609
|
0
|
|
|
|
|
|
for (0..$#temp) { |
1610
|
0
|
|
|
|
|
|
my($k,$v) = $temp[$_] =~ /^(.+):(\d+)$/; |
1611
|
0
|
|
|
|
|
|
my $b = substr($BFlags, $pos, $v); $pos+=$v; |
|
0
|
|
|
|
|
|
|
1612
|
|
|
|
|
|
|
# $devOptions->{"DCB_$k"} = ord pack "B8", substr("00000000".$b, -8); |
1613
|
0
|
|
|
|
|
|
$temp[$_] = "$k:".ord pack "B8", substr("00000000".$b, -8); |
1614
|
|
|
|
|
|
|
|
1615
|
|
|
|
|
|
|
} |
1616
|
|
|
|
|
|
|
|
1617
|
0
|
|
|
|
|
|
$devOptions->{"DCB_FlagsReadable"} = \@temp; |
1618
|
|
|
|
|
|
|
|
1619
|
0
|
|
|
|
|
|
my $caller = (caller(1))[3]; |
1620
|
|
|
|
|
|
|
|
1621
|
0
|
|
|
|
|
|
for (qw(BaudRate Flags XonLim XoffLim ByteSize Parity StopBits |
1622
|
|
|
|
|
|
|
XonChar XoffChar ErrorChar EofChar EvtChar)) { |
1623
|
|
|
|
|
|
|
|
1624
|
0
|
0
|
0
|
|
|
|
$devOptions->{"DCB_$_"} = |
1625
|
|
|
|
|
|
|
/Char$/ && $caller =~ /RasPrintEntryDevProperties/ |
1626
|
|
|
|
|
|
|
? sprintf("0x%2.2X", ord eval "\$$_") : eval "\$$_"; |
1627
|
|
|
|
|
|
|
} |
1628
|
|
|
|
|
|
|
|
1629
|
0
|
|
|
|
|
|
$devOptions->{DCB_Parity} = |
1630
|
|
|
|
|
|
|
("No parity", "Odd", "Even", "Mark", "Space")[$devOptions->{DCB_Parity}]; |
1631
|
|
|
|
|
|
|
|
1632
|
0
|
|
|
|
|
|
$devOptions; |
1633
|
|
|
|
|
|
|
} |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
=item RasPrintEntryDevProperties ( ) |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
This function provides nice printing of a phonebook entry device properties |
1638
|
|
|
|
|
|
|
if this entry uses MS Unimodem compartible TSP (Telephone Service Provider) or |
1639
|
|
|
|
|
|
|
in other words - Unimodem compartible driver, on Win95 - always. |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
Look at the C section and Win32 SDK |
1642
|
|
|
|
|
|
|
for more info. |
1643
|
|
|
|
|
|
|
|
1644
|
|
|
|
|
|
|
Char values (XonChar, XoffChar, ErrorChar, EofChar, EvtChar) are printed |
1645
|
|
|
|
|
|
|
in hexadecimal form like 0x13. |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
For debugging, for fun etc. |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
RasPrintEntryDevProperties( $entry ); |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
1652
|
|
|
|
|
|
|
|
1653
|
|
|
|
|
|
|
Croaks if C<$entry> does not exist. Silently returns if the device is not |
1654
|
|
|
|
|
|
|
Unimodem-compartible. |
1655
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
=cut |
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
#==================== |
1659
|
|
|
|
|
|
|
sub RasPrintEntryDevProperties ($) { |
1660
|
|
|
|
|
|
|
#==================== |
1661
|
0
|
|
|
0
|
|
|
my $entry = shift; |
1662
|
0
|
|
|
|
|
|
$LastError = 0; |
1663
|
|
|
|
|
|
|
|
1664
|
0
|
0
|
|
|
|
|
my $props = RasGetEntryDevProperties($entry) or return; |
1665
|
|
|
|
|
|
|
|
1666
|
0
|
|
|
|
|
|
print "RAS/DUN entry: $entry\n\n"; |
1667
|
|
|
|
|
|
|
|
1668
|
0
|
|
|
|
|
|
for my $p(sort keys %$props) { |
1669
|
0
|
0
|
|
|
|
|
next if $p eq "name"; |
1670
|
0
|
0
|
|
|
|
|
if (! ref $props->{$p}) { |
1671
|
0
|
|
|
|
|
|
printf "%30s: %s\n", $p, $props->{$p}; |
1672
|
|
|
|
|
|
|
} else { |
1673
|
0
|
0
|
|
|
|
|
printf "%30s: %s\n", $p, @{$props->{$p}} ? $props->{$p}->[0] : ""; |
|
0
|
|
|
|
|
|
|
1674
|
0
|
|
|
|
|
|
map {printf "%30s %s\n", "",$_} @{$props->{$p}}[1..$#{$props->{$p}}]; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
} |
1676
|
|
|
|
|
|
|
} |
1677
|
0
|
|
|
|
|
|
1; |
1678
|
|
|
|
|
|
|
} |
1679
|
|
|
|
|
|
|
|
1680
|
|
|
|
|
|
|
=item RasCopyEntry ( ) |
1681
|
|
|
|
|
|
|
|
1682
|
|
|
|
|
|
|
This function makes a copy of the existing RAS entry. |
1683
|
|
|
|
|
|
|
Some properties of this newly created entry could then be changed with the use |
1684
|
|
|
|
|
|
|
of C. In previous versions of the |
1685
|
|
|
|
|
|
|
module it was the only way to create a new entry silently, programmatically. But |
1686
|
|
|
|
|
|
|
as of 0.07 we have full featured C. |
1687
|
|
|
|
|
|
|
|
1688
|
|
|
|
|
|
|
You can also create new entry via dialog, see C. |
1689
|
|
|
|
|
|
|
|
1690
|
|
|
|
|
|
|
RasCopyEntry( $oldname, $newname ); |
1691
|
|
|
|
|
|
|
|
1692
|
|
|
|
|
|
|
Croaks if C<$oldname> does not exist or C<$newname> already exists. |
1693
|
|
|
|
|
|
|
You should call C or C before to verify both. |
1694
|
|
|
|
|
|
|
|
1695
|
|
|
|
|
|
|
C<$newname> must contain at least one non-white-space alphanumeric character |
1696
|
|
|
|
|
|
|
and cannot begin with a period ("."). |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
Username, password etc. (see C |
1699
|
|
|
|
|
|
|
and C) are not copied |
1700
|
|
|
|
|
|
|
to the newly created entry. |
1701
|
|
|
|
|
|
|
|
1702
|
|
|
|
|
|
|
=cut |
1703
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
#====================== |
1705
|
|
|
|
|
|
|
sub RasCopyEntry ($$) { |
1706
|
|
|
|
|
|
|
#====================== |
1707
|
|
|
|
|
|
|
# NB! country code is not TAPI countryID |
1708
|
0
|
|
|
0
|
|
|
my ($old, $new) = @_; |
1709
|
0
|
|
|
|
|
|
$LastError = 0; |
1710
|
|
|
|
|
|
|
|
1711
|
0
|
0
|
|
|
|
|
IsEntry($old) or RASCROAK "`$old' entry not found"; |
1712
|
0
|
0
|
|
|
|
|
IsEntry($new) and RASCROAK "`$new' entry already exists"; |
1713
|
|
|
|
|
|
|
|
1714
|
0
|
|
0
|
|
|
|
$RasSetEntryProperties ||= new("rasapi32", "RasSetEntryProperties", [P,P,P,N,P,N], N); |
1715
|
|
|
|
|
|
|
|
1716
|
0
|
0
|
|
|
|
|
my ($tagRASENTRY, $lpbDI) = RasGetEntryProperties($old) or return; |
1717
|
|
|
|
|
|
|
|
1718
|
0
|
|
0
|
|
|
|
my $ret = $RasSetEntryProperties->Call($PHONEBOOK||0, $new, $tagRASENTRY, |
1719
|
|
|
|
|
|
|
length($tagRASENTRY), $lpbDI, length $lpbDI); |
1720
|
|
|
|
|
|
|
|
1721
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
1722
|
0
|
|
|
|
|
|
1; |
1723
|
|
|
|
|
|
|
} |
1724
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
=item RasSetEntryProperties ( ) |
1726
|
|
|
|
|
|
|
|
1727
|
|
|
|
|
|
|
This function changes the connection information for an existing entry. |
1728
|
|
|
|
|
|
|
|
1729
|
|
|
|
|
|
|
RasSetEntryProperties( $props ); |
1730
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
$props - reference to hash with replacing properties |
1732
|
|
|
|
|
|
|
|
1733
|
|
|
|
|
|
|
Mainly keys/values of the %$props hash are described in the |
1734
|
|
|
|
|
|
|
C |
1735
|
|
|
|
|
|
|
section. But here we can use just part of the full hash - if keys are |
1736
|
|
|
|
|
|
|
undefined no changes will be made to the corresponding properties. Only |
1737
|
|
|
|
|
|
|
$props->{name} has to contain a name of the existing phonebook entry, all other |
1738
|
|
|
|
|
|
|
keys are optional. |
1739
|
|
|
|
|
|
|
|
1740
|
|
|
|
|
|
|
Those properties that do exist in %$props will replace current properties. |
1741
|
|
|
|
|
|
|
If $props->{some-key} is defined and empty ("") the corresponding property |
1742
|
|
|
|
|
|
|
will be empty. |
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
C, C, C and |
1745
|
|
|
|
|
|
|
C keys are not used by this function. Anyway, all |
1746
|
|
|
|
|
|
|
unneeded keys will be ignored without any errors. |
1747
|
|
|
|
|
|
|
|
1748
|
|
|
|
|
|
|
As of the version 0.07 you B change the RAS device using with |
1749
|
|
|
|
|
|
|
the entry by specifying the new device name in $props->{DeviceName}. |
1750
|
|
|
|
|
|
|
The function finds the device type internally, so $props->{DeviceType} |
1751
|
|
|
|
|
|
|
is ignored if specified. |
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
If "DeviceName" key is present in the C<%$props> |
1754
|
|
|
|
|
|
|
the function resets device properties for C<$props->{name}> entry to the |
1755
|
|
|
|
|
|
|
default values (for the list of device properties see |
1756
|
|
|
|
|
|
|
C). C function gives the |
1757
|
|
|
|
|
|
|
RAS-capable devices enumeration. |
1758
|
|
|
|
|
|
|
|
1759
|
|
|
|
|
|
|
B: With multiple modems installed under |
1760
|
|
|
|
|
|
|
Windows NT 4.0, the RasSetEntryProperties |
1761
|
|
|
|
|
|
|
API function calls will reset the selected modem to the first available modem. |
1762
|
|
|
|
|
|
|
This problem has been corrected in the latest U.S. Service Pack (4). |
1763
|
|
|
|
|
|
|
|
1764
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
Print the whole enumeraton like this: |
1766
|
|
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
%devices = RasEnumDevices() or die "Error"; |
1768
|
|
|
|
|
|
|
print map "\"$_\" of type \"$devices{$_}\"\n", keys %devices; |
1769
|
|
|
|
|
|
|
|
1770
|
|
|
|
|
|
|
In addition to the keys decribed in the C |
1771
|
|
|
|
|
|
|
section the string value |
1772
|
|
|
|
|
|
|
$props->{newFlags} can be used for adding/removing the existing flags |
1773
|
|
|
|
|
|
|
within the RAS-entry. |
1774
|
|
|
|
|
|
|
|
1775
|
|
|
|
|
|
|
This string has the format: " ..." (any C<\s> separators are possible) |
1776
|
|
|
|
|
|
|
|
1777
|
|
|
|
|
|
|
Each token can be one of the following values (same as mnemonic flags |
1778
|
|
|
|
|
|
|
described in the C section): |
1779
|
|
|
|
|
|
|
|
1780
|
|
|
|
|
|
|
UseCountryAndAreaCodes |
1781
|
|
|
|
|
|
|
SpecificIpAddr |
1782
|
|
|
|
|
|
|
SpecificNameServers |
1783
|
|
|
|
|
|
|
IpHeaderCompression |
1784
|
|
|
|
|
|
|
RemoteDefaultGateway |
1785
|
|
|
|
|
|
|
DisableLcpExtensions |
1786
|
|
|
|
|
|
|
TerminalBeforeDial |
1787
|
|
|
|
|
|
|
TerminalAfterDial |
1788
|
|
|
|
|
|
|
ModemLights |
1789
|
|
|
|
|
|
|
SwCompression |
1790
|
|
|
|
|
|
|
RequireEncryptedPw |
1791
|
|
|
|
|
|
|
RequireMsEncryptedPw |
1792
|
|
|
|
|
|
|
RequireDataEncryption |
1793
|
|
|
|
|
|
|
NetworkLogon |
1794
|
|
|
|
|
|
|
UseLogonCredentials |
1795
|
|
|
|
|
|
|
PromoteAlternates |
1796
|
|
|
|
|
|
|
SecureLocalFiles |
1797
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
These strings are just the meaningful parts of C constants' names |
1799
|
|
|
|
|
|
|
(from "ras.h" file). They are rather descriptive, you can easily find |
1800
|
|
|
|
|
|
|
their meaning by changing and printing an existing RAS entry. Not |
1801
|
|
|
|
|
|
|
all of them will work in this version of the module. |
1802
|
|
|
|
|
|
|
|
1803
|
|
|
|
|
|
|
Each of these flags could be used with or without the "RASEO_" prefix. |
1804
|
|
|
|
|
|
|
With or without |
1805
|
|
|
|
|
|
|
`+' or `-' prefix (no blanks between [+-] and "mnemonic flag") - this |
1806
|
|
|
|
|
|
|
is the token mentioned above. |
1807
|
|
|
|
|
|
|
|
1808
|
|
|
|
|
|
|
Additional token that can't be prefixed with `+' or `-' is "KeepOldFlags", |
1809
|
|
|
|
|
|
|
it still can be prefixed with "RASEO_". |
1810
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
If this new flag-string ($props->{newFlags}) is C the default action |
1812
|
|
|
|
|
|
|
is to reset all old flags. "KeepOldFlags" prevents from this cleanup. |
1813
|
|
|
|
|
|
|
|
1814
|
|
|
|
|
|
|
The token with `-' will reset the corresponding flag if it was set, otherwise - |
1815
|
|
|
|
|
|
|
no effect. The token with `+' will set the corresponding flag if it was not |
1816
|
|
|
|
|
|
|
set, otherwise - no effect. The order of tokens is not important, tokens are |
1817
|
|
|
|
|
|
|
separated by any number of blanks. Token without `+' or `-' means `+'. |
1818
|
|
|
|
|
|
|
|
1819
|
|
|
|
|
|
|
Examples: |
1820
|
|
|
|
|
|
|
|
1821
|
|
|
|
|
|
|
C<"NetworkLogon +SwCompression"> - reset old flags and add these two. |
1822
|
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
C<"-NetworkLogon -SwCompression KeepOldFlags"> - keep old flags and clean these two. |
1824
|
|
|
|
|
|
|
|
1825
|
|
|
|
|
|
|
The function croaks if C<$entry> does not exist and on some impossible |
1826
|
|
|
|
|
|
|
values of the parameters. |
1827
|
|
|
|
|
|
|
|
1828
|
|
|
|
|
|
|
B (Point to Point Tunneling Protocol): |
1829
|
|
|
|
|
|
|
You can use an ip-address in place of LocalPhoneNumber if your DUN/RAS entry |
1830
|
|
|
|
|
|
|
is configured to work with VPN (Virtual Private Networking) via PPTP. |
1831
|
|
|
|
|
|
|
PPTP appears as a new modem type that can be selected in DUN entry only manually. |
1832
|
|
|
|
|
|
|
It DeviceName is "Microsoft VPN Adapter" and DeviceType is "vpn". |
1833
|
|
|
|
|
|
|
In this case you can change the ip-address of the |
1834
|
|
|
|
|
|
|
VPN-host as if it were local phone number. For example |
1835
|
|
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
RasSetEntryProperties({ |
1837
|
|
|
|
|
|
|
name=>"NEV5", |
1838
|
|
|
|
|
|
|
LocalPhoneNumber=>"21.100.14.12", |
1839
|
|
|
|
|
|
|
}); |
1840
|
|
|
|
|
|
|
|
1841
|
|
|
|
|
|
|
You can get info about VPN and PPTP at |
1842
|
|
|
|
|
|
|
|
1843
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/q154/0/91.asp |
1844
|
|
|
|
|
|
|
|
1845
|
|
|
|
|
|
|
DUN 1.3 that supports VPN is downloadable from |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
http://support.microsoft.com/download/support/mslfiles/MSDUN13.EXE |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
and is described here |
1850
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/q194/4/77.asp |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
Thanks to Carl Sewell C<<>csewell@hiwaay.netC<>> for his explanations |
1855
|
|
|
|
|
|
|
and testing of VPN features. |
1856
|
|
|
|
|
|
|
|
1857
|
|
|
|
|
|
|
B |
1858
|
|
|
|
|
|
|
After applying Service Pack 2, the RasSetEntryProperties flags for |
1859
|
|
|
|
|
|
|
RASEO_TerminalAfterDial and RASEO_TerminalBeforeDial specified in |
1860
|
|
|
|
|
|
|
the Win32 function call are not set. This problem occurs because |
1861
|
|
|
|
|
|
|
Service Pack 2 causes the parameters to be ignored. |
1862
|
|
|
|
|
|
|
This problem has been corrected in Service Pack 3. |
1863
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
http://support.microsoft.com/support/ntserver/serviceware/nts40/E9MSL2CSA.ASP |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
B When using the RasSetEntryProperties API call to change the connection |
1867
|
|
|
|
|
|
|
information for an entry in the phone book or create a new phone-book entry, |
1868
|
|
|
|
|
|
|
the szScript (C<$props->{Script}> in C) parameter of the RASENTRY |
1869
|
|
|
|
|
|
|
structure is not always preserved. |
1870
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
http://support.microsoft.com/support/kb/articles/q160/1/90.asp |
1872
|
|
|
|
|
|
|
|
1873
|
|
|
|
|
|
|
This problem applies to WinNT 4.0 and was corrected in the latest |
1874
|
|
|
|
|
|
|
Microsoft Windows NT 4.0 U.S. Service Pack (4). |
1875
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
The function croaks if the specfied device is not found. |
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
=cut |
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
#====================== |
1881
|
|
|
|
|
|
|
sub RasSetEntryProperties ($) { |
1882
|
|
|
|
|
|
|
#====================== |
1883
|
0
|
|
|
0
|
|
|
my $props = shift; |
1884
|
0
|
|
|
|
|
|
$LastError = 0; |
1885
|
|
|
|
|
|
|
|
1886
|
0
|
0
|
|
|
|
|
ref($props) eq "HASH" or RASCROAK "argument is not a hash-reference"; |
1887
|
|
|
|
|
|
|
|
1888
|
0
|
0
|
|
|
|
|
$props->{name} or RASCROAK "\$props->{name} hash key does not exist"; |
1889
|
|
|
|
|
|
|
|
1890
|
0
|
0
|
|
|
|
|
IsEntry($props->{name}) or |
1891
|
|
|
|
|
|
|
RASCROAK "\$props->{name}==`$props->{name}' is not an existing entry"; |
1892
|
|
|
|
|
|
|
|
1893
|
0
|
0
|
|
|
|
|
my ($RASENTRY, $lpbDeviceInfo) = |
1894
|
|
|
|
|
|
|
RasGetEntryProperties($props->{name}) or return; |
1895
|
|
|
|
|
|
|
|
1896
|
|
|
|
|
|
|
# if ($props->{DeviceName}) { |
1897
|
|
|
|
|
|
|
# my $COMMCONFIG = GetDefaultCommConfig($props->{DeviceName}) or return; |
1898
|
|
|
|
|
|
|
# |
1899
|
|
|
|
|
|
|
# my $dwDeviceInfoSize = 12 + length $COMMCONFIG; |
1900
|
|
|
|
|
|
|
# my $DEVCFGHDR = pack "LLSS", $dwDeviceInfoSize, 0x00010003, 8, 10; |
1901
|
|
|
|
|
|
|
# $lpbDeviceInfo = $DEVCFGHDR.$COMMCONFIG; |
1902
|
|
|
|
|
|
|
# } |
1903
|
|
|
|
|
|
|
|
1904
|
0
|
|
|
|
|
|
$RASENTRY = ParseRASENTRY($props, $RASENTRY); |
1905
|
|
|
|
|
|
|
|
1906
|
0
|
|
0
|
|
|
|
$RasSetEntryProperties ||= new("rasapi32", "RasSetEntryProperties", [P,P,P,N,P,N], N); |
1907
|
|
|
|
|
|
|
|
1908
|
0
|
|
|
|
|
|
my $ret; |
1909
|
|
|
|
|
|
|
|
1910
|
0
|
0
|
|
|
|
|
unless ($props->{DeviceName}) { |
1911
|
0
|
|
0
|
|
|
|
$ret = $RasSetEntryProperties->Call($PHONEBOOK||0, |
1912
|
|
|
|
|
|
|
$props->{name}, $RASENTRY, length($RASENTRY), |
1913
|
|
|
|
|
|
|
$lpbDeviceInfo, length $lpbDeviceInfo); |
1914
|
|
|
|
|
|
|
|
1915
|
|
|
|
|
|
|
#print "ret1:$ret\n"; |
1916
|
|
|
|
|
|
|
} else { |
1917
|
0
|
|
0
|
|
|
|
$ret = $RasSetEntryProperties->Call($PHONEBOOK||0, |
1918
|
|
|
|
|
|
|
$props->{name}, $RASENTRY, length($RASENTRY),0,0); |
1919
|
|
|
|
|
|
|
#print "ret2:$ret\n"; |
1920
|
|
|
|
|
|
|
|
1921
|
0
|
0
|
|
|
|
|
my ($RASENTRY1, $lpbDeviceInfo1) = |
1922
|
|
|
|
|
|
|
RasGetEntryProperties($props->{name}) or return; |
1923
|
|
|
|
|
|
|
#print "New lpbDeviceInfo size:".length($lpbDeviceInfo1)."\n"; |
1924
|
|
|
|
|
|
|
|
1925
|
0
|
|
0
|
|
|
|
$ret = $RasSetEntryProperties->Call($PHONEBOOK||0, |
1926
|
|
|
|
|
|
|
$props->{name}, $RASENTRY, length($RASENTRY), |
1927
|
|
|
|
|
|
|
$lpbDeviceInfo1, length $lpbDeviceInfo1); |
1928
|
|
|
|
|
|
|
#print "ret3:$ret\n"; |
1929
|
|
|
|
|
|
|
} |
1930
|
|
|
|
|
|
|
|
1931
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
1932
|
0
|
|
|
|
|
|
1; |
1933
|
|
|
|
|
|
|
} |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
=item RasCreateEntry ( ) |
1936
|
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
This function creates RAS/DUN entry programmatically (note that |
1938
|
|
|
|
|
|
|
C displays dialo boxes). |
1939
|
|
|
|
|
|
|
|
1940
|
|
|
|
|
|
|
RasCreateEntry( $props ); |
1941
|
|
|
|
|
|
|
|
1942
|
|
|
|
|
|
|
C defines the phonebook in which the new entry will |
1943
|
|
|
|
|
|
|
be created (WinNT). |
1944
|
|
|
|
|
|
|
|
1945
|
|
|
|
|
|
|
For the explanation of the C<%$props> hash see the previous C |
1946
|
|
|
|
|
|
|
function. The main difference is that these keys |
1947
|
|
|
|
|
|
|
|
1948
|
|
|
|
|
|
|
name, LocalPhoneNumber, NetProtocols, FramingProtocol, DeviceName |
1949
|
|
|
|
|
|
|
|
1950
|
|
|
|
|
|
|
are mandatory in this hash. |
1951
|
|
|
|
|
|
|
|
1952
|
|
|
|
|
|
|
You have to specify at least one of CountryID and CountryCode keys and AreaCode |
1953
|
|
|
|
|
|
|
key if C<$props->{newFlags}> contains "+UseCountryAndAreaCodes". |
1954
|
|
|
|
|
|
|
|
1955
|
|
|
|
|
|
|
All ip-addresses if omitted are assumed to be "0.0.0.0". Empty or non-existing |
1956
|
|
|
|
|
|
|
C<$props->{newFlags}> gives zero numeric flag which means that none of the |
1957
|
|
|
|
|
|
|
C options are in use. Flag "KeepOldFlags" has no meaning but makes |
1958
|
|
|
|
|
|
|
no error. |
1959
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
Note that the device settings would be copied from your system defaults and |
1961
|
|
|
|
|
|
|
some minor features still could not be customized (see C). |
1962
|
|
|
|
|
|
|
|
1963
|
|
|
|
|
|
|
=cut |
1964
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
#====================== |
1966
|
|
|
|
|
|
|
sub RasCreateEntry ($) { |
1967
|
|
|
|
|
|
|
#====================== |
1968
|
0
|
|
|
0
|
|
|
my $props = shift; |
1969
|
0
|
|
|
|
|
|
local $_; |
1970
|
0
|
|
|
|
|
|
$LastError = 0; |
1971
|
|
|
|
|
|
|
|
1972
|
0
|
0
|
|
|
|
|
ref($props) eq "HASH" or RASCROAK "argument is not a hash-reference"; |
1973
|
|
|
|
|
|
|
|
1974
|
0
|
0
|
|
|
|
|
$props->{name} or RASCROAK "\$props->{name} hash key does not exist"; |
1975
|
|
|
|
|
|
|
|
1976
|
0
|
0
|
|
|
|
|
IsEntry($props->{name}) and |
1977
|
|
|
|
|
|
|
RASCROAK "\$props->{name}==`$props->{name}' entry already exists"; |
1978
|
|
|
|
|
|
|
|
1979
|
0
|
|
|
|
|
|
my @mandatory = qw(name LocalPhoneNumber NetProtocols FramingProtocol DeviceName); |
1980
|
|
|
|
|
|
|
|
1981
|
0
|
|
|
|
|
|
for (@mandatory) { |
1982
|
0
|
0
|
|
|
|
|
exists $props->{$_} or |
1983
|
|
|
|
|
|
|
RASCROAK "\$props->{$_} mandatory key does not exist"; |
1984
|
0
|
0
|
|
|
|
|
$props->{$_} or |
1985
|
|
|
|
|
|
|
RASCROAK "\$props->{$_} is empty"; |
1986
|
|
|
|
|
|
|
} |
1987
|
|
|
|
|
|
|
|
1988
|
0
|
|
|
|
|
|
my $RASENTRY = ParseRASENTRY($props); |
1989
|
|
|
|
|
|
|
# my $COMMCONFIG = GetDefaultCommConfig($props->{DeviceName}) or return; |
1990
|
|
|
|
|
|
|
# |
1991
|
|
|
|
|
|
|
# my $dwDeviceInfoSize = 12 + length $COMMCONFIG; |
1992
|
|
|
|
|
|
|
# my $DEVCFGHDR = pack "LLSS", $dwDeviceInfoSize, 0x00010003, 8, 10; |
1993
|
|
|
|
|
|
|
# my $lpbDeviceInfo = $DEVCFGHDR.$COMMCONFIG; |
1994
|
|
|
|
|
|
|
|
1995
|
0
|
|
0
|
|
|
|
$RasSetEntryProperties ||= new("rasapi32", "RasSetEntryProperties", [P,P,P,N,P,N], N); |
1996
|
|
|
|
|
|
|
|
1997
|
0
|
|
0
|
|
|
|
my $ret = $RasSetEntryProperties->Call($PHONEBOOK||0, |
1998
|
|
|
|
|
|
|
$props->{name}, $RASENTRY, length($RASENTRY),0,0); |
1999
|
|
|
|
|
|
|
|
2000
|
|
|
|
|
|
|
#print "ret1:$ret\n"; |
2001
|
|
|
|
|
|
|
|
2002
|
0
|
|
|
|
|
|
my($RASENTRY1, $lpbDeviceInfo) = RasGetEntryProperties($props->{name}); |
2003
|
|
|
|
|
|
|
|
2004
|
|
|
|
|
|
|
#print "lpbDeviceInfo size:".length($lpbDeviceInfo)."\n"; |
2005
|
|
|
|
|
|
|
|
2006
|
0
|
|
0
|
|
|
|
$ret = $RasSetEntryProperties->Call($PHONEBOOK||0, |
2007
|
|
|
|
|
|
|
$props->{name}, $RASENTRY, length($RASENTRY), |
2008
|
|
|
|
|
|
|
$lpbDeviceInfo, length $lpbDeviceInfo); |
2009
|
|
|
|
|
|
|
|
2010
|
|
|
|
|
|
|
#print "ret2:$ret\n"; |
2011
|
|
|
|
|
|
|
|
2012
|
|
|
|
|
|
|
|
2013
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
2014
|
0
|
|
|
|
|
|
1; |
2015
|
|
|
|
|
|
|
} |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
|
2018
|
|
|
|
|
|
|
#====================== |
2019
|
|
|
|
|
|
|
sub ParseRASENTRY ($;$) { |
2020
|
|
|
|
|
|
|
#====================== |
2021
|
0
|
|
|
0
|
|
|
my ($props, $RASENTRY) = @_; |
2022
|
0
|
|
|
|
|
|
my ($NP, $FP, $newFlags); |
2023
|
0
|
|
|
|
|
|
my $pat = HOSTNUMBER(); |
2024
|
0
|
|
|
|
|
|
local $_; |
2025
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
|
2027
|
0
|
|
|
|
|
|
my ($entry, $Flags, $CountryID, $CountryCode, $AreaCode, $LocalPhoneNumber, |
2028
|
|
|
|
|
|
|
$NetProtocols, $FramingProtocol, $Script, $DeviceName) = |
2029
|
|
|
|
|
|
|
map $props->{$_}, qw( |
2030
|
|
|
|
|
|
|
name newFlags CountryID CountryCode AreaCode LocalPhoneNumber |
2031
|
|
|
|
|
|
|
NetProtocols FramingProtocol Script DeviceName |
2032
|
|
|
|
|
|
|
); |
2033
|
|
|
|
|
|
|
|
2034
|
|
|
|
|
|
|
|
2035
|
0
|
0
|
|
|
|
|
($RASENTRY) = InitializeRASENTRY() unless $RASENTRY; |
2036
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
my ( |
2038
|
0
|
|
|
|
|
|
$dwSize, |
2039
|
|
|
|
|
|
|
$dwfOptions, |
2040
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
$dwCountryID, |
2042
|
|
|
|
|
|
|
$dwCountryCode, |
2043
|
|
|
|
|
|
|
$szAreaCode, |
2044
|
|
|
|
|
|
|
$szLocalPhoneNumber, |
2045
|
|
|
|
|
|
|
$dwAlternateOffset, |
2046
|
|
|
|
|
|
|
|
2047
|
|
|
|
|
|
|
$ipaddr, |
2048
|
|
|
|
|
|
|
$ipaddrDns, |
2049
|
|
|
|
|
|
|
$ipaddrDnsAlt, |
2050
|
|
|
|
|
|
|
$ipaddrWins, |
2051
|
|
|
|
|
|
|
$ipaddrWinsAlt, |
2052
|
|
|
|
|
|
|
|
2053
|
|
|
|
|
|
|
$dwFrameSize, |
2054
|
|
|
|
|
|
|
$dwfNetProtocols, |
2055
|
|
|
|
|
|
|
$dwFramingProtocol, |
2056
|
|
|
|
|
|
|
$szScript, |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
$szAutodialDll, |
2059
|
|
|
|
|
|
|
$szAutodialFunc, |
2060
|
|
|
|
|
|
|
|
2061
|
|
|
|
|
|
|
$szDeviceType, |
2062
|
|
|
|
|
|
|
$szDeviceName, |
2063
|
|
|
|
|
|
|
) = unpack "LLLLa".(RAS_MaxAreaCode+1)."a".(RAS_MaxPhoneNumber+1). |
2064
|
|
|
|
|
|
|
"La4a4a4a4a4LLL".(("a".MAX_PATH) x 3). |
2065
|
|
|
|
|
|
|
"a".(RAS_MaxDeviceType + 1)."a".(RAS_MaxDeviceName + 1), $RASENTRY; |
2066
|
|
|
|
|
|
|
|
2067
|
|
|
|
|
|
|
|
2068
|
0
|
0
|
|
|
|
|
if (defined $DeviceName) { |
2069
|
0
|
|
|
|
|
|
TRIM_LR($DeviceName); |
2070
|
0
|
|
|
|
|
|
CRUNCH($szDeviceName); |
2071
|
|
|
|
|
|
|
|
2072
|
0
|
0
|
|
|
|
|
if ($DeviceName ne $szDeviceName) { |
2073
|
0
|
0
|
|
|
|
|
%RasDevEnumeration = RasEnumDevices() unless defined %RasDevEnumeration; |
2074
|
0
|
0
|
|
|
|
|
exists $RasDevEnumeration{$DeviceName} or |
2075
|
|
|
|
|
|
|
RASCROAK "device `$DeviceName' not found or non RAS-capable"; |
2076
|
|
|
|
|
|
|
|
2077
|
0
|
|
|
|
|
|
$szDeviceName = $DeviceName; |
2078
|
0
|
|
|
|
|
|
$szDeviceType = $RasDevEnumeration{$DeviceName}; |
2079
|
|
|
|
|
|
|
} |
2080
|
|
|
|
|
|
|
} |
2081
|
|
|
|
|
|
|
|
2082
|
0
|
0
|
|
|
|
|
if (defined $Script) { |
2083
|
0
|
|
|
|
|
|
TRIM_LR($Script); |
2084
|
0
|
0
|
0
|
|
|
|
RASCROAK "script `$Script' not found/empty" |
|
|
|
0
|
|
|
|
|
2085
|
|
|
|
|
|
|
unless $Script eq "" || (-f $Script && -s_); |
2086
|
0
|
|
|
|
|
|
$szScript = $Script; |
2087
|
|
|
|
|
|
|
} |
2088
|
|
|
|
|
|
|
|
2089
|
0
|
0
|
|
|
|
|
if (defined $AreaCode) { |
2090
|
0
|
|
|
|
|
|
TRIM_LR($AreaCode); |
2091
|
0
|
0
|
|
|
|
|
RASCROAK "wrong area code `$AreaCode'" |
2092
|
|
|
|
|
|
|
unless $AreaCode =~ /^\d*$/; |
2093
|
0
|
|
|
|
|
|
$szAreaCode = $AreaCode; |
2094
|
|
|
|
|
|
|
} |
2095
|
|
|
|
|
|
|
|
2096
|
0
|
0
|
|
|
|
|
if (defined $LocalPhoneNumber) { |
2097
|
0
|
|
|
|
|
|
TRIM_LR($LocalPhoneNumber); |
2098
|
|
|
|
|
|
|
|
2099
|
0
|
0
|
|
|
|
|
RASCROAK "wrong local phone number `$LocalPhoneNumber'" |
2100
|
|
|
|
|
|
|
unless $LocalPhoneNumber =~ /^[\d\-.]*$/; |
2101
|
|
|
|
|
|
|
# dot '.' added for ip-address (DUN 1.3 - VPN via PPTP) or French style |
2102
|
|
|
|
|
|
|
|
2103
|
0
|
|
|
|
|
|
$szLocalPhoneNumber = $LocalPhoneNumber; |
2104
|
|
|
|
|
|
|
} |
2105
|
|
|
|
|
|
|
|
2106
|
0
|
0
|
|
|
|
|
if (defined $CountryID) { |
|
|
0
|
|
|
|
|
|
2107
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
2108
|
|
|
|
|
|
|
|
2109
|
0
|
|
|
|
|
|
TRIM_LR($CountryID); |
2110
|
|
|
|
|
|
|
|
2111
|
0
|
0
|
|
|
|
|
RASCROAK "wrong CountryID `$CountryID'" |
2112
|
|
|
|
|
|
|
unless $CountryID =~ /^\d*$/; |
2113
|
|
|
|
|
|
|
|
2114
|
0
|
0
|
|
|
|
|
RASCROAK "CountryID not found `$CountryID'" |
2115
|
|
|
|
|
|
|
unless exists $TAPIEnumeration{$CountryID}; |
2116
|
|
|
|
|
|
|
|
2117
|
0
|
|
|
|
|
|
$dwCountryID = $CountryID; |
2118
|
|
|
|
|
|
|
|
2119
|
0
|
0
|
|
|
|
|
if (defined $CountryCode) { |
2120
|
0
|
0
|
|
|
|
|
RASCROAK "CountryID `$CountryID'". |
2121
|
|
|
|
|
|
|
" does not match CountryCode `$CountryCode'" |
2122
|
|
|
|
|
|
|
unless $CountryCode == $TAPIEnumeration{$CountryID}->[1]; |
2123
|
|
|
|
|
|
|
} |
2124
|
|
|
|
|
|
|
|
2125
|
0
|
|
|
|
|
|
$dwCountryCode = $TAPIEnumeration{$CountryID}->[1]; |
2126
|
|
|
|
|
|
|
|
2127
|
|
|
|
|
|
|
} elsif (defined $CountryCode) { |
2128
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
2129
|
|
|
|
|
|
|
|
2130
|
0
|
|
|
|
|
|
TRIM_LR($CountryCode); |
2131
|
|
|
|
|
|
|
|
2132
|
0
|
0
|
|
|
|
|
RASCROAK "wrong CountryCode `$CountryCode'" unless $CountryCode =~ /^\d*$/; |
2133
|
|
|
|
|
|
|
|
2134
|
0
|
0
|
|
|
|
|
grep {$TAPIEnumeration{$_}->[1] == $CountryCode} keys %TAPIEnumeration or |
|
0
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
RASCROAK "CountryCode not found `$CountryCode'"; |
2136
|
|
|
|
|
|
|
|
2137
|
0
|
|
|
|
|
|
$dwCountryCode = $dwCountryID = $CountryCode; |
2138
|
|
|
|
|
|
|
} |
2139
|
|
|
|
|
|
|
|
2140
|
0
|
|
|
|
|
|
for (qw(ipaddrDns ipaddrDnsAlt ipaddrWins ipaddrWinsAlt ipaddr)) { |
2141
|
0
|
0
|
|
|
|
|
if (defined $props->{$_}) { |
2142
|
0
|
|
|
|
|
|
my $var = $props->{$_}; |
2143
|
|
|
|
|
|
|
|
2144
|
0
|
|
|
|
|
|
TRIM_LR($var); |
2145
|
|
|
|
|
|
|
|
2146
|
0
|
0
|
|
|
|
|
if (!$var) { |
2147
|
0
|
|
|
|
|
|
eval "\$$_ = DWORD_NULL"; |
2148
|
|
|
|
|
|
|
} else { |
2149
|
0
|
0
|
|
|
|
|
RASCROAK "wrong $_ `$var'" unless $var =~ /^$pat$/; |
2150
|
0
|
|
|
|
|
|
eval "\$$_ = pack 'C4', split/\\./, \$var"; |
2151
|
|
|
|
|
|
|
} |
2152
|
|
|
|
|
|
|
} |
2153
|
|
|
|
|
|
|
} |
2154
|
|
|
|
|
|
|
|
2155
|
0
|
0
|
|
|
|
|
if (defined $FramingProtocol) { |
2156
|
0
|
|
|
|
|
|
($FP = $FramingProtocol) =~ s/^ *(.*?) *$/uc $1/es; |
|
0
|
|
|
|
|
|
|
2157
|
0
|
0
|
|
|
|
|
RASCROAK "wrong framing protocol `$FramingProtocol'" |
2158
|
|
|
|
|
|
|
unless $FP =~ /^(PPP|SLIP|RAS)$/; |
2159
|
0
|
0
|
|
|
|
|
$dwFramingProtocol = RASFP_Ppp if $FP eq 'PPP'; |
2160
|
0
|
0
|
|
|
|
|
$dwFramingProtocol = RASFP_Slip if $FP eq 'SLIP'; |
2161
|
0
|
0
|
|
|
|
|
$dwFramingProtocol = RASFP_Ras if $FP eq 'RAS'; |
2162
|
|
|
|
|
|
|
} |
2163
|
|
|
|
|
|
|
|
2164
|
0
|
0
|
|
|
|
|
if (defined $NetProtocols) { |
2165
|
0
|
0
|
|
|
|
|
RASCROAK "\$props->{$NetProtocols} is not an array ref" |
2166
|
|
|
|
|
|
|
unless ref $NetProtocols eq "ARRAY"; |
2167
|
|
|
|
|
|
|
|
2168
|
0
|
|
|
|
|
|
($NP = join "|", @$NetProtocols) =~ s/^ *(.*?) *$/uc $1/es; |
|
0
|
|
|
|
|
|
|
2169
|
0
|
0
|
|
|
|
|
RASCROAK "wrong net protocols `$NetProtocols'" |
2170
|
|
|
|
|
|
|
unless $NP =~ /^(NETBEUI|IPX|IP)(\|(NETBEUI|IPX|IP))*$/; |
2171
|
0
|
|
|
|
|
|
$dwfNetProtocols = 0; |
2172
|
0
|
0
|
|
|
|
|
$dwfNetProtocols |= RASNP_NetBEUI if $NP =~ /NETBEUI/; |
2173
|
0
|
0
|
|
|
|
|
$dwfNetProtocols |= RASNP_Ipx if $NP =~ /IPX/; |
2174
|
0
|
0
|
|
|
|
|
$dwfNetProtocols |= RASNP_Ip if $NP =~ /IP(\||$)/; |
2175
|
|
|
|
|
|
|
} |
2176
|
|
|
|
|
|
|
|
2177
|
|
|
|
|
|
|
# flags logic |
2178
|
0
|
0
|
|
|
|
|
if (defined $Flags) { |
2179
|
0
|
0
|
|
|
|
|
$newFlags = ($Flags =~ s/\+?(RASEO_)?KeepOldFlags//) ? $dwfOptions : 0; |
2180
|
0
|
0
|
|
|
|
|
$newFlags = 0 if $Flags =~ s/\-(RASEO_)?KeepOldFlags//; |
2181
|
|
|
|
|
|
|
|
2182
|
|
|
|
|
|
|
|
2183
|
0
|
|
|
|
|
|
for(split/\s*\+|\s+/,$Flags) { |
2184
|
0
|
0
|
|
|
|
|
next unless $_; |
2185
|
|
|
|
|
|
|
|
2186
|
0
|
0
|
0
|
|
|
|
if (defined(&$_)) { |
|
0
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2187
|
0
|
|
|
|
|
|
$newFlags |= &$_; |
2188
|
|
|
|
|
|
|
} elsif (defined &{"RASEO_$_"}) { |
2189
|
0
|
|
|
|
|
|
$newFlags |= &{"RASEO_$_"}; |
|
0
|
|
|
|
|
|
|
2190
|
0
|
|
|
|
|
|
} elsif (/^-(.+)$/ && defined &$1) { |
2191
|
0
|
|
|
|
|
|
$newFlags = $newFlags ^ ($newFlags & &$1); |
2192
|
|
|
|
|
|
|
} elsif (/^-(.+)$/ && defined &{"RASEO_$1"}) { |
2193
|
0
|
|
|
|
|
|
$newFlags = $newFlags ^ ($newFlags & &{"RASEO_$1"}); |
|
0
|
|
|
|
|
|
|
2194
|
|
|
|
|
|
|
} else { |
2195
|
0
|
|
|
|
|
|
RASCROAK "wrong flag specified `$_'"; |
2196
|
|
|
|
|
|
|
} |
2197
|
|
|
|
|
|
|
} |
2198
|
|
|
|
|
|
|
} else { |
2199
|
0
|
|
|
|
|
|
$newFlags = $dwfOptions; |
2200
|
|
|
|
|
|
|
} |
2201
|
|
|
|
|
|
|
|
2202
|
|
|
|
|
|
|
#print "$newFlags, $dwCountryID, $dwCountryCode, $szAreaCode, $szLocalPhoneNumber, |
2203
|
|
|
|
|
|
|
#$ipaddr, $ipaddrDns, $ipaddrDnsAlt, $ipaddrWins, $ipaddrWinsAlt, |
2204
|
|
|
|
|
|
|
#$dwFrameSize, $dwfNetProtocols, $dwFramingProtocol, $szScript\n";#exit; |
2205
|
|
|
|
|
|
|
|
2206
|
|
|
|
|
|
|
# pack new header |
2207
|
0
|
|
|
|
|
|
my $newHead = pack "LLLLa".(RAS_MaxAreaCode+1). |
2208
|
|
|
|
|
|
|
"a".(RAS_MaxPhoneNumber+1)."La4a4a4a4a4LLL".(("a".MAX_PATH) x 3). |
2209
|
|
|
|
|
|
|
"a".(RAS_MaxDeviceType + 1)."a".(RAS_MaxDeviceName + 1), ( |
2210
|
|
|
|
|
|
|
$dwSize, |
2211
|
|
|
|
|
|
|
$newFlags, # +4 |
2212
|
|
|
|
|
|
|
|
2213
|
|
|
|
|
|
|
$dwCountryID, # +8 |
2214
|
|
|
|
|
|
|
$dwCountryCode, # +12 |
2215
|
|
|
|
|
|
|
$szAreaCode, # +16 |
2216
|
|
|
|
|
|
|
$szLocalPhoneNumber, |
2217
|
|
|
|
|
|
|
$dwAlternateOffset, |
2218
|
|
|
|
|
|
|
|
2219
|
|
|
|
|
|
|
$ipaddr, |
2220
|
|
|
|
|
|
|
$ipaddrDns, |
2221
|
|
|
|
|
|
|
$ipaddrDnsAlt, |
2222
|
|
|
|
|
|
|
$ipaddrWins, |
2223
|
|
|
|
|
|
|
$ipaddrWinsAlt, |
2224
|
|
|
|
|
|
|
|
2225
|
|
|
|
|
|
|
$dwFrameSize, |
2226
|
|
|
|
|
|
|
$dwfNetProtocols, |
2227
|
|
|
|
|
|
|
$dwFramingProtocol, |
2228
|
|
|
|
|
|
|
$szScript, |
2229
|
|
|
|
|
|
|
|
2230
|
|
|
|
|
|
|
$szAutodialDll, |
2231
|
|
|
|
|
|
|
$szAutodialFunc, |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
$szDeviceType, |
2234
|
|
|
|
|
|
|
$szDeviceName); |
2235
|
|
|
|
|
|
|
|
2236
|
0
|
|
|
|
|
|
substr($RASENTRY, 0, length $newHead) = $newHead; |
2237
|
0
|
|
|
|
|
|
$RASENTRY; |
2238
|
|
|
|
|
|
|
} |
2239
|
|
|
|
|
|
|
|
2240
|
|
|
|
|
|
|
=item RasChangePhoneNumber ( ) |
2241
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
This is a simplified version of the C. |
2243
|
|
|
|
|
|
|
|
2244
|
|
|
|
|
|
|
RasChangePhoneNumber($entry, $new_phone_number); |
2245
|
|
|
|
|
|
|
|
2246
|
|
|
|
|
|
|
$entry - name of RAS/DUN entry |
2247
|
|
|
|
|
|
|
$new_phone_number - fully qualified phone number of the remote |
2248
|
|
|
|
|
|
|
computer in almost any human-readable form. |
2249
|
|
|
|
|
|
|
|
2250
|
|
|
|
|
|
|
For example: |
2251
|
|
|
|
|
|
|
|
2252
|
|
|
|
|
|
|
'7-095-5555555' or '7(095)5555555' or '7 -( 095)-555-5555' |
2253
|
|
|
|
|
|
|
or '+7 (095) - 5-5-5-5-5-5-5' or '7 095 5555555' |
2254
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
It is smart enough to adjust entry flags to avoid long distance dialing if |
2256
|
|
|
|
|
|
|
country and area codes are the same as in Dialing Properties/Default Location. |
2257
|
|
|
|
|
|
|
All other flags are kept unchanged. |
2258
|
|
|
|
|
|
|
|
2259
|
|
|
|
|
|
|
B country code here is not TAPI C. |
2260
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
=cut |
2262
|
|
|
|
|
|
|
|
2263
|
|
|
|
|
|
|
#======================= |
2264
|
|
|
|
|
|
|
sub RasChangePhoneNumber ($$) { |
2265
|
|
|
|
|
|
|
#======================= |
2266
|
|
|
|
|
|
|
# full country-code-area-code-local in the form |
2267
|
0
|
|
|
0
|
|
|
my ($entry, $phone) = @_; |
2268
|
0
|
|
|
|
|
|
$LastError = 0; |
2269
|
|
|
|
|
|
|
|
2270
|
0
|
0
|
0
|
|
|
|
TAPIlineGetTranslateCaps() |
|
|
|
0
|
|
|
|
|
2271
|
|
|
|
|
|
|
unless defined($LOCAL_ID) && defined($LOCAL_CODE) && defined($LOCAL_AREA); |
2272
|
|
|
|
|
|
|
|
2273
|
0
|
|
|
|
|
|
my $props = {}; |
2274
|
0
|
|
|
|
|
|
$props->{name} = $entry; |
2275
|
|
|
|
|
|
|
|
2276
|
0
|
0
|
|
|
|
|
($props->{CountryCode}, $props->{AreaCode}, $props->{LocalPhoneNumber}) = |
2277
|
|
|
|
|
|
|
$phone =~ |
2278
|
|
|
|
|
|
|
/(\d+)(?:[+\- ]*\( *|[+\- ]+)(\d+)(?: *\)[+\- ]*|[+\- ]+)(\d[\d\-]+\d)/ or |
2279
|
|
|
|
|
|
|
RASCROAK "wrong number `$phone'"; |
2280
|
|
|
|
|
|
|
|
2281
|
0
|
0
|
0
|
|
|
|
if ($props->{AreaCode} eq $LOCAL_AREA && $props->{CountryCode} eq $LOCAL_CODE) { |
2282
|
0
|
|
|
|
|
|
$props->{newFlags} = 'KeepOldFlags -UseCountryAndAreaCodes'; |
2283
|
|
|
|
|
|
|
} else { |
2284
|
0
|
|
|
|
|
|
$props->{newFlags} = 'KeepOldFlags +UseCountryAndAreaCodes'; |
2285
|
|
|
|
|
|
|
} |
2286
|
|
|
|
|
|
|
|
2287
|
0
|
0
|
|
|
|
|
my $ret = RasSetEntryProperties($props) or return; |
2288
|
0
|
|
|
|
|
|
1; |
2289
|
|
|
|
|
|
|
} |
2290
|
|
|
|
|
|
|
|
2291
|
|
|
|
|
|
|
|
2292
|
|
|
|
|
|
|
=pod |
2293
|
|
|
|
|
|
|
|
2294
|
|
|
|
|
|
|
=back |
2295
|
|
|
|
|
|
|
|
2296
|
|
|
|
|
|
|
B< =====================================> |
2297
|
|
|
|
|
|
|
|
2298
|
|
|
|
|
|
|
B< CONNECTION RELATED FUNCTIONS> |
2299
|
|
|
|
|
|
|
|
2300
|
|
|
|
|
|
|
B< =====================================> |
2301
|
|
|
|
|
|
|
|
2302
|
|
|
|
|
|
|
|
2303
|
|
|
|
|
|
|
=over 4 |
2304
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
=item RasEnumConnections ( ) |
2306
|
|
|
|
|
|
|
|
2307
|
|
|
|
|
|
|
%connections = RasEnumConnections ( ); or as list |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
($entry1, $hrasconn1, ...) = RasEnumConnections ( ); |
2310
|
|
|
|
|
|
|
|
2311
|
|
|
|
|
|
|
Returns handles for each active RAS/DUN connection. C<$entry> is entry-name. |
2312
|
|
|
|
|
|
|
C<$hrasconn> is a numeric handle that might be used in C to |
2313
|
|
|
|
|
|
|
hang up the active connection or in C or in |
2314
|
|
|
|
|
|
|
C. |
2315
|
|
|
|
|
|
|
|
2316
|
|
|
|
|
|
|
Croaks on errors. Returns FALSE if no one active connection was found. |
2317
|
|
|
|
|
|
|
|
2318
|
|
|
|
|
|
|
Note that C also returns $hrasconn on success. |
2319
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
=cut |
2321
|
|
|
|
|
|
|
|
2322
|
|
|
|
|
|
|
#================ |
2323
|
|
|
|
|
|
|
sub RasEnumConnections () { |
2324
|
|
|
|
|
|
|
#================ |
2325
|
0
|
|
|
0
|
|
|
my ($dwSize, $hrasconn, $szEntryName, $szDeviceType, $szDeviceName); |
2326
|
0
|
|
|
|
|
|
$LastError = 0; |
2327
|
|
|
|
|
|
|
|
2328
|
0
|
|
0
|
|
|
|
$RasEnumConnections ||= new("rasapi32", "RasEnumConnections", [P,P,P], N); |
2329
|
|
|
|
|
|
|
|
2330
|
0
|
0
|
|
|
|
|
$dwSize = 4+4+(RAS_MaxEntryName+1)+ |
2331
|
|
|
|
|
|
|
($WINVER >= 0x400 ? RAS_MaxDeviceType+1 + RAS_MaxDeviceName+1 : 0); |
2332
|
|
|
|
|
|
|
|
2333
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
2334
|
|
|
|
|
|
|
|
2335
|
0
|
|
|
|
|
|
my $RASCONN = pack "LLa".($dwSize-8), ($dwSize, 0, ""); |
2336
|
|
|
|
|
|
|
|
2337
|
0
|
|
|
|
|
|
my ($lpcb, $lpcConnections) = |
2338
|
|
|
|
|
|
|
(pack ("L", length $RASCONN), DWORD_NULL); |
2339
|
|
|
|
|
|
|
|
2340
|
0
|
|
|
|
|
|
my $ret = $RasEnumConnections->Call($RASCONN, $lpcb, $lpcConnections); |
2341
|
|
|
|
|
|
|
|
2342
|
0
|
|
|
|
|
|
my $cb = unpack "L",$lpcb; |
2343
|
|
|
|
|
|
|
|
2344
|
0
|
0
|
|
|
|
|
if ($ret) { |
2345
|
0
|
|
|
|
|
|
$RASCONN = pack "LLa".($cb-8), ($dwSize, 0, ""); |
2346
|
0
|
|
|
|
|
|
$ret = $RasEnumConnections->Call($RASCONN, $lpcb, $lpcConnections); |
2347
|
|
|
|
|
|
|
} |
2348
|
|
|
|
|
|
|
|
2349
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
2350
|
|
|
|
|
|
|
|
2351
|
0
|
|
|
|
|
|
my $conns = unpack "L",$lpcConnections; |
2352
|
|
|
|
|
|
|
|
2353
|
0
|
|
|
|
|
|
my %connects; |
2354
|
|
|
|
|
|
|
|
2355
|
0
|
|
|
|
|
|
for my $i(1..$conns) { |
2356
|
0
|
|
|
|
|
|
my $buffer = substr $RASCONN, $dwSize*($i-1), $dwSize; |
2357
|
0
|
|
|
|
|
|
($dwSize, $hrasconn, $szEntryName) = |
2358
|
|
|
|
|
|
|
unpack "LL". "a".($dwSize-8), $buffer; |
2359
|
0
|
|
|
|
|
|
CRUNCH($szEntryName); |
2360
|
0
|
|
|
|
|
|
$connects{$szEntryName} = $hrasconn; |
2361
|
|
|
|
|
|
|
} |
2362
|
0
|
|
|
|
|
|
%connects; |
2363
|
|
|
|
|
|
|
} |
2364
|
|
|
|
|
|
|
|
2365
|
|
|
|
|
|
|
=item RasGetProjectionInfo ( ) |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
In the current version projection info is implemented for IP protocol only. |
2368
|
|
|
|
|
|
|
This is a subject to change. |
2369
|
|
|
|
|
|
|
|
2370
|
|
|
|
|
|
|
($ip, $server_ip) = RasGetProjectionInfo ( $hrasconn ); |
2371
|
|
|
|
|
|
|
|
2372
|
|
|
|
|
|
|
$hrasconn - handle of the active connection returned by either |
2373
|
|
|
|
|
|
|
RasDial() or RasEnumConnections(). |
2374
|
|
|
|
|
|
|
$ip - the client's IP address on the RAS connection |
2375
|
|
|
|
|
|
|
$server_ip - the IP address of the remote PPP peer (that is, the |
2376
|
|
|
|
|
|
|
server's IP address) |
2377
|
|
|
|
|
|
|
|
2378
|
|
|
|
|
|
|
Both IP addrs are in "nnn.nnn.nnn.nnn" form. |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
|
2381
|
|
|
|
|
|
|
B |
2382
|
|
|
|
|
|
|
|
2383
|
|
|
|
|
|
|
Remote access projection is the process whereby a remote access server |
2384
|
|
|
|
|
|
|
and a remote client negotiate network protocol-specific information. |
2385
|
|
|
|
|
|
|
A remote access server uses this network protocol-specific information |
2386
|
|
|
|
|
|
|
to represent a remote client on the network. |
2387
|
|
|
|
|
|
|
|
2388
|
|
|
|
|
|
|
B Remote access projection information is not available until |
2389
|
|
|
|
|
|
|
the operating system has executed the C C state on the |
2390
|
|
|
|
|
|
|
remote access connection. If C is called prior to the |
2391
|
|
|
|
|
|
|
C state, it returns C. |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
B Windows 95 Dial-Up Networking does not support the |
2394
|
|
|
|
|
|
|
C state. The projection phase may be done during the |
2395
|
|
|
|
|
|
|
C state. If the authentication is successful, the connection |
2396
|
|
|
|
|
|
|
operation proceeds to the C state, and projection information |
2397
|
|
|
|
|
|
|
is available for successfully configured protocols. If C |
2398
|
|
|
|
|
|
|
is called prior to the C state, it returns |
2399
|
|
|
|
|
|
|
C. |
2400
|
|
|
|
|
|
|
|
2401
|
|
|
|
|
|
|
PPP does not require that servers provide this address, but Windows NT |
2402
|
|
|
|
|
|
|
servers will consistently return the address anyway. Other PPP vendors |
2403
|
|
|
|
|
|
|
may not provide the address. If the address is not available, this member |
2404
|
|
|
|
|
|
|
returns an empty string (""). |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
I guess the last note is probably outdated because my Advanced Dialer |
2407
|
|
|
|
|
|
|
has a field for "Server's IP address" - so, it expects that it's always available. |
2408
|
|
|
|
|
|
|
|
2409
|
|
|
|
|
|
|
If you are using C in a single process application you can't |
2410
|
|
|
|
|
|
|
monitor C states (for more info look at C). |
2411
|
|
|
|
|
|
|
So, the rule is: use this function after C successfully |
2412
|
|
|
|
|
|
|
returned C<$hrasconn>. |
2413
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
The typical usage if you have only one connection is: |
2415
|
|
|
|
|
|
|
|
2416
|
|
|
|
|
|
|
unless ( $hrasconn = (RasEnumConnections())[1] ) { |
2417
|
|
|
|
|
|
|
print "Dialing sequence not started\n"; |
2418
|
|
|
|
|
|
|
|
2419
|
|
|
|
|
|
|
} elsif ( ($ip, $server_ip) = RasGetProjectionInfo( $hrasconn ) ) { |
2420
|
|
|
|
|
|
|
print "LOCAL:$ip SERVER:$server_ip\n"; |
2421
|
|
|
|
|
|
|
|
2422
|
|
|
|
|
|
|
} elsif ( Win32::RASE::GetLastError == 731 ) { |
2423
|
|
|
|
|
|
|
print "Protocol not configured yet\n"; |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
} else { |
2426
|
|
|
|
|
|
|
die Win32::RASE::FormatMessage(); |
2427
|
|
|
|
|
|
|
} |
2428
|
|
|
|
|
|
|
|
2429
|
|
|
|
|
|
|
Note also that LastError=6 means that C<$hrasconn> is an invalid handle. |
2430
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
Command line syntax: |
2432
|
|
|
|
|
|
|
|
2433
|
|
|
|
|
|
|
perl -MWin32::RASE -e "$,=', ';print RasGetProjectionInfo((RasEnumConnections)[1])" |
2434
|
|
|
|
|
|
|
|
2435
|
|
|
|
|
|
|
=cut |
2436
|
|
|
|
|
|
|
|
2437
|
|
|
|
|
|
|
#================ |
2438
|
|
|
|
|
|
|
sub RasGetProjectionInfo ($) { |
2439
|
|
|
|
|
|
|
#================ |
2440
|
0
|
|
|
0
|
|
|
my $hrasconn = shift; |
2441
|
0
|
|
|
|
|
|
my ($RASPPPIP, $dwSize, $lpcb, $dwError, $ip, $server_ip, $ret); |
2442
|
0
|
|
|
|
|
|
my $rasprojection = RASP_PppIp; |
2443
|
0
|
|
|
|
|
|
$LastError = 0; |
2444
|
|
|
|
|
|
|
|
2445
|
0
|
|
0
|
|
|
|
$RasGetProjectionInfo ||= new("rasapi32", "RasGetProjectionInfo",[N,N,P,P],N); |
2446
|
|
|
|
|
|
|
|
2447
|
0
|
0
|
|
|
|
|
if ($rasprojection == RASP_PppIp) { |
2448
|
0
|
|
|
|
|
|
$dwSize = 4+4+RAS_MaxIpAddress+1+RAS_MaxIpAddress+1; |
2449
|
|
|
|
|
|
|
|
2450
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
2451
|
|
|
|
|
|
|
|
2452
|
0
|
|
|
|
|
|
$RASPPPIP = pack "La".($dwSize-4), $dwSize, ""; |
2453
|
0
|
|
|
|
|
|
$lpcb = pack "L", $dwSize; |
2454
|
|
|
|
|
|
|
|
2455
|
0
|
0
|
|
|
|
|
$ret = $RasGetProjectionInfo->Call( |
2456
|
|
|
|
|
|
|
$hrasconn, $rasprojection, $RASPPPIP, $lpcb) |
2457
|
|
|
|
|
|
|
and ($LastError = $ret, return); |
2458
|
|
|
|
|
|
|
|
2459
|
0
|
|
|
|
|
|
($dwSize, $dwError, $ip, $server_ip) = |
2460
|
|
|
|
|
|
|
unpack "LL"."a".(RAS_MaxIpAddress+1)."a".(RAS_MaxIpAddress+1), $RASPPPIP; |
2461
|
0
|
|
|
|
|
|
CRUNCH($ip, $server_ip); |
2462
|
|
|
|
|
|
|
|
2463
|
0
|
0
|
|
|
|
|
$dwError and ($LastError = $dwError, return); |
2464
|
|
|
|
|
|
|
|
2465
|
0
|
|
|
|
|
|
return ($ip, $server_ip); |
2466
|
|
|
|
|
|
|
} |
2467
|
|
|
|
|
|
|
|
2468
|
|
|
|
|
|
|
} |
2469
|
|
|
|
|
|
|
|
2470
|
|
|
|
|
|
|
=item RasHangUp ( ) |
2471
|
|
|
|
|
|
|
|
2472
|
|
|
|
|
|
|
RasHangUp($hrasconn [, $timeout]); |
2473
|
|
|
|
|
|
|
|
2474
|
|
|
|
|
|
|
$hrasconn - handle of the active connection returned by either |
2475
|
|
|
|
|
|
|
RasDial() or RasEnumConnections(). |
2476
|
|
|
|
|
|
|
|
2477
|
|
|
|
|
|
|
$timeout - in sec, optional (3 sec by default). Maximum time to wait |
2478
|
|
|
|
|
|
|
for graceful disconnection. You can use float values if |
2479
|
|
|
|
|
|
|
Time::HiRes is installed. Otherwise cycle uses sleep(1) |
2480
|
|
|
|
|
|
|
and thus wastes some additional time. |
2481
|
|
|
|
|
|
|
|
2482
|
|
|
|
|
|
|
This function gracefully terminates the connection. You don't need to add any |
2483
|
|
|
|
|
|
|
C after it. |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
The connection is terminated even if the C call has not yet been completed. |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
After this call, the $hrasconn handle can no longer be used. |
2488
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
Returns FALSE if invalid handle was given but this is harmless |
2490
|
|
|
|
|
|
|
most of the time. Probably the connection failed itself and C<$hrasconn> |
2491
|
|
|
|
|
|
|
is not valid any more. So, you don't have to trap this error. |
2492
|
|
|
|
|
|
|
|
2493
|
|
|
|
|
|
|
Returns FALSE on timeout also (connection might be still active). LastError |
2494
|
|
|
|
|
|
|
is 0 in this case. So the exact logic is: |
2495
|
|
|
|
|
|
|
|
2496
|
|
|
|
|
|
|
if ( RasHangUp($hrasconn, $timeout) ) { |
2497
|
|
|
|
|
|
|
print "Connection is terminated successfully.\n"; |
2498
|
|
|
|
|
|
|
|
2499
|
|
|
|
|
|
|
} elsif ( !Win32::RASE::GetLastError ) { |
2500
|
|
|
|
|
|
|
print "Timeout. Connection is still active.\n"; |
2501
|
|
|
|
|
|
|
|
2502
|
|
|
|
|
|
|
} else { |
2503
|
|
|
|
|
|
|
# we don't have to die here |
2504
|
|
|
|
|
|
|
warn Win32::RASE::FormatMessage(), "\n"; |
2505
|
|
|
|
|
|
|
} |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
For more take a look at the API docs. |
2508
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
=cut |
2510
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
#================ |
2512
|
|
|
|
|
|
|
sub RasHangUp ($;$) { |
2513
|
|
|
|
|
|
|
#================ |
2514
|
|
|
|
|
|
|
# returns 0 on success or error-code |
2515
|
0
|
|
|
0
|
|
|
my ($hrasconn, $timeout) = @_; |
2516
|
0
|
|
|
|
|
|
$LastError = 0; |
2517
|
0
|
0
|
0
|
|
|
|
($LastError = 6, return) unless $hrasconn && $hrasconn !~ /\D/; |
2518
|
|
|
|
|
|
|
|
2519
|
0
|
|
0
|
|
|
|
$RasHangUp ||= new("rasapi32", "RasHangUp", [N], N); |
2520
|
|
|
|
|
|
|
|
2521
|
0
|
|
0
|
|
|
|
$timeout ||= 3; |
2522
|
|
|
|
|
|
|
|
2523
|
0
|
0
|
|
|
|
|
my ($delay) = $Time_HiRes_loaded ? 0.1 : 1; |
2524
|
|
|
|
|
|
|
|
2525
|
0
|
|
|
|
|
|
my $ret = $RasHangUp->Call($hrasconn); |
2526
|
|
|
|
|
|
|
|
2527
|
0
|
0
|
|
|
|
|
$ret and ($LastError = $ret, return); |
2528
|
|
|
|
|
|
|
|
2529
|
0
|
|
|
|
|
|
my $starttime = time; |
2530
|
|
|
|
|
|
|
|
2531
|
0
|
|
|
|
|
|
while ($starttime + $timeout >= time) { |
2532
|
0
|
0
|
|
|
|
|
RasGetConnectStatus($hrasconn) or ($LastError = 0, return 1); |
2533
|
|
|
|
|
|
|
|
2534
|
0
|
|
|
|
|
|
sleep $delay; |
2535
|
|
|
|
|
|
|
} |
2536
|
|
|
|
|
|
|
|
2537
|
0
|
|
|
|
|
|
return; |
2538
|
|
|
|
|
|
|
} |
2539
|
|
|
|
|
|
|
|
2540
|
|
|
|
|
|
|
=item HangUp ( ) |
2541
|
|
|
|
|
|
|
|
2542
|
|
|
|
|
|
|
This is the easier version of previous. |
2543
|
|
|
|
|
|
|
|
2544
|
|
|
|
|
|
|
Without parameters it will terminate all active connections, otherwise |
2545
|
|
|
|
|
|
|
terminates connections by B given as parameters. Note that |
2546
|
|
|
|
|
|
|
this function uses entry-names, not handles. |
2547
|
|
|
|
|
|
|
|
2548
|
|
|
|
|
|
|
$code = HangUp ( [$entry1, ...] ); |
2549
|
|
|
|
|
|
|
|
2550
|
|
|
|
|
|
|
Returns FALSE if at least one connection was not terminated gracefully, |
2551
|
|
|
|
|
|
|
otherwise TRUE even if no one active connecton was found. |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
Command line syntax: |
2554
|
|
|
|
|
|
|
|
2555
|
|
|
|
|
|
|
perl -MWin32::RASE -e HangUp |
2556
|
|
|
|
|
|
|
|
2557
|
|
|
|
|
|
|
|
2558
|
|
|
|
|
|
|
=cut |
2559
|
|
|
|
|
|
|
|
2560
|
|
|
|
|
|
|
#================ |
2561
|
|
|
|
|
|
|
sub HangUp (;@) { |
2562
|
|
|
|
|
|
|
#================ |
2563
|
0
|
|
|
0
|
|
|
$LastError = 0; |
2564
|
0
|
0
|
|
|
|
|
my %conns = RasEnumConnections() or return 1; |
2565
|
0
|
|
|
|
|
|
my @entries = @_; |
2566
|
0
|
|
|
|
|
|
my $ret = 1; |
2567
|
0
|
|
|
|
|
|
local $_; |
2568
|
|
|
|
|
|
|
|
2569
|
0
|
0
|
|
|
|
|
@entries = keys %conns unless @entries; |
2570
|
|
|
|
|
|
|
|
2571
|
0
|
|
|
|
|
|
for (@entries) { |
2572
|
0
|
0
|
|
|
|
|
next unless exists $conns{$_}; |
2573
|
|
|
|
|
|
|
|
2574
|
0
|
0
|
|
|
|
|
RasHangUp($conns{$_}) or $ret = 0; |
2575
|
|
|
|
|
|
|
} |
2576
|
0
|
|
|
|
|
|
$ret; |
2577
|
|
|
|
|
|
|
} |
2578
|
|
|
|
|
|
|
|
2579
|
|
|
|
|
|
|
=item RasGetConnectStatus ( ) |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
This function is used to monitor active connection in progress. In most |
2582
|
|
|
|
|
|
|
cases it's good to cycle calls to this function after a very small interval, |
2583
|
|
|
|
|
|
|
say 0.1 sec or less - at least at the dialing time. It's possible in |
2584
|
|
|
|
|
|
|
multithreading process (thread safety is not verified in this version) |
2585
|
|
|
|
|
|
|
or one process can monitor another, which is closer to perl practice. |
2586
|
|
|
|
|
|
|
|
2587
|
|
|
|
|
|
|
$status = RasGetConnectStatus($hrasconn); |
2588
|
|
|
|
|
|
|
|
2589
|
|
|
|
|
|
|
or |
2590
|
|
|
|
|
|
|
|
2591
|
|
|
|
|
|
|
($status, $status_text) = RasGetConnectStatus($hrasconn); |
2592
|
|
|
|
|
|
|
|
2593
|
|
|
|
|
|
|
$hrasconn - handle to active RAS/DUN connection |
2594
|
|
|
|
|
|
|
|
2595
|
|
|
|
|
|
|
In scalar context returns numeric status (RASCS_* enumerator values) or |
2596
|
|
|
|
|
|
|
FALSE if C<$hrasconn> is not a valid handle (LastError is set to 6). |
2597
|
|
|
|
|
|
|
|
2598
|
|
|
|
|
|
|
In list context returns numeric status and the string that characterizes |
2599
|
|
|
|
|
|
|
this status in short (the descriptive part of the corresponding RASCS_ constant's |
2600
|
|
|
|
|
|
|
name, like "OpenPort") or FALSE if handle is invalid. |
2601
|
|
|
|
|
|
|
|
2602
|
|
|
|
|
|
|
FALSE is also returned if handle is "not valid any more", i.e. connection |
2603
|
|
|
|
|
|
|
is terminated. |
2604
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
These string constants ("PortOpened" etc.) are stored in a non-exported hash |
2606
|
|
|
|
|
|
|
B<%Win32::RASE::RASCS> where the keys are numeric values of the corresponding RASCS_* |
2607
|
|
|
|
|
|
|
constants. So |
2608
|
|
|
|
|
|
|
|
2609
|
|
|
|
|
|
|
$Win32::RASE::RASCS{1} eq "PortOpened" |
2610
|
|
|
|
|
|
|
|
2611
|
|
|
|
|
|
|
You can check status yourself against exported RASCS_* constants: |
2612
|
|
|
|
|
|
|
|
2613
|
|
|
|
|
|
|
RASCS_OpenPort |
2614
|
|
|
|
|
|
|
RASCS_PortOpened |
2615
|
|
|
|
|
|
|
RASCS_ConnectDevice |
2616
|
|
|
|
|
|
|
RASCS_DeviceConnected |
2617
|
|
|
|
|
|
|
RASCS_AllDevicesConnected |
2618
|
|
|
|
|
|
|
RASCS_Authenticate |
2619
|
|
|
|
|
|
|
RASCS_AuthNotify |
2620
|
|
|
|
|
|
|
RASCS_AuthRetry |
2621
|
|
|
|
|
|
|
RASCS_AuthCallback |
2622
|
|
|
|
|
|
|
RASCS_AuthChangePassword |
2623
|
|
|
|
|
|
|
RASCS_AuthProject |
2624
|
|
|
|
|
|
|
RASCS_AuthLinkSpeed |
2625
|
|
|
|
|
|
|
RASCS_AuthAck |
2626
|
|
|
|
|
|
|
RASCS_ReAuthenticate |
2627
|
|
|
|
|
|
|
RASCS_Authenticated |
2628
|
|
|
|
|
|
|
RASCS_PrepareForCallback |
2629
|
|
|
|
|
|
|
RASCS_WaitForModemReset |
2630
|
|
|
|
|
|
|
RASCS_WaitForCallback |
2631
|
|
|
|
|
|
|
RASCS_Projected |
2632
|
|
|
|
|
|
|
RASCS_StartAuthentication // Windows 95 only |
2633
|
|
|
|
|
|
|
RASCS_CallbackComplete // Windows 95 only |
2634
|
|
|
|
|
|
|
RASCS_LogonNetwork // Windows 95 only |
2635
|
|
|
|
|
|
|
RASCS_SubEntryConnected |
2636
|
|
|
|
|
|
|
RASCS_SubEntryDisconnected |
2637
|
|
|
|
|
|
|
RASCS_Interactive = RASCS_PAUSED |
2638
|
|
|
|
|
|
|
RASCS_RetryAuthentication |
2639
|
|
|
|
|
|
|
RASCS_CallbackSetByCaller |
2640
|
|
|
|
|
|
|
RASCS_PasswordExpired |
2641
|
|
|
|
|
|
|
RASCS_Connected = RASCS_DONE |
2642
|
|
|
|
|
|
|
RASCS_Disconnected |
2643
|
|
|
|
|
|
|
|
2644
|
|
|
|
|
|
|
B |
2645
|
|
|
|
|
|
|
|
2646
|
|
|
|
|
|
|
The connection process states are divided into three classes: running states, |
2647
|
|
|
|
|
|
|
paused states, and terminal states. An application can easily determine the |
2648
|
|
|
|
|
|
|
class of a specific state by performing Boolean bit operations with the RASCS_PAUSED |
2649
|
|
|
|
|
|
|
and RASCS_DONE bitmasks. Here are some examples: |
2650
|
|
|
|
|
|
|
|
2651
|
|
|
|
|
|
|
$fDoneState = $status & RASCS_DONE; |
2652
|
|
|
|
|
|
|
$fPausedState = $status & RASCS_PAUSED; |
2653
|
|
|
|
|
|
|
$fRunState = !($fDoneState || $fPausedState); |
2654
|
|
|
|
|
|
|
|
2655
|
|
|
|
|
|
|
=cut |
2656
|
|
|
|
|
|
|
|
2657
|
|
|
|
|
|
|
#================ |
2658
|
|
|
|
|
|
|
sub RasGetConnectStatus ($) { |
2659
|
|
|
|
|
|
|
#================ |
2660
|
|
|
|
|
|
|
# dwError is sometimes 600 |
2661
|
|
|
|
|
|
|
# values are in %RASCS |
2662
|
0
|
|
|
0
|
|
|
my $hrasconn = shift; |
2663
|
0
|
|
|
|
|
|
$LastError = 0; |
2664
|
0
|
0
|
0
|
|
|
|
($LastError = 6, return) unless $hrasconn && $hrasconn !~ /\D/; |
2665
|
|
|
|
|
|
|
|
2666
|
0
|
|
0
|
|
|
|
$RasGetConnectStatus ||= new("rasapi32", "RasGetConnectStatus", [N,P], N); |
2667
|
|
|
|
|
|
|
|
2668
|
0
|
|
|
|
|
|
my $dwSize = 4+4+4 + RAS_MaxDeviceType+1 + RAS_MaxDeviceName+1; |
2669
|
|
|
|
|
|
|
|
2670
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
2671
|
|
|
|
|
|
|
|
2672
|
0
|
|
|
|
|
|
my $RASCONNSTATUS = pack "La".($dwSize-4), ($dwSize, ""); |
2673
|
|
|
|
|
|
|
|
2674
|
0
|
|
|
|
|
|
my ($ret, $dwError); |
2675
|
0
|
|
|
|
|
|
$ret = $RasGetConnectStatus->Call($hrasconn, $RASCONNSTATUS); |
2676
|
|
|
|
|
|
|
|
2677
|
0
|
0
|
|
|
|
|
$ret == 6 and ($LastError = 6, return); # invalid handle |
2678
|
|
|
|
|
|
|
|
2679
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
2680
|
|
|
|
|
|
|
|
2681
|
|
|
|
|
|
|
# don't know why do we need another error code if the function |
2682
|
|
|
|
|
|
|
# itself returns one |
2683
|
|
|
|
|
|
|
#$dwError = unpack L, substr($RASCONNSTATUS, 8,4) and RASERROR($dwError); |
2684
|
|
|
|
|
|
|
|
2685
|
0
|
|
|
|
|
|
my $status = unpack "L", substr($RASCONNSTATUS, 4,4); |
2686
|
0
|
0
|
|
|
|
|
wantarray ? ($status, $RASCS{$status}) : $status; |
2687
|
|
|
|
|
|
|
} |
2688
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
=item RasDialDlg ( ) |
2690
|
|
|
|
|
|
|
|
2691
|
|
|
|
|
|
|
This function tries to establish a RAS connection using |
2692
|
|
|
|
|
|
|
a specified phonebook entry and the credentials of the logged-on user. |
2693
|
|
|
|
|
|
|
It displays a stream of dialog boxes that indicate the state of the connection |
2694
|
|
|
|
|
|
|
operation and returns when the connection is established, |
2695
|
|
|
|
|
|
|
or when the user cancels the operation. B |
2696
|
|
|
|
|
|
|
|
2697
|
|
|
|
|
|
|
RasDialDlg( $EntryName [, $hwnd, $PhoneNumber] ); |
2698
|
|
|
|
|
|
|
|
2699
|
|
|
|
|
|
|
$EntryName - RAS/DUN entry, the only mandatory parameter |
2700
|
|
|
|
|
|
|
$hwnd - Identifies the window that owns the modal RasDialDlg |
2701
|
|
|
|
|
|
|
dialog boxes. |
2702
|
|
|
|
|
|
|
This member can be any valid window handle, or it can |
2703
|
|
|
|
|
|
|
be 0, undef (or omitted) if the dialog box has no owner |
2704
|
|
|
|
|
|
|
|
2705
|
|
|
|
|
|
|
The dialog box is centered on the owner window unless C<$hwnd> is C |
2706
|
|
|
|
|
|
|
or invalid handle, in which case the dialog box is centered on the screen. |
2707
|
|
|
|
|
|
|
|
2708
|
|
|
|
|
|
|
$PhoneNumber - an overriding phone number (if not needed - use "" or |
2709
|
|
|
|
|
|
|
undef). |
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
It does not inherit anything from phonebook if specified - no prefix, |
2712
|
|
|
|
|
|
|
no callin card, no waiting. |
2713
|
|
|
|
|
|
|
You should even add DP before the number for pulse dialing. |
2714
|
|
|
|
|
|
|
|
2715
|
|
|
|
|
|
|
Returns TRUE on success, FALSE if user selects "Cancel" button or an error occurs. |
2716
|
|
|
|
|
|
|
You can check the last case with C. |
2717
|
|
|
|
|
|
|
|
2718
|
|
|
|
|
|
|
if ( RasDialDlg("NEV4") ) { |
2719
|
|
|
|
|
|
|
print "Connection established\n"; |
2720
|
|
|
|
|
|
|
} elsif ( !Win32::RASE::GetLastError ) { |
2721
|
|
|
|
|
|
|
print "User selected \n"; |
2722
|
|
|
|
|
|
|
} else { |
2723
|
|
|
|
|
|
|
warn Win32::RASE::FormatMessage(), "\n"; |
2724
|
|
|
|
|
|
|
} |
2725
|
|
|
|
|
|
|
|
2726
|
|
|
|
|
|
|
=cut |
2727
|
|
|
|
|
|
|
|
2728
|
|
|
|
|
|
|
#================ |
2729
|
|
|
|
|
|
|
sub RasDialDlg ($;$$) { |
2730
|
|
|
|
|
|
|
#================ |
2731
|
0
|
|
|
0
|
|
|
$LastError = 0; |
2732
|
0
|
|
|
|
|
|
RASCROAK "this function works on NT only" unless Win32::IsWinNT; |
2733
|
|
|
|
|
|
|
|
2734
|
0
|
|
0
|
|
|
|
$RasDialDlg ||= new("rasdlg", "RasDialDlg", [P,P,P,P], N); |
2735
|
|
|
|
|
|
|
|
2736
|
0
|
|
|
|
|
|
my ($entry, $hwnd, $lpszPhoneNumber) = @_; |
2737
|
0
|
|
|
|
|
|
my $dwSize = 36; |
2738
|
|
|
|
|
|
|
|
2739
|
0
|
0
|
0
|
|
|
|
$hwnd = 0 if $hwnd && !IsWindow($hwnd); |
2740
|
|
|
|
|
|
|
|
2741
|
0
|
|
0
|
|
|
|
my $RASDIALDLG = pack "LLa".($dwSize-8), ($dwSize, $hwnd||0, ""); |
2742
|
|
|
|
|
|
|
|
2743
|
0
|
0
|
0
|
|
|
|
my $ret = $RasDialDlg->Call($PHONEBOOK||0, |
|
|
|
0
|
|
|
|
|
2744
|
|
|
|
|
|
|
$entry, $lpszPhoneNumber||0, $RASDIALDLG) and return 1; |
2745
|
|
|
|
|
|
|
|
2746
|
0
|
|
|
|
|
|
$LastError = unpack "L", substr($RASDIALDLG, 6*4,4); |
2747
|
0
|
|
|
|
|
|
return; |
2748
|
|
|
|
|
|
|
} |
2749
|
|
|
|
|
|
|
|
2750
|
|
|
|
|
|
|
=item RasDial ( ) |
2751
|
|
|
|
|
|
|
|
2752
|
|
|
|
|
|
|
This function establishes a RAS/DUN connection. The connection data includes |
2753
|
|
|
|
|
|
|
callback and user authentication information. |
2754
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
$hrasconn = RasDial($EntryName, $PhoneNumber, $UserName, $Password, |
2756
|
|
|
|
|
|
|
$Domain, $CallbackNumber); |
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
$EntryName - RAS/DUN entry, the only mandatory parameter |
2759
|
|
|
|
|
|
|
$PhoneNumber - an overriding phone number (if not needed - use "" or |
2760
|
|
|
|
|
|
|
undef). |
2761
|
|
|
|
|
|
|
|
2762
|
|
|
|
|
|
|
It does not inherit anything from the phonebook if specified - |
2763
|
|
|
|
|
|
|
no prefix, no calling card, no waiting. |
2764
|
|
|
|
|
|
|
You should add DP before the number for pulse dialing. |
2765
|
|
|
|
|
|
|
|
2766
|
|
|
|
|
|
|
$UserName - user's user name (look below) |
2767
|
|
|
|
|
|
|
$Password - user's password |
2768
|
|
|
|
|
|
|
$Domain - domain on which authentication is to occur. An empty |
2769
|
|
|
|
|
|
|
string ("" or undef) specifies the domain in which the remote |
2770
|
|
|
|
|
|
|
access server is a member (NT only). An asterisk specifies the |
2771
|
|
|
|
|
|
|
domain stored in the phonebook for the entry. |
2772
|
|
|
|
|
|
|
It's in addr form (size is limited to 15 chars). |
2773
|
|
|
|
|
|
|
$CallbackNumber - a callback phone number. An empty string ("") or |
2774
|
|
|
|
|
|
|
undef indicates that callback should not be used. This string is |
2775
|
|
|
|
|
|
|
ignored unless the user has "Set By Caller" callback permission |
2776
|
|
|
|
|
|
|
on the RAS server (NT only). An asterisk indicates that the number |
2777
|
|
|
|
|
|
|
stored in the phonebook should be used for callback. |
2778
|
|
|
|
|
|
|
|
2779
|
|
|
|
|
|
|
B |
2780
|
|
|
|
|
|
|
[These 2 paragraphs are copied from the API docs. I wanted to add this |
2781
|
|
|
|
|
|
|
for some completeness but I was told that probably this is not truth and if |
2782
|
|
|
|
|
|
|
Username or Password are empty user will get a dialog box with Username/Password |
2783
|
|
|
|
|
|
|
prompts.] |
2784
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
RAS does not actually log the user onto the network. The user does this in the usual |
2786
|
|
|
|
|
|
|
manner, for example, by logging on with cached credentials prior to making the |
2787
|
|
|
|
|
|
|
connection or by using CTRL+ALT+DEL, after the RAS connection is established. |
2788
|
|
|
|
|
|
|
|
2789
|
|
|
|
|
|
|
If both the UserName and Password members are empty strings (""), RAS uses the |
2790
|
|
|
|
|
|
|
user name and password of the current logon context for authentication. For a user |
2791
|
|
|
|
|
|
|
mode application, RAS uses the credentials of the currently logged-on interactive user. |
2792
|
|
|
|
|
|
|
For a Win32 service process, RAS uses the credentials associated with the service. |
2793
|
|
|
|
|
|
|
|
2794
|
|
|
|
|
|
|
B |
2795
|
|
|
|
|
|
|
|
2796
|
|
|
|
|
|
|
RAS uses the UserName and Password strings to log the user onto the network. |
2797
|
|
|
|
|
|
|
Windows 95 cannot get the password of the currently logged-on user, so if both |
2798
|
|
|
|
|
|
|
the UserName and the Password members are empty strings ("" or undef), RAS leaves |
2799
|
|
|
|
|
|
|
the user name and password empty during authentication. I.e. it provides no |
2800
|
|
|
|
|
|
|
additional search (look at C for that). |
2801
|
|
|
|
|
|
|
|
2802
|
|
|
|
|
|
|
|
2803
|
|
|
|
|
|
|
B It seems that overriding phone number is being dialed "as is" - without using |
2804
|
|
|
|
|
|
|
any long-distance/international phone settings. So you have to provide this number |
2805
|
|
|
|
|
|
|
with all prefixes and waitings (W etc.) if needed. Additional |
2806
|
|
|
|
|
|
|
dashes, blanks and brackets are OK. |
2807
|
|
|
|
|
|
|
|
2808
|
|
|
|
|
|
|
$hrasconn - on success - handle to active RAS/DUN connection, |
2809
|
|
|
|
|
|
|
otherwise undef |
2810
|
|
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
|
2812
|
|
|
|
|
|
|
You can use C<$hrasconn> in C or C. |
2813
|
|
|
|
|
|
|
Note that this function calls C internally on error, so after that, |
2814
|
|
|
|
|
|
|
the handle of the failed connection is not available and the port is ready |
2815
|
|
|
|
|
|
|
for the next try. |
2816
|
|
|
|
|
|
|
|
2817
|
|
|
|
|
|
|
B |
2818
|
|
|
|
|
|
|
|
2819
|
|
|
|
|
|
|
($err, $errtext) = RasDial("CLICK",undef,"ppblazer","qwerty"); |
2820
|
|
|
|
|
|
|
if ($err) { |
2821
|
|
|
|
|
|
|
print "$err, $errtext\n"; exit; |
2822
|
|
|
|
|
|
|
} else { |
2823
|
|
|
|
|
|
|
... your work here ... |
2824
|
|
|
|
|
|
|
} |
2825
|
|
|
|
|
|
|
|
2826
|
|
|
|
|
|
|
B this is the B operation. Nobody knows if it could really |
2827
|
|
|
|
|
|
|
hang fast enough if the line is busy (for ex.) The best way would be to run C |
2828
|
|
|
|
|
|
|
in the separate process or thread. In most cases you don't really need C<$hrasconn> |
2829
|
|
|
|
|
|
|
in the main process - you can terminate the connection at any time with C. |
2830
|
|
|
|
|
|
|
Or you can easily get C<$hrasconn> with the use of C. |
2831
|
|
|
|
|
|
|
|
2832
|
|
|
|
|
|
|
If you run C in a child-process and terminate dialing in progress (for ex. |
2833
|
|
|
|
|
|
|
on timeout) you have to free the port yourself (C or C). |
2834
|
|
|
|
|
|
|
|
2835
|
|
|
|
|
|
|
For more info take a look at Win32 API docs (RASDIALPARAMS etc). |
2836
|
|
|
|
|
|
|
|
2837
|
|
|
|
|
|
|
Command line syntax: |
2838
|
|
|
|
|
|
|
|
2839
|
|
|
|
|
|
|
perl -MWin32::RASE -e RasDial(NEV1,undef,ppblazer,'6hTR7dwA') |
2840
|
|
|
|
|
|
|
perl -MWin32::RASE -e "RasDial(NEV1,undef,ppblazer,'6hTR7dwA') or print Win32::RASE::FormatMessage" |
2841
|
|
|
|
|
|
|
perl -MWin32::RASE -e "print RasDial(NEV1,undef,ppblazer,'6hTR7dwA')||Win32::RASE::FormatMessage" |
2842
|
|
|
|
|
|
|
|
2843
|
|
|
|
|
|
|
=cut |
2844
|
|
|
|
|
|
|
|
2845
|
|
|
|
|
|
|
#================ |
2846
|
|
|
|
|
|
|
sub RasDial ($;$$$$$) { |
2847
|
|
|
|
|
|
|
#================ |
2848
|
0
|
|
|
0
|
|
|
my ($szEntryName, $szPhoneNumber, $szUserName, |
2849
|
|
|
|
|
|
|
$szPassword, $szDomain, $szCallbackNumber) = @_; |
2850
|
0
|
|
|
|
|
|
$LastError = 0; |
2851
|
|
|
|
|
|
|
|
2852
|
0
|
0
|
0
|
|
|
|
RASCROAK "entry-name and alt phone-number can't be both empty" |
2853
|
|
|
|
|
|
|
unless $szEntryName || $szPhoneNumber; |
2854
|
|
|
|
|
|
|
|
2855
|
0
|
|
0
|
|
|
|
$RasDial ||= new("rasapi32", "RasDial", [P,P,P,N,P,P], N); |
2856
|
|
|
|
|
|
|
|
2857
|
0
|
0
|
|
|
|
|
my $dwSize = 4 + RAS_MaxEntryName + 1 + RAS_MaxPhoneNumber + 1 + |
2858
|
|
|
|
|
|
|
RAS_MaxCallbackNumber + 1 + UNLEN + 1 + PWLEN + 1 + DNLEN + 1 + |
2859
|
|
|
|
|
|
|
(Win32::IsWinNT && $WINVER >= 0x401 ? 4+4 : 0); |
2860
|
|
|
|
|
|
|
|
2861
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
2862
|
|
|
|
|
|
|
|
2863
|
0
|
|
0
|
|
|
|
my $RASDIALPARAMS = |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2864
|
|
|
|
|
|
|
pack "La".(RAS_MaxEntryName + 1)."a".(RAS_MaxPhoneNumber + 1). |
2865
|
|
|
|
|
|
|
"a".(RAS_MaxCallbackNumber + 1)."a".(UNLEN + 1). |
2866
|
|
|
|
|
|
|
"a".(PWLEN + 1)."a".(DNLEN + 1) |
2867
|
|
|
|
|
|
|
, |
2868
|
|
|
|
|
|
|
($dwSize, $szEntryName||"", $szPhoneNumber||"", $szCallbackNumber||"", |
2869
|
|
|
|
|
|
|
$szUserName||"", $szPassword||"", $szDomain||""); |
2870
|
|
|
|
|
|
|
|
2871
|
0
|
|
|
|
|
|
$RASDIALPARAMS .= "\0"x($dwSize - length $RASDIALPARAMS); |
2872
|
|
|
|
|
|
|
|
2873
|
0
|
|
|
|
|
|
my $lphRasConn = DWORD_NULL; |
2874
|
0
|
|
0
|
|
|
|
my $ret = $RasDial->Call(0, $PHONEBOOK||0, |
2875
|
|
|
|
|
|
|
$RASDIALPARAMS, 0, 0, $lphRasConn); |
2876
|
|
|
|
|
|
|
|
2877
|
0
|
|
|
|
|
|
my $hrasconn = unpack "L", $lphRasConn; |
2878
|
|
|
|
|
|
|
|
2879
|
0
|
0
|
|
|
|
|
if ($ret) { |
2880
|
0
|
0
|
|
|
|
|
RasHangUp($hrasconn) if $hrasconn; |
2881
|
0
|
|
|
|
|
|
$LastError = $ret, return; |
2882
|
|
|
|
|
|
|
} else { |
2883
|
0
|
|
|
|
|
|
return $hrasconn; |
2884
|
|
|
|
|
|
|
} |
2885
|
|
|
|
|
|
|
} |
2886
|
|
|
|
|
|
|
|
2887
|
|
|
|
|
|
|
|
2888
|
|
|
|
|
|
|
=pod |
2889
|
|
|
|
|
|
|
|
2890
|
|
|
|
|
|
|
=back |
2891
|
|
|
|
|
|
|
|
2892
|
|
|
|
|
|
|
B< =====================================> |
2893
|
|
|
|
|
|
|
|
2894
|
|
|
|
|
|
|
B< TAPI RELATED FUNCTIONS> |
2895
|
|
|
|
|
|
|
|
2896
|
|
|
|
|
|
|
B< =====================================> |
2897
|
|
|
|
|
|
|
|
2898
|
|
|
|
|
|
|
|
2899
|
|
|
|
|
|
|
=over 4 |
2900
|
|
|
|
|
|
|
|
2901
|
|
|
|
|
|
|
=item RasEnumDevices ( ) |
2902
|
|
|
|
|
|
|
|
2903
|
|
|
|
|
|
|
%devices = RasEnumDevices(); |
2904
|
|
|
|
|
|
|
|
2905
|
|
|
|
|
|
|
This function returns the name and type of all available RAS-capable devices. |
2906
|
|
|
|
|
|
|
In the C<%devices> hash device names are keys and types are values. Common |
2907
|
|
|
|
|
|
|
device types are "modem", "x25", "vpn", "isdn", "rastapi" etc. |
2908
|
|
|
|
|
|
|
|
2909
|
|
|
|
|
|
|
Croaks on errors. Returns FALSE if no one RAS capable device was found. |
2910
|
|
|
|
|
|
|
|
2911
|
|
|
|
|
|
|
For example the first RAS-capable device name is |
2912
|
|
|
|
|
|
|
|
2913
|
|
|
|
|
|
|
$DeviceName = (RasEnumDevices())[0]; |
2914
|
|
|
|
|
|
|
|
2915
|
|
|
|
|
|
|
This function fills out a non-exported hash C<%Win32::RASE::RasDevEnumeration> |
2916
|
|
|
|
|
|
|
of the same structure as C<%devices>, so in most cases there is no need to call |
2917
|
|
|
|
|
|
|
this function more then once. |
2918
|
|
|
|
|
|
|
|
2919
|
|
|
|
|
|
|
Command line syntax: |
2920
|
|
|
|
|
|
|
|
2921
|
|
|
|
|
|
|
perl -MWin32::RASE -e "print ((RasEnumDevices)[0])" |
2922
|
|
|
|
|
|
|
|
2923
|
|
|
|
|
|
|
=cut |
2924
|
|
|
|
|
|
|
|
2925
|
|
|
|
|
|
|
#================ |
2926
|
|
|
|
|
|
|
sub RasEnumDevices () { |
2927
|
|
|
|
|
|
|
#================ |
2928
|
0
|
|
|
0
|
|
|
$LastError = 0; |
2929
|
0
|
|
0
|
|
|
|
$RasEnumDevices ||= new("rasapi32", "RasEnumDevices",[P,P,P],N); |
2930
|
|
|
|
|
|
|
|
2931
|
0
|
|
|
|
|
|
my $dwSize = RAS_MaxDeviceType+1+RAS_MaxDeviceName+1+4; |
2932
|
|
|
|
|
|
|
|
2933
|
0
|
|
|
|
|
|
DWORD_ALIGN($dwSize); |
2934
|
|
|
|
|
|
|
|
2935
|
0
|
|
|
|
|
|
my $RASDEVINFO = pack "La".(10*$dwSize-4), ($dwSize, ""); # 10 devices initially |
2936
|
|
|
|
|
|
|
|
2937
|
0
|
|
|
|
|
|
my ($lpcb, $lpcDevices) = (pack("L",length $RASDEVINFO), DWORD_NULL); |
2938
|
|
|
|
|
|
|
|
2939
|
0
|
|
|
|
|
|
my $ret = $RasEnumDevices->Call($RASDEVINFO, $lpcb, $lpcDevices); |
2940
|
|
|
|
|
|
|
|
2941
|
0
|
0
|
|
|
|
|
if ($ret) { |
2942
|
0
|
|
|
|
|
|
my $b = unpack "L",$lpcb; |
2943
|
0
|
|
|
|
|
|
$RASDEVINFO = pack "La".($b-4), ($dwSize, ""); |
2944
|
0
|
|
|
|
|
|
$ret = $RasEnumDevices->Call($RASDEVINFO, $lpcb, $lpcDevices); |
2945
|
|
|
|
|
|
|
} |
2946
|
|
|
|
|
|
|
|
2947
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
2948
|
|
|
|
|
|
|
|
2949
|
0
|
|
|
|
|
|
my %devices; |
2950
|
|
|
|
|
|
|
|
2951
|
0
|
|
|
|
|
|
for my $i(1..unpack "L",$lpcDevices) { |
2952
|
0
|
|
|
|
|
|
my $buffer = substr $RASDEVINFO, ($dwSize*($i-1)), $dwSize; |
2953
|
0
|
|
|
|
|
|
my ($dwSize1, $szDeviceType, $szDeviceName) = |
2954
|
|
|
|
|
|
|
unpack "La".(RAS_MaxDeviceType+1)."a".(RAS_MaxDeviceName+1), $buffer; |
2955
|
|
|
|
|
|
|
|
2956
|
0
|
|
|
|
|
|
CRUNCH($szDeviceType, $szDeviceName); |
2957
|
0
|
|
|
|
|
|
$devices{$szDeviceName} = $szDeviceType; |
2958
|
|
|
|
|
|
|
} |
2959
|
0
|
|
|
|
|
|
%RasDevEnumeration = %devices; |
2960
|
|
|
|
|
|
|
} |
2961
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
=item RasEnumDevicesByType ( ) |
2963
|
|
|
|
|
|
|
|
2964
|
|
|
|
|
|
|
The easier version of previous. |
2965
|
|
|
|
|
|
|
|
2966
|
|
|
|
|
|
|
@DevNames = RasEnumDevicesByType( $devtype ); |
2967
|
|
|
|
|
|
|
|
2968
|
|
|
|
|
|
|
Returns names of RAS-capable devices of type C<$devtype>. For example |
2969
|
|
|
|
|
|
|
the first modem's name |
2970
|
|
|
|
|
|
|
|
2971
|
|
|
|
|
|
|
$ModemName = (RasEnumDevicesByType("modem"))[0]; |
2972
|
|
|
|
|
|
|
|
2973
|
|
|
|
|
|
|
C<$devtype> is case insensitive. |
2974
|
|
|
|
|
|
|
|
2975
|
|
|
|
|
|
|
=cut |
2976
|
|
|
|
|
|
|
|
2977
|
|
|
|
|
|
|
#============================= |
2978
|
|
|
|
|
|
|
sub RasEnumDevicesByType ($) { |
2979
|
|
|
|
|
|
|
#============================= |
2980
|
0
|
|
|
0
|
|
|
my $type = shift; |
2981
|
0
|
0
|
|
|
|
|
%RasDevEnumeration = RasEnumDevices() unless defined %RasDevEnumeration; |
2982
|
|
|
|
|
|
|
|
2983
|
0
|
|
|
|
|
|
grep {lc($RasDevEnumeration{$_}) eq lc($type)} keys %RasDevEnumeration; |
|
0
|
|
|
|
|
|
|
2984
|
|
|
|
|
|
|
} |
2985
|
|
|
|
|
|
|
|
2986
|
|
|
|
|
|
|
=item TAPIlineGetTranslateCaps ( ) |
2987
|
|
|
|
|
|
|
|
2988
|
|
|
|
|
|
|
This function is not exported and is not intended for public use. |
2989
|
|
|
|
|
|
|
It is called each time you load Win32::RASE and fills out 3 global variables |
2990
|
|
|
|
|
|
|
and global hash (below). |
2991
|
|
|
|
|
|
|
|
2992
|
|
|
|
|
|
|
It takes local information from your dialup settings. |
2993
|
|
|
|
|
|
|
|
2994
|
|
|
|
|
|
|
($countryID, $countryCode, $areaCode) = |
2995
|
|
|
|
|
|
|
Win32::RASE::TAPIlineGetTranslateCaps (); |
2996
|
|
|
|
|
|
|
|
2997
|
|
|
|
|
|
|
The return values are describing the B that is selected |
2998
|
|
|
|
|
|
|
in you dialing properties. |
2999
|
|
|
|
|
|
|
|
3000
|
|
|
|
|
|
|
$countryID - the unique number that TAPI assigns to each country. |
3001
|
|
|
|
|
|
|
It is not what you are typing on your phone, though it |
3002
|
|
|
|
|
|
|
sometimes has the same value. Different countries always |
3003
|
|
|
|
|
|
|
have different countryID. This allows multiple entries |
3004
|
|
|
|
|
|
|
to exist in the country list with the same country code |
3005
|
|
|
|
|
|
|
(for example, all countries in North America and the |
3006
|
|
|
|
|
|
|
Caribbean share country code 1, but require separate |
3007
|
|
|
|
|
|
|
entries in the list). |
3008
|
|
|
|
|
|
|
|
3009
|
|
|
|
|
|
|
$countryCode - this really is the code that would be dialed in an |
3010
|
|
|
|
|
|
|
international call to your computer's location. |
3011
|
|
|
|
|
|
|
|
3012
|
|
|
|
|
|
|
$areaCode - city or area code (local). |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
These 3 values are copied to non-exported global variables |
3015
|
|
|
|
|
|
|
B<$Win32::RASE::LOCAL_ID>, B<$Win32::RASE::LOCAL_CODE> and |
3016
|
|
|
|
|
|
|
B<$Win32::RASE::LOCAL_AREA>. |
3017
|
|
|
|
|
|
|
|
3018
|
|
|
|
|
|
|
They are mainly for internal use, just note that they are here. |
3019
|
|
|
|
|
|
|
|
3020
|
|
|
|
|
|
|
The complete TAPI countries list is being copied to non-exported global hash |
3021
|
|
|
|
|
|
|
B<%Win32::RASE::TAPIEnumeration>. Keys are countryID's, each value points |
3022
|
|
|
|
|
|
|
to 3-element array: [0] is country-name, [1] is countryCode described above, |
3023
|
|
|
|
|
|
|
[2] is NextCountryID in TAPI-enumeration (TAPI docs, but in most cases you |
3024
|
|
|
|
|
|
|
don't need to use this hash explicitly). |
3025
|
|
|
|
|
|
|
|
3026
|
|
|
|
|
|
|
Use C to print this hash (for fun ;) |
3027
|
|
|
|
|
|
|
|
3028
|
|
|
|
|
|
|
=cut |
3029
|
|
|
|
|
|
|
|
3030
|
|
|
|
|
|
|
#================ |
3031
|
|
|
|
|
|
|
sub TAPIlineGetTranslateCaps () { |
3032
|
|
|
|
|
|
|
#================ |
3033
|
0
|
|
|
0
|
|
|
$LastError = 0; |
3034
|
0
|
|
|
|
|
|
my ($CurrentLocation, %locations) = TAPIEnumLocations(); |
3035
|
0
|
|
|
|
|
|
($LOCAL_ID, $LOCAL_CODE, $LOCAL_AREA) = @{$locations{$CurrentLocation}}[0,1,2]; |
|
0
|
|
|
|
|
|
|
3036
|
|
|
|
|
|
|
|
3037
|
0
|
0
|
|
|
|
|
IsCountryID($LOCAL_ID) or |
3038
|
|
|
|
|
|
|
RASCROAK "TAPI could not find your local settings\nPlease, contact the author of this module."; |
3039
|
|
|
|
|
|
|
|
3040
|
0
|
0
|
0
|
|
|
|
TAPICountryCode($LOCAL_ID) == $LOCAL_CODE and $LOCAL_AREA !~ /\D/ or |
3041
|
|
|
|
|
|
|
RASCROAK "TAPI-error. Please adjust your dialing properties."; |
3042
|
|
|
|
|
|
|
|
3043
|
0
|
|
|
|
|
|
($LOCAL_ID, $LOCAL_CODE, $LOCAL_AREA); |
3044
|
|
|
|
|
|
|
} |
3045
|
|
|
|
|
|
|
|
3046
|
|
|
|
|
|
|
=item TAPIEnumLocations ( ) |
3047
|
|
|
|
|
|
|
|
3048
|
|
|
|
|
|
|
Just a handy function (non-exported) to enumerate locations in your Dialing Properties. |
3049
|
|
|
|
|
|
|
It's being executed internally when Win32::RASE needs it, so in most cases you don't |
3050
|
|
|
|
|
|
|
need to use it explicitly. |
3051
|
|
|
|
|
|
|
|
3052
|
|
|
|
|
|
|
($CurrentLocation, %locations) = Win32::RASE::TAPIEnumLocations; |
3053
|
|
|
|
|
|
|
|
3054
|
|
|
|
|
|
|
$CurrentLocation - current dialing location's name |
3055
|
|
|
|
|
|
|
%locations - keys are location-names, values are anonymous |
3056
|
|
|
|
|
|
|
arrays that are filled out like: |
3057
|
|
|
|
|
|
|
[$CountryID, $CountryCode, $CityCode, $Options, $LocalAccessCode, |
3058
|
|
|
|
|
|
|
$LongDistanceAccessCode, $TollPrefixList, $PermanentLocationID] |
3059
|
|
|
|
|
|
|
|
3060
|
|
|
|
|
|
|
$Options - 0/1 tone/pulse dialing, this value could be |
3061
|
|
|
|
|
|
|
used to define good timeout for RasDial() |
3062
|
|
|
|
|
|
|
$LocalAccessCode - the access code to be dialed before calls to |
3063
|
|
|
|
|
|
|
addresses in the local calling area |
3064
|
|
|
|
|
|
|
$LongDistanceAccessCode - the access code to be dialed before calls to |
3065
|
|
|
|
|
|
|
addresses outside the local calling area |
3066
|
|
|
|
|
|
|
$TollPrefixList - the toll prefix list for the location. The |
3067
|
|
|
|
|
|
|
string will contain only prefixes consisting |
3068
|
|
|
|
|
|
|
of the digits "0" through "9", separated |
3069
|
|
|
|
|
|
|
from each other by a single comma |
3070
|
|
|
|
|
|
|
$PermanentLocationID - internal unique identifier of the location |
3071
|
|
|
|
|
|
|
|
3072
|
|
|
|
|
|
|
Other values in array are described in C. |
3073
|
|
|
|
|
|
|
|
3074
|
|
|
|
|
|
|
B |
3075
|
|
|
|
|
|
|
|
3076
|
|
|
|
|
|
|
($CurrentLocation, %locations) = Win32::RASE::TAPIEnumLocations; |
3077
|
|
|
|
|
|
|
print "$CurrentLocation\n"; |
3078
|
|
|
|
|
|
|
print map "$_ => [".(join", ",@{$locations{$_}})."]\n", |
3079
|
|
|
|
|
|
|
keys %locations; |
3080
|
|
|
|
|
|
|
|
3081
|
|
|
|
|
|
|
|
3082
|
|
|
|
|
|
|
=cut |
3083
|
|
|
|
|
|
|
|
3084
|
|
|
|
|
|
|
#================ |
3085
|
|
|
|
|
|
|
sub TAPIEnumLocations () { |
3086
|
|
|
|
|
|
|
#================ |
3087
|
0
|
|
|
0
|
|
|
$LastError = 0; |
3088
|
0
|
|
|
|
|
|
my ($dwTotalSize, $dwNeededSize, $dwUsedSize, $dwNumLocations, |
3089
|
|
|
|
|
|
|
$dwLocationListSize, $dwLocationListOffset, $dwCurrentLocationID, |
3090
|
|
|
|
|
|
|
$dwNumCards, $dwCardListSize, $dwCardListOffset, $dwCurrentPreferredCardID); |
3091
|
0
|
|
|
|
|
|
my ($dwPermanentLocationID, $dwLocationNameSize, $dwLocationNameOffset, |
3092
|
|
|
|
|
|
|
$dwCountryCode, $dwCityCodeSize, $dwCityCodeOffset, $dwPreferredCardID, |
3093
|
|
|
|
|
|
|
$dwLocalAccessCodeSize, $dwLocalAccessCodeOffset, $dwLongDistanceAccessCodeSize, |
3094
|
|
|
|
|
|
|
$dwLongDistanceAccessCodeOffset, $dwTollPrefixListSize, $dwTollPrefixListOffset, |
3095
|
|
|
|
|
|
|
$dwCountryID, $dwOptions, $dwCancelCallWaitingSize, $dwCancelCallWaitingOffset); |
3096
|
0
|
|
|
|
|
|
my (%locations, $CityCode, $LocationName, $CurrentLocation, $LocalAccessCode, |
3097
|
|
|
|
|
|
|
$LongDistanceAccessCode, $TollPrefixList); |
3098
|
0
|
|
|
|
|
|
$dwTotalSize = 4*11; |
3099
|
|
|
|
|
|
|
|
3100
|
0
|
|
0
|
|
|
|
$lineGetTranslateCaps ||= new("tapi32", "lineGetTranslateCaps", [N,N,P], N); |
3101
|
|
|
|
|
|
|
|
3102
|
0
|
|
|
|
|
|
my $LINETRANSLATECAPS = pack "La".($dwTotalSize-4), ($dwTotalSize, ""); |
3103
|
|
|
|
|
|
|
|
3104
|
0
|
|
|
|
|
|
my $ret = $lineGetTranslateCaps->Call(0, 0x10004, $LINETRANSLATECAPS); |
3105
|
|
|
|
|
|
|
|
3106
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
3107
|
|
|
|
|
|
|
|
3108
|
0
|
|
|
|
|
|
($dwNeededSize, $dwUsedSize) = unpack "LL", substr($LINETRANSLATECAPS, 4); |
3109
|
|
|
|
|
|
|
|
3110
|
0
|
|
|
|
|
|
$LINETRANSLATECAPS = pack "La".($dwNeededSize-4), ($dwNeededSize, ""); |
3111
|
|
|
|
|
|
|
|
3112
|
0
|
|
|
|
|
|
$ret = $lineGetTranslateCaps->Call(0, 0x10004, $LINETRANSLATECAPS); |
3113
|
|
|
|
|
|
|
|
3114
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
3115
|
|
|
|
|
|
|
|
3116
|
0
|
|
|
|
|
|
($dwNeededSize, $dwUsedSize, $dwNumLocations, |
3117
|
|
|
|
|
|
|
$dwLocationListSize, $dwLocationListOffset, $dwCurrentLocationID, |
3118
|
|
|
|
|
|
|
$dwNumCards, $dwCardListSize, $dwCardListOffset, $dwCurrentPreferredCardID) = |
3119
|
|
|
|
|
|
|
unpack "LLLLLLLLLL", substr($LINETRANSLATECAPS, 4); |
3120
|
|
|
|
|
|
|
|
3121
|
0
|
|
|
|
|
|
for my $i(0..$dwNumLocations-1) { |
3122
|
0
|
|
|
|
|
|
($dwPermanentLocationID, $dwLocationNameSize, $dwLocationNameOffset, |
3123
|
|
|
|
|
|
|
$dwCountryCode, $dwCityCodeSize, $dwCityCodeOffset, $dwPreferredCardID, |
3124
|
|
|
|
|
|
|
$dwLocalAccessCodeSize, $dwLocalAccessCodeOffset, $dwLongDistanceAccessCodeSize, |
3125
|
|
|
|
|
|
|
$dwLongDistanceAccessCodeOffset, $dwTollPrefixListSize, $dwTollPrefixListOffset, |
3126
|
|
|
|
|
|
|
$dwCountryID, $dwOptions, $dwCancelCallWaitingSize, $dwCancelCallWaitingOffset) = |
3127
|
|
|
|
|
|
|
unpack "LLLLLLLLLLLLLLLLL", |
3128
|
|
|
|
|
|
|
# 4*17 - sizeof(LINELOCATIONENTRY) |
3129
|
|
|
|
|
|
|
substr($LINETRANSLATECAPS, $dwLocationListOffset+$i*4*17); |
3130
|
|
|
|
|
|
|
|
3131
|
0
|
|
|
|
|
|
$LocationName = substr($LINETRANSLATECAPS, $dwLocationNameOffset, $dwLocationNameSize); |
3132
|
0
|
|
|
|
|
|
$CityCode = substr($LINETRANSLATECAPS, $dwCityCodeOffset, $dwCityCodeSize); |
3133
|
0
|
|
|
|
|
|
$LocalAccessCode = substr($LINETRANSLATECAPS, $dwLocalAccessCodeOffset, $dwLocalAccessCodeSize); |
3134
|
0
|
|
|
|
|
|
$LongDistanceAccessCode = substr($LINETRANSLATECAPS, $dwLongDistanceAccessCodeOffset, $dwLongDistanceAccessCodeSize); |
3135
|
0
|
|
|
|
|
|
$TollPrefixList = substr($LINETRANSLATECAPS, $dwTollPrefixListOffset, $dwTollPrefixListSize); |
3136
|
|
|
|
|
|
|
|
3137
|
0
|
|
|
|
|
|
CRUNCH($LocationName, $CityCode, $LocalAccessCode, |
3138
|
|
|
|
|
|
|
$LongDistanceAccessCode, $TollPrefixList); |
3139
|
|
|
|
|
|
|
|
3140
|
0
|
|
|
|
|
|
$locations{$LocationName} = [$dwCountryID, $dwCountryCode, $CityCode, $dwOptions, |
3141
|
|
|
|
|
|
|
$LocalAccessCode, $LongDistanceAccessCode, $TollPrefixList, $dwPermanentLocationID]; |
3142
|
|
|
|
|
|
|
|
3143
|
0
|
0
|
|
|
|
|
$CurrentLocation = $LocationName if $dwCurrentLocationID == $dwPermanentLocationID; |
3144
|
|
|
|
|
|
|
} |
3145
|
|
|
|
|
|
|
|
3146
|
0
|
|
|
|
|
|
($CurrentLocation, %locations); |
3147
|
|
|
|
|
|
|
} |
3148
|
|
|
|
|
|
|
|
3149
|
|
|
|
|
|
|
=item TAPISetCurrentLocation ( ) |
3150
|
|
|
|
|
|
|
|
3151
|
|
|
|
|
|
|
TAPISetCurrentLocation( $location ); |
3152
|
|
|
|
|
|
|
|
3153
|
|
|
|
|
|
|
$location - optional, the name of the location that is configured |
3154
|
|
|
|
|
|
|
in the Dialing Properies. |
3155
|
|
|
|
|
|
|
If omitted the "Default Location" is used. |
3156
|
|
|
|
|
|
|
|
3157
|
|
|
|
|
|
|
Returns TRUE on success, FALSE if C<$location> was not found in the |
3158
|
|
|
|
|
|
|
Dialing Properties, croaks on TAPI errors. |
3159
|
|
|
|
|
|
|
|
3160
|
|
|
|
|
|
|
=cut |
3161
|
|
|
|
|
|
|
|
3162
|
|
|
|
|
|
|
#================ |
3163
|
|
|
|
|
|
|
sub TAPISetCurrentLocation (;$) { |
3164
|
|
|
|
|
|
|
#================ |
3165
|
0
|
|
|
0
|
|
|
$LastError = 0; |
3166
|
0
|
|
0
|
|
|
|
my $location = shift || "Default Location"; |
3167
|
0
|
|
|
|
|
|
$location =~ s/^ *(.*?) *$/$1/; |
3168
|
0
|
|
|
|
|
|
my ($CurrentLocation, %locations) = TAPIEnumLocations(); |
3169
|
0
|
|
|
|
|
|
my $ret; |
3170
|
|
|
|
|
|
|
|
3171
|
0
|
0
|
|
|
|
|
exists($locations{$location}) or return; |
3172
|
|
|
|
|
|
|
|
3173
|
0
|
|
0
|
|
|
|
$lineSetCurrentLocation ||= new("tapi32", "lineSetCurrentLocation", [N,N], N); |
3174
|
|
|
|
|
|
|
|
3175
|
0
|
|
|
|
|
|
my $dwLocation = $locations{$location}->[7]; |
3176
|
|
|
|
|
|
|
|
3177
|
0
|
|
|
|
|
|
my $hLineApp = TAPIlineInitialize(); |
3178
|
|
|
|
|
|
|
|
3179
|
0
|
0
|
|
|
|
|
$ret = $lineSetCurrentLocation->Call($hLineApp, $dwLocation) and |
3180
|
|
|
|
|
|
|
(TAPIlineShutdown($hLineApp), RASERROR($ret)); |
3181
|
|
|
|
|
|
|
|
3182
|
|
|
|
|
|
|
|
3183
|
0
|
0
|
|
|
|
|
$ret = TAPIlineShutdown($hLineApp) and RASERROR($ret); |
3184
|
0
|
|
|
|
|
|
1; |
3185
|
|
|
|
|
|
|
} |
3186
|
|
|
|
|
|
|
|
3187
|
|
|
|
|
|
|
#================ |
3188
|
|
|
|
|
|
|
sub RasGetCountryInfo ($) { |
3189
|
|
|
|
|
|
|
#================ |
3190
|
0
|
|
0
|
0
|
|
|
$RasGetCountryInfo ||= new("rasapi32", "RasGetCountryInfo", [P,P], N); |
3191
|
|
|
|
|
|
|
|
3192
|
0
|
|
|
|
|
|
my $dwCountryId = shift; |
3193
|
0
|
|
|
|
|
|
my $dwSize = 20; |
3194
|
0
|
|
|
|
|
|
my $SizeBuf = 256; |
3195
|
0
|
|
|
|
|
|
my $RASCTRYINFO = pack "LLa".($SizeBuf-8), ($dwSize, $dwCountryId, ""); |
3196
|
|
|
|
|
|
|
|
3197
|
0
|
|
|
|
|
|
my $dwSizeBuf = pack "L", $SizeBuf; |
3198
|
0
|
|
|
|
|
|
my $ret = $RasGetCountryInfo->Call($RASCTRYINFO, $dwSizeBuf); |
3199
|
|
|
|
|
|
|
|
3200
|
0
|
0
|
|
|
|
|
if ($ret == 603) { |
3201
|
0
|
|
|
|
|
|
$SizeBuf = unpack "L", $dwSizeBuf; |
3202
|
0
|
|
|
|
|
|
$RASCTRYINFO = pack "LLa".($SizeBuf-8), ($dwSize, $dwCountryId, ""); |
3203
|
0
|
0
|
|
|
|
|
$ret = $RasGetCountryInfo->Call($RASCTRYINFO, $dwSizeBuf) and RASERROR($ret); |
3204
|
|
|
|
|
|
|
} |
3205
|
|
|
|
|
|
|
|
3206
|
0
|
0
|
|
|
|
|
$ret and RASERROR($ret); |
3207
|
|
|
|
|
|
|
|
3208
|
0
|
|
|
|
|
|
my ($dwNextCountryID, $dwCountryCode, $dwCountryNameOffset) = |
3209
|
|
|
|
|
|
|
unpack "x8 LLL", $RASCTRYINFO; |
3210
|
0
|
|
|
|
|
|
my $Country = substr $RASCTRYINFO, $dwCountryNameOffset; |
3211
|
|
|
|
|
|
|
|
3212
|
0
|
|
|
|
|
|
CRUNCH($Country); |
3213
|
|
|
|
|
|
|
|
3214
|
0
|
|
|
|
|
|
($Country, $dwCountryCode, $dwNextCountryID); |
3215
|
|
|
|
|
|
|
} |
3216
|
|
|
|
|
|
|
|
3217
|
|
|
|
|
|
|
#================ |
3218
|
|
|
|
|
|
|
sub TAPIEnumCountries () { |
3219
|
|
|
|
|
|
|
#================ |
3220
|
0
|
|
|
0
|
|
|
my $dwCountryId = 1; |
3221
|
0
|
|
|
|
|
|
my ($Country, $dwCountryCode, $dwNextCountryID, %cou); |
3222
|
|
|
|
|
|
|
|
3223
|
0
|
|
|
|
|
|
do { |
3224
|
0
|
|
|
|
|
|
($Country, $dwCountryCode, $dwNextCountryID) = RasGetCountryInfo($dwCountryId); |
3225
|
0
|
|
|
|
|
|
$cou{$dwCountryId} = [$Country, $dwCountryCode, $dwNextCountryID]; |
3226
|
0
|
|
|
|
|
|
$dwCountryId = $dwNextCountryID; |
3227
|
|
|
|
|
|
|
} until $dwNextCountryID == 0; |
3228
|
0
|
|
|
|
|
|
%cou; |
3229
|
|
|
|
|
|
|
} |
3230
|
|
|
|
|
|
|
|
3231
|
|
|
|
|
|
|
=item TAPIEnumerationPrint ( ) |
3232
|
|
|
|
|
|
|
|
3233
|
|
|
|
|
|
|
This function prints nicely formatted TAPI countries table that is stored in |
3234
|
|
|
|
|
|
|
the B<%Win32::RASE::TAPIEnumeration> (see above). Not exported by default; |
3235
|
|
|
|
|
|
|
|
3236
|
|
|
|
|
|
|
Win32::RASE::TAPIEnumerationPrint(); |
3237
|
|
|
|
|
|
|
|
3238
|
|
|
|
|
|
|
Columns: CountryID, CountryName, CountryCode, NextCountryID |
3239
|
|
|
|
|
|
|
|
3240
|
|
|
|
|
|
|
For more: C and TAPI docs. |
3241
|
|
|
|
|
|
|
|
3242
|
|
|
|
|
|
|
Always returns TRUE. |
3243
|
|
|
|
|
|
|
|
3244
|
|
|
|
|
|
|
=cut |
3245
|
|
|
|
|
|
|
|
3246
|
|
|
|
|
|
|
#================ |
3247
|
|
|
|
|
|
|
sub TAPIEnumerationPrint () { |
3248
|
|
|
|
|
|
|
#================ |
3249
|
0
|
|
|
0
|
|
|
my $maxlen = 0; |
3250
|
0
|
|
|
|
|
|
local $_; |
3251
|
0
|
|
|
|
|
|
$LastError = 0; |
3252
|
|
|
|
|
|
|
|
3253
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
3254
|
|
|
|
|
|
|
|
3255
|
0
|
|
|
|
|
|
for (keys %TAPIEnumeration) { |
3256
|
0
|
0
|
|
|
|
|
$maxlen = length($TAPIEnumeration{$_}->[0]) |
3257
|
|
|
|
|
|
|
if $maxlen < length $TAPIEnumeration{$_}->[0]; |
3258
|
|
|
|
|
|
|
} |
3259
|
|
|
|
|
|
|
|
3260
|
0
|
|
|
|
|
|
printf "%9s%".($maxlen-6)."s%16s %6s\n\n", "CountryID", "CountryName", |
3261
|
|
|
|
|
|
|
"CountryCode", "NextID"; |
3262
|
|
|
|
|
|
|
|
3263
|
0
|
|
|
|
|
|
map { printf "%6d %${maxlen}s %6d %6d\n", $_, $TAPIEnumeration{$_}->[0], |
|
0
|
|
|
|
|
|
|
3264
|
|
|
|
|
|
|
$TAPIEnumeration{$_}->[1], $TAPIEnumeration{$_}->[2]} sort keys %TAPIEnumeration; |
3265
|
0
|
|
|
|
|
|
1; |
3266
|
|
|
|
|
|
|
} |
3267
|
|
|
|
|
|
|
|
3268
|
|
|
|
|
|
|
=item TAPICountryName ( ) |
3269
|
|
|
|
|
|
|
|
3270
|
|
|
|
|
|
|
Returns CountryName by CountryID or FALSE if given CountryID does not |
3271
|
|
|
|
|
|
|
exist in TAPI-table. |
3272
|
|
|
|
|
|
|
|
3273
|
|
|
|
|
|
|
$CountryName = TAPICountryName($CountryID); |
3274
|
|
|
|
|
|
|
|
3275
|
|
|
|
|
|
|
Command line syntax: |
3276
|
|
|
|
|
|
|
|
3277
|
|
|
|
|
|
|
perl -MWin32::RASE -e "print TAPICountryName(1)" |
3278
|
|
|
|
|
|
|
|
3279
|
|
|
|
|
|
|
=cut |
3280
|
|
|
|
|
|
|
|
3281
|
|
|
|
|
|
|
#================ |
3282
|
|
|
|
|
|
|
sub TAPICountryName ($) { |
3283
|
|
|
|
|
|
|
#================ |
3284
|
0
|
|
|
0
|
|
|
my $CountryID = shift; |
3285
|
0
|
|
|
|
|
|
$LastError = 0; |
3286
|
|
|
|
|
|
|
|
3287
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
3288
|
0
|
0
|
|
|
|
|
exists($TAPIEnumeration{$CountryID}) ? $TAPIEnumeration{$CountryID}->[0] : undef; |
3289
|
|
|
|
|
|
|
} |
3290
|
|
|
|
|
|
|
|
3291
|
|
|
|
|
|
|
=item TAPICountryCode ( ) |
3292
|
|
|
|
|
|
|
|
3293
|
|
|
|
|
|
|
Returns CountryCode by CountryID or FALSE if given CountryID does not |
3294
|
|
|
|
|
|
|
exist in TAPI-table. |
3295
|
|
|
|
|
|
|
|
3296
|
|
|
|
|
|
|
$CountryCode = TAPICountryCode($CountryID); |
3297
|
|
|
|
|
|
|
|
3298
|
|
|
|
|
|
|
=cut |
3299
|
|
|
|
|
|
|
|
3300
|
|
|
|
|
|
|
#================ |
3301
|
|
|
|
|
|
|
sub TAPICountryCode ($) { |
3302
|
|
|
|
|
|
|
#================ |
3303
|
0
|
|
|
0
|
|
|
my $CountryID = shift; |
3304
|
0
|
|
|
|
|
|
$LastError = 0; |
3305
|
|
|
|
|
|
|
|
3306
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
3307
|
0
|
0
|
|
|
|
|
exists($TAPIEnumeration{$CountryID}) ? $TAPIEnumeration{$CountryID}->[1] : undef; |
3308
|
|
|
|
|
|
|
} |
3309
|
|
|
|
|
|
|
|
3310
|
|
|
|
|
|
|
=item IsCountryID ( ) |
3311
|
|
|
|
|
|
|
|
3312
|
|
|
|
|
|
|
Returns TRUE if given $CountryID exist in TAPI-table, otherwise FALSE. |
3313
|
|
|
|
|
|
|
|
3314
|
|
|
|
|
|
|
IsCountryID($CountryID); |
3315
|
|
|
|
|
|
|
|
3316
|
|
|
|
|
|
|
Just to have such a pretty name ;) |
3317
|
|
|
|
|
|
|
|
3318
|
|
|
|
|
|
|
=cut |
3319
|
|
|
|
|
|
|
|
3320
|
|
|
|
|
|
|
#================ |
3321
|
|
|
|
|
|
|
sub IsCountryID ($) { |
3322
|
|
|
|
|
|
|
#================ |
3323
|
0
|
|
|
0
|
|
|
my $CountryID = shift; |
3324
|
0
|
|
|
|
|
|
$LastError = 0; |
3325
|
|
|
|
|
|
|
|
3326
|
0
|
0
|
|
|
|
|
%TAPIEnumeration = TAPIEnumCountries() if !defined %TAPIEnumeration; |
3327
|
0
|
0
|
|
|
|
|
exists($TAPIEnumeration{$CountryID}) ? 1 : 0; |
3328
|
|
|
|
|
|
|
} |
3329
|
|
|
|
|
|
|
|
3330
|
|
|
|
|
|
|
#====================== |
3331
|
|
|
|
|
|
|
sub GetDefaultCommConfig ($) { |
3332
|
|
|
|
|
|
|
#====================== |
3333
|
0
|
0
|
|
0
|
|
|
my $dev = shift |
3334
|
|
|
|
|
|
|
or RASCROAK "empty DeviceName"; |
3335
|
|
|
|
|
|
|
|
3336
|
0
|
|
|
|
|
|
my $GetDefaultCommConfig = new("kernel32", "GetDefaultCommConfig", [P,P,P], N); |
3337
|
|
|
|
|
|
|
|
3338
|
0
|
|
|
|
|
|
my $lpCC = ""; |
3339
|
0
|
|
|
|
|
|
my $lpdwSize = DWORD_NULL; |
3340
|
|
|
|
|
|
|
|
3341
|
0
|
|
|
|
|
|
my $ret = $GetDefaultCommConfig->Call($dev, $lpCC, $lpdwSize); |
3342
|
0
|
|
|
|
|
|
my $dwSize = unpack "L", $lpdwSize; |
3343
|
|
|
|
|
|
|
|
3344
|
0
|
|
|
|
|
|
$lpCC = "\0"x$dwSize; |
3345
|
0
|
0
|
|
|
|
|
$ret = $GetDefaultCommConfig->Call($dev, $lpCC, $lpdwSize) |
3346
|
|
|
|
|
|
|
or ($LastError = Win32::GetLastError(), return); |
3347
|
|
|
|
|
|
|
|
3348
|
0
|
|
|
|
|
|
substr $lpCC, 0, $dwSize; |
3349
|
|
|
|
|
|
|
} |
3350
|
|
|
|
|
|
|
|
3351
|
|
|
|
|
|
|
=item TAPIlineInitialize ( ) |
3352
|
|
|
|
|
|
|
|
3353
|
|
|
|
|
|
|
This is a non-exported function mainly for internal use. It could be handy only |
3354
|
|
|
|
|
|
|
if you'd start writing your own TAPI-related functions. |
3355
|
|
|
|
|
|
|
|
3356
|
|
|
|
|
|
|
($hLineApp, $dwNumDevs) = Win32::RASE::TAPIlineInitialize(); |
3357
|
|
|
|
|
|
|
|
3358
|
|
|
|
|
|
|
or in scalar context |
3359
|
|
|
|
|
|
|
|
3360
|
|
|
|
|
|
|
$hLineApp = Win32::RASE::TAPIlineInitialize(); |
3361
|
|
|
|
|
|
|
|
3362
|
|
|
|
|
|
|
$hLineApp - the application's usage non-zero handle for TAPI |
3363
|
|
|
|
|
|
|
$dwNumDevs - number of line devices available to the TAPI application |
3364
|
|
|
|
|
|
|
|
3365
|
|
|
|
|
|
|
Croaks on TAPI errors. |
3366
|
|
|
|
|
|
|
|
3367
|
|
|
|
|
|
|
The applicaton should always call C to release memory |
3368
|
|
|
|
|
|
|
resources allocated by TAPI.DLL. |
3369
|
|
|
|
|
|
|
|
3370
|
|
|
|
|
|
|
=cut |
3371
|
|
|
|
|
|
|
|
3372
|
|
|
|
|
|
|
#================ |
3373
|
|
|
|
|
|
|
sub TAPIlineInitialize () { |
3374
|
|
|
|
|
|
|
#================ |
3375
|
0
|
|
|
0
|
|
|
$LastError = 0; |
3376
|
0
|
|
0
|
|
|
|
$lineInitialize ||= new("tapi32","lineInitialize",[P,N,P,P,P],N); |
3377
|
|
|
|
|
|
|
|
3378
|
|
|
|
|
|
|
# dll-instance |
3379
|
|
|
|
|
|
|
#my $tapi32dll = $Win32::API::Libraries{"tapi32"}; |
3380
|
0
|
|
|
|
|
|
my $tapi32dll = $lineInitialize->{dll}; |
3381
|
|
|
|
|
|
|
|
3382
|
0
|
|
|
|
|
|
my ($lphLineApp, $lpfnCallback, $lpdwNumDevs) = |
3383
|
|
|
|
|
|
|
(DWORD_NULL, DWORD_NULL, DWORD_NULL); |
3384
|
|
|
|
|
|
|
|
3385
|
0
|
|
|
|
|
|
my $ret; |
3386
|
0
|
0
|
|
|
|
|
$ret = $lineInitialize->Call($lphLineApp, |
3387
|
|
|
|
|
|
|
$tapi32dll, $lpfnCallback, "Win32::RASE v.$VERSION\0", $lpdwNumDevs) |
3388
|
|
|
|
|
|
|
and RASERROR($ret); |
3389
|
|
|
|
|
|
|
|
3390
|
0
|
|
|
|
|
|
my $hLineApp = unpack "L", $lphLineApp; |
3391
|
0
|
|
|
|
|
|
my $dwNumDevs = unpack "L", $lpdwNumDevs; |
3392
|
|
|
|
|
|
|
|
3393
|
0
|
0
|
|
|
|
|
wantarray ? ($hLineApp, $dwNumDevs) : $hLineApp; |
3394
|
|
|
|
|
|
|
} |
3395
|
|
|
|
|
|
|
|
3396
|
|
|
|
|
|
|
=item TAPIlineShutdown ( ) |
3397
|
|
|
|
|
|
|
|
3398
|
|
|
|
|
|
|
This is a non-exported function mainly for internal use. It could be handy only |
3399
|
|
|
|
|
|
|
if you'd start writing your own TAPI-related functions. |
3400
|
|
|
|
|
|
|
|
3401
|
|
|
|
|
|
|
Win32::RASE::TAPIlineShutdown($hLineApp); |
3402
|
|
|
|
|
|
|
|
3403
|
|
|
|
|
|
|
$hLineApp - the application's usage handle for TAPI |
3404
|
|
|
|
|
|
|
|
3405
|
|
|
|
|
|
|
Returns zero if the request is successful or a negative error number |
3406
|
|
|
|
|
|
|
if an error has occurred. |
3407
|
|
|
|
|
|
|
|
3408
|
|
|
|
|
|
|
=cut |
3409
|
|
|
|
|
|
|
|
3410
|
|
|
|
|
|
|
#================ |
3411
|
|
|
|
|
|
|
sub TAPIlineShutdown ($) { |
3412
|
|
|
|
|
|
|
#================ |
3413
|
0
|
|
|
0
|
|
|
$LastError = 0; |
3414
|
0
|
|
0
|
|
|
|
$lineShutdown ||= new("tapi32","lineShutdown",[N],N); |
3415
|
0
|
|
|
|
|
|
$lineShutdown->Call(shift); |
3416
|
|
|
|
|
|
|
} |
3417
|
|
|
|
|
|
|
|
3418
|
|
|
|
|
|
|
|
3419
|
|
|
|
|
|
|
# from RegExps.pm |
3420
|
0
|
|
|
0
|
|
|
sub OCTET {'(?:1\d\d|2[0-4]\d|25[0-5]|[1-9]\d?|0)'} |
3421
|
0
|
|
|
0
|
|
|
sub HOSTNUMBER {'(?:(?:'.OCTET.'\.){3}'.OCTET.'\.?)'} |
3422
|
|
|
|
|
|
|
|
3423
|
|
|
|
|
|
|
|
3424
|
|
|
|
|
|
|
1; |
3425
|
|
|
|
|
|
|
|
3426
|
|
|
|
|
|
|
__END__ |