(************************************************************************
*    This File is Part of the AHM Triton Tools                          *
*    for Borland Delphi and C++ Builder.                                *
*************************************************************************
* Copyright © 1995-1999 Alexander H. Mehlhorn (AHM) and Tritontools.com *
* All Rights reserved.                                                  *
*                                                                       *
*    For more Information contact us at                                 *
*    E-Mail : support@tritontools.com                                   *
*    URL : http://www.tritontools.com                                   *
*                                                                       *
*    AHM is copyright by Alexander H. Mehlhorn                          *
*    All Parts of this Collection were developed,                       *
*    designed and implemented by AHM                                    *
*                                                                       *
*    Under no Circumstances may you distribute this file                *
*    in this or any other format. This File is supplied                 *
*    as Evaluation of Source only. No Delphi Components may be developed*
*    using extracts or subsets of this code without expressed permission*
*    by AHM.                                                            *
*                                                                       *
*************************************************************************)
unit AHMTRASManager;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  AHMSystemClass,AHMSystemConst,Extctrls;

const
    rasapi32              = 'rasapi32.dll';
    RASnp_Netbeui=       1;
    RASnp_Ipx=           2;
    RASnp_Ip=            4;
    UNLEN                 = 256;
    PWLEN                 = 256;
    CNLEN                 = 15;
    DNLEN                 = CNLEN;
    RASDef_UseCountryAndAreaCodes=  1;
    RASDef_SpecificIpAddr=          2;
    RASDef_SpecificNameServers=     4;
    RASDef_IpHeaderCompression=     8;
    RASDef_RemoteDefaultGateway=    16;
    RASDef_DisableLcpExtensions=    32;
    RASDef_TerminalBeforeDial=      64;
    RASDef_TerminalAfterDial=       128;
    RASDef_ModemLights=             256;
    RASDef_SwCompression=           512;
    RASDef_RequireEncryptedPw=      1024;
    RASDef_RequireMsEncryptedPw=    2048;
    RASDef_RequireDataEncryption=   4096;
    RASDef_NetworkLogon=            8192;
    RASDef_UseLogonCredentials=     16384;
    RASDef_PromoteAlternates=       32768;
    RAS_MaxDeviceType     = 16;
    RAS_MaxPhoneNumber    = 128;
    RAS_MaxIpAddress      = 15;
    RAS_MaxIpxAddress     = 21;
    RAS_MaxEntryName      = 256;
    RAS_MaxDeviceName     = 128;
    RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;
    RAS_MaxAreaCode       = 10;
    RAS_MaxPadType        = 32;
    RAS_MaxX25Address     = 200;
    RAS_MaxFacilities     = 200;
    RAS_MaxUserData       = 200;
    RAScsOpenPort            = 0;
    RAScsPortOpened          = 1;
    RAScsConnectDevice       = 2;
    RAScsDeviceConnected     = 3;
    RAScsAllDevicesConnected = 4;
    RAScsAuthenticate        = 5;
    RAScsAuthNotify          = 6;
    RAScsAuthRetry           = 7;
    RAScsAuthCallback        = 8;
    RAScsAuthChangePassword  = 9;
    RAScsAuthProject         = 10;
    RAScsAuthLinkSpeed       = 11;
    RAScsAuthAck             = 12;
    RAScsReAuthenticate      = 13;
    RAScsAuthenticated       = 14;
    RAScsPrepareForCallback  = 15;
    RAScsWaitForModemReset   = 16;
    RAScsWaitForCallback     = 17;
    RAScsProjected           = 18;
    RAScsStartAuthentication = 19;
    RAScsCallbackComplete    = 20;
    RAScsLogonNetwork        = 21;
    RAScsSubEntryConnected   = 22;
    RAScsSubEntryDisconnected= 23;
    RAScsPAUSED              = $1000;
    RAScsInteractive         = RAScsPAUSED;
    RAScsRetryAuthentication = (RAScsPAUSED + 1);
    RAScsCallbackSetByCaller = (RAScsPAUSED + 2);
    RAScsPasswordExpired     = (RAScsPAUSED + 3);
    RAScsDone                = $2000;
    RAScsConnected           = RAScsDONE;
    RAScsDisconnected        = (RAScsDONE + 1);
    RASDialEvent    = 'RasDialEvent';
    WM_RASDialEvent = $CCCD;
type
    THRASConn     = THandle;
    PHRASConn     = ^THRASConn;
    TRASConnState = DWORD;
    PDWord        = ^DWORD;
    PBool         = ^BOOL;
    TAHMWinVer = (v400,v401,v500);
type
    TRASDialParams = packed record
        dwSize           : DWORD;
        szEntryName      : array [0..RAS_MaxEntryName] of Char;
        szPhoneNumber    : array [0..RAS_MaxPhoneNumber] of Char;
        szCallbackNumber : array [0..RAS_MaxCallbackNumber] of Char;
        szUserName       : array [0..UNLEN] of Char;
        szPassword       : array [0..PWLEN] of Char;
        szDomain         : array [0..DNLEN] of Char;
        case TAHMWinVer of
           v400  : (szPadding1 : array [0..2] of Char;);
           v401,v500 : (dwSubEntry : DWORD;
                        dwCallbackId : DWORD;
                        szPadding2 : array [0..2] of Char;);
    end;
    PRASDialParams = ^TRASDialParams;
    TRasIPAddr = record
	   a: byte;
	   b: byte;
	   c: byte;
	   d: byte;
    end;
  PRasIPAddr = ^TRasIPAddr;
  PRasEntry= ^TRasEntry;
  TRasEntry = record
     dwSize 	: DWord;
     Options  	: DWord;
     dwCountryID    : DWord;
     dwCountryCode	: DWord;
     szAreaCode	: array[0..RAS_MaxAreaCode] of char;
     pLocalPhoneNumber	: array[0..RAS_MaxPhoneNumber] of char;
     AlternatesOffset	: DWord;
     IPAddr	    	: TRasIPAddr;
     IPAddrDns	    	: TRasIPAddr;
     IPAddrDnsAlt	: TRasIPAddr;
     IPAddrWins	    	: TRasIPAddr;
     IPAddrWinsAlt    	: TRasIPAddr;
     dwFrameSize        : DWord;
     dwNetProtocols     : DWord;
     dwFramingProtocol	: DWord;
     szScript	    	: array[0..MAX_PATH-1] of char;
     szAutodialDll  	: array[0..MAX_PATH-1] of char;
     szAutodialFunc 	: array[0..MAX_PATH-1] of char;
     szDeviceType      	: array[0..RAS_MaxDeviceType] of char;
     szDeviceName      	: array[0..RAS_MaxDeviceName] of char;
     szX25PadType      	: array[0..RAS_MaxPadType] of char;
     szX25Address      	: array[0..RAS_MaxX25Address] of char;
     szX25Facilities   	: array[0..RAS_MaxFacilities] of char;
     szX25UserData	: array[0..RAS_MaxUserData] of char;
     dwChannels	    	: DWord;
     Reserved1	        : DWord;
     Reserved2		: DWord;
     case TAHMWinVer of
        v400  : ();
        v401  : (dw4SubEntries   : DWord;
                 dw4DialMode	: DWord;
                 dw4DialExtraPercent 	: DWord;
                 dw4DialExtraSampleSeconds  : DWord;
                 dw4HangUpExtraPercent	: DWord;
                 dw4HangUpExtraSampleSeconds	: DWord;
                 dw4IdleDisconnectSeconds : DWord;);
        v500  : (dw5SubEntries   : DWord;
                 dw5DialMode	: DWord;
                 dw5DialExtraPercent 	: DWord;
                 dw5DialExtraSampleSeconds  : DWord;
                 dw5HangUpExtraPercent	: DWord;
                 dw5HangUpExtraSampleSeconds	: DWord;
                 dw5IdleDisconnectSeconds : DWord;
                 szPortName : array[0..RAS_MaxDeviceName] of char;);
  end;
  TRASDialExtensions = packed record
        dwSize     : DWORD;
        dwfOptions : DWORD;
        hwndParent : HWND;
        reserved   : DWORD;
   end;
   PRASDialExtensions = ^TRASDialExtensions;
   TRASConnStatus = packed record
       dwSize       : DWORD;
        RasConnState : TRASConnState;
        dwError      : DWORD;
        szDeviceType : array [0..RAS_MaxDeviceType] of char;
        szDeviceName : array [0..RAS_MaxDeviceName] of char;
        szPadding    : array [0..1] of Char;
   end;
   PRASConnStatus = ^TRASConnStatus;
   TRASConn = packed record
      dwSize       : DWORD;
      HRASConn     : THRASConn;
      szEntryName  : array [0..RAS_MaxEntryName] of char;
      szDeviceType : array [0..RAS_MaxDeviceType] of char;
      szDeviceName : array [0..RAS_MaxDeviceName] of char;
      szPadding    : array [0..0] of Char;
   end;
   PRASConn = ^TRASConn;
   TRASEntryName = packed record
      dwSize       : DWORD;
      szEntryName  : array [0..RAS_MaxEntryName] of char;
      szPadding    : array [0..2] of Char;
    end;
    PRASEntryName = ^TRASEntryName;

type
  PFNRasDial = ^TFNRasDial;
  TFNRasDial = function(RasDialExtensions: PRASDialExtensions;PhoneBook : PChar;RasDialParams : PRASDialParams;NotifierType  : DWORD;Notifier : Pointer;RasConn : PHRASConn): DWORD; stdcall;

  PFNRasGetErrorString = ^TFNRasGetErrorString;
  TFNRasGetErrorString = function(uErrorValue   : DWORD;szErrorString : PChar;cBufSize : DWORD): DWORD; stdcall;

  PFNRasHangUp = ^TFNRasHangUp;
  TFNRasHangUp = function(RasConn: THRASConn): DWORD; stdcall;

  PFNRasGetConnectStatus = ^TFNRasGetConnectStatus;
  TFNRasGetConnectStatus = function(HRASConn: THRASConn;lpRasConnStatus : PRASConnStatus): DWORD; stdcall;

  PFNRasEnumConnections = ^TFNRasEnumConnections;
  TFNRasEnumConnections = function(pRasConn : PRASConn;pCB : PDWord;pcConnections : PDWord) : DWORD; stdcall;

  PFNRasEnumEntries = ^TFNRasEnumEntries;
  TFNRasEnumEntries = function(Reserved : Pointer;szPhonebook : PChar;lpRasEntryName : PRASEntryName; lpcb : PDWord;lpcEntries : PDWord) : DWORD; stdcall;

  PFNRasGetEntryDialParams = ^TFNRasGetEntryDialParams;
  TFNRasGetEntryDialParams = function(lpszPhonebook : PChar;lprasDialParams : PRASDialParams;lpfPassword : PBool) : DWORD; stdcall;

  PFNRasEditPhoneBookEntry = ^TFNRasEditPhoneBookEntry;
  TFNRasEditPhoneBookEntry = function(hWndParent : HWND;lpszPhonebook : PChar;lpszEntryName : PChar) : DWORD; stdcall;

  PFNRasCreatePhonebookEntry = ^TFNRasCreatePhonebookEntry;
  TFNRasCreatePhonebookEntry = function(hWndParent : HWND;lpszPhonebook : PChar) : DWORD; stdcall;

  PFNRasGetEntryProperties = ^TFNRasGetEntryProperties;
  TFNRasGetEntryProperties = function(lpszPhonebook:PChar;lpszEntry:PChar;lpRasEntry : PRasEntry;lpdwEntryInfoSize : PDWord;lpbDeviceInfo :PByte;lpdwDeviceInfoSize:PDWord) : DWORD; stdcall;

  PFNRasSetEntryProperties = ^TFNRasSetEntryProperties;
  TFNRasSetEntryProperties = function(lpszPhonebook:PChar;lpszEntry:PChar;lpRasEntry : PRasEntry;lpdwEntryInfoSize : DWord;lpbDeviceInfo :PByte;lpdwDeviceInfoSize:PDWord) : DWORD; stdcall;

  PFNRasDeleteEntry = ^TFNRasDeleteEntry;
  TFNRasDeleteEntry = function(lpszPhonebook:PChar;lpszEntry:PChar): DWORD; stdcall;

  TAHMOnChangeConnection=Procedure(Sender:TObject;OldConnection,NewConnection : String) of object;
  TAHMOnConnectionExists=Procedure(Sender:TObject;Connection : String) of object;
  TAHMOnNewPhoneEntry=Procedure(Sender:TObject;Connection : String) of object;
  TAHMOnRasMessage=Procedure(Sender:TObject;RasMessage : DWord) of object;
  TAHMOnRasError=Procedure(Sender:TObject;RasMessage : String;Error : DWord) of object;
  TAHMOnRasDelAfter=Procedure(Sender:TObject;Const Success : Boolean) of object;
  TAHMOnRasDelBefore=Procedure(Sender:TObject;Var DoDelete : Boolean) of object;
  TAHMRasError=Procedure(Sender:TObject;Status : DWord) of object;
  TAHMRASManager = class;
  TAHMRASTimer = class;
  TAHMRasTimerThread = class(TThread)
    OwnerTimer: TAHMRASTimer;
    Procedure Execute; override;
    Procedure DoTimer;
  end;
  TAHMRASTimer = class(TObject)
  private
    FEnabled: Boolean;
    FInterval: Word;
    FOnTimer: TNotifyEvent;
    FTimerThread: TAHMRasTimerThread;
    FThreadPriority: TThreadPriority;
    Procedure SetEnabled(Const Value: Boolean);
    Procedure SetInterval(Const Value: Word);
    Procedure SetThreadPriority(Const Value: TThreadPriority);
  Protected
    Procedure UpdateTimer;
    Procedure Timer; dynamic;
  public
    constructor Create; virtual;
    destructor Destroy; override;
  published
    Property Enabled: Boolean read FEnabled write SetEnabled;
    Property Interval: Word read FInterval write SetInterval;
    Property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
    Property Priority: TThreadPriority read FThreadPriority write SetThreadPriority;
  end;

  TAHMConnectionOptionFlags=(coUseCountryAndAreaCodes,coSpecificIpAddr,coSpecificNameServers,coIpHeaderCompression,
                         coRemoteDefaultGateway,coDisableLcpExtensions,coTerminalBeforeDial,coTerminalAfterDial,
                         coModemLights,coSwCompression,coRequireEncryptedPw,coRequireMsEncryptedPw,coRequireDataEncryption,
                         coNetworkLogon,coUseLogonCredentials,coPromoteAlternates,coSecureLocalFiles);
  TAHMConnectionOptions=Set of TAHMConnectionOptionFlags;
  TAHMNetProtocolsFlags = (npIPX,npTCPIP,npNETBEUI);
  TAHMNetProtocols=Set of TAHMNetProtocolsFlags;
  TAHMFramingProtocolsFlags = (fpPPP,fpSLIP,fpRAS);
  TAHMFramingProtocols=Set of TAHMFramingProtocolsFlags;
  TAHMRASProperties = class(TPersistent)
  private
    FAHMRASManager : TAHMRASManager;
    InternalEntry : TRASEntry;
    function GetAreaCode: String;
    function GetAutoDialDLL: String;
    function GetAutoDialFunc: String;
    function GetCountryCode: DWord;
    function GetCountryID: DWord;
    function GetDeviceName: String;
    function GetDeviceType: String;
    function GetFrameSize: DWord;
    function GetIPAddress: String;
    function GetIPAddressDNS: String;
    function GetIPAddressDNSAlt: String;
    function GetIPAddressWINS: String;
    function GetIPAddressWINSAlt: String;
    function GetNetProtocols: TAHMNetProtocols;
    function GetPhoneNumber: String;
    function GetScript: String;
    function GetX25PadType: String;
    procedure SetAreaCode(const Value: String);
    procedure SetAutoDialDLL(const Value: String);
    procedure SetAutoDialFunc(const Value: String);
    procedure SetConnectionOptions(const Value: TAHMConnectionOptions);
    procedure SetCountryCode(const Value: DWord);
    procedure SetCountryID(const Value: DWord);
    procedure SetDeviceName(const Value: String);
    procedure SetDeviceType(const Value: String);
    procedure SetFrameSize(const Value: DWord);
    procedure SetIPAddress(const Value: String);
    procedure SetIPAddressDNS(const Value: String);
    procedure SetIPAddressDNSAlt(const Value: String);
    procedure SetIPAddressWINS(const Value: String);
    procedure SetIPAddressWINSAlt(const Value: String);
    procedure SetNetProtocols(const Value: TAHMNetProtocols);
    procedure SetPhoneNumber(const Value: String);
    procedure SetScript(const Value: String);
    procedure SetX25PadType(const Value: String);
    function GetX25Address: String;
    function GetX25Facilities: String;
    function GetX25UserData: String;
    procedure SetX25Address(const Value: String);
    procedure SetX25Facilities(const Value: String);
    procedure SetX25UserData(const Value: String);
    function GetConnectionOptions: TAHMConnectionOptions;
    function GetInternalEntry: Boolean;
    procedure SetInternalEntry;
  protected
  public
    Constructor Create(AOwner : TAHMRASManager); virtual;
    Property RasManager : TAHMRasManager read FAHMRasManager;
  published
    property Options : TAHMConnectionOptions read GetConnectionOptions write SetConnectionOptions stored False;
    property CountryID : DWord read GetCountryID write SetCountryID stored False;
    property CountryCode : DWord read GetCountryCode write SetCountryCode stored False;
    property AreaCode : String read GetAreaCode write SetAreaCode stored False;
    property PhoneNumber : String read GetPhoneNumber write SetPhoneNumber stored False;
    property IPAddress : String read GetIPAddress write SetIPAddress stored False;
    property IPAddressDNS : String read GetIPAddressDNS write SetIPAddressDNS stored False;
    property IPAddressDNSAlt : String read GetIPAddressDNSAlt write SetIPAddressDNSAlt stored False;
    property IPAddressWINS : String read GetIPAddressWINS write SetIPAddressWINS stored False;
    property IPAddressWINSAlt : String read GetIPAddressWINSAlt write SetIPAddressWINSAlt stored False;
    property FrameSize : DWord read GetFrameSize write SetFrameSize stored False;
    property NetProtocols : TAHMNetProtocols read GetNetProtocols write SetNetProtocols stored False;
    property Script : String read GetScript write SetScript stored False;
    property AutoDialDLL : String read GetAutoDialDLL write SetAutoDialDLL stored False;
    property AutoDialFunc : String read GetAutoDialFunc write SetAutoDialFunc stored False;
    property DeviceType : String read GetDeviceType write SetDeviceType stored False;
    property DeviceName : String read GetDeviceName write SetDeviceName stored False;
    property X25PadType : String read GetX25PadType write SetX25PadType stored False;
    property X25Address : String read GetX25Address write SetX25Address stored False;
    property X25Facilities : String read GetX25Facilities write SetX25Facilities stored False;
    property X25UserData : String read GetX25UserData write SetX25UserData stored False;
  end;
  TAHMRASManager = class(TAHMSystemsComponent)
  private
    FLastError : String;
    FConnections: TStrings;
    FOnUpdate: TNotifyevent;
    FConnection: String;
    FOnChangeConnection: TAHMOnChangeConnection;
    FUserName: String;
    FPassword: String;
    FNumber: String;
    HRASConn : THRASConn;
    nRasConn : DWORD;
    FActive: Boolean;
    FRasTimer : TAHMRASTimer;
    FOnDisconnected: TNotifyEvent;
    FOnConnected: TNotifyEvent;
    FOnConnectFailed: TNotifyEvent;
    FOnConnectionExists: TAHMOnConnectionExists;
    FApplicationHandle,FOwnerhandle : Hwnd;
    FOwnerForm : TWinControl;
    FOnNewPhoneEntry: TAHMOnNewPhoneEntry;
    FCheckStatus: LongInt;
    FNoPassword: Boolean;
    FDomain: String;
    FAHMRASProperties: TAHMRASProperties;
    FOnMSGOpenPort : TNotifyevent;
    FOnMSGPortOpened : TNotifyevent;
    FOnMSGConnectDevice : TNotifyevent;
    FOnRASError: TAHMOnRASError;
    FOnAnyMessage: TAHMOnRasMessage;
    FOnMsgOther: TAHMOnRasMessage;
    FOnMsgPrepareForCallback: TNotifyEvent;
    FOnMsgPasswordExpired: TnotifyEvent;
    FOnMsgLogonNetwork: TnotifyEvent;
    FOnMsgStartAuthentication: TNotifyEvent;
    FOnMsgProjected: TNotifyEvent;
    FOnMsgAuthenticated: Tnotifyevent;
    FOnMsgAuthLinkSpeed: TnotifyEvent;
    FOnMsgAuthProject: TNotifyevent;
    FOnMsgAuthChangePassword: TNotifyEvent;
    FOnMsgDeviceConnected: TNotifyevent;
    FOnMsgDisconnected: TNotifyEvent;
    FOnMsgAuthNotify: TNotifyevent;
    FOnMsgInteractive: TnotifyEvent;
    FOnMsgReAuthenticate: TNotifyEvent;
    FOnMsgAuthAck: TNotifyEvent;
    FOnMsgRetryAuthentication: TNotifyevent;
    FOnMsgSubEntryConnected: TNotifyEvent;
    FOnMsgAuthRetry: TNotifyevent;
    FOnMsgCallbackSetByCaller: Tnotifyevent;
    FOnMsgAuthenticate: TNotifyevent;
    FOnMsgWaitForModemReset: TnotifyEvent;
    FOnMsgConnected: TNotifyEvent;
    FOnMsgWaitForCallback: TNotifyEvent;
    FOnMsgCallBackComplete: TNotifyEvent;
    FOnMsgAllDevicesConnected: TNotifyEvent;
    FOnMsgSubEntryDisconnected: TnotifyEvent;
    FOnMsgAuthCallback: TNotifyEvent;
    FPhoneBook: String;
    FAfterDeleteEntry: TAHMOnRASDelAfter;
    FBeforeDeleteEntry: TAHMOnRASDelBefore;
    FConnectedOn : String;
    procedure OnRasTimer(Sender : TObject);
    procedure SetConnections(const Value: TStrings);
    procedure SetConnection(const Value: String);
    procedure SetPassword(const Value: String);
    procedure SetUsername(const Value: String);
    function GetActive: Boolean;
    function GetConnected: Boolean;
    procedure SetActive(const Value: Boolean);
    function GetActiveConnection : Boolean;
    procedure SetCheckStatus(const Value: LongInt);
    procedure SetDomain(const Value: String);
    function GetInstalled: Boolean;
    procedure Setinstalled(const Value: Boolean);
    procedure SetPhonebook(const Value: String);
    function SetError(const Error : DWord): Boolean;
    { Private declarations }
  protected
    { Protected declarations }
    OldWndProc  : TFarProc;
    NewWndProc  : Pointer;
    procedure   HookWin;
    procedure   UnhookWin;
    Procedure UpdateEntry;
    Function LoadPhoneBook : Boolean;
  public
    { Public declarations }
    procedure Hooked(var AMsg: TMessage); virtual;
    property OwnerForm : TWinControl read FOwnerForm;
    property OwnerHandle : HWnd read FOwnerHandle;
    property ApplicationHandle : HWnd read FApplicationHandle;
    Procedure UpdateRAS;
    Function ConfigureEntry(Entry : String) : Boolean;
    Function CreateEntry : Boolean;
    Function DeleteEntry(Entry : String) : Boolean;
    Constructor Create(AOwner : TComponent); override;
    procedure Loaded; override;
    Destructor Destroy; override;
    Function Connect : Boolean;
    Procedure Disconnect;
    Property LastError : String read FLastError;
    Property HasPassword : Boolean read FNoPassword;
    Property Connections : TStrings read FConnections write SetConnections;
    Property Connected : Boolean read GetConnected;
    Property ConnectedOn : String read FConnectedOn;
  published
    Property Phonebook : String read FPhoneBook write SetPhonebook stored False;
    Property Connection : String read FConnection write SetConnection stored False;
    Property CheckStatus : LongInt read FCheckStatus write SetCheckStatus;
    Property Active : Boolean read GetActive write SetActive stored False;
    Property UserName : String read FUserName write SetUsername stored False;
    Property Password : String read FPassword write SetPassword stored False;
    Property Domain : String read FDomain write SetDomain stored False;
    Property Installed : Boolean read GetInstalled write Setinstalled stored False;
    Property Properties : TAHMRASProperties read FAHMRASProperties write FAHMRASProperties stored False;
    Property OnUpdate : TNotifyevent read FOnUpdate write FOnUpdate;
    Property BeforeDeleteEntry : TAHMOnRASDelBefore read FBeforeDeleteEntry write FBeforeDeleteEntry;
    Property AfterDeleteEntry : TAHMOnRASDelAfter read FAfterDeleteEntry write FAfterDeleteEntry;
    Property OnChangeConnection : TAHMOnChangeConnection read FOnChangeConnection write FOnChangeConnection;
    Property OnConnectFailed : TNotifyEvent read FOnConnectFailed write FOnConnectFailed;
    Property OnConnected : TNotifyEvent read FOnConnected write FOnConnected;
    Property OnDisconnected : TNotifyEvent read FOnDisconnected write FOnDisconnected;
    Property OnConnectionExists : TAHMOnConnectionExists read FOnConnectionExists write FOnConnectionExists;
    Property OnNewPhoneEntry : TAHMOnNewPhoneEntry read FOnNewPhoneEntry write FOnNewPhoneEntry;
    Property OnRASError : TAHMOnRASError read FOnRASError write FOnRASError;
    Property OnMsgOpenPort : TNotifyevent read FOnMsgOpenPort write FOnMsgOpenPort;
    Property OnMsgPortOpened : TNotifyevent read FOnMsgPortOpened write FOnMsgPortOpened;
    Property OnMsgConnectDevice : TNotifyevent read FOnMsgConnectDevice write FOnMsgConnectDevice;
    Property OnMsgDeviceConnected : TNotifyevent read FOnMsgDeviceConnected write FOnMsgDeviceConnected;
    Property OnMsgAllDevicesConnected : TNotifyEvent read FOnMsgAllDevicesConnected write FOnMsgAllDevicesConnected;
    Property OnMsgAuthenticate : TNotifyevent read FOnMsgAuthenticate write FOnMsgAuthenticate;
    Property OnMsgAuthenticated : TNotifyevent read FOnMsgAuthenticated write FOnMsgAuthenticated;
    Property OnMsgAuthNotify : TNotifyevent read FOnMsgAuthNotify write FOnMsgAuthNotify;
    Property OnMsgAuthRetry : TNotifyevent read FOnMsgAuthRetry write FOnMsgAuthRetry;
    Property OnMsgAuthCallback : TNotifyEvent read FOnMsgAuthCallback write FOnMsgAuthCallback;
    Property OnMsgAuthChangePassword : TNotifyEvent read FOnMsgAuthChangePassword write FOnMsgAuthChangePassword;
    Property OnMsgAuthProject : TNotifyevent read FOnMsgAuthProject write FOnMsgAuthProject;
    Property OnMsgAuthLinkSpeed : TnotifyEvent read FOnMsgAuthLinkSpeed write FOnMsgAuthLinkSpeed;
    Property OnMsgAuthAck : TNotifyEvent read FOnMsgAuthAck write FOnMsgAuthAck;
    Property OnMsgReAuthenticate : TNotifyEvent read FOnMsgReAuthenticate write FOnMsgReAuthenticate;
    Property OnMsgPrepareForCallback : TNotifyEvent read FOnMsgPrepareForCallback write FOnMsgPrepareForCallback;
    Property OnMsgWaitForModemReset : TnotifyEvent read FOnMsgWaitForModemReset write FOnMsgWaitForModemReset;
    Property OnMsgWaitForCallback : TNotifyEvent read FOnMsgWaitForCallback write FOnMsgWaitForCallback;
    Property OnMsgProjected : TNotifyEvent read FOnMsgProjected write FOnMsgProjected;
    Property OnMsgStartAuthentication : TNotifyEvent read FOnMsgStartAuthentication write FOnMsgStartAuthentication;
    Property OnMsgCallBackComplete : TNotifyEvent read FOnMsgCallBackComplete write FOnMsgCallBackComplete;
    Property OnMsgLogonNetwork : TnotifyEvent read FOnMsgLogonNetwork write FOnMsgLogonNetwork;
    Property OnMsgSubEntryConnected : TNotifyEvent read FOnMsgSubEntryConnected write FOnMsgSubEntryConnected;
    Property OnMsgSubEntryDisconnected : TnotifyEvent read FOnMsgSubEntryDisconnected write FOnMsgSubEntryDisconnected;
    Property OnMsgInteractive : TnotifyEvent read FOnMsgInteractive write FOnMsgInteractive;
    Property OnMsgRetryAuthentication : TNotifyevent read FOnMsgRetryAuthentication write FOnMsgRetryAuthentication;
    Property OnMsgCallbackSetByCaller : Tnotifyevent read FOnMsgCallbackSetByCaller write FOnMsgCallbackSetByCaller;
    Property OnMsgPasswordExpired : TnotifyEvent read FOnMsgPasswordExpired write FOnMsgPasswordExpired;
    Property OnMsgConnected : TNotifyEvent read FOnMsgConnected write FOnMsgConnected;
    Property OnMsgDisconnected : TNotifyEvent read FOnMsgDisconnected write FOnMsgDisconnected;
    Property OnMsgOther : TAHMOnRasMessage read FOnMsgOther write FOnMsgOther;
    Property OnMsgAny : TAHMOnRasMessage read FOnAnyMessage write FOnAnyMessage;
  end;


implementation
uses AHMTRasDefinition;
Var X_Handle : THandle;
    RasModule : HModule = 0;
    AHMRasDial : TFNRasDial = nil;
    AHMRasGetErrorString : TFNRasGetErrorString = nil;
    AHMRasHangUp : TFNRasHangUp = nil;
    AHMRasGetConnectStatus : TFNRasGetConnectStatus = nil;
    AHMRasEnumConnections : TFNRasEnumConnections = nil;
    AHMRasEnumEntries : TFNRasEnumEntries = nil;
    AHMRasGetEntryDialParams : TFNRasGetEntryDialParams = nil;
    AHMRasEditPhonebookEntry : TFNRasEditPhonebookEntry = nil;
    AHMRasCreatePhonebookEntry : TFNRasCreatePhonebookEntry = nil;
    AHMRasGetEntryProperties : TFNRasGetEntryProperties = nil;
    AHMRasSetEntryProperties : TFNRasSetEntryProperties = nil;
    AHMRasDeleteEntry : TFNRasDeleteEntry = nil;
    RASChecked : Boolean = False;

function StrToRas(Value : String): Pointer;
begin
  if Value='' then result:=nil else result:=PChar(Value);
end;

Procedure TAHMRASTimerThread.Execute;
begin
  Priority := OwnerTimer.FThreadPriority;
  repeat
    SleepEx(OwnerTimer.FInterval, False);
    Synchronize(DoTimer);
  until Terminated;
end;

Procedure TAHMRASTimerThread.DoTimer;
begin
  OwnerTimer.Timer;
end;

constructor TAHMRASTimer.Create;
begin
  inherited Create;
  FEnabled := True;
  FInterval := 1000;
  FThreadPriority := tpTimeCritical;
  FTimerThread := TAHMRASTimerThread.Create(false);
  FTimerThread.OwnerTimer := Self;
  UpdateTimer;
end;

destructor TAHMRASTimer.Destroy;
begin
  FEnabled := False;
  UpdateTimer;
  FTimerThread.Free;
  inherited Destroy;
end;

Procedure TAHMRASTimer.UpdateTimer;
begin
  if not(FTimerThread.Suspended) then FTimerThread.Suspend;
  if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
  if (FTimerThread.Suspended) then  FTimerThread.Resume;
end;

Procedure TAHMRASTimer.SetEnabled(Const Value: Boolean);
begin
  if Value <> FEnabled then FEnabled := Value;
  UpdateTimer;
end;

Procedure TAHMRASTimer.SetInterval(Const Value: Word);
begin
  if Value <> FInterval then FInterval := Value;
  UpdateTimer;
end;

Procedure TAHMRASTimer.SetThreadPriority(Const Value: TThreadPriority);
begin
  if Value <> FThreadPriority then FThreadPriority := Value;
  UpdateTimer;
end;

Procedure TAHMRASTimer.Timer;
begin
  if Assigned(FOnTimer) then FOnTimer(Self);
end;


Function InitRas : Boolean;
begin
  if not(RASChecked) then
  begin
    RASChecked:=True;
    RASModule:=0;
    RASModule := LoadLibrary(PChar(RASAPI32));
    result:=RASModule<>0;
  end else result:=RASModule<>0;
end;

function RasDial(RasDialExtensions: PRASDialExtensions;PhoneBook : PChar;RasDialParams : PRASDialParams;
                  NotifierType  : DWORD;Notifier : Pointer;RasConn : PHRASConn): DWORD;
begin
  InitRas;
  if @AHMRasDial = nil then @AHMRasDial := GetProcAddress(RasModule, 'RasDialA');
  if @AHMRasDial <> nil then Result := AHMRasDial(RasDialExtensions,PhoneBook,RasDialParams,NotifierType,Notifier,RasConn)
 else Result := 200;
end;

function RasGetErrorString(uErrorValue   : DWORD;szErrorString : PChar;cBufSize : DWORD): DWORD;
begin
  InitRas;
  if @AHMRasGetErrorString = nil then @AHMRasGetErrorString := GetProcAddress(RasModule, 'RasGetErrorStringA');
  if @AHMRasGetErrorString <> nil then Result := AHMRasGetErrorString(uErrorValue,szErrorString,cBufSize)
  else Result := 200;
end;

function RasHangUp(RasConn: THRASConn): DWORD;
begin
  InitRas;
  if @AHMRasHangUp = nil then @AHMRasHangUp := GetProcAddress(RasModule, 'RasHangUpA');
  if @AHMRasHangUp <> nil then Result := AHMRasHangUp(RasConn) else result:=200;
end;

function RasGetConnectStatus(HRASConn: THRASConn;lpRasConnStatus : PRASConnStatus): DWORD;
begin
  InitRas;
  if @AHMRasGetConnectStatus = nil then @AHMRasGetConnectStatus := GetProcAddress(RasModule, 'RasGetConnectStatusA');
  if @AHMRasGetConnectStatus <> nil then Result := AHMRasGetConnectStatus(HRASConn,lpRasConnStatus)
  else Result := 200;
end;

function RasEnumConnections(pRasConn : PRASConn;pCB : PDWord;pcConnections : PDWord) : DWORD;
begin
  InitRAS;
  if @AHMRasEnumConnections = nil then @AHMRasEnumConnections := GetProcAddress(RasModule, 'RasEnumConnectionsA');
  if @AHMRasEnumConnections <> nil then Result := AHMRasEnumConnections(pRasConn,pCB,pcConnections) else result:=200;
end;

function RasEnumEntries(Reserved : Pointer;szPhonebook : PChar;lpRasEntryName : PRASEntryName; lpcb : PDWord;
                         lpcEntries : PDWord) : DWORD;
begin
  InitRAS;
  if @AHMRasEnumEntries = nil then @AHMRasEnumEntries := GetProcAddress(RasModule, 'RasEnumEntriesA');
  if @AHMRasEnumEntries <> nil then Result := AHMRasEnumEntries(Reserved,szPhonebook,lpRasEntryName,lpcb,lpcEntries) else result:=200;
end;

function RasGetEntryDialParams(lpszPhonebook : PChar;lprasDialParams : PRASDialParams;lpfPassword : PBool) : DWORD;
begin
  InitRAS;
  if @AHMRasGetEntryDialParams = nil then @AHMRasGetEntryDialParams := GetProcAddress(RasModule, 'RasGetEntryDialParamsA');
  if @AHMRasGetEntryDialParams <> nil then Result := AHMRasGetEntryDialParams(lpszPhonebook,lprasDialParams,lpfPassword) else result:=200;
end;

function RasEditPhonebookEntry(hWndParent : HWND;lpszPhonebook : PChar;lpszEntryName : PChar) : DWORD;
begin
  InitRAS;
  if @AHMRasEditPhonebookEntry = nil then @AHMRasEditPhonebookEntry := GetProcAddress(RasModule, 'RasEditPhonebookEntryA');
  if @AHMRasEditPhonebookEntry <> nil then Result := AHMRasEditPhonebookEntry(hWndParent,lpszPhonebook,lpszEntryName) else result:=200;
end;

function RasCreatePhonebookEntryA(hWndParent : HWND;lpszPhonebook : PChar) : DWORD;
begin
  InitRAS;
  if @AHMRasCreatePhonebookEntry = nil then @AHMRasCreatePhonebookEntry := GetProcAddress(RasModule, 'RasCreatePhonebookEntryA');
  if @AHMRasCreatePhonebookEntry <> nil then Result := AHMRasCreatePhonebookEntry(hWndParent,lpszPhonebook) else result:=200;
end;

function RasGetEntryProperties(lpszPhonebook:PChar;lpszEntry:PChar;lpRasEntry : PRasEntry;lpdwEntryInfoSize : PDWord;lpbDeviceInfo :PByte;lpdwDeviceInfoSize:PDWord) : DWORD;
begin
  InitRAS;
  if @AHMRasGetEntryProperties = nil then @AHMRasGetEntryProperties := GetProcAddress(RasModule, 'RasGetEntryPropertiesA');
  if @AHMRasGetEntryProperties <> nil then Result := AHMRasGetEntryProperties(lpszPhonebook,lpszEntry,lpRasEntry,lpdwEntryInfoSize,lpbDeviceInfo,lpdwDeviceInfoSize) else result:=200;
end;

function RasSetEntryProperties(lpszPhonebook:PChar;lpszEntry:PChar;lpRasEntry : PRasEntry;lpdwEntryInfoSize : DWord;lpbDeviceInfo :PByte;lpdwDeviceInfoSize:PDWord) : DWORD;
begin
  InitRAS;
  if @AHMRasSetEntryProperties = nil then @AHMRasSetEntryProperties := GetProcAddress(RasModule, 'RasSetEntryPropertiesA');
  if @AHMRasSetEntryProperties <> nil then Result := AHMRasSetEntryProperties(lpszPhonebook,lpszEntry,lpRasEntry,lpdwEntryInfoSize,lpbDeviceInfo,lpdwDeviceInfoSize) else result:=200;
end;

function RasDeleteEntry(lpszPhonebook:PChar;lpszEntry:PChar): DWORD;
begin
  InitRAS;
  if @AHMRasDeleteEntry = nil then @AHMRasDeleteEntry := GetProcAddress(RasModule, 'RasDeleteEntryA');
  if @AHMRasDeleteEntry <> nil then Result := AHMRasDeleteEntry(lpszPhonebook,lpszEntry) else result:=200;
end;

Function TAHMRASManager.SetError(const Error : DWord) : Boolean;
var Buffer   : Array [0..512] of char;
begin
  result:=False;
  if Error=200 then
  begin
    if assigned(OnRasError) then FOnRasError(self,ahmscRASNotInstalled,Error);
  end else
  if Error=201 then
  begin
    if assigned(OnRasError) then FOnRasError(self,ahmscRASFunctionDoesNotExist,Error);
  end else
  if Error=0 then result:=true else
  begin
    FillChar(Buffer, SizeOf(Buffer), #0);
    RasGetErrorString(Error,@Buffer,SizeOf(Buffer));
    if assigned(OnRasError) then FOnRasError(self,String(Buffer),Error);
  end;
end;

Function TAHMRASManager.ConfigureEntry(Entry : String) : Boolean;
begin
  if Installed and (Entry<>'') then
    result:=SetError(RasEditPhoneBookEntry(X_Handle,StrToRas(FPhoneBook),PChar(Entry)))
  else result:=false;
  UpdateRas;
end;


Function TAHMRASManager.DeleteEntry(Entry : String) : Boolean;
var FDoDelete : Boolean;
begin
  if Installed and (Entry<>'') then
  begin
    Result:=True;
    FDoDelete:=True;
    if assigned(FBeforeDeleteEntry) then FBeforeDeleteEntry(self,FDoDelete);
    if not(FDoDelete) then
    begin
      if assigned(FAfterDeleteEntry) then FAfterDeleteEntry(self,False);
      exit;
    end else
    begin
      if SetError(RasDeleteEntry(StrToRas(FPhoneBook),PChar(Entry))) then
      begin
        if FConnection=Entry then FConnection:='';
        result:=True;
        UpdateRAS;
      end;
      if assigned(FAfterDeleteEntry) then FAfterDeleteEntry(self,result);
    end;
  end else result:=false;
end;


Function TAHMRASManager.CreateEntry : Boolean;
begin
  result:=false;
  if Installed then
  begin
    if SetError(RasCreatePhonebookEntryA(X_Handle, StrToRas(FPhoneBook))) then
    begin
      Result:=True;
      UpdateRas;
      if assigned(FOnNewPhoneEntry) then FOnNewPhoneEntry(self,FConnections[FConnections.Count-1]);
    end;
  end;
end;

Procedure TAHMRASManager.UpdateRAS;
begin
  LoadPhoneBook;
  UpdateEntry;
  if assigned(FOnUpdate) then FOnUpdate(self);
end;

Function TAHMRASManager.LoadPhoneBook : Boolean;
var
  Entries  : array [0..32] of TRASEntryName;
  cb       : DWORD;
  cEntries : DWORD;
  I        : Integer;
begin
  if Installed then
  begin
    FillChar(Entries, SizeOf(Entries), 0);
    Entries[0].dwSize := SizeOf(TRASEntryName);
    cb := SizeOf(Entries);
    cEntries := 0;
    Result:=SetError(RasEnumEntries(NIL,StrToRas(FPhoneBook), @Entries[0], @cb, @cEntries));
    FConnections.Clear;
    for I := 0 to cEntries - 1 do FConnections.Add(Entries[I].szEntryName);
  end else
  begin
    FConnections.Clear;
    result:=false;
  end;
end;



procedure TAHMRASManager.SetConnections(const Value: TStrings);
begin
  FConnections.assign(Value);
end;

constructor TAHMRASManager.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FConnections:=TStringlist.Create;
  FApplicationHandle := Application.Handle;
  FOwnerHandle:=FApplicationHandle;
  FRasTimer:=TAHMRASTimer.Create;
  FRasTimer.OnTimer:=OnRasTimer;
  FRasTimer.Enabled:=True;
  FCheckStatus:=FRasTimer.Interval;
  FAHMRASProperties :=TAHMRASProperties.Create(Self);
  HRASConn:=0;
  InitRAS;
  Hookwin;

end;

Procedure TAHMRasManager.OnRasTimer(Sender : TObject);
var
  RasConnStatus : TRASConnStatus;
  Status        : DWORD;
begin
  if Installed then
  begin
    if (HRASConn = 0) then
    begin
      GetActiveConnection;
      Exit;
    end;
    FillChar(RasConnStatus, SizeOf(RasConnStatus), 0);
    RasConnStatus.dwSize := SizeOf(RasConnStatus);
    Status := RasGetConnectStatus(HRASConn, @RasConnStatus);
    if Status = ERROR_INVALID_HANDLE then
    begin
      if assigned(FOnDisconnected) then FOnDisconnected(self);
      HRASConn := 0;
      FConnectedOn:='';
    end;
  end;
end;


destructor TAHMRASManager.Destroy;
begin
  UnHookWin;
  FRasTimer.Free;
  FConnections.Free;
  FAHMRASProperties.Free;
  inherited Destroy;
end;

procedure TAHMRASManager.Loaded;
begin
  inherited Loaded;
  UpdateRAS;
//  If FOwnerHandle <> FOwnerForm.Handle then
  If FOwnerHandle <> Application.Handle then
  begin
    UnhookWin;
    HookWin;
  end;
end;

procedure TAHMRASManager.SetConnection(const Value: String);
Var OldC : String;
begin
  if Installed then
  begin
    OldC:=FConnection;
    FConnection := Value;
    UpdateEntry;
    if (OldC<>'') and (FConnection<>'') and not(csLoading in Componentstate) then
    if assigned(FOnChangeConnection) then FOnChangeConnection(self,OldC,FConnection);
  end else FConnection:='';
end;

procedure TAHMRASManager.SetPassword(const Value: String);
begin
  FPassword := Value;
end;

procedure TAHMRASManager.SetUsername(const Value: String);
begin
  FUserName := Value;
end;

procedure RasDialFunc(unMsg : DWORD; RasConnState : TRASConnState;dwError : DWORD); stdcall;
begin
  PostMessage(X_Handle,WM_RASDialEvent,RasConnState,dwError);
end;


Function TAHMRASManager.Connect : Boolean;
var rdParams : TRASDialParams;
begin
  result:=False;
  if Installed then
  begin
    if Connected then
    begin
      if assigned(OnRasError) then FOnRasError(self,ahmscrasalreadyConnected,0);
      if assigned(FOnConnectFailed) then FOnConnectFailed(self);
      Exit;
    end;
    FillChar(rdParams,GetRasDialParamSize, 0);
    rdParams.dwSize := GetRasDialParamSize;
    StrCopy(rdParams.szUserName,PChar(FUserName));
    StrCopy(rdParams.szPassword,PChar(FPassword));
    StrCopy(rdParams.szEntryName,PChar(FConnection));
    StrCopy(rdParams.szPhoneNumber,PChar(FNumber));
    StrCopy(rdParams.szDomain,PChar(FDomain));
    rdParams.szCallbackNumber[0] := '*';
    rdParams.szDomain            := '*';
    HRASConn := 0;
    FConnectedOn:='';
    result:=SetError(RasDial(nil,StrToRas(FPhoneBook), @rdParams, 0, @RasDialFunc, @HRASConn));
    if not(result) then
    begin
      Disconnect;
      if assigned(FOnConnectFailed) then FOnConnectFailed(self);
    end else FConnectedOn:=FConnection;
  end;
end;

procedure TAHMRASManager.Disconnect;
begin
  if (HRASConn<>0) then SetError(RasHangUp(HRASConn));
end;

Function TAHMRasManager.GetActiveConnection : Boolean;
var
  nCB    : DWORD;
  I,CO      : Integer;
  aRasConn : array[0..10] of TRASConn;
begin
  Result:=False;
  if Installed then
  begin
    if (HRASConn<>0) then
    begin
      Result:=True;
      Exit;
    end;
    For I:=0 to 10 do
    Fillchar(aRasConn[I],SizeOf(aRasConn[I]),0);
    aRasConn[0].dwSize := SizeOf(aRasConn[0]);
    nCB   := SizeOf(aRasConn);
    if SetError(RasEnumConnections(@aRasConn, @nCB, @nRasConn)) then
    if (nRasConn>0) and (FConnections.Count>0) then
    begin
      for I := 0 to nRasConn - 1 do
      For Co:=0 to FConnections.Count-1 do
      begin
        if StrIComp(PChar(FConnections[CO]), aRasConn[I].szEntryName) = 0 then
        begin
          FConnectedOn:=aRasConn[I].szEntryName;
          if assigned(FOnConnectionExists) then FOnConnectionExists(self,aRasConn[I].szEntryName);
          HRASConn:=aRasConn[I].HRASConn;
          if Connection=FConnections[CO] then
          begin
            result:=true;
            if Assigned(FOnConnected) then FOnConnected(Self);
            Exit;
          end else result:=false;
        end;
      end;
    end;
  end;
end;

function TAHMRASManager.GetActive: Boolean;
begin
  result := GetActiveConnection and (FConnectedOn=FConnection);
  FActive:=Result;
end;

function TAHMRASManager.GetConnected: Boolean;
begin
  if Installed then
  begin
    GetActiveConnection;
    result := (HRASConn<>0);
  end else result:=False;
end;


procedure TAHMRASManager.SetActive(const Value: Boolean);
begin
  if not(Value) and GetActive then
  begin
    Disconnect;
  end else
  if Value and not(GetActive) then
  begin
    Connect;
  end;
  FActive:=Value;
end;

procedure TAHMRASManager.Hooked(var AMsg: TMessage);
begin
  if (AMsg.Msg <> WM_RASDialEvent) or not(Installed) then
  begin
    AMsg.Result:=CallWindowProc(OldWndProc,FOwnerHandle, AMsg.Msg, AMsg.wParam, AMsg.lParam);
    Exit;
  end;
  begin
    case AMsg.wParam of
      RAScsOpenPort: if assigned(FOnMSGOpenPort) then FOnMSGOpenPort(self);
      RAScsPortOpened: if assigned(FOnMSGPortOpened) then FOnMSGOpenPort(self);
      RAScsConnectDevice: if assigned(FOnMSGConnectDevice) then FOnMSGConnectDevice(self);
      RAScsDeviceConnected: if assigned(FOnMSGDeviceConnected) then FOnMSGDeviceConnected(self);
      RAScsAllDevicesConnected: if assigned(FOnMSGAllDevicesConnected) then FOnMSGAllDevicesConnected(self);
      RAScsAuthenticate: if assigned(FOnMSGAuthenticate) then FOnMSGAuthenticate(self);
      RAScsAuthNotify: if assigned(FOnMSGAuthNotify) then FOnMSGAuthNotify(self);
      RAScsAuthRetry: if assigned(FOnMSGAuthRetry) then FOnMSGAuthRetry(self);
      RAScsAuthCallback: if assigned(FOnMSGAuthCallback) then FOnMSGAuthCallback(self);
      RAScsAuthChangePassword: if assigned(FOnMSGAuthChangePassword) then FOnMSGAuthChangePassword(self);
      RAScsAuthProject: if assigned(FOnMSGAuthProject) then FOnMSGAuthProject(self);
      RAScsAuthLinkSpeed: if assigned(FOnMSGAuthLinkSpeed) then FOnMSGAuthlinkSpeed(self);
      RAScsAuthAck: if assigned(FOnMSGAuthAck) then FOnMSGAuthAck(self);
      RAScsReAuthenticate: if assigned(FOnMSGReAuthenticate) then FOnMSGReAuthenticate(self);
      RAScsAuthenticated: if assigned(FOnMSGAuthenticated) then FOnMSGAuthenticated(self);
      RAScsPrepareForCallback: if assigned(FOnMSGPrepareForCallback) then FOnMSGPrepareForCallback(self);
      RAScsWaitForModemReset: if assigned(FOnMSGWaitForModemReset) then FOnMSGWaitForModemReset(self);
      RAScsWaitForCallback: if assigned(FOnMSGWaitForCallback) then FOnMSGWaitForCallback(self);
      RAScsProjected: if assigned(FOnMSGProjected) then FOnMSGProjected(self);
      RAScsStartAuthentication: if assigned(FOnMSGStartAuthentication) then FOnMSGStartAuthentication(self);
      RAScsCallbackComplete: if assigned(FOnMSGCallBackComplete) then FOnMSGCallbackComplete(self);
      RAScsLogonNetwork: if assigned(FOnMSGLogonNetwork) then FOnMSGLogonNetwork(self);
      RAScsSubEntryConnected: if assigned(FOnMSGSubEntryConnected) then FOnMSGSubEntryConnected(self);
      RAScsSubEntryDisconnected: if assigned(FOnMSGSubEntryDisconnected) then FOnMSGSubEntryDisconnected(self);
      RAScsInteractive: if assigned(FOnMSGInteractive) then FOnMSGInteractive(self);
      RAScsRetryAuthentication: if assigned(FOnMSGRetryAuthentication) then FOnMSGRetryAuthentication(self);
      RAScsCallbackSetByCaller: if assigned(FOnMSGCallbackSetByCaller) then FOnMSGCallBackSetByCaller(self);
      RAScsPasswordExpired: if assigned(FOnMSGPasswordExpired) then FOnMSGPasswordExpired(self);
      RAScsConnected: if assigned(FOnMsgConnected) then FOnMSGConnected(self);
      RAScsDisconnected: if assigned(FOnMsgDisconnected) then FOnMSGDisconnected(self);
    else
      if assigned(FOnMSGOther) then FOnMSGOther(self,AMsg.WParam);
    end;
    if assigned(FOnAnyMessage) then FOnAnyMessage(self,AMsg.WParam);
    if AMsg.wParam = RAScsConnected then  if assigned(FOnConnected) then FOnConnected(Self);
  end;
  AMsg.Result:=CallWindowProc(OldWndProc,FOwnerHandle, AMsg.Msg, AMsg.wParam, AMsg.lParam);
end;

procedure TAHMRASManager.HookWin;
begin
  if (csDesigning in Componentstate) then exit;
  X_Handle     := FOwnerHandle;
  FOwnerHandle:=Application.Handle;
  OldWndProc   := TFarProc(GetWindowLong(FOwnerHandle, GWL_WNDPROC));
  NewWndProc   := MakeObjectInstance(Hooked);
  SetWindowLong(FOwnerHandle, GWL_WNDPROC, LongInt(NewWndProc));
end;

procedure TAHMRASManager.UnhookWin;
begin
  if (csDesigning in Componentstate) then exit;
  SetWindowLong(FOwnerHandle, GWL_WNDPROC, LongInt(OldWndProc));
  if assigned(NewWndProc) then FreeObjectInstance(NewWndProc);
  NewWndProc := nil;
end;

procedure TAHMRASManager.SetCheckStatus(const Value: LongInt);
begin
  FCheckStatus := Value;
  FRasTimer.Interval:=Value;
end;

procedure TAHMRASManager.UpdateEntry;
var
  rdParams : TRASDialParams;
  rdEntry : TRASEntry;
  Return   : DWORD;
  szEntry : DWord;
  Buffer   : array [0..255] of Char;
  Pass : BOOL;
begin
  if Installed and (FConnection<>'') then
  begin
    FillChar(rdParams, GetRasDialParamSize,#0);
    rdParams.dwSize := GetRasDialParamSize;
    StrCopy(rdParams.szEntryName,PChar(FConnection));
    StrPCopy(rdParams.szUserName,'');
    StrPCopy(rdParams.szPhoneNumber,'');
    StrPCopy(rdParams.szDomain,'');
    Return := RasGetEntryDialParams(StrToRas(FPhoneBook),@rdParams,@Pass);
    if Return <> 0 then
    begin
      FillChar(Buffer, SizeOf(Buffer), #0);
      RasGetErrorString(Return,@Buffer,255);
      if assigned(OnRasError) then FOnRasError(self,String(Buffer),Return);
    end else
    begin
      FillChar(rdEntry, GetRasEntrySize, 0);
      rdEntry.dwSize := GetRasEntrySize;
      szEntry:=GetRasEntrySize;
      Return:=RasGetEntryProperties(StrToRas(FPhoneBook),PChar(FConnection),@rdEntry,@szEntry,nil,nil);
      if Return <> 0 then
      begin
        FillChar(Buffer, SizeOf(Buffer), #0);
        RasGetErrorString(Return,@Buffer,255);
      if assigned(OnRasError) then FOnRasError(self,String(Buffer),Return);
      end else
      begin
        Username := String(rdParams.szUserName);
        Password := String(rdParams.szPassword);
        Domain := String(rdParams.szDomain);
        FNoPassword := Boolean(Pass);
      end;
      FAHMRasProperties.GetInternalEntry;
    end;
  end;
end;

procedure TAHMRASManager.SetDomain(const Value: String);
begin
  FDomain := Value;
end;

{ TAHMRASProperties }

Function TAHMRASProperties.GetInternalEntry : Boolean;
var
  Return   : DWORD;
  szEntry : DWord;
  Buffer   : array [0..255] of Char;
begin
  result:=false;
  if (RasManager.Installed) and (RasManager.FConnection<>'') then
  begin
    FillChar(InternalEntry, GetRasEntrySize, 0);
    InternalEntry.dwSize := GetRasEntrySize;
    szEntry:=GetRasEntrySize;
    Return:=RasGetEntryProperties(StrToRas(RASManager.FPhoneBook),PChar(RASManager.FConnection),@InternalEntry,@szEntry,nil,nil);
    if Return <> 0 then
    begin
      FillChar(Buffer, SizeOf(Buffer), #0);
      RasGetErrorString(Return,@Buffer,255);
      if assigned(RasManager.FOnRasError) then RasManager.FOnRasError(self,String(Buffer),Return);
    end else result:=true;
  end;
end;

procedure TAHMRASProperties.SetInternalEntry;
var
  Return   : DWORD;
  szEntry : DWord;
  Buffer   : array [0..512] of Char;
begin
  if RasManager.Installed and (RasManager.FConnection<>'') then
  begin
    InternalEntry.dwSize := GetRasEntrySize;
    szEntry:=GetRasEntrySize;
    Return:=RasSetEntryProperties(PChar(RasManager.FPhoneBook),PChar(RASManager.FConnection),@InternalEntry,szEntry,nil,nil);
    if Return <> 0 then
    begin
      FillChar(Buffer, SizeOf(Buffer), #0);
      RasGetErrorString(Return,@Buffer,512);
      if assigned(RasManager.FOnRasError) then RasManager.FOnRasError(self,String(Buffer),Return);
    end;
  end;
end;


constructor TAHMRASProperties.Create(AOwner: TAHMRASManager);
begin
  inherited Create;
  FAHMRASManager:=AOwner;
end;

function TAHMRASProperties.GetAreaCode: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szAreaCode) else result:='';
end;

function TAHMRASProperties.GetAutoDialDLL: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szAutoDialDLL) else result:='';
end;

function TAHMRASProperties.GetAutoDialFunc: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szAutoDialFunc) else result:='';
end;

function TAHMRASProperties.GetCountryCode: DWord;
begin
  if GetInternalEntry then Result:= InternalEntry.dwCountryCode else result:=0;
end;

function TAHMRASProperties.GetCountryID: DWord;
begin
  if GetInternalEntry then Result:= InternalEntry.dwCountryID else result:=0;
end;

function TAHMRASProperties.GetDeviceName: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szDeviceName) else result:='';
end;

function TAHMRASProperties.GetDeviceType: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szDeviceType) else result:='';
end;

function TAHMRASProperties.GetFrameSize: DWord;
begin
  if GetInternalEntry then Result:= InternalEntry.dwFrameSize else result:=0;
end;

function TAHMRASProperties.GetIPAddress: String;
begin
  if GetInternalEntry then Result:= InttoStr(InternalEntry.IpAddr.a)+'.'+InttoStr(InternalEntry.IpAddr.b)+'.'+InttoStr(InternalEntry.IpAddr.c)+'.'+InttoStr(InternalEntry.IpAddr.d) else result:='0.0.0.0';
end;

function TAHMRASProperties.GetIPAddressDNS: String;
begin
  if GetInternalEntry then Result:= InttoStr(InternalEntry.IpAddrDNS.a)+'.'+InttoStr(InternalEntry.IpAddrDNS.b)+'.'+InttoStr(InternalEntry.IpAddrDNS.c)+'.'+InttoStr(InternalEntry.IpAddrDNS.d) else result:='0.0.0.0';
end;

function TAHMRASProperties.GetIPAddressDNSAlt: String;
begin
  if GetInternalEntry then Result:= InttoStr(InternalEntry.IpAddrDNSAlt.a)+'.'+IntToStr(InternalEntry.IpAddrDNSAlt.b)+'.'+InttoStr(InternalEntry.IpAddrDNSAlt.c)+'.'+IntToStr(InternalEntry.IpAddrDNSAlt.d) else result:='0.0.0.0';
end;

function TAHMRASProperties.GetIPAddressWINS: String;
begin
  if GetInternalEntry then Result:= InttoStr(InternalEntry.IpAddrWINS.a)+'.'+InttoStr(InternalEntry.IpAddrWINS.b)+'.'+InttoStr(InternalEntry.IpAddrWINS.c)+'.'+InttoStr(InternalEntry.IpAddrWINS.d) else result:='0.0.0.0';
end;

function TAHMRASProperties.GetIPAddressWINSAlt: String;
begin
  if GetInternalEntry then Result:= inttoStr(InternalEntry.IpAddrWINSAlt.a)+'.'+InttoStr(InternalEntry.IpAddrWINSAlt.b)+'.'+InttoStr(InternalEntry.IpAddrWINSAlt.c)+'.'+inttoStr(InternalEntry.IpAddrWINSAlt.d) else result:='0.0.0.0';
end;

function TAHMRASProperties.GetNetProtocols: TAHMNetProtocols;
begin
  Result:=[];
  if GetInternalEntry then
  begin
    if (InternalEntry.dwNetProtocols and RASnp_Ipx)=RASnp_Ipx then include(result,npIPX);
    if (InternalEntry.dwNetProtocols and RASnp_Ip)=RASnp_Ip then include(result,npTCPIP);
    if (InternalEntry.dwNetProtocols and RASnp_NetBeui)=RASnp_Netbeui then include(result,npNETBEUI);
  end;
end;

function TAHMRASProperties.GetPhoneNumber: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.pLocalPhoneNumber) else result:='';
end;

function TAHMRASProperties.GetScript: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szScript) else result:='';
end;

function TAHMRASProperties.GetX25Address: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szX25Address) else result:='';
end;

function TAHMRASProperties.GetX25Facilities: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szX25Facilities) else result:='';
end;

function TAHMRASProperties.GetX25PadType: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szX25PadType) else result:='';
end;

function TAHMRASProperties.GetX25UserData: String;
begin
  if GetInternalEntry then Result:= String(InternalEntry.szX25UserData) else result:='';
end;

procedure TAHMRASProperties.SetAreaCode(const Value: String);
begin
  StrCopy(InternalEntry.szAreaCode,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetAutoDialDLL(const Value: String);
begin
  StrCopy(InternalEntry.szAutoDialDLL,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetAutoDialFunc(const Value: String);
begin
  StrCopy(InternalEntry.szAutoDialFunc,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetCountryCode(const Value: DWord);
begin
  InternalEntry.dwCountryCode:=Value;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetCountryID(const Value: DWord);
begin
  InternalEntry.dwCountryID:=Value;
  if Value<>0 then
    InternalEntry.Options:=InternalEntry.Options or RASDef_UseCountryAndAreaCodes
  else
    InternalEntry.Options:=InternalEntry.Options - RASDef_UseCountryAndAreaCodes;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetDeviceName(const Value: String);
begin
  StrCopy(InternalEntry.szDeviceName,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetDeviceType(const Value: String);
begin
  StrCopy(InternalEntry.szDeviceType,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetFrameSize(const Value: DWord);
begin
  InternalEntry.dwFrameSize:=Value;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetIPAddress(const Value: String);
Var IPD,IPC : String;
begin
  try
    IpD:=Value;
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddr.a:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddr.b:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddr.c:=StrToInt(IPC);
    IPC:=IPD;
    InternalEntry.IpAddr.d:=StrToInt(IPC);
    InternalEntry.Options:=InternalEntry.Options or RASDef_SpecificIpAddr;
    SetInternalEntry;
  except
    if assigned(RasManager.FOnRasError) then RasManager.FOnRasError(self,ahmscInvalidIp,0);
  end;
end;

procedure TAHMRASProperties.SetIPAddressDNS(const Value: String);
var IpD,IpC : String;
begin
  try
    IpD:=Value;
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNS.a:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNS.b:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNS.c:=StrToInt(IPC);
    IPC:=IPD;
    InternalEntry.IpAddrDNS.d:=StrToInt(IPC);
  except
     if assigned(Rasmanager.FOnRasError) then Rasmanager.FOnRasError(self,ahmscinvalidIp,0);
  end;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetIPAddressDNSAlt(const Value: String);
var IpD,IpC : String;
begin
  try
    IpD:=Value;
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNSAlt.a:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNSAlt.b:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrDNSAlt.c:=StrToInt(IPC);
    IPC:=IPD;
    InternalEntry.IpAddrDNSAlt.d:=StrToInt(IPC);
  except
     if assigned(Rasmanager.FOnRasError) then Rasmanager.FOnRasError(self,ahmscinvalidIp,0);
  end;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetIPAddressWINS(const Value: String);
var IpD,IpC : String;
begin
  try
    IpD:=Value;
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINS.a:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINS.b:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINS.c:=StrToInt(IPC);
    IPC:=IPD;
    InternalEntry.IpAddrWINS.d:=StrToInt(IPC);
  except
     if assigned(Rasmanager.FOnRasError) then Rasmanager.FOnRasError(self,ahmscinvalidIp,0);
  end;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetIPAddressWINSAlt(const Value: String);
var IpD,IpC : String;
begin
  try
    IpD:=Value;
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINSAlt.a:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINSAlt.b:=StrToInt(IPC);
    IPC:=Copy(IPD,1,Pos('.',IPD)-1);
    Delete(IPD,1,Pos('.',IPD));
    InternalEntry.IpAddrWINSAlt.c:=StrToInt(IPC);
    IPC:=IPD;
    InternalEntry.IpAddrWINSAlt.d:=StrToInt(IPC);
  except
     if assigned(Rasmanager.FOnRasError) then Rasmanager.FOnRasError(self,ahmscinvalidIp,0);
  end;
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetNetProtocols(const Value: TAHMNetProtocols);
begin
  InternalEntry.dwNetProtocols:=0;
  if (npIPX in Value) then InternalEntry.dwNetProtocols:=(InternalEntry.dwNetProtocols or RASnp_Ipx);
  if (npTCPIP in Value) then InternalEntry.dwNetProtocols:=(InternalEntry.dwNetProtocols or RASnp_Ip);
  if (npNETBEUI in Value) then InternalEntry.dwNetProtocols:=(InternalEntry.dwNetProtocols or RASnp_NetBeui);
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetPhoneNumber(const Value: String);
begin
  StrCopy(InternalEntry.pLocalPhoneNumber,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetScript(const Value: String);
begin
  StrCopy(InternalEntry.szScript,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetX25Address(const Value: String);
begin
  StrCopy(InternalEntry.szX25Address,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetX25Facilities(const Value: String);
begin
  StrCopy(InternalEntry.szX25Facilities,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetX25PadType(const Value: String);
begin
  StrCopy(InternalEntry.szX25PadType,PChar(Value));
  SetInternalEntry;
end;

procedure TAHMRASProperties.SetX25UserData(const Value: String);
begin
  StrCopy(InternalEntry.szX25UserData,PChar(Value));
  SetInternalEntry;
end;

function TAHMRASProperties.GetConnectionOptions: TAHMConnectionOptions;
begin
  result:=[];
  if GetInternalEntry then
  begin
    if (InternalEntry.Options and RASDef_UseCountryAndAreaCodes)=RASDef_UseCountryAndAreaCodes then Include(result,coUseCountryAndAreaCodes);
    if (InternalEntry.Options and RASDef_SpecificIpAddr)=RASDef_SpecificIpAddr then Include(result,coSpecificIpAddr);
    if (InternalEntry.Options and RASDef_SpecificNameServers)=RASDef_SpecificNameServers then Include(result,coSpecificNameServers);
    if (InternalEntry.Options and RASDef_IpHeaderCompression)=RASDef_IpHeaderCompression then Include(result,coIpHeaderCompression);
    if (InternalEntry.Options and RASDef_RemoteDefaultGateway)=RASDef_RemoteDefaultGateway then Include(result,coRemoteDefaultGateway);
    if (InternalEntry.Options and RASDef_DisableLcpExtensions)=RASDef_DisableLcpExtensions then Include(result,coDisableLcpExtensions);
    if (InternalEntry.Options and RASDef_TerminalBeforeDial)=RASDef_TerminalBeforeDial then Include(result,coTerminalBeforeDial);
    if (InternalEntry.Options and RASDef_TerminalAfterDial)=RASDef_TerminalAfterDial then Include(result,coTerminalAfterDial);
    if (InternalEntry.Options and RASDef_ModemLights)=RASDef_ModemLights then Include(result,coModemLights);
    if (InternalEntry.Options and RASDef_SwCompression)=RASDef_SwCompression then Include(result,coSwCompression);
    if (InternalEntry.Options and RASDef_RequireEncryptedPw)=RASDef_RequireEncryptedPw then Include(result,coRequireEncryptedPw);
    if (InternalEntry.Options and RASDef_RequireMsEncryptedPw)=RASDef_RequireMsEncryptedPw then Include(result,coRequireMsEncryptedPw);
    if (InternalEntry.Options and RASDef_RequireDataEncryption)=RASDef_RequireDataEncryption then Include(result,coRequireDataEncryption);
    if (InternalEntry.Options and RASDef_NetworkLogon)=RASDef_NetworkLogon then Include(result,coNetworkLogon);
    if (InternalEntry.Options and RASDef_UseLogonCredentials)=RASDef_UseLogonCredentials then Include(result,coUseLogonCredentials);
{    if (InternalEntry.Options and RASDef_PromoteAlternates)=RASDef_PromoteAlternates then Include(result,coPromoteAlternates);}
  end;
end;



procedure TAHMRASProperties.SetConnectionOptions(
  const Value: TAHMConnectionOptions);
begin
  InternalEntry.Options:=0;
  if (coUseCountryAndAreaCodes in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_UseCountryAndAreaCodes;
  if (coSpecificIpAddr in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_SpecificIpAddr;
  if (coSpecificNameServers in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_SpecificNameServers;
  if (coIpHeaderCompression in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_IpHeaderCompression;
  if (coRemoteDefaultGateway in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_RemoteDefaultGateway;
  if (coDisableLcpExtensions in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_DisableLcpExtensions;
  if (coTerminalBeforeDial in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_TerminalBeforeDial;
  if (coTerminalAfterDial in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_TerminalAfterDial;
  if (coModemLights in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_ModemLights;
  if (coSwCompression in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_SwCompression;
  if (coRequireEncryptedPw in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_RequireEncryptedPw;
  if (coRequireMsEncryptedPw in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_RequireMsEncryptedPw;
  if (coRequireDataEncryption in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_RequireDataEncryption;
  if (coNetworkLogon in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_NetworkLogon;
  if (coUseLogonCredentials in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_UseLogonCredentials;
  if (coPromoteAlternates in Value) then InternalEntry.Options:=InternalEntry.Options or RASDef_PromoteAlternates;
  SetInternalEntry;
end;


function TAHMRASManager.GetInstalled: Boolean;
begin
  result:=RASModule<>0;
  {Still outstanding - AHM}
end;

procedure TAHMRASManager.Setinstalled(const Value: Boolean);
begin
  {Still outstanding - AHM}
end;

procedure TAHMRASManager.SetPhonebook(const Value: String);
begin
  FPhoneBook := Value;
  UpdateEntry;
end;

initialization

finalization
  if RASModule <> 0 then FreeLibrary(RASModule);

end.
