コード例 #1
0
ファイル: os_aros_support.c プロジェクト: michalsc/AROS
/*******************************************
 Name  : attemptAddDosVolume
 Descr.: adds a new volume to dos
 Input : volume - volume to add
 Output: DOSTRUE for success; DOSFALSE otherwise
********************************************/
LONG attemptAddDosVolume(struct AFSBase *afsbase, struct Volume *volume) {
struct DosList *doslist;
struct DosList *dl=NULL;
char string[32];
BSTR bname;
UBYTE i;

	if (volume->volumenode) {
	    D(bug("[afs 0x%08lX] VolumeNode is already present!\n", volume));
	    return DOSTRUE;
	}
	bname = volume->devicelist.dl_Name;
	for (i=0; i<AROS_BSTR_strlen(bname); i++)
		string[i] = AROS_BSTR_getchar(bname,i);
	string[AROS_BSTR_strlen(bname)] = 0;
	D(bug("[afs 0x%08lX] Processing inserted volume %s\n", volume, string));
	/* is the volume already in the list? */
	doslist = AttemptLockDosList(LDF_WRITE | LDF_VOLUMES);
	if (doslist != NULL)
	{
		dl = FindDosEntry(doslist,string,LDF_VOLUMES);
		UnLockDosList(LDF_WRITE | LDF_VOLUMES);
	}
	else
		return TRUE;

	/* if not create a new doslist */
	if (dl == NULL)
	{
		D(bug("[afs 0x%08lX] Creating new VolumeNode\n", volume));
		doslist = MakeDosEntry(string,DLT_VOLUME);
		if (doslist == NULL)
			return DOSFALSE;
		doslist->dol_Task = &((struct Process *)FindTask(NULL))->pr_MsgPort;
		doslist->dol_misc.dol_volume.dol_VolumeDate.ds_Days =
			volume->devicelist.dl_VolumeDate.ds_Days;
		doslist->dol_misc.dol_volume.dol_VolumeDate.ds_Minute =
			volume->devicelist.dl_VolumeDate.ds_Minute;
		doslist->dol_misc.dol_volume.dol_VolumeDate.ds_Tick =
			volume->devicelist.dl_VolumeDate.ds_Tick;
		AddDosEntry(doslist);
		/* if we re-use "volume" clear locklist */
		volume->locklist = NULL;
		dl = doslist;
	}
	volume->volumenode = dl;
	SendEvent(afsbase, IECLASS_DISKINSERTED);
	return DOSTRUE;
}
コード例 #2
0
ファイル: mount_8G.c プロジェクト: michalsc/AROS
/* 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;
}
コード例 #3
0
ファイル: setup.c プロジェクト: chris-y/ntfs-3g
struct DiskIO *DIO_Setup(CONST_STRPTR name, const struct TagItem *tags) {
	DEBUGF("DIO_Setup('%s', %#p)\n", name, tags);

	if (name == NULL || name[0] == '\0' || name[0] == ':') {
		DEBUGF("DIO_Setup: No valid name argument specified.\n");
		return NULL;
	}

	struct DiskIO *dio;
	struct TagItem *tstate;
	const struct TagItem *tag;
#ifndef DISABLE_DOSTYPE_CHECK
	ULONG check_dostype = 0;
	ULONG dostype_mask = ~0;
#endif
	struct DosList *dol;
	struct DeviceNode *dn = NULL;
	struct FileSysStartupMsg *fssm = NULL;
	struct DosEnvec *de = NULL;
	struct MsgPort *mp = NULL;
	struct IOExtTD *iotd = NULL;
	char devname[256];
	struct NSDeviceQueryResult nsdqr;
	int error = DIO_ERROR_UNSPECIFIED;
	int *error_storage;

	dio = AllocMem(sizeof(*dio), MEMF_PUBLIC|MEMF_CLEAR);
	if (dio == NULL) {
		error = DIO_ERROR_NOMEM;
		goto cleanup;
	}

	tstate = (struct TagItem *)tags;
	while ((tag = NextTagItem(&tstate)) != NULL) {
		switch (tag->ti_Tag) {
#ifndef DISABLE_BLOCK_CACHE
			case DIOS_Cache:
				dio->no_cache = !tag->ti_Data;
				break;
			case DIOS_WriteCache:
				dio->no_write_cache = !tag->ti_Data;
				break;
#endif
			case DIOS_Inhibit:
				dio->inhibit = !!tag->ti_Data;
				break;
#ifndef DISABLE_DOSTYPE_CHECK
			case DIOS_DOSType:
				check_dostype = tag->ti_Data;
				break;
			case DIOS_DOSTypeMask:
				dostype_mask = tag->ti_Data;
				break;
#endif
			case DIOS_ReadOnly:
				dio->read_only = !!tag->ti_Data;
				break;
		}
	}

	/* Remove possible colon from name and anything else that might follow it */
	SplitName(name, ':', dio->devname, 0, sizeof(dio->devname));

	/* Find device node */
	dol = LockDosList(LDF_DEVICES|LDF_READ);
	if (dol != NULL) {
		dn = (struct DeviceNode *)FindDosEntry(dol, dio->devname, LDF_DEVICES|LDF_READ);
		UnLockDosList(LDF_DEVICES|LDF_READ);
	}
	if (dn == NULL) {
		error = DIO_ERROR_GETFSD;
		goto cleanup;
	}

	/* Add back trailing colon for Inhibit() */
	strlcat((char *)dio->devname, ":", sizeof(dio->devname));

	/* Check that device node has the necessary data */
	if ((fssm = BADDR(dn->dn_Startup)) == NULL ||
		(de = BADDR(fssm->fssm_Environ)) == NULL ||
		de->de_TableSize < DE_UPPERCYL)
	{
		error = DIO_ERROR_GETFSD;
		goto cleanup;
	}

	if (dio->inhibit) {
		if (!Inhibit(dio->devname, TRUE)) {
			error = DIO_ERROR_INHIBIT;
			goto cleanup;
		}

		dio->uninhibit = TRUE; /* So Cleanup() knows that it should uninhibit */
	}

	dio->diskmp = mp = CreateMsgPort();
	dio->diskiotd = iotd = CreateIORequest(dio->diskmp, sizeof(*iotd));
	if (iotd == NULL) {
		error = DIO_ERROR_NOMEM;
		goto cleanup;
	}

	FbxCopyStringBSTRToC(fssm->fssm_Device, (STRPTR)devname, sizeof(devname));
	if (OpenDevice((CONST_STRPTR)devname, fssm->fssm_Unit,
		(struct IORequest *)iotd, fssm->fssm_Flags) != 0)
	{
		DEBUGF("DIO_Setup: Failed to open %s unit %u using flags 0x%x.\n",
			fssm->fssm_Device,
			(unsigned int)fssm->fssm_Unit,
			(unsigned int)fssm->fssm_Flags);
		error = DIO_ERROR_OPENDEVICE;
		goto cleanup;
	}

	dio->disk_device = iotd->iotd_Req.io_Device;

	if (de->de_LowCyl == 0) {
		dio->use_full_disk = TRUE;
		DEBUGF("de_LowCyl == 0 => using full disk\n");
	} else {
		UQUAD sector_size = de->de_SizeBlock * sizeof(ULONG);
		UQUAD cylinder_size = (UQUAD)de->de_BlocksPerTrack * (UQUAD)de->de_Surfaces * sector_size;
		dio->use_full_disk = FALSE;
		SetSectorSize(dio, sector_size);
		dio->partition_start = (UQUAD)de->de_LowCyl * cylinder_size;
		dio->partition_size = (UQUAD)(de->de_HighCyl - de->de_LowCyl + 1) * cylinder_size;
		dio->total_sectors = dio->partition_size / dio->sector_size;
		DEBUGF("partiton start: %llu partition size: %llu cylinder size: %llu sector size: %lu total sectors: %llu\n",
			dio->partition_start, dio->partition_size, cylinder_size, dio->sector_size, dio->total_sectors);
	}

	DEBUGF("Trying NSD query command\n");
	iotd->iotd_Req.io_Command = NSCMD_DEVICEQUERY;
	iotd->iotd_Req.io_Data = &nsdqr;
	iotd->iotd_Req.io_Length = sizeof(nsdqr);
	bzero(&nsdqr, sizeof(nsdqr)); /* Required for usbscsi.device */
	if (DoIO((struct IORequest *)iotd) == 0) {
		if (nsdqr.DeviceType != NSDEVTYPE_TRACKDISK) {
			DEBUGF("Not a trackdisk device\n");
			error = DIO_ERROR_NSDQUERY;
			goto cleanup;
		}

		if (nsdqr.SupportedCommands != NULL) {
			UWORD cmd;
			int i = 0;
			while ((cmd = nsdqr.SupportedCommands[i++]) != CMD_INVALID) {
				if (cmd == CMD_READ)
					dio->cmd_support |= CMDSF_TD32;
				else if (cmd == ETD_READ)
					dio->cmd_support |= CMDSF_ETD32;
				else if (cmd == TD_READ64)
					dio->cmd_support |= CMDSF_TD64;
				else if (cmd == NSCMD_TD_READ64)
					dio->cmd_support |= CMDSF_NSD_TD64;
				else if (cmd == NSCMD_ETD_READ64)
					dio->cmd_support |= CMDSF_NSD_ETD64;
				else if (cmd == CMD_UPDATE)
					dio->cmd_support |= CMDSF_CMD_UPDATE;
				else if (cmd == ETD_UPDATE)
					dio->cmd_support |= CMDSF_ETD_UPDATE;
			}
		}
	} else if (iotd->iotd_Req.io_Error == IOERR_NOCMD) {
		DEBUGF("Not an NSD device\n");
		dio->cmd_support = CMDSF_TD32|CMDSF_CMD_UPDATE;

		DEBUGF("Checking for TD64 support\n");
		iotd->iotd_Req.io_Command = TD_READ64;
		iotd->iotd_Req.io_Data = NULL;
		iotd->iotd_Req.io_Actual = 0;
		iotd->iotd_Req.io_Offset = 0;
		iotd->iotd_Req.io_Length = 0;
		if (DoIO((struct IORequest *)iotd) != IOERR_NOCMD)
			dio->cmd_support |= CMDSF_TD64;
	} else {
		DEBUGF("NSD query command failed (error: %d)\n", (int)iotd->iotd_Req.io_Error);
		error = DIO_ERROR_NSDQUERY;
		goto cleanup;
	}

	if ((dio->cmd_support & (CMDSF_TD32|CMDSF_ETD32|CMDSF_TD64|CMDSF_NSD_TD64|CMDSF_NSD_ETD64)) == 0) {
		DEBUGF("No I/O commands supported\n");
		error = DIO_ERROR_NSDQUERY;
		goto cleanup;
	}

	if (dio->cmd_support & CMDSF_ETD_UPDATE)
		dio->update_cmd = ETD_UPDATE;
	else if (dio->cmd_support & CMDSF_CMD_UPDATE)
		dio->update_cmd = CMD_UPDATE;
	else
		dio->update_cmd = CMD_INVALID;

	dio->mempool = CreatePool(MEMF_PUBLIC, 4096, 1024);
	if (dio->mempool == NULL) {
		error = DIO_ERROR_NOMEM;
		goto cleanup;
	}

	DIO_Update(dio);

	DEBUGF("DIO_Setup: %#p\n", dio);
	return dio;

cleanup:
	if (dio != NULL) DIO_Cleanup(dio);

	error_storage = (int *)GetTagData(DIOS_Error, (Tag)NULL, tags);
	if (error_storage != NULL) *error_storage = error;

	DEBUGF("DIO_Setup failed (error: %d)\n", error);
	return NULL;
}
コード例 #4
0
ファイル: diskio.c プロジェクト: timofonic/dopus5allamigas
// 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;
}
コード例 #5
0
LONG DoNameAsynch(struct IOFileSys *iofs, STRPTR name, 
		  struct DosLibrary *DOSBase)
{
    STRPTR volname, pathname, s1 = NULL;
    BPTR cur, lock = (BPTR)NULL;
    struct DosList    *dl;
    struct Device     *device;
    struct Unit       *unit;
    struct FileHandle *fh;
    struct Process    *me = (struct Process *)FindTask(NULL);

    if (!Strnicmp(name, "PROGDIR:", 8) && me->pr_HomeDir)
    {
	cur = me->pr_HomeDir;
	volname = NULL;
	pathname = name + 8;
    }
    else if (*name == ':')
    {
	cur = me->pr_CurrentDir;
	volname = NULL;
	pathname = name + 1;
    }
    else
    {
	/* Copy volume name */
	cur = me->pr_CurrentDir;
	s1 = name;
	pathname = name;
	volname = NULL;

	while (*s1)
	{
	    if (*s1++ == ':')
	    {
		volname = (STRPTR)AllocMem(s1-name, MEMF_ANY);

		if (volname == NULL)
		{
		    return ERROR_NO_FREE_STORE;
		}

		CopyMem(name, volname, s1 - name - 1);

		volname[s1 - name - 1] = '\0';
		pathname = s1;
		break;
	    }
	}
    }

    if (!volname && !cur && !DOSBase->dl_SYSLock)
    {
    	return ERROR_OBJECT_NOT_FOUND;
    }
    
    dl = LockDosList(LDF_ALL | LDF_READ);

    if (volname != NULL)
    {
	/* Find logical device */
	dl = FindDosEntry(dl, volname, LDF_ALL);

	if (dl == NULL)
	{
	    UnLockDosList(LDF_ALL | LDF_READ);
	    FreeMem(volname, s1 - name);

	    return ERROR_DEVICE_NOT_MOUNTED;
	}
	else if (dl->dol_Type == DLT_LATE)
	{
	    lock = Lock(dl->dol_misc.dol_assign.dol_AssignName, SHARED_LOCK);
	    UnLockDosList(LDF_ALL | LDF_READ);

	    if (lock != NULL)
	    {
		AssignLock(volname, lock);
		dl = LockDosList(LDF_ALL | LDF_READ);
		dl = FindDosEntry(dl, volname, LDF_ALL);

		if (dl == NULL)
		{
		    UnLockDosList(LDF_ALL | LDF_READ);
		    FreeMem(volname, s1 - name);

		    return ERROR_DEVICE_NOT_MOUNTED;
	        }
		
		device = dl->dol_Ext.dol_AROS.dol_Device;
		unit = dl->dol_Ext.dol_AROS.dol_Unit;
	    } 
	    else
	    {
		FreeMem(volname, s1 - name);

		return IoErr();
	    }
	} 
	else if (dl->dol_Type == DLT_NONBINDING)
	{
	    lock = Lock(dl->dol_misc.dol_assign.dol_AssignName, SHARED_LOCK);
	    fh = (struct FileHandle *)BADDR(lock);

	    if (fh != NULL)
	    {
		device = fh->fh_Device;
		unit = fh->fh_Unit;
	    } 
	    else
	    {
		UnLockDosList(LDF_ALL | LDF_READ);
		FreeMem(volname, s1 - name);

		return IoErr();
	    }
	}
	else
	{
	    device = dl->dol_Ext.dol_AROS.dol_Device;
	    unit   = dl->dol_Ext.dol_AROS.dol_Unit;
	}
    }
    else if (cur)
    {
	fh = (struct FileHandle *)BADDR(cur);
	device = fh->fh_Device;
	unit = fh->fh_Unit;
    }
    else
    {
    #if 0
    	/* stegerg: ?? */
	device = DOSBase->dl_NulHandler;
	unit = DOSBase->dl_NulLock;
    #else
    	fh = (struct FileHandle *)BADDR(DOSBase->dl_SYSLock);
	device = fh->fh_Device;
	unit = fh->fh_Unit;
    #endif
    }
    
    iofs->IOFS.io_Device = device;
    iofs->IOFS.io_Unit = unit;
    iofs->io_Union.io_NamedFile.io_Filename = pathname;

    if (volname != NULL)
    {
	FreeMem(volname, s1 - name);
    }

    return 0;
}
コード例 #6
0
	int access (

/*  SYNOPSIS */
	const char *path,
	int         mode)

/*  FUNCTION
	Check access permissions of a file or pathname

    INPUTS
	path - the path of the file being checked
	mode - the bitwise inclusive OR of the access permissions
	       to be checked:

	       W_OK - for write permission
	       R_OK - for readpermissions
	       X_OK - for execute permission
	       F_OK - Just to see whether the file exists

    RESULT
	If path cannot be found or if any of the desired access
	modes would not be granted, then a -1 value is returned;
	otherwise a 0 value is returned.

    NOTES

    EXAMPLE

    BUGS

    SEE ALSO
	open(), ftruncate()

    INTERNALS

******************************************************************************/
{
    BPTR lock = NULL;
    struct FileInfoBlock *fib = NULL;
    int result = -1;
    char vol[32];
    struct DosList *dl = NULL;

    if (!path) /* safety check */
    {
    	errno = EFAULT;
        return -1;
    }

    if (!strlen(path)) /* empty path */
    {
        errno = ENOENT;
        return -1;
    }

    /* Check if the volume exists. Calling Lock on non-existing volume will bring up System Requester */
    if (SplitName(__path_u2a(path), ':', vol, 0, sizeof(vol)-1) != -1)
    {
	if(strcmp(vol, "PROGDIR") != 0)
	{
            dl = LockDosList(LDF_ALL | LDF_READ);
            dl = FindDosEntry(dl, vol, LDF_ALL);
            UnLockDosList(LDF_ALL | LDF_READ);
            /* Volume / Assign / Device not found */
            if (dl == NULL)
            {
                errno = ENOENT;
                return -1;
            }
	}
    }

    /* Create a lock and examine a lock */

    lock = Lock(__path_u2a(path), SHARED_LOCK);
    if (lock == NULL)
    {
        errno = IoErr2errno(IoErr());
        return -1;
    }

    fib = AllocDosObject(DOS_FIB, NULL);
    if (!fib)
    {
        errno = IoErr2errno(IoErr());
        UnLock(lock);
        return -1;
    }
        
    if (Examine(lock, fib))
    {
        /* Notice : protection flags are 'low-active' (0 means access is granted) */
        result = 0;
        if ((mode & R_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_READ)))
        {
            errno = EACCES;
            result = -1;
        }
        if ((mode & W_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_WRITE)))
        {
            errno = EACCES;
            result = -1;
        }
        if ((mode & X_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_EXECUTE)))
        {
            errno = EACCES;
            result = -1;
        }
    }
    else
    {
        errno = EBADF;
        result = -1;
    }

    FreeDosObject(DOS_FIB, fib);
    fib = NULL;

    UnLock(lock);
    return result;
}
コード例 #7
0
/* 
 Output: 0 - no mount (no partition change)
         1 - mount that device
         2 - reboot not really neccessary
             (FS not so important things changed like de_Mask)
         3 - reboot neccessary
             (FS important things changed like de_LowCyl)
*/
WORD checkMount(struct HDTBPartition *table, STRPTR name, struct DosEnvec *de)
{
    WORD retval = 1;
    struct DosList *dl;
    struct DeviceNode *entry;
    ULONG i;

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

    dl = LockDosList(LDF_READ | LDF_DEVICES);
    if (dl)
    {
        entry = (struct DeviceNode *)FindDosEntry(dl, name, LDF_DEVICES);
        if (entry)
        {
            struct FileSysStartupMsg *fssm;
            struct DosEnvec *d_de;
            STRPTR devname;

            fssm = (struct FileSysStartupMsg *)BADDR(entry->dn_Startup);
            devname = AROS_BSTR_ADDR(fssm->fssm_Device);
            if (
                    (fssm->fssm_Unit != table->hd->unit) ||
                    (strcmp(devname, table->hd->devname))
                )
            {
                retval = 3; /* better do a reboot */
            }
            else
            {	
                d_de = (struct DosEnvec *)BADDR(fssm->fssm_Environ);
                i = getOffset(table->ph);
                if (
                        (d_de->de_SizeBlock != de->de_SizeBlock) ||
                        (d_de->de_Reserved  != de->de_Reserved) ||
                        (d_de->de_PreAlloc  != de->de_PreAlloc) ||
                        (d_de->de_LowCyl    != (de->de_LowCyl+i)) ||
                        (d_de->de_HighCyl   != (de->de_HighCyl+i)) ||
                        (d_de->de_DosType   != de->de_DosType) ||
                        (
                            (
                                /* at least one has de_BootBocks */
                                (d_de->de_TableSize>=DE_BOOTBLOCKS) ||
                                (de->de_TableSize>=DE_BOOTBLOCKS)
                            ) &&
                            (
                                /* if one has no de_BootBlock assume de_BootBlock change */
                                (d_de->de_TableSize<DE_BOOTBLOCKS) ||
                                (de->de_TableSize<DE_BOOTBLOCKS)
                            )
                        ) ||
                        (
                            /* both have de_BootBlocks */
                            (d_de->de_TableSize>=DE_BOOTBLOCKS) &&
                            (de->de_TableSize>=DE_BOOTBLOCKS) &&
                            (d_de->de_BootBlocks != de->de_BootBlocks)
                        )
                    )
                {
                    retval = 3;
                }
                else if
                    (
                        (d_de->de_NumBuffers  != de->de_NumBuffers) ||
                        (d_de->de_BufMemType  != de->de_BufMemType) ||
                        (d_de->de_MaxTransfer != de->de_MaxTransfer) ||
                        (d_de->de_Mask        != de->de_Mask) ||
                        (d_de->de_BootPri     != de->de_BootPri)
                    )
                {
                    retval = 2;
                }
                else
                    retval = 0;
            }
        }
        UnLockDosList(LDF_READ | LDF_DEVICES);
    }
    return retval;
}