1/24/2003
Resolved issues for APRO [Windows]
This file details all the resolved issues in APRO. The fixes are generated from our changes log. This page is being made available as a service to our customers, those who want to have the absolute latest code for their development. The issues listed may be present in older versions of APRO, having been unnoticed until the present time.
If you decide to make use of this information a couple of things must be made clear.
Total number of resolved issues: 43
| Issue |
Fixed? |
Fix date | Description |
|
1350 |
11/5/2002 | TInAddr conflicts with other components | |
|
1880 |
1/7/2003 | Multiple instances | |
|
3217 |
11/4/2002 | Once connected to an invalid ftp site, can't connect again. | |
|
3373 |
11/1/2002 | YModem locks files | |
|
3515 |
9/19/2002 | Need update the status when setting DTR and RTS. | |
|
3548 |
11/4/2002 | Cannot enter hex values in state conditions | |
|
3580 |
10/30/2002 | Error handling | |
|
3623 |
10/31/2002 | TAPI Hold and transfer capabilities | |
|
3688 |
10/31/2002 | TAdModem.BPSRate property not updated | |
|
3702 |
9/19/2002 | TApdSendFax, fpPageOK not used for class1 | |
|
3756 |
11/1/2002 | enh: Add ability to force YModem to 128 byte blocks | |
|
3861 |
9/17/2002 | Invalid modem attributes in XML files | |
|
3866 |
9/18/2002 | State machine - Mem leak upon deactivating | |
|
3867 |
11/4/2002 | States - StartString and EndString do not escape strings | |
|
3879 |
10/31/2002 | Fax - Class 1.0 implementation omission | |
|
3887 |
9/20/2002 | Data packet - AV on destroy | |
|
3888 |
9/20/2002 | Assign/AssignFile overloads causing problems | |
|
3927 |
9/24/2002 | TAdModem AV when destroyed | |
|
3941 |
9/25/2002 | State machine accesses port after closing | |
|
3980 |
11/5/2002 | OnProcessChar Command ecAnswerBack does not work. | |
|
3981 |
11/5/2002 | Add OnProcessChar commands for cursor on/off | |
|
3982 |
1/7/2003 | Support for Siemens S35i (PDU Mode?) | |
|
4004 |
10/9/2002 | Dialing using tone/pulse with TAdModem. | |
|
4010 |
11/4/2002 | AV even though ftp://ftp.turbopower.com/pub/apro/updates/APROFixes.htm#3887 was applied. | |
|
4016 |
10/29/2002 | FConnectFired may have broken DoDisconnect. | |
|
4050 |
11/5/2002 | Request for read only properties to indicate if scroll bars in use. | |
|
4055 |
11/1/2002 | TAdModem - incorrect exception if modemcap folder not found | |
|
4056 |
11/1/2002 | TApdModemStatusDialog - Cancel button doesn't work | |
|
4057 |
11/1/2002 | TAdModem - AV if port not opened | |
|
4062 |
11/4/2002 | Data packet - AV on destroy revisited | |
|
4064 |
11/5/2002 | RAS - Add support for programatic phonebook additions | |
|
4065 |
11/6/2002 | RAS - Add support to retrieve connection statistics | |
|
4066 |
11/5/2002 | Invalid Scroll Regions cause AV | |
|
4067 |
11/5/2002 | Provide manual adjustment of character cell sizes in terminal | |
|
4068 |
11/5/2002 | TAdTerminalEmulator.teProcessCommand can AV with no terminal | |
|
4071 |
11/6/2002 | RAS - Missing some consts | |
|
4082 |
11/8/2002 | AV On destroy when turning off mouseselect | |
|
4096 |
11/18/2002 | TAdModem - incompatible with user's OnTriggerXxx | |
|
4121 |
11/26/2002 | OnTapiFail getting called twice for one failure. | |
|
4132 |
12/3/2002 | Fonts changing works incorrectly with VT100 | |
|
4159 |
12/6/2002 | AdModem - SetDevConfig not forcing initialization | |
|
4177 |
12/13/2002 | TApdFaxConverter - idShell conversion may leave reg/ini keys | |
|
4186 |
12/13/2002 | TApdSendFax - Class1 error handling |
Bug fixes and enhancements
| Issue |
Type |
Description |
|
fix |
TInAddr conflicts with other components | |
The TInAddr type was declared in AdWUtil.pas and AdWnPort.pas, which could
cause a type conflict problem. To fix, move the following declarations to
OOMisc.pas:
{$IFNDEF PrnDrv}
type
{ moved from AdWUtil } {!!.06}
SunB = packed record
s_b1, s_b2, s_b3, s_b4 : AnsiChar;
end;
{ moved from AdWUtil } {!!.06}
SunW = packed record
s_w1, s_w2 : Word;
end;
{ moved from AdWnPort and AdWUtil } {!!.06}
PInAddr = ^TInAddr;
TInAddr = packed record
case Integer of
0 : (S_un_b : SunB);
1 : (S_un_w : SunW);
2 : (S_addr : LongInt);
end;
{ XML support }
Back |
||
|
enh |
Multiple instances | |
The TApdFaxDriverInterface is a single-instance component, only one can interface with the printer driver at any given time. As a workaround, the 4.06 printer driver provides several different ways to control the print job via registry/ini settings. Back |
||
|
fix |
Once connected to an invalid ftp site, can't connect again. | |
Connecting to an invalid FTP server (one that does not exist or that refuses
the connection) will cause subsequent connection attempts by the TApdFTPClient
to fail. To fix, make the following change to AdFtp.pas marked by {!!.06}
function TApdCustomFtpClient.Login : Boolean;
{log on to ftp server}
...
end else begin
{ port is already open, must be trying to re-log in }
SendCommand(fcUSER + ' ' + FUserName);
end;
if Result then {!!.06}
ChangeState(psLogin);
end;
end;
Back |
||
|
fix |
YModem locks files | |
In AwAbsPcl.pas, make the following changes marked by {!!.06}
procedure apStopProtocol(P : PProtocolData);
...
{Close the file, if it's still open}
if aFileOpen or (TFileRec(aWorkFile).Mode <> fmClosed) then begin {!!.06}
CloseFile(aWorkFile); {!!.06}
aFileOpen := False;
end;
Back |
||
|
fix |
Need update the status when setting DTR and RTS. | |
Under Win9x, status triggers could be missed. This was due to a timing problem
with the notification we receive from the port drivers. To fix, make the
following change to AwUser.pas marked by {!!!}. This has been tested on
Win98SE, W2K and XP boxes, further testing is required. Search for "received
status" to find the location to change, around line 4750 in 4.05)
...
{ Get any available data }
ExtractData;
{Check for received status & data triggers}
if not fEventBusy then begin
ModemStatus := GetModemStatus;{!!!}
while CheckStatusTriggers do
if ClosePending then
Exit;
while CheckReceiveTriggers do
if ClosePending then
Exit;
end;
...
Back |
||
|
fix |
Cannot enter hex values in state conditions | |
The TApdState.Conditions.StartString and EndString properties do not support
non-printable characters in the object inspector. To fix, make the following
change to AdPropEd.pas marked by {!!.06} and rebuild the packages.
{ property editor for TApdState strings }
RegisterPropertyEditor(TypeInfo(string), TApdStateCondition, {!!.06}
'StartString', TApdPacketStringProperty); {!!.06}
RegisterPropertyEditor(TypeInfo(string), TApdStateCondition, {!!.06}
'EndString', TApdPacketStringProperty); {!!.06}
Back |
||
|
enh |
Error handling | |
Error handling in the printer drivers could use some tweaking. 4.06 greatly
improved error handling and printer driver customization, enabled through
registry entries. Changes are quite numerous, contact tech support if you need
the revisions.
Registry entries are described below.
NOTE, for Windows Terminal Server/Clients, changing the root to
HKEY_CURRENT_USER, and using the ShellHandle and ShellName entries may allow
you to control the printer driver under this environment.
The fax printer driver supports several registry entries to control the
print jobs. Absence of these values will cause default behavior.
HKEY_LOCAL_MACHINE
ApdRegKey - defined in OOMisc.pas
// idShell conversions
ShellHandle : Integer, determines whether we are in an idShell conversion
this is the window handle that will receive our messages
ShellName : string, the name of the resulting APF for an idShell
conversion
// spawning app when print job starts
AutoExec : string, the name of an app to spawn if a
TApdFaxDriverInterface isn't found
Timeout : Integer, the time we'll wait for the app to spawn
// debug logging
EventLogging: Boolean, whether we log the codes/subcodes
DumpLogging : Boolean, whether we record the raw printer data
// general
DefFileName : string, the default name of the resulting APF
SuppressAV : Bool, true to suppress any APRO-raised AVs*
// Post-print job APF modifications
HeadFiller : Integer, a 1-byte value to be written to the APF's file
header in the Filler field, can be used to identify the
machine, job, etc
HeadPadding : string, a 26-char value to be written to the APF's file
header in the Padding field, can be used for phone number,
ID, etc
Back |
||
|
enh |
TAPI Hold and transfer capabilities | |
TAPI Transfer, Hold and UnHold methods added to TApdTapiDevice. Quite extensive changes ranging across AdTapi.pas and AdTUtil.pas. Modified unit available from http://www.aprozilla.com/betatest.htm. Back |
||
|
fix |
TAdModem.BPSRate property not updated | |
Fixed as a side-effect of a 4.04 change. Back |
||
|
fix |
TApdSendFax, fpPageOK not used for class1 | |
The fpPageOK FaxProgress flag was not used for Class1 transmits. To fix, make
the following changes marked by {!!.06} to AwFax.pas:
procedure fFaxTransmit(Msg, wParam : Cardinal;
lParam : LongInt);
{-Perform one increment of a fax transmit}
...
tf1WaitMCF :
...
{No more pages}
caPutFrameT(FP);
fState := tf1SendDCN;
end;
end;
if cReceivedFrame in [RTPFrame, MCFFrame] then begin {!!.06}
aFaxProgress := fpPageOK; {!!.06}
cForceStatus := True; {!!.06}
end; {!!.06}
{Ask for the next frame if there are more coming}
Back |
||
|
enh |
enh: Add ability to force YModem to 128 byte blocks | |
New TApdProtocol.YModem128ByteBlocks property added (public). Set to true to start YModem in 128-byte blocks and prohibit 1K blocks. Not normally required. Back |
||
|
fix |
Invalid modem attributes in XML files | |
Several of the modemcap files had invalid attributes. Most notably, the Friendly names of some modems contained comments from the original INF file. For example, the Rockwell 33.6 modem (in mdmrock4.xml), had a FriendlyName of FriendlyName = ""Rockwell 33.6 PnP" ;//WHQL" when it should have been FriendlyName = "Rockwell 33.6 PnP" To fix, download the new modemcap.zip from ftp://ftp.turbopower.com/pub/apro/updates/, or manually remove the comments from the XML files. Back |
||
|
fix |
State machine - Mem leak upon deactivating | |
When a state is deactivated, the internal PacketList is not cleared, leading to
a memory leak and Index out of bounds exceptions. To fix, make the following
change to AdStMach.pas marked by {!!.05}:
procedure TApdStateComPortSource.StateMachineDeactivate (State :
TApdCustomState);
var
I : Integer;
begin
{ disable and free our Condition's data packets }
for I := 0 to pred(PacketList.Count) do begin
TApdDataPacket(PacketList[I]).Free;
PacketList[I] := nil;
end;
PacketList.Clear; {!!.05}
end;
Back |
||
|
fix |
States - StartString and EndString do not escape strings | |
Same as bug 3548. Entering the strings at run-time can be done literally. Back |
||
|
fix |
Fax - Class 1.0 implementation omission | |
When we're using FaxClass 1.0, we are sending the wrong FCLASS= command. To
fix, make the following changes to AwFax.pas marked by {!!.06}:
procedure fFaxReceive(Msg, wParam : Cardinal;
...
{Main state machine}
case fState of
rfInit :
begin
...
{Set the fax class}
if aClassInUse = ctClass1 then begin
fState := rf1Init1;
caPutModem(FP, cClassCmd); {!!.06}
end else begin
fState := rf2Init1;
....
function fPrepareFaxReceive(FP : PFaxRec) : Integer;
...
{Set class}
if (fFirstState <> rf2GetSenderID) then
if aClassInUse = ctClass1 then begin
if not caProcessModemCmd(FP, cClassCmd) then begin {!!.06}
Cleanup;
Exit;
....
Back |
||
|
fix |
Data packet - AV on destroy | |
Under certain conditions, the TApdDataPacket can cause an AV when being
destroyed. To fix, make the following changes to AdPacket.pas marked by
{!!.06}:
procedure TApdDataPacketManager.DisablePackets;
var
i : integer;
begin
{ this can get called when destroying, and called in the context of }
{ different threads, make sure the PacketList is still around }
if Assigned(PacketList) do {!!.06}
for i := 0 to pred(PacketList.Count) do
if Assigned(PacketList[i]) then {!!.06}
with TApdDataPacket(PacketList[i]) do
Disable;
end;
Back |
||
|
fix |
Assign/AssignFile overloads causing problems | |
Delphi 6.00 had a bug in the Assign/AssignFile methods which would cause AVs
when PChar parameters were passed to those methods. Since the bowels of APRO
contains many instances where we pass PChars to these methods, they were
overloaded in 3.07. Tests with Delphi 6.02 reveal that these bugs have been
fixed. The overloaded methods were not all-inclusive, which would cause
compiler errors when using a non-overloaded version. To fix, comment out the
following sections in OOMisc.pas:
{.$IFDEF Delphi6} {!!.06}
{ These methods were overloaded to work around a Delphi 6 bug. Tests with
Delphi 6.02 reveal that the bugs have been fixed. Comment-out the declarations
in the implementation section below also.
procedure AssignFile(var F: File; const FileName: string); overload;
procedure AssignFile(var F: TextFile; const FileName : string); overload;
procedure Assign(var F: File; const FileName: string); overload;
procedure Assign(var F: TextFile; const FileName: string); overload;}
{.$ENDIF} {!!.06}
implementation
...
{.$IFDEF Delphi6} {!!.06}
{ These methods were overloaded to work around a Delphi 6 bug. Tests with
Delphi 6.02 reveal that the bugs have been fixed. Comment-out the declarations
in the interface section above also.
procedure AssignFile(var F: File; const FileName: string);
begin
System.AssignFile(F, FileName);
end;
procedure AssignFile(var F: TextFile; const FileName : string);
begin
System.AssignFile(F, FileName);
end;
procedure Assign(var F: File; const FileName: string);
begin
System.Assign(F, FileName);
end;
procedure Assign(var F: TextFile; const FileName: string);
begin
System.Assign(F, FileName);
end;}
{.$ENDIF}
Back |
||
|
fix |
TAdModem AV when destroyed | |
Destroying a TAdModem when the ComPort property is not assigned will cause an
AV. To fix, make the following change to AdMdm.pas marked by {!!.06}:
destructor TAdCustomModem.Destroy;
{ we're being destroyed }
begin
DeallocateHWnd(FHandle); {!!.02}
ResponsePacket.Free;
FNegotiationResponses.Free;
FSelectedDevice.Free;
LibModem.Free;
if Assigned(FComPort) then {!!.06}
FComPort.DeregisterUserCallbackEx(PortOpenCloseEx); {!!.05}
inherited Destroy;
end;
Back |
||
|
fix |
State machine accesses port after closing | |
The state machine will access the port when deactivated to write to the
dispatcher log. This can cause an ie_NOpen exception under some conditions. To
fix, make the following change to AdStMach.pas marked by {!!.06}
procedure TApdStateComPortSource.StateDeactivate (State : TApdCustomState);
begin
if FComPort.Open then {!!.06}
FComPort.AddStringToLog (Name + ': Deactivate');
end;
Back |
||
|
fix |
OnProcessChar Command ecAnswerBack does not work. | |
Changes to extensive to list. Back |
||
|
enh |
Add OnProcessChar commands for cursor on/off | |
Dependent on other changes. Back |
||
|
fix |
Support for Siemens S35i (PDU Mode?) | |
PDU mode added for 4.06 Back |
||
|
fix |
Dialing using tone/pulse with TAdModem. | |
In the AdMdm.pas unit make the following changes marked {!!.06} below:
apw_StartDial :
begin
ResponsePacket.Enabled := True;
if FModemConfig.ToneDial then {!!.06}
FComPort.Output := ConvertXML(LmModem.Settings.Prefix +
LMModem.Settings.DialPrefix +
LmModem.Settings.Tone + {!!.06}
FPhoneNumber +
LmModem.Settings.Terminator)
else
FComPort.Output := ConvertXML(LmModem.Settings.Prefix +
LMModem.Settings.DialPrefix +
LmModem.Settings.Pulse + {!!.06}
FPhoneNumber +
LmModem.Settings.Terminator);
DoStatus(msConnectWait);
end;
Back |
||
|
fix |
AV even though ftp://ftp.turbopower.com/pub/apro/updates/APROFixes.htm#3887 was applied. | |
An AV can occur when the TApdDataPacket is destroyed. To fix, make the
following change to AdPacket.pas marked by {!!.06}. Note, this also affects
design-time, depending on the creation order of the TApdComPort and
TApdDataPacket. To prevent the AV at design-time, either drop TApdComPorts on
the form before dropping the TApdDataPackets, or rebuild the run-time and
design-time packages after making this change.
procedure TApdDataPacket.SetComPort(const NewComPort : TApdCustomComPort);
var
Manager : TApdDataPacketManager;
begin
if NewComPort <> fComPort then begin
if Assigned(fComPort) then begin
{ remove the old port hooks }
Manager := PacketManagerList.GetPortManager(fComPort); {!!.06}
if Assigned(Manager) then {!!.06}
Manager.Remove(Self); {!!.06}
end; {!!.06}
FComPort := NewComPort;
if Assigned(fComPort) then begin
{ add the new port hooks }
Manager := PacketManagerList.GetPortManager(fComPort);
if Manager = nil then
Manager := TApdDataPacketManager.Create(fComPort);
Manager.Insert(Self);
end;
end;
end;
Back |
||
|
fix |
FConnectFired may have broken DoDisconnect. | |
Change 3733 (4.05) broke the server's OnDisconnect event generation. The
OnDisconnect event would not fire when the client or server disconnected. To
fix, make the following change to AdWnPort.pas marked by {!!.06}
procedure TApdCustomWinsockPort.DoDisconnect;
begin
if (FConnectFired or (FWsMode = WsServer))and Assigned(FOnWsDisconnect){!!.06}
then FOnWsDisconnect(Self);
FConnectFired := False; {!!.05}
end;
Back |
||
|
fix |
Request for read only properties to indicate if scroll bars in use. | |
Make the following changes to AdCustomTerminal in the AdTrmEmu unit.
property Scrollback : boolean
read FScrollback write tmSetScrollback;
property UseLazyDisplay : boolean
read FUseLazyDisplay write tmSetUseLazyDisplay
default adc_TermUseLazyDisplay;
property UsingHScrollBar : Boolean {!!.06}
read FUseHScrollbar; {!!.06}
property UsingVScrollBar : Boolean {!!.06}
read FUseVScrollbar; {!!.06}
property WantAllKeys : boolean
read FWantAllKeys write tmSetWantAllKeys
default adc_TermWantAllKeys;
property FreezeScrollBack : boolean
read FFreezeScrollBack write tmSetFreezeScrollBack
default adc_FreezeScrollBack;
Back |
||
|
fix |
TAdModem - incorrect exception if modemcap folder not found | |
If the TAdModem.ModemcapFolder is not found, an exception was raised in the XML
parsing code that wasn't very clear. To fix, make the following change to
AdMdm.pas marked by {!!.06}
function TAdCustomModem.SelectDevice: Boolean;
{ display the modem selection dialog }
begin
try
Result := False; {!!.06}
if not DirectoryExists(FModemCapFolder) then {!!.06}
raise EInOutError.CreateFmt( {!!.06}
'Modemcap folder not found'#13#10'(%s)', [FModemCapFolder]); {!!.06}
Back |
||
|
fix |
TApdModemStatusDialog - Cancel button doesn't work | |
The Cancel button on the modem status dialog doesn't work. To fix, make the
following change to AdMdmDlg.pas marked by {!!.06}
procedure TApdModemStatusDialog.btnCancelClick(Sender: TObject);
begin
if Assigned(FModem) then
Postmessage(FModem.Handle, apw_CancelCall, 0, 0); {!!.06}
end;
Back |
||
|
fix |
TAdModem - AV if port not opened | |
An AV can be raised when showing the modem status dialog if the port is not
open. To fix, make the following change to AdMdmDlg.pas marked by {!!.06}:
procedure TApdModemStatusDialog.SetModem(const NewModem : TAdCustomModem);
begin
FModem := NewModem;
if Assigned(FModem) then begin {!!.06}
lblUsingDevice.Caption := FModem.SelectedDevice.Name;
if Assigned(FModem.ComPort) then {!!.06}
lblUsingPort.Caption := Format('COM%d', [FModem.ComPort.ComNumber]){!!.06}
else {!!.06}
lblUsingPort.Caption := 'No com port component assigned'; {!!.06}
end; {!!.06}
end;
Back |
||
|
fix |
Data packet - AV on destroy revisited | |
This bug was entered to consolidate the code changes to fix the AV problems
with the 4.05 TApdDataPacket.
procedure TApdDataPacketManager.DisablePackets;
var
i : integer;
begin
{ this can get called when destroying, and called in the context of }
{ different threads, make sure the PacketList is still around }
if Assigned(PacketList) do {!!.06}
for i := 0 to pred(PacketList.Count) do
if Assigned(PacketList[i]) then {!!.06}
with TApdDataPacket(PacketList[i]) do
Disable;
end;
destructor TApdDataPacketManagerList.Destroy;
begin
while ManagerList.Count > 0 do
with TApdDataPacketManager(ManagerList[pred(ManagerList.Count)]) do begin
{ we're only being destroyed from the Finalization block, it's OK to }
{ set fComPort to nil here since that will be destroyed shortly anyway }
fComPort := nil; {!!.06}
Free; {!!.06}
end;
ManagerList.Free;
inherited Destroy;
end;
Back |
||
|
enh |
RAS - Add support for programatic phonebook additions | |
There wasn't a way to programatically add a phone book entry (without showing
the RAS phonebook dialog and requiring user intervention). To add this
enhancement, TApdRasDialer.AddPhonebookEntry, .ValidateEntryName
and .GetPhonebookEntry methods were added. To add these methods, make the
following changes marked with {!!.06} to the following units. An example of
using these new methods will be available from
ftp://ftp.turbopower.com/pub/apro/demos/_Index.htm (ExRasPB.zip)
Since these are rather extensive changes, with lots of duplications, only some
changes are listed. Instructions for applying the changes are marked below
with "**". The changes span several units, do not attempt to test-compile until
all changes are in-place (it won't work until everything is changed.)
AdRas.pas
**add the following 3 methods to the TApdCustomRasDialer in the public section:
function TApdCustomRasDialer.AddPhonebookEntry(PBEntryName : string; {!!.06}
RasEntry : TRasEntry; TapiConfigRec : TTapiConfigRec): Integer;
{ add a new phonebook entry }
var
EntrySize : DWORD;
DevInfoSize : DWORD;
TempPhoneBook : string;
begin
{ make sure the entry name is valid }
Result := AdRasValidateEntryName(FPhoneBook, PBEntryName);
if Result = 0 then begin
EntrySize := SizeOf(TRasEntry);
if IsWinNT then begin
TempPhoneBook := FPhoneBook;
DevInfoSize := 0;
end else begin
{ Win9x/ME doesn't use phone book or TAPI config params }
TempPhoneBook := '';
DevInfoSize := SizeOf(TTapiConfigRec);
end;
{ Required items for RasEntry are szPLocalPhoneNumber, szDeviceName, }
{ szDeviceType, dwFramingProtocol and dwfOptions. See help for }
{ RasSetEntryProperties for details }
Result := AdRasSetEntryProperties(TempPhonebook,
PBEntryName,
@RasEntry,
EntrySize,
@TapiConfigRec,
DevInfoSize)
end;
end;
function TApdCustomRasDialer.GetPhonebookEntry(PBEntryName: string; {!!.06}
var RasEntry: TRasEntry; var TapiConfigRec: TTapiConfigRec): Integer;
var
RasEntrySize : DWORD;
DevInfoSize : DWORD;
begin
RasEntrySize := SizeOf(TRasEntry);
FillChar(RasEntry, RasEntrySize, 0);
RasEntry.dwSize := RasEntrySize;
DevInfoSize := SizeOf(DevInfoSize);
FillChar(TapiConfigRec, DevInfoSize, 0);
Result := AdRasGetEntryProperties(FPhoneBook,
PBEntryName,
@RasEntry,
RasEntrySize,
@TapiConfigRec,
DevInfoSize);
end;
function TApdCustomRasDialer.ValidateEntryName(EntryName:string):Integer;{!!.06}
{Validates an entry name}
begin
Result := AdRasValidateEntryName(FPhoneBook, EntryName);
end;
AdRasUtl.pas
**add AdExcept and OOMisc to the interface uses clause, comment out
implementation uses clause.
**several type definitions moved to OOMisc.pas. See that section below
and comment out/delete the definition for those types in this unit.
** The RasGetEntryProperties and RasSetEntryProperties used the wrong type
in the parameters. Search for "EntryProperties" in this unit to find
the proc types, prototypes and methods for them. Change the lpDevideInfo
parameter type to PTapiConfigRec. Here is one as an example:
TRasGetEntryProperties = function(lpszPhonebook, lpszEntry: PChar;
lpEntry: PRasEntry;
var lpEntrySize : DWord;
lpDeviceInfo : PTapiConfigRec; {!!.06}
var lpDeviceInfoSize : DWord
): DWord; stdcall;
This should be applied to the TRasGetEntryProperties and TRasSetEntryProperties
type definitions, and the interface and implementation of the
AdRasGetEntryProperties and AdRasSetEntryProperties functions.
OOMisc.pas
**Moved several types and consts to OOMisc.pas so they are available from
a common location. Copy the following section and paste it into OOMisc. The
EventTimer definition and "const {Compile-time configurations}" are already
in OOMisc, only placed here to show where to paste. The units where these
were moved from is in comments, comment out the original definitions in those
units as well.
{Standard event timer record structure used by all timing routines}
EventTimer = record
StartTicks : LongInt; {Tick count when timer was initialized}
ExpireTicks : LongInt; {Tick count when timer will expire}
end;
type{ moved from AdTapi.pas } {!!.06}
{ TAPI device config record, opaque and undefined by definition } {!!.06}
PTapiConfigRec = ^TTapiConfigRec; {!!.06}
TTapiConfigRec = record {!!.06}
DataSize : Cardinal; {!!.06}
Data : array[0..1023] of Byte; {!!.06}
end;
{ moved from AdRasUtl.pas } {!!.06}
const {RasMaximum buffer sizes} {!!.06}
RasMaxDomain = 15; {!!.06}
RasMaxPassword = 256; {!!.06}
RasMaxUserName = 256; {!!.06}
RasMaxEntryName = 256; {!!.06}
RasMaxPhoneBook = 256; {!!.06}
RasMaxError = 256; {!!.06}
RasMaxEntries = 64; {!!.06}
RasMaxDeviceName = 128; {!!.06}
RasMaxDeviceType = 16; {!!.06}
RasMaxPhoneNumber = 128; {!!.06}
RasMaxCallBackNum = 128; {!!.06}
RasMaxAreaCode = 10; {!!.06}
RasMaxPadType = 32; {!!.06}
RasMaxX25Address = 200; {!!.06}
RasMaxIPAddress = 15; {!!.06}
RasMaxIPXAddress = 21; {!!.06}
RasMaxFacilities = 200; {!!.06}
RasMaxUserData = 200; {!!.06}
type { moved from AdRasUtl.pas } {!!.06}
{RAS IP address - "a.b.c.d"} {!!.06}
PRasIPAddr = ^TRasIPAddr; {!!.06}
TRasIPAddr = record {!!.06}
a : byte; {!!.06}
b : byte; {!!.06}
c : byte; {!!.06}
d : byte; {!!.06}
end; {!!.06}
type { moved from AdRasUtl.pas } {!!.06}
{RAS phonebook entry properties} {!!.06}
PRasEntry = ^TRasEntry; {!!.06}
TRasEntry = record {!!.06}
dwSize : DWord; {!!.06}
dwOptions : DWord; {!!.06}
dwCountryID : DWord; {!!.06}
dwCountryCode : DWord; {!!.06}
szAreaCode : array[0..RasMaxAreaCode] of char; {!!.06}
szLocalPhoneNumber : array[0..RasMaxPhoneNumber] of char; {!!.06}
dwAlternatesOffset : DWord; {!!.06}
IPAddr : TRasIPAddr; {!!.06}
IPAddrDns : TRasIPAddr; {!!.06}
IPAddrDnsAlt : TRasIPAddr; {!!.06}
IPAddrWins : TRasIPAddr; {!!.06}
IPAddrWinsAlt : TRasIPAddr; {!!.06}
dwFrameSize : DWord; {!!.06}
dwNetProtocols : DWord; {!!.06}
dwFramingProtocol : DWord; {!!.06}
szScript : array[0..Max_PATH-1] of char; {!!.06}
szAutodialDll : array[0..Max_PATH-1] of char; {!!.06}
szAutodialFunc : array[0..Max_PATH-1] of char; {!!.06}
szDeviceType : array[0..RasMaxDeviceType] of char; {!!.06}
szDeviceName : array[0..RasMaxDeviceName] of char; {!!.06}
szX25PadType : array[0..RasMaxPadType] of char; {!!.06}
szX25Address : array[0..RasMaxX25Address] of char; {!!.06}
szX25Facilities : array[0..RasMaxFacilities] of char; {!!.06}
szX25UserData : array[0..RasMaxUserData] of char; {!!.06}
dwChannels : DWord; {!!.06}
dwReserved1 : DWord; {!!.06}
dwReserved2 : DWord; {!!.06}
end; {!!.06}
const
{Compile-time configurations}
AdTapi.pas
** comment-out the TTapiConfigRec definition, it has been moved to OOMisc.
{TTapiConfigRec definition moved to OOMisc to support RAS} {!!.06}
Back |
||
|
enh |
RAS - Add support to retrieve connection statistics | |
The 4.05 TApdRasDialer did not have a way to retrieve the connection
statistics. To add this enhancement, make the following changes marked by
{!!.06} to the following units.
NOTE: Several new types and DLL imports are added, exact placement in their
respective units is not important. Placement instructions are provided in-line,
marked with **.
See the ExRasStat.zip archive on
ftp://ftp.turbopower.com/pub/apro/demos/_Index.htm for an example.
OOMisc.pas
{**can be placed anywhere in the interface section}
type
PRasStatistics = ^TRasStatistics; {!!.06}
TRasStatistics = record {!!.06}
dwSize : DWORD; {!!.06}
dwBytesXmited : DWORD; {!!.06}
dwBytesRcved : DWORD; {!!.06}
dwFramesXmited : DWORD; {!!.06}
dwFramesRcved : DWORD; {!!.06}
dwCrcErr : DWORD; {!!.06}
dwTimeoutErr : DWORD; {!!.06}
dwAlignmentErr : DWORD; {!!.06}
dwHardwareOverrunErr : DWORD; {!!.06}
dwFramingErr : DWORD; {!!.06}
dwBufferOverrunErr : DWORD; {!!.06}
dwCompressionRatioIn : DWORD; {!!.06}
dwCompressionRatioOut : DWORD; {!!.06}
dwBps : DWORD; {!!.06}
dwConnectDuration : DWORD; {!!.06}
end; {!!.06}
AdRasUtl.pas
{RASAPI32 DLL function prototypes}
{**can be placed anywhere in this section}
TRasClearConnectionStatistics = function(Conn : HRasConn {!!.06}
) : DWORD; stdcall; {!!.06}
TRasGetConnectionStatistics = function(Conn : HRasConn; {!!.06}
lpStatistics : PRasStatistics {!!.06}
) : DWord; stdcall; {!!.06}
{ RAS DLL routine wrappers and public routines }
{**can be placed anywhere in this section}
function AdRasClearConnectionStatistics(HConn : THandle) : Integer; {!!.06}
function AdRasGetConnectionStatistics(HConn : THandle; {!!.06}
PStatistics : PRasStatistics {!!.06}
) : Integer; {!!.06}
var {RAS DLL functions}
{**can be placed anywhere in this section}
RasClearConnectionStatistics : TRasClearConnectionStatistics = nil; {!!.06}
RasGetConnectionStatistics : TRasGetConnectionStatistics = nil; {!!.06}
{ Misc utilities }
procedure LoadRASDLL;
begin
...
@RasDial := GetProcAddress(RASModule, 'RasDialA');
@RasEnumConnections := GetProcAddress(RASModule, 'RasEnumConnectionsA');
@RasClearConnectionStatistics := GetProcAddress(RasModule, {!!.06}
'RasClearConnectionStatistics'); {!!.06}
@RasGetConnectionStatistics := GetProcAddress(RASModule, {!!.06}
'RasGetConnectionStatistics'); {!!.06}
@RasGetConnectStatus := GetProcAddress(RASModule, 'RasGetConnectStatusA');
@RasGetErrorString := GetProcAddress(RASModule, 'RasGetErrorStringA');
...
{**Following methods can be placed immediately before Initialization block}
function AdRasClearConnectionStatistics(HConn : THandle) : Integer; {!!.06}
begin {!!.06}
LoadRASDLL; {!!.06}
if Assigned(RasClearConnectionStatistics) then {!!.06}
Result := RasClearConnectionStatistics(HConn) {!!.06}
else {!!.06}
Result := ecRasFunctionNotSupported; {!!.06}
end; {!!.06}
function AdRasGetConnectionStatistics(HConn : THandle; {!!.06}
PStatistics : PRasStatistics {!!.06}
) : Integer; {!!.06}
begin {!!.06}
LoadRASDLL; {!!.06}
if Assigned(RasGetConnectionStatistics) then {!!.06}
Result := RasGetConnectionStatistics(HConn, PStatistics) {!!.06}
else {!!.06}
Result := ecRasFunctionNotSupported; {!!.06}
end; {!!.06}
AdRas.pas
{**Add to public section of TApdCustomRasDialer}
function ClearConnectionStatistics : Integer; {!!.06}
function GetConnectionStatistics( {!!.06}
var Statistics : TRasStatistics) : Integer; {!!.06}
function TApdCustomRasDialer.ClearConnectionStatistics : Integer; {!!.06}
begin {!!.06}
Result := AdRasClearConnectionStatistics(Connection); {!!.06}
end; {!!.06}
function TApdCustomRasDialer.GetConnectionStatistics( {!!.06}
var Statistics : TRasStatistics) : Integer; {!!.06}
begin {!!.06}
FillChar(Statistics, SizeOf(TRasStatistics), 0); {!!.06}
Statistics.dwSize := SizeOf(TRasStatistics); {!!.06}
Result := AdRasGetConnectionStatistics(Connection, @Statistics); {!!.06}
end; {!!.06}
Back |
||
|
fix |
Invalid Scroll Regions cause AV | |
Make the following changes to AdTrmBuf.pas
procedure TAdTerminalBuffer.SetScrollRegion(aTopRow, aBottomRow : integer);
var
Temp : integer;
begin
FBeyondMargin := false;
{if the top row is greater than the bottom row, they're out of
order, so switch 'em round}
if (aTopRow > aBottomRow) then begin
Temp := aTopRow;
aTopRow := aBottomRow;
aBottomRow := Temp;
end;
{$IFDEF UseRangeChecks}
if ((aBottomRow - aTopRow) < 1) or
(aTopRow < 1) or (aTopRow > RowCount) or
(aBottomRow < 1) or (aBottomRow > RowCount) then
raise Exception.Create('TAdTerminalBuffer.SetScrollRegion: invalid row
number(s)');
{$ELSE} {!!.06}
if ((aBottomRow - aTopRow) < 1) then {!!.06}
Exit; {!!.06}
if (aTopRow < 1) then {!!.06}
aTopRow := 1; {!!.06}
if (aTopRow > RowCount) then {!!.06}
aTopRow := RowCount; {!!.06}
if (aBottomRow < 1) then {!!.06}
aBottomRow := 1; {!!.06}
if (aBottomRow > RowCount) then {!!.06}
aBottomRow := RowCount; {!!.06}
{$ENDIF}
FSRStartRow := tbCvtToInternalRow(aTopRow, true);
FSREndRow := tbCvtToInternalRow(aBottomRow, true);
{force the scroll region to be used}
if UseScrollRegion then
UseScrollRegion := false;
if (aTopRow <> 1) or (aBottomRow <> RowCount) then
UseScrollRegion := true;
end;
Back |
||
|
fix |
Provide manual adjustment of character cell sizes in terminal | |
Changes are too extensive to list. Back |
||
|
fix |
TAdTerminalEmulator.teProcessCommand can AV with no terminal | |
Change is dependant on other changes. Back |
||
|
fix |
RAS - Missing some consts | |
In addition to bug 4064, these consts should be added to OOMisc.pas, inserted
after TRasEntry declaration.
const {RASENTRY 'dwfOptions' bit flags} {!!.06}
RASEO_UseCountryAndAreaCodes = $00000001; {!!.06}
RASEO_SpecificIpAddr = $00000002; {!!.06}
RASEO_SpecificNameServers = $00000004; {!!.06}
RASEO_IpHeaderCompression = $00000008; {!!.06}
RASEO_RemoteDefaultGateway = $00000010; {!!.06}
RASEO_DisableLcpExtensions = $00000020; {!!.06}
RASEO_TerminalBeforeDial = $00000040; {!!.06}
RASEO_TerminalAfterDial = $00000080; {!!.06}
RASEO_ModemLights = $00000100; {!!.06}
RASEO_SwCompression = $00000200; {!!.06}
RASEO_RequireEncryptedPw = $00000400; {!!.06}
RASEO_RequireMsEncryptedPw = $00000800; {!!.06}
RASEO_RequireDataEncryption = $00001000; {!!.06}
RASEO_NetworkLogon = $00002000; {!!.06}
RASEO_UseLogonCredentials = $00004000; {!!.06}
RASEO_PromoteAlternates = $00008000; {!!.06}
RASEO_SecureLocalFiles = $00010000; {!!.06}
RASEO_RequireEAP = $00020000; {!!.06}
RASEO_RequirePAP = $00040000; {!!.06}
RASEO_RequireSPAP = $00080000; {!!.06}
RASEO_Custom = $00100000; {!!.06}
RASEO_PreviewPhoneNumber = $00200000; {!!.06}
RASEO_SharedPhoneNumbers = $00800000; {!!.06}
RASEO_PreviewUserPw = $01000000; {!!.06}
RASEO_PreviewDomain = $02000000; {!!.06}
RASEO_ShowDialingProgress = $04000000; {!!.06}
RASEO_RequireCHAP = $08000000; {!!.06}
RASEO_RequireMsCHAP = $10000000; {!!.06}
RASEO_RequireMsCHAP2 = $20000000; {!!.06}
RASEO_RequireW95MSCHAP = $40000000; {!!.06}
RASEO_CustomScript = $80000000; {!!.06}
{RASENTRY 'dwNetProtocols' bit flags} {!!.06}
RASNP_NetBEUI = $00000001; {!!.06}
RASNP_Ipx = $00000002; {!!.06}
RASNP_Ip = $00000004; {!!.06}
{RASENTRY 'dwFramingProtocols' bit flags} {!!.06}
RASFP_Ppp = $00000001; {!!.06}
RASFP_Slip = $00000002; {!!.06}
RASFP_Ras = $00000004; {!!.06}
{RASENTRY 'szDeviceType' default strings} {!!.06}
RASDT_Modem = 'modem'; {!!.06}
RASDT_Isdn = 'isdn'; {!!.06}
RASDT_X25 = 'x25'; {!!.06}
RASDT_Vpn = 'vpn'; {!!.06}
RASDT_Pad = 'pad'; {!!.06}
RASDT_Generic = 'GENERIC'; {!!.06}
RASDT_Serial = 'SERIAL'; {!!.06}
RASDT_FrameRelay = 'FRAMERELAY'; {!!.06}
RASDT_Atm = 'ATM'; {!!.06}
RASDT_Sonet = 'SONET'; {!!.06}
RASDT_SW56 = 'SW56'; {!!.06}
RASDT_Irda = 'IRDA'; {!!.06}
RASDT_Parallel = 'PARALLEL'; {!!.06}
Back |
||
|
fix |
AV On destroy when turning off mouseselect | |
Make the changes indicated by a !!.06 to TAdCustomTerminal.HideSelection in the
AdTrmEmu unit.
procedure TAdCustomTerminal.HideSelection;
var
i : integer;
ColCount : integer;
begin
{Don't clear if nothing is selected } {!!.06}
if (IsRectEmpty (FLButtonRect)) then {!!.06}
Exit;
{!!.06}
{clear the current selection}
ColCount := FEmulator.Buffer.ColCount;
tmMarkDeselected(FLButtonRect.Top, FLButtonRect.Left, ColCount);
for i := succ(FLButtonRect.Top) to pred(FLButtonRect.Bottom) do
tmMarkDeselected(i, 1, ColCount);
tmMarkDeselected(FLButtonRect.Bottom, 1, FLButtonRect.Right);
{initialize the selection variables}
SetRectEmpty(FLButtonRect);
FLButtonAnchor.X := 0;
FLButtonAnchor.Y := 0;
FHaveSelection := false;
end;
Back |
||
|
fix |
TAdModem - incompatible with user's OnTriggerXxx | |
The TAdModem installed it's own internal OnTriggerTimer and OnTriggerStatus event handlers, which would overwrite the developer's event handlers. Symptoms are the TApdComPort.OnTriggerStatus and OnTriggerTimer events not firing after opening the TAdModem. The fix is somewhat extensive, contact tech support for the new unit. Back |
||
|
fix |
OnTapiFail getting called twice for one failure. | |
To fix, move setting the flag above the call to FOnTapiFail from inside the
TapiFail procedure and make the following changes marked {!!.06} in AdTapi.pas
unit as follows:
procedure TApdCustomTapiDevice.TapiFail;
{-Generate the TapiFail event}
begin
{Call the user's event handler}
if not TapiFailFired then begin
TapiFailFired := True; {!!.06}
if Assigned(FOnTapiFail) then
FOnTapiFail(Self);
//TapiFailFired := True; moved up above {!!.06}
if not Open then {!!.04}
{ if we're open, then we were either already waiting for a call }
{ or have a call already }
FWaitingForCall := False; {!!.04}
end
end;
Back |
||
|
fix |
Fonts changing works incorrectly with VT100 | |
Make the following changes indicated by !!.06 to the
TAdVT100Emulator.vttExecutePaintScript method in the AdTrmEmu.pas unit. Make
sure that you keep an unmodified version of AdTrmEmu.pas around in case things
go wrong.
...
{display the bit o'text}
if (FontName = DefaultFontName) then
Canvas.Font := Font
else begin
FSecondaryFont.Name := FontName;
Canvas.Font := FSecondaryFont;
end;
Canvas.Font.Color := ForeColor;
{$IFDEF VERSION3}
if Assigned (Terminal.Font) then {!!.06}
Canvas.Font.CharSet := Terminal.Font.CharSet {!!.06}
else {!!.06}
Canvas.Font.CharSet := DEFAULT_CHARSET;
{$ENDIF}
if DblHeight then
Canvas.Font.Size := Canvas.Font.Size * 2;
ExtTextOut(Canvas.Handle,
WorkRect.Left,
WorkRect.Top,
ETO_OPAQUE,
@WorkRect,
FDisplayStr,
PartTextLen,
@FCellWidths^);
...
Back |
||
|
fix |
AdModem - SetDevConfig not forcing initialization | |
Calling the TAdModem.SetDevConfig with a new configuration does not cause the
modem to be reinitialized. To fix, make the following change to AdMdm.pas
marked by {!!.06}
procedure TAdCustomModem.SetDevConfig(const Config: TApdModemConfig);
{ forces new configuration }
begin
{$IFDEF AdModemDebug}
if Assigned(FComPort) then
FComPort.AddStringToLog('ConfigChange');
{$ENDIF}
if CompareMem(@FModemConfig, @Config, SizeOf(TApdModemConfig)) then {!!.06}
Initialized := False; {!!.06}
FModemConfig := Config;
end;
Back |
||
|
fix |
TApdFaxConverter - idShell conversion may leave reg/ini keys | |
When using the idShell converter in the TApdFaxConverter, the TApdFaxConverter
adds registry/ini keys when the conversion starts, and the printer driver
deletes them when the print job ends. Under some conditions, the printer
driver does not start (see "Keys left in registry after conversion timeout" in
the apro.fax newsgroup, 12/13/2002), so the printer driver does not delete the
keys. As a failsafe measure, add the following changes marked by {!!.06} to
AdFaxCvt.pas, which will delete the keys from the TApdFaxConverter also.
procedure TApdCustomFaxConverter.ConvertShell(const FileName: string);
{ print the selected document to the fax printer driver using ShellExecute }
begin
...
finally
if DefPrnChanged then {!!.01}
ChangeDefPrinter(False); {!!.01}
Status(False, True, FShellPageCount, 0, 0, 0, DummyBool); {!!.01}
{ remove the registry/ini keys, just in case the printer driver }
{ failed to do so }
if IsWinNT then begin {!!.06}
Reg := TRegistry.Create; {!!.06}
try {!!.06}
Reg.RootKey := HKEY_LOCAL_MACHINE; {!!.06}
Reg.OpenKey(ApdRegKey,False); {!!.06}
Reg.DeleteValue('ShellName'); {!!.06}
Reg.DeleteValue('ShellHandle'); {!!.06}
finally {!!.06}
Reg.Free; {!!.06}
end; {!!.06}
end else begin {!!.06}
Ini := TIniFile.Create(ApdIniFileName); {!!.06}
try {!!.06}
Ini.DeleteKey(ApdIniSection, 'ShellHandle'); {!!.06}
Ini.DeleteKey(ApdIniSection, 'ShellName'); {!!.06}
{$IFDEF Delphi4} {!!.06}
Ini.UpdateFile; {!!.06}
{$ENDIF} {!!.06}
finally {!!.06}
Ini.Free; {!!.06}
end; {!!.06}
end; {!!.06}
end; {!!.01}
end;
Back |
||
|
fix |
TApdSendFax - Class1 error handling | |
When sending a fax using fcClass1 we report an error when the receiver
disconnects after we send out 'last page' ack request. This only happens in
Class1, only with some receivers, and only when they disconnect after we say
there are no more pages to send. According to the fax specs, a remote that
doesn't ack the last page message causes the session to fail; however, it is a
relatively common implementation to diconnect like this. Since the page data
has already been transmitted, and it's the last page, we're going to deviate a
bit from the specs and report this as a successful transmission. Apply the
following changes marked by {!!.06} to AwFax.pas:
tf1PrepareEOP :
begin
Inc(cRetry);
if cRetry > 3 then begin
if fState = tf1WaitMCF then begin {!!.06}
{ some receivers will disconnect after receiving the MCF }
{ fra | ||