home *** CD-ROM | disk | FTP | other *** search
- /* device.c:
- *
- * Handler for ISO-9660 (+ Rock Ridge) + HFS CDROM filing system.
- * Based on DOSDEV V1.10 (2 Nov 87) by Matthew Dillon.
- *
- * ----------------------------------------------------------------------
- * This code is (C) Copyright 1993,1994 by Frank Munkert.
- * All rights reserved.
- * This software may be freely distributed and redistributed for
- * non-commercial purposes, provided this notice is included.
- * ----------------------------------------------------------------------
- * History:
- *
- * 17-May-94 fmu New option MAYBELOWERCASE (=ML).
- * 20-Apr-94 fmu Improved implementation of ACTION_INHIBIT.
- * 17-Apr-94 fmu Fixed bug concerning TRACKDISK disk change recognition.
- * 12-Apr-94 fmu Adapted ACTION_CURRENT_VOLUME to new filehandle
- * management.
- * 09-Apr-94 fmu Volume management: locks and filehandles will not
- * be forgotten if a CDROM is removed from the drive.
- * 06-Feb-94 dmb - Full support for ACTION_INHIBIT
- * - Change Check_Disk() for trackdisk support
- * 05-Jan-93 fmu - Retry displaying CD-DA icon if WB is not open.
- * - id_UnitNumber of InfoData set to SCSI unit number.
- * - Added Make_FSSM().
- * 01-Jan-93 fmu Support for symbolic links on RockRidge disks.
- * 11-Dec-93 fmu - ACTION_FLUSH always returns DOSTRUE.
- * - ISO volume names are mapped to lowercase if
- * the option LOWERCASE has been selected.
- * 26-Nov-93 fmu Some packets are now handled even if no disk
- * is inserted.
- * 21-Nov-93 fmu - User programmable diskchange check interval.
- * - Better support for ACTION_INHIBIT.
- * - Handles filenames with ';'.
- * 15-Nov-93 fmu Missing return value for 'handler' inserted.
- * 14-Nov-93 fmu Added ACTION_USER packet for 'cdcontrol' program.
- * 15-Oct-93 fmu Adapted to new VOLUME structure.
- * 10-Oct-93 fmu - Creates volume node for 'no DOS' disks.
- * - Volume node now contains the correct volume
- * creation date.
- * 09-Oct-93 fmu - New format for mountlist startup field.
- * - SAS/C support.
- * - Debug process assembly tag adapted to small
- * memory model.
- * - Get_Startup moved to file devsupp.c.
- * 03-Oct-93 fmu - New buffering options 'S' and 'C'.
- * - Fixed bug in cdlock.
- * - Fixed bug in ACTION_CURRENT_VOLUME.
- * 27-Sep-93 fmu Added ACTION_SAME_LOCK
- * 25-Sep-93 fmu - Send 'disk inserted' / 'disk removed' event via
- * input.device if disk has been changed.
- * - Corrected bug in ACTION_DISK_INFO.
- * 24-Sep-93 fmu - Added fast memory option 'F'.
- * - Added ACTION_IS_FILESYSTEM.
- * - Added 'write protected' error for write actions.
- * - Added ACTION_CURRENT_VOLUME.
- * - Unload handler code after ACTION_DIE.
- * - Immediately terminate program if called from CLI.
- * - Added library version number.
- * - Set volume label to "Unnamed" for disks without name.
- * 16-Sep-93 fmu Added code to detect whether a lock stems from the
- * current volume or from another volume which has
- * been removed from the drive.
- */
-
- /*
- * Debugging routines are disabled by simply attempting to open the
- * file "debugoff", turned on again with "debugon". No prefix may be
- * attached to these names (you must be CD'd to TEST:).
- *
- * See Documentation for a detailed discussion.
- */
-
- #include <stdlib.h>
- #include <string.h>
-
- #if defined(_DCC) && !defined(REGISTERED)
- #define abs
- #endif
-
- #include "device.h"
- #include "intui.h"
- #include "devsupp.h"
- #include "cdcontrol.h"
- #include "params.h"
- #include "rock.h"
-
- /*
- * Since this code might be called several times in a row without being
- * unloaded, you CANNOT ASSUME GLOBALS HAVE BEEN ZERO'D!! This also goes
- * for any global/static assignments that might be changed by running the
- * code.
- */
-
- PROC *DosProc; /* Our Process */
- DEVNODE *DosNode; /* Our DOS node.. created by DOS for us */
- DEVLIST *DevList; /* Device List structure for our volume node */
-
- #if !defined(_DCC) || defined(REGISTERED)
- EXECLIB *SysBase; /* EXEC library base */
- #endif
- DOSLIB *DOSBase; /* DOS library base for debug process */
- LIB *UtilityBase; /* Utility library for miscellaneous tasks */
-
- CDROM *g_cd;
- VOLUME *g_volume;
- CDROM_OBJ *g_top_level_obj;
- char *g_vol_name;
-
- PORT *g_timer_mp; /* timer message port */
- struct timerequest *g_timer_io; /* timer i/o request */
- ULONG g_timer_sigbit;
- ULONG g_dos_sigbit;
-
- char g_device[80]; /* SCSI device name */
- short g_unit; /* SCSI unit */
- short g_use_rock_ridge; /* Use Rock Ridge flag 'R' */
- short g_maybe_map_to_lowercase;/* Conditional map to lower case flag 'ML' */
- short g_map_to_lowercase; /* Map to lower case flag 'L' */
- int g_trackdisk; /* Use trackdisk calls instead of SCSI-direct */
-
- int g_std_buffers; /* Number of buffers for standard SCSI access */
- int g_file_buffers; /* Number of buffers for contiguous reads */
-
- t_bool g_show_version_numbers; /* Show version numbers */
-
- int g_scan_interval; /* Time between successive diskchange checks */
-
- t_bool g_disk_inserted; /* Is a disk inserted? */
-
- char g_play_cdda_command[80];/* Command invoked if appicon is activated */
-
- int g_inhibited; /* Number of active INHIBIT(TRUE) packets */
-
- struct MsgPort *DosTask;
-
- #if !defined(NDEBUG) || defined(DEBUG_SECTORS)
- /* DEBUGGING */
- PORT *Dbport; /* owned by the debug process */
- PORT *Dback; /* owned by the DOS device driver */
- short DBDisable;
- MSG DummyMsg; /* Dummy message that debug proc can use */
- #endif
-
- void *dosalloc(ulong);
- void dosfree (ulong *);
- void btos(LONG, char *);
- void *NextNode (NODE *);
- void *GetHead (LIST *);
- LOCK *cdlock(CDROM_OBJ *, int);
- void cdunlock (LOCK *);
- CDROM_OBJ *getlockfile (LONG);
- char *typetostr (int);
- void returnpacket(struct DosPacket *);
- int packetsqueued (void);
- int Check_For_Volume_Name_Prefix (char *);
- void Fill_FileInfoBlock (FIB *, CDROM_INFO *, VOLUME *);
- void Mount (void);
- void Unmount (int);
- int Mount_Check (void);
- void Check_Disk (void);
- void Send_Timer_Request (void);
- void Cleanup_Timer_Device (void);
- int Open_Timer_Device (void);
- void Send_Event (int);
- void Remove_Seglist (void);
- BPTR Make_FSSM (void);
-
- /*
- * Don't call the entry point main(). This way, if you make a mistake
- * with the compile options you'll get a link error.
- */
-
- #if defined(LATTICE)
- int __saveds handler (void)
- #elif defined(_DCC) && !defined(REGISTERED)
- int _main (void)
- #elif defined(_DCC) && defined(REGISTERED)
- __geta4 int handler (void)
- #else
- int handler (void)
- #endif
- {
- register PACKET *packet;
- register short error;
- MSG *msg;
- ubyte notdone = 1;
- char buf[256];
- void *tmp;
- ULONG signals;
- ubyte playing = FALSE;
-
- /*
- * Initialize all global variables. SysBase MUST be initialized before
- * we can make Exec calls. The DOS library is opened for the debug
- * process only.
- */
-
- #if !defined(_DCC) || defined(REGISTERED)
- SysBase = *(EXECLIB **) 4L;
- #endif
- DosProc = (PROC *) FindTask(NULL);
- if (DosProc->pr_CLI)
- return RETURN_FAIL;
- DOSBase = (DOSLIB *) OpenLibrary ((UBYTE *) "dos.library",37);
- UtilityBase = (LIB *) OpenLibrary ((UBYTE *) "utility.library",37);
-
- BUG2(DBDisable = 0;) /* Init. globals */
- BUG2(Dbport = Dback = NULL;)
- DevList = NULL;
- {
- WaitPort(&DosProc->pr_MsgPort); /* Get Startup Packet */
- msg = GetMsg(&DosProc->pr_MsgPort);
- packet = (PACKET *)msg->mn_Node.ln_Name;
-
- /*
- * Loading DosNode->dn_Task causes DOS *NOT* to startup a new
- * instance of the device driver for every reference. E.G. if
- * you were writing a CON device you would want this field to
- * be NULL.
- */
-
- DosNode = BTOC(packet->dp_Arg3);
-
- Init_Intui ();
-
- if (UtilityBase && DOSBase && Get_Startup (packet->dp_Arg2)) {
- packet->dp_Res1 = DOS_TRUE;
- packet->dp_Res2 = 0;
-
- /*
- * Set dn_Task field which tells DOS not to startup a new
- * process on every reference.
- */
-
- DosNode->dn_Task = &DosProc->pr_MsgPort;
- DosTask = DosNode->dn_Task;
-
- /*
- * Load dn_Startup field with a BPTR to a FileSysStartupMsg.
- * (According to the official documentation, this is not
- * required. Some debugging tools, however, depend on it.)
- */
-
- DosNode->dn_Startup = Make_FSSM ();
-
- } else { /* couldn't open dos.library */
- packet->dp_Res1 = DOS_FALSE;
- returnpacket(packet);
- if (DOSBase) {
- Close_Intui ();
- if (UtilityBase)
- CloseLibrary (UtilityBase);
- CloseLibrary ((struct Library *) DOSBase);
- }
- return 0; /* exit process */
- }
- returnpacket(packet);
- }
-
- g_inhibited = 0;
-
- g_disk_inserted = (Test_Unit_Ready (g_cd) ||
- Test_Unit_Ready (g_cd));
-
- /*
- * Initialize debugging code
- */
-
- BUG2(dbinit();)
-
- BUG(dbprintf("%d std buffers, %d file buffers\n",
- g_std_buffers, g_file_buffers);)
-
- g_timer_sigbit = 0;
- if (g_scan_interval > 0) {
- /* Initialize timer: */
- if (Open_Timer_Device ())
- Send_Timer_Request ();
- }
-
- g_vol_name = dosalloc (128);
-
- /* Mount volume (if any disk is inserted): */
- Mount ();
-
- g_dos_sigbit = 1L << DosProc->pr_MsgPort.mp_SigBit;
-
- /*
- * Here begins the endless loop, waiting for requests over our
- * message port and executing them. Since requests are sent over
- * our message port, this precludes being able to call DOS functions
- * ourselves (that is why the debugging routines are a separate process)
- */
-
- top:
- for (; notdone;) {
- signals = Wait(g_dos_sigbit | g_timer_sigbit | g_app_sigbit);
- if (signals & g_timer_sigbit) {
- GetMsg (g_timer_mp);
- if (!g_inhibited)
- Check_Disk ();
- Send_Timer_Request ();
- if (g_retry_show_cdda_icon)
- Show_CDDA_Icon ();
- }
- if (signals & g_app_sigbit) {
- struct Message *msg;
- while (msg = GetMsg (g_app_port)) {
- ReplyMsg (msg);
- if (g_play_cdda_command[0])
- SystemTags ((UBYTE *) g_play_cdda_command,
- SYS_Input, Open ((UBYTE *) "NIL:", MODE_OLDFILE),
- SYS_Output, Open ((UBYTE *) "NIL:", MODE_NEWFILE),
- SYS_Asynch, TRUE,
- TAG_END);
- else {
- int res;
- if (playing)
- res = Stop_Play_Audio (g_cd);
- else
- res = Start_Play_Audio (g_cd);
- if (!res)
- Display_Error ("Cannot perform play audio command!");
- else
- playing = !playing;
- }
- }
- }
- if (!(signals & g_dos_sigbit))
- continue;
- while (msg = GetMsg(&DosProc->pr_MsgPort)) {
- packet = (PACKET *)msg->mn_Node.ln_Name;
- packet->dp_Res1 = DOS_TRUE;
- packet->dp_Res2 = 0;
- error = 0;
- #ifndef NDEBUG
- dbprintf("Packet: %3ld %08lx %08lx %08lx %10s ",
- packet->dp_Type,
- packet->dp_Arg1, packet->dp_Arg2,
- packet->dp_Arg3,
- typetostr(packet->dp_Type)
- );
- #endif
-
- if (g_inhibited) {
- switch (packet->dp_Type) {
- /* packets we will handle even if the handler is inhibited: */
- case ACTION_DIE:
- case ACTION_INHIBIT:
- case ACTION_MORE_CACHE:
- case ACTION_DISK_INFO:
- break;
- /* packets we cannot handle because the handler is inhibited: */
- default:
- packet->dp_Res1 = DOS_FALSE;
- packet->dp_Res2 = ERROR_NOT_A_DOS_DISK;
- BUG(dbprintf("ERR=%ld\n", (long) packet->dp_Res2);)
- returnpacket(packet);
- continue;
- }
- } else if (DevList == NULL) {
- switch (packet->dp_Type) {
- /* packets we will handle even if no disk is inserted: */
- case ACTION_DIE:
- case ACTION_USER:
- case ACTION_IS_FILESYSTEM:
- case ACTION_INHIBIT:
- case ACTION_MORE_CACHE:
- case ACTION_FLUSH:
- break;
- /* packets we cannot handle because no disk is inserted: */
- default:
- packet->dp_Res1 = DOS_FALSE;
- packet->dp_Res2 = (g_disk_inserted ? ERROR_NOT_A_DOS_DISK :
- ERROR_NO_DISK);
- BUG(dbprintf("ERR=%ld\n", (long) packet->dp_Res2);)
- returnpacket(packet);
- continue;
- }
- }
-
- switch(packet->dp_Type) {
- case ACTION_DIE: /* attempt to die? */
- notdone = 0; /* try to die */
- break;
- case ACTION_USER: /* Mode,Par1,Par2 Bool */
- error = Handle_Control_Packet (packet->dp_Arg1,
- packet->dp_Arg2,
- packet->dp_Arg3);
- break;
- case ACTION_FINDINPUT: /* FileHandle,Lock,Name Bool */
- {
- if (Mount_Check ()) {
- CDROM_OBJ *obj;
- CDROM_OBJ *parentdir = getlockfile(packet->dp_Arg2);
- int offs;
-
- if (parentdir->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- goto openbreak;
- }
-
- btos(packet->dp_Arg3,buf);
- BUG(dbprintf("'%s' ", buf);)
- offs = Check_For_Volume_Name_Prefix (buf);
- if (obj = Open_Object (parentdir, buf + offs)) {
- if (obj->symlink_f) {
- error = ERROR_IS_SOFT_LINK;
- goto openbreak;
- }
- if (obj->directory_f) {
- error = ERROR_OBJECT_WRONG_TYPE;
- goto openbreak;
- }
- } else {
- if (iso_errno == ISOERR_ILLEGAL_NAME) {
- error = ERROR_INVALID_COMPONENT_NAME;
- goto openbreak;
- } else if (iso_errno == ISOERR_NOT_FOUND)
- error = ERROR_OBJECT_NOT_FOUND;
- else if (iso_errno == ISOERR_NO_MEMORY) {
- error = ERROR_NO_FREE_STORE;
- goto openbreak;
- } else if (iso_errno == ISOERR_IS_SYMLINK) {
- error = ERROR_IS_SOFT_LINK;
- goto openbreak;
- } else {
- error = 333;
- goto openbreak;
- }
- }
- if (!error) {
- g_volume->file_handles++;
- ((FH *)BTOC(packet->dp_Arg1))->fh_Arg1 = (long) obj;
- Register_File_Handle (obj);
- }
- } else
- error = ERROR_NO_DISK;
- }
- openbreak:
- break;
- case ACTION_READ: /* FHArg1,CPTRBuffer,Length ActLength */
- {
- CDROM_OBJ *obj = (CDROM_OBJ *) packet->dp_Arg1;
- char *ptr = (char *) packet->dp_Arg2;
- long length = packet->dp_Arg3;
- int actual;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- actual = Read_From_File (obj, ptr, length);
- packet->dp_Res1 = actual;
- }
- break;
- case ACTION_END: /* FHArg1 Bool:TRUE */
- {
- CDROM_OBJ *obj = (CDROM_OBJ *) packet->dp_Arg1;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- Unregister_File_Handle (obj);
- Close_Object (obj);
- g_volume->file_handles--;
- }
- break;
- case ACTION_SEEK: /* FHArg1,Position,Mode OldPosition*/
- {
- CDROM_OBJ *obj = (CDROM_OBJ *) packet->dp_Arg1;
- long offset = packet->dp_Arg2;
- int mode = packet->dp_Arg3;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- packet->dp_Res1 = obj->pos;
- if (!Seek_Position (obj, offset, mode)) {
- error = ERROR_SEEK_ERROR;
- packet->dp_Res1 = -1;
- }
- }
- break;
- case ACTION_EXAMINE_NEXT: /* Lock,Fib Bool */
- {
- FIB *fib = BTOC (packet->dp_Arg2);
- CDROM_OBJ *dir = getlockfile (packet->dp_Arg1);
- CDROM_INFO info;
-
- if (dir->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- if (!dir->directory_f) {
- error = ERROR_OBJECT_WRONG_TYPE;
- break;
- }
- if (Examine_Next (dir, &info,
- (unsigned long *) &fib->fib_DiskKey)) {
- error = 0;
- Fill_FileInfoBlock (fib, &info, dir->volume);
- } else {
- error = ERROR_NO_MORE_ENTRIES;
- }
- break;
- }
- case ACTION_EXAMINE_OBJECT: /* Lock,Fib Bool */
- {
- FIB *fib = BTOC (packet->dp_Arg2);
- CDROM_OBJ *obj = getlockfile (packet->dp_Arg1);
- CDROM_INFO info;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- fib->fib_DiskKey = 0;
- error = 0;
- if (!CDROM_Info (obj, &info))
- error = -1;
- else
- Fill_FileInfoBlock (fib, &info, obj->volume);
- }
- break;
- case ACTION_INFO: /* Lock, InfoData Bool:TRUE */
- tmp = BTOC(packet->dp_Arg2);
- error = -1;
- /* fall through */
- case ACTION_DISK_INFO: /* InfoData Bool:TRUE */
- {
- if (Mount_Check ()) {
- register INFODATA *id;
-
- (error) ? (id = tmp) : (id = BTOC (packet->dp_Arg1));
- error = 0;
- memset (id, 0, sizeof(*id));
- id->id_UnitNumber = g_unit;
- id->id_VolumeNode = (long) CTOB (DevList);
- id->id_InUse = 0;
- id->id_DiskState = ID_WRITE_PROTECTED;
- if (g_inhibited) {
- id->id_DiskType = 0x42555359 /* "BUSY" */;
- id->id_NumBlocks = 0;
- id->id_BytesPerBlock = 0;
- } else {
- id->id_DiskType = ID_DOS_DISK;
- id->id_NumBlocks = Volume_Size (g_volume);
- id->id_BytesPerBlock = Block_Size (g_volume);
- }
- id->id_NumBlocksUsed = id->id_NumBlocks;
- }
- }
- break;
- case ACTION_IS_FILESYSTEM: /* - Bool */
- packet->dp_Res1 = DOSTRUE;
- break;
- case ACTION_PARENT: /* Lock ParentLock */
- {
- if (Mount_Check ()) {
- if (packet->dp_Arg1) {
- CDROM_OBJ *obj = getlockfile (packet->dp_Arg1);
- CDROM_OBJ *parent;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- if (Is_Top_Level_Object (obj)) {
- packet->dp_Res1 = packet->dp_Res2 = 0;
- } else {
- parent = Find_Parent (obj);
- if (!parent) {
- if (iso_errno == ISOERR_NO_MEMORY)
- error = ERROR_NO_FREE_STORE;
- else
- error = ERROR_OBJECT_NOT_FOUND;
- } else {
- packet->dp_Res1 = (long)
- CTOB (cdlock (parent, ACCESS_READ));
- }
- }
- } else
- error = ERROR_OBJECT_NOT_FOUND;
- } else
- error = ERROR_NO_DISK;
- }
- break;
- case ACTION_LOCATE_OBJECT: /* Lock,Name,Mode Lock */
- {
- if (Mount_Check ()) {
- CDROM_OBJ *parentdir = getlockfile (packet->dp_Arg1);
- CDROM_OBJ *obj;
- int offs;
-
- if (parentdir->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- btos (packet->dp_Arg2, buf);
- #ifndef NDEBUG
- dbprintf ("'%s' %ld ", buf, packet->dp_Arg3);
- if (strcmp(buf,"debugoff") == 0)
- DBDisable = 1;
- if (strcmp(buf,"debugon") == 0)
- DBDisable = 0;
- #endif
-
- offs = Check_For_Volume_Name_Prefix (buf);
- if (buf[offs]==0) {
- if (parentdir)
- obj = Clone_Object (parentdir);
- else
- obj = Open_Top_Level_Directory (g_volume);
- } else
- obj = Open_Object (parentdir, buf + offs);
-
- if (obj) {
- if (obj->symlink_f)
- error = ERROR_IS_SOFT_LINK;
- else
- packet->dp_Res1 = (long) CTOB (cdlock (obj, packet->dp_Arg3));
- } else {
- if (iso_errno == ISOERR_SCSI_ERROR) {
- error = ERROR_OBJECT_NOT_FOUND;
- Unmount (FALSE);
- } else if (iso_errno == ISOERR_ILLEGAL_NAME)
- error = ERROR_INVALID_COMPONENT_NAME;
- else if (iso_errno == ISOERR_NOT_FOUND)
- error = ERROR_OBJECT_NOT_FOUND;
- else if (iso_errno == ISOERR_NO_MEMORY)
- error = ERROR_NO_FREE_STORE;
- else if (iso_errno == ISOERR_IS_SYMLINK)
- error = ERROR_IS_SOFT_LINK;
- else
- error = 333;
- }
- } else
- error = ERROR_NO_DISK;
- }
- break;
- case ACTION_COPY_DIR: /* Lock, Lock */
- {
- if (packet->dp_Arg1) {
- CDROM_OBJ *obj = getlockfile (packet->dp_Arg1);
- CDROM_OBJ *new;
-
- if (obj->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- new = Clone_Object (obj);
- if (!new)
- error = ERROR_NO_FREE_STORE;
- else
- packet->dp_Res1 = (long) CTOB (cdlock (new, ACCESS_READ));
- } else
- packet->dp_Res1 = 0;
- }
- break;
- case ACTION_FREE_LOCK: /* Lock, Bool */
- if (packet->dp_Arg1);
- cdunlock (BTOC(packet->dp_Arg1));
- break;
- case ACTION_CURRENT_VOLUME: /* FHArg1 DevList */
- {
- CDROM_OBJ *obj = (CDROM_OBJ*) packet->dp_Arg1;
- if (obj)
- packet->dp_Res1 = (long) CTOB (Find_Dev_List (obj));
- else
- packet->dp_Res1 = (long) CTOB (DevList);
- break;
- }
- case ACTION_INHIBIT: /* Bool Bool */
- if (packet->dp_Arg1 != DOS_FALSE) {
- /* true meens forbid access */
- g_inhibited++;
- if (DevList)
- Unmount(FALSE);
- Hide_CDDA_Icon ();
- g_cd->t_changeint2 = -2;
- } else {
- /* false meens access allowed */
- if (g_inhibited)
- g_inhibited--;
- if (g_inhibited == 0) {
- g_disk_inserted = FALSE;
- Check_Disk();
- }
- }
- break;
- /*
- * FINDINPUT and FINDOUTPUT normally should return the
- * 'write protected' error. If the field 'Name', however,
- * designates the root (e.g. CD0:), then the 'wrong type'
- * error should be returned. Otherwise, AmigaDOS would do
- * some funny things (such as saying 'Volume CD0: is write-
- * protected') if you try to mount the handler with the
- * field 'Mount' set to 1.
- */
- case ACTION_FINDOUTPUT: /* Handle Lock Name Bool */
- case ACTION_FINDUPDATE: /* Handle Lock Name Bool */
- {
- int pos;
-
- btos(packet->dp_Arg3,buf);
- BUG(dbprintf("'%s' ", buf);)
- if ((pos = Check_For_Volume_Name_Prefix (buf)) &&
- buf[pos] == 0)
- error = ERROR_OBJECT_WRONG_TYPE;
- else
- error = ERROR_DISK_WRITE_PROTECTED;
- break;
- }
- case ACTION_SAME_LOCK: /* Lock Lock Bool */
- {
- CDROM_OBJ *obj1 = getlockfile(packet->dp_Arg1),
- *obj2 = getlockfile(packet->dp_Arg2);
-
- if (Same_Objects (obj1, obj2))
- packet->dp_Res1 = DOSTRUE;
- else
- packet->dp_Res1 = DOSFALSE;
-
- break;
- }
- case ACTION_READ_LINK: /* Lock Name Buf Length NumChar */
- {
- CDROM_OBJ *obj;
- CDROM_OBJ *parentdir = getlockfile (packet->dp_Arg1);
- char *outbuf = (char *) packet->dp_Arg3;
- t_ulong maxlength = packet->dp_Arg4;
- int offs;
- char buf[256];
- int res;
-
- if (parentdir->volume != g_volume) {
- /* old lock from another disk: */
- error = ERROR_DEVICE_NOT_MOUNTED;
- break;
- }
- BUG(dbprintf ("'%s' len=%lu ", packet->dp_Arg2, maxlength);)
- offs = Check_For_Volume_Name_Prefix ((char *) packet->dp_Arg2);
- obj = Open_Object (parentdir, (char *) packet->dp_Arg2 + offs);
- if (obj) {
- res = Get_Link_Name (obj, buf, sizeof (buf));
- if (res == 0 ||
- strlen (buf) + strlen (g_vol_name+1) + 1 >= maxlength)
- strncpy (outbuf, "illegal_link", maxlength - 1);
- else {
- if (buf[0] == ':')
- strcpy (outbuf, g_vol_name+1);
- else
- outbuf[0] = 0;
- strcat (outbuf, buf);
- }
- outbuf[maxlength - 1] = 0;
- Close_Object (obj);
- packet->dp_Res1 = strlen (outbuf);
- } else {
- if (iso_errno == ISOERR_ILLEGAL_NAME)
- error = ERROR_INVALID_COMPONENT_NAME;
- else if (iso_errno == ISOERR_NOT_FOUND)
- error = ERROR_OBJECT_NOT_FOUND;
- else if (iso_errno == ISOERR_NO_MEMORY)
- error = ERROR_NO_FREE_STORE;
- else if (iso_errno == ISOERR_IS_SYMLINK)
- error = ERROR_IS_SOFT_LINK;
- else
- error = 333;
- }
- break;
- }
- case ACTION_RENAME_DISK:
- case ACTION_WRITE:
- case ACTION_SET_PROTECT:
- case ACTION_DELETE_OBJECT:
- case ACTION_RENAME_OBJECT:
- case ACTION_CREATE_DIR:
- case ACTION_SET_COMMENT:
- case ACTION_SET_DATE:
- case ACTION_SET_FILE_SIZE:
- error = ERROR_DISK_WRITE_PROTECTED;
- break;
- case ACTION_FLUSH: /* writeout bufs, disk motor off */
- break;
- /*
- * A few other packet types which we do not support
- */
- case ACTION_MORE_CACHE: /* #BufsToAdd Bool */
- case ACTION_WAIT_CHAR: /* Timeout, ticks Bool */
- case ACTION_SCREEN_MODE:/* Bool(-1:RAW 0:CON) OldState */
- default:
- error = ERROR_ACTION_NOT_KNOWN;
- break;
- }
- if (packet) {
- if (error) {
- BUG(dbprintf("ERR=%ld\n", error);)
- packet->dp_Res1 = DOS_FALSE;
- packet->dp_Res2 = error;
- } else {
- BUG(dbprintf("RES=%06lx\n", packet->dp_Res1));
- }
- returnpacket(packet);
- }
- }
- }
- BUG(dbprintf("Can we remove ourselves? ");)
- Delay(100); /* I wanna even see the debug message! */
- Forbid();
- if (packetsqueued() ||
- (g_volume && (g_volume->locks || g_volume->file_handles))) {
- Permit();
- BUG(dbprintf(" .. not yet!\n");)
- notdone = 1;
- goto top; /* sorry... can't exit */
- } else
- BUG(dbprintf(" .. yes!\n");)
-
- /* remove timer device and any pending timer requests: */
- if (g_timer_sigbit)
- Cleanup_Timer_Device ();
-
- /* this is getting dangerous. We will unload our very own
- * code via UnLoadSeg() and need to keep the system in
- * Forbid() state in order to avoid getting the free memory
- * reclaimed by other tasks. This means: *NO* Wait() after
- * Unmount(TRUE) ist called!
- */
-
- Unmount (TRUE);
-
- dosfree ((ulong *) g_vol_name);
-
- Cleanup_CDROM (g_cd);
-
- Close_Intui ();
-
- /*
- * Remove debug process, closedown, fall of the end of the world
- * (which is how you kill yourself if a PROCESS. A TASK would have
- * had to RemTask(NULL) itself).
- */
-
- BUG2(Delay (50);)
- BUG2(dbuninit();)
- if (UtilityBase)
- CloseLibrary (UtilityBase);
- if (DOSBase)
- CloseLibrary ((struct Library *) DOSBase);
-
- return 0;
- }
-
-
- /*
- * PACKET ROUTINES. Dos Packets are in a rather strange format as you
- * can see by this and how the PACKET structure is extracted in the
- * GetMsg() of the main routine.
- */
-
- void returnpacket(struct DosPacket *packet)
- {
- register struct Message *mess;
- register struct MsgPort *replyport;
-
- replyport = packet->dp_Port;
- mess = packet->dp_Link;
- packet->dp_Port = &DosProc->pr_MsgPort;
- mess->mn_Node.ln_Name = (char *)packet;
- mess->mn_Node.ln_Succ = NULL;
- mess->mn_Node.ln_Pred = NULL;
- PutMsg(replyport, mess);
- }
-
- /*
- * Are there any packets queued to our device?
- */
-
- int packetsqueued (void)
- {
- return ((void *)DosProc->pr_MsgPort.mp_MsgList.lh_Head !=
- (void *)&DosProc->pr_MsgPort.mp_MsgList.lh_Tail);
- }
-
- /*
- * DOS MEMORY ROUTINES
- *
- * DOS makes certain assumptions about LOCKS. A lock must minimally be
- * a FileLock structure, with additional private information after the
- * FileLock structure. The longword before the beginning of the structure
- * must contain the length of structure + 4.
- *
- * NOTE!!!!! The workbench does not follow the rules and assumes it can
- * copy lock structures. This means that if you want to be workbench
- * compatible, your lock structures must be EXACTLY sizeof(struct FileLock).
- */
-
- void *dosalloc(ulong bytes)
- {
- register ulong *ptr;
-
- bytes += 4;
- ptr = AllocMem(bytes, MEMF_PUBLIC|MEMF_CLEAR);
- *ptr = bytes;
- return(ptr+1);
- }
-
- void dosfree (ulong *ptr)
- {
- --ptr;
- FreeMem(ptr, *ptr);
- }
-
- /*
- * Convert a BSTR into a normal string.. copying the string into buf.
- * I use normal strings for internal storage, and convert back and forth
- * when required.
- */
-
- void btos(LONG bstr, char *buf)
- {
- unsigned char *str = BTOC(bstr);
- bmov((char *) str+1, buf, *str);
- buf[*str] = 0;
- }
-
- /*
- * Some EXEC list handling routines not found in the EXEC library.
- */
-
- void *NextNode (NODE *node)
- {
- node = node->mln_Succ;
- if (node->mln_Succ == NULL)
- return(NULL);
- return(node);
- }
-
- void *GetHead (LIST *list)
- {
- if ((void *)list->mlh_Head != (void *)&list->mlh_Tail)
- return(list->mlh_Head);
- return(NULL);
- }
-
- /*
- * The lock function. The file has already been checked to see if it
- * is lockable given the mode.
- */
-
- LOCK *cdlock(CDROM_OBJ *cdfile, int mode)
- {
- LOCK *lock = dosalloc (sizeof(LOCK));
-
- cdfile->volume->locks++;
- lock->fl_Key = (long) cdfile;
- lock->fl_Access = ACCESS_READ;
- lock->fl_Task = &DosProc->pr_MsgPort;
- lock->fl_Volume = (BPTR) CTOB (DevList);
- Register_Lock (lock);
- return(lock);
- }
-
- void cdunlock (LOCK *lock)
- {
- CDROM_OBJ *obj = (CDROM_OBJ *) lock->fl_Key;
-
- Unregister_Lock (lock);
- --obj->volume->locks;
- Close_Object (obj);
- dosfree ((ulong *) lock); /* free lock */
- }
-
- /*
- * GETLOCKFILE(bptrlock)
- *
- * Return the CDROM_OBJ (file or directory) associated with the
- * given lock, which is passed as a BPTR.
- *
- * According to the DOS spec, the only way a NULL lock will ever be
- * passed to you is if the DosNode->dn_Lock is NULL, but I'm not sure.
- * In anycase, If a NULL lock is passed to me I simply assume it means
- * the root directory of the CDROM.
- */
-
- CDROM_OBJ *getlockfile (LONG lock)
- {
- LOCK *rl = BTOC (lock);
-
- if (rl)
- return (CDROM_OBJ *) rl->fl_Key;
- return g_top_level_obj;
- }
-
- /*
- * If p_pathname contains a ':' character, return the position of the first
- * character after ':'
- * Otherwise, return 0.
- */
-
- int Check_For_Volume_Name_Prefix (char *p_pathname)
- {
- char *pos = strchr (p_pathname, ':');
-
- return pos ? (pos - p_pathname) + 1 : 0;
- }
-
- /*
- * Fills a FileInfoBlock with the information contained in the
- * directory record of a CD-ROM directory or file.
- */
-
- void Fill_FileInfoBlock (FIB *p_fib, CDROM_INFO *p_info, VOLUME *p_volume)
- {
- char *src = p_info->name;
- char *dest = p_fib->fib_FileName+1;
- int len = p_info->name_length;
-
- if (p_info->symlink_f)
- p_fib->fib_DirEntryType = ST_SOFTLINK;
- else
- p_fib->fib_DirEntryType = p_info->directory_f ? ST_USERDIR : ST_FILE;
-
- /* I don't know exactly why I have to set fib_EntryType, but other
- * handlers (e.g. DiskHandler by J Toebes et.al.) also do this.
- */
-
- p_fib->fib_EntryType = p_fib->fib_DirEntryType;
-
- if (len == 1 && *src == ':') {
- /* root of file system: */
- p_fib->fib_DirEntryType = ST_USERDIR;
- /* file name == volume name: */
- memcpy (p_fib->fib_FileName, g_vol_name, (int)(g_vol_name[0])+1);
- } else {
- /* copy file name: */
- if (g_show_version_numbers) {
- p_fib->fib_FileName[0] = len;
- for (; len; len--)
- *dest++ = *src++;
- } else {
- short i, real_len=len;
- for (i=0; i<len; i++) {
- if (*src == ';')
- real_len = i;
- *dest++ = *src++;
- }
- p_fib->fib_FileName[0] = real_len;
- }
-
- if ((g_map_to_lowercase && p_volume->protocol == PRO_ISO) ||
- (g_maybe_map_to_lowercase && !p_volume->mixed_char_filenames)) {
- /* convert ISO filename to lowercase: */
- int i, len = p_fib->fib_FileName[0];
- char *cp = p_fib->fib_FileName + 1;
-
- for (i=0; i<len; i++, cp++)
- *cp = ToLower (*cp);
- }
- }
- p_fib->fib_Protection = 0;
- p_fib->fib_Size = p_info->file_length;
- p_fib->fib_NumBlocks = p_info->file_length >> 11;
- if (p_info->symlink_f)
- strcpy (p_fib->fib_Comment, "\x0DSymbolic link");
- else
- p_fib->fib_Comment[0] = 0;
-
- p_fib->fib_Date.ds_Days = p_info->date / (24 * 60 * 60);
- p_fib->fib_Date.ds_Minute = (p_info->date % (24 * 60 * 60)) / 60;
- p_fib->fib_Date.ds_Tick = (p_info->date % 60) * TICKS_PER_SECOND;
- }
-
- /*
- * Create Volume node and add to the device list. This will
- * cause the WORKBENCH to recognize us as a disk. If we don't
- * create a Volume node, Wb will not recognize us.
- */
-
- void Create_Volume_Node (LONG p_disk_type, ULONG p_volume_date)
- {
- DOSINFO *di = BTOC(((ROOTNODE *)DOSBase->dl_Root)->rn_Info);
- DEVLIST *dl;
- char *name;
-
- if (dl = Find_Volume_Node (g_vol_name + 1)) {
- BUG(dbprintf("[Reusing old volume node]");)
- Forbid ();
- DevList = dl;
- dl->dl_Task = &DosProc->pr_MsgPort;
- Permit ();
- } else {
- Forbid ();
- DevList = dl = dosalloc(sizeof(DEVLIST));
- dl->dl_Type = DLT_VOLUME;
- dl->dl_Task = &DosProc->pr_MsgPort;
- dl->dl_DiskType = p_disk_type;
- name = dosalloc (g_vol_name[0]+2);
- if (name) {
- dl->dl_Name = (BSTR) CTOB (name);
- memcpy (name, g_vol_name, g_vol_name[0]+2);
- }
- dl->dl_VolumeDate.ds_Days = p_volume_date / (24 * 60 * 60);
- dl->dl_VolumeDate.ds_Minute = (p_volume_date % (24 * 60 * 60)) / 60;
- dl->dl_VolumeDate.ds_Tick = (p_volume_date % 60) * TICKS_PER_SECOND;
- dl->dl_Next = di->di_DevInfo;
- di->di_DevInfo = (long)CTOB(dl);
- Permit ();
- Register_Volume_Node (dl);
- }
- }
-
- /*
- * Mount a volume.
- */
-
- void Mount (void)
- {
- char buf[33];
-
- if (Has_Audio_Tracks (g_cd))
- Show_CDDA_Icon ();
-
- g_volume = Open_Volume (g_cd, g_use_rock_ridge);
- if (!g_volume) {
- BUG(dbprintf ("!!! cannot open VOLUME (iso_errno=%d) !!!\n", iso_errno);)
- return;
- } else {
- g_disk_inserted = TRUE;
- g_cd->t_changeint2 = g_cd->t_changeint;
- g_top_level_obj = Open_Top_Level_Directory (g_volume);
- if (!g_top_level_obj) {
- BUG(dbprintf ("!!! cannot open top level directory !!!\n");)
- return;
- }
- }
-
- BUG(dbprintf ("***mounting*** ");)
-
- Volume_ID (g_volume, buf, sizeof (buf)-1);
- g_vol_name[0] = strlen (buf);
- memcpy (g_vol_name+1, buf, strlen (buf));
-
- if (!(g_vol_name[0]))
- memcpy (g_vol_name, "\7Unnamed", 8);
-
- /* AmigaDOS expects the BCPL string g_vol_name to be null-terminated: */
- g_vol_name[(int)(g_vol_name[0])+1] = 0;
-
- /* convert ISO volume name to lowercase: */
- if ((g_map_to_lowercase && g_volume->protocol == PRO_ISO) ||
- (g_maybe_map_to_lowercase && !g_volume->mixed_char_filenames)) {
- int i;
- for (i=0; i<g_vol_name[0]; i++)
- g_vol_name[i+1] = ToLower (g_vol_name[i+1]);
- }
-
- g_volume->locks = Reinstall_Locks ();
- g_volume->file_handles = Reinstall_File_Handles ();
-
- Create_Volume_Node (ID_DOS_DISK, Volume_Creation_Date (g_volume));
- g_cd->t_changeint2 = g_cd->t_changeint;
- Send_Event (TRUE);
- }
-
- void Remove_Seglist (void)
- {
- DOSINFO *di;
- void *dlp;
- DEVNODE *dn;
-
- di = BTOC (((ROOTNODE *) DOSBase->dl_Root)->rn_Info);
- dlp = &di->di_DevInfo;
- dn = BTOC (di->di_DevInfo);
-
- while (dn) {
- if (dn->dn_Task == DosTask) {
- BUG(dbprintf("got it!\n");)
- if (TypeOfMem (BADDR (dn->dn_SegList))) {
- UnLoadSeg (dn->dn_SegList);
- dn->dn_SegList = 0;
- } else
- BUG(dbprintf("not a valid seglist\n");)
-
- dn->dn_Task = NULL;
-
- *(BPTR *) dlp = dn->dn_Next;
- dosfree ((ulong *) dn);
-
- break;
- } else {
- dlp = &dn->dn_Next;
- dn = BTOC (dn->dn_Next);
- }
- }
- }
-
- /* Remove a volume node from the DOS list.
- * (Must be nested between Forbid() and Permit()!)
- * Since DOS uses singly linked lists, we must (ugg) search it manually to find
- * the link before our Volume entry.
- */
-
- void Remove_Volume_Node (DEVLIST* p_volume)
- {
- DOSINFO *di;
- DEVLIST *dl;
- void *dlp;
-
- Unregister_Volume_Node (p_volume);
-
- di = BTOC(((ROOTNODE *)DOSBase->dl_Root)->rn_Info);
-
- dlp = &di->di_DevInfo;
- for (dl = BTOC(di->di_DevInfo); dl && dl != p_volume; dl = BTOC(dl->dl_Next))
- dlp = &dl->dl_Next;
- if (dl == p_volume) {
- *(BPTR *)dlp = dl->dl_Next;
- dosfree((ulong *) BTOC (dl->dl_Name));
- dosfree((ulong *) dl);
- } else {
- BUG(dbprintf("****PANIC: Unable to find volume node\n");)
- }
- }
-
- /* Unmount a volume, and optionally unload the handler code.
- */
-
- void Unmount (int p_remove_seglist)
- {
- g_cd->t_changeint2 = g_cd->t_changeint;
- Hide_CDDA_Icon ();
-
- Forbid ();
-
- if (DevList) {
-
- BUG(dbprintf("***unmounting***");)
-
- Close_Object (g_top_level_obj);
- if (g_volume->locks == 0 && g_volume->file_handles == 0) {
- Remove_Volume_Node (DevList);
- Close_Volume (g_volume);
- } else {
- BUG(dbprintf("[there are still %d locks on this volume]",
- g_volume->locks);)
- BUG(dbprintf("[there are still %d file handles on this volume]",
- g_volume->file_handles);)
- DevList->dl_Task = NULL;
- }
-
- DevList = NULL;
- }
-
- Send_Event (FALSE);
-
- g_volume = 0;
-
- /* when the handler code exits the corresponding device
- * node (e.g. "CD0") will be modified. The handler code
- * will be unloaded and the task entry will be set to
- * zero, so the next device access will reload and
- * restart the handler code.
- */
-
- if (p_remove_seglist) {
- Remove_Seglist ();
- } else
- Permit ();
- }
-
- /*
- * Mount_Check returns 1 if a valid disk is inserted in the drive. A check is
- * only performed if previously the drive was empty.
- */
-
- int Mount_Check (void)
- {
- if (!g_disk_inserted) {
- /*
- * No disk was inserted up to now: we will check whether
- * a disk has been inserted by sending the test unit ready
- * command. We have to send the command twice because
- * the first SCSI command after inserting a new disk is
- * always rejected.
- */
- if (Test_Unit_Ready (g_cd) ||
- Test_Unit_Ready (g_cd)) {
- g_disk_inserted = TRUE;
- Mount ();
- } else {
- return 0;
- }
- if (DevList)
- return 1;
- else {
- /* Mount() did not succeed: */
- return 0;
- }
- }
- return 1;
- }
-
- /*
- * Open timer device structures:
- */
-
- int Open_Timer_Device (void)
- {
- if (!(g_timer_mp = CreateMsgPort ())) {
- BUG(dbprintf ("cannot create timer message port!\n");)
- return 0;
- }
- if (!(g_timer_io = (struct timerequest *)
- CreateIORequest (g_timer_mp, sizeof (struct timerequest)))) {
- BUG(dbprintf ("cannot create timer i/o structure!\n");)
- DeleteMsgPort (g_timer_mp);
- return 0;
- }
- if (OpenDevice ((UBYTE *) TIMERNAME, UNIT_VBLANK,
- (struct IORequest *) g_timer_io, 0)) {
- BUG(dbprintf ("cannot open timer device!\n");)
- DeleteIORequest ((struct IORequest *) g_timer_io);
- DeleteMsgPort (g_timer_mp);
- return 0;
- }
- g_timer_sigbit = 1L << g_timer_mp->mp_SigBit;
- return 1;
- }
-
- /*
- * Remove timer device structures:
- */
-
- void Cleanup_Timer_Device (void)
- {
- /* remove any pending requests: */
- if (!CheckIO ((struct IORequest *) g_timer_io))
- AbortIO ((struct IORequest *) g_timer_io);
- WaitIO ((struct IORequest *) g_timer_io);
-
- CloseDevice ((struct IORequest *) g_timer_io);
- DeleteIORequest ((struct IORequest *) g_timer_io);
- DeleteMsgPort (g_timer_mp);
- }
-
- /*
- * Send timer request
- */
-
- void Send_Timer_Request (void)
- {
- g_timer_io->tr_node.io_Command = TR_ADDREQUEST;
- g_timer_io->tr_time.tv_secs = g_scan_interval;
- g_timer_io->tr_time.tv_micro = 0;
- SendIO ((struct IORequest *) g_timer_io);
- }
-
- /*
- * Check whether the disk has been removed or inserted.
- */
-
- void Check_Disk (void)
- {
- int i;
- unsigned long l1, l2;
-
- BUG(dbprintf ("Checking Disk... ");)
- if (g_cd->use_trackdisk) {
- i = (Test_Unit_Ready (g_cd) ||
- Test_Unit_Ready (g_cd));
- l1 = g_cd->t_changeint;
- l2 = g_cd->t_changeint2;
- BUG(if (l1==l2 && i) dbprintf ("no disk change (T %ld)", l1);)
- if (l1!=l2 && i) {
- g_disk_inserted = TRUE;
- BUG(dbprintf ("disk has been inserted (T %ld)", l1);)
- if (DevList)
- Unmount (FALSE);
- Delay (50);
- Clear_Sector_Buffers (g_cd);
- Mount ();
- }
- BUG(if (l1==l2 && !i) dbprintf ("no disk in drive (T %ld)", l1);)
- if (l1!=l2 && !i) {
- g_disk_inserted = FALSE;
- BUG(dbprintf ("disk has been removed (T %ld)", l1);)
- if (DevList)
- Unmount (FALSE);
- g_cd->t_changeint2 = g_cd->t_changeint;
- }
- } else {
- if (g_disk_inserted) {
- if (Test_Unit_Ready (g_cd)) {
- BUG(dbprintf ("no disk change"));
- } else {
- g_disk_inserted = FALSE;
- BUG(dbprintf ("disk has been removed");)
- if (DevList)
- Unmount (FALSE);
- Hide_CDDA_Icon ();
- }
- }
- if (!g_disk_inserted) {
- if (Test_Unit_Ready (g_cd) ||
- Test_Unit_Ready (g_cd)) {
- g_disk_inserted = TRUE;
- BUG(dbprintf ("disk has been inserted");)
- Clear_Sector_Buffers (g_cd);
- Mount ();
- }
- }
- }
- BUG(dbprintf ("\n");)
- }
-
- /* The following lines will generate a `disk inserted/removed' event, in order
- * to get Workbench to rescan the DosList and update the list of
- * volume icons.
- */
-
- void Send_Event (int p_inserted)
- {
- struct IOStdReq *InputRequest;
- struct MsgPort *InputPort;
-
- if (InputPort = (struct MsgPort *) CreateMsgPort ()) {
- if (InputRequest = (struct IOStdReq *)
- CreateIORequest (InputPort, sizeof (struct IOStdReq))) {
- if (!OpenDevice ((UBYTE *) "input.device", 0,
- (struct IORequest *) InputRequest, 0)) {
- static struct InputEvent InputEvent;
-
- memset (&InputEvent, 0, sizeof (struct InputEvent));
-
- InputEvent.ie_Class = p_inserted ? IECLASS_DISKINSERTED :
- IECLASS_DISKREMOVED;
-
- InputRequest->io_Command = IND_WRITEEVENT;
- InputRequest->io_Data = &InputEvent;
- InputRequest->io_Length = sizeof (struct InputEvent);
-
- DoIO ((struct IORequest *) InputRequest);
-
- CloseDevice ((struct IORequest *) InputRequest);
- }
- DeleteIORequest (InputRequest);
- }
- DeleteMsgPort (InputPort);
- }
- }
-
- BPTR Make_FSSM (void)
- {
- struct FileSysStartupMsg* fssm;
- struct DosEnvec *env;
- char *dev;
-
- fssm = dosalloc (sizeof (*fssm));
- fssm->fssm_Unit = g_unit;
- dev = dosalloc (strlen (g_device) + 2);
- strcpy (dev+1, g_device);
- dev[0] = strlen (g_device);
- fssm->fssm_Device = (BPTR) CTOB (dev);
- env = dosalloc (sizeof (struct DosEnvec));
- env->de_TableSize = 19;
- env->de_SizeBlock = 2048;
- env->de_Surfaces = 1;
- env->de_SectorPerBlock = 1;
- env->de_BlocksPerTrack = 1;
- env->de_DosType = 0x4E444F53; /* NDOS */
- fssm->fssm_Environ = (BPTR) CTOB (env);
- fssm->fssm_Flags = 0;
-
- return (BPTR) CTOB (fssm);
- }
-