Some more investigation brought me to this code in Freebasic ??
Maybe i'm looking to far away in time. These topics are from 2005 !! The BTR files I talk about are from a program that is updated reguarly and running from ALL windows platforms.
Link :
http://www.freebasic.net/forum/viewtopic.php?t=388
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.
I found some Source code with the looks of fWH. Maybe this will make more sence to some of you.
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
and also
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