home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 274.lha / DiskHandler / mount.c < prev    next >
C/C++ Source or Header  |  1989-07-25  |  6KB  |  190 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved */
  3. /* |. o.| || This program may not be distributed without the permission of   */
  4. /* | .  | || the authors:                                          BBS:      */
  5. /* | o  | ||   John Toebes     Dave Baker                                    */
  6. /* |  . |//                                                                  */
  7. /* ======                                                                    */
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9. /* Volume Manipulation */
  10. /* mount */
  11. #include "handler.h"
  12.  
  13. void DisMount(global)
  14. GLOBAL global;
  15. {
  16.    struct DeviceList *volume;
  17.    struct DosInfo *info;
  18.    struct RootNode *root;
  19.  
  20.    BUG(("Dismount\n"));
  21.  
  22.    /* start at the root of the device list */
  23.    root   = (struct RootNode   *)DOSBase->dl_Root;
  24.    info   = (struct DosInfo    *)BADDR(root->rn_Info);
  25.    volume = (struct DeviceList *)BADDR(info->di_DevInfo);
  26.  
  27.    /* Flush and purge all buffers */
  28.    FlushBuffers(global, 1);
  29.  
  30.    /* Free bitmap storage for this disk */
  31.    FreeBitMap(global);
  32.  
  33.    /* See if we have a current volume that we have to get rid of ? */
  34.    /* Make sure there are no outstanding locks for the volume */
  35.    if ((global->volume != NULL) && (global->volume->dl_Lock == NULL))
  36.       {
  37.       /* This volume needs to be removed from the list */
  38.       /* First locate it on the list */
  39.       Forbid();
  40.  
  41.       /* is it at the head of the list? */
  42.       if (volume == global->volume)
  43.          /* sure enough, just get rid of it */
  44.          info->di_DevInfo = volume->dl_Next;
  45.       else
  46.          {
  47.          /* Find it in the list */
  48.          while(volume != NULL &&
  49.                (struct DeviceList *)(BADDR(volume->dl_Next)) != global->volume)
  50.             volume = (struct DeviceList *)BADDR(volume->dl_Next);
  51.  
  52.          /* if we found it then take it out of the chain */
  53.          if (volume != NULL)
  54.             volume->dl_Next = global->volume->dl_Next;
  55.          }
  56.       Permit();
  57.  
  58.       if (global->volume)
  59.          {
  60.          DosFreeMem((char *)global->volume);
  61.          }
  62.       }
  63.  
  64.    global->volume = NULL;
  65.    global->diskstate  = ID_VALIDATING;
  66. }
  67.  
  68. void Mount(global)
  69. GLOBAL global;
  70. {
  71.    struct RootBlock *block;
  72.    struct DeviceList *volume;
  73.    struct DosInfo *info;
  74.    struct RootNode *root;
  75.    char *newname;
  76.    short newlen; /* Cause memcmp to use the most efficient code */
  77.    int rwflag;
  78.  
  79.    BUG(("Mount\n"));
  80.  
  81.    global->changedisk = 0;
  82.    global->ErrorCount = 0;
  83.    global->DiskChange = 0;
  84.    rwflag = ResetDrive(global);
  85.  
  86.    DisMount(global);
  87.  
  88.    if (global->diskstatus == ID_NO_DISK_PRESENT)
  89.       {
  90.       /* If we don't have a disk, we might as well return */
  91.       Motor(global, 0);
  92.       return;
  93.       }
  94.  
  95.    /* first see if anything is in the drive. */
  96.    if ((block = (struct RootBlock *)GetBlock(global,0)) == NULL)
  97.       {
  98.       global->diskstatus = ID_UNREADABLE_DISK;
  99.       global->diskstate  = ID_VALIDATING;
  100.       return;
  101.       }
  102.  
  103.    global->diskstatus = block->rb_Type;
  104.    global->diskstate  = ID_VALIDATED;
  105.  
  106.    /* OK, something is there, hows about asking for more information on */
  107.    /* the volume */
  108.    if ((block = (struct RootBlock *)GetBlock(global,global->Root)) == NULL)
  109.       return;
  110.  
  111.    /* Now make sure we have a valid block to write to */
  112.    newname = (char *)(block->rb_Name);
  113.    newlen = *newname + 1;
  114.  
  115.    /* Now find it on the device list. */
  116.    /* First start at the root of the device list */
  117.    root   = (struct RootNode   *)DOSBase->dl_Root;
  118.    info   = (struct DosInfo    *)BADDR(root->rn_Info);
  119.    volume = (struct DeviceList *)BADDR(info->di_DevInfo);
  120.  
  121.    BUGBSTR("Volume name is : ", newname);
  122.  
  123.    /* Can't let the system change the list underneath us...        */
  124.    Forbid();
  125.    
  126.    /* Now run through the list until we come up empty OR we find it */
  127.    while(volume != NULL)
  128.       {
  129.       if (volume->dl_Type == DLT_VOLUME                               &&
  130.           !memcmp(newname, (char *)BADDR(volume->dl_Name), newlen)    &&
  131.           volume->dl_VolumeDate.ds_Days   == block->rb_CreateDays     &&
  132.           volume->dl_VolumeDate.ds_Minute == block->rb_CreateMinutes  &&
  133.           volume->dl_VolumeDate.ds_Tick   == block->rb_CreateTicks)
  134.          break;
  135.       volume = (struct DeviceList *)BADDR(volume->dl_Next);
  136.       }
  137.  
  138.    Permit();
  139.  
  140.    BUG(("mount: Volume is %08lx\n", volume));
  141.  
  142.    /* OK, now did we find it? */
  143.    if (volume != NULL)
  144.       {
  145.       BUG(("Got a matching node\n"));
  146.  
  147.       /* Sure did, We probably need to check to see if another handler has */
  148.       /* it to work with, but for now we assume only onw such volume can   */
  149.       /* exist.  This was a problem with all but the latest version of 1.2 */
  150.       /* If we have write access, we should probably nudge the ticks by one*/
  151.       /* just to make it unique                                            */
  152.       }
  153.    else
  154.       /* No such volume is known to the system.  So we will just have to   */
  155.       /* allocate a node to put everything on.                             */
  156.       {
  157.       volume = (struct DeviceList *)
  158.                DosAllocMem(global, sizeof(struct DeviceList)+newlen);
  159.  
  160.       BUG(("Created new node at %08lx\n", volume));
  161.  
  162.       /* Note that volume+1 gets us to the extra memory we allocated.  */
  163.       /* Just a lot simpler to write that in C than ...+sizeof(...)    */
  164.       memcpy((char *)(volume + 1), newname, newlen);
  165.       volume->dl_VolumeDate.ds_Days   = block->rb_CreateDays;
  166.       volume->dl_VolumeDate.ds_Minute = block->rb_CreateMinutes;
  167.       volume->dl_VolumeDate.ds_Tick   = block->rb_CreateTicks;
  168.       volume->dl_Name = (BSTR *)MKBADDR((volume + 1));
  169.       volume->dl_Lock = NULL;
  170.       volume->dl_Type = DLT_VOLUME;
  171.  
  172.       /* Also we need to link it into the list */
  173.       Forbid();
  174.       volume->dl_Next = info->di_DevInfo;
  175.       info->di_DevInfo = MKBADDR(volume);
  176.       Permit();
  177.       }
  178.  
  179.    /* Now we can own the volume by giving it our task id */
  180.    volume->dl_Task = global->port;
  181.    volume->dl_DiskType = ID_DOS_DISK;
  182.    global->diskstate = (rwflag) ? ID_WRITE_PROTECTED : ID_VALIDATED;
  183.  
  184.    /* all set up, remember what our base volume is */
  185.    global->volume = volume;
  186.  
  187.    /* Initialize the bitmap */
  188.    AllocBitMap(global);
  189. }
  190.