home *** CD-ROM | disk | FTP | other *** search
- /* */
- /* MicroSoft/IBM C interface to the */
- /* Btrieve OS/2 dynamic link library */
- /* */
- extern int far pascal btrcall(); /* declaration of dynamic link */
- extern int far pascal DosGetMachineMode();
-
- BTRV (operation, posblock, databuf, datalen, keybuf, keynum)
- int operation;
- char posblock[];
- char databuf[];
- int *datalen;
- char keybuf[];
- int keynum;
-
- {
-
- unsigned char keylen = 255;
- char ckeynum = keynum;
- char machineMode;
-
- DosGetMachineMode ( (char far *) &machineMode);
- if (machineMode)
-
- /* */
- /* Make call to the dynamic link entry point */
- /* */
- return (btrcall (operation,
- (char far *) posblock,
- (char far *) databuf,
- (int far *) datalen,
- (char far *) keybuf,
- keylen,
- ckeynum));
- else
-
- {
-
- /* make sure this constant is not commented if
- compiling for MS windows
- #define WINDOWS 1
- */
-
- /* macros to break MS C "far" pointers into their segment and offset
- * components
- */
-
- #define FP_SEG(fp) (*((unsigned *)&(fp) + 1))
- #define FP_OFF(fp) (*((unsigned *)&(fp)))
-
-
- #define BTR_ERR 20 /* record manager not started */
- #define BTR_INT 0x7B /* Btrieve interrupt vector */
- #define BTR2_INT 0x2F /* multi-user interrupt vector */
- #define BTR_VECTOR BTR_INT * 4 /* offset for interrupt */
- #define BTR_OFFSET 0x33 /* Btrieve offset within segment */
- #define VARIABLE_ID 0x6176 /* id for variable length records - 'va' */
- #define _2FCODE 0xAB00 /* function code for int 2F to btrieve */
-
- /* ProcId is used for communicating with the Multi Tasking Version of */
- /* Btrieve. It contains the process id returned from BMulti and should */
- /* not be changed once it has been set. */
- /* */
-
- static unsigned ProcId = 0; /* initialize to no process id */
- static char MULTI = 0; /* flag set to true if MultiUser */
- static char VSet = 0; /* flag set to true if checked version */
-
- struct REGVAL { int AX, BX, CX, DX, SI, DI, CY; } REGS;
-
- struct SEGREG { short ES, CS, SS, DS; } SREGS;
-
- struct BTRIEVE_PARMS /* structure passed to Btrieve Record Manager */
- {
- char far *BUF_OFFSET; /* callers data buffer offset */
- int BUF_LEN; /* length of data buffer */
- char far *CUR_OFFSET; /* user position block offset */
- char far *FCB_OFFSET; /* offset of disk FCB */
- int FUNCTION; /* requested function */
- char far *KEY_OFFSET; /* offset of user's key buffer */
- char KEY_LENGTH; /* length of user's key buffer */
- char KEY_NUMBER; /* key of reference for request */
- int far *STAT_OFFSET; /* offset of status word */
- int XFACE_ID; /* language identifier */
- } XDATA;
-
- char far *fptr;
- int stat = 0; /* status of Btrieve call */
-
- segread (&SREGS);
-
- /* */
- /* Check to see that the Btrieve Record Manager has been started. */
- /* */
-
- if (!VSet) /* if we don't know version of Btrieve yet */
- {
- VSet = 1;
- REGS.AX = 0x3000; /* check dos version */
- #ifdef WINDOWS
- int86 (0x21, ®S, ®S);
- #else
- int86x (0x21, ®S, ®S, &SREGS);
- #endif
- if ((REGS.AX & 0x00FF) >= 3) /* if DOS version 3 or later */
- {
- REGS.AX = _2FCODE;
- #ifdef WINDOWS
- int86 (BTR2_INT, ®S, ®S); /* is bmulti loaded? */
- #else
- int86x (BTR2_INT, ®S, ®S, &SREGS);
- #endif
- MULTI = ((REGS.AX & 0xFF) == 'M'); /* if al is M, bmulti is loaded */
- }
- }
-
- if (!MULTI)
- { /* if bmulti not loaded */
- REGS.AX = 0x3500 + BTR_INT;
- #ifdef WINDOWS
- int86 (0x21, ®S, ®S); /* check for btrieve being loaded */
- #else
- int86x (0x21, ®S, ®S, &SREGS);
- #endif
- if (REGS.BX != BTR_OFFSET)
- return (BTR_ERR);
- }
-
- /* */
- /* Move user parameters to XDATA, the block where Btrieve expects them.*/
- /* */
-
- XDATA.FUNCTION = operation;
- XDATA.STAT_OFFSET = (int far *) &stat;
- XDATA.FCB_OFFSET = (char far *) posblock;
- XDATA.CUR_OFFSET = (char far *) posblock + 38;
- XDATA.BUF_OFFSET = (char far *) databuf;
- XDATA.BUF_LEN = *datalen;
- XDATA.KEY_OFFSET = (char far *) keybuf;
- XDATA.KEY_LENGTH = 255; /* use max since we don't know */
- XDATA.KEY_NUMBER = keynum;
- XDATA.XFACE_ID = VARIABLE_ID;
-
- /* */
- /* Make call to the Btrieve Record Manager. */
- /* */
-
- fptr = (char far *) &XDATA;
- REGS.DX = FP_OFF(fptr); /* parameter block is expected to be in DX */
- SREGS.DS = FP_SEG(fptr);
- if (!MULTI)
- #ifdef WINDOWS /* if bmulti not loaded, call Btrieve */
- int86 (BTR_INT, ®S, ®S);
- #else
- int86x (BTR_INT, ®S, ®S, &SREGS);
- #endif
- else
- { /* call bmulti */
- while (1)
- {
- REGS.AX = 1; /* assume no proc id obtained yet */
- if ((REGS.BX = ProcId) != 0) /* if we have a proc id */
- REGS.AX = 2; /* tell bmulti that */
- REGS.AX += _2FCODE;
- #ifdef WINDOWS
- int86 (BTR2_INT, ®S, ®S); /* call bmulti */
- #else
- int86x (BTR2_INT, ®S, ®S, &SREGS);
- #endif
- if ((REGS.AX & 0x00FF) == 0) break; /* if call was processed */
- #ifndef WINDOWS /* by bmulti, leave loop */
- REGS.AX = 0x0200; /* if multilink advanced is loaded, it will */
- int86x (0x7F, ®S, ®S, &SREGS); /* it will switch processes */
- #endif
- }
- if (ProcId == 0) ProcId = REGS.BX;
- }
-
- *datalen = XDATA.BUF_LEN;
- return (stat); /* return status */
- }
- }