home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header * Header built automatically - do not edit! *************
- *
- * (C) Copyright 1990 by MXM
- *
- * Name .....: LockDevice-Handler.c
- * Created ..: Tuesday 26-Jun-90 14:19
- * Revision .: 1
- *
- * Date Author Comment
- * ========= ======== ====================
- * 26-Jun-90 Olsen Created this file!
- *
- * $Revision Header ********************************************************/
-
- /* Global lock segment. */
-
- struct LockSeg *LSeg;
-
- /* Prototypes. */
-
- BYTE StrCmp(char *a,char *b);
- struct FileSysStartupMsg * FindDevice(char *DevName);
- BYTE CreatePatch(char *DeviceName,char *PassWord);
- extern VOID NewBeginIO(VOID);
- VOID * PatchedBeginIO(struct IOExtTD *Request);
- LONG _main(VOID);
-
- /* StrCmp(char *a,char *b):
- *
- * Do a string comparison ignoring case.
- */
-
- BYTE
- StrCmp(char *a,char *b)
- {
- for( ; toupper(*a) == toupper(*b) ; a++, b++)
- {
- if(!(*a))
- return(0);
- }
-
- return(1);
- }
-
- /* FindDevice(char *DevName):
- *
- * Find the environment data for filing system device.
- */
-
- struct FileSysStartupMsg *
- FindDevice(char *DevName)
- {
- char *Pointer,Name[257];
- struct DeviceNode *DevInfo;
- SHORT i;
-
- Forbid();
-
- DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
-
- while(DevInfo)
- {
- if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
- {
- Pointer = (char *)BADDR(DevInfo -> dn_Name);
-
- for(i = 0 ; i < Pointer[0] ; i++)
- Name[i] = Pointer[i + 1];
-
- Name[Pointer[0] ] = ':';
- Name[Pointer[0] + 1] = 0;
-
- if(!StrCmp(Name,DevName))
- {
- Permit();
- return(BADDR(DevInfo -> dn_Startup));
- }
- }
-
- DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
- }
-
- Permit();
-
- return(NULL);
- }
-
- /* CreatePatch(char *DeviceName,char *PassWord):
- *
- * Create a BeginIO patch for a given filing device.
- */
-
- BYTE
- CreatePatch(char *DeviceName,char *PassWord)
- {
- struct Patch *NewPatch,*TempPatch = LSeg -> RootPatch;
- struct FileSysStartupMsg *Startup;
- char *DriverName;
-
- /* Try to find the environment vector. */
-
- if(Startup = FindDevice(DeviceName))
- {
- /* Allocate memory for the patch. */
-
- if(NewPatch = (struct Patch *)AllocMem(sizeof(struct Patch),MEMF_PUBLIC | MEMF_CLEAR))
- {
- /* Allocate memory for the IORequest. */
-
- if(NewPatch -> Request = (struct IOExtTD *)AllocMem(sizeof(struct IOExtTD),MEMF_PUBLIC | MEMF_CLEAR))
- {
- NewPatch -> Request -> iotd_Req . io_Message . mn_Node . ln_Type = NT_MESSAGE;
- NewPatch -> Request -> iotd_Req . io_Message . mn_Length = sizeof(struct IOExtTD);
-
- /* Remember the name of the device driver. */
-
- DriverName = (char *)((ULONG)BADDR(Startup -> fssm_Device) + 1);
-
- /* Open the device driver. */
-
- if(!OpenDevice(DriverName,Startup -> fssm_Unit,NewPatch -> Request,Startup -> fssm_Flags))
- {
- /* Remember the device pointer. */
-
- NewPatch -> Device = NewPatch -> Request -> iotd_Req . io_Device;
-
- /* Copy the password. */
-
- if(PassWord)
- strcpy(NewPatch -> PassWord,PassWord);
-
- /* Copy the name of the filing device. */
-
- strcpy(NewPatch -> UnitName,DeviceName);
-
- /* Copy the name of the device driver. */
-
- strcpy(NewPatch -> DriverName,DriverName);
-
- Disable();
-
- /* Remember old BeginIO vector. */
-
- NewPatch -> OldBeginIO = (VOID *)SetFunction((struct Library *)NewPatch -> Device,DEV_BEGINIO,NewBeginIO);
-
- /* Add the patch to the patch list. */
-
- while(TempPatch)
- {
- if(!TempPatch -> NextPatch)
- {
- TempPatch -> NextPatch = NewPatch;
-
- Enable();
-
- return(TRUE);
- }
-
- TempPatch = TempPatch -> NextPatch;
- }
-
- LSeg -> RootPatch = NewPatch;
-
- Enable();
-
- return(TRUE);
- }
-
- FreeMem(NewPatch -> Request,sizeof(struct IOExtTD));
- }
-
- FreeMem(NewPatch,sizeof(struct Patch));
- }
- }
-
- return(FALSE);
- }
-
- /* PatchedBeginIO(struct IOExtTD *Request):
- *
- * Our patched BeginIO routine. Note: this code is
- * shared between a number of calling tasks and has
- * to be reentrant.
- */
-
- VOID *
- PatchedBeginIO(struct IOExtTD *Request)
- {
- struct Patch *Patch = LSeg -> RootPatch;
- VOID *JumpAddress = NULL;
-
- Disable();
-
- /* Find the patch for this device. */
-
- while(Patch)
- {
- if(Patch -> Device == Request -> iotd_Req . io_Device)
- break;
-
- Patch = Patch -> NextPatch;
- }
-
- /* Got it! Remember the old BeginIO vector. */
-
- if(Patch)
- JumpAddress = Patch -> OldBeginIO;
-
- Enable();
-
- if(!Patch)
- Request -> iotd_Req . io_Error = TDERR_NotSpecified;
- else
- {
- switch(Request -> iotd_Req . io_Command & ~TDF_EXTCOM)
- {
- /* Reject illegal commands. */
-
- case CMD_WRITE:
- case TD_FORMAT:
- case TD_RAWWRITE: Request -> iotd_Req . io_Error = TDERR_WriteProt;
- return(NULL);
-
- /* Disk is write protected. */
-
- case TD_PROTSTATUS: Request -> iotd_Req . io_Error = 0;
- Request -> iotd_Req . io_Actual = ~0;
- return(NULL);
-
- default: break;
- }
- }
-
- /* Return to the interface code. */
-
- return(JumpAddress);
- }
-
- /* _main():
- *
- * Handler entry point.
- */
-
- LONG
- _main()
- {
- struct Process *ThisProcess = (struct Process *)SysBase -> ThisTask;
- ULONG SignalSet;
-
- /* Called from shell? */
-
- if(ThisProcess -> pr_CLI || !(LSeg = (struct LockSeg *)FindPort(PORTNAME)))
- return(-1);
-
- /* Initialize the global MsgPort. */
-
- LSeg -> SignalPort . mp_SigBit = SIGBREAKB_CTRL_E;
- LSeg -> SignalPort . mp_SigTask = ThisProcess;
- LSeg -> SignalPort . mp_Flags = PA_SIGNAL;
-
- /* Add the child entry and ring back. */
-
- LSeg -> Child = (struct Task *)ThisProcess;
-
- Signal(LSeg -> Father,LSeg -> HandShake);
-
- for(;;)
- {
- SignalSet = Wait(SIG_PORT | SIG_QUIT);
-
- /* A new patch request came in. */
-
- if(SignalSet & SIG_PORT)
- {
- struct LockMsg *Message;
-
- while(Message = (struct LockMsg *)GetMsg(&LSeg -> SignalPort))
- {
- Message -> Success = CreatePatch(Message -> DeviceName,Message -> PassWord);
-
- ReplyMsg((struct Message *)Message);
- }
- }
-
- /* Deallocate the handler. */
-
- if(SignalSet & SIG_QUIT)
- {
- LSeg -> Child = NULL;
-
- Forbid();
-
- Signal(LSeg -> Father,LSeg -> HandShake);
-
- return(0);
- }
- }
- }
-