home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a011 / 2.ddi / MSCXBTRV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-16  |  5.6 KB  |  181 lines

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