home *** CD-ROM | disk | FTP | other *** search
- #include <exec/memory.h>
- #include <dos/dos.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <clib/alib_protos.h>
- #include <string.h>
- #include "split.h"
-
- /* for debug purposes */
- #include <stdio.h>
-
- /* in diskhandler.c */
- extern struct Task *thisTask;
- extern UBYTE diskBit;
-
- /* end of external definitions */
-
- char *str_unreadable, *str_unknown;
-
- /* OK then if you really want to look in this source you'll find some
- hacks'n'things made for efficiency... not a good style of doing things
- but they work, and well! */
-
-
- VolumeList *allocVolumeList( void )
- {
- VolumeList *newList;
- if ( newList = AllocVec( sizeof(struct List), MEMF_ANY | MEMF_CLEAR ) )
- {
- NewList( newList );
- return newList;
- }
- return NULL;
- }
-
-
- void freeVolumeList( VolumeList *list )
- {
- struct volumeInfo *v_info;
- while ( v_info = (struct volumeInfo *)RemHead( (struct List *)list ) )
- {
- if ( v_info->volumeNode.ln_Name )
- FreeVec( v_info->volumeNode.ln_Name );
- if ( v_info->volumeName )
- FreeVec( v_info->volumeName );
- if ( v_info->deviceName )
- FreeVec( v_info->deviceName );
- FreeVec( v_info );
- }
- FreeVec( list );
- }
-
-
- char *getStringFromBSTR( BSTR source )
- {
- UBYTE length = *(UBYTE*)(source<<2), counter;
- char *name;
-
- if ( name = AllocVec( length + 2, MEMF_ANY | MEMF_CLEAR ) )
- {
- for ( counter = 0; counter < length; counter++ )
- if ( (*(name+counter) = *(char*)((source<<2)+counter+1)) == 0 ) break;
- *(name+counter)=':';
- return name;
- }
- return (char *)NULL;
- }
-
-
- char *getDosType( ULONG disktype )
- {
- switch( disktype )
- {
- case ID_UNREADABLE_DISK:
- return str_unreadable;
- case ID_DOS_DISK:
- return "DOS";
- case ID_FFS_DISK:
- return "FFS";
- case ID_INTER_DOS_DISK:
- return "Intl DOS";
- case ID_INTER_FFS_DISK:
- return "Intl FFS";
- case ID_FASTDIR_DOS_DISK:
- return "Cached DOS";
- case ID_FASTDIR_FFS_DISK:
- return "Cached FFS";
- case ID_NOT_REALLY_DOS:
- return "Not DOS";
- case ID_KICKSTART_DISK:
- return "Kickstart";
- case ID_MSDOS_DISK:
- return "MS-DOS";
- default:
- return str_unknown;
- }
- }
-
-
- /*
- * Given a specific volume name, returns the physical device on which
- * the volume is mounted.
- *
- */
-
- char *getDeviceName( char *volumename )
- {
- struct MsgPort *vol_Task = DeviceProc( volumename );
- struct DosList *dlist;
- char *devicename;
-
- dlist = LockDosList( LDF_DEVICES | LDF_READ );
- while( dlist->dol_Task != vol_Task )
- dlist = NextDosEntry( dlist, LDF_DEVICES );
- devicename = getStringFromBSTR( dlist->dol_Name );
- UnLockDosList( LDF_DEVICES | LDF_READ );
- return devicename;
- }
-
-
- /*
- * Searches through the DosList for all mounted volumes.
- *
- */
-
- struct InfoData diskinfo;
- BOOL searchForVolumes( VolumeList *list )
- {
- struct DosList *dlist;
- struct volumeInfo *el;
- BOOL gotInfo;
-
- if ( dlist = LockDosList( LDF_VOLUMES|LDF_READ ) )
- {
- while( dlist = NextDosEntry( dlist, LDF_VOLUMES ) )
- {
- gotInfo = FALSE;
- if ( el = AllocVec( sizeof(struct volumeInfo), MEMF_ANY | MEMF_CLEAR ) )
- {
- if ( el->volumeName = getStringFromBSTR(dlist->dol_Name) )
- {
- BPTR lock;
-
- if ( lock = Lock( el->volumeName, ACCESS_READ ) )
- {
- if ( Info(lock,&diskinfo) )
- {
- el->dosType = getDosType(diskinfo.id_DiskType);
- el->freeSpace = (diskinfo.id_NumBlocks-diskinfo.id_NumBlocksUsed-1)*diskinfo.id_BytesPerBlock;
- el->freeBlocks = diskinfo.id_NumBlocks-diskinfo.id_NumBlocksUsed-1;
- el->bytesPerBlock = diskinfo.id_BytesPerBlock;
- el->diskType = diskinfo.id_DiskType;
-
- Enqueue( (struct List *)list, (struct Node *)el );
- gotInfo = TRUE;
- }
- UnLock( lock );
- }
- }
- }
- if ( !gotInfo )
- FreeVec( el );
- }
- UnLockDosList( LDF_VOLUMES|LDF_READ );
- }
- else return FALSE;
- return TRUE;
- }
-
-
- /*
- * Given a volume list, fills the device field. (See getDeviceName)
- *
- */
-
- void searchForDevices( VolumeList *list )
- {
- struct volumeInfo *el = (struct volumeInfo *)list->lh_Head;
-
- while ( el->volumeNode.ln_Pred != list->lh_TailPred )
- {
- el->deviceName = getDeviceName( el->volumeName );
- el = (struct volumeInfo *)el->volumeNode.ln_Succ;
- }
- }
-
- /*
- * Walks through a given volume list and checks for NDos (really for
- * MS-DOS) disks and fixes free space and disk type, as
- * Info(...,diskinfo) does not report ID_MSDOS_DISK in diskinfo->di_DiskType
- *
- */
-
-
- void searchForNDos( VolumeList *list )
- {
- struct volumeInfo *el = (struct volumeInfo *)list->lh_Head;
- struct DosList *dlist;
- struct MsgPort *vol_Task;
-
- while ( el->volumeNode.ln_Pred != list->lh_TailPred )
- {
- vol_Task = DeviceProc( el->volumeName );
- dlist = LockDosList( LDF_VOLUMES | LDF_READ );
- while( dlist->dol_Task != vol_Task )
- dlist = NextDosEntry( dlist, LDF_VOLUMES );
- if ( dlist->dol_misc.dol_volume.dol_DiskType == ID_MSDOS_DISK )
- {
- el->diskType = ID_MSDOS_DISK;
- el->dosType = getDosType( ID_MSDOS_DISK );
- if ( (LONG)el->freeSpace < 0 )
- el->freeSpace = 0;
- }
- el = (struct volumeInfo *)el->volumeNode.ln_Succ;
- UnLockDosList( LDF_VOLUMES | LDF_READ );
- }
- }
-
-
- BOOL putNamesAndSpace( VolumeList *list )
- {
- struct volumeInfo *el;
- UBYTE len, cnt;
- ULONG size;
- char *outString;
-
- len = VOLUMENODENAMELEN;
- el = (struct volumeInfo *)list->lh_Head;
- while ( el->volumeNode.ln_Pred != list->lh_TailPred )
- if ( outString = AllocVec( len + 1, MEMF_ANY | MEMF_CLEAR ) )
- {
- el->volumeNode.ln_Name = outString;
- strncpy( outString, el->volumeName, MAXVOLNAME );
- strncpy( outString + MAXVOLNAME + 2, el->deviceName, MAXDEVNAME );
- strncpy( outString + MAXVOLNAME + MAXDEVNAME + 4, el->dosType, MAXDOSTYPENAME );
- for ( cnt = 0; cnt < len; cnt++ )
- if ( !*(outString+cnt) )
- *(outString+cnt)=' ';
-
- /* Small hack to get available RAM instead of 0 ... :-) */
- if ( !strcmp( el->deviceName, "RAM:" ) )
- {
- el->freeSpace = AvailMem(MEMF_ANY);
- el->freeBlocks = el->freeSpace / el->bytesPerBlock;
- }
-
- size = el->freeSpace;
- cnt = len;
- if ( !size )
- *(outString+cnt) = '0';
- else
- while( size )
- {
- *(outString+cnt) = '0' + size % 10;
- size /= 10;
- cnt--;
- }
- el = (struct volumeInfo *)el->volumeNode.ln_Succ;
- }
- else return FALSE;
- return TRUE;
- }
-
-
- /*
- * This is the main routine. If everything works fine, it returns a
- * list composed of volumeInfo structures (see Split.h).
- *
- */
-
-
- VolumeList *getVolumeList( VolumeList *list )
- {
- VolumeList *newList;
-
- if ( list != NULL )
- freeVolumeList( list );
-
- if ( newList = allocVolumeList() )
- {
- if ( searchForVolumes( newList ) )
- {
- searchForNDos( newList );
- searchForDevices( newList );
- if ( putNamesAndSpace( newList ) )
- return newList;
- }
- freeVolumeList( newList );
- }
- return NULL;
- }
-