home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 073.lha / FileIO / volname.c < prev   
Encoding:
C/C++ Source or Header  |  1987-06-02  |  6.7 KB  |  218 lines

  1.  
  2. /* *** volname.c ************************************************************
  3.  *
  4.  * File IO Suite  --  Volume Name Construction Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * HISTORY      NAME            DESCRIPTION
  15.  * -----------  --------------  --------------------------------------------
  16.  * 4 Feb 87     RJ              Real release
  17.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  18.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  19.  * 1 Feb 86     =RJ Mical=      Created this file.
  20.  *
  21.  * *********************************************************************** */
  22.  
  23.  
  24. #define FILEIO_SOURCEFILE
  25. #include "fileio.h"
  26. #include <libraries\dosextens.h>
  27.  
  28.  
  29. /* Lattice doesn't accept the ID_DOS_DISK which looks like this:
  30.  * #define ID_DOS_DISK ('DOS\0')
  31.  * so I make up my own.
  32.  */
  33. #define X_ID_DOS_DISK (((LONG)'D'<<24)|((LONG)'O'<<16)|('S'<<8)|('\0'))
  34.  
  35.  
  36. BOOL DOSDisk(device)
  37. struct DeviceList *device;
  38. /* This little routine dips its gnarled toes directly into the 
  39.  * scary murky depths of AmigaDOS interior.
  40.  * If it survives, it returns TRUE or FALSE depending on whether or
  41.  * the specified device is a DOS disk.
  42.  * Jeez, Look at the structure names in this routine!  Whew!  You almost
  43.  * gotta be a computer scientist to understand this stuff.
  44.  */
  45. {
  46.     struct MsgPort *port;
  47.     BOOL result;
  48.     struct InfoData *info;
  49.     struct StandardPacket *packet;
  50.  
  51.  
  52.     result = FALSE;
  53.  
  54.     /* Allocate the data structures required to communicate with AmigaDOS */
  55.     info = (struct InfoData *)AllocMem(sizeof(struct InfoData), MEMF_CLEAR);
  56.     packet = (struct StandardPacket *)AllocMem(sizeof(struct StandardPacket),
  57.             MEMF_CLEAR);
  58.  
  59.     /* Grab us a message port for the reply from DOS */
  60.     port = CreatePort(NULL, 0);
  61.  
  62.     if (port && info && packet)
  63.         {
  64.         /* OK, everything is set so here we go! */
  65.  
  66.         /* Set up the StandardPacket's Exec message */
  67.         packet->sp_Msg.mn_Node.ln_Type = NT_MESSAGE;
  68.         packet->sp_Msg.mn_Node.ln_Name = (char *)&packet->sp_Pkt;
  69.         packet->sp_Msg.mn_ReplyPort = port;
  70.  
  71.         /* Set up the StandardPacket's DOS data */
  72.         packet->sp_Pkt.dp_Link = &packet->sp_Msg;
  73.         packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
  74.         packet->sp_Pkt.dp_Arg1 = ((LONG)info >> 2);
  75.         packet->sp_Pkt.dp_Port = port;
  76.  
  77.         /* Now, ask the device whether or not it's a DOS disk */
  78.         PutMsg(device->dl_Task, &packet->sp_Msg);
  79.         /* zzz */
  80.         WaitPort(port);
  81.  
  82.         /* Well? */
  83.         if (info->id_DiskType == X_ID_DOS_DISK) result = TRUE;
  84.         }
  85.  
  86.     if (port) DeletePort(port);
  87.     if (info) FreeMem(info, sizeof(struct InfoData));
  88.     if (packet) FreeMem(packet, sizeof(struct StandardPacket));
  89.  
  90.     return(result);
  91. }
  92.  
  93.  
  94.  
  95. VOID BuildVolumeTable(fileio)
  96. struct FileIOSupport *fileio;
  97. /* This routine builds an alphabetically-sorted list of all active volumes.
  98.  * The names can be either the device names or the volume names, depending
  99.  * on whether you set USE_VOLUME_NAMES.
  100.  */
  101. {
  102.     struct DosInfo *dosinfo;
  103.     struct DeviceList *masterlist, *devlist, *worklist;
  104.     struct MsgPort *handler;
  105.     LONG yuck;
  106.     UBYTE *nameptr, *textptr;
  107.     UBYTE len;
  108.     SHORT i;
  109.     struct Remember **key, *localkey;
  110.  
  111.  
  112.     if (DosBase == NULL) return;
  113.  
  114.     key = &fileio->VolumeKey;
  115.     FreeRemember(key, TRUE);
  116.     localkey = NULL;
  117.  
  118.     fileio->VolumeCount = fileio->VolumeIndex = 0;
  119.  
  120.     /* First, feel through from DosBase down to the device list, dancing
  121.      * all the while with the bcpl pointers.
  122.      */
  123.     yuck = (LONG)((struct RootNode *)DosBase->dl_Root)->rn_Info;
  124.     dosinfo = (struct DosInfo *)(yuck << 2);    /* reality pointer */
  125.     yuck = (LONG)dosinfo->di_DevInfo;
  126.     masterlist = (struct DeviceList *)(yuck << 2);  /* reality pointer */
  127.  
  128.     devlist = masterlist;
  129.  
  130.  
  131.     while (devlist)
  132.         {
  133.         /* First, find each device that's active (dl_Task is not NULL) */
  134.         if ((devlist->dl_Type == DLT_DEVICE) && (devlist->dl_Task))
  135.             {
  136.             /* OK, got a device.  Now ask it if it's a DOS disk. */
  137.             if (NOT DOSDisk(devlist)) goto NEXT_DEVICE;
  138.  
  139.             /* OK, got a device that's a DOS disk.  Now find the name.
  140.              * If USE_VOLUME_NAMES is clear, use the device name,
  141.              * else look up the volume name.
  142.              */
  143.             nameptr = (UBYTE *)devlist->dl_Name;
  144.             if (FlagIsSet(fileio->Flags, USE_VOLUME_NAMES))
  145.                 {
  146.                 /* Use the handler for this volume to find the matching device */
  147.                 handler = (struct MsgPort *)devlist->dl_Task;
  148.  
  149.                 worklist = masterlist;
  150.                 while (worklist)
  151.                     {
  152.                     if ((worklist->dl_Type == DLT_VOLUME)
  153.                             && (worklist->dl_Task == handler))
  154.                         {
  155.                         nameptr = (UBYTE *)worklist->dl_Name;
  156.                         goto GOT_NAME;
  157.                         }
  158.  
  159.                     yuck = worklist->dl_Next;
  160.                     worklist = (struct DeviceList *)(yuck << 2);
  161.                     }
  162.                 /* If we get to the end of this loop and fall out, then what?  
  163.                  * Got an active device but no matching volume?  OK.
  164.                  */
  165.                 }
  166.  
  167. GOT_NAME:
  168.             yuck = (LONG)nameptr;
  169.             nameptr = (UBYTE *)(yuck << 2);
  170.             len = *nameptr++;
  171.  
  172.             if ((textptr = AllocRemember(&localkey, len + 2, NULL)) == NULL)
  173.                 {
  174.                 Alert(ALERT_OUTOFMEM, NULL);
  175.                 goto DEVICES_DONE;
  176.                 }
  177.  
  178.             fileio->VolumeCount++;
  179.             for (i = 0; i < len; i++) *textptr++ = *nameptr++;
  180.             *textptr++ = ':';
  181.             *textptr = '\0';
  182.             MakeEntry(localkey->Memory, &fileio->VolumeKey, NULL);
  183.             }
  184.  
  185. NEXT_DEVICE:
  186.         yuck = devlist->dl_Next;
  187.         devlist = (struct DeviceList *)(yuck << 2);
  188.         }
  189.  
  190.  
  191. DEVICES_DONE:
  192.  
  193.     FreeRemember(&localkey, TRUE);
  194. }
  195.  
  196.  
  197. UBYTE *CurrentVolumeName()
  198. /* This routine returns a pointer the name of the current volume */
  199. {
  200.     SHORT i;
  201.     struct Remember *remember;
  202.  
  203.     /* If there's no active volumes then return the "safe" volume name */
  204.     if (OpenReqFileIO->VolumeCount < 1)
  205.         return(&CurrentDiskString[0]);
  206.  
  207.     /* Safety measure */
  208.     if (OpenReqFileIO->VolumeIndex >= OpenReqFileIO->VolumeCount)
  209.         OpenReqFileIO->VolumeIndex = 0;
  210.  
  211.     /* Finally, look up the name */
  212.     remember = OpenReqFileIO->VolumeKey;
  213.     for (i = 0; i < OpenReqFileIO->VolumeIndex; i++)
  214.         remember = remember->NextRemember;
  215.     return(remember->Memory);
  216. }
  217.  
  218.