BTRIEVE access for DOS

Source-code only - please, don't post questions here.
mjs
Site Admin
Posts: 842
Joined: Jun 16, 2005 19:50
Location: Germany

BTRIEVE access for DOS

Postby mjs » Jun 30, 2005 8:02

Hi,

here's a little snippet to access BTRIEVE (v6.15 and older) DB files under DOS. Don't forget to load the BTRIEVE.EXE (DOS TSR required to access the DB files) first. I made this because I had to port some old DOS sources. BTRIEVE is the predecessor of PervasiveSQL.

Regards,
Mark

btrv.bas

Code: Select all

option explicit
option private

defint a-z

'$include: "btrv.bi"

'$include: "dos/sys/farptr.bi"
'$include: "dos/dpmi.bi"
'$include: "dos/go32.bi"
'$include: "dos/dos.bi"


'parameter positions within ParamBlock array
const Btr.Param.DBOfst = 0
const Btr.Param.DBSeg = 1
const Btr.Param.DBLength = 2
const Btr.Param.PosOfst = 3
const Btr.Param.PosSeg = 4
const Btr.Param.FCBOfst = 5
const Btr.Param.FCBSeg = 6
const Btr.Param.OpCode = 7
const Btr.Param.KBOfst = 8
const Btr.Param.KBSeg = 9
const Btr.Param.KeyInfo = 10
const Btr.Param.StatOfst = 11
const Btr.Param.StatSeg = 12
const Btr.Param.IfaceID = 13

const FCBPosSize = 128     '128 = correct size for FCB + position info

public function BTRVFarNew(byval Operation as integer, _
                           FCBPosBlock as string, _
                           DataBufferPtr as any ptr, _
                           DataBufLen as integer, _
                           KeyBuffer as string, _
                           byval KeyNumber as integer) as integer
   dim RetStatus as integer

   dim r as __dpmi_regs

   dim iParamDosSelector as integer
   dim iParamDosSegment as integer
    dim iParamDosLength as integer

    ' length of the parameter block
    iParamDosLength = _
          (14*2) + _
          DataBufLen + _
          len(FCBPosBlock) + _
          len(KeyBuffer) + _
          2

   iParamDosSegment = __dpmi_allocate_dos_memory((iParamDosLength + 15) \ 16, @iParamDosSelector)

   if iParamDosSegment=0 then
      function = 999
        exit function
    end if

    static VersionDetermined as integer
    static BMULTIPresent as integer
    static BMULTIProcessID as integer

    dim DosErrorVec as integer
    dosmemget(&H51A, 4, @DosErrorVec)

   dim CriticalErrorVec as uinteger        'holds critical error handler vector
    dosmemget(&H24*4, 4, @CriticalErrorVec) 'get critical error handler vector
    dosmemput(@DosErrorVec, 4, &H24*4)      'tell DOS to handle errors

    dim int_7b_offset as ushort
   dosmemget( &H7b*4, 2, @int_7b_offset )

                                   'if INT 7B offset = 33 hex, BTRIEVE handler
    if int_7b_offset = &h33 then   '  has been loaded
      if VersionDetermined = 0 then    'DOS version has yet to be determined
           VersionDetermined += 1         'set flag since we're determining now
            dim iDosVersion as integer
            iDosVersion = _get_dos_version(0) ' reported version
            if (iDosVersion and &Hff) >= 3 then 'we have DOS 3.00 or above
                r.x.ax = &Hab00              'so check to see if BMULTI loaded
                __dpmi_simulate_real_mode_interrupt &H2F, @r
                BMULTIPresent = (r.x.ax and &HFF)=77
            end if
      end if
   else                            'BTRIEVE handler isn't loaded, so warn user
         function = Btr.Err.BtrieveNotLoaded
        __dpmi_free_dos_memory(iParamDosSelector)
        dosmemput(@CriticalErrorVec, 4, &H24*4) 'restore critical error handler
         exit function                      'then quit
    end if

    if len(FCBPosBlock$) < FCBPosSize then    'make sure the passed FCBPosBlock$
         function = Btr.Err.FCBPosLen     '  is long enough to hold FCB and
                                 '  position info -- quit if not
        __dpmi_free_dos_memory(iParamDosSelector)
        dosmemput(@CriticalErrorVec, 4, &H24*4) 'restore critical error handler
         exit function
   end if

   'Now set up 14-word parameter block for the BTRIEVE interrupt
   dim ParamBlock(0 to 13) as ushort  'local array holds 14-word parameter block

   ParamBlock(Btr.Param.DBOfst) = 14*2                     'offset and segment
   ParamBlock(Btr.Param.DBSeg) = iParamDosSegment          'of data buffer
   ParamBlock(Btr.Param.DBLength)  = DataBufLen            'data buffer length
   ParamBlock(Btr.Param.FCBOfst) = _
          ParamBlock(Btr.Param.DBOfst) + DataBufLen         'offset and segment
   ParamBlock(Btr.Param.FCBSeg) = iParamDosSegment         'of FCB block
   ParamBlock(Btr.Param.PosOfst) = _
          ParamBlock(Btr.Param.FCBOfst) + 38                 'offset and segment
   ParamBlock(Btr.Param.PosSeg) = iParamDosSegment         'of position block
   ParamBlock(Btr.Param.OpCode) = Operation%               'BTRIEVE operation code
   ParamBlock(Btr.Param.KBOfst) = _
          ParamBlock(Btr.Param.FCBOfst) + len(FCBPosBlock)  'offset and segment
   ParamBlock(Btr.Param.KBSeg) = iParamDosSegment          'of key buffer
   ParamBlock(Btr.Param.KeyInfo) = _
          len(KeyBuffer$)+(KeyNumber%*256)                  'key info word
   ParamBlock(Btr.Param.StatOfst) = _
          ParamBlock(Btr.Param.KBOfst) + len(KeyBuffer)     'offset and segment
   ParamBlock(Btr.Param.StatSeg) = iParamDosSegment        'of status variable
   ParamBlock(Btr.Param.IfaceID) = &h6176                  'interface ID

    ' copy data to DOS memory
    movedata( _
        _my_ds(), @ParamBlock(0), _
        iParamDosSelector, 0, _
        14*2)
    movedata( _
        _my_ds(), DataBufferPtr, _
        iParamDosSelector, ParamBlock(Btr.Param.DBOfst), _
        DataBufLen)
    movedata( _
        _my_ds(), @FCBPosBlock[0], _
        iParamDosSelector, ParamBlock(Btr.Param.FCBOfst), _
        len(FCBPosBlock))
    movedata( _
        _my_ds(), @KeyBuffer[0], _
        iParamDosSelector, ParamBlock(Btr.Param.KBOfst), _
        len(KeyBuffer))
    movedata( _
        _my_ds(), @RetStatus, _
        iParamDosSelector, ParamBlock(Btr.Param.StatOfst), _
        2)

'   WColor 15, 1
'    ShowMemory iParamDosSelector, 0, iParamDosLength

   'Now do the interrupt with DS:DX pointing to the parameter block
    r.x.dx = 0
    r.x.ds = iParamDosSegment

   if not BMULTIPresent then           'BMULTI not present, so use INT 7B
       __dpmi_simulate_real_mode_interrupt &H7B, @r
   else
      do                                  'use BMULTI to do it
         if BMULTIProcessID% = 0 then   'get process ID if haven't yet
                r.x.ax = &HAB01
            else
             r.x.ax = &hAB02            'here if we have process ID -- need
             r.x.bx = BMULTIProcessID   '  to set it now
            end if
          __dpmi_simulate_real_mode_interrupt &H2F, @r 'invoke BMULTI
            if (r.x.ax and &HFF)=0 then exit do   'go on if done processing
            r.x.ax = &h0200                       'otherwise allow task
            __dpmi_simulate_real_mode_interrupt &h7F, @r '  switch and try request
      loop                                             '  again
        if BMULTIProcessID% = 0 then
           BMULTIProcessID% = r.x.bx  'assign proc ID
       end if
    end if

    ' copy data from DOS memory
    movedata( _
        iParamDosSelector, 0, _
        _my_ds(), @ParamBlock(0), _
        14*2)
    movedata( _
        iParamDosSelector, ParamBlock(Btr.Param.DBOfst), _
        _my_ds(), DataBufferPtr, _
        DataBufLen)
    movedata( _
        iParamDosSelector, ParamBlock(Btr.Param.FCBOfst), _
        _my_ds(), @FCBPosBlock[0], _
        len(FCBPosBlock))
    movedata( _
        iParamDosSelector, ParamBlock(Btr.Param.KBOfst), _
        _my_ds(), @KeyBuffer[0], _
        len(KeyBuffer))
    movedata( _
        iParamDosSelector, ParamBlock(Btr.Param.StatOfst), _
        _my_ds(), @RetStatus, _
        2)

   __dpmi_free_dos_memory(iParamDosSelector)

    DataBufLen = ParamBlock(Btr.Param.DBLength)  'pass new data buffer length back

    'Now restore critical error handler vector
    dosmemput(@CriticalErrorVec, 4, &H24*4)

   function = RetStatus
end function


btrv.bi

Code: Select all

const Btr.Key.Flag.Duplicates   = 1
const Btr.Key.Flag.Modifiable   = 2
const Btr.Key.Flag.Binary      = 4
const Btr.Key.Flag.Null      = 8
const Btr.Key.Flag.Segmented      = 16
const Btr.Key.Flag.AltCol      = 32
const Btr.Key.Flag.Descending   = 64
const Btr.Key.Flag.Supplemental   = 128
const Btr.Key.Flag.ExtType      = 256
const Btr.Key.Flag.Manual      = 512

const Btr.Key.Type.String   = 0
const Btr.Key.Type.Integer   = 1
const Btr.Key.Type.Float   = 2
const Btr.Key.Type.Date   = 3
const Btr.Key.Type.Time   = 4
const Btr.Key.Type.Decimal   = 5
const Btr.Key.Type.Money   = 6
const Btr.Key.Type.Logical   = 7
const Btr.Key.Type.Numeric   = 8
const Btr.Key.Type.BFloat   = 9
const Btr.Key.Type.LString   = 10
const Btr.Key.Type.ZString   = 11
const Btr.Key.Type.UnsBinary   = 14
const Btr.Key.Type.AutoInc   = 15

const Btr.File.Open.Exclusive   = -4
const Btr.File.Open.Verify      = -3
const Btr.File.Open.ReadOnly      = -2
const Btr.File.Open.Accel      = -1
const Btr.File.Open.Normal      = 0

const Btr.File.Flag.VarLength   = 1
const Btr.File.Flag.BlankTrunc   = 2
const Btr.File.Flag.PreAllocate   = 4
const Btr.File.Flag.DataComp      = 8
const Btr.File.Flag.KeyOnly      = 16
const Btr.File.Flag.Free10      = 64
const Btr.File.Flag.Free20      = 128
const Btr.File.Flag.Free30      = 192

const Btr.Op.File.Open      = 0
const Btr.Op.File.Close      = 1
const Btr.Op.Rec.Insert      = 2
const Btr.Op.Rec.Update      = 3
const Btr.Op.Rec.Delete      = 4
const Btr.Op.Rec.GetEQ      = 5
const Btr.Op.Rec.GetNext      = 6
const Btr.Op.Rec.GetPrev      = 7
const Btr.Op.Rec.GetGT      = 8
const Btr.Op.Rec.GetGE      = 9
const Btr.Op.Rec.GetLT      = 10
const Btr.Op.Rec.GetLE      = 11
const Btr.Op.Rec.GetFirst      = 12
const Btr.Op.Rec.GetLast      = 13
const Btr.Op.File.Create      = 14
const Btr.Op.File.Stat      = 15
const Btr.Op.File.Extend      = 16
const Btr.Op.Dir.Set         = 17
const Btr.Op.Dir.Get         = 18
const Btr.Op.Trans.Begin      = 19
const Btr.Op.Trans.Commit      = 20
const Btr.Op.Trans.Abort      = 21
const Btr.Op.Rec.GetPos      = 22
const Btr.Op.Rec.GetDirect      = 23
const Btr.Op.Rec.StepNext      = 24
const Btr.Op.DB.Stop         = 25
const Btr.Op.DB.Version      = 26
const Btr.Op.DB.Unlock      = 27
const Btr.Op.DB.Reset      = 28
const Btr.Op.File.SetOwner      = 29
const Btr.Op.File.ClearOwner      = 30
const Btr.Op.File.CreateSuppIdx   = 31
const Btr.Op.File.DropSuppIdx   = 32
const Btr.Op.Rec.StepFirst      = 33
const Btr.Op.Rec.StepLast      = 34
const Btr.Op.Rec.StepPrev      = 35
const Btr.Op.Rec.GetNextExt      = 36
const Btr.Op.Rec.GetPrevExt      = 37
const Btr.Op.Rec.StepNextExt      = 38
const Btr.Op.Rec.StepPrevExt      = 39
const Btr.Op.Rec.InsertExt      = 40
const Btr.Op.Rec.GetKey      = 50

const Btr.Comp.EQ      = 1
const Btr.Comp.GT      = 2
const Btr.Comp.LT      = 3
const Btr.Comp.NE      = 4
const Btr.Comp.GE      = 5
const Btr.Comp.LE      = 6
const Btr.Comp.UseAltColl   = 32
const Btr.Comp.UseField   = 64
const Btr.Comp.UseNoCase   = 128

const Btr.Err.Success   = 0
const Btr.Err.IO   = 2
const Btr.Err.FileNotOpen   = 3
const Btr.Err.KeyValueNotFound = 4
const Btr.Err.DuplicateKeyValue = 5
const Btr.Err.InvalidKeyNumber = 6
const Btr.Err.DifferentKeyNumber = 7
const Btr.Err.InvalidPositioning = 8
const Btr.Err.EndOfFile = 9
const Btr.Err.ModifiableKeyValueError   = 10
const Btr.Err.InvalidFilename   = 11
const Btr.Err.FileNotFound   = 12
const Btr.Err.PreImageOpenError = 14
const Btr.Err.PreImageIOError = 15
const Btr.Err.DiskFull   = 18
const Btr.Err.BtrieveNotLoaded = 20    'status code returned if BTRIEVE not loaded
const Btr.Err.KeyBufferTooShort   = 21
const Btr.Err.DataBufferLength   = 22
const Btr.Err.FCBPosLen = 23    'status code returned if size exceeded
const Btr.Err.PageSize   = 24
const Btr.Err.CreateIO   = 25
const Btr.Err.NumberOfKeys   = 26
const Btr.Err.InvalidKeyPos   = 27
const Btr.Err.InvalidRecordLen   = 28
const Btr.Err.InvalidKeyLen   = 29
const Btr.Err.Transaction = 36
const Btr.Err.TransactionIsActive = 37
const Btr.Err.EndOrAbortTransaction = 39
const Btr.Err.OperationNotAllowed = 41
const Btr.Err.InvalidDataRecordAddress = 43
const Btr.Err.SpecifiedKeyPathInvalid = 44
const Btr.Err.InconsistentKeyFlags = 45
const Btr.Err.FileAccessDenied = 46
const Btr.Err.InvalidAlternateSeqDef   = 48
const Btr.Err.KeyType   = 49
const Btr.Err.InvalidOwner = 51
const Btr.Err.VariablePageError = 54
const Btr.Err.IncompleteIndex = 56
const Btr.Err.CompressionBufferTooShort = 58
const Btr.Err.FileAlreadyExists   = 59
const Btr.Err.RejectCountReached = 60
const Btr.Err.WorkSpaceTooSmall = 61
const Btr.Err.IncorrectDescriptor = 62
const Btr.Err.FilterLimitReached = 64
const Btr.Err.IncorrectFieldOffset = 65
const Btr.Err.Conflict = 80
const Btr.Err.LostPosition = 82
const Btr.Err.ReadOutsideTransaction = 83
const Btr.Err.RecordOrPageLocked = 84
const Btr.Err.FileLocked = 85
const Btr.Err.FileTableFull = 86
const Btr.Err.HandleTableFull = 87
const Btr.Err.IncompatibleMode = 88
const Btr.Err.Server = 91
const Btr.Err.DataMessageTooSmall = 97
const Btr.Err.ChunkOffsetTooBig = 103
const Btr.Err.LocaleNotFound   = 104
const Btr.Err.CannotCreateWithVAT   = 105
const Btr.Err.CannotGetNextInRecord = 106
const Btr.Err.ChunkApiIncompatibleWithFile = 107

declare function BTRVFarNew(byval Operation as integer, _
                            FCBPosBlock as string, _
                            DataBuffer as any ptr,  _
                            DataBufLen as integer, _
                            KeyBuffer as string, _
                            byval KeyNumber as integer) as integer
scottmcardle
Posts: 8
Joined: Jan 05, 2017 17:11

Re: BTRIEVE access for DOS

Postby scottmcardle » Jan 05, 2017 17:18

Hi, is there more of a working example for this? I think there are parts missing?

Cheers scott
St_W
Posts: 1173
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: BTRIEVE access for DOS

Postby St_W » Jan 20, 2017 16:35

First note that this is a very old piece of software.

It is basically complete, there's nothing missing. The only thing you need additionally is the btrieve.exe for DOS as stated in the first post.

I just tried it and the code compiled fine with FBC 1.05 for DOS using "-lang deprecated", but it may also compile in other language modes.

For examples how to program Btrieve see the Programmer's Manual;
copy from the internet archive as the original site isn't available anymore: http://web.archive.org/web/200610190410 ... 15prog.pdf

Return to “Tips and Tricks”

Who is online

Users browsing this forum: fxm and 1 guest