home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
cpluspls
/
tsr100je.zip
/
PROTECT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-22
|
5KB
|
172 lines
//--------------------------------------------------------------------------
//
// PROTECT.CPP: Disk protection demo for DOS TSR class.
// (c) J.English 1993 (je@unix.brighton.ac.uk)
//
// This is a very simple-minded floppy disk write protector.
// It shows how to use "startup" and "shutdown". No hotkey
// or timeslice are needed (it's a resident interrupt handler).
// It also illustrates how a foreground program can communicate
// with a background copy using "request" and "respond".
//
//--------------------------------------------------------------------------
#include <iostream.h>
#include <dos.h>
#include <ctype.h>
#include <string.h>
#include "tsr.h"
#define CARRY (0x01)
typedef void interrupt (*Handler)(...); // interrupt handler address type
Handler oldDisk;
//----- Error messages for TSR status values -----
const char* status_msg [] = {
"success",
"DOS version 3 or higher required",
"multiple TSR instances declared in program",
"can't allocate stack",
"can't allocate multiplex function code",
"already loaded",
"can't make program resident",
"startup error"
};
//----- Error messages for unload result -----
const char* unload_msg [] = {
"unloaded",
"not loaded",
"can't be unhooked",
"can't be unloaded",
"environment can't be unloaded"
};
//----- The derived TSR class -----
class DiskProtector : public TSR
{
private:
virtual void main (int hotkey) // body of TSR
{ }
virtual int startup (); // TSR startup code
virtual int shutdown (); // TSR shutdown code
virtual int respond (int, int far&, int far&);
// Update list of protected drives
public:
DiskProtector () : // constructor
TSR ("TSR write protection system")
{ }
static unsigned drives; // Bit mask for drives
};
unsigned DiskProtector::drives = 0;
//----- The main program -----
int main (int argc, char** argv)
{
DiskProtector protect; // create TSR instance
if (argc == 1)
{
cout << "Installing " << protect.name() << "\n";
protect.run (TSR::NONE);
cout << "Error installing " << protect.name() << ": "
<< status_msg [protect.status()] << "\n";
return protect.status ();
}
else if (argc == 2)
{
if (!protect.loaded ())
{ cout << protect.name() << " is not loaded\n";
return TSR::NOT_LOADED;
}
char drive = toupper (argv[1][0]);
if (drive == 'A' || drive == 'B')
{ int list = drive;
int x = 0;
int res = protect.request (x, list, x);
if (res == TSR::SUCCESS)
{ cout << "Drives protected: "
<< (list == 0 ? "none" :
list == 1 ? "A" :
list == 2 ? "B" :
"A,B") << "\n";
}
else
cout << "Couldn't change protection status for drive "
<< drive << ":\n";
return protect.status ();
}
else if (argv[1][0] == '/' && toupper (argv[1][1]) == 'U')
{ cout << protect.name() << " "
<< unload_msg [protect.unload()] << "\n";
return protect.status ();
}
}
cout << "Usage: Load using \"PROTECT\"\n"
" Change protection for a floppy drive using \"PROTECT drive\"\n"
" Unload using \"PROTECT /U\"\n";
return protect.status ();
}
//----- Disk interrupt handler -----
void interrupt newDisk (unsigned, unsigned, unsigned,
unsigned, unsigned, unsigned dx,
unsigned, unsigned, unsigned ax,
unsigned, unsigned, unsigned flags)
{
int d = dx & 0xFF; // drive code
switch (ax >> 8)
{
case 0x03: case 0x05: case 0x06: case 0x07: // calls involving writes
case 0x0B: case 0x0F: case 0x0A:
if (d != 0 && d != 1)
_chain_intr (oldDisk);
if (DiskProtector::drives & (1 << d))
{ ax = 0x0300; // "write protect" code
flags |= CARRY; // error status
return;
}
default:
_chain_intr (oldDisk);
}
}
//----- Startup and shutdown of TSR -----
int DiskProtector::startup ()
{
// hook disk interrupt
oldDisk = getvect (0x13);
setvect (0x13, Handler (newDisk));
// chain to base class startup
return TSR::startup ();
}
int DiskProtector::shutdown ()
{
// fail if disk interrupt re-hooked
if (getvect (0x13) != Handler (newDisk))
return 1;
// unhook disk interrupt
setvect (0x13, oldDisk);
// chain to base class shutdown
return TSR::shutdown ();
}
//----- Update list of protected drives -----
int DiskProtector::respond (int f, int far& d, int far&)
{
if (f == 0 && (d == 'A' || d == 'B'))
{ drives ^= 1 << (d - 'A');
d = drives;
return 1;
}
return 0;
}