/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */ /* |. o.| || This program may not be distributed without the permission of */ /* | . | || the authors: BBS: */ /* | o | || John Toebes Dave Baker */ /* | . |// */ /* ====== */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Volume Manipulation */ /* mount */ #include "handler.h" void DisMount(global) GLOBAL global; { struct DeviceList *volume; struct DosInfo *info; struct RootNode *root; BUG(("Dismount\n")); /* start at the root of the device list */ root = (struct RootNode *)DOSBase->dl_Root; info = (struct DosInfo *)BADDR(root->rn_Info); volume = (struct DeviceList *)BADDR(info->di_DevInfo); /* Flush and purge all buffers */ FlushBuffers(global, 1); /* Free bitmap storage for this disk */ FreeBitMap(global); /* See if we have a current volume that we have to get rid of ? */ /* Make sure there are no outstanding locks for the volume */ if ((global->volume != NULL) && (global->volume->dl_Lock == NULL)) { /* This volume needs to be removed from the list */ /* First locate it on the list */ Forbid(); /* is it at the head of the list? */ if (volume == global->volume) /* sure enough, just get rid of it */ info->di_DevInfo = volume->dl_Next; else { /* Find it in the list */ while(volume != NULL && (struct DeviceList *)(BADDR(volume->dl_Next)) != global->volume) volume = (struct DeviceList *)BADDR(volume->dl_Next); /* if we found it then take it out of the chain */ if (volume != NULL) volume->dl_Next = global->volume->dl_Next; } Permit(); if (global->volume) { DosFreeMem((char *)global->volume); } } global->volume = NULL; global->diskstate = ID_VALIDATING; } void Mount(global) GLOBAL global; { struct RootBlock *block; struct DeviceList *volume; struct DosInfo *info; struct RootNode *root; char *newname; short newlen; /* Cause memcmp to use the most efficient code */ int rwflag; BUG(("Mount\n")); global->changedisk = 0; global->ErrorCount = 0; global->DiskChange = 0; rwflag = ResetDrive(global); DisMount(global); if (global->diskstatus == ID_NO_DISK_PRESENT) { /* If we don't have a disk, we might as well return */ Motor(global, 0); return; } /* first see if anything is in the drive. */ if ((block = (struct RootBlock *)GetBlock(global,0)) == NULL) { global->diskstatus = ID_UNREADABLE_DISK; global->diskstate = ID_VALIDATING; return; } global->diskstatus = block->rb_Type; global->diskstate = ID_VALIDATED; /* OK, something is there, hows about asking for more information on */ /* the volume */ if ((block = (struct RootBlock *)GetBlock(global,global->Root)) == NULL) return; /* Now make sure we have a valid block to write to */ newname = (char *)(block->rb_Name); newlen = *newname + 1; /* Now find it on the device list. */ /* First start at the root of the device list */ root = (struct RootNode *)DOSBase->dl_Root; info = (struct DosInfo *)BADDR(root->rn_Info); volume = (struct DeviceList *)BADDR(info->di_DevInfo); BUGBSTR("Volume name is : ", newname); /* Can't let the system change the list underneath us... */ Forbid(); /* Now run through the list until we come up empty OR we find it */ while(volume != NULL) { if (volume->dl_Type == DLT_VOLUME && !memcmp(newname, (char *)BADDR(volume->dl_Name), newlen) && volume->dl_VolumeDate.ds_Days == block->rb_CreateDays && volume->dl_VolumeDate.ds_Minute == block->rb_CreateMinutes && volume->dl_VolumeDate.ds_Tick == block->rb_CreateTicks) break; volume = (struct DeviceList *)BADDR(volume->dl_Next); } Permit(); BUG(("mount: Volume is %08lx\n", volume)); /* OK, now did we find it? */ if (volume != NULL) { BUG(("Got a matching node\n")); /* Sure did, We probably need to check to see if another handler has */ /* it to work with, but for now we assume only onw such volume can */ /* exist. This was a problem with all but the latest version of 1.2 */ /* If we have write access, we should probably nudge the ticks by one*/ /* just to make it unique */ } else /* No such volume is known to the system. So we will just have to */ /* allocate a node to put everything on. */ { volume = (struct DeviceList *) DosAllocMem(global, sizeof(struct DeviceList)+newlen); BUG(("Created new node at %08lx\n", volume)); /* Note that volume+1 gets us to the extra memory we allocated. */ /* Just a lot simpler to write that in C than ...+sizeof(...) */ memcpy((char *)(volume + 1), newname, newlen); volume->dl_VolumeDate.ds_Days = block->rb_CreateDays; volume->dl_VolumeDate.ds_Minute = block->rb_CreateMinutes; volume->dl_VolumeDate.ds_Tick = block->rb_CreateTicks; volume->dl_Name = (BSTR *)MKBADDR((volume + 1)); volume->dl_Lock = NULL; volume->dl_Type = DLT_VOLUME; /* Also we need to link it into the list */ Forbid(); volume->dl_Next = info->di_DevInfo; info->di_DevInfo = MKBADDR(volume); Permit(); } /* Now we can own the volume by giving it our task id */ volume->dl_Task = global->port; volume->dl_DiskType = ID_DOS_DISK; global->diskstate = (rwflag) ? ID_WRITE_PROTECTED : ID_VALIDATED; /* all set up, remember what our base volume is */ global->volume = volume; /* Initialize the bitmap */ AllocBitMap(global); }