Close Back

/*       CODE TO OPEN THE DOOR.   */

# include "dos.h"
# include "stdio.h"
# include "ctype.h"
# include "conio.h"


struct IoctlOutputDataBlockHeader
   {
   unsigned char commandCode;
   };



void initializeIoctlOutputDataBlockHeader(
   struct IoctlOutputDataBlockHeader* i, unsigned char
code)
   {
   i->commandCode = code;
   }



enum IoctlOutputCodes
   {
   EJECT_DISK            = 0,
   LOCK_UNLOCK_DOOR      = 1,
   RESET_DRIVE           = 2,
   AUDIO_CHANNEL_CONTROL = 3,
   CLOSE_TRAY            = 5
   };

struct RequestHeader
   {
   unsigned char length;
   unsigned char unit;
   unsigned char commandCode;
   unsigned int  status;
   unsigned char unused[ 8 ];
   };


struct IoctlOutputHeader
   {
   struct RequestHeader base;
   unsigned char        mediaDescriptor;
   void far*            transferAddress;
   unsigned int         byteCount;
   unsigned int         sectorNumber;
   void far*            volumeIdPtr;
   };

enum CommandCodes
   {
   INIT               =   0,
   IOCTL_INPUT        =   3,
   INPUT_FLUSH        =   7,
   OUTPUT_FLUSH       =  11,
   IOCTL_OUTPUT       =  12,
   DEVICE_OPEN        =  13,
   DEVICE_CLOSE       =  14,
   READ_LONG          = 128,
   READ_LONG_PREFETCH = 130,
   SEEK               = 131,
   PLAY_AUDIO         = 132,
   STOP_AUDIO         = 133,
   WRITE_LONG         = 134,
   WRITE_LONG_VERIFY  = 135,
   RESUME_AUDIO       = 136
   };

void initializeRequestHeader(struct RequestHeader*
r,
   unsigned int length, unsigned char subunit, enum
CommandCodes code)
   {
   r->length = length;
   r->unit = subunit;
   r->commandCode = code;
   r->status = 0; // not necessary, but sets status to a known value
   }




void initializeIoctlOutputHeader(struct
IoctlOutputHeader* i,
   void far* data, unsigned int dataLength, unsigned
char subunit)
   {
   initializeRequestHeader(&i->base, sizeof(struct
IoctlOutputHeader), subunit, IOCTL_OUTPUT);
   i->mediaDescriptor = 0;
   i->transferAddress = data;
   i->byteCount = dataLength;
   i->sectorNumber = 0;
   i->volumeIdPtr = (void far*)0;
   }




void callDevice(char drive, void* data)
   {
   struct SREGS s;
   union REGS   r;

   s.es = FP_SEG(data);
   r.x.bx = FP_OFF(data);
   r.x.ax = 0x1510;
   if (isupper(drive))
      {
      r.x.cx = drive - 'A';
      }
   else if (islower(drive))
      {
      r.x.cx = drive - 'a';
      }
   else
      {
      r.x.cx = (unsigned char)drive;
      }
   int86x(0x2F, &r, &r, &s);
   }



unsigned int getStatus(struct RequestHeader* r)
   {
   return r->status;
   }




char* getErrorCode(unsigned int status)
   {
   char* result = 0;
   if (status & 0x8000)
      {
      switch (status & 0x00FF)
{
case 0:
    result = "write-protect violation";
    break;
case 1:
    result = "unknown unit";
    break;
case 2:
    result = "drive not ready";
    break;
case 3:
    result = "unknown command";
    break;
case 4:
    result = "CRC error";
    break;
case 5:
    result = "bad drive request structure length";
    break;
case 6:
    result = "seek error";
    break;
case 7:
    result = "unknown media";
    break;
case 8:
    result = "sector not found";
    break;
case 9:
    result = "printer out of paper";
    break;
case 10:
    result = "write fault";
    break;
case 11:
    result = "read fault";
    break;
case 12:
    result = "general failure";
    break;
case 14:
    result = "media unavailable";
    break;
case 15:
    result = "invalid disk change";
    break;
default:
    result = "undocumented error code";
    break;
}
      }
   return result;
   }





int isBusy(unsigned int status)
   {
   return (status & 0x0200) ? 1 : 0;
   }


struct Eject
   {
   struct IoctlOutputDataBlockHeader base;
   };

void initializeEject(struct Eject* e)
   {
   initializeIoctlOutputDataBlockHeader(&(e->base),
EJECT_DISK);
   }

int eject(char drive, unsigned char subunit)
   {
   struct Eject             e;
   struct IoctlOutputHeader i;
   unsigned int             status;
   char*                    error;

   initializeEject(&e);
   initializeIoctlOutputHeader(&i, (void far*)&e,
sizeof(struct Eject), subunit);
   callDevice(drive, (void far*)&i);
   status = getStatus(&i.base);
   error = getErrorCode(status);
   if (error)
      {
      printf("Error ejecting disk: %s\n", error);
      return 0;
      }
   if (isBusy(status))
      {
      printf("Device busy\n");
      return 0;
      }
   return 1;
   }
void main()
{
struct Eject e;
clrscr();
initializeEject(&e);
eject('g',3);

}