home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR36 / BTV200.ZIP / BTRVDPMI.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-18  |  8KB  |  289 lines

  1. {*
  2. * This is a protected mode interface to the Btrieve TSR.
  3. *
  4. * IT CANNOT BE USED FOR REAL MODE!!!!!
  5. *
  6. *========================================================================= 
  7. *  BTRVDPMI.PAS  for BTV.PAS Version 1.50                        
  8. *                                                                
  9. *  BTRIEVE object oriented interface for Turbo Pascal 6.0, 7.0   
  10. *                                                                
  11. *  Copyright (c) 1992 by Richard W. Hansen, all rights reserved. 
  12. *
  13. *
  14. *  Requires Turbo Pascal version 7.0
  15. *
  16. *
  17. *  Registration and payment of a license fee is required for any use, whether
  18. *  in whole or part, of this source code.
  19. *========================================================================= 
  20. *
  21. *}
  22.  
  23. UNIT BTRVDPMI;
  24. {$X+}
  25. {$V-}
  26.  
  27. INTERFACE
  28.  
  29. {$IFDEF DPMI}
  30. USES
  31.   BtvConst,
  32.   WinDos, WINApi;
  33.  
  34.  
  35. CONST
  36.   BTR_INT        : Byte = $7B;
  37.  
  38.  
  39.   The paramters to this function must be exactly right. If they are not
  40.   then a GPF error is just about guaranteed. The buffer sizes must be
  41.   right, or else a memory overwrite will result. Buffer sizes of zero
  42.   are allowed and should be handled properly. 
  43.  
  44.   The KeyLen parameter is new, make sure it is correct for the operation
  45.   you are executing. All other parameters are the same.
  46. }
  47.  
  48. Function BTRV(    Op       : Integer;
  49.               var PosBlock;
  50.               var DataBuff;
  51.               var DataLen  : Word;
  52.               var KeyBuff;
  53.                   KeyLen   : Byte;
  54.                   KeyNumber: Integer): Integer;
  55.  
  56.  
  57.  
  58. IMPLEMENTATION
  59.  
  60. TYPE
  61.   MemPtr = record
  62.     Selector: Word;  {Protected mode}
  63.     Segment : Word;  {Real mode}
  64.   end;
  65.  
  66.  
  67. VAR
  68.   {these could be setup once, if enough memory is available }
  69.   pPosBlock : MemPtr;
  70.   pDataBuff : MemPtr;
  71.   pKeyBuff  : MemPtr;
  72.   pStatus   : MemPtr;
  73.   pParams   : MemPtr;
  74.  
  75.  
  76. Function BTRV(    Op       : Integer;
  77.               var PosBlock;
  78.               var DataBuff;
  79.               var DataLen  : Word;
  80.               var KeyBuff;
  81.                   KeyLen   : Byte;
  82.                   KeyNumber: Integer
  83.               ): Integer;
  84.  
  85.   const
  86.     VAR_ID         = $6176;     {id for variable length records - 'va'}
  87.     BTR_OFFSET     = $0033;
  88.     DPMI_INTR      = $31;
  89.  
  90.  
  91.   type
  92.     Addr32 = record             {32 bit address}
  93.       Offset : Word;
  94.       Segment: Word;
  95.     end;
  96.  
  97.     BtrieveBuff = record
  98.       USER_BUF_ADDR  : Addr32;  {data buffer address}
  99.       USER_BUF_LEN   : Word;    {data buffer length}
  100.       USER_CUR_ADDR  : Addr32;  {currency block address}
  101.       USER_FCB_ADDR  : Addr32;  {file control block address}
  102.       USER_FUNCTION  : Word;    {Btrieve operation}
  103.       USER_KEY_ADDR  : Addr32;  {key buffer address}
  104.       USER_KEY_LENGTH: Byte;    {key buffer length}
  105.       USER_KEY_NUMBER: Byte;    {key number}
  106.       USER_STAT_ADDR : Addr32;  {return status address}
  107.       XFACE_ID       : Word;    {language interface id}
  108.     end;
  109.  
  110.     TDPMIRegisters = record     { DPMI call structure }
  111.       EDI     : LongInt;
  112.       ESI     : LongInt;
  113.       EBP     : LongInt;
  114.       Reserved: LongInt;
  115.       EBX     : LongInt;
  116.       EDX     : LongInt;
  117.       ECX     : LongInt;
  118.       EAX     : LongInt;
  119.       Flags   : Word;
  120.       ES      : Word;
  121.       DS      : Word;
  122.       FS      : Word;
  123.       GS      : Word;
  124.       IP      : Word;
  125.       CS      : Word;
  126.       SP      : Word;
  127.       SS      : Word;
  128.     end;
  129.  
  130.  
  131.   Function GetMem(var Mem : MemPtr; Size : Word): Boolean;
  132.     begin
  133.       if (Size > 0) then
  134.       begin
  135.         LongInt(Mem) := GlobalDOSAlloc(Size);
  136.         GetMem := (LongInt(Mem) <> 0);
  137.       end
  138.  
  139.       else
  140.       begin
  141.         LongInt(Mem) := 0;
  142.         GetMem := True;
  143.       end;
  144.     end;
  145.  
  146.   Procedure FreeMem(Mem : MemPtr; Size : Word);
  147.     begin
  148.       if (Size > 0) then
  149.         GlobalDOSFree(Mem.Selector);
  150.     end;
  151.  
  152.   Function MakePtr(Mem : MemPtr): Pointer;
  153.     begin
  154.       MakePtr := Ptr(Mem.Selector, 0);
  155.     end;
  156.  
  157.  
  158.   var
  159.     Regs    : TRegisters;
  160.     DPMIRegs: TDPMIRegisters;
  161.  
  162.   begin
  163.     FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  164.     DPMIRegs.EAX := $3500 + BTR_INT;
  165.     Regs.AX := $0300;
  166.     Regs.BL := $21;
  167.     Regs.BH := 0;
  168.     Regs.CX := 0;
  169.     Regs.ES := Seg(DPMIRegs);
  170.     Regs.DI := Ofs(DPMIRegs);
  171.     Intr(DPMI_INTR, Regs);
  172.  
  173.     if (DPMIRegs.EBX <> BTR_OFFSET) then
  174.     begin
  175.       Btrv := bNotLoaded;
  176.       EXIT;
  177.     end;
  178.  
  179.     { Allocate and initialize real mode storage for Btrieve }
  180.     { Btrieve call/return parameter block }
  181.     if not GetMem(pParams, SizeOf(BtrieveBuff)) then
  182.     begin
  183.       Btrv := bOutOfMemory;
  184.       EXIT;
  185.     end;
  186.  
  187.     { Status code }
  188.     if not GetMem(pStatus, SizeOf(Integer)) then
  189.     begin
  190.       FreeMem(pParams, SizeOf(BtrieveBuff));
  191.       Btrv := bOutOfMemory;
  192.       EXIT;
  193.     end;
  194.  
  195.     { position block }
  196.     if not GetMem(pPosBlock, 128) then
  197.     begin
  198.       FreeMem(pParams, SizeOf(BtrieveBuff));
  199.       FreeMem(pStatus, SizeOf(Integer));
  200.       Btrv := bOutOfMemory;
  201.       EXIT;
  202.     end;
  203.  
  204.     { data buffer }
  205.     if not GetMem(pDataBuff, DataLen) then
  206.     begin
  207.       FreeMem(pParams, SizeOf(BtrieveBuff));
  208.       FreeMem(pStatus, SizeOf(Integer));
  209.       FreeMem(pPosBlock, 128);
  210.       Btrv := bOutOfMemory;
  211.       EXIT;
  212.     end;
  213.  
  214.     { key buffer }
  215.     if not GetMem(pKeyBuff, 255) then
  216.     begin
  217.       FreeMem(pParams, SizeOf(BtrieveBuff));
  218.       FreeMem(pStatus, SizeOf(Integer));
  219.       FreeMem(pPosBlock, 128);
  220.       FreeMem(pDataBuff, DataLen);
  221.       Btrv := bOutOfMemory;
  222.       EXIT;
  223.     end;
  224.  
  225.     { Copy to transfer buffers }
  226.     if (DataLen > 0) then
  227.       Move(DataBuff, MakePtr(pDataBuff)^, DataLen);
  228.  
  229.     Move(PosBlock, MakePtr(pPosBlock)^, 128);
  230.  
  231.     if (KeyLen > 0) then
  232.       Move(KeyBuff,  MakePtr(pKeyBuff)^,  KeyLen);
  233.  
  234.     { Setup Btrieve call/return parameter block }
  235.     with BtrieveBuff(MakePtr(pParams)^) do
  236.     begin
  237.       USER_BUF_ADDR.Segment := pDataBuff.Segment;
  238.       USER_BUF_ADDR.Offset  := 0;
  239.       USER_BUF_LEN          := DataLen;
  240.       USER_FCB_ADDR.Segment := pPosBlock.Segment;
  241.       USER_FCB_ADDR.Offset  := 0;
  242.       USER_CUR_ADDR.Segment := USER_FCB_ADDR.Segment;
  243.       USER_CUR_ADDR.Offset  := 38;
  244.       USER_FUNCTION         := Op;
  245.       USER_KEY_ADDR.Segment := pKeyBuff.Segment;
  246.       USER_KEY_ADDR.Offset  := 0;
  247.       USER_KEY_LENGTH       := 255;        {assume its large enough}
  248.       USER_KEY_NUMBER       := KeyNumber;
  249.       USER_STAT_ADDR.SEGMENT:= pStatus.Segment;
  250.       USER_STAT_ADDR.OFFSET := 0;
  251.       XFACE_ID              := VAR_ID;
  252.     end;
  253.  
  254.  
  255.     { Use DPMI interface to issue real mode interrupt to call Btrieve }
  256.     FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  257.     DPMIRegs.DS  := pParams.Segment;
  258.     DPMIRegs.EDX := 0;
  259.     Regs.AX := $0300;
  260.     Regs.BL := BTR_INT;
  261.     Regs.BH := 0;
  262.     Regs.CX := 0;
  263.     Regs.ES := Seg(DPMIRegs);
  264.     Regs.DI := Ofs(DPMIRegs);
  265.     Intr(DPMI_INTR, Regs);
  266.  
  267.     { Copy from transfer buffers }
  268.     if (DataLen > 0) then
  269.       Move(MakePtr(pDataBuff)^, DataBuff, DataLen);
  270.  
  271.     Move(MakePtr(pPosBlock)^, PosBlock, 128);
  272.  
  273.     if (KeyLen > 0) then
  274.       Move(MakePtr(pKeyBuff)^,  KeyBuff,  KeyLen);
  275.  
  276.     BTRV := Integer(MakePtr(pStatus)^);
  277.  
  278.     FreeMem(pParams, SizeOf(BtrieveBuff));
  279.     FreeMem(pStatus, SizeOf(Integer));
  280.     FreeMem(pPosBlock, 128);
  281.     FreeMem(pDataBuff, DataLen);
  282.     FreeMem(pKeyBuff, 255);
  283.   end;
  284. {$ENDIF}
  285.  
  286. end.
  287.  
  288.