Exemplo n.º 1
0
static __regargs BOOL AllocHunks(FileT *fh, LONG hunkNum, HunkT **hunks) {
  LONG memFlags, n, size;
  HunkT *hunk, *prev = NULL;

  while (hunkNum--) {
    /* size specifiers including memory attribute flags */
    FileRead(fh, ONSTACK(n));

    memFlags = n >> 30;
    size = n & 0x3FFFFFFF;
    if (memFlags == 1)
      memFlags = MEMF_CHIP;
    else if (memFlags == 2)
      memFlags = MEMF_FAST;
    else
      memFlags = MEMF_PUBLIC;

    if (!(hunk = AllocMem(sizeof(HunkT) + n * sizeof(LONG), memFlags)))
      return FALSE;

    hunk->size = n * sizeof(LONG);
    hunk->next = NULL;

    if (prev)
      prev->next = MKBADDR(&hunk->next);
    prev = hunk;

    *hunks++ = hunk;
  }

  return TRUE;
}
Exemplo n.º 2
0
static BSTR mkbstr(APTR pool, CONST_STRPTR str) {
    UBYTE *buf;
    UBYTE len;

    len = strlen(str) & 0xff;

    buf = AllocPooled(pool, len + 1);
    CopyMem(str, &(buf[1]), len);
    buf[0] = len;

    return (BSTR) MKBADDR(buf);
}
Exemplo n.º 3
0
void mount(struct HDTBPartition *table, struct PartitionHandle *ph, STRPTR name, struct DosEnvec *de)
{
    struct ExpansionBase *ExpansionBase;
    struct DeviceNode *dn;
    struct DosEnvec *nde;
    IPTR *params;
    ULONG i;

    D(bug("[HDToolBox] mount('%s')\n", name));

#error "TODO: pass DOS device name in params[0] and set handler name manually"
#warning "TODO: get filesystem"
    if ((de->de_DosType & 0xFFFFFF00) == BBNAME_DOS)
    {
        ExpansionBase = (struct ExpansionBase *)OpenLibrary("expansion.library",41);
        if (ExpansionBase)
        {
            params = (IPTR *)AllocVec(sizeof(struct DosEnvec)+sizeof(IPTR)*4, MEMF_PUBLIC | MEMF_CLEAR);
            if (params)
            {
                nde = (struct DosEnvec *)&params[4];
                CopyMem(de, nde, sizeof(struct DosEnvec));
                params[0] = (IPTR)"afs.handler";
                params[1] = (IPTR)table->hd->devname;
                params[2] = (IPTR)table->hd->unit;
                params[3] = 0;
                i = getOffset(ph->root);
                nde->de_LowCyl += i;
                nde->de_HighCyl += i;
                dn = MakeDosNode(params);
                if (dn)
                {
                    dn->dn_Name = MKBADDR(AllocVec(AROS_BSTR_MEMSIZE4LEN(strlen(name)), MEMF_PUBLIC));
                    dn->dn_Ext.dn_AROS.dn_DevName = AROS_BSTR_ADDR(dn->dn_Name);

                    i = 0;
                    do
                    {
                        AROS_BSTR_putchar(dn->dn_Name, i, name[i]);
                    } while (name[i++]);
                    AROS_BSTR_setstrlen(dn->dn_Name, i-1);
                    AddDosNode(nde->de_BootPri, ADNF_STARTPROC, dn);
                }
                else
                    FreeVec(params);
            }
            CloseLibrary((struct Library *)ExpansionBase);
        }
    }
    else
        kprintf("ignored %s: unknown FS (0x%lx)\n", name, de->de_DosType);
}
Exemplo n.º 4
0
// Get the root of a pathname
int get_path_root(char *path,char *root_name,struct DateStamp *date)
{
	struct DevProc *proc;
	D_S(struct InfoData, info)
	struct DosList *dos;

	// Get device process
	if (!(proc=GetDeviceProc(path,0)))
		return 0;

	// Send info packet
#ifdef __AROS__
	if (((struct Library *)DOSBase)->lib_Version<50)
	{
		//Info(proc->dvp_Lock,info);
		BPTR lock;
		if (!(lock=Lock(path,SHARED_LOCK)))
		{
			FreeDeviceProc(proc);
			return 0;
		}
		Info(lock,info);
		UnLock(lock);
	}
	else
#endif
	DoPkt(proc->dvp_Port,ACTION_DISK_INFO,MKBADDR(info),0,0,0,0);

	// Get DOS list pointer
	if (!(dos=(struct DosList *)BADDR(info->id_VolumeNode)))
	{
		FreeDeviceProc(proc);
		return 0;
	}

	// Get root device name
	if (root_name)
	{
		if (dos->dol_Name) BtoCStr(dos->dol_Name,root_name,32);
		else *root_name=0;
	}

	// Copy datestamp if buffer supplied
	if (date) *date=dos->dol_misc.dol_volume.dol_VolumeDate;

	// Free device process
	FreeDeviceProc(proc);

	// Return disk state
	return info->id_DiskState;
}
Exemplo n.º 5
0
Arquivo: nil.c Projeto: michalsc/AROS
SIPTR handleNIL(LONG action, SIPTR arg1, SIPTR arg2, SIPTR arg3)
{
    switch(action)
    {
    case(ACTION_FINDUPDATE):
    case(ACTION_FINDINPUT):
    case(ACTION_FINDOUTPUT):
    {
        struct FileHandle * fh = BADDR(arg1);
        fh->fh_Type = BNULL;
        fh->fh_Interactive = DOSFALSE;/* NIL: is not considered interactive */
        return (SIPTR)MKBADDR(fh);
    }
    case(ACTION_INFO): return (SIPTR)0;
    case(ACTION_FREE_LOCK):
    {
        FreeMem((APTR)arg1, sizeof(struct FileLock));
        return (SIPTR)0;
    }
    case(ACTION_COPY_DIR_FH):
    {
        struct FileLock *fl = AllocMem(sizeof(struct FileLock), MEMF_PUBLIC | MEMF_CLEAR);
        fl->fl_Access = SHARED_LOCK;
        return (SIPTR)MKBADDR(fl);
    }
    case(ACTION_FH_FROM_LOCK):
    {
        struct FileHandle * fh = BADDR(arg2);
        fh->fh_Interactive = DOSFALSE;
        FreeMem((APTR)arg3, sizeof(struct FileLock));
        return (SIPTR)DOSTRUE;
    }
    case(ACTION_WRITE): return (SIPTR)arg3;
    case(ACTION_PARENT_FH): return (SIPTR)BNULL;
    default: return TRUE;
    }
}
Exemplo n.º 6
0
/*******************************************
 Name  : remDosVolume
 Descr.: removes a volume added by addDosVolume
         or if there are some locks active
         set dol_LockList
 Input : volume - volume to remove
 Output: -
********************************************/
void remDosVolume(struct AFSBase *afsbase, struct Volume *volume) {
struct DosList *dl;

	dl = volume->volumenode;
	if (dl) {
		if (volume->locklist != NULL)
		{
			D(bug("[afs 0x%08lX] VolumeNode in use, keeping as offline\n", volume));
			dl->dol_misc.dol_volume.dol_LockList = MKBADDR(volume->locklist);
		}
		else
		{
			D(bug("[afs 0x%08lX] Removing VolumeNode\n", volume));
			remDosNode(afsbase, dl);
		}
		volume->volumenode = NULL;
	}
}
Exemplo n.º 7
0
BOOL MyRenameDosEntry(struct Handler *handler, struct DosList *entry, const TEXT *name)
{
   LONG error = 0;
   UPINT length;
   TEXT *name_copy, *old_name;

   /* Allocate new string */

   name_copy = NULL;
   if(name != NULL)
   {
      length = StrLen(name);
#ifdef AROS_FAST_BPTR
      name_copy = AllocVec(length + 1, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         CopyMem(name, name_copy, length + 1);
      }
#else
      name_copy = AllocVec(length + 2, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         name_copy[0] = (UBYTE)(length > 255 ? 255 : length); 
         CopyMem(name, name_copy + 1, length + 1);
      }
#endif
      else
         error = IoErr();
   }

   /* Deallocate old string and set new one */

   if(error == 0)
   {
      old_name = BADDR(entry->dol_Name);
      FreeVec(old_name);
      entry->dol_Name = MKBADDR(name_copy);
   }

   /* Store error code and return success flag */

   SetIoErr(error);
   return error == 0;
}
Exemplo n.º 8
0
// Get disk info
LONG GetDiskInfo(char *device,struct InfoData *info)
{
	struct DevProc *proc;
	struct DosList *dos;
	LONG res=0;

	// Get device proc
	if (!(proc=GetDeviceProc(device,0)))
		return 0;

	// Send packet
#ifdef __AROS__
	if (((struct Library *)DOSBase)->lib_Version<50)
	{
		//res=Info(proc->dvp_Lock,info);
		BPTR lock;
		if ((lock=Lock(device,SHARED_LOCK)))
		{
			res=Info(lock,info);
			UnLock(lock);
		}
	}
	else
#endif
	res=DoPkt(proc->dvp_Port,ACTION_DISK_INFO,MKBADDR(info),0,0,0,0);

	// Clear "in use" flag to indicate formatting by default
	info->id_InUse=0;

	// Get doslist pointer
	if ((dos=DeviceFromHandler(proc->dvp_Port,NULL)))
	{
		// Invalid device?
		if (!GetDeviceUnit(dos->dol_misc.dol_handler.dol_Startup,NULL,NULL))
		{
			// Disk can't be formatted
			info->id_InUse=1;
		}
	}

	// Free device proc
	FreeDeviceProc(proc);
	return res;
}
Exemplo n.º 9
0
/*******************************************
 Name  : initDeviceList
 Descr.: initializes a devicelist structure
 Input : devicelist - devicelist structure to initialize
         rootblock  - cacheblock of the rootblock
 Output: DOSTRUE for success; DOSFALSE otherwise
********************************************/
LONG initDeviceList
	(
		struct AFSBase *afsbase,
		struct Volume *volume,
		struct BlockCache *rootblock
	)
{
STRPTR name;
BSTR newname;
UBYTE i;

	name=(char *)rootblock->buffer+(BLK_DISKNAME_START(volume)*4);
	volume->devicelist.dl_Next = 0;
	volume->devicelist.dl_Type = DLT_VOLUME;
	volume->devicelist.dl_Lock = 0;
	volume->devicelist.dl_VolumeDate.ds_Days =
		AROS_BE2LONG(rootblock->buffer[BLK_ROOT_DAYS(volume)]);
	volume->devicelist.dl_VolumeDate.ds_Minute =
		AROS_BE2LONG(rootblock->buffer[BLK_ROOT_MINS(volume)]);
	volume->devicelist.dl_VolumeDate.ds_Tick =
		AROS_BE2LONG(rootblock->buffer[BLK_ROOT_TICKS(volume)]);
	volume->devicelist.dl_LockList = 0;
	volume->devicelist.dl_DiskType = volume->dostype;
	if (volume->devicelist.dl_Name != BNULL)
	{
		newname = volume->devicelist.dl_Name;
	}
	else
	{
		newname = MKBADDR(AllocVec(32,MEMF_CLEAR | MEMF_PUBLIC));
		if (newname == BNULL)
			return DOSFALSE;
	}
	for (i=0; i<name[0]; i++)
		AROS_BSTR_putchar(newname, i, name[i+1]);
	AROS_BSTR_setstrlen(newname, name[0]);
	volume->devicelist.dl_Name = newname;
	return DOSTRUE;
}
Exemplo n.º 10
0
__regargs BPTR LoadExecutable(FileT *fh) {
  HunkT **hunks;
  LONG n, hunkId, hunkNum;
 
  FileRead(fh, ONSTACK(hunkId));
  hunkId &= 0x3FFFFFFF;

  if (hunkId == HUNK_HEADER) {
    /* Skip resident library names. */
    do {
      FileRead(fh, ONSTACK(n));
      if (n == 0) break;
      FileSeek(fh, n * sizeof(LONG), SEEK_CUR);
    } while(1);

    /*
     * number of hunks (including resident libraries and overlay hunks)
     * number of the first (root) hunk
     * number of the last (root) hunk
     */
    {
      struct { LONG hunks, first, last; } s;
      FileRead(fh, ONSTACK(s));
      hunkNum = s.last - s.first + 1;
    }

    hunks = __builtin_alloca(sizeof(HunkT *) * hunkNum);

    if (AllocHunks(fh, hunkNum, hunks)) {
      BPTR seglist = MKBADDR(&(hunks[0]->next));
      if (LoadHunks(fh, hunks))
        return seglist;
      FreeSegList(seglist);
    }
  }

  return NULL;
}
Exemplo n.º 11
0
BOOL MyRenameDosEntry(struct DosList *entry, const TEXT *name)
{
   LONG error = 0;
   UPINT length;
   TEXT *name_copy, *old_name;

   /* Allocate new string */

   name_copy = NULL;
   if(name != NULL)
   {
      length = StrLen(name);
      name_copy = AllocVec(length + 2, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         CopyMem(name, name_copy + 1, length + 1);
         *name_copy = length;
      }
      else
         error = IoErr();
   }

   /* Deallocate old string and set new one */

   if(error == 0)
   {
      old_name = BADDR(entry->dol_Name);
      FreeVec(old_name);
      entry->dol_Name = MKBADDR(name_copy);
   }

   /* Store error code and return success flag */

   SetIoErr(error);
   return error == 0;
}
Exemplo n.º 12
0
static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR conbase)
{
    static const char *devnames[2] = { "CON", "RAW" };
    struct DeviceNode *dn;
    int     	      i;


    /* Really bad hack, but con_handler is in ROM, intuition.library is
       open, if intuition.library is open, then Input.Device must be
       open, too, ... and I don't like to OpenDevice just for Peek-
       Qualifier */

#warning InputDevice open hack. Hope this is not a problem since it is only used for PeekQualifier
    Forbid();
    conbase->inputbase = (struct Device *)FindName(&SysBase->DeviceList, "input.device");
    Permit();

    /* Install CON: and RAW: handlers into device list
     *
     * KLUDGE: con-handler should create only one device node, depending on
     * the startup packet it gets. The mountlists for CON:/RAW: should be into dos.library bootstrap
     * routines.
     */
    for(i = 0; i < 2; i++)
    {
	if((dn = AllocMem(sizeof (struct DeviceNode) + 4 + AROS_BSTR_MEMSIZE4LEN(3),
                          MEMF_CLEAR|MEMF_PUBLIC)))
	{
	    BSTR s = (BSTR)MKBADDR(((IPTR)dn + sizeof(struct DeviceNode) + 3) & ~3);
	    WORD   a;
	    
	    for(a = 0; a < 3; a++)
	    {
		AROS_BSTR_putchar(s, a, devnames[i][a]);
	    }
	    AROS_BSTR_setstrlen(s, 3);

	    dn->dn_Type		= DLT_DEVICE;

	    /* 
	       i equals 1 when dn_DevName is "RAW", and 0 otherwise. This
	       tells con_task that it has to start in RAW mode
	     */   
	    dn->dn_Ext.dn_AROS.dn_Unit		= (struct Unit *)i;

	    dn->dn_Ext.dn_AROS.dn_Device	= &conbase->device;
	    dn->dn_Handler	= NULL;
	    dn->dn_Startup	= NULL;
	    dn->dn_Name		= s;
	    dn->dn_Ext.dn_AROS.dn_DevName	= AROS_BSTR_ADDR(dn->dn_Name);

	    if (AddDosEntry((struct DosList *)dn))
	    {
		if (i == 0)
		    continue;

		return TRUE;
	    }

	    FreeMem(dn, sizeof (struct DeviceNode));
	}
    }

    return FALSE;
}
Exemplo n.º 13
0
/****************************
 Function: VPrintf
   Vector: 159
   Offset: -954
Arguments: D1.L pointer to format string
           D2.L pointer to data array
  Returns: D0.L number of bytes written
****************************/
int lib_dos_f_VPrintf(emumsg_syscall_t *msg)
{
	cpu_t *cpu;
	uint8_t *fptr, *bptr, *sptr;
	uint8_t ch, *buf;
	uint32_t fvptr, dvptr;
	int rc, status, f_long;
	uint16_t data16;
	uint32_t data32;

	DEBUG(4) dprintf("dos.library: lib_dos_f_VPrintf() called\n");
	cpu = msg->proc->cpu;

	DEBUG(5) dprintf("  Format string (D1): 0x%x, Data stream (D2): 0x%x\n",cpu->d[1],cpu->d[2]);

	if(cpu->d[1] == 0) {
		DEBUG(1) dprintf("Warning: dos.library: lib_dos_f_VPrintf() called with NULL format string, skipping\n");
		return HOOK_DONE;
	}

	/* TODO: Implement some kind of check for MMU entry ending within
	         the string
	*/

        /* Allocate a native buffer for the converted native data stream */
        buf = (uint8_t *)AllocVec(LIB_DOS_F_VPRINTF_BUFFER_SIZE,MEMF_PUBLIC|MEMF_CLEAR);
        if(buf == NULL) {
                dprintf("Error: dos.library: lib_dos_f_VPrintf: AllocVec failed for buffer\n");
                return HOOK_END_PROC;
        }
	bptr = buf;

	/* Loop through the string to build a special mapping for the
	   data stream */
	fvptr = cpu->d[1];
	dvptr = cpu->d[2];
	status = 0;
	f_long = 0;

	rc = READMEM_8(fvptr++, &ch);
	if(rc) return rc;

	while(ch != '\0'){
		if(status == 0) {
			/* Idle, look for a % */
			if(ch == '%') {
                                f_long = 0;
                                status = 1;
                        }
                } else {
			/* Got a % */
                        if(ch=='-' || (ch>='0' && ch<='9') || ch=='.') {
				/* Format parameters */

                        } else if(ch=='l') {
				/* Long indicator */
                                f_long = 1;

                        } else if(ch=='d' || ch=='u' || ch=='x' || ch=='c') {
				/* Signed decimal, unsigned decimal,
				   hexadecimal or character */

				if(f_long) {
					/* 32bit data */
					rc = READMEM_32(dvptr, &data32);
					if(rc) return rc;
					dvptr += 4;

					*((ULONG *)bptr)=(ULONG)data32;
					bptr += sizeof(LONG);

				} else {
					/* 16bit data */
					rc = READMEM_16(dvptr, &data16);
					if(rc) return rc;
					dvptr += 2;

					*((UWORD *)bptr)=(UWORD)data32;
					bptr += sizeof(UWORD);

				}
				status = 0;

                        } else if(ch=='s') {
				/* String */

				/* 32bit pointer */
				rc = READMEM_32(dvptr, &data32);
				if(rc) return rc;
				dvptr += 4;

				/* Get native pointer to string */
				sptr = vptr(data32);

				/* TODO: Check mappings */

				*((APTR *)bptr)=(APTR)sptr;
				bptr += sizeof(APTR);

				status = 0;

                        } else if(ch=='b') {
				/* BString */

				/* 32bit pointer */
				rc = READMEM_32(dvptr, &data32);
				if(rc) return rc;
				dvptr += 4;

				/* BPTR -> APTR */
				data32 <<= 2;

				/* Get native pointer to string */
				sptr = vptr(data32);

				/* TODO: Check mappings */

				*((BPTR *)bptr)=MKBADDR((APTR)sptr);
				bptr += sizeof(BPTR);

				status = 0;

                        } else {
				/* Literal % or illegal char */
                                status = 0;
                        }
                }
		rc = READMEM_8(fvptr++, &ch);
		if(rc) return rc;
        }

	fptr = vptr(cpu->d[1]);

	DEBUG(5) dprintf("  Format string (native): %p, Data stream (native): %p\n",fptr,buf);

	/* Prepare syscall */
	msg->arg[0]._strptr = (STRPTR)fptr;
	msg->arg[1]._aptr = (APTR)buf;

	/* Remember buffer */
	msg->internalPtr = buf;

	return HOOK_SYSCALL;
}
Exemplo n.º 14
0
    INPUTS
	task		- The new filesystem handler.

    RESULT
	The old filesystem handler.

    NOTES

    EXAMPLE

    BUGS

    SEE ALSO
	GetFileSysTask()

    INTERNALS

*****************************************************************************/
{
    AROS_LIBFUNC_INIT

    struct Process *pr = (struct Process *)FindTask(NULL);
    BPTR old;

    old = pr->pr_FileSystemTask;
    pr->pr_FileSystemTask = MKBADDR(task);
    return BADDR(old);

    AROS_LIBFUNC_EXIT
} /* SetFileSysTask */
Exemplo n.º 15
0
void packet_handle_request(struct IOFileSys *iofs, struct PacketBase *PacketBase) {
    struct ph_handle *handle;
    struct ph_packet *pkt;
    struct DosPacket *dp;

    D(bug("[packet] got io request %d (%s)\n", iofs->IOFS.io_Command, fsa_str(iofs->IOFS.io_Command)));

    /* get our data back */
    handle = (struct ph_handle *) iofs->IOFS.io_Unit;

    /* make a fresh new packet */
    pkt = packet_alloc();
    dp = &(pkt->dp);

    /* hook the iofs up to the packet so we can find it on return
     * dp_Arg7 should be unused; DoPkt() doesn't touch it */
    dp->dp_Arg7 = (IPTR) iofs;

    /* our reply port will cause packet_reply() to be called when they reply */
    dp->dp_Port = &(handle->mount->reply_port);

    /* convert the command */
    switch (iofs->IOFS.io_Command) {

        case FSA_OPEN:
            D(bug("[packet] OPEN: lock 0x%08x (%s) name '%s' type %s\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_OPEN.io_Filename,
                (iofs->io_Union.io_OPEN.io_FileMode & FMF_LOCK) ? "EXCLUSIVE" : "SHARED"));

            if (!handle->is_lock) {
                /* If passed a filehandle, we can only deal with locking the
                 * filehandle itself or its parent (unless we were to resort
                 * to sending multiple packets)
                 */
                if (iofs->io_Union.io_OPEN.io_Filename[0] == '\0') {
                    dp->dp_Type = ACTION_COPY_DIR_FH;
                    dp->dp_Arg1 = (IPTR) handle->actual;
                }
                else if (iofs->io_Union.io_OPEN.io_Filename[0] == '/' &&
                    iofs->io_Union.io_OPEN.io_Filename[1] == '\0') {
                    dp->dp_Type = ACTION_PARENT_FH;
                    dp->dp_Arg1 = (IPTR) handle->actual;
                }
                else {
                    iofs->io_DosError = ERROR_NOT_IMPLEMENTED;
                    goto reply;
                }
            }
            else {
                dp->dp_Type = ACTION_LOCATE_OBJECT;
                dp->dp_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_OPEN.io_Filename);
                dp->dp_Arg3 = (iofs->io_Union.io_OPEN.io_FileMode & FMF_LOCK) ? EXCLUSIVE_LOCK : SHARED_LOCK;
            }

            break;

        case FSA_OPEN_FILE: {
            ULONG mode = iofs->io_Union.io_OPEN_FILE.io_FileMode;
            struct ph_handle *new_handle;

            D(bug("[packet] OPEN_FILE: lock 0x%08x (%s) name '%s' mode 0x%x prot 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_OPEN_FILE.io_Filename,
                mode,
                iofs->io_Union.io_OPEN_FILE.io_Protection));

            /* convert modes to the proper packet type (as best we can) */
            if ((mode & FMF_CLEAR) != 0)
                dp->dp_Type = ACTION_FINDOUTPUT;
            else if ((mode & FMF_CREATE) != 0)
                dp->dp_Type = ACTION_FINDUPDATE;
            else
                dp->dp_Type = ACTION_FINDINPUT;
            if ((mode & FMF_APPEND) != 0) {
                iofs->io_DosError = ERROR_BAD_NUMBER;
                goto reply;
            }

            /* make a new handle */
            new_handle =
                (struct ph_handle *) AllocMem(sizeof(struct ph_handle),
                MEMF_PUBLIC | MEMF_CLEAR);
            if (new_handle == NULL) {
                iofs->io_DosError = ERROR_NO_FREE_STORE;
                goto reply;
            }

            /* dos.lib buffer stuff, must be initialised this way */
            new_handle->fh.fh_Pos = new_handle->fh.fh_End = (UBYTE *) -1;

            dp->dp_Arg1 = (IPTR) MKBADDR(&new_handle->fh);
            dp->dp_Arg2 = (IPTR) (handle->is_lock ? handle->actual : NULL);
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_OPEN.io_Filename);

            break;
        }

        case FSA_CLOSE:
            D(bug("[packet] CLOSE: lock 0x%08x (%s)\n",
                handle->actual, handle_desc(handle)));

            /* if this is the root handle, then we previously intercepted a
             * call and returned it (e.g. FSA_OPEN/ACTION_PARENT), so we don't
             * want the handler to do anything */
            if (handle == &(handle->mount->root_handle)) {
                iofs->IOFS.io_Unit = NULL;
                goto reply;
            }

            dp->dp_Type = (handle->is_lock) ? ACTION_FREE_LOCK : ACTION_END;
            dp->dp_Arg1 = (IPTR) handle->actual;
            break;

        case FSA_READ:
            D(bug("[packet] READ: handle 0x%08x buf 0x%08x len %ld\n",
                handle->actual,
                iofs->io_Union.io_READ.io_Buffer,
                iofs->io_Union.io_READ.io_Length));

            dp->dp_Type = ACTION_READ;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_READ.io_Buffer;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_READ.io_Length;

            /* DOSFALSE == 0, so we can't distinguish between a zero-length
             * read and an actual error. So, we reset the length here. If the
             * returned packet is DOSFALSE, but no error, this will make sure
             * DOS gets the right length back */
            iofs->io_Union.io_READ.io_Length = 0;
            break;

        case FSA_WRITE:
            D(bug("[packet] WRITE: handle 0x%08x buf 0x%08x len %ld\n",
                handle->actual,
                iofs->io_Union.io_WRITE.io_Buffer,
                iofs->io_Union.io_WRITE.io_Length));

            dp->dp_Type = ACTION_WRITE;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_WRITE.io_Buffer;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_WRITE.io_Length;

            iofs->io_Union.io_WRITE.io_Length = 0;
            break;

        case FSA_SEEK:
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_SEEK.io_SeekMode;

            bug("[packet] SEEK: handle 0x%08x offset %ld mode %ld (%s)\n",
                handle->actual,
                (LONG) iofs->io_Union.io_SEEK.io_Offset,
                mode,
                mode == OFFSET_BEGINNING ? "OFFSET_BEGINNING" :
                mode == OFFSET_CURRENT   ? "OFFSET_CURRENT"   :
                mode == OFFSET_END       ? "OFFSET_END"       :
                                           "[unknown]");
        }
#endif

            dp->dp_Type = ACTION_SEEK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_SEEK.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_SEEK.io_SeekMode;
            break;

        case FSA_SET_FILE_SIZE:
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode;

            bug("[packet] SET_FILE_SIZE: handle 0x%08x offset %ld mode %ld (%s)\n",
                handle->actual,
                (LONG) iofs->io_Union.io_SET_FILE_SIZE.io_Offset,
                mode,
                mode == OFFSET_BEGINNING ? "OFFSET_BEGINNING" :
                mode == OFFSET_CURRENT   ? "OFFSET_CURRENT"   :
                mode == OFFSET_END       ? "OFFSET_END"       :
                                           "[unknown]");
        }
#endif

            dp->dp_Type = ACTION_SET_FILE_SIZE;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_SET_FILE_SIZE.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode;
            break;

        case FSA_FILE_MODE: {

            D(bug("[packet] FILE_MODE: object 0x%08x (%s) mode 0x%x\b\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_FILE_MODE.io_FileMode));

            dp->dp_Type = ACTION_CHANGE_MODE;

            /* We can only change access mode */
            if ((iofs->io_Union.io_FILE_MODE.io_Mask & FMF_LOCK) == 0) {
                iofs->io_DosError = 0;
                goto reply;
            }
            if (handle->is_lock) {
                dp->dp_Arg1 = CHANGE_LOCK;
                dp->dp_Arg2 = (IPTR) handle->actual;
            }
            else {
                dp->dp_Arg1 = CHANGE_FH;
                handle->fh.fh_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) MKBADDR(&handle->fh);
            }
            dp->dp_Arg3 = (iofs->io_Union.io_FILE_MODE.io_FileMode & FMF_LOCK) ?
                EXCLUSIVE_LOCK : SHARED_LOCK;

            break;
        }

        case FSA_IS_INTERACTIVE:
            /* XXX is there some other way to query this? how does (eg) aos
             * console handler do it? */
            iofs->io_Union.io_IS_INTERACTIVE.io_IsInteractive = FALSE;
            iofs->io_DosError = 0;
            goto reply;

        case FSA_SAME_LOCK: {
            struct ph_handle *h1, *h2;
            h1 = (struct ph_handle *) iofs->io_Union.io_SAME_LOCK.io_Lock[0];
            h2 = (struct ph_handle *) iofs->io_Union.io_SAME_LOCK.io_Lock[1];

            D(bug("[packet] SAME_LOCK: lock1 0x%08x (%s) lock2 0x%08x (%s)\n",
                h1->actual, handle_desc(h1), h2->actual, handle_desc(h2)));

            dp->dp_Type = ACTION_SAME_LOCK;
            dp->dp_Arg1 = (IPTR) h1->actual;
            dp->dp_Arg2 = (IPTR) h2->actual;
            break;
        }

        case FSA_EXAMINE: {
            struct FileInfoBlock *fib;

            D(bug("[packet] EXAMINE: lock 0x%08x (%s)\n",
                handle->actual, handle_desc(handle)));

            fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC | MEMF_CLEAR);

            dp->dp_Type = (handle->is_lock) ? ACTION_EXAMINE_OBJECT : ACTION_EXAMINE_FH;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) MKBADDR(fib);
            break;
        }

        case FSA_EXAMINE_NEXT:
            D(bug("[packet] EXAMINE_NEXT: lock 0x%08x (%s) fib 0x%08x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_EXAMINE_NEXT.io_fib));

            dp->dp_Type = ACTION_EXAMINE_NEXT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) MKBADDR(iofs->io_Union.io_EXAMINE_NEXT.io_fib);
            break;

        case FSA_CREATE_DIR:
            D(bug("[packet] CREATE_DIR: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_CREATE_DIR.io_Filename));

            dp->dp_Type = ACTION_CREATE_DIR;
            dp->dp_Arg1 = (IPTR) (handle->is_lock ? handle->actual : NULL);
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_CREATE_DIR.io_Filename);
            break;

        case FSA_IS_FILESYSTEM:
            dp->dp_Type = ACTION_IS_FILESYSTEM;
            break;

        case FSA_DISK_INFO:
            dp->dp_Type = ACTION_DISK_INFO;
            dp->dp_Arg1 = (IPTR) MKBADDR(iofs->io_Union.io_INFO.io_Info);
            break;

        case FSA_CREATE_HARDLINK:
            {
                struct ph_handle *target = (struct ph_handle *)
                    iofs->io_Union.io_CREATE_HARDLINK.io_OldFile;

                D(bug("[packet] CREATE_HARDLINK: lock 0x%08x (%s) name '%s' "
                    "target 0x%08x (%s)\n",
                    handle->actual, handle_desc(handle),
                    iofs->io_Union.io_CREATE_HARDLINK.io_Filename,
                    target->actual, handle_desc(target)));

                dp->dp_Type = ACTION_MAKE_LINK;
                dp->dp_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool,
                    iofs->io_Union.io_CREATE_HARDLINK.io_Filename);
                dp->dp_Arg3 = (IPTR) target->actual;
                dp->dp_Arg4 = LINK_HARD;
                break;
            }

        case FSA_CREATE_SOFTLINK:
            D(bug("[packet] CREATE_SOFTLINK: lock 0x%08x (%s) name '%s' target '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_CREATE_SOFTLINK.io_Filename,
                iofs->io_Union.io_CREATE_SOFTLINK.io_Reference));

            dp->dp_Type = ACTION_MAKE_LINK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_CREATE_SOFTLINK.io_Filename);
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_CREATE_SOFTLINK.io_Reference;
            dp->dp_Arg4 = LINK_SOFT;
            break;

        case FSA_RENAME:
            D(bug("[packet] RENAME: lock 0x%08x (%s) name '%s' target '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_RENAME.io_Filename,
                iofs->io_Union.io_RENAME.io_NewName));

            /* XXX the two paths from FSA_RENAME are copied directly from the
             * arguments to rename with no changes, so they may contain volume
             * specifiers, path seperators, etc. both can be calculated
             * relative to the handle. here we just pass them through to the
             * handler as-is, but I'm not sure if that's right. fat.handler at
             * least will do the right thing. this probably needs to be
             * revisited if another packet-based handler is ported */

            dp->dp_Type = ACTION_RENAME_OBJECT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RENAME.io_Filename);
            dp->dp_Arg3 = (IPTR) handle->actual;
            dp->dp_Arg4 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RENAME.io_NewName);
            break;

        case FSA_READ_SOFTLINK:
            D(bug("[packet] READ_SOFTLINK: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_READ_SOFTLINK.io_Filename));

            dp->dp_Type = ACTION_READ_LINK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Filename;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Buffer;
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Size;
            break;

        case FSA_DELETE_OBJECT:
            D(bug("[packet] DELETE: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_DELETE_OBJECT.io_Filename));

            dp->dp_Type = ACTION_DELETE_OBJECT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_DELETE_OBJECT.io_Filename);
            break;

        case FSA_SET_COMMENT:
            D(bug("[packet] SET_COMMENT: lock 0x%08x (%s) name '%s' comment '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_COMMENT.io_Filename,
                iofs->io_Union.io_SET_COMMENT.io_Comment));

            dp->dp_Type = ACTION_SET_COMMENT;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_COMMENT.io_Filename);
            dp->dp_Arg4 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_COMMENT.io_Comment);
            break;
            
        case FSA_SET_PROTECT:
            D(bug("[packet] SET_PROTECT: lock 0x%08x (%s) name '%s' attrs 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_PROTECT.io_Filename,
                iofs->io_Union.io_SET_PROTECT.io_Protection));

            dp->dp_Type = ACTION_SET_PROTECT;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_PROTECT.io_Filename);
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_SET_PROTECT.io_Protection;
            break;

        case FSA_SET_OWNER: /* XXX untested */
            D(bug("[packet] SET_OWNER: lock 0x%08x (%s) name '%s' uid 0x%x gid 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_OWNER.io_Filename,
                iofs->io_Union.io_SET_OWNER.io_UID,
                iofs->io_Union.io_SET_OWNER.io_GID));

            dp->dp_Type = ACTION_SET_OWNER;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_OWNER.io_Filename);
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_SET_OWNER.io_GID << 16 |
                                 iofs->io_Union.io_SET_OWNER.io_UID;
            break;

        case FSA_SET_DATE: /* XXX untested */
#if defined(DEBUG) && DEBUG != 0
        {
            struct DateTime dt;
            char datestr[LEN_DATSTRING];

            dt.dat_Stamp = iofs->io_Union.io_SET_DATE.io_Date;
            dt.dat_Format = FORMAT_DOS;
            dt.dat_Flags = 0;
            dt.dat_StrDay = NULL;
            dt.dat_StrDate = datestr;
            dt.dat_StrTime = NULL;
            DateToStr(&dt);

            bug("[packet] SET_DATE: lock 0x%08x (%s) name '%s' date '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_DATE.io_Filename,
                datestr);
        }
#endif

            dp->dp_Type = ACTION_SET_DATE;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_DATE.io_Filename);
            dp->dp_Arg4 = (IPTR) &iofs->io_Union.io_SET_DATE.io_Date;
            break;

        case FSA_MORE_CACHE: /* XXX untested */
            D(bug("[packet] MORE_CACHE: buffers '0x%x'\n", iofs->io_Union.io_MORE_CACHE.io_NumBuffers));

            dp->dp_Type = ACTION_MORE_CACHE;
            dp->dp_Arg1 = (IPTR) iofs->io_Union.io_MORE_CACHE.io_NumBuffers;
            break;

        case FSA_FORMAT: /* XXX untested */
            D(bug("[packet] FSA_FORMAT: name '%s' type 0x%x\n",
                  iofs->io_Union.io_FORMAT.io_VolumeName,
                  iofs->io_Union.io_FORMAT.io_DosType));

            dp->dp_Type = ACTION_FORMAT;
            dp->dp_Arg1 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_FORMAT.io_VolumeName);
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_FORMAT.io_DosType;
            break;

        case FSA_INHIBIT:
            D(bug("[packet] FSA_INHIBIT: %sinhibit\n", iofs->io_Union.io_INHIBIT.io_Inhibit == 0 ? "un" : ""));

            dp->dp_Type = ACTION_INHIBIT;
            dp->dp_Arg1 = iofs->io_Union.io_INHIBIT.io_Inhibit ? DOSTRUE : DOSFALSE;
            break;

        case FSA_RELABEL:
            D(bug("[packet] FSA_RELABEL: name '%s'\n", iofs->io_Union.io_RELABEL.io_NewName));

            dp->dp_Type = ACTION_RENAME_DISK;
            dp->dp_Arg1 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RELABEL.io_NewName);
            break;

        case FSA_LOCK_RECORD: /* XXX untested */
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_RECORD.io_RecordMode;

            bug("[packet] FSA_LOCK_RECORD: handle 0x%08x offset %ld size %ld mode %d (%s) timeout %d\n",
                handle->actual,
                (LONG) iofs->io_Union.io_RECORD.io_Offset,
                iofs->io_Union.io_RECORD.io_Size,
                mode,
                mode == REC_EXCLUSIVE       ? "REC_EXCLUSIVE"       :
                mode == REC_EXCLUSIVE_IMMED ? "REC_EXCLUSIVE_IMMED" :
                mode == REC_SHARED          ? "REC_SHARED"          :
                mode == REC_SHARED_IMMED    ? "REC_SHARED_IMMED"    :
                                              "[unknown]",
                iofs->io_Union.io_RECORD.io_Timeout);
        }
#endif

            dp->dp_Type = ACTION_LOCK_RECORD;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_RECORD.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_RECORD.io_Size;
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_RECORD.io_RecordMode;
            dp->dp_Arg5 = (IPTR) iofs->io_Union.io_RECORD.io_Timeout;
            break;

        case FSA_UNLOCK_RECORD: /* XXX untested */
            D(bug("[packet] FSA_UNLOCK_RECORD: handle 0x%08x offset %ld size %ld\n",
                  handle->actual,
                  (LONG) iofs->io_Union.io_RECORD.io_Offset,
                  iofs->io_Union.io_RECORD.io_Size));

            dp->dp_Type = ACTION_FREE_RECORD;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_RECORD.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_RECORD.io_Size;
            break;

        case FSA_ADD_NOTIFY:
            D(bug("[packet] FSA_ADD_NOTIFY: nr 0x%08x name '%s'\n", 
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest,
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest->nr_FullName));

            dp->dp_Type = ACTION_ADD_NOTIFY;
            dp->dp_Arg1 =
                (SIPTR) iofs->io_Union.io_NOTIFY.io_NotificationRequest;
            break;

        case FSA_REMOVE_NOTIFY:
            D(bug("[packet] FSA_REMOVE_NOTIFY: nr 0x%08x name '%s'\n", 
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest,
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest->nr_FullName));

            dp->dp_Type = ACTION_REMOVE_NOTIFY;
            dp->dp_Arg1 =
                (SIPTR) iofs->io_Union.io_NOTIFY.io_NotificationRequest;
            break;

        /* XXX implement */
        case FSA_EXAMINE_ALL:
        case FSA_EXAMINE_ALL_END:
        case FSA_MOUNT_MODE:
        case FSA_CHANGE_SIGNAL:
        case FSA_PARENT_DIR:
        case FSA_PARENT_DIR_POST:
        case FSA_CONSOLE_MODE:
            D(bug("[packet] command not implemented\n"));
            iofs->io_DosError = ERROR_NOT_IMPLEMENTED;
            goto reply;

        default:
            D(bug("[packet] unknown command\n"));
            iofs->io_DosError = ERROR_ACTION_NOT_KNOWN;
            goto reply;
    }

    D(bug("[packet] converted to %s packet\n", act_str(dp->dp_Type)));

    /* WaitIO() will look into this */
    iofs->IOFS.io_Message.mn_Node.ln_Type = NT_MESSAGE;

    /* since these all go to the packet handler process, they can't be done now */
    iofs->IOFS.io_Flags &= ~IOF_QUICK;

    /* send the packet */
    PutMsg(&(handle->mount->process->pr_MsgPort), dp->dp_Link);

    return;

    /* jump here to reply to the packet now, handling IOF_QUICK appropriately */
reply:
    D(bug("[packet] replying directly with error %d\n", iofs->io_DosError));
    
    /* kill the packet */
    DeletePool(pkt->pool);

    /* if they can handle quick replies, just bail out */
    if (iofs->IOFS.io_Flags & IOF_QUICK)
        return;

    /* otherwise tell them properly */
    ReplyMsg((APTR) iofs);
}
Exemplo n.º 16
0
void IOFS_SendPkt(struct DosPacket *dp, struct MsgPort *replyport, struct DosLibrary *DOSBase)
{
    /*
     * Trying to emulate the packet system by rewriting the
     * packets to IO Requests. Sometimes there are too many
     * parameters in the packet but thats fine. If there are
     * not enough parameters or the wrong type etc. then
     * it is more difficult to translate the packet.
     *
     */

    struct IOFileSys  *iofs = AllocMem(sizeof(struct IOFileSys), MEMF_CLEAR);
    struct FileHandle *fh;
    BPTR               oldCurDir;
    LONG               result; 
     
    if (iofs != NULL)
    {
	/*
	 * Also attach the packet to the io request.
	 * Will remain untouched by the driver.
	 */

	iofs->io_PacketEmulation = dp;
    
	/*
	 * In case the packet is to be aborted 
	 * I know which IORequest to use. The user will
	 * use the packet itself to abort the operation.
	 */
	dp->dp_Arg7 = (IPTR)iofs;


	iofs->IOFS.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
	iofs->IOFS.io_Message.mn_ReplyPort = replyport;
	iofs->IOFS.io_Message.mn_Length = sizeof(struct IOFileSys);
	iofs->IOFS.io_Flags = 0;

        /*
         * Have to rewrite this packet...
         */

        switch (dp->dp_Type)
	{
	case ACTION_NIL:
	case ACTION_READ_RETURN:
	case ACTION_WRITE_RETURN:
	case ACTION_TIMER:
	    kprintf("This packet is a reserved one and should not be sent"
		    " by you!\n");
	    // Alert();
	    return;
	    
	    // case ACTION_GET_BLOCK:
	case ACTION_DISK_CHANGE:
	case ACTION_DISK_TYPE:
	case ACTION_EVENT:
	case ACTION_SET_MAP:
	    
	    kprintf("This packet is obsolete. (ACTION type %d)\n",
		    dp->dp_Type);
	    return;


	case ACTION_FINDINPUT:      // Open() MODE_OLDFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		kprintf("Error: Didn't find file\n");
		return;
	    }
	    
	    kprintf("Returned from DoNameAsynch()\n");

	    break;
	    
	case ACTION_FINDOUTPUT:     // Open() MODE_NEWFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_LOCK |
		FMF_CREATE | FMF_CLEAR | FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;
	    

	case ACTION_FINDUPDATE:     // Open() MODE_READWRITE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_CREATE |
		FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_READ:           // Read() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_READ;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;
	    
	    break;


	case ACTION_WRITE:          // Write() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_WRITE;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;

	    break;

	case ACTION_SEEK:           // Seek()      [*] CH
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;

	    /* If the file is in write mode flush it. This is done
	       synchronously as otherwise the seek may be served before
	       the flush. (TODO: What are a reasonable semantics here?) */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }
	    else
	    {
		/* Read mode. Just reinit the buffers. We can't call
		   Flush() in this case as that would end up in recursion. */
		fh->fh_Pos = fh->fh_End = fh->fh_Buf;
	    }
	    
	    iofs->IOFS.io_Command = FSA_SEEK;
	    iofs->io_Union.io_SEEK.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SEEK.io_SeekMode = dp->dp_Arg3;
	    
	    break;
	    
	case ACTION_SET_FILE_SIZE:  // SetFileSize()        [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_FILE_SIZE;
	    iofs->io_Union.io_SET_FILE_SIZE.io_Offset   = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode = dp->dp_Arg3;
	    break;

	case ACTION_EXAMINE_FH:     // ExamineFH()
	case ACTION_EXAMINE_OBJECT: // Examine() [*]  --  the same thing
	                            //                    in AROS
	    {
		UBYTE *buffer = AllocVec(sizeof(struct ExAllData), 
					 MEMF_PUBLIC | MEMF_CLEAR);

		if (buffer == NULL)
		{
		    dp->dp_Res1 = DOSFALSE;
		    dp->dp_Res2 = ERROR_NO_FREE_STORE;

		    return;
		}
		
		fh = (struct FileHandle *)dp->dp_Arg1;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;
		
		iofs->IOFS.io_Command = FSA_EXAMINE;
		iofs->io_Union.io_EXAMINE.io_ead = (struct ExAllData *)buffer;
		iofs->io_Union.io_EXAMINE.io_Size = sizeof(struct ExAllData);
		iofs->io_Union.io_EXAMINE.io_Mode = ED_OWNER;

		/* A supplied FileInfoBlock (is a BPTR) is in dp_Arg2 */
		
		break;
	    }
	    
	case ACTION_EXAMINE_NEXT:   // ExNext() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_EXAMINE_NEXT;
	    iofs->io_Union.io_EXAMINE_NEXT.io_fib = (BPTR)dp->dp_Arg2;
	    
	    break;	    

	case ACTION_CREATE_DIR:     // CreateDir() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_CREATE_DIR;
	    iofs->io_Union.io_CREATE_DIR.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->io_Union.io_CREATE_DIR.io_Protection = 0;
	    
	    break;

	    
	case ACTION_DELETE_OBJECT:  // DeleteFile()     [*]
	    // ARG1:   LOCK    Lock to which ARG2 is relative
	    // ARG2:   BSTR    Name of object to delete (relative to ARG1)
	    
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* IFS_DELETE_OBJECT just consists of a STRPTR so we have to
	       use NameFromLock() here -- TODO */
	    // iofs->io_Union.io_DELETE_OBJECT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->IOFS.io_Command = FSA_DELETE_OBJECT;
	    
	    break;

	case ACTION_RENAME_OBJECT:  // Rename()
	    /* TODO */
	    break;

	case ACTION_LOCK_RECORD:    // LockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);

	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    iofs->io_Union.io_RECORD.io_Timeout = (LONG)dp->dp_Arg5;
	    break;
	    
	case ACTION_FREE_RECORD:    // UnlockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    break; 

	case ACTION_PARENT:         // ParentDir()     [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ; // Shared lock
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "/", DOSBase);
	    CurrentDir(oldCurDir);
	    
	    if (result != 0)
	    {
		return;
	    }

	    return;

	case ACTION_SET_PROTECT:    // SetProtection()    [*]
	    // STRPTR io_Filename;   /* The file to change. */
	    // ULONG  io_Protection; /* The new protection bits. */

	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    	
	    iofs->IOFS.io_Command = FSA_SET_PROTECT;
	    iofs->io_Union.io_SET_PROTECT.io_Protection = dp->dp_Arg4;
	    iofs->io_Union.io_SET_PROTECT.io_Filename = BStrtoCStr(dp->dp_Arg3);
		
	    break;
	    
	case ACTION_SET_COMMENT:    // SetComment()       [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_COMMENT;
	    iofs->io_Union.io_SET_COMMENT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg3);
	    iofs->io_Union.io_SET_COMMENT.io_Comment = BStrtoCStr(dp->dp_Arg4);
	    
	    break;

	case ACTION_LOCATE_OBJECT:  // Lock()         [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    switch (dp->dp_Arg3)
	    {
	    case EXCLUSIVE_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_LOCK | FMF_READ;
		break;
		
	    case SHARED_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		break;
		
	    default:
		iofs->io_Union.io_OPEN.io_FileMode = dp->dp_Arg3;
		break;
	    }
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg2),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_COPY_DIR:       // DupLock()
	case ACTION_COPY_DIR_FH:    // DupLockFromFH() -- the same thing
	                            //                    in AROS
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    /* Create a shared lock */
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "", DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_END:            // Close() [*]
	case ACTION_FREE_LOCK:      // UnLock() -- the same thing in AROS
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* If the filehandle has a pending write on it Flush() the buffer.
	       This is made synchronously... */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }

	    iofs->IOFS.io_Command = FSA_CLOSE;

	    break;

	case ACTION_SET_DATE:       // SetFileDate() [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_DATE;
	    memcpy(&iofs->io_Union.io_SET_DATE.io_Date, (APTR)dp->dp_Arg4,
		   sizeof(struct DateStamp));

	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_SAME_LOCK:      // SameLock() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SAME_LOCK;
	    
	    iofs->io_Union.io_SAME_LOCK.io_Lock[0] = BADDR((BPTR)dp->dp_Arg1);
	    iofs->io_Union.io_SAME_LOCK.io_Lock[1] = BADDR((BPTR)dp->dp_Arg2);
	    
	    break;
	    
	case ACTION_MAKE_LINK:      // MakeLink()
	    {
		STRPTR name = BStrtoCStr(dp->dp_Arg2);
	    
		if (dp->dp_Arg4 == LINK_SOFT)
		{
		    /* We want a soft-link. */
		    iofs->IOFS.io_Command = FSA_CREATE_SOFTLINK;
		    iofs->io_Union.io_CREATE_SOFTLINK.io_Reference = (STRPTR)dp->dp_Arg3;
		}
		else
		{
		    /* We want a hard-link. */
		    struct FileHandle *fh = (struct FileHandle *)BADDR((BPTR)dp->dp_Arg3);
                    struct DevProc *dvp;

		    /* We check, if name and dest are on the same device. */
                    if ((dvp = GetDeviceProc(name, NULL)) == NULL)
		    {
			/* TODO: Simulate packet return */
			return;
		    }
		    
		    if (dvp->dvp_Port != (struct MsgPort *)fh->fh_Device)
		    {
                        FreeDeviceProc(dvp);
			SetIoErr(ERROR_RENAME_ACROSS_DEVICES);
			
			/* TODO: Simulate packet return */
			return;
		    }

                    FreeDeviceProc(dvp);
		    
		    iofs->IOFS.io_Command = FSA_CREATE_HARDLINK;
		    iofs->io_Union.io_CREATE_HARDLINK.io_OldFile = fh->fh_Unit;
		}
		
		oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
		DoNameAsynch(iofs, name, DOSBase);
		CurrentDir(oldCurDir);
	    }
	    
	    break;
	    
	case ACTION_READ_LINK:      // ReadLink()
	    /* TODO */
	    break;
	    
	case ACTION_EXAMINE_ALL:    // ExAll()
	    /* TODO */
	    break;
	    
	case ACTION_ADD_NOTIFY:     // StartNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);
	        struct FileHandle *dir;

		iofs->IOFS.io_Command = FSA_ADD_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;

		notify->nr_MsgCount = 0;

		if (strchr(notify->nr_Name, ':') != NULL)
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    dir = BADDR(CurrentDir(NULL));
		    CurrentDir(MKBADDR(dir));	/* Set back the current dir */
		    
		    if (dir == NULL)
		    {
			return;
		    }
		    
		    iofs->IOFS.io_Device = dir->fh_Device;
		    iofs->IOFS.io_Unit = dir->fh_Unit;
		    
		    /* Save device for EndNotify() purposes */
		    notify->nr_Handler = (struct MsgPort *) dir->fh_Device;
	
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    
	case ACTION_REMOVE_NOTIFY:  // EndNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);

		iofs->IOFS.io_Command = FSA_REMOVE_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;
		
		if (strchr(notify->nr_Name, ':'))
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    iofs->IOFS.io_Device = (struct Device *)notify->nr_Handler;
		    
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    

	    /* The following five packets are only relative to the
	       message port of the file system to send to. Therefore, 
	       we fill in only partial information in the IOFileSys and
	       hope for the best... Specifically, the device cannot
	       use iofs->io_Device. TODO */
	case ACTION_RENAME_DISK:    // Relabel()
	    /* TODO */
	    break;

	case ACTION_FORMAT:         // Format()
	    /* TODO */
	    break;
	    
	case ACTION_MORE_CACHE:     // AddBuffers()
	    /* TODO */
	    break;
	    
	case ACTION_INHIBIT:        // Inhibit()
	    /* TODO */
	    break;

	case ACTION_IS_FILESYSTEM:  // IsFileSystem()
	    /* TODO */
	    break;

	case ACTION_DISK_INFO:      // Info()
	    /* TODO */
	    break;

	case ACTION_INFO:           // No associated function
	    /* TODO */
	    break;

	case ACTION_CURRENT_VOLUME: // No associated function
	    /* TODO */
	    break;

	case ACTION_PARENT_FH:      // ParentOfFH()
	    /* TODO -- Should be the same as ACTION_PARENT? For some reason
	               ParentDir() and ParentOfFH() is implemented differently
	               in AROS. Have to investigate this further. */
	    break;
	    
	case ACTION_FH_FROM_LOCK:   // OpenFromLock()
	    /* TODO: Have so simulate ReplyMsg() here */
	    return;

	case ACTION_SET_OWNER:      // SetOwner()
	    // Unfortunately, I have no info regardning this packet.
	    
	    // iofs->IOFS.io_Command = FSA_SET_OWNER;
	    // iofs->io_Union.io_SET_OWNER.io_UID = owner_info >> 16;
	    // iofs->io_Union.io_SET_OWNER.io_GID = owner_info & 0xffff;
	    
	    break;

	case ACTION_CHANGE_MODE:    // ChangeMode()
	    /* TODO */
	    break;

	    /* I haven't looked into the following packets in detail */
	case ACTION_DIE:            // No associated function
	    break;
	    
	case ACTION_WRITE_PROTECT:  // No associated function
	    break;
	    
	case ACTION_FLUSH:          // No associated function
	    break;
	    
	case ACTION_SERIALIZE_DISK: // No associated function
	    break;
	    

	    // ---  Console only packets  ------------------------------
	    /* I think these should not be implemented as packets except
	       for ACTION_WAIT_CHAR which is not really a console only
	       packet. Instead functions should be added to console.device */

	case ACTION_SCREEN_MODE:    // SetMode()
	    /* TODO*/
	    break;
	    
	case ACTION_CHANGE_SIGNAL:  // No associated function
	    {
	    	struct MsgPort *msgport;
		struct Task    *task;
		
		fh = (struct FileHandle *)dp->dp_Arg1;
    	    	msgport = (struct MsgPort *)dp->dp_Arg2;
		task = msgport ? msgport->mp_SigTask : NULL;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;

		iofs->IOFS.io_Command = FSA_CHANGE_SIGNAL;
		iofs->io_Union.io_CHANGE_SIGNAL.io_Task = task;
	    }
	    break;
	    
	case ACTION_WAIT_CHAR:      // WaitForChar()	
	    /* TODO */
	    break;

	default:
	    D(kprintf("Unknown packet type %d found in SendPkt()\n", dp->dp_Type));
            dp->dp_Res1 = DOSFALSE;
            dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
            PutMsg(replyport, dp->dp_Link);
	    return;
	}

	D(kprintf("Calling SendIO() with command %u\n", iofs->IOFS.io_Command));
	
	SendIO((struct IORequest *)iofs);
    }        
 
}
Exemplo n.º 17
0
/* Mount a volume with the given name; route all handler
** messages to the given port.
*/
struct DeviceNode *Mount(char *name, struct MsgPort *port)
{
   struct DeviceNode *volume;
   struct DosList *dlist;
   struct FileSysStartupMsg *fssm = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_CLEAR);
   struct DosEnvec  *dosenvec = AllocVec(sizeof(struct DosEnvec), MEMF_CLEAR);

   if(name == NULL || port == NULL) return NULL;

	/* make dosenvec */
	/* test: bpt=8,hc=1250000 */
	/* zip: bpt=8,hc=24575 */
	dosenvec->de_TableSize = 17;
	dosenvec->de_SizeBlock = 128;
	dosenvec->de_Surfaces = 16;		// 1;          // !!
	dosenvec->de_SectorPerBlock = 1;
	dosenvec->de_BlocksPerTrack = 63;	// 8;	//555;  // !!
	dosenvec->de_Reserved = 2;
	dosenvec->de_LowCyl = 2;		// 0;         // !!
	dosenvec->de_HighCyl = 14759;	// 1250000;        // !!
	dosenvec->de_NumBuffers = 350;
	dosenvec->de_BufMemType = 0;
	dosenvec->de_MaxTransfer = 0x1ffff;
	dosenvec->de_Mask = 0x7ffffffe;
	dosenvec->de_DosType = 0x6d757577;      //ID_MUAF_DISK;     //  0x6D754653; //ID_PFS_DISK or just fun: 0x6d757575;
	dosenvec->de_BootBlocks = 2;

	/* make fssm */
	fssm->fssm_Unit = 1;		// 5;                // !!
	fssm->fssm_Device = MKBADDR(devicename);
	fssm->fssm_Environ = MKBADDR(dosenvec);
	fssm->fssm_Flags = 0;

	while(!(dlist = AttemptLockDosList(LDF_DEVICES|LDF_WRITE)))
	{
		/* Can't lock the DOS list.  Wait a second and try again. */
		Delay(50);
	}
	volume = (struct DeviceNode *)FindDosEntry(dlist, name, LDF_DEVICES);
	if(volume) RemDosEntry((struct DosList *)volume);
	UnLockDosList(LDF_DEVICES|LDF_WRITE);

	if(!volume && !(volume = (struct DeviceNode *)MakeDosEntry(name, DLT_DEVICE)))
		return NULL;
   
	volume->dn_Startup = MKBADDR(fssm);
	volume->dn_Lock = NULL;
	volume->dn_GlobalVec = -1;

	/* Now we can own the volume by giving it our msgport */
	volume->dn_Task = port;

	while(!(dlist = AttemptLockDosList(LDF_DEVICES|LDF_WRITE)))
	{
	  /* Oops, can't lock DOS list.  Wait 1 second and retry. */
	  Delay(50);
	}
	AddDosEntry((struct DosList *)volume);
	UnLockDosList(LDF_DEVICES|LDF_WRITE);

	return volume;
}
Exemplo n.º 18
0
// Open a disk for IO
DiskHandle *LIBFUNC L_OpenDisk(
    REG(a0, char *disk),
    REG(a1, struct MsgPort *port))
{
    DiskHandle *handle;
    struct DosList *dl;
    unsigned long blocks;
    char *ptr;

    // Allocate handle
    if (!(handle=AllocVec(sizeof(DiskHandle),MEMF_CLEAR)))
        return 0;

    // Copy name, strip colon
    stccpy(handle->dh_name,disk,31);
    if ((ptr=strchr(handle->dh_name,':'))) *ptr=0;

    // Lock DOS list
    dl=LockDosList(LDF_DEVICES|LDF_READ);

    // Find entry
    if (!(dl=FindDosEntry(dl,handle->dh_name,LDF_DEVICES)))
    {
        // Not found
        UnLockDosList(LDF_DEVICES|LDF_READ);
        FreeVec(handle);
        return 0;
    }

    // Add colon back on
    strcat(handle->dh_name,":");

    // Get pointer to startup message and geometry
    handle->dh_startup=(struct FileSysStartupMsg *)BADDR(dl->dol_misc.dol_handler.dol_Startup);
    handle->dh_geo=(struct DosEnvec *)BADDR(handle->dh_startup->fssm_Environ);

    // Shortcuts to root block and blocksize
    blocks=handle->dh_geo->de_BlocksPerTrack*
           handle->dh_geo->de_Surfaces*
           (handle->dh_geo->de_HighCyl-handle->dh_geo->de_LowCyl+1);
    handle->dh_root=(blocks-1+handle->dh_geo->de_Reserved)>>1;
    handle->dh_blocksize=handle->dh_geo->de_SizeBlock<<2;

    // Get real device name
    L_BtoCStr((BPTR)handle->dh_startup->fssm_Device,handle->dh_device,32);

    // Get information
#ifdef __AROS__
    if (((struct Library *)DOSBase)->lib_Version<50)
    {
        //handle->dh_result=Info(dl->dol_Lock,&handle->dh_info);
        BPTR lock;
        handle->dh_result=0;
        if ((lock=Lock(handle->dh_name,SHARED_LOCK)))
        {
            handle->dh_result=Info(lock,&handle->dh_info);
            UnLock(lock);
        }
    }
    else
#endif
        handle->dh_result=DoPkt(dl->dol_Task,ACTION_DISK_INFO,MKBADDR(&handle->dh_info),0,0,0,0);

    // Unlock dos list
    UnLockDosList(LDF_DEVICES|LDF_READ);

    // Create message port if needed
    if (!port)
    {
        if (!(handle->dh_port=CreateMsgPort()))
        {
            FreeVec(handle);
            return 0;
        }
        port=handle->dh_port;
    }

    // Create IO request
    if (!(handle->dh_io=(struct IOExtTD *)CreateIORequest(port,sizeof(struct IOExtTD))))
    {
        if (handle->dh_port) DeleteMsgPort(handle->dh_port);
        FreeVec(handle);
        return 0;
    }

    // Open device
    if (OpenDevice(
                handle->dh_device,
                handle->dh_startup->fssm_Unit,
                (struct IORequest *)handle->dh_io,
                handle->dh_startup->fssm_Flags))
    {
        // Failed to open
        L_CloseDisk(handle);
        return 0;
    }

    return handle;
}