home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / zkuste / delphi / kompon / d456 / RASMG110.ZIP / RasManager.pas < prev    next >
Pascal/Delphi Source File  |  2002-08-10  |  33KB  |  647 lines

  1. {
  2.   RASManager.pas
  3.  
  4.   Written by Frank Plagge
  5.   Copyright (c) 1998-2002 by Frank Plagge, Elsterweg 39, 38446 Wolfsburg, Germany
  6.   All rights reserved
  7.  
  8.   *****************************************************************************
  9.   Remote Access external API
  10.   Public header for external API clients
  11.   ras.h   - Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved
  12.   *****************************************************************************
  13.  
  14.   Please send comments to plagge@wolfsburg.de
  15.  
  16.   V 1.01 - Aug 7th, 1998
  17.            first implementation, never trust a version 1.00 :-)
  18.   V 1.02 - Aug 23th, 1998
  19.            + added real connected state
  20.              the property Connected represents the connection state from
  21.              RAS services. if the connection state for a service is needed
  22.              simply set the property RASName and next check the poperty
  23.              Connected.
  24.   V 1.03 - Sep 29th, 1998
  25.            + fixed some uninititialized function results
  26.   V 1.04 - Oct 17th, 1998
  27.            + minor changes
  28.            + documentation completed - it's never complete :-)
  29.            + first public release
  30.   V 1.05 - Apr 1st 2002
  31.            + added getting the phone number of a RAS service
  32.  
  33.   V 1.10 - July 26th 2002
  34.            + complete new interface and internal design. now all available
  35.              ras service can be managed by one instance
  36.   *****************************************************************************
  37.   NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
  38.   PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
  39.   NEITHER FRANK PLAGGE OR ANY OTHER PERSON SHALL BE LIABLE FOR ANY DAMAGES
  40.   SUFFERED BY THE USE OF THIS SOFTWARE.
  41.   *****************************************************************************
  42.  
  43.   description:
  44.    This is a component for an easy access to ras services. It includes
  45.    connecting and disconnecting services as well as an easy access to
  46.    important properties like connection state, IP numbers of client and server,
  47.    phone number, aerea code, country code, device name, device type and a time
  48.    stamp of the last connection state change.
  49.  
  50.    I know there are much more possibilities with RAS, but there is no time to
  51.    implement all of them.
  52.  
  53.   *****************************************************************************
  54.  
  55.   properties and events at design time:
  56.  
  57.     property OnConnect: TOnConnectionEvent read FOnConnect write FOnConnect;           // connect event
  58.     property OnConnecting: TOnConnectingEvent read FOnConnecting write FOnConnecting;  // disconnect event
  59.     property OnDisconnect: TOnConnectionEvent read FOnDisconnect write FOnDisconnect;  // state change event during connection phase
  60.  
  61.   *****************************************************************************
  62.    properties and events at runtime:
  63.  
  64.     constructor Create(AOwner: TComponent); override;  // create a new instance
  65.     destructor Destroy; override;                      // destroy an existing instance
  66.     procedure Connect( Index: Integer );               // connect a ras service
  67.     procedure DisConnect(Index: Integer);              // disconnect a ras service
  68.     function  IndexOf( Name: string ) : Integer;       // get the index of a ras service by name
  69.     procedure Start;                                   // start the autorefresh mechanism
  70.     procedure Stop;                                    // stop the autorefresh mechanism
  71.     property Count: Integer read GetCount;             // get the number of available ras connections
  72.     property AreaCode[Index: Integer]: string read GetAreaCode;        // get area code by index
  73.     property Connected[Index: Integer]: Boolean read GetConnected;     // get connection state by index
  74.     property CountryCode[Index: Integer]: Integer read GetCountryCode; // get countryCode by index
  75.     property DeviceName[Index: Integer]: string read GetDeviceName;    // get device name by index
  76.     property DeviceType[Index: Integer]: string read GetDeviceType;    // get device type by index
  77.     property Handle[Index: Integer]: THRasConn read GetHandle;         // get ras service handle by index
  78.     property IPClient[Index: Integer]: string read GetIPClient;        // get client ip number by index
  79.     property IPServer[Index: Integer]: string read GetIPServer;        // get server ip number by index
  80.     property Name[Index: Integer]: string read GetName;                // get connection name by index
  81.     property PhoneNumber[Index: Integer]: string read GetPhoneNumber;  // get phone number by index
  82.     property TimeStamp[Index: Integer]: TDateTime read GetTimeStamp;   // get state toggle timestamp by index
  83.     property Version: string read GetVersion;
  84.  
  85.   *****************************************************************************
  86.   other very useful procedures
  87.  
  88.     function  GetStatusString(State: Integer): string;  // convert state to string message
  89.  
  90. }
  91. unit RasManager;
  92.  
  93. interface
  94.  
  95. uses
  96.   Windows, Messages, SysUtils, Classes, ExtCtrls,
  97.   Ras;
  98.  
  99. type
  100.   TRasEntry = class
  101.               public
  102.                 Handle:      THRasConn;               // connection handle
  103.                 DeviceName:  string;                  // name of connection device
  104.                 DeviceType:  string;                  // type of conection device
  105.                 Name:        string;                  // name of the connection
  106.                 IPClient:    string;                  // own IP number if connected
  107.                 IPServer:    string;                  // server IP number if connected
  108.                 Connected:   Boolean;                 // connection state
  109.                 TimeStamp:   TDateTime;               // timestamp connection toggled
  110.                 PhoneNumber: string;                  // local phone number
  111.                 AreaCode:    string;                  // area code for phone number
  112.                 CountryCode: Integer;                 // country code for phone number
  113.                 constructor Create( aName: string );  // create a new entry
  114.               end;
  115.  
  116.   // list of all available ras connections
  117.   TRasList = class (TList )
  118.              public
  119.                destructor Destroy; override;
  120.                procedure  AddName( Name: string );                           // add a new conneection name
  121.                function   GetItem( Name: string ) : TRasEntry;               // get the ras entry
  122.              end;
  123.  
  124.   // event type for connect and disconnect events
  125.   TOnConnectionEvent = procedure (Sender: TObject; Connection: TRasEntry) of object;
  126.  
  127.   // asynchronous dialing event
  128.   TOnConnectingEvent = procedure ( Sender: TObject; Index: Integer;
  129.                                    Msg: Integer; State: Integer; Error: Longint) of object;
  130.  
  131.   // main RASManager component
  132.   TRasManager = class(TComponent)
  133.   private
  134.     FOnConnect: TOnConnectionEvent;     // local connect event
  135.     FOnConnecting: TOnConnectingEvent;  // local event for connecting events (state is changing)
  136.     FOnDisconnect: TOnConnectionEvent;  // local disconnect event
  137.     RasList: TRasList;                  // list of available RAS connections
  138.     Timer: TTimer;                      // autorefresh timer
  139.     function  GetParams(Server: string; var DialParams: TRasDialParams): Boolean;
  140.     function  GetAreaCode(Index: Integer) : string;     // get area code
  141.     function  GetCount: Integer;                        // get number of ras services
  142.     function  GetConnected(Index: Integer) : Boolean;   // get connection state
  143.     function  GetCountryCode(Index: Integer) : Integer; // get connection state
  144.     function  GetDeviceName(Index: Integer) : string;   // get device name
  145.     function  GetDevicetype(Index: Integer) : string;   // get device type
  146.     function  GetHandle(Index: Integer) : THRasConn;    // get ras handle
  147.     function  GetIPClient(Index: Integer) : string;     // get client IP address
  148.     function  GetIPServer(Index: Integer) : string;     // get server IP address
  149.     function  GetName(Index: Integer) : string;         // get connection name
  150.     function  GetPhoneNumber(Index: Integer): string;   // get phone number
  151.     procedure GetProperties;                            // get device name, device type, area code phone number
  152.     function  GetTimeStamp(Index: Integer) : TDateTime; // get connection timestamp
  153.     function  GetVersion: string;                       // get internal version number
  154.     procedure OnTimer( Sender: TObject );               // local timer method for auto refresh
  155.     procedure RefreshConnections;                       // refresh state of ras services
  156.   protected
  157.   public
  158.     constructor Create(AOwner: TComponent); override;  // create a new instance
  159.     destructor Destroy; override;                      // destroy an existing instance
  160.     procedure Connect( Index: Integer );               // connect a ras service
  161.     procedure DisConnect(Index: Integer);              // disconnect a ras service
  162.     function  IndexOf( Name: string ) : Integer;       // get the index of a ras service by name
  163.     procedure Start;                                   // start the autorefresh mechanism
  164.     procedure Stop;                                    // stop the autorefresh mechanism
  165.     property Count: Integer read GetCount;             // get the number of available ras connections
  166.     property AreaCode[Index: Integer]: string read GetAreaCode;        // get area code by index
  167.     property Connected[Index: Integer]: Boolean read GetConnected;     // get connection state by index
  168.     property CountryCode[Index: Integer]: Integer read GetCountryCode; // get countryCode by index
  169.     property DeviceName[Index: Integer]: string read GetDeviceName;    // get device name by index
  170.     property DeviceType[Index: Integer]: string read GetDeviceType;    // get device type by index
  171.     property Handle[Index: Integer]: THRasConn read GetHandle;         // get ras service handle by index
  172.     property IPClient[Index: Integer]: string read GetIPClient;        // get client ip number by index
  173.     property IPServer[Index: Integer]: string read GetIPServer;        // get server ip number by index
  174.     property Name[Index: Integer]: string read GetName;                // get connection name by index
  175.     property PhoneNumber[Index: Integer]: string read GetPhoneNumber;  // get phone number by index
  176.     property TimeStamp[Index: Integer]: TDateTime read GetTimeStamp;   // get state toggle timestamp by index
  177.     property Version: string read GetVersion;
  178.   published
  179.     property OnConnect: TOnConnectionEvent read FOnConnect write FOnConnect;           // connect event
  180.     property OnConnecting: TOnConnectingEvent read FOnConnecting write FOnConnecting;  // disconnect event
  181.     property OnDisconnect: TOnConnectionEvent read FOnDisconnect write FOnDisconnect;  // state change event during connection phase
  182.   end;
  183.  
  184. procedure Register;                                 // component registration
  185. function  GetStatusString(State: Integer): string;  // convert state to string message
  186.  
  187. implementation
  188.  
  189. const
  190.   cIPEmpty = '0.0.0.0';   // default empty IP number
  191.   cRegisterName = 'FPL';
  192.   cVersion = '1.10';
  193.  
  194. var
  195.   RasSave:  TRasManager;  // class var for callback function at asynch dial
  196.   RASIndex: Integer;      // class var for ras service index at asynch dial
  197.  
  198. // ***************************************************************************
  199. // register the component
  200. procedure Register;
  201. begin
  202.   RegisterComponents( cRegisterName, [TRasManager]);
  203. end;
  204.  
  205. // ***************************************************************************
  206. // convert a ras state to a text message
  207. function GetStatusString(State: Integer): string;
  208. begin
  209.   case State of
  210.       RASCS_OpenPort:            Result := 'Opening port';
  211.       RASCS_PortOpened:          Result := 'Port opened';
  212.       RASCS_ConnectDevice:       Result := 'Connecting device';
  213.       RASCS_DeviceConnected:     Result := 'Device connected';
  214.       RASCS_AllDevicesConnected: Result := 'All devices connected';
  215.       RASCS_Authenticate:        Result := 'Start authenticating';
  216.       RASCS_AuthNotify:          Result := 'Authentication: notify';
  217.       RASCS_AuthRetry:           Result := 'Authentication: retry';
  218.       RASCS_AuthCallback:        Result := 'Authentication: callback';
  219.       RASCS_AuthChangePassword:  Result := 'Authentication: change password';
  220.       RASCS_AuthProject:         Result := 'Authentication: projecting';
  221.       RASCS_AuthLinkSpeed:       Result := 'Authentication: link speed';
  222.       RASCS_AuthAck:             Result := 'Authentication: acknowledge';
  223.       RASCS_ReAuthenticate:      Result := 'Authentication: reauthenticate';
  224.       RASCS_Authenticated:       Result := 'Authenticated';
  225.       RASCS_PrepareForCallback:  Result := 'Preparing for callback';
  226.       RASCS_WaitForModemReset:   Result := 'Waiting for modem reset';
  227.       RASCS_WaitForCallback:     Result := 'Waiting for callback';
  228.       RASCS_Projected:           Result := 'Projected';
  229.       RASCS_StartAuthentication: Result := 'Start authentication';
  230.       RASCS_CallbackComplete:    Result := 'Callback complete';
  231.       RASCS_LogonNetwork:        Result := 'Logging on network';
  232.       RASCS_Interactive:         Result := 'Interactive';
  233.       RASCS_RetryAuthentication: Result := 'Retry Authentication';
  234.       RASCS_CallbackSetByCaller: Result := 'Callback set by caller';
  235.       RASCS_PasswordExpired:     Result := 'Password expired';
  236.       RASCS_Connected:           Result := 'Connected';
  237.       RASCS_Disconnected:        Result := 'Disconnected';
  238.     else                         Result := 'Unknown state';
  239.   end;
  240. end;
  241.  
  242. // ***************************************************************************
  243. // callback function if asynchronous dialing is enabled
  244. procedure RASCallback(Msg: Integer; State: TRasConnState; Error: Longint); stdcall
  245. begin
  246.   // if a connecting event is defined the event is called
  247.   if Assigned(RASSave.FOnConnecting) then begin
  248.     RASSave.FOnConnecting( RASSave, RASIndex, Msg, State, Error );
  249.   end;
  250. end;
  251.  
  252. // create a new ras service entry and initialize it
  253. constructor TRasEntry.Create( aName: string );
  254. begin
  255.   inherited Create;    // create to object itself
  256.   Handle := 0;         // do the initialization
  257.   DeviceName:= '';
  258.   DeviceType := '';
  259.   Name := aName;
  260.   IPClient := cIPEmpty;
  261.   IPServer := cIPEmpty;
  262.   Connected := false;
  263.   TimeStamp := now;    // get the actual time and date
  264.   Phonenumber := '';
  265.   AreaCode := '';
  266.   CountryCode := 0;
  267. end;
  268.  
  269. // ***************************************************************************
  270. // destroy the instance of a ras service list
  271. destructor TRasList.Destroy;
  272. var thisItem: TRasEntry;    // single ras service entry
  273.     i: Integer;             // loop counter
  274. begin
  275.   for i :=1 to Count do begin // for all entries
  276.     thisItem := Items[i-1];   // get the entry
  277.     thisItem.Free;            // destroy the entry
  278.   end;
  279.   inherited Destroy;          // destroy the instance itself
  280. end;
  281.  
  282. // ***************************************************************************
  283. // add a new ras service name
  284. procedure TRasList.AddName( Name: string );
  285. var thisItem: TRasEntry;
  286. begin
  287.   if GetItem( Name ) = nil then begin       // if the name is really new
  288.     thisItem := TRasEntry.Create( Name );   // create a new ras list entry
  289.     Add( thisItem );                        // add this entry the the list
  290.   end;
  291. end;
  292.  
  293. // ***************************************************************************
  294. // get a list item by name
  295. function TRasList.GetItem( Name: string ) : TRasEntry;
  296. var thisItem: TRasEntry;
  297.     i: Integer;
  298. begin
  299.   Result := nil;                          // the default result is 'not found'
  300.   for i :=1 to Count do begin             // for all entries
  301.     thisItem := Items[i-1];               // the the entry
  302.     if thisItem.Name = Name then begin    // if the search name was found
  303.       Result := thisItem;                 // this entry is the result
  304.       Break;                              // leave the loop
  305.     end;
  306.   end;
  307. end;
  308.  
  309. // ***************************************************************************
  310. // create a new ras manager instance
  311. constructor TRasManager.Create(AOwner: TComponent);
  312. const cMaxRas = 100;                            // maximum number of ras services
  313. var BufferSize: LongInt;                        // used for size of result buffer
  314.     RASNames:   array[1..cMaxRas] of TRasEntryName; // the API result buffer itself
  315.     RASCount:   LongInt;                         // number of found ras services
  316.     i:           Integer;                        // loop counter
  317. begin
  318.   inherited Create( AOwner );      // create the instance
  319.   RasList := TRasList.Create;      // create an empty ras service list
  320.  
  321.   // get all available RAS names
  322.   FillChar( RASNames, SizeOf(RASNames), 0 );    // clear the API Buffer
  323.   RASNames[1].dwSize := SizeOf(TRasEntryName);  // set the API buffer size for a single record
  324.   BufferSize := SizeOf(TRasEntryName) * cMaxRas;// calc complete buffer size
  325.   // if the API call causes no error
  326.   if RasEnumEntries(nil, nil, @RASNames[1], BufferSize, RASCount) = 0 then begin
  327.     for i := 1 to RASCount do begin                 // for all found ras services
  328.       RasList.AddName( RasNames[i].szEntryName );   // save the name of the ras service
  329.     end;
  330.   end;
  331.  
  332.   RefreshConnections;                               // refresh the ras connection states
  333.                                                     // this call will generate the connect events for
  334.                                                     // already connected services
  335.  
  336.   GetProperties;                   // get device name, device type, phone number, area code
  337.  
  338.   Timer := TTimer.Create( self );  // create the autorefresh timer
  339.   Timer.Enabled := false;          // it is not active
  340.   Timer.Interval := 1000;          // the timer interval is 1 second
  341.   Timer.OnTimer := OnTimer;        // bind the timer event method
  342. end;
  343.  
  344. // ***************************************************************************
  345. // destroy an instance of a RASManager
  346. destructor TRasManager.Destroy;
  347. begin
  348.   RasList.Free;        // destroy the list of ras services
  349.   Timer.Free;          // destroy the autorefresh timer
  350.   inherited Destroy;   // destroy the component itself
  351. end;
  352.  
  353. // ***************************************************************************
  354. // connect a not connected ras service
  355. procedure TRASManager.Connect(Index: Integer);
  356. var DialParams: TRasDialParams;  // local dial parameters
  357.     RASResult:  LongInt;         // used result for RASDial call, not used
  358.     thisEntry:  TRasEntry;       // the ras service entry
  359. begin
  360.   thisEntry := RasList.Items[Index];                      // get the ras service entry
  361.   if not thisEntry.Connected then begin                   // only if the service is not connected
  362.     if GetParams( thisEntry.Name, DialParams ) then begin // get actual dial parameters
  363.       RASSave := self;                                    // save the object itself for callback function
  364.       RASIndex := Index;                                  // save the ras service index for callback function
  365.       RASResult := RasDial(nil, nil, DialParams, 0, @RASCallback, thisEntry.Handle ); // call with a callback function
  366.     end;
  367.   end;
  368. end;
  369.  
  370. // ***************************************************************************
  371. // disconnect the already connected ras service
  372. procedure TRASManager.DisConnect(Index: Integer);
  373. var thisEntry:  TRasEntry;
  374. begin
  375.   thisEntry := RasList.Items[Index];      // get the ras entry from internal list
  376.   if thisEntry.Connected then begin       // only if a connection is available
  377.     if thisEntry.Handle<>0 then begin     // only if a vaild handle is available
  378.       RasHangup( thisEntry.Handle );      // hangup the ras service
  379.     end;
  380.   end;
  381. end;
  382.  
  383. // ***************************************************************************
  384. // get the dial parameters for a ras server
  385. function TRASManager.GetParams(Server: string; var DialParams: TRasDialParams): Boolean;
  386. var DialPassword: LongBool;
  387.     RASResult:    LongInt;
  388. begin
  389.   Result := true;                                     // result is first vaild
  390.   FillChar( DialParams, SizeOf(TRasDialParams), 0);   // clear the result record
  391.   DialParams.dwSize := Sizeof(TRasDialParams);        // set the result array size
  392.   StrPCopy(DialParams.szEntryName, Server);           // set the ras service name
  393.   DialPassword := true;                               // get the dial password
  394.   RASResult := RasGetEntryDialParams(nil, DialParams, DialPassword); // read the ras parameters
  395.   if (RASResult<>0) then begin                        // if the API call was not successful
  396.     Result := false;                                  // result is not vaild
  397.   end;
  398. end;
  399.  
  400. // ***************************************************************************
  401. // get the index of a ras service name
  402. function TRasManager.IndexOf( Name: string ) : Integer;
  403. var i: Integer;
  404. begin
  405.   Result := -1;                                             // default result if 'not found'
  406.   for i := 1 to RasList.Count do begin                      // for all available ras services
  407.     if TRasEntry(RasList.Items[i-1]).Name = Name then begin // if the name was found
  408.       Result := i-1;                                        // save the index
  409.       Break;                                                // leave the loop
  410.     end;
  411.   end;
  412. end;
  413.  
  414. // ***************************************************************************
  415. // index based wrapper to RasList entries
  416. function TRasManager.GetAreaCode(Index: Integer) : string;
  417. begin
  418.   Result := TRasEntry(RasList.Items[Index]).AreaCode;
  419. end;
  420.  
  421. // ***************************************************************************
  422. // get the number of available ras services
  423. function TRasManager.GetCount: Integer;
  424. begin
  425.   Result := RasList.Count;  // wrapper to ras service list counter
  426. end;
  427.  
  428. // ***************************************************************************
  429. // index based wrapper to RasList entries
  430. function TRasManager.GetConnected(Index: Integer) : Boolean;
  431. begin
  432.   Result := TRasEntry(RasList.Items[Index]).Connected;
  433. end;
  434.  
  435. // ***************************************************************************
  436. // index based wrapper to RasList entries
  437. function TRasManager.GetCountryCode(Index: Integer) : Integer;
  438. begin
  439.   Result := TRasEntry(RasList.Items[Index]).CountryCode;
  440. end;
  441.  
  442. // ***************************************************************************
  443. // index based wrapper to RasList entries
  444. function TRasManager.GetDeviceName(Index: Integer) : string;
  445. begin
  446.   Result := TRasEntry(RasList.Items[Index]).DeviceName;
  447. end;
  448.  
  449. // ***************************************************************************
  450. // index based wrapper to RasList entries
  451. function TRasManager.GetDeviceType(Index: Integer) : string;
  452. begin
  453.   Result := TRasEntry(RasList.Items[Index]).DeviceType;
  454. end;
  455.  
  456. // ***************************************************************************
  457. // index based wrapper to RasList entries
  458. function TRasManager.GetHandle(Index: Integer) : THRasConn;
  459. begin
  460.   Result := TRasEntry(RasList.Items[Index]).Handle;
  461. end;
  462.  
  463. // ***************************************************************************
  464. // index based wrapper to RasList entries
  465. function TRasManager.GetIPClient(Index: Integer) : string;
  466. begin
  467.   Result := TRasEntry(RasList.Items[Index]).IPClient;
  468. end;
  469.  
  470. // ***************************************************************************
  471. function TRasManager.GetIPServer(Index: Integer) : string;
  472. // index based wrapper to RasList entries
  473. begin
  474.   Result := TRasEntry(RasList.Items[Index]).IPServer;
  475. end;
  476.  
  477. // ***************************************************************************
  478. // index based wrapper to RasList entries
  479. function TRasManager.GetName(Index: Integer) : string;
  480. begin
  481.   Result := TRasEntry(RasList.Items[Index]).Name;
  482. end;
  483.  
  484. // ***************************************************************************
  485. // index based wrapper to RasList entries
  486. function TRasManager.GetPhoneNumber(Index: Integer): string;
  487. begin
  488.   Result := TRasEntry(RasList.Items[Index]).PhoneNumber;
  489. end;
  490.  
  491.  
  492. // ***************************************************************************
  493. // get device name, device type, phone number, aera code, country code
  494. procedure TRASManager.GetProperties;
  495. var thisEntry: TRasEntry;       // entry from internal list
  496.     Entry: LPRasEntry;          // single ras entry
  497.     EntrySize: Integer;         // size of a single ras service entry
  498.     DeviceInfoSize: Integer;    // used for api call
  499.     i: Integer;                 // loop counter
  500.     RasResult: LongInt;         // result of ras api call
  501. begin
  502.   for i := 1 to RasList.Count do begin    // for all available ras entries do
  503.     thisEntry := RasList.Items[i-1];      // get the ras entry from internal list
  504.     EntrySize := 0;                       // init the entry size
  505.     DeviceInfoSize := 0;                  // init the devive info size
  506.     // first get the real needed buffer sizes into EntrySize and DeviceInfoSize
  507.     if RasGetEntryProperties(nil, PChar(thisEntry.Name), nil, EntrySize, nil, DeviceInfoSize) <> ERROR_BUFFER_TOO_SMALL then begin
  508.       raise Exception.Create( 'Call of RasGetEntryProperties failed for "' + thisEntry.Name+ '"' );
  509.       Exit;
  510.     end;
  511.     Entry := AllocMem(EntrySize);              // allocate the needed buffer size
  512.     try
  513.       Entry^.dwSize := SizeOf(Ras.TRasEntry); // set the size of an entry
  514.      // Get the properties for the needed RAS entry
  515.       RasResult := RasGetEntryProperties(nil, PChar(thisEntry.Name), Entry, EntrySize, nil, DeviceInfoSize);
  516.       if RasResult = 0 then begin                            // if the api call was successful
  517.         thisEntry.Phonenumber := Entry^.szLocalPhoneNumber;  // save ras service informations
  518.         thisEntry.AreaCode := Entry^.szAreaCode;
  519.         thisEntry.DeviceName := Entry^.szDeviceName;
  520.         thisEntry.DeviceType := Entry^.szDeviceType;
  521.         thisEntry.CountryCode := Entry^.dwCountryCode;
  522.       end;
  523.     finally
  524.       FreeMem(Entry);  // free the formerly allocated memory
  525.     end;
  526.   end;
  527. end;
  528.  
  529. // ***************************************************************************
  530. // index based wrapper to RasList entries
  531. function TRasManager.GetTimeStamp(Index: Integer) : TDateTime;
  532. begin
  533.   Result := TRasEntry(RasList.Items[Index]).TimeStamp;
  534. end;
  535.  
  536. // ***************************************************************************
  537. // autorefresh mechanism
  538. function TRasManager.GetVersion: string;                       // get internal version number
  539. begin
  540.   Result := cVersion;
  541. end;
  542.  
  543. // ***************************************************************************
  544. // autorefresh mechanism
  545. procedure TRasManager.OnTimer( Sender: TObject );
  546. begin
  547.   RefreshConnections; // every timer event the connection state is refreshed
  548. end;
  549.  
  550. // ***************************************************************************
  551. // get all available ras conections and save them within RASList
  552. procedure TRasManager.RefreshConnections;
  553. const cMaxRas = 100;                             // maximum number of ras services
  554. var BufferSize: LongInt;                         // used for size of result buffer
  555.     RASConnect: array[1..cMaxRas] of TRasConn;   // the API result buffer itself
  556.     RASCount:   LongInt;                         // number of found ras services
  557.     i:          Integer;                         // loop counter
  558.     thisItem:   TRasEntry;                       // single ras service
  559.     ConnList:   TStringList;                     // list of available connections
  560.     RASInfo:  DWord;                             // result of gettimg IP addresses
  561.     RASPppIp: TRASPppIp;                         // result record of getting IP addresses
  562.     lpcp: LongInt;                               // IP address result size
  563.  
  564. begin
  565.   ConnList := TStringList.Create;                    // create list of found connections
  566.   FillChar( RASConnect, SizeOf(RASConnect), 0 );     // clear the API result buffer
  567.   RASConnect[1].dwSize := SizeOf(TRasConn);          // set the API buffer size for a single result record
  568.   BufferSize := SizeOf(TRasConn) * cMaxRas;          // calc complete buffer size
  569.   // if the API call causes no error
  570.   if RasEnumConnections(@RASConnect[1], BufferSize, RASCount) = 0 then begin
  571.     for i := 1 to RASCount do begin                  // for all found ras services
  572.       ConnList.Add(RasConnect[i].szEntryName);       // save RAS name to the list of established connections
  573.       thisItem := RASList.GetItem( RasConnect[i].szEntryName );
  574.       thisItem.Handle := RASConnect[i].hrasconn;                 // save the belonging ras handle
  575. //      RasList.SetDeviceName( RASConnect[i].szEntryName, StrPas(RasConnect[i].szDeviceName ) ); // save the belonging device name
  576. //      RasList.SetDeviceType( RASConnect[i].szEntryName, StrPas(RasConnect[i].szDeviceType) ); // save the belonging device type
  577.  
  578.       // get IP Numbers of connection
  579.       FillChar(RASPppIp,SizeOf(TRASPppIp), 0);   // clear API result buffer
  580.       RASPppIp.dwSize:=SizeOf(TRASPppIp);        // set the API buffer size for a single result record
  581.       lpcp := RASPppIp.dwSize;                   // same again
  582.       RASInfo := RASGetProjectionInfo(RASConnect[i].hrasconn,RASP_PppIp,@RASPppIp,lpcp);  // get the IP addresses for this ras handle
  583.       if RASInfo = 0 then begin                  // if the API call was successful
  584.         thisItem.IPClient := StrPas(RASPppIp.szIpAddress);       // save the client address
  585.         thisItem.IPServer := StrPas(RASPppIp.szServerIpAddress); // save the server address
  586.       end else begin                             // if the API call wa snot succesful
  587.         thisItem.IPClient := cIPEmpty;           // save an empty default address
  588.         thisItem.IPServer := cIPEmpty;           // save an empty default address
  589.       end;
  590.     end;
  591.   end;
  592.  
  593.   for i := 1 to RasList.Count do begin                     // for all available ras services do
  594.     thisItem := RasList.Items[i-1];                        // get the ras service entry
  595.     if thisItem.Connected then begin                       // is fromerly the service was sconnected
  596.       if ConnList.IndexOf(thisItem.Name) < 0 then begin    // and now the service is not within the list of established connections
  597.         thisItem.Connected := false;                       // it is no longer connected
  598.         thisItem.DeviceName := '';                         // clear the device name
  599.         thisItem.DeviceType := '';                         // clear the device type
  600.         thisItem.Handle := 0;                              // clear the service handle
  601.         thisItem.IPClient := cIPEmpty;                     // set the client IP address to a default empty address
  602.         thisItem.IPServer := cIPEmpty;                     // set the server IP address to a default empty address
  603.         thisItem.TimeStamp := now;                         // reinit the time stamp
  604.         if Assigned(FOnDisConnect) then begin              // if a disconnect event is assigned
  605.           FOnDisConnect( self, thisItem );                 // call the assigned event
  606.         end;
  607.       end;
  608.     end else begin                                         // if fromerly the service was not connected
  609.       if ConnList.IndexOf(thisItem.Name) >= 0 then begin   // and now it is connected
  610.         thisItem.Connected := true;                        // set the new connection state
  611.         thisItem.TimeStamp := now;                         // reinit the time stamp because state is toggled
  612.         if Assigned(FOnConnect) then begin                 // if a connect event is assiged
  613.           FOnConnect( self, thisItem );                    // call the assigned event
  614.         end;
  615.       end;
  616.     end;
  617.   end;
  618.  
  619.   ConnList.Free;  // destroy local list of connections
  620. end;
  621.  
  622. // ***************************************************************************
  623. // start the autorefresh mechanism
  624. procedure TRasManager.Start;
  625. var thisItem: TRasEntry;  // a single ras service entry
  626.     i: Integer;
  627. begin
  628.   for i := 1 to RasList.Count do begin   // for all available ras service entries
  629.     thisItem := RasList.Items[i-1];      // get the ras service entry
  630.     if thisItem.Connected then begin     // if the ras service is connected
  631.       if Assigned(FOnConnect) then begin // if a connect event is assiged
  632.         FOnConnect( self, thisItem );    // call the assigned event
  633.       end;
  634.     end;
  635.   end;
  636.   Timer.Enabled := true;                  // enable the autorefersh timer
  637. end;
  638.  
  639. // ***************************************************************************
  640. // stop the autorefresh mechanism
  641. procedure TRasManager.Stop;
  642. begin
  643.   Timer.Enabled := false;     // disable the autorefresh timer
  644. end;
  645.  
  646. end.
  647.