home *** CD-ROM | disk | FTP | other *** search
Wrap
/* $Revision Header * Header built automatically - do not edit! ************* * * (C) Copyright 1990 by Olaf Barthel & MXM * * Name .....: Format.c * Created ..: Wednesday 29-May-91 17:06 * Revision .: 1 * * Date Author Comment * ========= ======== ==================== * 06-Jun-91 Olsen Kept the panel from being created * twice. * 29-May-91 Olsen Created this file! * * $Revision Header ********************************************************/ /* A handy keyboard shortcut. */ struct Shortcut { UBYTE Key; SHORT GadgetID,GadgetType; }; /* A custom node, contains both the DeviceNode and the change * count of a disk drive. */ struct DevNode { struct Node VanillaNode; struct DeviceNode *DevNode; ULONG ChangeCount; }; /* Gadget IDs. */ enum { GAD_DRIVES,GAD_SIZE,GAD_NAME,GAD_WHOLEDISK,GAD_VERIFY, GAD_CREATEICONS,GAD_INSTALLDISK,GAD_AUTOSTART, GAD_EJECTDISK,GAD_USEFFS,GAD_STATUS,GAD_START, GAD_STOP }; /* Size of the Format window. */ #define WIDTH 556 #define HEIGHT 125 /* Shell interface. */ enum { ARG_DRIVE,ARG_NAME,ARG_FFS,ARG_NOICONS,ARG_QUICK,ARG_NOVERIFY,ARG_INSTALL,ARG_EJECT }; #define NUM_ARGS ARG_EJECT + 1 #define ARG_TEMPLATE "DRIVE/K/A,NAME/K,FFS/S,NOICONS/S,QUICK/S,NOVERIFY/S,INSTALL/S,EJECT/S" /* Just another macro. */ #define SetWait(Window) SetPointer((Window),&Stopwatch[0],16,16,-6,0) /* A set of keyboard macros. */ struct Shortcut Shortcuts[] = { 'N', GAD_NAME, STRING_KIND, 'F', GAD_WHOLEDISK, CHECKBOX_KIND, 'V', GAD_VERIFY, CHECKBOX_KIND, 'C', GAD_CREATEICONS, CHECKBOX_KIND, 'I', GAD_INSTALLDISK, CHECKBOX_KIND, 'A', GAD_AUTOSTART, CHECKBOX_KIND, 'E', GAD_EJECTDISK, CHECKBOX_KIND, 'U', GAD_USEFFS, CHECKBOX_KIND }; /* Global library identifiers. */ extern struct ExecBase *SysBase; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Library *GadToolsBase; struct Library *IconBase; struct Library *WorkbenchBase; /* Part of the Workbench interface. */ struct MsgPort *WBenchPort; struct AppWindow *WBenchWindow; /* Graphics & Intuition data. */ struct Screen *DefaultScreen; APTR VisualInfo; struct TextFont *Topaz; struct Gadget *GadgetList; struct Gadget *GadgetArray[GAD_STOP + 1]; struct Window *Window; /* List of filing devices. */ struct List *DevList; /* Some more global data and flags. */ UBYTE *DiskName; struct DeviceNode *LastNode; BYTE Formatting; BYTE WholeDisk,Verify,CreateIcons,InstallDisk,AutoStart,EjectDisk,UseFFS; BYTE FromShell; /* The default font. */ struct TextAttr DefaultFont = { (UBYTE *)"topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; /* The stopwatch sprite pointer. */ UWORD __chip Stopwatch[(2 + 16) * 2] = { 0x0000,0x0000, 0x0400,0x07C0, 0x0000,0x07C0, 0x0100,0x0380, 0x0000,0x07E0, 0x07C0,0x1FF8, 0x1FF0,0x3FEC, 0x3FF8,0x7FDE, 0x3FF8,0x7FBE, 0x7FFC,0xFF7F, 0x7EFC,0xFFFF, 0x7FFC,0xFFFF, 0x3FF8,0x7FFE, 0x3FF8,0x7FFE, 0x1FF0,0x3FFC, 0x07C0,0x1FF8, 0x0000,0x07E0, 0x0000,0x0000 }; /* Run-dump of a standard filing system bootblock. */ ULONG Bootblock_OFS[13] = { 0x444F5300,0xC0200F19,0x00000370,0x43FA0018, 0x4EAEFFA0,0x4A80670A,0x20402068,0x00167000, 0x4E7570FF,0x60FA646F,0x732E6C69,0x62726172, 0x79000000 }; /* Run-dump of an FFS bootblock (the checksum's different). */ ULONG Bootblock_FFS[13] = { 0x444F5301,0xC0200F18,0x00000370,0x43FA0018, 0x4EAEFFA0,0x4A80670A,0x20402068,0x00167000, 0x4E7570FF,0x60FA646F,0x732E6C69,0x62726172, 0x79000000 }; /* Disable the SAS/C ^C trapping. */ int CXBRK(VOID) { return(0); } /* UpdateInfo(): * * Check the checkbox gadgets and set the formatting * flags accordingly. */ VOID UpdateInfo() { if(!FromShell) { if(GadgetArray[GAD_WHOLEDISK] -> Flags & GFLG_SELECTED) WholeDisk = TRUE; else WholeDisk = FALSE; if(GadgetArray[GAD_VERIFY] -> Flags & GFLG_SELECTED) Verify = TRUE; else Verify = FALSE; if(GadgetArray[GAD_CREATEICONS] -> Flags & GFLG_SELECTED) CreateIcons = TRUE; else CreateIcons = FALSE; if(GadgetArray[GAD_INSTALLDISK] -> Flags & GFLG_SELECTED) InstallDisk = TRUE; else InstallDisk = FALSE; if(GadgetArray[GAD_AUTOSTART] -> Flags & GFLG_SELECTED) AutoStart = TRUE; else AutoStart = FALSE; if(GadgetArray[GAD_EJECTDISK] -> Flags & GFLG_SELECTED) EjectDisk = TRUE; else EjectDisk = FALSE; if(GadgetArray[GAD_USEFFS] -> Flags & GFLG_SELECTED) UseFFS = TRUE; else UseFFS = FALSE; } } /* CloseDrive(struct IOExtTD *DevRequest): * * Close a disk driver opened using OpenDrive. */ VOID CloseDrive(struct IOExtTD *DevRequest) { CloseDevice(DevRequest); DeleteMsgPort(DevRequest -> iotd_Req . io_Message . mn_ReplyPort); DeleteIORequest(DevRequest); } /* OpenDrive(struct DeviceNode *DevNode): * * Open a filing system driver */ struct IOExtTD * OpenDrive(struct DeviceNode *DevNode) { struct FileSysStartupMsg *Startup = (struct FileSysStartupMsg *)BADDR(DevNode -> dn_Startup); struct MsgPort *DevPort; struct IOExtTD *DevRequest; if(DevPort = CreateMsgPort()) { if(DevRequest = (struct IOExtTD *)CreateIORequest(DevPort,sizeof(struct IOExtTD))) { if(!OpenDevice(&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit,DevRequest,Startup -> fssm_Flags)) return(DevRequest); DeleteIORequest(DevRequest); } DeleteMsgPort(DevPort); } return(NULL); } /* GetChangedDrive(): * * Walk through the list of filing devices and obtain * the change count of each drive. Return the device * which has recently had a disk-change. */ struct DevNode * GetChangedDrive() { struct DevNode *ChangedDrive = NULL; struct DevNode *SomeNode; struct IOExtTD *DevRequest; SomeNode = (struct DevNode *)DevList -> lh_Head; /* Walk through the list.. */ while(SomeNode -> VanillaNode . ln_Succ) { /* Open the driver. */ if(DevRequest = OpenDrive(SomeNode -> DevNode)) { DevRequest -> iotd_Req . io_Command = TD_CHANGENUM; /* Obtain the disk change count. */ if(!DoIO(DevRequest)) { /* Is it different from the * value last obtained? */ if(SomeNode -> ChangeCount != DevRequest -> iotd_Req . io_Actual) { ChangedDrive = SomeNode; SomeNode -> ChangeCount = DevRequest -> iotd_Req . io_Actual; } } CloseDrive(DevRequest); } SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; } return(ChangedDrive); } /* FindDevices(): * * Scan the DosList for block-mapped filing devices. */ struct List * FindDevices() { struct DosList *DosList; struct DeviceNode *DevNode; struct List *SomeList; struct DevNode *SomeNode; UBYTE *Pointer; SHORT i; /* Allocate a list for the DevNode entries. */ if(SomeList = (struct List *)AllocVec(sizeof(struct List),MEMF_PUBLIC|MEMF_CLEAR)) { NewList(SomeList); /* Lock the DosList for reading. */ DosList = LockDosList(LDF_DEVICES|LDF_READ); /* Scan the list for device entries. */ while(DosList = NextDosEntry(DosList,LDF_DEVICES|LDF_READ)) { /* Swap the entry type. */ DevNode = (struct DeviceNode *)DosList; /* Kludge: RAW:, PRT:, PAR: have dn_Startup * set to a nonzero value. */ if(DevNode -> dn_Startup > 1000 && (DevNode -> dn_Task || DevNode -> dn_Handler || DevNode -> dn_SegList)) { Pointer = (UBYTE *)BADDR(DevNode -> dn_Name); /* If it has a name, add it to the list. */ if(Pointer[0]) { if(SomeNode = AllocVec(sizeof(struct DevNode) + Pointer[0] + 2,MEMF_PUBLIC|MEMF_CLEAR)) { SomeNode -> VanillaNode . ln_Name = (UBYTE *)(SomeNode + 1); for(i = 0 ; i < Pointer[0] ; i++) SomeNode -> VanillaNode . ln_Name[i] = Pointer[i + 1]; SomeNode -> VanillaNode . ln_Name[Pointer[0] ] = ':'; SomeNode -> VanillaNode . ln_Name[Pointer[0] + 1] = 0; SomeNode -> DevNode = DevNode; AddTail(SomeList,SomeNode); } } } } UnLockDosList(LDF_DEVICES|LDF_READ); } return(SomeList); } /* FreeDevices(struct List *SomeList): * * Free the list of devices obtained through FindDevices. */ VOID FreeDevices(struct List *SomeList) { struct Node *SomeNode,*NextNode; SomeNode = SomeList -> lh_Head; while(SomeNode -> ln_Succ) { NextNode = SomeNode -> ln_Succ; FreeVec(SomeNode); SomeNode = NextNode; } FreeVec(SomeList); } /* CreateAllGadgets(): * * Create all the gadgets for the Format window. */ struct Gadget * CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge) { struct Gadget *Gadget; struct NewGadget NewGadget; UWORD Counter = 0,LeftEdge; if(Gadget = CreateContext(GadgetList)) { if(DevList = FindDevices()) GetChangedDrive(); NewGadget . ng_Width = 268; NewGadget . ng_Height = 60; NewGadget . ng_GadgetText = "Drives"; NewGadget . ng_TextAttr = &DefaultFont; NewGadget . ng_VisualInfo = VisualInfo; NewGadget . ng_GadgetID = Counter; NewGadget . ng_Flags = PLACETEXT_LEFT; NewGadget . ng_LeftEdge = LeftEdge = (strlen(NewGadget . ng_GadgetText) + 2) * 8 + 1; NewGadget . ng_TopEdge = 1 + TopEdge; GadgetArray[Counter++] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget, GTLV_Labels, DevList, GTLV_Selected, DevList ? 0 : ~0, GTLV_ShowSelected, NULL, TAG_DONE); NewGadget . ng_GadgetText = "Size"; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 13; GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget, GTTX_Text, " -- Tracks --.--- MBytes", GTTX_Border, TRUE, TAG_DONE); NewGadget . ng_GadgetText = "_Name"; NewGadget . ng_Height = 14; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget, GTST_MaxChars, 31, GTST_String, "Empty", GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "_Format Whole Disk"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_Flags = PLACETEXT_RIGHT; NewGadget . ng_LeftEdge = LeftEdge + 272; NewGadget . ng_TopEdge = 1 + TopEdge; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', GTCB_Checked, TRUE, TAG_DONE); NewGadget . ng_GadgetText = "_Verify Writes"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', GTCB_Checked, TRUE, TAG_DONE); NewGadget . ng_GadgetText = "_Create Icons"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', GTCB_Checked, TRUE, TAG_DONE); NewGadget . ng_GadgetText = "_Install Disk"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "_Auto Start"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "_Eject Disk"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "_Use Fast Filing System"; NewGadget . ng_Width = 244; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget, GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "Status"; NewGadget . ng_Width = 268; NewGadget . ng_Height = 12; NewGadget . ng_Flags = 0; NewGadget . ng_GadgetID = Counter; NewGadget . ng_LeftEdge = LeftEdge; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 2; GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget, GTTX_Text, "Idle", GTTX_Border, TRUE, TAG_DONE); NewGadget . ng_GadgetText = "Start (_S)"; NewGadget . ng_Width = 133; NewGadget . ng_Height = 12; NewGadget . ng_Flags = 0; NewGadget . ng_GadgetID = Counter; NewGadget . ng_LeftEdge = LeftEdge; NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 1; GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget, GT_Underscore, '_', TAG_DONE); NewGadget . ng_GadgetText = "Stop (_S)"; NewGadget . ng_Width = 133; NewGadget . ng_Height = 12; NewGadget . ng_GadgetID = Counter; NewGadget . ng_LeftEdge = LeftEdge + 135; GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget, GT_Underscore, '_', GA_Disabled, TRUE, TAG_DONE); } return(Gadget); } /* CloseAll(LONG ReturnCode): * * Return all resources obtained at startup and exit * gracefully. */ VOID CloseAll(LONG ReturnCode) { if(WBenchWindow) RemoveAppWindow(WBenchWindow); if(WBenchPort) { struct Message *Massage; while(Massage = GetMsg(WBenchPort)) ReplyMsg(Massage); DeleteMsgPort(WBenchPort); } if(WorkbenchBase) CloseLibrary(WorkbenchBase); if(Window) CloseWindow(Window); if(GadgetList) FreeGadgets(GadgetList); if(VisualInfo) FreeVisualInfo(VisualInfo); if(DefaultScreen) UnlockPubScreen(NULL,DefaultScreen); if(DevList) FreeDevices(DevList); if(IconBase) CloseLibrary(IconBase); if(GadToolsBase) CloseLibrary(GadToolsBase); if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); exit(ReturnCode); } /* OpenAll(): * * Obtain all resourced required to run this program. */ VOID OpenAll() { if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))) CloseAll(RETURN_FAIL + 1); if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37))) CloseAll(RETURN_FAIL + 2); if(!(GadToolsBase = (struct Library *)OpenLibrary("gadtools.library",37))) CloseAll(RETURN_FAIL + 3); IconBase = OpenLibrary("icon.library",37); if(!(Topaz = (struct TextFont *)OpenFont(&DefaultFont))) CloseAll(RETURN_FAIL + 4); if(!(DefaultScreen = (struct Screen *)LockPubScreen(NULL))) CloseAll(RETURN_FAIL + 5); if(!(VisualInfo = GetVisualInfo(DefaultScreen,TAG_DONE))) CloseAll(RETURN_FAIL + 6); if(!CreateAllGadgets(&GadgetArray[0],&GadgetList,VisualInfo,DefaultScreen -> WBorTop + DefaultScreen -> Font -> ta_YSize + 1)) CloseAll(RETURN_FAIL + 7); if(!(Window = OpenWindowTags(NULL, WA_Width, WIDTH, WA_Height, HEIGHT + DefaultScreen -> Font -> ta_YSize - 8, WA_Activate, TRUE, WA_DragBar, TRUE, WA_DepthGadget, TRUE, WA_CloseGadget, TRUE, WA_RMBTrap, TRUE, WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_DISKINSERTED | CHECKBOXIDCMP | BUTTONIDCMP | LISTVIEWIDCMP, WA_Title, "Format v1.1 © Copyright 1991 by MXM", TAG_DONE))) CloseAll(RETURN_FAIL + 8); if(WorkbenchBase = OpenLibrary("workbench.library",37)) { if(!(WBenchPort = CreateMsgPort())) CloseAll(RETURN_FAIL + 9); WBenchWindow = AddAppWindow(0,0,Window,WBenchPort,NULL); } SetFont(Window -> RPort,Topaz); AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL); RefreshGList(GadgetList,Window,NULL,(UWORD)-1); GT_RefreshWindow(Window,NULL); UpdateInfo(); } /* LockWindow(struct Window *Window): * * Disable all gadgets in the Format window and set the * stopwatch mouse pointer. */ VOID LockWindow(struct Window *Window) { SetWait(Window); GT_SetGadgetAttrs(GadgetArray[GAD_NAME],Window,NULL, GA_Disabled, TRUE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_WHOLEDISK],Window,NULL, GA_Disabled, TRUE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_USEFFS],Window,NULL, GA_Disabled, TRUE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_START],Window,NULL, GA_Disabled, TRUE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_STOP],Window,NULL, GA_Disabled, FALSE, TAG_DONE); } /* UnLockWindow(struct Window *Window): * * Re-enable the gadgets in the Format window and clear * the mouse pointer. */ VOID UnLockWindow(struct Window *Window) { ClearPointer(Window); GT_SetGadgetAttrs(GadgetArray[GAD_NAME],Window,NULL, GA_Disabled, FALSE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_WHOLEDISK],Window,NULL, GA_Disabled, FALSE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_USEFFS],Window,NULL, GA_Disabled, FALSE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_STOP],Window,NULL, GA_Disabled, TRUE, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_START],Window,NULL, GA_Disabled, FALSE, TAG_DONE); } /* GetUsedBlocks(struct DosEnvec *DosEnvec,BYTE UseFFS): * * Calculate the number of blocks which will be * occupied if a filing system is formatted. */ ULONG GetUsedBlocks(struct DosEnvec *DosEnvec,BYTE UseFFS) { ULONG Blocks,BitmapBlocks,ExtensionBlocks = 0; /* Number of blocks available for the * filing system. */ Blocks = (DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1) * DosEnvec -> de_BlocksPerTrack * DosEnvec -> de_Surfaces; /* Calculate the number of bitmap blocks. */ BitmapBlocks = (((Blocks + 31) / 32) + 126) / 127; /* The old filing system only allows 25 bitmap * blocks. */ if(UseFFS && BitmapBlocks > 25) BitmapBlocks = 25; else { /* If there are more than 25 bitmap blocks, * calculate the number of bitmap extension * blocks required to chain them. */ if(BitmapBlocks > 25) ExtensionBlocks = (BitmapBlocks - 25 + 126) / 127; } return(DosEnvec -> de_Reserved + BitmapBlocks + ExtensionBlocks + 1); } /* SizeInfo(struct DeviceNode *DevNode): * * Give a brief size info on a given filing system. */ VOID SizeInfo(struct DeviceNode *DevNode) { if(Formatting) { struct DevNode *SomeNode; SHORT i = 0; /* This is a nuisance: you cannot disable * gadtools listviews. As a fix we will * simply ignore any clicks in this area * and revert to the previously selected * entry. */ SomeNode = (struct DevNode *)DevList -> lh_Head; while(SomeNode -> VanillaNode . ln_Succ) { if(SomeNode -> DevNode != LastNode) { i++; SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; } else break; } GT_SetGadgetAttrs(GadgetArray[GAD_DRIVES],Window,NULL, GTLV_Selected, i, TAG_DONE); } else { struct DosEnvec *DosEnvec; ULONG Blocks; UBYTE Buffer[60]; UpdateInfo(); /* Neat casting, innit? */ DosEnvec = (struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(DevNode -> dn_Startup)) -> fssm_Environ); /* Determine the number of blocks which are actually * not in use. */ Blocks = (DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1) * DosEnvec -> de_Surfaces * DosEnvec -> de_SectorPerBlock * DosEnvec -> de_BlocksPerTrack - GetUsedBlocks(DosEnvec,UseFFS); /* Multiply by the verbatim size of a DOS block. */ if(UseFFS) Blocks = Blocks * (DosEnvec -> de_SizeBlock << 2) / 1000; else Blocks = Blocks * 488 / 1000; SPrintf(Buffer,"%5ld Tracks %4ld.%03ld MBytes",DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1,Blocks / 1000,Blocks % 1000); GT_SetGadgetAttrs(GadgetArray[GAD_SIZE],Window,NULL, GTTX_Text, Buffer, TAG_DONE); LastNode = DevNode; } } /* ShowInfo(UBYTE *Format,...): * * Show a text in the status field of the Format window. */ VOID ShowInfo(UBYTE *Format,...) { UBYTE Buffer[60]; va_list VarArgs; va_start(VarArgs,Format); VSPrintf(Buffer,Format,VarArgs); va_end(VarArgs); if(FromShell) Printf("\33[A%s\33[K\n",Buffer); else { GT_SetGadgetAttrs(GadgetArray[GAD_STATUS],Window,NULL, GTTX_Text, Buffer, TAG_DONE); } } /* MyEasyRequest(): * * Varargs version of the EasyRequest call. */ SHORT __stdargs MyEasyRequest(struct Window *Window,UBYTE *Text,UBYTE *Gadgets,...) { struct EasyStruct __aligned Easy; SHORT Result; ULONG IDCMP = NULL; va_list VarArgs; Easy . es_StructSize = sizeof(struct EasyStruct); Easy . es_Flags = NULL; Easy . es_Title = (UBYTE *)"Format Request"; Easy . es_TextFormat = (UBYTE *)Text; Easy . es_GadgetFormat = (UBYTE *)Gadgets; va_start(VarArgs,Gadgets); Result = EasyRequestArgs(Window,&Easy,&IDCMP,VarArgs); va_end(VarArgs); return(Result); } /* HandleInput(): * * Tiny subroutine which handles all the input coming * while we are formatting. */ BYTE HandleInput() { BYTE Finished = FALSE; if(FromShell) { if(SetSignal(0,0) & SIGBREAKF_CTRL_C) { SetSignal(0,SIGBREAKF_CTRL_C); Finished = TRUE; Printf("\n***BREAK: Format\n\n"); } } else { if(WBenchPort) { if(SetSignal(0,0) & (1 << WBenchPort -> mp_SigBit)) { struct Message *Massage; SetSignal(0,(1 << WBenchPort -> mp_SigBit)); while(Massage = GetMsg(WBenchPort)) ReplyMsg(Massage); } } if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit)) { struct IntuiMessage *Massage; ULONG Class,Code; struct Gadget *Gadget; SetSignal(0,(1 << Window -> UserPort -> mp_SigBit)); while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort)) { Class = Massage -> Class; Code = Massage -> Code; Gadget = (struct Gadget *)Massage -> IAddress; GT_ReplyIMsg(Massage); if(Class == IDCMP_GADGETUP) { UpdateInfo(); if(Gadget -> GadgetID == GAD_STOP) Finished = TRUE; if(Gadget -> GadgetID == GAD_DRIVES) SizeInfo(NULL); } if(Class == IDCMP_VANILLAKEY) { if(toupper(Code) == 'S') Finished = TRUE; else { SHORT i; for(i = 0 ; i < (sizeof(Shortcuts) / sizeof(struct Shortcut)) ; i++) { if(Shortcuts[i] . Key == toupper(Code)) { if(Shortcuts[i] . GadgetType == CHECKBOX_KIND) { if(!(GadgetArray[Shortcuts[i] . GadgetID] -> Flags & GFLG_DISABLED)) { GT_SetGadgetAttrs(GadgetArray[Shortcuts[i] . GadgetID],Window,NULL, GTCB_Checked, (GadgetArray[Shortcuts[i] . GadgetID] -> Flags & GFLG_SELECTED) ? FALSE : TRUE, TAG_DONE); UpdateInfo(); } } } } } } } } } return(Finished); } /* Initialize(): * * Initialize a filing system, check if there is a disk in the * drive and if it's write enabled. Format the whole disk if * necessary. */ BYTE Initialize(struct DevNode *DriveNode,struct IOExtTD *DevRequest) { /* Is there a disk in the drive? */ FOREVER { DevRequest -> iotd_Req . io_Command = TD_CHANGESTATE; if(!DoIO(DevRequest)) { if(DevRequest -> iotd_Req . io_Actual) { if(FromShell) { Printf("No disk present in drive.\n",DriveNode -> VanillaNode . ln_Name); return(FALSE); } else { if(!MyEasyRequest(Window,"No disk present in drive\n%s","Retry|Cancel",DriveNode -> VanillaNode . ln_Name)) return(FALSE); } } else break; } else break; } /* Is the disk write enabled? */ FOREVER { DevRequest -> iotd_Req . io_Command = TD_PROTSTATUS; if(!DoIO(DevRequest)) { if(DevRequest -> iotd_Req . io_Actual) { if(FromShell) { Printf("Disk in drive %s is write protected.\n",DriveNode -> VanillaNode . ln_Name); return(FALSE); } else { if(!MyEasyRequest(Window,"Disk in drive\n%s\nis write protected.","Retry|Cancel",DriveNode -> VanillaNode . ln_Name)) return(FALSE); } } else break; } else break; } /* Are we to format the whole disk? */ if(WholeDisk) { ULONG *Track1,*Track2,*Src,*Dst; ULONG SizeTrack,i,j; struct DosEnvec *DosEnvec; ULONG LowTrack,NumTracks; BYTE Result = TRUE,Match; DosEnvec = (struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(DriveNode -> DevNode -> dn_Startup)) -> fssm_Environ); /* Determine the size of a disk track. */ SizeTrack = (DosEnvec -> de_SizeBlock << 2) * DosEnvec -> de_Surfaces * DosEnvec -> de_BlocksPerTrack; /* Allocate a write track... */ if(Track1 = (ULONG *)AllocVec(SizeTrack,DosEnvec -> de_BufMemType|MEMF_CLEAR)) { /* ...and a verification track. */ if(Track2 = (ULONG *)AllocVec(SizeTrack,DosEnvec -> de_BufMemType)) { /* Look up the first track and the number of * tracks to format. */ LowTrack = DosEnvec -> de_LowCyl * SizeTrack; NumTracks = DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1; /* Run down the number of tracks to format. */ for(i = 0 ; i < NumTracks ; i++) { if(HandleInput()) { Result = FALSE; break; } Retry: ShowInfo("Formatting %ld, %ld To Go",i,NumTracks - i - 1); /* Format a track. */ DevRequest -> iotd_Req . io_Command = TD_FORMAT; DevRequest -> iotd_Req . io_Data = Track1; DevRequest -> iotd_Req . io_Offset = LowTrack; DevRequest -> iotd_Req . io_Length = SizeTrack; if(DoIO(DevRequest)) { if(FromShell) { Printf("Error %ld occured while formatting track %ld.\n",DevRequest -> iotd_Req . io_Error,i); Result = FALSE; break; } else { if(MyEasyRequest(Window,"Error %ld occured while formatting track %ld.","Rewrite|Abort",DevRequest -> iotd_Req . io_Error,i)) goto Retry; else { Result = FALSE; break; } } } /* Check for abort. */ if(HandleInput()) { Result = FALSE; break; } /* If verification is enabled, * reread the track. */ if(Verify) { DevRequest -> iotd_Req . io_Command = CMD_UPDATE; if(DoIO(DevRequest)) { if(FromShell) { Printf("Error %ld occured while formatting track %ld.\n",DevRequest -> iotd_Req . io_Error,i); Result = FALSE; break; } else { if(MyEasyRequest(Window,"Error %ld occured while formatting track %ld.","Rewrite|Abort",DevRequest -> iotd_Req . io_Error,i)) goto Retry; else { Result = FALSE; break; } } } Retry2: ShowInfo("Verifying %ld, %ld To Go",i,NumTracks - i - 1); DevRequest -> iotd_Req . io_Command = CMD_READ; DevRequest -> iotd_Req . io_Data = Track2; DevRequest -> iotd_Req . io_Offset = LowTrack; DevRequest -> iotd_Req . io_Length = SizeTrack; if(DoIO(DevRequest)) { if(FromShell) { Printf("Error %ld occured while verifying track %ld.\n",DevRequest -> iotd_Req . io_Error,i); Result = FALSE; break; } else { if(MyEasyRequest(Window,"Error %ld occured while verifying track %ld.","Reread|Abort",DevRequest -> iotd_Req . io_Error,i)) goto Retry2; else { Result = FALSE; break; } } } Match = TRUE; j = SizeTrack >> 2; Src = Track1; Dst = Track2; /* Compare both * tracks. If the * data compared in * this loop was * residing in * chip ram, we * could use the * blitter to do * the job. */ while(j--) { if(*Src++ != *Dst++) { Match = FALSE; break; } } /* Are both tracks equal? */ if(!Match) { if(FromShell) { Printf("Verification error on track %ld.\n",i); Result = FALSE; break; } else { if(MyEasyRequest(Window,"Verification error on track %ld.","Rewrite|Abort",i)) goto Retry2; else { Result = FALSE; break; } } } } LowTrack += SizeTrack; } FreeVec(Track2); } FreeVec(Track1); } return(Result); } else return(TRUE); } /* Install(): * * Handle the rest of the initialization, write the root block, * the bitmap blocks and install the disk if necessary. */ BYTE Install(struct DevNode *DriveNode,struct IOExtTD *DevRequest) { struct DosEnvec *DosEnvec; ULONG *Block; UBYTE *Name; ShowInfo("Preparing Disk"); DosEnvec = (struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(DriveNode -> DevNode -> dn_Startup)) -> fssm_Environ); if(HandleInput()) return(FALSE); if(DiskName) Name = DiskName; else Name = ((struct StringInfo *)GadgetArray[GAD_NAME] -> SpecialInfo) -> Buffer; if(HandleInput()) return(FALSE); /* Tell the handler to initialize the underlying data media. */ if(!Format(DriveNode -> VanillaNode . ln_Name,Name[0] ? Name : "Empty",UseFFS ? ID_FFS_DISK : ID_DOS_DISK)) { if(FromShell) Printf("Failed to format drive %s.\n",DriveNode -> VanillaNode . ln_Name); else MyEasyRequest(Window,"Failed to format drive\n%s","Proceed",DriveNode -> VanillaNode . ln_Name); return(FALSE); } /* Are we to install the disk and is there enough space left * to install it? */ if(DosEnvec -> de_Reserved > 0 && InstallDisk) { /* Allocate a bootblock-sized chunk. */ if(Block = (ULONG *)AllocVec((DosEnvec -> de_SizeBlock << 2) * DosEnvec -> de_Reserved,DosEnvec -> de_BufMemType|MEMF_CLEAR)) { ShowInfo("Installing Disk"); /* Install the approriate bootblock type. */ if(UseFFS) CopyMem(Bootblock_FFS,Block,sizeof(Bootblock_FFS)); else CopyMem(Bootblock_OFS,Block,sizeof(Bootblock_OFS)); DevRequest -> iotd_Req . io_Command = CMD_WRITE; DevRequest -> iotd_Req . io_Data = Block; DevRequest -> iotd_Req . io_Length = (DosEnvec -> de_SizeBlock << 2) * DosEnvec -> de_Reserved; DevRequest -> iotd_Req . io_Offset = DosEnvec -> de_LowCyl * DosEnvec -> de_Surfaces * (DosEnvec -> de_SizeBlock << 2); if(DoIO(DevRequest)) { if(FromShell) Printf("Error %ld occured while writing the boot block.\n",DevRequest -> iotd_Req . io_Error); else MyEasyRequest(Window,"Error %ld occured while writing the boot block.","Proceed",DevRequest -> iotd_Req . io_Error); FreeVec(Block); return(FALSE); } FreeVec(Block); } } if(EjectDisk) { DevRequest -> iotd_Req . io_Command = TD_EJECT; DoIO(DevRequest); } return(TRUE); } /* FormatDrive(struct DevNode *DriveNode,BYTE Query): * * Format a filing system, handle the user-interface part. */ VOID FormatDrive(struct DevNode *DriveNode,BYTE Query) { struct DosEnvec *DosEnvec; ULONG Blocks; DosEnvec = (struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(DriveNode -> DevNode -> dn_Startup)) -> fssm_Environ); Blocks = (DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1) * DosEnvec -> de_Surfaces * DosEnvec -> de_BlocksPerTrack; Formatting = TRUE; if(!FromShell) LockWindow(Window); UpdateInfo(); /* Is the user trying to format filing system larger than * 52 MBytes using the old filing system? */ if(Blocks > 101600 && !UseFFS) { if(FromShell) Printf("You cannot format partitions larger than approximately 52 MBytes\nusing the old filing system. Use Fast File System instead.\n"); else MyEasyRequest(Window,"You cannot format partitions larger than\napproximately 52 MBytes using the old\nfiling system. Use Fast File System\ninstead.","Proceed"); } else { SHORT Result; /* Give the user a last chance to abort the * formatting. */ if(Query) { /* Display a special text if the * data media to be formatted is not * a standard 3½" disk. */ if(Blocks > 1760) { DisplayBeep(Window -> WScreen); Result = MyEasyRequest(Window," Caution!\n\n\ Drive %s is not a standard-sized\n\ floppy disk drive but rather a hard-disk\n\ or high-density-floppy-disk drive.\n\n\ OK to format disk in drive\n\ %s\n\ (all data will be erased)?","OK|OK-Quick|Cancel",DriveNode -> VanillaNode . ln_Name,DriveNode -> VanillaNode . ln_Name); } else Result = MyEasyRequest(Window,"OK to format disk in drive\n%s\n(all data will be erased)?","OK|OK-Quick|Cancel",DriveNode -> VanillaNode . ln_Name); if(Result == 2) { GT_SetGadgetAttrs(GadgetArray[GAD_WHOLEDISK],Window,NULL, GTCB_Checked, FALSE, TAG_DONE); WholeDisk = FALSE; } } else Result = 1; UpdateInfo(); /* Start to format the disk. */ if(Result) { struct MsgPort *Proc; ShowInfo("Preparing to format drive %s",DriveNode -> VanillaNode . ln_Name); /* Tell the filing system to sleep. */ if(Proc = DeviceProc(DriveNode -> VanillaNode . ln_Name)) { if(DoPkt1(Proc,ACTION_INHIBIT,DOSTRUE)) { struct IOExtTD *DevRequest; BYTE Success = FALSE; if(DevRequest = OpenDrive(DriveNode -> DevNode)) { ShowInfo("Initializing Disk"); if(Initialize(DriveNode,DevRequest)) Success = Install(DriveNode,DevRequest); CloseDrive(DevRequest); } else { if(FromShell) Printf("Failed to open unit driver for drive %s.",DriveNode -> VanillaNode . ln_Name); else MyEasyRequest(Window,"Failed to open unit driver for drive %s.","Proceed",DriveNode -> VanillaNode . ln_Name); } /* Reenable the filing system. */ DoPkt1(Proc,ACTION_INHIBIT,DOSFALSE); /* Are we to create icons? */ if(Success && CreateIcons && IconBase) { struct DiskObject *Object; UBYTE Buffer[60]; ShowInfo("Creating Icons"); /* Create a disk icon. */ if(Object = GetDefDiskObject(WBDISK)) { SPrintf(Buffer,"%sDisk",DriveNode -> VanillaNode . ln_Name); Success = PutDiskObject(Buffer,Object); FreeDiskObject(Object); } /* Create a trashcan icon. */ if(Success) { if(Object = GetDefDiskObject(WBGARBAGE)) { SPrintf(Buffer,"%sTrashcan",DriveNode -> VanillaNode . ln_Name); if(PutDiskObject(Buffer,Object)) UnLock(CreateDir(Buffer)); FreeDiskObject(Object); } } } if(!FromShell) ShowInfo("Done!"); } } } } if(!FromShell) { ShowInfo("Idle"); UnLockWindow(Window); } Formatting = FALSE; } /* FormatFromWB(struct WBArg *Arg): * * Grab a Workbench argument pointer and try to format * the associated filing system. */ VOID FormatFromWB(struct WBArg *Arg) { struct DevNode *SomeNode; SHORT i = 0; UBYTE DriverName[256]; /* If it has got a lock take the name of the * associated filing system, else take a look * at the name passed to us. */ if(Arg -> wa_Lock) { struct FileLock *FileLock = BADDR(Arg -> wa_Lock); strcpy(DriverName,((struct Task *)FileLock -> fl_Task -> mp_SigTask) -> tc_Node . ln_Name); strcat(DriverName,":"); } else strcpy(DriverName,Arg -> wa_Name); SomeNode = (struct DevNode *)DevList -> lh_Head; /* Look for the node corresponding to the name. */ while(SomeNode -> VanillaNode . ln_Succ) { if(stricmp(DriverName,SomeNode -> VanillaNode . ln_Name)) { i++; SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; } else break; } /* Did we find a device of that name? */ if(SomeNode -> VanillaNode . ln_Succ) { GT_SetGadgetAttrs(GadgetArray[GAD_DRIVES],Window,NULL, GTLV_Selected, i, TAG_DONE); GT_SetGadgetAttrs(GadgetArray[GAD_USEFFS],Window,NULL, GTCB_Checked, ((struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(SomeNode -> DevNode -> dn_Startup)) -> fssm_Environ)) -> de_DosType == ID_FFS_DISK ? TRUE : FALSE, TAG_DONE); SizeInfo(SomeNode -> DevNode); FormatDrive(SomeNode,TRUE); } else MyEasyRequest(Window,"Drive %s is not a block-mapped\ndisk filing system.","Proceed",DriverName); } /* main(int argc,char **argv): * * The main routine (what else?). */ VOID main(int argc,char **argv) { struct IntuiMessage *Massage; ULONG Class,Code; struct Gadget *Gadget; BYTE Terminated = FALSE; SHORT i; struct DevNode *DriveNode; extern struct ExecBase *SysBase; /* Check to see if it's below our preferred * revision number. */ if(SysBase -> LibNode . lib_Version < 37) exit(RETURN_FAIL); /* We were run from Workbench, have a look at the * startup packet being passed. */ if(!argc) { extern struct WBStartup *WBenchMsg; /* We are asked to format data media. */ if(WBenchMsg -> sm_NumArgs > 1) { OpenAll(); /* Run down the list of * arguments. */ for(i = 1 ; i < WBenchMsg -> sm_NumArgs ; i++) FormatFromWB(&WBenchMsg -> sm_ArgList[i]); CloseAll(RETURN_OK); } } /* If the argument count is below two, then we're * probably to display the shiny gadtools panel. */ if(argc < 2) { ULONG SignalSet; /* Open the libs and create the panel. */ OpenAll(); /* Pick up the first filing system in the list. */ DriveNode = (struct DevNode *)DevList -> lh_Head; /* Toggle the `Use FFS' button if necessary. */ GT_SetGadgetAttrs(GadgetArray[GAD_USEFFS],Window,NULL, GTCB_Checked, ((struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(DriveNode -> DevNode -> dn_Startup)) -> fssm_Environ)) -> de_DosType == ID_FFS_DISK ? TRUE : FALSE, TAG_DONE); /* Display the size of the data media. */ SizeInfo(DriveNode -> DevNode); /* Go into loop waiting for input... */ while(!Terminated) { /* Piece the signal mask to wait * for together. */ SignalSet = (1 << Window -> UserPort -> mp_SigBit); /* Wait for any messages sent by Workbench. */ if(WBenchPort) SignalSet |= (1 << WBenchPort -> mp_SigBit); SignalSet = Wait(SignalSet); /* Have a look at the Workbench port. */ if(WBenchPort) { struct AppMessage *AppMassage; /* Remove the application window * messages. */ while(AppMassage = (struct AppMessage *)GetMsg(WBenchPort)) { /* Format the associated media. */ for(i = 0 ; i < AppMassage -> am_NumArgs ; i++) FormatFromWB(&AppMassage -> am_ArgList[i]); ReplyMsg(&AppMassage -> am_Message); } } /* Remove all the messages pending * at the panel window. */ while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))) { Class = Massage -> Class; Code = Massage -> Code; Gadget = (struct Gadget *)Massage -> IAddress; GT_ReplyIMsg(Massage); /* Terminate the program? */ if(Class == IDCMP_CLOSEWINDOW) Terminated = TRUE; /* A disk has been inserted and * we're probably autostart-enabled. */ if(Class == IDCMP_DISKINSERTED) { struct DevNode *Node; /* To insure that all the * disk change counts are * kept even, even if auto- * start is not enabled we * will call the checkup * routine and abort if * autostart is not enabled. * If were not playing the * game this way, we could * accidentally assume that * a disk changed long ago * before autostart was * enabled was a candidat * for formatting... */ if((Node = GetChangedDrive()) && AutoStart) { struct DevNode *SomeNode; /* Try to find the * index of the * DevNode whose * device we are to * initialize (to * keep the listview * happy). */ i = 0; SomeNode = (struct DevNode *)DevList -> lh_Head; while(SomeNode -> VanillaNode . ln_Succ) { if(SomeNode != Node) { i++; SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; } else break; } DriveNode = SomeNode; /* Display the * size of the * data media. */ SizeInfo(SomeNode -> DevNode); /* Display the * approriate listview * entry. */ GT_SetGadgetAttrs(GadgetArray[GAD_DRIVES],Window,NULL, GTLV_Selected, i, TAG_DONE); /* Bring the screen * to the front... */ MoveScreen(Window -> WScreen,-Window -> WScreen -> LeftEdge,-Window -> WScreen -> TopEdge); ScreenToFront(Window -> WScreen); /* Flash the display. */ DisplayBeep(Window -> WScreen); /* Bring the window to * the front. */ WindowToFront(Window); LockWindow(Window); /* Wait two seconds * before actually * starting the * formatting process. * This little break * will (hopefully!) * allow the user to * abort the * initialization of * precious data media. */ for(i = 0 ; i < 2 ; i++) { ShowInfo("%ld seconds to format %s",2 - i,DriveNode -> VanillaNode . ln_Name); if(HandleInput()) { Node = NULL; break; } Delay(TICKS_PER_SECOND); } /* Format the drive * or don't... */ if(Node) FormatDrive(DriveNode,FALSE); else { UnLockWindow(Window); ShowInfo("Idle"); } } } /* The user hit one of the gadgets * displayed in the panel. */ if(Class == IDCMP_GADGETUP) { UpdateInfo(); /* Start formatting? */ if(Gadget -> GadgetID == GAD_START) FormatDrive(DriveNode,TRUE); /* Select another disk * drive? */ if(Gadget -> GadgetID == GAD_DRIVES) { struct DevNode *SomeNode; i = 0; SomeNode = (struct DevNode *)DevList -> lh_Head; while(SomeNode -> VanillaNode . ln_Succ) { if(i++ != Code) SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; else break; } DriveNode = SomeNode; GT_SetGadgetAttrs(GadgetArray[GAD_USEFFS],Window,NULL, GTCB_Checked, ((struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(SomeNode -> DevNode -> dn_Startup)) -> fssm_Environ)) -> de_DosType == ID_FFS_DISK ? TRUE : FALSE, TAG_DONE); SizeInfo(SomeNode -> DevNode); } /* Toggle the effects * of the FFS gadget. */ if(Gadget -> GadgetID == GAD_USEFFS) SizeInfo(LastNode); } /* The following block handles * the keyboard shortcuts available. * Most important among these * are `S' (= Start/Stop formatting) * and Escape (= terminate the * program. */ if(Class == IDCMP_VANILLAKEY) { if(toupper(Code) == 'S') FormatDrive(DriveNode,TRUE); else { if(Code == '\033') Terminated = TRUE; else { for(i = 0 ; i < (sizeof(Shortcuts) / sizeof(struct Shortcut)) ; i++) { if(Shortcuts[i] . Key == toupper(Code)) { switch(Shortcuts[i] . GadgetType) { case STRING_KIND: ActivateGadget(GadgetArray[Shortcuts[i] . GadgetID],Window,NULL); break; case CHECKBOX_KIND: if(!(GadgetArray[Shortcuts[i] . GadgetID] -> Flags & GFLG_DISABLED)) { GT_SetGadgetAttrs(GadgetArray[Shortcuts[i] . GadgetID],Window,NULL, GTCB_Checked, (GadgetArray[Shortcuts[i] . GadgetID] -> Flags & GFLG_SELECTED) ? FALSE : TRUE, TAG_DONE); UpdateInfo(); if(Shortcuts[i] . GadgetID == GAD_USEFFS) SizeInfo(LastNode); } break; default: break; } break; } } } } } } } } else { UBYTE **Arg; /* Let's come to the Shell interface, * start by allocating the argument vector * table to pass to ReadArgs. */ if(Arg = (UBYTE **)AllocVec(sizeof(UBYTE *) * NUM_ARGS,MEMF_PUBLIC | MEMF_CLEAR)) { struct RDArgs *ArgsPtr; /* Perform command line parsing. */ if(ArgsPtr = ReadArgs(ARG_TEMPLATE,(LONG *)Arg,NULL)) { struct DevNode *SomeNode; /* Let it be known: no GUI this * time! */ FromShell = TRUE; /* Set up the list of legal * filing devices. */ if(DevList = FindDevices()) { /* Try to find the device * we are to format. */ SomeNode = (struct DevNode *)DevList -> lh_Head; while(SomeNode -> VanillaNode . ln_Succ) { if(!stricmp(SomeNode -> VanillaNode . ln_Name,Arg[ARG_DRIVE])) break; else SomeNode = (struct DevNode *)SomeNode -> VanillaNode . ln_Succ; } /* Did we find the device? */ if(SomeNode -> VanillaNode . ln_Succ) { struct MsgPort *Proc; UBYTE TinyBuffer[5]; /* Turn up the driver behind the * data media. */ if(Proc = DeviceProc(DriveNode -> VanillaNode . ln_Name)) { /* Disable the restart validation process. */ if(DoPkt1(Proc,ACTION_INHIBIT,DOSTRUE)) { /* Prompt for <return> */ Printf("Insert disk to be formatted in drive %s and press RETURN",SomeNode -> VanillaNode . ln_Name); Flush(((struct Process *)SysBase -> ThisTask) -> pr_CIS); FGets(((struct Process *)SysBase -> ThisTask) -> pr_COS,TinyBuffer,5); /* Abort the process? */ if(SetSignal(0,0) & SIGBREAKF_CTRL_C) { SetSignal(0,SIGBREAKF_CTRL_C); DoPkt1(Proc,ACTION_INHIBIT,DOSFALSE); Printf("\n*** BREAK: Format\a\n\n"); FreeArgs(ArgsPtr); FreeVec(Arg); CloseAll(RETURN_WARN); } /* Make sure that we will get a * valid disk name ("" expands * to `Empty'). */ if(Arg[ARG_NAME]) DiskName = Arg[ARG_NAME]; else DiskName = ""; /* See if by default FFS is * enabled. */ UseFFS = ((struct DosEnvec *)BADDR(((struct FileSysStartupMsg *)BADDR(SomeNode -> DevNode -> dn_Startup)) -> fssm_Environ)) -> de_DosType == ID_FFS_DISK ? TRUE : FALSE; /* Transform the remaining * arguments into flags. */ if(Arg[ARG_FFS]) UseFFS = TRUE; if(!Arg[ARG_NOICONS]) CreateIcons = TRUE; if(!Arg[ARG_QUICK]) WholeDisk = TRUE; if(!Arg[ARG_NOVERIFY]) Verify = TRUE; if(Arg[ARG_INSTALL]) InstallDisk = TRUE; if(Arg[ARG_EJECT]) EjectDisk = TRUE; /* Turn off the console cursor. */ Printf("\33[0 p\n"); /* Format the drive. */ FormatDrive(SomeNode,FALSE); /* Turn the console cursor back on. */ Printf("\33[ p"); /* Reenable the disk validation process. */ DoPkt1(Proc,ACTION_INHIBIT,DOSFALSE); } } } else { Printf("Format: Cannot format drive %s.\a\n",SomeNode -> VanillaNode . ln_Name); FreeArgs(ArgsPtr); FreeVec(Arg); CloseAll(RETURN_FAIL); } } else { Printf("Format: Out of memory!\a\n"); FreeArgs(ArgsPtr); FreeVec(Arg); CloseAll(RETURN_FAIL); } FreeArgs(ArgsPtr); } else { PrintFault(IoErr(),"Format\a"); FreeVec(Arg); CloseAll(RETURN_FAIL); } FreeVec(Arg); } else { Printf("Format: Out of memory!\a\n"); CloseAll(RETURN_FAIL); } } CloseAll(RETURN_OK); } /* Et c'est tout! */