home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR36
/
BTV200.ZIP
/
BTRVDPMI.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-12-18
|
8KB
|
289 lines
{*
* This is a protected mode interface to the Btrieve TSR.
*
* IT CANNOT BE USED FOR REAL MODE!!!!!
*
*=========================================================================
* BTRVDPMI.PAS for BTV.PAS Version 1.50
*
* BTRIEVE object oriented interface for Turbo Pascal 6.0, 7.0
*
* Copyright (c) 1992 by Richard W. Hansen, all rights reserved.
*
*
* Requires Turbo Pascal version 7.0
*
*
* Registration and payment of a license fee is required for any use, whether
* in whole or part, of this source code.
*=========================================================================
*
*}
UNIT BTRVDPMI;
{$X+}
{$V-}
INTERFACE
{$IFDEF DPMI}
USES
BtvConst,
WinDos, WINApi;
CONST
BTR_INT : Byte = $7B;
{
The paramters to this function must be exactly right. If they are not
then a GPF error is just about guaranteed. The buffer sizes must be
right, or else a memory overwrite will result. Buffer sizes of zero
are allowed and should be handled properly.
The KeyLen parameter is new, make sure it is correct for the operation
you are executing. All other parameters are the same.
}
Function BTRV( Op : Integer;
var PosBlock;
var DataBuff;
var DataLen : Word;
var KeyBuff;
KeyLen : Byte;
KeyNumber: Integer): Integer;
IMPLEMENTATION
TYPE
MemPtr = record
Selector: Word; {Protected mode}
Segment : Word; {Real mode}
end;
VAR
{these could be setup once, if enough memory is available }
pPosBlock : MemPtr;
pDataBuff : MemPtr;
pKeyBuff : MemPtr;
pStatus : MemPtr;
pParams : MemPtr;
Function BTRV( Op : Integer;
var PosBlock;
var DataBuff;
var DataLen : Word;
var KeyBuff;
KeyLen : Byte;
KeyNumber: Integer
): Integer;
const
VAR_ID = $6176; {id for variable length records - 'va'}
BTR_OFFSET = $0033;
DPMI_INTR = $31;
type
Addr32 = record {32 bit address}
Offset : Word;
Segment: Word;
end;
BtrieveBuff = record
USER_BUF_ADDR : Addr32; {data buffer address}
USER_BUF_LEN : Word; {data buffer length}
USER_CUR_ADDR : Addr32; {currency block address}
USER_FCB_ADDR : Addr32; {file control block address}
USER_FUNCTION : Word; {Btrieve operation}
USER_KEY_ADDR : Addr32; {key buffer address}
USER_KEY_LENGTH: Byte; {key buffer length}
USER_KEY_NUMBER: Byte; {key number}
USER_STAT_ADDR : Addr32; {return status address}
XFACE_ID : Word; {language interface id}
end;
TDPMIRegisters = record { DPMI call structure }
EDI : LongInt;
ESI : LongInt;
EBP : LongInt;
Reserved: LongInt;
EBX : LongInt;
EDX : LongInt;
ECX : LongInt;
EAX : LongInt;
Flags : Word;
ES : Word;
DS : Word;
FS : Word;
GS : Word;
IP : Word;
CS : Word;
SP : Word;
SS : Word;
end;
Function GetMem(var Mem : MemPtr; Size : Word): Boolean;
begin
if (Size > 0) then
begin
LongInt(Mem) := GlobalDOSAlloc(Size);
GetMem := (LongInt(Mem) <> 0);
end
else
begin
LongInt(Mem) := 0;
GetMem := True;
end;
end;
Procedure FreeMem(Mem : MemPtr; Size : Word);
begin
if (Size > 0) then
GlobalDOSFree(Mem.Selector);
end;
Function MakePtr(Mem : MemPtr): Pointer;
begin
MakePtr := Ptr(Mem.Selector, 0);
end;
var
Regs : TRegisters;
DPMIRegs: TDPMIRegisters;
begin
FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
DPMIRegs.EAX := $3500 + BTR_INT;
Regs.AX := $0300;
Regs.BL := $21;
Regs.BH := 0;
Regs.CX := 0;
Regs.ES := Seg(DPMIRegs);
Regs.DI := Ofs(DPMIRegs);
Intr(DPMI_INTR, Regs);
if (DPMIRegs.EBX <> BTR_OFFSET) then
begin
Btrv := bNotLoaded;
EXIT;
end;
{ Allocate and initialize real mode storage for Btrieve }
{ Btrieve call/return parameter block }
if not GetMem(pParams, SizeOf(BtrieveBuff)) then
begin
Btrv := bOutOfMemory;
EXIT;
end;
{ Status code }
if not GetMem(pStatus, SizeOf(Integer)) then
begin
FreeMem(pParams, SizeOf(BtrieveBuff));
Btrv := bOutOfMemory;
EXIT;
end;
{ position block }
if not GetMem(pPosBlock, 128) then
begin
FreeMem(pParams, SizeOf(BtrieveBuff));
FreeMem(pStatus, SizeOf(Integer));
Btrv := bOutOfMemory;
EXIT;
end;
{ data buffer }
if not GetMem(pDataBuff, DataLen) then
begin
FreeMem(pParams, SizeOf(BtrieveBuff));
FreeMem(pStatus, SizeOf(Integer));
FreeMem(pPosBlock, 128);
Btrv := bOutOfMemory;
EXIT;
end;
{ key buffer }
if not GetMem(pKeyBuff, 255) then
begin
FreeMem(pParams, SizeOf(BtrieveBuff));
FreeMem(pStatus, SizeOf(Integer));
FreeMem(pPosBlock, 128);
FreeMem(pDataBuff, DataLen);
Btrv := bOutOfMemory;
EXIT;
end;
{ Copy to transfer buffers }
if (DataLen > 0) then
Move(DataBuff, MakePtr(pDataBuff)^, DataLen);
Move(PosBlock, MakePtr(pPosBlock)^, 128);
if (KeyLen > 0) then
Move(KeyBuff, MakePtr(pKeyBuff)^, KeyLen);
{ Setup Btrieve call/return parameter block }
with BtrieveBuff(MakePtr(pParams)^) do
begin
USER_BUF_ADDR.Segment := pDataBuff.Segment;
USER_BUF_ADDR.Offset := 0;
USER_BUF_LEN := DataLen;
USER_FCB_ADDR.Segment := pPosBlock.Segment;
USER_FCB_ADDR.Offset := 0;
USER_CUR_ADDR.Segment := USER_FCB_ADDR.Segment;
USER_CUR_ADDR.Offset := 38;
USER_FUNCTION := Op;
USER_KEY_ADDR.Segment := pKeyBuff.Segment;
USER_KEY_ADDR.Offset := 0;
USER_KEY_LENGTH := 255; {assume its large enough}
USER_KEY_NUMBER := KeyNumber;
USER_STAT_ADDR.SEGMENT:= pStatus.Segment;
USER_STAT_ADDR.OFFSET := 0;
XFACE_ID := VAR_ID;
end;
{ Use DPMI interface to issue real mode interrupt to call Btrieve }
FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
DPMIRegs.DS := pParams.Segment;
DPMIRegs.EDX := 0;
Regs.AX := $0300;
Regs.BL := BTR_INT;
Regs.BH := 0;
Regs.CX := 0;
Regs.ES := Seg(DPMIRegs);
Regs.DI := Ofs(DPMIRegs);
Intr(DPMI_INTR, Regs);
{ Copy from transfer buffers }
if (DataLen > 0) then
Move(MakePtr(pDataBuff)^, DataBuff, DataLen);
Move(MakePtr(pPosBlock)^, PosBlock, 128);
if (KeyLen > 0) then
Move(MakePtr(pKeyBuff)^, KeyBuff, KeyLen);
BTRV := Integer(MakePtr(pStatus)^);
FreeMem(pParams, SizeOf(BtrieveBuff));
FreeMem(pStatus, SizeOf(Integer));
FreeMem(pPosBlock, 128);
FreeMem(pDataBuff, DataLen);
FreeMem(pKeyBuff, 255);
end;
{$ENDIF}
end.