home *** CD-ROM | disk | FTP | other *** search
-
- /**************************************************************************/
- /* Format */
- /* Version 1.00 */
- /* */
- /* This is a replacement for the AmigaDOS "Format" command. It sports */
- /* (for the Workbench user) more friendly user-interface, although it is */
- /* virtually identical to the standard Format command where the CLI */
- /* interface is concerned. */
- /* */
- /* This program is Copyright 1992 by Dave Schreiber, All Rights Reserved. */
- /* This program may not be sold for more than a small copying and shipping*/
- /* and handling fee, except by written permission of Dave Schreiber. */
- /* */
- /* Version list: */
- /* 1.00 - First release (August 31, 1992) */
- /**************************************************************************/
-
-
- /*System header files*/
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <intuition/intuition.h>
- #include <dos/dos.h>
- #include <dos/filehandler.h>
- #include <workbench/startup.h>
- #include <libraries/gadtools.h>
- #include <workbench/icon.h>
- #include <devices/trackdisk.h>
- #include <dos/rdargs.h>
-
- /*Prototypes for system functions*/
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/dos.h>
- #include <proto/gadtools.h>
- #include <proto/icon.h>
- #include <proto/graphics.h>
-
- /*Other headers*/
- #include "Format.h"
- #include "GUI.h"
-
- /*These hold the user's selections*/
- /*They are initialized in main()*/
- BOOL FFS;
- BOOL QuickFmt;
- BOOL Verify;
- BOOL Icon;
-
- /*This holds the pointer to the Workbench startup message, if we're started*/
- /*from Workbench*/
- extern struct WBStartup *WBenchMsg;
-
- /*Library base pointers*/
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *GadToolsBase,*IconBase;
-
- /*This is initialized in GUI.c and holds the location and size*/
- /*of the progress indicator box in the status window*/
- extern Rect box;
-
- BPTR StdErr=NULL;
-
- /*For use with the CLI "Version" command*/
- char *Version = "$VER: NewFormat V1.00 (31.8.92)";
-
- /*The entry point for the program (_main to keep a CLI window from opening*/
- /*when the program is run from Workbench)*/
- _main()
- {
- UWORD disk;
- char volumeName[256];
- prepResult stat;
- char statusString[80];
-
- /*Open the various shared libraries that are needed*/
- IntuitionBase=(struct Library *)OpenLibrary("intuition.library",37L);
- GfxBase=(struct Library *)OpenLibrary("graphics.library",37L);
- IconBase=(struct Library *)OpenLibrary("icon.library",37L);
- GadToolsBase=(struct Library *)OpenLibrary("gadtools.library",37L);
-
- /*Check to see that they all opened, and exit if any did not*/
- if(IntuitionBase==NULL || GfxBase==NULL || IconBase==NULL ||
- GadToolsBase==NULL)
- cleanup(100);
-
- if(WBenchMsg!=NULL)
- {
- /*If we're running from Workbench, and the user did not select*/
- /*a drive, print an error and exit*/
- if(WBenchMsg->sm_NumArgs==1)
- {
- printError("Please select a drive to format and try again.",NULL,NULL);
- cleanup(100);
- }
-
- /*Get the visual info, etc.*/
- SetupScreen();
-
- /*For every selected disk...*/
- for(disk=1;disk<WBenchMsg->sm_NumArgs && stat!=eQuit;disk++)
- {
- /*This will hold the disk's new name*/
- char newName[36];
-
- /*Initialize the format settings*/
- FFS=FALSE;
- QuickFmt=FALSE;
- Verify=TRUE;
- Icon=TRUE;
-
- /*Get the volume/device name of the disk to format*/
- getVolumeName(volumeName,WBenchMsg->sm_ArgList,disk);
-
- /*If there is no lock to the volume, that means it is */
- /*unformatted, so just use the name given to us by Workbench*/
- if(WBenchMsg->sm_ArgList[disk].wa_Lock==NULL)
- strcpy(volumeName,WBenchMsg->sm_ArgList[disk].wa_Name);
-
- /*Open the options window*/
- if((stat=OpenPrepWindow(volumeName))==0)
- {
- /*Get the user's input*/
- stat=getPrepInput();
-
- /*And close the window*/
- ClosePrepWindow();
-
- /*If the user selected 'OK'*/
- if(stat==eOK)
- {
- /*Get the new name of the disk*/
- strcpy(newName,((struct StringInfo *)
- (PrepGadgets[GD_NameGadget]->SpecialInfo))->Buffer);
-
- /*Ask the user for verification*/
- if(askAreYouSure(volumeName,
- (WBenchMsg->sm_ArgList[disk].wa_Lock!=NULL)))
- {
-
- /*If everything's OK, open the status window*/
- if((stat=OpenStatusWindow(statusString))==0)
- {
- /*And format the disk*/
- formatVolume(&(WBenchMsg->sm_ArgList[disk].wa_Lock),
- volumeName,newName,FFS,QuickFmt,Verify,Icon,
- statusString);
-
- /*We're done, so close the status window*/
- CloseStatusWindow();
- }
- }
- }
- }
- }
- /*Free the visual info, etc.*/
- CloseDownScreen();
- }
- else /*We've been run from the CLI*/
- {
- char driveName[64];
- BPTR driveLock;
- struct Process *process;
- APTR oldWdw;
- char temp[32];
- char temp2[4];
- DriveLayout junk;
-
- /*Open a 'stderr' I/O channel to the shell*/
- /*(the normal stderr was not opened since we used _main() ) */
- StdErr=Open("CONSOLE:",MODE_OLDFILE);
-
- /*Make sure requestors don't open*/
- process=(struct Process *)FindTask(0L);
- oldWdw=process->pr_WindowPtr;
- process->pr_WindowPtr=(APTR)(-1);
-
- /*Get the command-line arguments*/
- parseArgs(driveName,volumeName,&FFS,&Icon,&QuickFmt,&Verify);
-
- /*Get a lock on the selected drive*/
- /*(note: NULL is a valid return value; it means that the disk we*/
- /*want to format is itself unformatted)*/
- driveLock=Lock(driveName,ACCESS_READ);
-
- strcpy(temp,driveName);
-
- /*Get the volume/drive name*/
- if(volumeToDevName(driveLock,temp,&junk))
- {
- /*Wait for the user to tell us to go ahead*/
- Write(Output(),"Insert the disk to be formatted in drive ",41);
- Write(Output(),temp,strlen(temp));
- Write(Output()," and press RETURN ",18);
- Read(Input(),temp2,1);
-
- /*Format the disk*/
- formatVolume(&driveLock,temp,volumeName,FFS,QuickFmt,Verify,Icon,
- statusString);
- }
- else
- Write(Output(),"Cannot find the specified drive!\n",33);
-
- Close(StdErr);
-
- /*Restore the old contents of this pointer*/
- process->pr_WindowPtr=(APTR)(-1);
-
- Write(Output(),"\n",1);
- }
- cleanup(0);
- return(0);
- }
-
- /*This functions handles the low-level format, the high-level format, the*/
- /*creation of icons, etc.*/
- void formatVolume(BPTR *volumeLock,char *volumeName,char *newName,BOOL ffs,
- BOOL quick,BOOL verify,BOOL icon,char *statString)
- {
- struct IOExtTD *io1;
- BOOL fmtResult=TRUE;
- int result;
- char deviceName[64];
- DriveLayout layout;
- struct MsgPort *devPort;
- BOOL writeProtCont=TRUE;
-
- /*If the volume lock is NULL, assume that the volumeName string holds*/
- /*a valid device pointer*/
- if(*volumeLock==NULL)
- strcpy(deviceName,volumeName);
-
- /*Get the drive name (if possible)*/
- if(!volumeToDevName(*volumeLock,deviceName,&layout))
- {
- printError("Can't find the drive!",NULL,NULL);
- return;
- }
-
- /*This port will be used to communicate with the filesystem*/
- devPort=DeviceProc(deviceName);
- if(devPort==NULL)
- {
- printError("Can't find the drive",NULL,NULL);
- return;
- }
-
- /*Inhibit the drive*/
- DoPkt(devPort,ACTION_INHIBIT,DOSTRUE,NULL,NULL,NULL);
-
- /*If we got a lock to the volume that we're going to format it, destroy*/
- /*it, since the volume that it points to is about to be erased anyway*/
- if(*volumeLock!=NULL)
- {
- UnLock(*volumeLock);
- *volumeLock=NULL;
- }
-
- /*Open the disk device*/
- if((io1=OpenDrive(layout.devName,layout.unit,layout.flags))!=NULL)
- {
- /*Determine the write protect status*/
- io1->iotd_Req.io_Data=NULL;
- io1->iotd_Req.io_Length=0;
- io1->iotd_Req.io_Command=TD_PROTSTATUS;
- DoIO((struct IOReq *)io1);
-
- /*Loop while the disk stays protected and user keeps pressing Retry*/
- while(io1->iotd_Req.io_Actual!=0 &&
- (writeProtCont=alertIsWriteProtected(volumeName)))
- DoIO((struct IOReq *)io1);
-
- /*If the disk is not write-protected*/
- if(writeProtCont)
- {
- /*Do a full format if the user didn't select the 'Quick' option*/
- if(!quick)
- fmtResult=doFullFormat(&layout,statString,volumeName,io1);
-
- /*If the format was successful*/
- if(fmtResult)
- {
- /*Write an extra carriage return, if run from the CLI*/
- if(WBenchMsg==NULL)
- Write(Output(),"\n",1);
-
- /*Tell the user that we're doing the high-level format*/
- fmtResult=!updateStatWindow("Formatting disk...",1000);
-
- /*If the user hasn't clicked on 'Stop', do the high-level format*/
- if(fmtResult)
- result=Format(deviceName,newName,
- ffs ? ID_FFS_DISK : ID_DOS_DISK);
- }
- }
- else
- printError("Cannot format volume",volumeName,
- "because the disk is write protected");
- /*Close the disk device*/
- CloseDrive(io1);
- }
- else
- {
- printError("Couldn't access the device",NULL,NULL);
- return;
- }
-
- /*Uninhibit the drive*/
- DoPkt(devPort,ACTION_INHIBIT,DOSFALSE,NULL,NULL,NULL);
-
- /*Wait for the drive to come on line*/
- Delay(50);
-
- /*If the disk was never unprotected, return*/
- if(!writeProtCont)
- return;
-
- /*If the format was successful and the user wants icons created*/
- if(icon && result==DOSTRUE)
- {
- struct DiskObject *trashIcon;
- BPTR trashLock;
-
- /*Update the user*/
- fmtResult=!updateStatWindow("Creating Trashcan ",1000);
-
- /*If she didn't press 'Stop'*/
- if(fmtResult)
- {
- /*Create the trashcan name (<volume>:Trashcan)*/
- strcpy(deviceName,newName);
- strcat(deviceName,":");
- strcat(deviceName,"Trashcan");
-
- /*Create the trashcan directory*/
- trashLock=CreateDir(deviceName);
-
- /*If it was successfully created*/
- if(trashLock!=NULL)
- {
- UnLock(trashLock);
- /*Get the trashcan icon*/
- trashIcon=GetDefDiskObject(WBGARBAGE);
-
- /*If there wasn't an error*/
- if(trashIcon!=NULL)
- {
- /*Write the icon to disk*/
- if(!PutDiskObject(deviceName,trashIcon))
- printError("There was an error while creating the trashcan",
- NULL,NULL);
-
- /*and free it*/
- FreeDiskObject(trashIcon);
- }
- else
- printError("There was an error while creating the trashcan",
- NULL,NULL);
- }
- else
- printError("There was an error while creating the trashcan directory",
- NULL,NULL);
- }
- }
- return;
- }
-
- /*This function does a full (low-level) format of a disk*/
- BOOL doFullFormat(DriveLayout *layout,char *statString,char *devName,
- struct IOExtTD *io1)
- {
- ULONG *write;
- ULONG trackSize,sectorPos,numTracks;
- LONG track;
- int c;
- UBYTE error=2;
- BOOL errorB=FALSE;
-
- /*Get the size of a track (#surfaces*#blocks*#longwordsPerTrack*4*/
- trackSize=layout->surfaces*layout->blockSize*4*layout->BPT;
-
- /*Allocate enough memory for one track*/
- write=AllocMem(trackSize,layout->memType|MEMF_CLEAR);
- if(write!=NULL)
- {
- /*Initialize the IORequest*/
- io1->iotd_Req.io_Data=write;
- io1->iotd_Req.io_Length=trackSize;
-
- /*Get the starting byte position in the volume*/
- sectorPos=layout->lowCyl*trackSize;
-
- /*Get the number of tracks to format*/
- numTracks=layout->highCyl-layout->lowCyl+1;
-
- /*Clear the status window*/
- error=(updateStatWindow(" ",0)) ? 0 : error;
-
- /*For each track*/
- for(track=0;track<numTracks && error!=0;track++)
- {
- /*Setup to format the disk*/
- io1->iotd_Req.io_Command=TD_FORMAT;
- io1->iotd_Req.io_Offset=sectorPos;
-
- /*Update the status window*/
- strcpy(statString,"Formatting cylinder ");
- stci_d(&statString[20],track+layout->lowCyl);
- strcat(statString,", ");
- stci_d(&statString[strlen(statString)],numTracks-track-1);
- strcat(statString," to go ");
-
- error=(updateStatWindow(statString,track*1000/numTracks)) ?0:error;
-
- /*If the user didn't press 'Stop'*/
- if(error!=0)
- {
- error=(DoIO((struct IOReq *)io1)) ? 0 : error;
- if(error==0)
- printError("A formatting error occured",NULL,NULL);
- }
-
- /*If we're suppossed to verify, and the user didn't press 'Stop'*/
- if(Verify && error!=0)
- {
- /*Setup the same IORequest to do a read*/
- io1->iotd_Req.io_Command=CMD_READ;
-
- /*Update the status*/
- strcpy(statString," Verifying cylinder ");
- stci_d(&statString[20],track+layout->lowCyl);
- strcat(statString,", ");
- stci_d(&statString[strlen(statString)],numTracks-track-1);
- strcat(statString," to go ");
-
- error=(updateStatWindow(statString,
- ( (1+(track*2))*1000)/(2*numTracks) )) ? 0 : error;
-
- /*If the user hasn't pressed 'Stop'*/
- if(error!=0)
- {
- /*Do the read*/
- if(DoIO((struct IOReq *)io1))
- {
- if(--error==0)
- printError("A verify error occurred",NULL,NULL);
- errorB=TRUE;
- }
- }
-
- /*Check the data that was read back.*/
- for(c=0;c<trackSize>>2 && error!=0;c++)
- {
- /*If there was an error*/
- if(write[c]!=0L)
- {
- /*Record the fact*/
- if(!errorB)
- {
- errorB=TRUE;
- if(--error==0)
- /*Print an error message*/
- printError("A verify error occurred",NULL,NULL);
- }
- write[c]=0L;
- }
- }
- if(!errorB && error!=2)
- error=2;
- }
- /*Get the byte position of the next track*/
- if(errorB)
- {
- errorB=FALSE;
- track--;
- }
- else
- sectorPos+=trackSize;
- }
-
- /*We're done, so free the track memory*/
- FreeMem(write,trackSize);
- }
- else
- printError("Couldn't allocate write buffer",NULL,NULL);
-
- return(error!=0);
- }
-
- /*Used in askAreYouSure()*/
- struct EasyStruct areYouSure=
- {
- sizeof(struct EasyStruct),
- 0,
- "Format Request...",
- "Are you sure you want to format volume\n%s\n(the contents of the disk will be destroyed)?",
- "Yes|No"
- };
-
- /*Ask the user if she really wants to format the disk*/
- BOOL askAreYouSure(char *volumeName,BOOL truncColon)
- {
- char name[36];
- APTR args[2];
- UBYTE result;
-
- /*Get the device name*/
- strcpy(name,volumeName);
-
- /*Truncate the trailing colon if so specified*/
- if(truncColon)
- name[strlen(name)-1]=NULL;
-
- /*Setup the device name as the argument to the requestor*/
- args[0]=name;
- args[1]=NULL;
-
- /*Put up the requestor*/
- result=EasyRequestArgs(NULL,&areYouSure,NULL,args);
-
- /*Return the result*/
- return(result==1);
- }
-
- /*Used in askAreYouSure()*/
- struct EasyStruct writeProtected=
- {
- sizeof(struct EasyStruct),
- 0,
- "Format Request...",
- "Volume\n%s\nis write protected",
- "Retry|Cancel"
- };
-
- /*Alert the user to the fact that the disk is write protected, and give*/
- /*the user a chance to unprotect the disk*/
- BOOL alertIsWriteProtected(char *devName)
- {
- APTR args[2];
- BYTE result;
-
- /*Setup the device name as the argument to the requestor*/
- args[0]=devName;
- args[1]=NULL;
-
- /*Put up the requestor*/
- result=EasyRequestArgs(NULL,&writeProtected,NULL,args);
-
- /*Return the result*/
- return(result==1);
- }
-
- /*This is used to print errors*/
- struct EasyStruct errorReq=
- {
- sizeof(struct EasyStruct),
- 0,
- "Format Request...",
- NULL,
- "Ok"
- };
-
- char *oneLine="%s";
- char *twoLine="%s\n%s";
- char *threeLine="%s\n%s\n%s";
-
- /*Print one, two, or three lines of error messages in an EasyRequestor*/
- /*or to 'StdErr'*/
- void printError(char *first,char *second,char *third)
- {
- APTR args[4];
- args[0]=args[3]=NULL;
-
- /*If we're running from the CLI*/
- if(WBenchMsg==NULL)
- {
- /*And a StdErr handle was opened successfully*/
- if(StdErr!=NULL)
- {
- char LF=0x0A;
-
- /*Print the first line*/
- if(first!=NULL)
- {
- Write(StdErr,first,strlen(first));
- Write(StdErr," ",1);
- }
-
- /*Print the second line*/
- if(second!=NULL)
- {
- Write(StdErr,second,strlen(second));
- Write(StdErr," ",1);
- }
-
- /*Print the third line*/
- if(third!=NULL)
- {
- Write(StdErr,third,strlen(third));
- Write(StdErr," ",1);
- }
-
- /*Print the terminating carriage return*/
- Write(StdErr,&LF,1);
- }
- }
- else /*Otherwise, we're running from Workbench, so put up the requestor*/
- {
- /*Three lines*/
- if(third!=NULL)
- {
- args[2]=third;
- args[1]=second;
- args[0]=first;
- errorReq.es_TextFormat=threeLine;
- }
- else if(second!=NULL) /*Two lines*/
- {
- args[1]=second;
- args[0]=first;
- errorReq.es_TextFormat=twoLine;
- }
- else if(first!=NULL) /*One line*/
- {
- args[0]=first;
- errorReq.es_TextFormat=oneLine;
- }
- /*Put up the requestor*/
- EasyRequestArgs(NULL,&errorReq,NULL,args);
- }
-
- return;
- }
-
- /*Get the name of a volume, given a lock to that volume*/
- void getVolumeName(char *name,struct WBArg *argList,UWORD disk)
- {
- /*Get the name*/
- if(NameFromLock(argList[disk].wa_Lock,name,256)==DOSFALSE)
- /*Or return <unknown> if the name couldn't be determined*/
- strcpy(name,"<unknown>");
-
- return;
- }
-
- /*Exit from the program, closing any open libraries*/
- void cleanup(ULONG err)
- {
- if(IntuitionBase!=NULL)
- CloseLibrary((struct Library *)IntuitionBase);
-
- if(GfxBase!=NULL)
- CloseLibrary((struct Library *)GfxBase);
-
- if(GadToolsBase!=NULL)
- CloseLibrary(GadToolsBase);
-
- if(IconBase!=NULL)
- CloseLibrary(IconBase);
-
- exit(err);
- }
-
- /*Get input from the original window*/
- prepResult getPrepInput(void)
- {
- struct IntuiMessage *mesg;
- ULONG class;
- ULONG code;
- struct Gadget *gadget;
- struct TagItem tags[2];
-
- /*Setup tags that will be used to toggle the states of checkbox gadgets*/
- tags[0].ti_Tag=GTCB_Checked;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- /*Loop until the user presses 'OK' or 'Cancel'*/
- for(;;)
- {
- /*Wait for input*/
- Wait(1<<PrepWnd->UserPort->mp_SigBit);
-
- /*Get the input*/
- mesg=GT_GetIMsg(PrepWnd->UserPort);
-
- /*Loop while there are messages to be processed*/
- while(mesg!=NULL)
- {
- /*Get the message type, etc.*/
- class=mesg->Class;
- code=mesg->Code;
- gadget=(struct Gadget *)mesg->IAddress;
-
- /*Reply to the message*/
- GT_ReplyIMsg(mesg);
-
- /*Act on the message*/
- switch(class)
- {
- /*User clicked on close gadget. Treat it as a click on 'Cancel'*/
- case CLOSEWINDOW:
- return(eQuit);
-
- /*User pressed a gadget*/
- case GADGETUP:
- switch(gadget->GadgetID)
- {
- /*Checkbox gadgets*/
- /*(each toggles the appropriate status flag)*/
- case GD_FFSGadget:
- FFS=!FFS;
- break;
- case GD_IconGadget:
- Icon=!Icon;
- break;
- case GD_QuickFmtGadget:
- QuickFmt=!QuickFmt;
- break;
- case GD_VerifyGadget:
- Verify=!Verify;
- break;
-
- /*OK*/
- case GD_OKGadget:
- return(eOK);
-
- /*Cancel*/
- case GD_CancelGadget:
- return(eCancel);
- }
- break;
-
- /*Keypress (gadget equivalents)*/
- case VANILLAKEY:
- switch(code)
- {
- /*Disk name*/
- case 'n':
- case 'N':
- ActivateGadget(PrepGadgets[GD_NameGadget],
- PrepWnd,NULL);
- break;
-
- /*FFS*/
- case 'f':
- case 'F':
- tags[0].ti_Data=(FFS=!FFS);
-
- /*Toggle the checkmark state of the gadget*/
- GT_SetGadgetAttrsA(PrepGadgets[GD_FFSGadget],
- PrepWnd,NULL, tags);
- break;
-
- /*Verify*/
- case 'v':
- case 'V':
- tags[0].ti_Data=(Verify=!Verify);
-
- GT_SetGadgetAttrsA(PrepGadgets[GD_VerifyGadget],
- PrepWnd,NULL, tags);
- break;
-
- /*Quick Format*/
- case 'q':
- case 'Q':
- tags[0].ti_Data=(QuickFmt=!QuickFmt);
-
- GT_SetGadgetAttrsA(PrepGadgets[GD_QuickFmtGadget],
- PrepWnd,NULL, tags);
- break;
-
- /*Create icons*/
- case 'r':
- case 'R':
- tags[0].ti_Data=(Icon=!Icon);
-
- GT_SetGadgetAttrsA(PrepGadgets[GD_IconGadget],
- PrepWnd,NULL, tags);
- break;
-
- /*Cancel*/
- case 'c':
- case 'C':
- return(eCancel);
-
- /*OK*/
- case 'o':
- case 'O':
- return(eOK);
- }
- break;
- }
- /*Get the next message*/
- mesg=GT_GetIMsg(PrepWnd->UserPort);
- }
- }
- return(FALSE);
- }
-
- /*Convert a volume name to a device name, and get information*/
- /*on the layout of the disk*/
- BOOL volumeToDevName(BPTR volumeLock,char *dev,DriveLayout *layout)
- {
- BOOL stat;
- struct DosList *dosList;
- struct DeviceNode *devNode;
- char name[36];
- char *temp;
- int c;
- BPTR tempLock=NULL;
- struct DosEnvec *driveEnv;
- struct Process *process;
- APTR oldWdw;
-
- /*Disable requestors during the execution of this function*/
- process=(struct Process *)FindTask(0L);
- oldWdw=process->pr_WindowPtr;
- process->pr_WindowPtr=(APTR)(-1);
-
- /*Get the DOS device list*/
- dosList=LockDosList(LDF_DEVICES|LDF_READ);
-
- /*Go through each entry*/
- while(dosList = NextDosEntry(dosList,LDF_DEVICES|LDF_READ))
- {
- devNode=(struct DeviceNode *)dosList;
-
- /*If the node in the list is a volume*/
- if(devNode->dn_Startup > 1000 &&
- (devNode->dn_Task || devNode->dn_Handler || devNode->dn_SegList))
- {
- /*Get the name of the device*/
- temp=(char *)BADDR(devNode->dn_Name);
-
- for(c=0;c<temp[0];c++)
- name[c]=temp[c+1];
-
- name[c]=':';
- name[c+1]=0;
-
- /*Get the information on the device*/
- /* driveEnv=(struct DosEnvec *)
- BADDR(((struct FileSysStartupMsg *)
- BADDR(devNode->dn_Startup))->fssm_Environ);*/
-
- /*If the volume lock is NULL, the 'dev' is assumed to be the*/
- /*name of a device holding an unformatted disk, so compare the*/
- /*name to the name of the current node*/
- if(volumeLock==NULL)
- stat=(stricmp(dev,name)==0);
- else
- {
- /*Otherwise, since 'dev' could hold a volume rather than*/
- /*device name, get a lock on it and compare it to the lock*/
- /*on the device that was given; if they're the same, we've*/
- /*found the drive*/
-
- tempLock=Lock(name,ACCESS_READ);
- stat=(SameLock(tempLock,volumeLock)==LOCK_SAME);
- }
-
- /*If we've found the drive, get the information on it*/
- if(stat)
- {
- struct FileSysStartupMsg *startup;
- char *devName;
-
- /*Get a pointer to the structure that holds the needed info*/
- startup=(struct FileSysStartupMsg *)BADDR(devNode->dn_Startup);
- driveEnv=(struct DosEnvec *)BADDR(startup->fssm_Environ);
-
- /*Get the information*/
- layout->unit=startup->fssm_Unit;
-
- devName=(char *)BADDR(startup->fssm_Device);
-
- /*Copy the device name to layout->devName*/
- for(c=0;c<devName[0];c++)
- layout->devName[c]=devName[c+1];
- layout->devName[c+1]=0;
-
- layout->flags=startup->fssm_Flags;
-
- layout->memType=driveEnv->de_BufMemType;
-
- layout->lowCyl=driveEnv->de_LowCyl;
- layout->highCyl=driveEnv->de_HighCyl;
- layout->surfaces=driveEnv->de_Surfaces;
- layout->BPT=driveEnv->de_BlocksPerTrack;
- layout->blockSize=driveEnv->de_SizeBlock;
-
- /*Copy the device name back to 'dev'*/
- strcpy(dev,name);
-
- /*UnLock the drive lock, if it exists*/
- if(tempLock!=NULL)
- UnLock(tempLock);
-
- /*Unlock the DOS list*/
- UnLockDosList(LDF_DEVICES|LDF_READ);
-
- /*Restore the requester pointer*/
- process->pr_WindowPtr=oldWdw;
-
- /*And return TRUE*/
- return(TRUE);
- }
-
- /*We didn't find the drive, so unlock the lock and try again*/
- if(tempLock!=NULL)
- UnLock(tempLock);
- }
- }
-
- /*We didn't find the drive in the list, so unlock the list*/
- UnLockDosList(LDF_DEVICES|LDF_READ);
-
- /*Restore the requester pointer*/
- process->pr_WindowPtr=oldWdw;
-
- /*And return*/
- return(FALSE);
- }
-
- /*Create a communications port linking this process to the drive*/
- struct IOExtTD *OpenDrive(char *driveDevName,ULONG unit,ULONG flags)
- {
- struct MsgPort *diskPort;
- struct IOExtTD *diskRequest;
-
- /*Create the message port*/
- if((diskPort = CreateMsgPort())!=NULL)
- {
- /*Create the IORequest*/
- diskRequest=
- (struct IOExtTD *)CreateIORequest(diskPort,sizeof(struct IOExtTD));
- if(diskRequest!=NULL)
- {
- /*Open the device, and return the IORequest if the device*/
- /*opened successfully*/
- if(!OpenDevice(driveDevName,unit,(struct IORequest *)diskRequest,flags))
- return(diskRequest);
-
- /*The device didn't open, so clean up*/
- DeleteIORequest(diskRequest);
- }
-
- DeleteMsgPort(diskPort);
- }
-
- /*Return NULL to indicate that an error occurred*/
- return(NULL);
- }
-
- /*Close an open device and delete the accompanying port, etc.*/
- void CloseDrive(struct IOExtTD *diskRequest)
- {
- CloseDevice((struct IORequest *)diskRequest);
- DeleteMsgPort(diskRequest->iotd_Req.io_Message.mn_ReplyPort);
- DeleteIORequest(diskRequest);
- }
-
- /*Convert a CSTR to a BSTR*/
- BSTR makeBSTR(char *in,char *out)
- {
- int c;
-
- out[0]=strlen(in);
- for(c=0;c<out[0];c++)
- out[c+1]=in[c];
-
- return(MKBADDR(out));
- }
-
- LONG args[6]=
- {
- NULL,NULL,0,0,0,0
- };
-
- /*Get the command-line arguments given by the user, by using ReadArgs()*/
- void parseArgs(char *drive,char *newName,BOOL *ffs,BOOL *icons,BOOL *quick,
- BOOL *verify)
- {
- APTR r;
-
- /*Get the arguments*/
- r=ReadArgs("DRIVE/K/A,NAME/K/A,FFS/S,NOICONS/S,QUICK/S,NOVERIFY/S",args,
- NULL);
-
- /*If the user didn't specify a drive name, print an error*/
- if(args[0]==NULL)
- {
- printError("You need to specify a drive to format",NULL,NULL);
- if(r!=NULL)
- FreeArgs(r);
- cleanup(200);
- }
- else
- strcpy(drive,(char *)args[0]);
-
- /*Likewise for a name for the newly formatted volume*/
- if(args[1]==NULL)
- {
- printError("You need to specify a name for the volume",NULL,NULL);
- cleanup(200);
- }
- else
- strcpy(newName,(char *)args[1]);
-
- /*Get the four togglable settings*/
- *ffs=(args[2]!=0);
- *icons=(args[3]==0);
- *quick=(args[4]!=0);
- *verify=(args[5]==0);
-
- /*We're done, so free the ReadArgs result*/
- FreeArgs(r);
-
- /*And return*/
- return;
- }
-
- /*Update the status window (from Workbench), or CLI output (from the CLI)*/
- /*If running from the CLI, this also checks to see if the user has pressed*/
- /*control-C*/
- BOOL updateStatWindow(char *string,UWORD percent)
- {
- UWORD width;
- ULONG class;
- UWORD code;
- struct TagItem tags[3];
- static char Message[80];
-
- struct IntuiMessage *mesg;
-
- /*If this is NULL, we're running from the CLI*/
- if(WBenchMsg==NULL)
- {
- /*Write the string to the CLI, followed by a carriage return (but*/
- /*not a line feed)*/
- char CR=0x0d;
- Write(Output(),string,strlen(string));
- Write(Output(),&CR,1);
-
- /*Check to see if the user pressed Control-C*/
- if( (SetSignal(0,0) & SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
- {
- /*If he did, print "***Break" and return TRUE, to signal that*/
- /*the user aborted the formatting process*/
- Write(Output(),"\n***Break\n",10);
- return(TRUE);
- }
- /*Otherwise, continue*/
- return(FALSE);
- }
-
- /*This code is used to update the status window that is displayed when*/
- /*the user runs NewFormat from the Workbench*/
-
- /*This puts the message into the text-display gadget*/
- /*This copy is so that the caller can change the contents of 'string'*/
- /*upon return (which can't be done without the copy, since GadTools*/
- /*won't copy the contents of 'string' to an internal buffer*/
- strcpy(Message,string);
- tags[0].ti_Tag=GTTX_Text;
- tags[0].ti_Data=(ULONG)Message;
-
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- GT_SetGadgetAttrsA(StatusGadgets[GD_StatusGadget],
- StatusWnd,NULL, tags);
-
- /*Fill the status box with the current percentage of completion*/
- SetAPen(StatusWnd->RPort,3);
- width=box.left+((box.width-3)*percent)/1000;
- RectFill(StatusWnd->RPort,box.left+2,box.top+1,width,box.top+box.height-2);
-
- /*Check user input*/
- mesg=GT_GetIMsg(StatusWnd->UserPort);
-
- /*Loop while there are messages*/
- while(mesg!=NULL)
- {
- class=mesg->Class;
- code=mesg->Code;
- GT_ReplyIMsg(mesg);
-
- switch(class)
- {
- /*Return TRUE (user abort) if the user pressed 's', 'S'*/
- case IDCMP_VANILLAKEY:
- if(code=='s' || code=='S')
- return(TRUE);
- break;
-
- /*Or if the user pressed the 'Stop' gadget*/
- case IDCMP_GADGETUP:
- return(TRUE);
- }
- /*Get the next message*/
- mesg=GT_GetIMsg(StatusWnd->UserPort);
- }
- return(FALSE);
- }
-
- /*End of Format.c*/
-
-