home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / docum / dos-ref.doc / examples / chap5.arj / DOSSWAP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-31  |  5.4 KB  |  179 lines

  1. /* DOSSWAP.C - Functions to manage DOS swap areas */
  2.  
  3. #include <stdlib.h>
  4. #include <dos.h>
  5. #include <memory.h>
  6. #include "tsr.h"
  7.  
  8. #define GET_DOSSWAP3       0x5d06
  9. #define GET_DOSSWAP4       0x5d0b
  10.  
  11. #define SWAP_LIST_LIMIT    20     
  12.  
  13. struct  swap_list    /* format of DOS 4+ SDA list */
  14. {
  15.     void    far*    swap_ptr;
  16.             int     swap_size;
  17. };
  18.  
  19. /* variables for 3.x swap work */
  20. static   char  far *  swap_ptr;  /* pointer to dos swap area */
  21. static   char  far *  swap_save; /* pointer to our local save area */
  22. static   int   swap_size_indos;
  23. static   int   swap_size_always;
  24. static   int   size;
  25.  
  26. /* variables for 4.x swap work */
  27. static int swap_count;      /* count of swappable areas */
  28. static struct swap_list swp_list[SWAP_LIST_LIMIT]; /*list of swap areas*/
  29. static char far *swp_save[SWAP_LIST_LIMIT];   /* out save area */
  30. static int swp_flag[SWAP_LIST_LIMIT];   /* flags if has been swapped */
  31.  
  32. static int dos_level;    /* for level dependent code */
  33. int dos_critical;       /* in critical section, can't swap */
  34.  
  35. /*****
  36. Function: InitDosSwap
  37. Initialize pointers and sizes of DOS swap area. Return zero if success
  38. *****/
  39. int InitDosSwap(void)
  40.     union  REGS regs;
  41.     struct SREGS segregs;
  42.  
  43.     if ((_osmajor == 3) && (_osminor >= 10))
  44.         dos_level = 3;
  45.     else if (_osmajor >= 4)
  46.         dos_level = 4;
  47.     else
  48.         dos_level = 0;
  49.     
  50.     if (dos_level == 3)    /* use 215D06 */
  51.     {
  52.         regs.x.ax = GET_DOSSWAP3;   
  53.         intdosx(®s,®s,&segregs);
  54.         /* pointer to swap area is returned in DS:SI */
  55.         FP_SEG(swap_ptr) = segregs.ds;
  56.         FP_OFF(swap_ptr) = regs.x.si;
  57.    
  58.         swap_size_indos = regs.x.cx;
  59.         swap_size_always= regs.x.dx;
  60.  
  61.         size = 0;  /* initialize for later */
  62.         return ((swap_save = malloc(swap_size_indos)) == 0);
  63.     }
  64.     else if (dos_level == 4)  /* use 5d0b */
  65.     {
  66.         struct swap_list far *ptr;
  67.         int far *iptr;
  68.         int i;
  69.         regs.x.ax = GET_DOSSWAP3;             // was 4   
  70.         intdosx(®s,®s,&segregs);
  71.         /* pointer to swap list is returned in DS:SI */
  72.         FP_SEG(iptr) = segregs.ds;
  73.         FP_OFF(iptr) = regs.x.si;
  74.         swap_count = *iptr;                   /* get size of list */
  75.         iptr++;
  76.         ptr = (struct swap_list far *) iptr;  /* create point to list */
  77.  
  78.         if (swap_count > SWAP_LIST_LIMIT)     /* too many data areas */
  79.             return 2;
  80.  
  81.         /* get pointers and sizes of data areas */
  82.         for (i = 0; i < swap_count; i++)
  83.         {
  84.             swp_list[i].swap_ptr = ptr->swap_ptr;
  85.             swp_list[i].swap_size= ptr->swap_size;
  86.             if (! (swp_save[i] = malloc(swp_list[i].swap_size & 0x7fff)))
  87.                 return 3;   /* out of memory */
  88.             swp_flag[i] = 0;
  89.             ptr++;   /* point to next entry in the list */
  90.         }
  91.         return 0;
  92.     }
  93.     else
  94.         return 1;   /* unsupported DOS */
  95. }
  96.  
  97. /*****
  98. Function: SaveDosSwap
  99. This function will save the dos swap area to a local buffer
  100. It returns zero on success, non-zero meaning can't swap 
  101. *****/ 
  102. int SaveDosSwap(void)
  103. {
  104.     if (dos_level == 3)
  105.     {
  106.         if (swap_ptr && !dos_critical)   
  107.         {
  108.             /* if INDOS flag is zero, use smaller swap size */
  109.             size = (*indos_ptr) ? swap_size_indos : swap_size_always;
  110.               
  111.             movedata(FP_SEG(swap_ptr),  FP_OFF(swap_ptr), 
  112.                      FP_SEG(swap_save), FP_OFF(swap_save),
  113.                      size);
  114.         }
  115.         else       /* can't swap it */
  116.             return 1;
  117.     }
  118.     else if (dos_level == 4)
  119.     {
  120.         /* loop through pointer list and swap appropriate items */
  121.         int i;
  122.         for (i = 0; i < swap_count; i++)
  123.         {
  124.             if (swp_list[i].swap_size & 0x8000)  /* swap always */
  125.             {
  126.                 movedata(FP_SEG(swp_list[i].swap_ptr), 
  127.                          FP_OFF(swp_list[i].swap_ptr),
  128.                          FP_SEG(swp_save[i]),          
  129.                          FP_OFF(swp_save[i]),
  130.                          swp_list[i].swap_size & 0x7fff);
  131.             }
  132.             else if (*indos_ptr)     /* swap only if dos busy */
  133.             {
  134.                 movedata(FP_SEG(swp_list[i].swap_ptr), 
  135.                          FP_OFF(swp_list[i].swap_ptr),
  136.                          FP_SEG(swp_save[i]),          
  137.                          FP_OFF(swp_save[i]),
  138.                          swp_list[i].swap_size);
  139.             }
  140.         }
  141.     }
  142.     else 
  143.         return 1;
  144.    
  145.     return 0;
  146. }
  147.  
  148. /*****
  149. Function: RestoreDosSwap
  150. This function will restore a previously swapped dos data area
  151. *****/
  152. void RestoreDosSwap(void)
  153. {
  154.     if (dos_level == 3)
  155.     {
  156.         /* make sure its already saved and we have a good ptr */
  157.         if (size && swap_ptr)
  158.         {
  159.             movedata(FP_SEG(swap_save), FP_OFF(swap_save), 
  160.                      FP_SEG(swap_ptr),  FP_OFF(swap_ptr), size);
  161.             size = 0;
  162.         }
  163.     }
  164.     else if (dos_level == 4)
  165.     {
  166.         int i;
  167.         for (i = 0; i < swap_count; i++)
  168.         {
  169.             movedata(FP_SEG(swp_save[i]),          
  170.                      FP_OFF(swp_save[i]),
  171.                      FP_SEG(swp_list[i].swap_ptr), 
  172.                      FP_OFF(swp_list[i].swap_ptr),
  173.                      swp_list[i].swap_size);
  174.            swp_flag[i] = 0;   /* clear flag */
  175.         }
  176.     }
  177. }   
  178.