home *** CD-ROM | disk | FTP | other *** search
-
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <devices/trackdisk.h>
- #include <dos/dosextens.h>
- #include <dos/filehandler.h>
-
- #define __USE_SYSBASE 42
-
- #include <proto/exec.h>
-
- #include <string.h>
-
- struct DosPacket *WaitDosPacket(void);
- void __regargs ReplyDosPacket(struct DosPacket *,LONG,LONG);
-
- void __regargs OpenDH(struct DosPacket *,ULONG *);
- void __regargs CloseDH(struct DHHandle *,ULONG *);
-
- LONG __regargs RawRead(struct DHHandle *,UBYTE *,LONG);
- LONG __regargs RawWrite(struct DHHandle *,UBYTE *,LONG);
-
- struct ExecBase *SysBase;
-
- struct DHHandle
- {
- struct IOStdReq *rh_IO;
- struct DriveGeometry rh_DG;
- ULONG rh_Len,rh_Pos,rh_Left;
- UBYTE *rh_Buffer,*rh_Ptr;
- BOOL rh_Write;
- };
-
- #define BCPL_MAX_LEN 256
- #define MIN __builtin_min
-
- char *Version = "$VER: Device-Handler 1.0 "__AMIGADATE__;
-
- LONG __saveds DeviceHandler(void)
-
- {
- struct Process *MyProc;
- struct DosPacket *Pkt;
- struct DeviceNode *DeviceNode;
- BOOL Done;
- ULONG OpenCnt;
-
- SysBase=*(struct ExecBase **)4L;
- if ((MyProc=(struct Process *)SysBase->ThisTask)->pr_CLI) return 20L;
-
- Pkt=WaitDosPacket();
- DeviceNode=(struct DeviceNode *)BADDR(Pkt->dp_Arg3);
- if (SysBase->LibNode.lib_Version<37)
- {
- ReplyDosPacket (Pkt,DOSFALSE,0L);
- return 0L;
- }
-
- DeviceNode->dn_Task=&MyProc->pr_MsgPort;
- ReplyDosPacket (Pkt,DOSTRUE,Pkt->dp_Res2);
-
- Done=FALSE;
- OpenCnt=0L;
-
- while (!Done)
- {
- Pkt=WaitDosPacket();
-
- switch (Pkt->dp_Type)
- {
- case ACTION_FINDINPUT:
- OpenDH (Pkt,&OpenCnt);
- ReplyDosPacket (Pkt,Pkt->dp_Res1,Pkt->dp_Res2);
- break;
- case ACTION_FINDOUTPUT:
- OpenDH (Pkt,&OpenCnt);
- ReplyDosPacket (Pkt,Pkt->dp_Res1,Pkt->dp_Res2);
- break;
- case ACTION_END:
- CloseDH ((struct DHHandle *)Pkt->dp_Arg1,&OpenCnt);
- ReplyDosPacket (Pkt,DOSTRUE,0L);
- break;
- case ACTION_READ:
- if (!((struct DHHandle *)Pkt->dp_Arg1)->rh_Write)
- {
- LONG Bytes;
-
- Bytes=RawRead((struct DHHandle *)Pkt->dp_Arg1,(UBYTE *)Pkt->dp_Arg2,Pkt->dp_Arg3);
- if (Bytes<0L) ReplyDosPacket (Pkt,-1L,ERROR_SEEK_ERROR);
- else ReplyDosPacket (Pkt,Bytes,0L);
- }
- else ReplyDosPacket (Pkt,-1L,ERROR_OBJECT_WRONG_TYPE);
- break;
- case ACTION_WRITE:
- if (((struct DHHandle *)Pkt->dp_Arg1)->rh_Write)
- {
- LONG Bytes;
-
- Bytes=RawWrite((struct DHHandle *)Pkt->dp_Arg1,(UBYTE *)Pkt->dp_Arg2,Pkt->dp_Arg3);
- if (Bytes<0L) ReplyDosPacket (Pkt,-1L,ERROR_SEEK_ERROR);
- else ReplyDosPacket (Pkt,Bytes,0L);
- }
- else ReplyDosPacket (Pkt,-1L,ERROR_OBJECT_WRONG_TYPE);
- break;
- case ACTION_IS_FILESYSTEM:
- ReplyDosPacket (Pkt,DOSFALSE,0L);
- break;
- default:
- ReplyDosPacket (Pkt,DOSFALSE,ERROR_ACTION_NOT_KNOWN);
- }
-
- if (OpenCnt==0L)
- {
- Disable();
- if (MyProc->pr_MsgPort.mp_MsgList.lh_Head->ln_Succ==NULL)
- {
- DeviceNode->dn_Task=NULL;
- Done=TRUE;
- }
- Enable();
- }
- }
-
- return 0L;
- }
-
- struct DosPacket *WaitDosPacket(void)
-
- {
- struct Process *MyProc;
-
- MyProc=(struct Process *)SysBase->ThisTask;
- (void)WaitPort(&MyProc->pr_MsgPort);
- return (struct DosPacket *)GetMsg(&MyProc->pr_MsgPort)->mn_Node.ln_Name;
- }
-
- void __regargs ReplyDosPacket(struct DosPacket *Packet,LONG Res1,LONG Res2)
-
- {
- struct MsgPort *ReplyPort;
-
- ReplyPort=Packet->dp_Port;
- Packet->dp_Port=&((struct Process *)SysBase->ThisTask)->pr_MsgPort;
- Packet->dp_Link->mn_Node.ln_Name=(char *)Packet;
- Packet->dp_Res1=Res1;
- Packet->dp_Res2=Res2;
-
- PutMsg (ReplyPort,Packet->dp_Link);
- }
-
- void __regargs OpenDH(struct DosPacket *Pkt,ULONG *OpenCnt)
-
- {
- struct FileHandle *FH;
- UBYTE *BStr,Name[BCPL_MAX_LEN],*Ptr;
- ULONG Unit;
- struct DHHandle *RH;
- struct MsgPort *IOPort;
-
- Pkt->dp_Res1=DOSFALSE;
- FH=(struct FileHandle *)BADDR(Pkt->dp_Arg1);
- FH->fh_Port=(struct MsgPort *)FALSE;
- FH->fh_Arg1=0L;
-
- BStr=(UBYTE *)BADDR(Pkt->dp_Arg3);
- (void)memcpy(Name,&BStr[1],BStr[0]);
- Name[BStr[0]]='\0';
-
- if (Ptr=strchr(Name,':')) (void)strcpy(Name,Ptr+1L);
- if ((Ptr=strchr(Name,'/'))==NULL)
- {
- Pkt->dp_Res2=ERROR_BAD_STREAM_NAME;
- return;
- }
- *Ptr++='\0';
-
- if ((Name[0]=='\0')||(*Ptr=='\0'))
- {
- Pkt->dp_Res2=ERROR_BAD_STREAM_NAME;
- return;
- }
-
- Unit=0L;
- while (*Ptr)
- if ((*Ptr<'0')||(*Ptr>'9'))
- {
- Pkt->dp_Res2=ERROR_BAD_NUMBER;
- return;
- }
- else Unit=10L*Unit+(*Ptr++-'0');
-
- Pkt->dp_Res2=ERROR_NO_FREE_STORE;
- if (RH=AllocVec(sizeof(struct DHHandle),MEMF_PUBLIC|MEMF_CLEAR))
- {
- if (IOPort=CreateMsgPort())
- {
- if (RH->rh_IO=CreateStdIO(IOPort))
- {
- if (OpenDevice(Name,Unit,(struct IORequest *)RH->rh_IO,0L)==0L)
- {
- RH->rh_IO->io_Command=TD_GETGEOMETRY;
- RH->rh_IO->io_Length=sizeof(struct DriveGeometry);
- RH->rh_IO->io_Data=&RH->rh_DG;
- if (DoIO((struct IORequest *)RH->rh_IO)==0L)
- if (RH->rh_Buffer=AllocMem(RH->rh_DG.dg_SectorSize,RH->rh_DG.dg_BufMemType))
- {
- RH->rh_Len=RH->rh_DG.dg_SectorSize*RH->rh_DG.dg_TotalSectors;
- if (Pkt->dp_Type==ACTION_FINDOUTPUT)
- {
- RH->rh_Write=TRUE;
- RH->rh_Left=RH->rh_DG.dg_SectorSize;
- RH->rh_Ptr=RH->rh_Buffer;
- }
- else RH->rh_Write=FALSE;
- FH->fh_Arg1=(LONG)RH;
- Pkt->dp_Res1=DOSTRUE;
- Pkt->dp_Res2=0L;
-
- (*OpenCnt)++;
- return;
- }
- CloseDevice ((struct IORequest *)RH->rh_IO);
- }
- else Pkt->dp_Res2=ERROR_OBJECT_NOT_FOUND;
-
- DeleteStdIO (RH->rh_IO);
- }
- DeleteMsgPort (IOPort);
- }
- FreeVec (RH);
- }
- }
-
- void __regargs CloseDH(struct DHHandle *RH,ULONG *OpenCnt)
-
- {
- if (RH->rh_Write)
- {
- if (RH->rh_Left<RH->rh_DG.dg_SectorSize)
- {
- (void)memset(RH->rh_Ptr,'\0',RH->rh_Left);
- RH->rh_IO->io_Command=CMD_WRITE;
- RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
- RH->rh_IO->io_Data=RH->rh_Buffer;
- RH->rh_IO->io_Offset=RH->rh_Pos+RH->rh_Left-RH->rh_DG.dg_SectorSize;
- (void)DoIO((struct IORequest *)RH->rh_IO);
- }
- RH->rh_IO->io_Command=CMD_UPDATE;
- (void)DoIO((struct IORequest *)RH->rh_IO);
- }
-
- FreeMem (RH->rh_Buffer,RH->rh_DG.dg_SectorSize);
-
- RH->rh_IO->io_Command=TD_MOTOR;
- RH->rh_IO->io_Length=0L;
- (void)DoIO((struct IORequest *)RH->rh_IO);
- CloseDevice ((struct IORequest *)RH->rh_IO);
-
- DeleteMsgPort (RH->rh_IO->io_Message.mn_ReplyPort);
- DeleteStdIO (RH->rh_IO);
-
- FreeVec (RH);
-
- (*OpenCnt)--;
- }
-
- LONG __regargs RawRead(struct DHHandle *RH,UBYTE *Buffer,LONG Bytes)
-
- {
- LONG Total,RDBytes;
-
- if ((RH->rh_Pos+Bytes)>RH->rh_Len) Bytes=RH->rh_Len-RH->rh_Pos;
-
- Total=0L;
- while (Bytes)
- {
- if (RH->rh_Left)
- {
- RDBytes=MIN(RH->rh_Left,Bytes);
- (void)memcpy(Buffer,RH->rh_Ptr,RDBytes);
-
- Buffer+=RDBytes;
- Bytes-=RDBytes;
- Total+=RDBytes;
-
- RH->rh_Pos+=RDBytes;
- RH->rh_Ptr+=RDBytes;
- RH->rh_Left-=RDBytes;
-
- if (Bytes==0L) return Total;
- }
-
- RH->rh_IO->io_Command=CMD_READ;
- RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
- RH->rh_IO->io_Data=RH->rh_Buffer;
- RH->rh_IO->io_Offset=RH->rh_Pos;
- if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
-
- RH->rh_Ptr=RH->rh_Buffer;
- RH->rh_Left=RH->rh_IO->io_Actual;
- }
- return Total;
- }
-
- LONG __regargs RawWrite(struct DHHandle *RH,UBYTE *Buffer,LONG Bytes)
-
- {
- LONG Total,WRBytes;
-
- if ((RH->rh_Pos+Bytes)>RH->rh_Len) Bytes=RH->rh_Len-RH->rh_Pos;
-
- Total=0L;
- while (Bytes)
- {
- WRBytes=MIN(RH->rh_Left,Bytes);
- (void)memcpy(RH->rh_Ptr,Buffer,WRBytes);
-
- Buffer+=WRBytes;
- Bytes-=WRBytes;
- Total+=WRBytes;
-
- RH->rh_Pos+=WRBytes;
- RH->rh_Ptr+=WRBytes;
- RH->rh_Left-=WRBytes;
-
- if (RH->rh_Left==0L)
- {
- RH->rh_IO->io_Command=CMD_WRITE;
- RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
- RH->rh_IO->io_Data=RH->rh_Buffer;
- RH->rh_IO->io_Offset=RH->rh_Pos-RH->rh_DG.dg_SectorSize;
- if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
-
- RH->rh_Ptr=RH->rh_Buffer;
- RH->rh_Left=RH->rh_DG.dg_SectorSize;
- }
- }
- return Total;
- }
-