home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / cpluspls / tsr100je.zip / PROTECT.CPP < prev    next >
C/C++ Source or Header  |  1993-03-22  |  5KB  |  172 lines

  1. //--------------------------------------------------------------------------
  2. //
  3. //      PROTECT.CPP: Disk protection demo for DOS TSR class.
  4. //      (c) J.English 1993 (je@unix.brighton.ac.uk)
  5. //
  6. //      This is a very simple-minded floppy disk write protector.
  7. //      It shows how to use "startup" and "shutdown".  No hotkey
  8. //      or timeslice are needed (it's a resident interrupt handler).
  9. //      It also illustrates how a foreground program can communicate
  10. //      with a background copy using "request" and "respond".
  11. //
  12. //--------------------------------------------------------------------------
  13.  
  14. #include <iostream.h>
  15. #include <dos.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include "tsr.h"
  19.  
  20. #define CARRY   (0x01)
  21.  
  22. typedef void interrupt (*Handler)(...); // interrupt handler address type
  23.  
  24. Handler oldDisk;
  25.  
  26. //----- Error messages for TSR status values -----
  27. const char* status_msg [] = {
  28.     "success",
  29.     "DOS version 3 or higher required",
  30.     "multiple TSR instances declared in program", 
  31.     "can't allocate stack",
  32.     "can't allocate multiplex function code",
  33.     "already loaded",
  34.     "can't make program resident",
  35.     "startup error"
  36. };
  37.  
  38. //----- Error messages for unload result -----
  39. const char* unload_msg [] = {
  40.     "unloaded",
  41.     "not loaded",
  42.     "can't be unhooked",
  43.     "can't be unloaded",
  44.     "environment can't be unloaded"
  45. };
  46.  
  47. //----- The derived TSR class -----
  48. class DiskProtector : public TSR
  49. {
  50.   private:
  51.     virtual void main (int hotkey)          // body of TSR
  52.         { }
  53.     virtual int startup ();                 // TSR startup code
  54.     virtual int shutdown ();                // TSR shutdown code
  55.     virtual int respond (int, int far&, int far&);
  56.                                             // Update list of protected drives
  57.   public:
  58.     DiskProtector () :                      // constructor
  59.         TSR ("TSR write protection system")
  60.         { }
  61.     static unsigned drives;                 // Bit mask for drives
  62. };
  63.  
  64. unsigned DiskProtector::drives = 0;
  65.  
  66. //----- The main program -----
  67. int main (int argc, char** argv)
  68. {
  69.     DiskProtector protect;                  // create TSR instance
  70.  
  71.     if (argc == 1)
  72.     {
  73.         cout << "Installing " << protect.name() << "\n";
  74.         protect.run (TSR::NONE);
  75.         cout << "Error installing " << protect.name() << ": "
  76.              << status_msg [protect.status()] << "\n";
  77.         return protect.status ();
  78.     }
  79.     else if (argc == 2)
  80.     {
  81.         if (!protect.loaded ())
  82.         {   cout << protect.name() << " is not loaded\n";
  83.             return TSR::NOT_LOADED;
  84.         }
  85.  
  86.         char drive = toupper (argv[1][0]);
  87.         if (drive == 'A' || drive == 'B')
  88.         {   int list = drive;
  89.             int x = 0;
  90.             int res = protect.request (x, list, x);
  91.             if (res == TSR::SUCCESS)
  92.             {   cout << "Drives protected: "
  93.                      << (list == 0 ? "none" :
  94.                          list == 1 ? "A"    :
  95.                          list == 2 ? "B"    :
  96.                                      "A,B") << "\n";
  97.             }
  98.             else
  99.                 cout << "Couldn't change protection status for drive "
  100.                      << drive << ":\n";
  101.             return protect.status ();
  102.         }
  103.         else if (argv[1][0] == '/' && toupper (argv[1][1]) == 'U')
  104.         {   cout << protect.name() << " "
  105.                  << unload_msg [protect.unload()] << "\n";
  106.             return protect.status ();
  107.         }
  108.     }
  109.     cout << "Usage: Load using \"PROTECT\"\n"
  110.             "  Change protection for a floppy drive using \"PROTECT drive\"\n"
  111.             "  Unload using \"PROTECT /U\"\n";
  112.     return protect.status ();
  113. }
  114.  
  115. //----- Disk interrupt handler -----
  116. void interrupt newDisk (unsigned, unsigned, unsigned,
  117.                         unsigned, unsigned, unsigned dx,
  118.                         unsigned, unsigned, unsigned ax,
  119.                         unsigned, unsigned, unsigned flags)
  120. {
  121.     int d = dx & 0xFF;                              // drive code
  122.     switch (ax >> 8)
  123.     {
  124.       case 0x03: case 0x05: case 0x06: case 0x07:   // calls involving writes
  125.       case 0x0B: case 0x0F: case 0x0A:
  126.         if (d != 0 && d != 1)
  127.             _chain_intr (oldDisk);
  128.         if (DiskProtector::drives & (1 << d))
  129.         {   ax = 0x0300;                            // "write protect" code
  130.             flags |= CARRY;                         // error status
  131.             return;
  132.         }
  133.       default:
  134.         _chain_intr (oldDisk);
  135.     }
  136. }
  137.  
  138. //----- Startup and shutdown of TSR -----
  139. int DiskProtector::startup ()
  140. {
  141.     // hook disk interrupt
  142.     oldDisk = getvect (0x13);
  143.     setvect (0x13, Handler (newDisk));
  144.  
  145.     // chain to base class startup
  146.     return TSR::startup ();
  147. }
  148.  
  149. int DiskProtector::shutdown ()
  150. {
  151.     // fail if disk interrupt re-hooked
  152.     if (getvect (0x13) != Handler (newDisk))
  153.         return 1;
  154.     
  155.     // unhook disk interrupt
  156.     setvect (0x13, oldDisk);
  157.  
  158.     // chain to base class shutdown
  159.     return TSR::shutdown ();
  160. }
  161.  
  162. //----- Update list of protected drives -----
  163. int DiskProtector::respond (int f, int far& d, int far&)
  164. {
  165.     if (f == 0 && (d == 'A' || d == 'B'))
  166.     {   drives ^= 1 << (d - 'A');
  167.         d = drives;
  168.         return 1;
  169.     }
  170.     return 0;
  171. }
  172.