home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / Split_GUI.lha / Split_v1.0 / Sources.lha / Sources / doslist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-09  |  6.4 KB  |  293 lines

  1. #include <exec/memory.h>
  2. #include <dos/dos.h>
  3.  
  4. #include <proto/exec.h>
  5. #include <proto/dos.h>
  6. #include <clib/alib_protos.h>
  7. #include <string.h>
  8. #include "split.h"
  9.  
  10. /* for debug purposes */
  11. #include <stdio.h>
  12.  
  13. /* in diskhandler.c */
  14. extern struct Task *thisTask;
  15. extern UBYTE diskBit;
  16.  
  17. /* end of external definitions */
  18.  
  19. char *str_unreadable, *str_unknown;
  20.  
  21. /* OK then if you really want to look in this source you'll find some
  22.    hacks'n'things made for efficiency... not a good style of doing things
  23.    but they work, and well! */
  24.  
  25.  
  26. VolumeList *allocVolumeList( void )
  27. {
  28. VolumeList *newList;
  29. if ( newList = AllocVec( sizeof(struct List), MEMF_ANY | MEMF_CLEAR ) )
  30.     {
  31.     NewList( newList );
  32.     return newList;
  33.     }
  34. return NULL;
  35. }
  36.  
  37.  
  38. void freeVolumeList( VolumeList *list )
  39. {
  40. struct volumeInfo *v_info;
  41. while ( v_info = (struct volumeInfo *)RemHead( (struct List *)list ) )
  42.     {
  43.     if ( v_info->volumeNode.ln_Name )
  44.         FreeVec( v_info->volumeNode.ln_Name );
  45.     if ( v_info->volumeName )
  46.         FreeVec( v_info->volumeName );
  47.     if ( v_info->deviceName )
  48.         FreeVec( v_info->deviceName );
  49.     FreeVec( v_info );
  50.     }
  51. FreeVec( list );
  52. }
  53.  
  54.  
  55. char *getStringFromBSTR( BSTR source )
  56. {
  57. UBYTE length = *(UBYTE*)(source<<2), counter;
  58. char *name;
  59.  
  60. if ( name = AllocVec( length + 2, MEMF_ANY | MEMF_CLEAR ) )
  61.     {
  62.     for ( counter = 0; counter < length; counter++ )
  63.         if ( (*(name+counter) = *(char*)((source<<2)+counter+1)) == 0 ) break;
  64.     *(name+counter)=':';
  65.     return name;
  66.     }
  67. return (char *)NULL;
  68. }
  69.  
  70.  
  71. char *getDosType( ULONG disktype )
  72. {
  73. switch( disktype )
  74.     {
  75.     case ID_UNREADABLE_DISK:
  76.         return str_unreadable;
  77.     case ID_DOS_DISK:
  78.         return "DOS";
  79.     case ID_FFS_DISK:
  80.         return "FFS";
  81.     case ID_INTER_DOS_DISK:
  82.         return "Intl DOS";
  83.     case ID_INTER_FFS_DISK:
  84.         return "Intl FFS";
  85.     case ID_FASTDIR_DOS_DISK:
  86.         return "Cached DOS";
  87.     case ID_FASTDIR_FFS_DISK:
  88.         return "Cached FFS";
  89.     case ID_NOT_REALLY_DOS:
  90.         return "Not DOS";
  91.     case ID_KICKSTART_DISK:
  92.         return "Kickstart";
  93.     case ID_MSDOS_DISK:
  94.         return "MS-DOS";
  95.     default:
  96.         return str_unknown;
  97.     }
  98. }
  99.  
  100.  
  101. /*
  102.  * Given a specific volume name, returns the physical device on which
  103.  * the volume is mounted.
  104.  *
  105.  */
  106.  
  107. char *getDeviceName( char *volumename )
  108. {
  109. struct MsgPort *vol_Task = DeviceProc( volumename );
  110. struct DosList *dlist;
  111. char *devicename;
  112.  
  113. dlist = LockDosList( LDF_DEVICES | LDF_READ );
  114. while( dlist->dol_Task != vol_Task )
  115.     dlist = NextDosEntry( dlist, LDF_DEVICES );
  116. devicename = getStringFromBSTR( dlist->dol_Name );
  117. UnLockDosList( LDF_DEVICES | LDF_READ );
  118. return devicename;
  119. }
  120.  
  121.  
  122. /*
  123.  * Searches through the DosList for all mounted volumes.
  124.  *
  125.  */
  126.  
  127. struct InfoData diskinfo;
  128. BOOL searchForVolumes( VolumeList *list )
  129. {
  130. struct DosList *dlist;
  131. struct volumeInfo *el;
  132. BOOL gotInfo;
  133.  
  134. if ( dlist = LockDosList( LDF_VOLUMES|LDF_READ ) )
  135.     {
  136.     while( dlist = NextDosEntry( dlist, LDF_VOLUMES ) )
  137.         {
  138.         gotInfo = FALSE;
  139.         if ( el = AllocVec( sizeof(struct volumeInfo), MEMF_ANY | MEMF_CLEAR ) )
  140.             {
  141.             if ( el->volumeName = getStringFromBSTR(dlist->dol_Name) )
  142.                 {
  143.                 BPTR lock;
  144.  
  145.                 if ( lock = Lock( el->volumeName, ACCESS_READ ) )
  146.                     {
  147.                     if ( Info(lock,&diskinfo) )
  148.                         {
  149.                         el->dosType = getDosType(diskinfo.id_DiskType);
  150.                         el->freeSpace = (diskinfo.id_NumBlocks-diskinfo.id_NumBlocksUsed-1)*diskinfo.id_BytesPerBlock;
  151.                         el->freeBlocks = diskinfo.id_NumBlocks-diskinfo.id_NumBlocksUsed-1;
  152.                         el->bytesPerBlock = diskinfo.id_BytesPerBlock;
  153.                         el->diskType = diskinfo.id_DiskType;
  154.  
  155.                         Enqueue( (struct List *)list, (struct Node *)el );
  156.                         gotInfo = TRUE;
  157.                         }
  158.                     UnLock( lock );
  159.                     }
  160.                 }
  161.             }
  162.         if ( !gotInfo )
  163.             FreeVec( el );
  164.         }
  165.     UnLockDosList( LDF_VOLUMES|LDF_READ );
  166.     }
  167. else return FALSE;
  168. return TRUE;
  169. }
  170.  
  171.  
  172. /*
  173.  * Given a volume list, fills the device field. (See getDeviceName)
  174.  *
  175.  */
  176.  
  177. void searchForDevices( VolumeList *list )
  178. {
  179. struct volumeInfo *el = (struct volumeInfo *)list->lh_Head;
  180.  
  181. while ( el->volumeNode.ln_Pred != list->lh_TailPred )
  182.     {
  183.     el->deviceName = getDeviceName( el->volumeName );
  184.     el = (struct volumeInfo *)el->volumeNode.ln_Succ;
  185.     }
  186. }
  187.  
  188. /*
  189.  * Walks through a given volume list and checks for NDos (really for
  190.  * MS-DOS) disks and fixes free space and disk type, as 
  191.  * Info(...,diskinfo) does not report ID_MSDOS_DISK in diskinfo->di_DiskType
  192.  *
  193.  */
  194.  
  195.  
  196. void searchForNDos( VolumeList *list )
  197. {
  198. struct volumeInfo *el = (struct volumeInfo *)list->lh_Head;
  199. struct DosList *dlist;
  200. struct MsgPort *vol_Task;
  201.  
  202. while ( el->volumeNode.ln_Pred != list->lh_TailPred )
  203.     {
  204.     vol_Task = DeviceProc( el->volumeName );
  205.     dlist = LockDosList( LDF_VOLUMES | LDF_READ );
  206.     while( dlist->dol_Task != vol_Task )
  207.         dlist = NextDosEntry( dlist, LDF_VOLUMES );
  208.     if ( dlist->dol_misc.dol_volume.dol_DiskType == ID_MSDOS_DISK )
  209.         {
  210.         el->diskType = ID_MSDOS_DISK;
  211.         el->dosType = getDosType( ID_MSDOS_DISK );
  212.         if ( (LONG)el->freeSpace < 0 )
  213.             el->freeSpace = 0;
  214.         }
  215.     el = (struct volumeInfo *)el->volumeNode.ln_Succ;
  216.     UnLockDosList( LDF_VOLUMES | LDF_READ );
  217.     }
  218. }
  219.  
  220.  
  221. BOOL putNamesAndSpace( VolumeList *list )
  222. {
  223. struct volumeInfo *el;
  224. UBYTE len, cnt;
  225. ULONG size;
  226. char *outString;
  227.  
  228. len = VOLUMENODENAMELEN;
  229. el = (struct volumeInfo *)list->lh_Head;
  230. while ( el->volumeNode.ln_Pred != list->lh_TailPred )
  231.     if ( outString = AllocVec( len + 1, MEMF_ANY | MEMF_CLEAR ) )
  232.         {
  233.         el->volumeNode.ln_Name = outString;
  234.         strncpy( outString, el->volumeName, MAXVOLNAME );
  235.         strncpy( outString + MAXVOLNAME + 2, el->deviceName, MAXDEVNAME );
  236.         strncpy( outString + MAXVOLNAME + MAXDEVNAME + 4, el->dosType, MAXDOSTYPENAME );
  237.         for ( cnt = 0; cnt < len; cnt++ )
  238.             if ( !*(outString+cnt) )
  239.                 *(outString+cnt)=' ';
  240.  
  241.         /* Small hack to get available RAM instead of 0 ... :-) */
  242.         if ( !strcmp( el->deviceName, "RAM:" ) )
  243.             {
  244.             el->freeSpace = AvailMem(MEMF_ANY);
  245.             el->freeBlocks = el->freeSpace / el->bytesPerBlock;
  246.             }
  247.  
  248.         size = el->freeSpace;
  249.         cnt = len;
  250.         if ( !size )
  251.             *(outString+cnt) = '0';
  252.         else
  253.             while( size )
  254.                 {
  255.                 *(outString+cnt) = '0' + size % 10;
  256.                 size /= 10;
  257.                 cnt--;
  258.                 }
  259.         el = (struct volumeInfo *)el->volumeNode.ln_Succ;
  260.         }
  261.     else return FALSE;
  262. return TRUE;
  263. }
  264.  
  265.  
  266. /*
  267.  * This is the main routine. If everything works fine, it returns a
  268.  * list composed of volumeInfo structures (see Split.h).
  269.  *
  270.  */
  271.  
  272.  
  273. VolumeList *getVolumeList( VolumeList *list )
  274. {
  275. VolumeList *newList;
  276.  
  277. if ( list != NULL )
  278.     freeVolumeList( list );
  279.  
  280. if ( newList = allocVolumeList() )
  281.     {
  282.     if ( searchForVolumes( newList ) )
  283.         {
  284.         searchForNDos( newList );
  285.         searchForDevices( newList );
  286.         if ( putNamesAndSpace( newList ) )
  287.             return newList;
  288.         }
  289.     freeVolumeList( newList );
  290.     }
  291. return NULL;
  292. }
  293.