/* $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); } } }