home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a011 / 2.ddi / C2FXBTRV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-09-08  |  7.1 KB  |  183 lines

  1. /*                                                                      */
  2. /*              MicroSoft/IBM C interface to the                        */
  3. /*              Btrieve OS/2 dynamic link library                       */
  4. /*                                                                      */
  5. extern int far pascal btrcall();      /* declaration of dynamic link    */
  6. extern int far pascal DosGetMachineMode();
  7.  
  8. BTRV (operation, posblock, databuf, datalen, keybuf, keynum)
  9.   int  operation;
  10.   char posblock[];
  11.   char databuf[];
  12.   int  *datalen;
  13.   char keybuf[];
  14.   int  keynum;
  15.  
  16. {
  17.  
  18. unsigned char keylen = 255;
  19. char ckeynum = keynum;
  20. char machineMode;
  21.  
  22. DosGetMachineMode ( (char far *) &machineMode);
  23. if (machineMode)
  24.  
  25. /*                                                                      */
  26. /*  Make call to the dynamic link entry point                           */
  27. /*                                                                      */
  28.     return (btrcall (operation,
  29.                     (char far *) posblock,
  30.                     (char far *) databuf,
  31.                     (int  far *) datalen,
  32.                     (char far *) keybuf,
  33.                     keylen,
  34.                     ckeynum));
  35. else
  36.  
  37.  {
  38.  
  39.   /*         make sure this constant is not commented if
  40.                    compiling for MS windows
  41.   #define WINDOWS 1
  42.   */
  43.  
  44.   /* macros to break MS C "far" pointers into their segment and offset
  45.    * components
  46.    */
  47.  
  48.   #define FP_SEG(fp) (*((unsigned *)&(fp) + 1))
  49.   #define FP_OFF(fp) (*((unsigned *)&(fp)))
  50.  
  51.  
  52.   #define BTR_ERR     20                    /* record manager not started */
  53.   #define BTR_INT     0x7B                    /* Btrieve interrupt vector */
  54.   #define BTR2_INT    0x2F                 /* multi-user interrupt vector */
  55.   #define BTR_VECTOR  BTR_INT * 4                 /* offset for interrupt */
  56.   #define BTR_OFFSET  0x33               /* Btrieve offset within segment */
  57.   #define VARIABLE_ID 0x6176     /* id for variable length records - 'va' */
  58.   #define _2FCODE     0xAB00       /* function code for int 2F to btrieve */
  59.  
  60.   /* ProcId is used for communicating with the Multi Tasking Version of  */
  61.   /* Btrieve. It contains the process id returned from BMulti and should */
  62.   /* not be changed once it has been set.                                */
  63.   /*                                                                     */
  64.  
  65.   static unsigned ProcId = 0;             /* initialize to no process id */
  66.   static char MULTI = 0;                /* flag set to true if MultiUser */
  67.   static char VSet = 0;           /* flag set to true if checked version */
  68.  
  69.   struct REGVAL { int AX, BX, CX, DX, SI, DI, CY; } REGS;
  70.  
  71.   struct SEGREG { short ES, CS, SS, DS; } SREGS;
  72.  
  73.   struct BTRIEVE_PARMS      /* structure passed to Btrieve Record Manager */
  74.    {
  75.      char far *BUF_OFFSET;                  /* callers data buffer offset */
  76.      int   BUF_LEN;                              /* length of data buffer */
  77.      char far *CUR_OFFSET;                  /* user position block offset */
  78.      char far *FCB_OFFSET;                          /* offset of disk FCB */
  79.      int   FUNCTION;                                /* requested function */
  80.      char far *KEY_OFFSET;                 /* offset of user's key buffer */
  81.      char  KEY_LENGTH;                     /* length of user's key buffer */
  82.      char  KEY_NUMBER;                    /* key of reference for request */
  83.      int  far *STAT_OFFSET;                      /* offset of status word */
  84.      int   XFACE_ID;                               /* language identifier */
  85.    } XDATA;
  86.  
  87.   char far *fptr;
  88.   int stat = 0;                                 /* status of Btrieve call */
  89.  
  90.   segread (&SREGS);
  91.  
  92.   /*                                                                      */
  93.   /*  Check to see that the Btrieve Record Manager has been started.      */
  94.   /*                                                                      */
  95.  
  96.   if (!VSet)                   /* if we don't know version of Btrieve yet */
  97.    {
  98.     VSet = 1;
  99.     REGS.AX = 0x3000;                                /* check dos version */
  100.   #ifdef WINDOWS
  101.     int86 (0x21, ®S, ®S);
  102.   #else
  103.     int86x (0x21, ®S, ®S, &SREGS);
  104.   #endif
  105.     if ((REGS.AX & 0x00FF) >= 3)             /* if DOS version 3 or later */
  106.      {
  107.       REGS.AX = _2FCODE;
  108.   #ifdef WINDOWS
  109.       int86 (BTR2_INT, ®S, ®S);                /* is bmulti loaded? */
  110.   #else
  111.       int86x (BTR2_INT, ®S, ®S, &SREGS);
  112.   #endif
  113.       MULTI = ((REGS.AX & 0xFF) == 'M');  /* if al is M, bmulti is loaded */
  114.      }
  115.    }
  116.  
  117.   if (!MULTI)
  118.    {                                              /* if bmulti not loaded */
  119.     REGS.AX = 0x3500 + BTR_INT;
  120.   #ifdef WINDOWS
  121.     int86 (0x21, ®S, ®S);         /* check for btrieve being loaded */
  122.   #else
  123.     int86x (0x21, ®S, ®S, &SREGS);
  124.   #endif
  125.     if (REGS.BX != BTR_OFFSET)
  126.        return (BTR_ERR);
  127.    }
  128.  
  129.   /*                                                                      */
  130.   /*  Move user parameters to XDATA, the block where Btrieve expects them.*/
  131.   /*                                                                      */
  132.  
  133.   XDATA.FUNCTION    = operation;
  134.   XDATA.STAT_OFFSET = (int far *) &stat;
  135.   XDATA.FCB_OFFSET  = (char far *) posblock;
  136.   XDATA.CUR_OFFSET  = (char far *) posblock + 38;
  137.   XDATA.BUF_OFFSET  = (char far *) databuf;
  138.   XDATA.BUF_LEN     = *datalen;
  139.   XDATA.KEY_OFFSET  = (char far *) keybuf;
  140.   XDATA.KEY_LENGTH  = 255;                 /* use max since we don't know */
  141.   XDATA.KEY_NUMBER  = keynum;
  142.   XDATA.XFACE_ID    = VARIABLE_ID;
  143.  
  144.   /*                                                                      */
  145.   /*  Make call to the Btrieve Record Manager.                            */
  146.   /*                                                                      */
  147.  
  148.   fptr = (char far *) &XDATA;
  149.   REGS.DX = FP_OFF(fptr);          /* parameter block is expected to be in DX */
  150.   SREGS.DS = FP_SEG(fptr);
  151.   if (!MULTI)
  152.   #ifdef WINDOWS                    /* if bmulti not loaded, call Btrieve */
  153.     int86 (BTR_INT, ®S, ®S);
  154.   #else
  155.     int86x (BTR_INT, ®S, ®S, &SREGS);
  156.   #endif
  157.   else
  158.    {                                                       /* call bmulti */
  159.     while (1)
  160.      {
  161.       REGS.AX = 1;                     /*  assume no proc id obtained yet */
  162.       if ((REGS.BX = ProcId) != 0)                /* if we have a proc id */
  163.         REGS.AX = 2;                                  /* tell bmulti that */
  164.       REGS.AX += _2FCODE;
  165.   #ifdef WINDOWS
  166.       int86 (BTR2_INT, ®S, ®S);                      /* call bmulti */
  167.   #else
  168.       int86x (BTR2_INT, ®S, ®S, &SREGS);
  169.   #endif
  170.       if ((REGS.AX & 0x00FF) == 0) break;        /* if call was processed */
  171.   #ifndef WINDOWS                                /* by bmulti, leave loop */
  172.       REGS.AX = 0x0200;       /* if multilink advanced is loaded, it will */
  173.       int86x (0x7F, ®S, ®S, &SREGS);    /* it will switch processes */
  174.   #endif
  175.      }
  176.     if (ProcId == 0) ProcId = REGS.BX;
  177.    }
  178.  
  179.   *datalen = XDATA.BUF_LEN;
  180.   return (stat);                                         /* return status */
  181.  }
  182. }
  183.