home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / disk / Devs+Handler / RawDiskHandler / RawDisk.c < prev   
C/C++ Source or Header  |  1994-02-12  |  16KB  |  305 lines

  1. /* RawDisk-Handler V1.1
  2.    © 1993 Christian Stieber
  3.    stieber@informatik.tu-muenchen.de
  4.    freely distributable */
  5.  
  6. #ifndef EXEC_ALERTS_H
  7. #include <exec/alerts.h>
  8. #endif
  9.  
  10. #ifndef DOS_FILEHANDLER_H
  11. #include <dos/filehandler.h>
  12. #endif
  13.  
  14. #ifndef DEVICES_TRACKDISK_H
  15. #include <devices/trackdisk.h>
  16. #endif
  17.  
  18. #include <string.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22.  
  23. /***********************************************/
  24.  
  25. struct MyFileHandle
  26.    {
  27.       long FilePos;
  28.    };
  29.  
  30. static char Version[]="$VER: RawDisk-Handler 1.1 (13.01.94) © Christian Stieber (stieber@informatik.tu-muenchen.de); freely distributable";
  31.  
  32. /***********************************************/
  33.  
  34. long MyDoIO(struct IOExtTD *IORequest)
  35.  
  36. {
  37.    long Error;
  38.  
  39.    Error=DoIO(IORequest);
  40.    switch(Error)
  41.       {
  42.          case TDERR_WriteProt:   return ERROR_DISK_WRITE_PROTECTED;
  43.          case TDERR_DiskChanged: return ERROR_NO_DISK;
  44.          case TDERR_NoMem:       return ERROR_NO_FREE_STORE;
  45.          case 0:                 return 0;
  46.          default:                return ABORT_DISK_ERROR;
  47.       }
  48. }
  49.  
  50. /***********************************************/
  51.  
  52. void __saveds RawDisk(void)
  53.  
  54. {
  55.    struct DosLibrary *DOSBase;
  56.    struct DosPacket *Packet;
  57.    struct DeviceNode *DeviceNode;
  58.    ULONG OpenCnt;
  59.    int Quit;
  60.    struct IOExtTD IORequest;
  61.    struct DriveGeometry DriveGeometry;
  62.    UBYTE *Buffer;
  63.  
  64.    if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)))
  65.       {
  66.          Alert(AT_DeadEnd | AG_OpenLib | AO_DOSLib);
  67.       }
  68.    IORequest.iotd_Req.io_Message.mn_ReplyPort=&((struct Process *)FindTask(NULL))->pr_MsgPort;
  69.  
  70.    Packet=WaitPkt();
  71.    DeviceNode=BADDR(Packet->dp_Arg3);
  72.  
  73.    DeviceNode->dn_Task=IORequest.iotd_Req.io_Message.mn_ReplyPort;
  74.  
  75.    {
  76.       struct FileSysStartupMsg *FileSysStartupMsg;
  77.       struct DosEnvec *DosEnvec;
  78.  
  79.       FileSysStartupMsg=BADDR(DeviceNode->dn_Startup);
  80.       DosEnvec=BADDR(FileSysStartupMsg->fssm_Environ);
  81.       DriveGeometry.dg_TotalSectors=DosEnvec->de_BlocksPerTrack*DosEnvec->de_Surfaces*(DosEnvec->de_HighCyl-DosEnvec->de_LowCyl+1);
  82.       DriveGeometry.dg_SectorSize=DosEnvec->de_SizeBlock*4;
  83.       if (OpenDevice(((char *)BADDR(FileSysStartupMsg->fssm_Device))+1,FileSysStartupMsg->fssm_Unit,&IORequest,FileSysStartupMsg->fssm_Flags))
  84.          {
  85.             ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_NOT_FOUND);
  86.             Quit=TRUE;
  87.          }
  88.       else
  89.          {
  90.             ReplyPkt(Packet,DOSTRUE,0);
  91.             Quit=FALSE;
  92.          }
  93.    }
  94.  
  95.    OpenCnt=0;
  96.    while (!Quit)
  97.       {
  98.          Packet=WaitPkt();
  99.          switch(Packet->dp_Type)
  100.             {
  101.                case ACTION_FINDUPDATE:
  102.                case ACTION_FINDINPUT:
  103.                case ACTION_FINDOUTPUT:      {
  104.                                                struct FileHandle *FileHandle;
  105.                                                struct MyFileHandle *MyFileHandle;
  106.  
  107.                                                if (!OpenCnt)
  108.                                                   {
  109.                                                      long Error;
  110.                                                      IORequest.iotd_Req.io_Command=TD_GETGEOMETRY;
  111.                                                      IORequest.iotd_Req.io_Data=&DriveGeometry;
  112.                                                      IORequest.iotd_Req.io_Length=sizeof(struct DriveGeometry);
  113.                                                      if (Error=MyDoIO(&IORequest))
  114.                                                         {
  115.                                                            ReplyPkt(Packet,DOSFALSE,Error);
  116.                                                         }
  117.                                                      if (!(Buffer=AllocMem(DriveGeometry.dg_SectorSize,0))) goto OutOfMem;
  118.                                                   }
  119.  
  120.                                                if (MyFileHandle=AllocMem(sizeof(struct MyFileHandle),0))
  121.                                                   {
  122.                                                      FileHandle=BADDR(Packet->dp_Arg1);
  123.                                                      MyFileHandle->FilePos=0;
  124.                                                      FileHandle->fh_Arg1=(long)MyFileHandle;
  125.                                                      OpenCnt++;
  126.                                                      ReplyPkt(Packet,DOSTRUE,0);
  127.                                                   }
  128.                                                else
  129.                                                   {
  130. OutOfMem:                                            ReplyPkt(Packet,DOSFALSE,ERROR_NO_FREE_STORE);
  131.                                                   }
  132.                                             }
  133.                                             break;
  134.  
  135.                case ACTION_READ:            {
  136.                                                struct MyFileHandle *MyFileHandle;
  137.                                                long Length;
  138.                                                UBYTE *Destination;
  139.                                                long Error;
  140.  
  141.                                                MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
  142.                                                Destination=(UBYTE *)Packet->dp_Arg2;
  143.                                                Length=Packet->dp_Arg3;
  144.                                                Error=0;
  145.  
  146.                                                while (!Error && Length && (MyFileHandle->FilePos!=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize))
  147.                                                   {
  148.                                                      int Size;
  149.                                                      int BufferPos;
  150.                                                      BufferPos=MyFileHandle->FilePos % DriveGeometry.dg_SectorSize;
  151.                                                      IORequest.iotd_Req.io_Command=CMD_READ;
  152.                                                      IORequest.iotd_Req.io_Data=Buffer;
  153.                                                      IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
  154.                                                      IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
  155.                                                      if (!(Error=MyDoIO(&IORequest)))
  156.                                                         {
  157.                                                            Size=DriveGeometry.dg_SectorSize-BufferPos;
  158.                                                            if (Length<Size) Size=Length;
  159.                                                            memcpy(Destination,Buffer+BufferPos,Size);
  160.                                                            Length-=Size;
  161.                                                            Destination+=Size;
  162.                                                            MyFileHandle->FilePos+=Size;
  163.                                                         }
  164.                                                   }
  165.                                                ReplyPkt(Packet,Error ? -1 : Packet->dp_Arg3-Length,Error);
  166.                                             }
  167.                                             break;
  168.  
  169.                case ACTION_WRITE:           {
  170.                                                struct MyFileHandle *MyFileHandle;
  171.                                                long Length;
  172.                                                UBYTE *Source;
  173.                                                long Error;
  174.  
  175.                                                MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
  176.                                                Source=(UBYTE *)Packet->dp_Arg2;
  177.                                                Length=Packet->dp_Arg3;
  178.                                                Error=0;
  179.  
  180.                                                while (Length)
  181.                                                   {
  182.                                                      if (MyFileHandle->FilePos!=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize)
  183.                                                         {
  184.                                                            int Size;
  185.                                                            int BufferPos;
  186.                                                            BufferPos=MyFileHandle->FilePos % DriveGeometry.dg_SectorSize;
  187.                                                            if (BufferPos || Length<DriveGeometry.dg_SectorSize)
  188.                                                               {
  189.                                                                  IORequest.iotd_Req.io_Command=CMD_READ;
  190.                                                                  IORequest.iotd_Req.io_Data=Buffer;
  191.                                                                  IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
  192.                                                                  IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
  193.                                                                  if (Error=MyDoIO(&IORequest))
  194.                                                                     {
  195.                                                                        break;
  196.                                                                     }
  197.                                                               }
  198.                                                            Size=DriveGeometry.dg_SectorSize-BufferPos;
  199.                                                            if (Length<Size) Size=Length;
  200.                                                            memcpy(Buffer+BufferPos,Source,Size);
  201.                                                            IORequest.iotd_Req.io_Command=CMD_WRITE;
  202.                                                            IORequest.iotd_Req.io_Data=Buffer;
  203.                                                            IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
  204.                                                            IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
  205.                                                            if (Error=MyDoIO(&IORequest))
  206.                                                               {
  207.                                                                  break;
  208.                                                               }
  209.                                                            Length-=Size;
  210.                                                            Source+=Size;
  211.                                                            MyFileHandle->FilePos+=Size;
  212.                                                         }
  213.                                                      else
  214.                                                         {
  215.                                                            if (!(Packet->dp_Arg3-Length))
  216.                                                               {
  217.                                                                  Error=ERROR_DISK_FULL;
  218.                                                               }
  219.                                                            break;
  220.                                                         }
  221.                                                   }
  222.                                                ReplyPkt(Packet,Error ? -1 : Packet->dp_Arg3-Length,Error);
  223.                                             }
  224.                                             break;
  225.  
  226.                case ACTION_SEEK:            {
  227.                                                struct MyFileHandle *MyFileHandle;
  228.                                                long NewFilePos;
  229.  
  230.                                                NewFilePos=-1;
  231.                                                MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
  232.                                                switch(Packet->dp_Arg3)
  233.                                                   {
  234.                                                      case OFFSET_BEGINNING: NewFilePos=Packet->dp_Arg2;
  235.                                                                             break;
  236.                                                      case OFFSET_CURRENT:   NewFilePos=MyFileHandle->FilePos+Packet->dp_Arg2;
  237.                                                                             break;
  238.                                                      case OFFSET_END:       NewFilePos=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize-Packet->dp_Arg2;
  239.                                                                             break;
  240.                                                   }
  241.                                                if (NewFilePos<0 || NewFilePos>DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize)
  242.                                                   {
  243.                                                      ReplyPkt(Packet,-1,ERROR_SEEK_ERROR);
  244.                                                   }
  245.                                                else
  246.                                                   {
  247.                                                      long OldPos=MyFileHandle->FilePos;
  248.                                                      MyFileHandle->FilePos=NewFilePos;
  249.                                                      ReplyPkt(Packet,OldPos,0);
  250.                                                   }
  251.                                             }
  252.                                             break;
  253.  
  254.                case ACTION_END:             {
  255.                                                long Error;
  256.  
  257.                                                Error=0;
  258.                                                FreeMem((struct MyFileHandle *)Packet->dp_Arg1,sizeof(struct MyFileHandle));
  259.                                                if (!--OpenCnt)
  260.                                                   {
  261.                                                      IORequest.iotd_Req.io_Command=CMD_UPDATE;
  262.                                                      Error=MyDoIO(&IORequest);
  263.                                                      IORequest.iotd_Req.io_Command=TD_MOTOR;
  264.                                                      IORequest.iotd_Req.io_Length=0;
  265.                                                      DoIO(&IORequest);
  266.                                                      FreeMem(Buffer,DriveGeometry.dg_SectorSize);
  267.                                                   }
  268.                                                ReplyPkt(Packet,Error ? DOSTRUE : DOSFALSE,Error);
  269.                                             }
  270.                                             break;
  271.  
  272.                case ACTION_DIE:             if (!OpenCnt)
  273.                                                {
  274.                                                   Forbid();
  275.                                                   ReplyPkt(Packet,DOSTRUE,0);
  276.                                                   while (!IsMsgPortEmpty(IORequest.iotd_Req.io_Message.mn_ReplyPort))
  277.                                                      {
  278.                                                         ReplyPkt(WaitPkt(),DOSFALSE,ERROR_OBJECT_NOT_FOUND);
  279.                                                      }
  280.                                                   Quit=TRUE;
  281.                                                }
  282.                                             else
  283.                                                {
  284.                                                   ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
  285.                                                }
  286.                                             break;
  287.  
  288.                default:                     {
  289.                                                ReplyPkt(Packet,DOSFALSE,ERROR_ACTION_NOT_KNOWN);
  290.                                             }
  291.                                             break;
  292.             }
  293.       }
  294.  
  295.    {
  296.       BPTR SegList;
  297.       SegList=DeviceNode->dn_SegList;
  298.       DeviceNode->dn_Task=NULL;
  299.       DeviceNode->dn_SegList=NULL;
  300.       CloseDevice(&IORequest);
  301.       UnLoadSeg(DeviceNode->dn_SegList);
  302.       CloseLibrary((struct Library *)DOSBase);
  303.    }
  304. }
  305.