TSBTRV.MOD 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * TopSpeed Modula-2 Interface for BTRIEVE - Supports TopSpeed Extender *
  5. * Public Domain - May be used without restriction *
  6. * *
  7. *--------------------------------------------------------------------------*)
  8. IMPLEMENTATION MODULE TSBTRV;
  9. IMPORT SYSTEM,Lib,Str;
  10. (*%T _XTD*)
  11. IMPORT TSXLIB;
  12. (*%E*)
  13. (****************************************************************************)
  14. PROCEDURE BTRV1(fn : CARDINAL);
  15. VAR
  16. NullControl : FileControlBlock;
  17. NullBuffer : LONGCARD;
  18. NullBufferSize : CARDINAL;
  19. NullKey : KeyType;
  20. BEGIN
  21. NullBufferSize := SIZE(NullBuffer);
  22. StatusCode := BTRV(fn,NullControl,NullBuffer,NullBufferSize,NullKey,0);
  23. END BTRV1;
  24. PROCEDURE BTRV2(fn : CARDINAL;VAR FileControl : FileControlBlock);
  25. VAR
  26. NullBuffer : LONGCARD;
  27. NullBufferSize : CARDINAL;
  28. NullKey : KeyType;
  29. BEGIN
  30. NullBufferSize := SIZE(NullBuffer);
  31. StatusCode := BTRV(fn,FileControl,NullBuffer,NullBufferSize,NullKey,0);
  32. END BTRV2;
  33. PROCEDURE BTRV3(fn : CARDINAL;VAR FileControl : FileControlBlock;Key : SHORTCARD);
  34. VAR
  35. NullBuffer : LONGCARD;
  36. NullBufferSize : CARDINAL;
  37. NullKey : KeyType;
  38. BEGIN
  39. NullBufferSize := SIZE(NullBuffer);
  40. StatusCode := BTRV(fn,FileControl,NullBuffer,NullBufferSize,NullKey,Key);
  41. END BTRV3;
  42. PROCEDURE BTRV4(fn : CARDINAL;VAR FileControl : FileControlBlock;
  43. VAR KeyBuffer : ARRAY OF BYTE; Key : SHORTCARD);
  44. VAR
  45. NullBuffer : LONGCARD;
  46. NullBufferSize : CARDINAL;
  47. BEGIN
  48. NullBufferSize := SIZE(NullBuffer);
  49. StatusCode := BTRV(fn,FileControl,NullBuffer,NullBufferSize,KeyBuffer,Key);
  50. END BTRV4;
  51. (****************************************************************************)
  52. PROCEDURE AbortTransaction;
  53. BEGIN
  54. BTRV1(opAbortTrans);
  55. END AbortTransaction;
  56. (****************************************************************************)
  57. PROCEDURE BeginTransaction;
  58. BEGIN
  59. BTRV1(opBeginTrans);
  60. END BeginTransaction;
  61. (****************************************************************************)
  62. PROCEDURE ClearOwner(VAR FileControl : FileControlBlock);
  63. BEGIN
  64. BTRV2(opClearOwner,FileControl);
  65. END ClearOwner;
  66. (****************************************************************************)
  67. PROCEDURE Close(VAR FileControl : FileControlBlock);
  68. BEGIN
  69. BTRV2(opClose,FileControl);
  70. END Close;
  71. (****************************************************************************)
  72. PROCEDURE Create( VAR FileControl : FileControlBlock;
  73. FileDescriptor : ARRAY OF BYTE;
  74. DescriptorLength : CARDINAL;
  75. FileName : ARRAY OF CHAR);
  76. VAR
  77. KeyBuffer : KeyType;
  78. BEGIN
  79. Str.Copy(KeyBuffer,FileName);
  80. StatusCode := BTRV(opCreate,FileControl,FileDescriptor,DescriptorLength,KeyBuffer,0);
  81. END Create;
  82. (****************************************************************************)
  83. PROCEDURE DeleteRec(VAR FileControl : FileControlBlock; KeyID : SHORTCARD);
  84. BEGIN
  85. BTRV3(opDelete,FileControl,KeyID);
  86. END DeleteRec;
  87. (****************************************************************************)
  88. PROCEDURE EndTransaction;
  89. BEGIN
  90. BTRV1(opEndTrans);
  91. END EndTransaction;
  92. (****************************************************************************)
  93. PROCEDURE Extend(VAR FileControl : FileControlBlock; FileName : ARRAY OF CHAR;
  94. UseNow : BOOLEAN);
  95. VAR
  96. KeyBuffer : KeyType;
  97. KeyID : SHORTCARD;
  98. BEGIN
  99. Str.Copy(KeyBuffer,FileName);
  100. IF UseNow THEN KeyID := 255 ELSE KeyID := 0; END;
  101. BTRV4(opExtend,FileControl,KeyBuffer,KeyID);
  102. END Extend;
  103. (****************************************************************************)
  104. PROCEDURE FindEQ(VAR FileControl : FileControlBlock;
  105. VAR KeyBuffer : ARRAY OF BYTE;
  106. KeyID : SHORTCARD);
  107. BEGIN
  108. BTRV4(opGetEQ+opKeyOnly,FileControl,KeyBuffer,KeyID);
  109. END FindEQ;
  110. (****************************************************************************)
  111. PROCEDURE FindGT(VAR FileControl : FileControlBlock;
  112. VAR KeyBuffer : ARRAY OF BYTE;
  113. KeyID : SHORTCARD);
  114. BEGIN
  115. BTRV4(opGetGT+opKeyOnly,FileControl,KeyBuffer,KeyID);
  116. END FindGT;
  117. (****************************************************************************)
  118. PROCEDURE FindGE(VAR FileControl : FileControlBlock;
  119. VAR KeyBuffer : ARRAY OF BYTE;
  120. KeyID : SHORTCARD);
  121. BEGIN
  122. BTRV4(opGetGE+opKeyOnly,FileControl,KeyBuffer,KeyID);
  123. END FindGE;
  124. (****************************************************************************)
  125. PROCEDURE FindLast(VAR FileControl : FileControlBlock;
  126. VAR KeyBuffer : ARRAY OF BYTE;
  127. KeyID : SHORTCARD);
  128. BEGIN
  129. BTRV4(opGetLast+opKeyOnly,FileControl,KeyBuffer,KeyID);
  130. END FindLast;
  131. (****************************************************************************)
  132. PROCEDURE FindLT(VAR FileControl : FileControlBlock;
  133. VAR KeyBuffer : ARRAY OF BYTE;
  134. KeyID : SHORTCARD);
  135. BEGIN
  136. BTRV4(opGetLT+opKeyOnly,FileControl,KeyBuffer,KeyID);
  137. END FindLT;
  138. (****************************************************************************)
  139. PROCEDURE FindLE(VAR FileControl : FileControlBlock;
  140. VAR KeyBuffer : ARRAY OF BYTE;
  141. KeyID : SHORTCARD);
  142. BEGIN
  143. BTRV4(opGetLE+opKeyOnly,FileControl,KeyBuffer,KeyID);
  144. END FindLE;
  145. (****************************************************************************)
  146. PROCEDURE FindFirst(VAR FileControl : FileControlBlock;
  147. VAR KeyBuffer : ARRAY OF BYTE;
  148. KeyID : SHORTCARD);
  149. BEGIN
  150. BTRV4(opGetFirst+opKeyOnly,FileControl,KeyBuffer,KeyID);
  151. END FindFirst;
  152. (****************************************************************************)
  153. PROCEDURE FindNext(VAR FileControl : FileControlBlock;
  154. VAR KeyBuffer : ARRAY OF BYTE;
  155. KeyID : SHORTCARD);
  156. BEGIN
  157. BTRV4(opGetNext+opKeyOnly,FileControl,KeyBuffer,KeyID);
  158. END FindNext;
  159. (****************************************************************************)
  160. PROCEDURE FindPrev(VAR FileControl : FileControlBlock;
  161. VAR KeyBuffer : ARRAY OF BYTE;
  162. KeyID : SHORTCARD);
  163. BEGIN
  164. BTRV4(opGetPrev+opKeyOnly,FileControl,KeyBuffer,KeyID);
  165. END FindPrev;
  166. (****************************************************************************)
  167. PROCEDURE GetDirect(VAR FileControl : FileControlBlock;
  168. VAR DataBuffer : ARRAY OF BYTE;
  169. VAR BufferLength : CARDINAL;
  170. VAR KeyBuffer : ARRAY OF BYTE;
  171. KeyID : SHORTCARD);
  172. BEGIN
  173. StatusCode := BTRV(opGetDirect,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  174. END GetDirect;
  175. (****************************************************************************)
  176. PROCEDURE GetDir(Drive : SHORTCARD; VAR DirName : ARRAY OF CHAR);
  177. VAR
  178. NullControl : FileControlBlock;
  179. BEGIN
  180. BTRV4(opGetDir,NullControl,DirName,Drive);
  181. END GetDir;
  182. (****************************************************************************)
  183. PROCEDURE GetEQ(VAR FileControl : FileControlBlock;
  184. VAR DataBuffer : ARRAY OF BYTE;
  185. VAR BufferLength : CARDINAL;
  186. VAR KeyBuffer : ARRAY OF BYTE;
  187. KeyID : SHORTCARD);
  188. BEGIN
  189. StatusCode := BTRV(opGetEQ,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  190. END GetEQ;
  191. (****************************************************************************)
  192. PROCEDURE GetGT(VAR FileControl : FileControlBlock;
  193. VAR DataBuffer : ARRAY OF BYTE;
  194. VAR BufferLength : CARDINAL;
  195. VAR KeyBuffer : ARRAY OF BYTE;
  196. KeyID : SHORTCARD);
  197. BEGIN
  198. StatusCode := BTRV(opGetGT,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  199. END GetGT;
  200. (****************************************************************************)
  201. PROCEDURE GetGE(VAR FileControl : FileControlBlock;
  202. VAR DataBuffer : ARRAY OF BYTE;
  203. VAR BufferLength : CARDINAL;
  204. VAR KeyBuffer : ARRAY OF BYTE;
  205. KeyID : SHORTCARD);
  206. BEGIN
  207. StatusCode := BTRV(opGetGE,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  208. END GetGE;
  209. (****************************************************************************)
  210. PROCEDURE GetLast(VAR FileControl : FileControlBlock;
  211. VAR DataBuffer : ARRAY OF BYTE;
  212. VAR BufferLength : CARDINAL;
  213. VAR KeyBuffer : ARRAY OF BYTE;
  214. KeyID : SHORTCARD);
  215. BEGIN
  216. StatusCode := BTRV(opGetLast,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  217. END GetLast;
  218. (****************************************************************************)
  219. PROCEDURE GetLT(VAR FileControl : FileControlBlock;
  220. VAR DataBuffer : ARRAY OF BYTE;
  221. VAR BufferLength : CARDINAL;
  222. VAR KeyBuffer : ARRAY OF BYTE;
  223. KeyID : SHORTCARD);
  224. BEGIN
  225. StatusCode := BTRV(opGetLT,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  226. END GetLT;
  227. (****************************************************************************)
  228. PROCEDURE GetLE(VAR FileControl : FileControlBlock;
  229. VAR DataBuffer : ARRAY OF BYTE;
  230. VAR BufferLength : CARDINAL;
  231. VAR KeyBuffer : ARRAY OF BYTE;
  232. KeyID : SHORTCARD);
  233. BEGIN
  234. StatusCode := BTRV(opGetLE,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  235. END GetLE;
  236. (****************************************************************************)
  237. PROCEDURE GetFirst(VAR FileControl : FileControlBlock;
  238. VAR DataBuffer : ARRAY OF BYTE;
  239. VAR BufferLength : CARDINAL;
  240. VAR KeyBuffer : ARRAY OF BYTE;
  241. KeyID : SHORTCARD);
  242. BEGIN
  243. StatusCode := BTRV(opGetFirst,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  244. END GetFirst;
  245. (****************************************************************************)
  246. PROCEDURE GetNext(VAR FileControl : FileControlBlock;
  247. VAR DataBuffer : ARRAY OF BYTE;
  248. VAR BufferLength : CARDINAL;
  249. VAR KeyBuffer : ARRAY OF BYTE;
  250. KeyID : SHORTCARD);
  251. BEGIN
  252. StatusCode := BTRV(opGetNext,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  253. END GetNext;
  254. (****************************************************************************)
  255. PROCEDURE GetPosition(VAR FileControl :FileControlBlock;
  256. VAR pos : ARRAY OF BYTE);
  257. VAR BufferSize : CARDINAL;
  258. NullKey : KeyType;
  259. BEGIN
  260. BufferSize := SIZE(pos);
  261. StatusCode := BTRV(opGetPos,FileControl,pos,BufferSize,NullKey,0);
  262. END GetPosition;
  263. (****************************************************************************)
  264. PROCEDURE GetPrev(VAR FileControl : FileControlBlock;
  265. VAR DataBuffer : ARRAY OF BYTE;
  266. VAR BufferLength : CARDINAL;
  267. VAR KeyBuffer : ARRAY OF BYTE;
  268. KeyID : SHORTCARD);
  269. BEGIN
  270. StatusCode := BTRV(opGetPrev,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  271. END GetPrev;
  272. (****************************************************************************)
  273. PROCEDURE Insert(VAR FileControl : FileControlBlock;
  274. VAR DataBuffer : ARRAY OF BYTE;
  275. VAR BufferLength : CARDINAL;
  276. VAR KeyBuffer : ARRAY OF BYTE;
  277. KeyID : SHORTCARD);
  278. BEGIN
  279. StatusCode := BTRV(opInsert,FileControl,DataBuffer,BufferLength,KeyBuffer,KeyID);
  280. END Insert;
  281. (****************************************************************************)
  282. PROCEDURE Open(VAR FileControl : FileControlBlock;
  283. FileName,OwnerName : ARRAY OF CHAR;
  284. OpenMode : SHORTCARD);
  285. VAR
  286. DataBuffer : ARRAY [0..7] OF CHAR;
  287. KeyBuffer : KeyType;
  288. BufferLength : CARDINAL;
  289. BEGIN
  290. Str.Copy(KeyBuffer,FileName);
  291. Str.Copy(DataBuffer,OwnerName);
  292. DataBuffer[7] := 0C;
  293. BufferLength := Str.Length(DataBuffer) + 1;
  294. StatusCode := BTRV(opOpen,FileControl,DataBuffer,BufferLength,
  295. KeyBuffer,OpenMode);
  296. END Open;
  297. (****************************************************************************)
  298. PROCEDURE Reset;
  299. BEGIN
  300. BTRV1(opReset);
  301. END Reset;
  302. (****************************************************************************)
  303. PROCEDURE SetDirectory(DirName : ARRAY OF CHAR);
  304. VAR
  305. KeyBuffer : KeyType;
  306. NullControl : FileControlBlock;
  307. BEGIN
  308. Str.Copy(KeyBuffer,DirName);
  309. BTRV4(opSetDir,NullControl,KeyBuffer,0);
  310. END SetDirectory;
  311. (****************************************************************************)
  312. PROCEDURE SetOwner(VAR FileControl : FileControlBlock;
  313. OwnerName : ARRAY OF CHAR;
  314. AccessMode : SHORTCARD);
  315. VAR
  316. DataBuffer : OwnerType;
  317. KeyBuffer : KeyType;
  318. BufferLength : CARDINAL;
  319. BEGIN
  320. Str.Copy(DataBuffer,OwnerName);
  321. Str.Copy(KeyBuffer,OwnerName);
  322. DataBuffer[7] := 0C;
  323. BufferLength := Str.Length(DataBuffer) + 1;
  324. StatusCode := BTRV(opSetOwner,FileControl,DataBuffer,
  325. BufferLength,KeyBuffer,AccessMode);
  326. END SetOwner;
  327. (****************************************************************************)
  328. PROCEDURE Status(VAR FileControl : FileControlBlock;
  329. VAR DataBuffer : ARRAY OF BYTE;
  330. VAR BufferLength : CARDINAL;
  331. VAR KeyBuffer : ARRAY OF BYTE;
  332. KeyID : SHORTCARD);
  333. BEGIN
  334. StatusCode := BTRV(opStat,FileControl,DataBuffer,BufferLength,KeyBuffer,0);
  335. END Status;
  336. (****************************************************************************)
  337. PROCEDURE StepDirect(VAR FileControl : FileControlBlock;
  338. VAR DataBuffer : ARRAY OF BYTE;
  339. VAR BufferLength : CARDINAL);
  340. VAR
  341. NullKey : KeyType;
  342. BEGIN
  343. StatusCode := BTRV(opStepDirect,FileControl,DataBuffer,
  344. BufferLength,NullKey,0);
  345. END StepDirect;
  346. (****************************************************************************)
  347. PROCEDURE Stop;
  348. BEGIN
  349. BTRV1(opStop);
  350. END Stop;
  351. (****************************************************************************)
  352. PROCEDURE Update(VAR FileControl : FileControlBlock;
  353. VAR DataBuffer : ARRAY OF BYTE;
  354. VAR BufferLength : CARDINAL;
  355. VAR KeyBuffer : ARRAY OF BYTE;
  356. KeyID : SHORTCARD);
  357. BEGIN
  358. StatusCode := BTRV(opUpdate,FileControl,DataBuffer,BufferLength,KeyBuffer,0);
  359. END Update;
  360. (****************************************************************************)
  361. PROCEDURE Version(VAR DataBuffer : ARRAY OF BYTE );
  362. VAR
  363. NullControl : FileControlBlock;
  364. BufferSize : CARDINAL;
  365. NullKey : KeyType;
  366. BEGIN
  367. BufferSize := SIZE(DataBuffer);
  368. StatusCode := BTRV(opVersion,NullControl,DataBuffer,BufferSize,NullKey,0);
  369. END Version;
  370. (****************************************************************************)
  371. (* Low Level Btrieve Call *)
  372. (****************************************************************************)
  373. VAR
  374. ProcId: CARDINAL; (* initialize to no process id *)
  375. Multi: BOOLEAN; (* set to true if BMulti is loaded *)
  376. VSet: BOOLEAN; (* set to true if we have checked for BMulti *)
  377. (*%T _XTD*)
  378. TYPE
  379. rADDRESS = LONGCARD;
  380. PROCEDURE RealAlloc(VAR handle : CARDINAL; size : CARDINAL; VAR src : ARRAY OF BYTE):rADDRESS;
  381. (* Needed to copy to Real Memory (i.e. addressable from real mode) *)
  382. VAR csize : CARDINAL;
  383. BEGIN
  384. IF size=0 THEN handle:=0; RETURN 0 END;
  385. handle := TSXLIB.ALLOCLOWSEG(size);
  386. IF Seg(src)<>0 THEN (* copy in *)
  387. (* protect against buffers that are too short *)
  388. csize := TSXLIB.GETSEGLIMIT(Seg(src));
  389. IF (csize>=Ofs(src)) THEN
  390. DEC(csize,Ofs(src)-1);
  391. IF (csize=0)OR(csize>size) THEN csize := size END;
  392. Lib.FastMove(ADR(src),[handle:0],csize);
  393. END;
  394. ELSE
  395. Lib.Fill([handle:0],size,0);
  396. END;
  397. RETURN TSXLIB.MAKEREALADDR(handle,0);
  398. END RealAlloc;
  399. PROCEDURE RealFree(handle :CARDINAL; size : CARDINAL; VAR dst : ARRAY OF BYTE);
  400. VAR csize : CARDINAL;
  401. BEGIN
  402. IF handle=0 THEN RETURN END;
  403. IF Seg(dst)<>0 THEN (* copy out *)
  404. (* protect against buffers that are too short *)
  405. csize := TSXLIB.GETSEGLIMIT(Seg(dst));
  406. IF (csize>=Ofs(dst)) THEN
  407. DEC(csize,Ofs(dst)-1);
  408. IF (csize=0)OR(csize>size) THEN csize := size END;
  409. Lib.FastMove([handle:0],ADR(dst),csize);
  410. END;
  411. END;
  412. TSXLIB.FREESEG(handle);
  413. END RealFree;
  414. PROCEDURE BTRV ( op: CARDINAL; (* Operation *)
  415. VAR pos: FileControlBlock; (* Position Block *)
  416. VAR data: ARRAY OF BYTE; (* Data Buffer *)
  417. VAR datalen: CARDINAL; (* Data Length *)
  418. VAR kbuf: ARRAY OF BYTE; (* Key Buffer *)
  419. key: SHORTCARD (* Key Number *)
  420. ): StatusCodes ; (* Btrieve error code *)
  421. CONST
  422. VarID = 06176H; (* id for variable length records - 'va'*)
  423. BtrInt = 07BH;
  424. Btr2Int = 02FH;
  425. BtrOffset = 00033H;
  426. MultiFunction = 0AB00H;
  427. TYPE
  428. rBtrParms = RECORD
  429. UserBufAddr : rADDRESS; (* data buffer address *)
  430. UserBufLen : CARDINAL; (* data buffer length *)
  431. UserCurAddr : rADDRESS; (* currency block address *)
  432. UserFCBAddr : rADDRESS; (* file control block address *)
  433. UserFunction : CARDINAL; (* Btrieve operation *)
  434. UserKeyAddr : rADDRESS; (* key buffer address *)
  435. UserKeyLength: SHORTCARD; (* key buffer length *)
  436. UserKeyNumber: SHORTCARD; (* key number *)
  437. UserStatAddr : rADDRESS; (* return status address *)
  438. xFaceID : CARDINAL; (* language interface id *)
  439. END;
  440. VAR
  441. Stat: CARDINAL; (* Btrieve status code *)
  442. Params: rBtrParms; (* Btrieve parameter block *)
  443. r: SYSTEM.Registers; (* register structure used on interrrupt call *)
  444. DataSel,PosSel,KeySel,StatSel,ParamSel : CARDINAL;
  445. rParams : rADDRESS;
  446. BEGIN
  447. Lib.Fill(ADR(r),SIZE(r),0);
  448. r.AX:= 03500H + BtrInt;
  449. TSXLIB.REALINTR(ADR(r), 21H); (* NB using Lib.Intr will return
  450. prot mode address *)
  451. IF r.BX # BtrOffset THEN (* make sure Btrieve is installed *)
  452. RETURN BtrieveAbsent
  453. END;
  454. IF NOT VSet THEN (* if we haven't checked for Multi-User version *)
  455. r.AX:= 03000H;
  456. Lib.Intr(r, 021H);
  457. IF r.AL >= 3 THEN (* DOS version >= 3.0 *)
  458. VSet:= TRUE;
  459. r.AX:= MultiFunction;
  460. Lib.Intr(r, Btr2Int);
  461. Multi:= r.AL = 4DH (* ORD('M') *)
  462. ELSE
  463. Multi:= FALSE
  464. END
  465. END; (* make normal btrieve call *)
  466. IF datalen > HIGH(data)+1 THEN datalen:= HIGH(data)+1 END;
  467. WITH Params DO
  468. UserBufAddr := RealAlloc(DataSel,datalen,data); (* set data buffer address *)
  469. UserBufLen := datalen; (* set length *)
  470. UserFCBAddr := RealAlloc(PosSel,38+90,pos); (* set FCB address*)
  471. UserCurAddr := UserFCBAddr+38;
  472. UserFunction := op; (* set Btrieve operation code *)
  473. UserKeyAddr := RealAlloc(KeySel,255,kbuf); (* set key buffer address *)
  474. UserKeyLength := 255;
  475. UserKeyNumber := key; (* set key number *)
  476. UserStatAddr := RealAlloc(StatSel,SIZE(Stat),Stat);;
  477. xFaceID := VarID; (* set language id *)
  478. END;
  479. rParams := RealAlloc(ParamSel,SIZE(Params),Params);
  480. r.DX := CARDINAL(rParams);
  481. r.DS := CARDINAL(rParams>>16);
  482. IF NOT Multi THEN (* MultiUser version not installed *)
  483. TSXLIB.REALINTR(ADR(r), BtrInt); (* passing real addresses *)
  484. ELSE
  485. LOOP
  486. r.BX:= ProcId;
  487. IF r.BX # 0 THEN r.AX:= 2 ELSE r.AX:= 1 END;
  488. INC(r.AX, MultiFunction);
  489. Lib.Intr(r, Btr2Int);
  490. IF r.AL = 0 THEN EXIT END;
  491. r.AX:= 200H;
  492. TSXLIB.REALINTR(ADR(r), 07FH); (* passing real addresses *)
  493. END;
  494. IF ProcId = 0 THEN ProcId:= r.BX END
  495. END;
  496. RealFree(ParamSel,SIZE(Params),Params);
  497. RealFree(DataSel,datalen,data);
  498. RealFree(PosSel,38,pos);
  499. RealFree(KeySel,255,kbuf);
  500. RealFree(StatSel,SIZE(Stat),Stat);
  501. datalen:= Params.UserBufLen;
  502. RETURN StatusCodes(Stat);
  503. END BTRV;
  504. (*%E*)
  505. (*%F _XTD*)
  506. PROCEDURE BTRV ( op: CARDINAL; (* Operation *)
  507. VAR pos: FileControlBlock; (* Position Block *)
  508. VAR data: ARRAY OF BYTE; (* Data Buffer *)
  509. VAR datalen: CARDINAL; (* Data Length *)
  510. VAR kbuf: ARRAY OF BYTE; (* Key Buffer *)
  511. key: SHORTCARD (* Key Number *)
  512. ): StatusCodes ; (* Btrieve error code *)
  513. CONST
  514. VarID = 06176H; (* id for variable length records - 'va'*)
  515. BtrInt = 07BH;
  516. Btr2Int = 02FH;
  517. BtrOffset = 00033H;
  518. MultiFunction = 0AB00H;
  519. TYPE
  520. BtrParms = RECORD
  521. UserBufAddr : ADDRESS; (* data buffer address *)
  522. UserBufLen : CARDINAL; (* data buffer length *)
  523. UserCurAddr : ADDRESS; (* currency block address *)
  524. UserFCBAddr : ADDRESS; (* file control block address *)
  525. UserFunction : CARDINAL; (* Btrieve operation *)
  526. UserKeyAddr : ADDRESS; (* key buffer address *)
  527. UserKeyLength: SHORTCARD; (* key buffer length *)
  528. UserKeyNumber: SHORTCARD; (* key number *)
  529. UserStatAddr : ADDRESS; (* return status address *)
  530. xFaceID : CARDINAL; (* language interface id *)
  531. END;
  532. VAR
  533. Stat: CARDINAL; (* Btrieve status code *)
  534. XData: BtrParms; (* Btrieve parameter block *)
  535. r: SYSTEM.Registers; (* register structure used on interrrupt call *)
  536. BEGIN
  537. r.AX:= 03500H + BtrInt;
  538. Lib.Intr(r, 021H);
  539. IF r.BX # BtrOffset THEN (* make sure Btrieve is installed *)
  540. RETURN BtrieveAbsent
  541. END;
  542. IF NOT VSet THEN (* if we haven't checked for Multi-User version *)
  543. r.AX:= 03000H;
  544. Lib.Intr(r, 021H);
  545. IF r.AL >= 3 THEN (* DOS version >= 3.0 *)
  546. VSet:= TRUE;
  547. r.AX:= MultiFunction;
  548. Lib.Intr(r, Btr2Int);
  549. Multi:= r.AL = 4DH (* ORD('M') *)
  550. ELSE
  551. Multi:= FALSE
  552. END
  553. END; (* make normal btrieve call *)
  554. IF datalen > HIGH(data)+1 THEN datalen:= HIGH(data)+1 END;
  555. WITH XData DO
  556. UserBufAddr := ADR(data); (* set data buffer address *)
  557. UserBufLen := datalen; (* set length *)
  558. UserFCBAddr := ADR(pos); (* set FCB address*)
  559. UserCurAddr := ADR(pos[38]);
  560. UserFunction := op; (* set Btrieve operation code *)
  561. UserKeyAddr := ADR(kbuf); (* set key buffer address *)
  562. UserKeyLength := 255;
  563. UserKeyNumber:= key; (* set key number *)
  564. UserStatAddr := ADR(Stat); (* set status address *)
  565. xFaceID := VarID; (* set language id *)
  566. END;
  567. r.DX:= SYSTEM.Ofs(XData);
  568. r.DS:= SYSTEM.Seg(XData);
  569. IF NOT Multi THEN (* MultiUser version not installed *)
  570. Lib.Intr(r, BtrInt)
  571. ELSE
  572. LOOP
  573. r.BX:= ProcId;
  574. IF r.BX # 0 THEN r.AX:= 2 ELSE r.AX:= 1 END;
  575. INC(r.AX, MultiFunction);
  576. Lib.Intr(r, Btr2Int);
  577. IF r.AL = 0 THEN EXIT END;
  578. r.AX:= 200H;
  579. Lib.Intr(r, 07FH)
  580. END;
  581. IF ProcId = 0 THEN ProcId:= r.BX END
  582. END;
  583. datalen:= XData.UserBufLen;
  584. RETURN StatusCodes(Stat);
  585. END BTRV;
  586. (*%E*)
  587. BEGIN
  588. VSet := FALSE;
  589. Multi := FALSE;
  590. ProcId:= 0;
  591. END TSBTRV.
  592.