move additional libs under workbench/
[AROS-Contrib.git] / dopus / DOpus_Disk / format.c
blobb7a7396bed944444e7ec2097c16f58a25eeca09e
1 /*
3 Directory Opus 4
4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 All users of Directory Opus 4 (including versions distributed
22 under the GPL) are entitled to upgrade to the latest version of
23 Directory Opus version 5 at a reduced price. Please see
24 http://www.gpsoft.com.au for more information.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
31 #include "diskop.h"
33 #define FORMATFLAG_FFS 1
34 #define FORMATFLAG_INTERNATIONAL 2
35 #define FORMATFLAG_CACHING 4
36 #define FORMATFLAG_TRASHCAN 8
37 #define FORMATFLAG_VERIFY 16
39 enum {
40 FORMAT_NAME,
41 FORMAT_FFS,
42 FORMAT_INTERNATIONAL,
43 FORMAT_CACHING,
44 FORMAT_TRASHCAN,
45 FORMAT_VERIFY,
46 FORMAT_FORMAT,
47 FORMAT_QUICKFORMAT,
48 FORMAT_CANCEL};
50 struct TagItem
51 format_name_gadget[]={
52 {RO_Type,OBJECT_GADGET},
53 {RO_GadgetType,GADGET_STRING},
54 {RO_GadgetID,FORMAT_NAME},
55 {RO_Left,19},
56 {RO_Width,21},
57 {RO_Height,1},
58 {RO_TextNum,STR_FORMAT_NAME},
59 {RO_TextPos,TEXTPOS_LEFT},
60 {RO_StringLen,31},
61 {TAG_END,0}},
62 format_ffs_gadget[]={
63 {RO_Type,OBJECT_GADGET},
64 {RO_GadgetType,GADGET_CHECK},
65 {RO_GadgetID,FORMAT_FFS},
66 {RO_Left,14},
67 {RO_Top,2},
68 {RO_TextNum,STR_FORMAT_FFS},
69 {RO_TextPos,TEXTPOS_RIGHT},
70 {TAG_END,0}},
71 format_international_gadget[]={
72 {RO_Type,OBJECT_GADGET},
73 {RO_GadgetType,GADGET_CHECK},
74 {RO_GadgetID,FORMAT_INTERNATIONAL},
75 {RO_Left,14},
76 {RO_Top,3},
77 {RO_TopFine,5},
78 {RO_TextNum,STR_FORMAT_INTERNATIONAL},
79 {RO_TextPos,TEXTPOS_RIGHT},
80 {TAG_END,0}},
81 format_caching_gadget[]={
82 {RO_Type,OBJECT_GADGET},
83 {RO_GadgetType,GADGET_CHECK},
84 {RO_GadgetID,FORMAT_CACHING},
85 {RO_Left,14},
86 {RO_Top,4},
87 {RO_TopFine,10},
88 {RO_TextNum,STR_FORMAT_CACHING},
89 {RO_TextPos,TEXTPOS_RIGHT},
90 {TAG_END,0}},
91 format_trashcan_gadget[]={
92 {RO_Type,OBJECT_GADGET},
93 {RO_GadgetType,GADGET_CHECK},
94 {RO_GadgetID,FORMAT_TRASHCAN},
95 {RO_Left,14},
96 {RO_Top,5},
97 {RO_TopFine,15},
98 {RO_TextNum,STR_FORMAT_TRASHCAN},
99 {RO_TextPos,TEXTPOS_RIGHT},
100 {TAG_END,0}},
101 format_verify_gadget[]={
102 {RO_Type,OBJECT_GADGET},
103 {RO_GadgetType,GADGET_CHECK},
104 {RO_GadgetID,FORMAT_VERIFY},
105 {RO_Left,14},
106 {RO_Top,6},
107 {RO_TopFine,20},
108 {RO_TextNum,STR_FORMAT_VERIFY},
109 {RO_TextPos,TEXTPOS_RIGHT},
110 {RO_BoolOn,TRUE},
111 {TAG_END,0}},
112 format_format_gadget[]={
113 {RO_Type,OBJECT_GADGET},
114 {RO_GadgetType,GADGET_BOOLEAN},
115 {RO_GadgetID,FORMAT_FORMAT},
116 {RO_Top,8},
117 {RO_TopFine,37},
118 {RO_Width,13},
119 {RO_Height,1},
120 {RO_HeightFine,4},
121 {RO_TextNum,STR_FORMAT_FORMAT},
122 {RO_TextPos,TEXTPOS_CENTER},
123 {RO_HighRecess,TRUE},
124 {TAG_END,0}},
125 format_quickformat_gadget[]={
126 {RO_Type,OBJECT_GADGET},
127 {RO_GadgetType,GADGET_BOOLEAN},
128 {RO_GadgetID,FORMAT_QUICKFORMAT},
129 {RO_Left,14},
130 {RO_Top,8},
131 {RO_TopFine,37},
132 {RO_Width,13},
133 {RO_Height,1},
134 {RO_HeightFine,4},
135 {RO_TextNum,STR_FORMAT_QUICKFORMAT},
136 {RO_TextPos,TEXTPOS_CENTER},
137 {RO_HighRecess,TRUE},
138 {TAG_END,0}},
139 format_cancel_gadget[]={
140 {RO_Type,OBJECT_GADGET},
141 {RO_GadgetType,GADGET_BOOLEAN},
142 {RO_GadgetID,FORMAT_CANCEL},
143 {RO_Left,28},
144 {RO_Top,8},
145 {RO_TopFine,37},
146 {RO_Width,13},
147 {RO_Height,1},
148 {RO_HeightFine,4},
149 {RO_TextNum,STR_FORMAT_EXIT},
150 {RO_TextPos,TEXTPOS_CENTER},
151 {RO_HighRecess,TRUE},
152 {TAG_END,0}},
154 format_device_list[]={
155 {RO_Type,OBJECT_LISTVIEW},
156 {RO_ListViewID,0},
157 {RO_LeftFine,2},
158 {RO_Width,10},
159 {RO_Height,6},
160 {RO_HeightFine,30},
161 {RO_HighRecess,TRUE},
162 {TAG_END,0}},
164 format_info_box[]={
165 {RO_Type,OBJECT_BORDER},
166 {RO_BorderType,BORDER_RECESSED},
167 {RO_LeftFine,2},
168 {RO_Top,7},
169 {RO_TopFine,28},
170 {RO_Width,41},
171 {RO_WidthFine,-4},
172 {RO_Height,1},
173 {RO_HeightFine,4},
174 {TAG_END,0}},
176 *format_gadgets[]={
177 format_name_gadget,
178 format_ffs_gadget,
179 format_international_gadget,
180 format_caching_gadget,
181 format_trashcan_gadget,
182 format_verify_gadget,
183 format_format_gadget,
184 format_quickformat_gadget,
185 format_cancel_gadget,
186 NULL};
188 void diskop_format(vis,portname,argc,argv)
189 struct VisInfo *vis;
190 char *portname;
191 int argc;
192 char *argv[];
194 struct RequesterBase formatreq;
195 struct Window *window;
196 struct IntuiMessage *msg;
197 Object_Border *infobox;
198 struct DOpusListView *devicelist,*view;
199 struct Gadget *gadlist,*gad,*gad_international=NULL,*gad_caching=NULL;
200 ULONG class,mask,flags;
201 UWORD code,gadgetid;
202 APTR iaddress;
203 struct StringExtend stringex;
204 char *diskname;
205 int a,b,gadcount=0,ignorechange=0;
206 int start=-1,quick=0,startflags=FORMATFLAG_TRASHCAN;
208 formatreq.rb_width=41;
209 formatreq.rb_height=9;
210 formatreq.rb_widthfine=16;
211 formatreq.rb_heightfine=54;
212 formatreq.rb_leftoffset=8;
213 formatreq.rb_topoffset=8;
214 formatreq.rb_flags=0;
216 fill_out_req(&formatreq,vis);
218 formatreq.rb_privateflags=0;
219 formatreq.rb_screenname=NULL;
221 if (formatreq.rb_screen && !(vis->vi_flags&VISF_BORDERS)) {
222 formatreq.rb_flags|=RBF_STRINGS;
223 formatreq.rb_title=NULL;
225 else {
226 formatreq.rb_flags|=RBF_BORDERS|RBF_CLOSEGAD|RBF_STRINGS;
227 formatreq.rb_title=string_table[STR_FORMAT_FORMAT];
230 formatreq.rb_extend=&stringex;
231 formatreq.rb_idcmpflags=0;
232 formatreq.rb_string_table=string_table;
234 for (a=0;a<2;a++) {
235 stringex.Pens[a]=vis->vi_stringcol[a];
236 stringex.ActivePens[a]=vis->vi_activestringcol[a];
238 stringex.InitialModes=0;
239 stringex.EditHook=NULL;
240 stringex.WorkBuffer=NULL;
241 for (a=0;a<4;a++) stringex.Reserved[a]=0;
243 if (SysBase->LibNode.lib_Version<39) mask=12;
244 else mask=0;
246 if (!(window=OpenRequester(&formatreq)) ||
247 !(gadlist=addreqgadgets(&formatreq,format_gadgets,mask,&gadcount)) ||
248 !(infobox=(Object_Border *)
249 AddRequesterObject(&formatreq,format_info_box)) ||
250 !(devicelist=(struct DOpusListView *)
251 AddRequesterObject(&formatreq,format_device_list)) ||
252 !(devicelist->items=get_device_list(&formatreq.rb_memory,NULL))) {
253 CloseRequester(&formatreq);
254 return;
257 fix_listview(&formatreq,devicelist);
258 select_device(devicelist,NULL);
260 diskname=((struct StringInfo *)gadlist->SpecialInfo)->Buffer;
261 strcpy(diskname,string_table[STR_FORMAT_EMPTY]);
263 get_env("format",gadlist,gadcount,devicelist);
265 flags=0;
266 gad=gadlist;
267 for (a=0;a<gadcount;a++) {
268 if (gad->Activation&GACT_TOGGLESELECT)
269 if (gad->Flags&GFLG_SELECTED) flags|=1<<(gad->GadgetID-1);
270 gad->Flags&=~GFLG_DISABLED;
271 gad=gad->NextGadget;
274 if (SysBase->LibNode.lib_Version>38) {
275 gad_international=gadlist->NextGadget->NextGadget;
276 gad_caching=gad_international->NextGadget;
279 for (a=0;a<argc;a++) {
280 if (LStrCmpI(argv[a],"quick")==0) quick=1;
281 else if (LStrCmpI(argv[a],"ffs")==0) startflags|=FORMATFLAG_FFS;
282 else if (LStrCmpI(argv[a],"cache")==0) startflags|=FORMATFLAG_CACHING;
283 else if (LStrnCmpI(argv[a],"inter",5)==0) startflags|=FORMATFLAG_INTERNATIONAL;
284 else if (LStrCmpI(argv[a],"noicons")==0) startflags&=~FORMATFLAG_TRASHCAN;
285 else if (LStrCmpI(argv[a],"verify")==0) startflags|=FORMATFLAG_VERIFY;
286 else {
287 if (start==-1) {
288 for (b=0;devicelist->items[b];b++) {
289 if (LStrCmpI(argv[a],devicelist->items[b])==0) {
290 start=b;
291 devicelist->itemselected=b;
292 break;
296 else LStrnCpy(diskname,argv[a],30);
300 if (start>-1) {
301 gad=gadlist;
302 for (a=0;a<gadcount;a++) {
303 if (startflags&(1<<(gad->GadgetID-1))) gad->Flags|=GFLG_SELECTED;
304 else gad->Flags&=~GFLG_SELECTED;
305 gad=gad->NextGadget;
309 RefreshRequesterObject(&formatreq,NULL);
310 RefreshGList(gadlist,window,NULL,gadcount);
312 if (flags&FORMATFLAG_CACHING && gad_international) {
313 flags|=FORMATFLAG_INTERNATIONAL;
314 gad_international->Flags|=GFLG_SELECTED;
315 RefreshGList(gad_international,window,NULL,1);
316 DisableGadget(gad_international,window->RPort,0,0);
319 if (!(AddListView(devicelist,1))) {
320 CloseRequester(&formatreq);
321 return;
323 show_sel_item(devicelist);
324 show_device_info(&formatreq,infobox,devicelist->items[devicelist->itemselected]);
326 if (start>-1) {
327 if (do_format(&formatreq,
328 infobox,
329 devicelist->items[start],
330 diskname,
331 startflags,
332 quick))
333 dopus_message(DOPUSMSG_UPDATEDRIVE,(APTR)devicelist->items[start],portname);
334 RemoveListView(devicelist,1);
335 CloseRequester(&formatreq);
336 return;
339 FOREVER {
340 while (msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
341 if ((view=(struct DOpusListView *)ListViewIDCMP(devicelist,msg))==
342 (struct DOpusListView *)-1) {
343 class=msg->Class; code=msg->Code;
344 iaddress=msg->IAddress;
345 ReplyMsg((struct Message *)msg);
347 switch (class) {
348 case IDCMP_DISKINSERTED:
349 case IDCMP_DISKREMOVED:
350 if (ignorechange) ignorechange=0;
351 else {
352 show_device_info(&formatreq,
353 infobox,
354 devicelist->items[devicelist->itemselected]);
356 break;
358 case IDCMP_VANILLAKEY:
359 a=0;
360 code=ToUpper(code);
361 switch (code) {
362 case 'N':
363 ActivateStrGad(gadlist,window);
364 break;
365 case 'F':
366 a=1;
367 flags^=FORMATFLAG_FFS;
368 break;
369 case 'I':
370 if (SysBase->LibNode.lib_Version>38) {
371 a=2;
372 flags^=FORMATFLAG_INTERNATIONAL;
374 break;
375 case 'D':
376 if (SysBase->LibNode.lib_Version>38) {
377 a=3;
378 flags^=FORMATFLAG_CACHING;
380 break;
381 case 'P':
382 if (SysBase->LibNode.lib_Version>38) a=4;
383 else a=2;
384 flags^=FORMATFLAG_TRASHCAN;
385 break;
386 case 'V':
387 if (SysBase->LibNode.lib_Version>38) a=5;
388 else a=3;
389 flags^=FORMATFLAG_VERIFY;
390 break;
392 case 0x1b:
393 set_env("format",gadlist,gadcount,devicelist);
394 RemoveListView(devicelist,1);
395 CloseRequester(&formatreq);
396 return;
398 if (a) {
399 gad=gadlist;
400 while (a-- && gad->NextGadget) gad=gad->NextGadget;
401 gad->Flags^=GFLG_SELECTED;
402 RefreshGList(gad,window,NULL,1);
403 if (gad==gad_international) {
404 gad_caching->Flags&=~GFLG_SELECTED;
405 RefreshGList(gad_caching,window,NULL,1);
406 flags&=~FORMATFLAG_CACHING;
408 else if (gad==gad_caching) {
409 gad_international->Flags&=~GFLG_SELECTED;
410 RefreshGList(gad_international,window,NULL,1);
411 flags&=~FORMATFLAG_INTERNATIONAL;
414 break;
416 case IDCMP_GADGETDOWN:
417 case IDCMP_GADGETUP:
418 gadgetid=((struct Gadget *)iaddress)->GadgetID;
419 case IDCMP_CLOSEWINDOW:
420 if (class==IDCMP_CLOSEWINDOW) gadgetid=FORMAT_CANCEL;
422 switch (gadgetid) {
423 case FORMAT_FFS:
424 flags^=FORMATFLAG_FFS;
425 break;
427 case FORMAT_INTERNATIONAL:
428 flags^=FORMATFLAG_INTERNATIONAL;
429 flags&=~FORMATFLAG_CACHING;
430 gad_caching->Flags&=~GFLG_SELECTED;
431 RefreshGList(gad_caching,window,NULL,1);
432 break;
434 case FORMAT_CACHING:
435 flags^=FORMATFLAG_CACHING;
436 if (flags&FORMATFLAG_CACHING) {
437 flags|=FORMATFLAG_INTERNATIONAL;
438 gad_international->Flags|=GFLG_SELECTED;
439 RefreshGList(gad_international,window,NULL,1);
440 DisableGadget(gad_international,window->RPort,0,0);
442 else EnableGadget(gad_international,window->RPort,0,0);
443 break;
445 case FORMAT_TRASHCAN:
446 flags^=FORMATFLAG_TRASHCAN;
447 break;
449 case FORMAT_VERIFY:
450 flags^=FORMATFLAG_VERIFY;
451 break;
453 case FORMAT_CANCEL:
454 set_env("format",gadlist,gadcount,devicelist);
455 RemoveListView(devicelist,1);
456 CloseRequester(&formatreq);
457 return;
459 case FORMAT_FORMAT:
460 case FORMAT_QUICKFORMAT:
461 if (do_format(&formatreq,
462 infobox,
463 devicelist->items[devicelist->itemselected],
464 diskname,
465 flags,
466 (gadgetid==FORMAT_QUICKFORMAT))) {
467 ignorechange=1;
468 dopus_message(DOPUSMSG_UPDATEDRIVE,
469 (APTR)devicelist->items[devicelist->itemselected],
470 portname);
472 break;
474 break;
477 else if (view) show_device_info(&formatreq,infobox,view->items[view->itemselected]);
479 Wait(1<<window->UserPort->mp_SigBit);
483 void show_device_info(reqbase,border,name)
484 struct RequesterBase *reqbase;
485 Object_Border *border;
486 char *name;
488 struct DeviceNode *devnode;
489 struct DosEnvec *dosenvec;
490 int tracks,tracksize,size;
491 char infobuf[60],sizebuf[20];
493 border_text(reqbase,border,NULL);
495 if (!name || !(devnode=find_device(name))) return;
497 dosenvec=(struct DosEnvec *)
498 BADDR(((struct FileSysStartupMsg *)BADDR(devnode->dn_Startup))->fssm_Environ);
500 tracks=dosenvec->de_HighCyl-dosenvec->de_LowCyl+1;
501 tracksize=(dosenvec->de_BlocksPerTrack*dosenvec->de_Surfaces)*(dosenvec->de_SizeBlock*4);
502 size=tracks*tracksize;
504 getsizestring(sizebuf,size);
505 lsprintf(infobuf,string_table[STR_FORMAT_INFODISPLAY],tracks,tracksize,sizebuf);
507 border_text(reqbase,border,infobuf);
510 void getsizestring(buf,a)
511 char *buf;
512 ULONG a;
514 a/=1024;
515 if (a>1073741824) lsprintf(buf,"HUGE");
516 else if (a>1048576) {
517 getfloatstr((double)((double)a/1048576),buf);
518 LStrCat(buf,"G");
520 else if (a>1024) {
521 getfloatstr((double)((double)a/1024),buf);
522 LStrCat(buf,"M");
524 else lsprintf(buf,"%ldK",a);
527 void getfloatstr(f,buf)
528 double f;
529 char *buf;
531 int a,b,c,d;
532 char buf1[20];
534 a=(int)f; f-=a;
535 b=(int)(f*100);
536 c=(b/10)*10; d=b-c;
537 if (d>4) c+=10;
538 if (c==100) {
539 c=0; ++a;
541 lsprintf(buf1,"%ld",c); buf1[1]=0;
542 lsprintf(buf,"%ld.%s",a,buf1);
545 do_format(reqbase,border,device,name,flags,quick)
546 struct RequesterBase *reqbase;
547 Object_Border *border;
548 char *device,*name;
549 ULONG flags;
550 char quick;
552 ULONG dostype;
553 struct DeviceHandle handle;
554 int suc=1,txt=STR_FAILED_ERROR;
555 struct Requester busyreq;
557 if (flags&FORMATFLAG_INTERNATIONAL) {
558 if (flags&FORMATFLAG_FFS) dostype=ID_INTER_FFS_DISK;
559 else dostype=ID_INTER_DOS_DISK;
561 else if (flags&FORMATFLAG_CACHING) {
562 if (flags&FORMATFLAG_FFS) dostype=ID_FASTDIR_FFS_DISK;
563 else dostype=ID_FASTDIR_DOS_DISK;
565 else if (flags&FORMATFLAG_FFS) dostype=ID_FFS_DISK;
566 else dostype=ID_DOS_DISK;
568 if (!(open_device(device,&handle))) txt=STR_NODEVICE_ERROR;
569 else {
570 InitRequester(&busyreq);
571 busyreq.Flags=NOISYREQ;
572 Request(&busyreq,reqbase->rb_window);
573 SetBusyPointer(reqbase->rb_window);
575 border_text(reqbase,border,string_table[STR_CHECKING_DESTINATION]);
577 if (check_disk(reqbase,handle.device_req,device,1)) {
578 if (check_blank_disk(reqbase,device,string_table[STR_FORMAT_FORMAT])) {
580 suc=0;
582 inhibit_drive(device,DOSTRUE);
583 drive_motor(handle.device_req,1);
585 if (!quick) {
586 suc=do_raw_format(reqbase,border,
587 handle.device_req,
588 (handle.dosenvec->de_SizeBlock<<2)*
589 handle.dosenvec->de_Surfaces*handle.dosenvec->de_BlocksPerTrack,
590 handle.dosenvec->de_LowCyl,
591 handle.dosenvec->de_HighCyl-handle.dosenvec->de_LowCyl+1,
592 handle.dosenvec->de_BufMemType,
593 flags);
596 if (!suc) {
597 border_text(reqbase,border,string_table[STR_FORMAT_INITIALISING]);
599 if (DOSBase->dl_lib.lib_Version>36) {
600 if (Format(device,name,dostype)) suc=0;
601 else suc=ERROR_FAILED;
603 else {
604 suc=do_initialise(handle.device_req,name,dostype,
605 handle.dosenvec->de_LowCyl*
606 handle.dosenvec->de_BlocksPerTrack*
607 handle.dosenvec->de_Surfaces,
608 (handle.dosenvec->de_HighCyl-handle.dosenvec->de_LowCyl+1)*
609 handle.dosenvec->de_BlocksPerTrack*handle.dosenvec->de_Surfaces,
610 handle.dosenvec->de_Reserved,
611 handle.dosenvec->de_BufMemType,
612 flags);
616 drive_motor(handle.device_req,0);
617 inhibit_drive(device,FALSE);
619 switch (suc) {
620 case 0:
621 if (flags&FORMATFLAG_TRASHCAN) {
622 if (SysBase->LibNode.lib_Version<36) Delay(150);
623 write_trashcan(reqbase,border,device);
625 txt=STR_SUCCESS;
626 break;
627 case ERROR_FAILED: txt=STR_FAILED_ERROR; break;
628 case ERROR_MEMORY: txt=STR_MEMORY_ERROR; break;
629 case ERROR_BITMAP: txt=STR_BITMAP_ERROR; break;
630 case ERROR_ABORTED: txt=STR_ABORTED; break;
631 case ERROR_VERIFY: txt=-1; break;
632 default: txt=STR_DEVICE_ERROR; break;
635 else txt=STR_ABORTED;
637 else txt=STR_ABORTED;
639 EndRequest(&busyreq,reqbase->rb_window);
640 ClearPointer(reqbase->rb_window);
643 close_device(&handle);
644 if (txt>-1) border_text(reqbase,border,string_table[txt]);
645 return((txt==STR_SUCCESS));
648 do_initialise(device_req,name,dostype,firstblock,numblocks,reserved,memtype,flags)
649 struct IOExtTD *device_req;
650 char *name;
651 ULONG dostype;
652 ULONG firstblock,numblocks,reserved;
653 ULONG memtype;
654 ULONG flags;
656 ULONG *bitmap,bitmapsize;
657 char *buffer;
658 struct BitmapBlock *bitmapblock;
659 struct BitmapExtension *bitmapextension;
660 struct RootDirectory *rootdirectory;
661 struct DOpusRemember *key=NULL;
662 LONG error,a;
663 LONG bitmapcount,bitmapblocks;
664 LONG count,root;
665 LONG extensioncount,extensionblocks=0;
667 bitmapsize=(numblocks-reserved+31)/32;
669 if (!(buffer=LAllocRemember(&key,TD_SECTOR,memtype|MEMF_PUBLIC|MEMF_CLEAR)))
670 return(ERROR_MEMORY);
672 *(ULONG *)buffer=dostype;
674 for (a=0;a<2;a++) {
675 if (error=do_writeblock(device_req,buffer,firstblock+a)) {
676 LFreeRemember(&key);
677 return(error);
679 *(ULONG *)buffer=0;
682 if (!(bitmap=(ULONG *)LAllocRemember(&key,sizeof(ULONG)*bitmapsize,MEMF_PUBLIC))) {
683 LFreeRemember(&key);
684 return(ERROR_MEMORY);
687 for (a=0;a<bitmapsize;a++) bitmap[a]=~0;
689 count=bitmapblocks=(bitmapsize+126)/127;
691 if (count>25) {
692 if (!(flags&FORMATFLAG_FFS)) {
693 LFreeRemember(&key);
694 return(ERROR_BITMAP);
696 count-=25;
698 do {
699 ++extensionblocks;
701 if (count>127) count-=127;
702 else count=0;
704 while (count);
707 root=numblocks>>1;
708 rootdirectory=(struct RootDirectory *)buffer;
709 for (a=0;a<TD_SECTOR;a++) buffer[a]=0;
711 rootdirectory->PrimaryType=2;
712 rootdirectory->HashTableSize=128-56;
713 rootdirectory->BitmapFlag=DOSTRUE;
714 DateStamp(&rootdirectory->LastRootChange);
716 if ((a=strlen(name))>31) a=31;
718 rootdirectory->DiskName[0]=a;
719 CopyMem(name,&rootdirectory->DiskName[1],a);
721 DateStamp(&rootdirectory->LastDiskChange);
722 DateStamp(&rootdirectory->CreationDate);
724 rootdirectory->SecondaryType=1;
726 for (a=0;a<bitmapblocks;a++) {
727 if (a==25) break;
728 rootdirectory->BitmapPointers[a]=root+firstblock+a+1;
731 if (bitmapblocks>25) rootdirectory->BitmapExtension=root+firstblock+26;
732 rootdirectory->Checksum=-do_checksum((ULONG *)rootdirectory);
734 if (error=do_writeblock(device_req,rootdirectory,root+firstblock)) {
735 LFreeRemember(&key);
736 return(error);
739 for (a=root-reserved;a<root-reserved+bitmapblocks+extensionblocks+1;a++)
740 bitmap[a/32]&=BitTable[a%32];
742 bitmapblock=(struct BitmapBlock *)buffer;
744 for (a=0;a<bitmapblocks;a++) {
745 CopyMem(&bitmap[a*127],&bitmapblock->Bitmap[0],sizeof(ULONG)*127);
746 bitmapblock->Checksum=0;
747 bitmapblock->Checksum=-do_checksum((ULONG *)bitmapblock);
748 if (error=do_writeblock(device_req,bitmapblock,root+firstblock+a+1)) {
749 LFreeRemember(&key);
750 return(error);
754 if (extensionblocks) {
755 bitmapextension=(struct BitmapExtension *)buffer;
757 bitmapcount=root+firstblock+1;
758 extensioncount=bitmapcount+bitmapblocks;
759 bitmapblocks-=25;
761 while (bitmapblocks) {
762 for (a=0;a<TD_SECTOR;a++) buffer[a]=0;
763 for (a=0;a<(bitmapblocks<127?bitmapblocks:127);a++)
764 bitmapextension->BitmapPointers[a]=bitmapcount++;
765 if (bitmapblocks>127) bitmapblocks-=127;
766 else bitmapblocks=0;
768 if (bitmapblocks) bitmapextension->BitmapExtension=extensioncount+1;
769 if (error=do_writeblock(device_req,bitmapextension,extensioncount++)) {
770 LFreeRemember(&key);
771 return(error);
776 LFreeRemember(&key);
777 return(0);
780 do_raw_format(reqbase,border,device_req,tracksize,lowtrack,numtracks,memtype,flags)
781 struct RequesterBase *reqbase;
782 Object_Border *border;
783 struct IOExtTD *device_req;
784 ULONG tracksize,lowtrack,numtracks;
785 ULONG memtype;
786 ULONG flags;
788 ULONG *trackbuffer,*verifybuffer;
789 struct DOpusRemember *key=NULL;
790 ULONG offset;
791 int track,a,cmpsize,ret;
792 char infobuf[80];
794 if (!(trackbuffer=(ULONG *)LAllocRemember(&key,tracksize,memtype|MEMF_CLEAR)))
795 return(ERROR_MEMORY);
796 if (flags&FORMATFLAG_VERIFY) {
797 verifybuffer=(ULONG *)LAllocRemember(&key,tracksize,memtype);
798 cmpsize=tracksize>>2;
800 else verifybuffer=NULL;
802 offset=lowtrack*tracksize;
804 for (track=0;track<numtracks;track++) {
805 lsprintf(infobuf,string_table[STR_FORMAT_FORMATTING],track,numtracks-track-1);
806 border_text(reqbase,border,infobuf);
808 FOREVER {
809 if (check_abort(reqbase->rb_window)) {
810 LFreeRemember(&key);
811 return(ERROR_ABORTED);
814 device_req->iotd_Req.io_Command=TD_FORMAT;
815 device_req->iotd_Req.io_Data=(APTR)trackbuffer;
816 device_req->iotd_Req.io_Offset=offset;
817 device_req->iotd_Req.io_Length=tracksize;
819 if (!(DoIO((struct IORequest *)device_req))) {
820 if (!verifybuffer) break;
821 device_req->iotd_Req.io_Command=CMD_UPDATE;
822 if (!(DoIO((struct IORequest *)device_req))) break;
825 lsprintf(infobuf,string_table[STR_FORMAT_FORMATERROR],track);
826 border_text(reqbase,border,infobuf);
827 if (!(check_error(reqbase,infobuf,STR_RETRY))) {
828 LFreeRemember(&key);
829 return(ERROR_FAILED);
833 if (verifybuffer) {
834 lsprintf(infobuf,string_table[STR_FORMAT_VERIFYING],track,numtracks-track-1);
835 border_text(reqbase,border,infobuf);
837 FOREVER {
838 if (check_abort(reqbase->rb_window)) {
839 LFreeRemember(&key);
840 return(ERROR_ABORTED);
843 device_req->iotd_Req.io_Command=CMD_READ;
844 device_req->iotd_Req.io_Data=(APTR)verifybuffer;
845 device_req->iotd_Req.io_Offset=offset;
846 device_req->iotd_Req.io_Length=tracksize;
848 if (!(DoIO((struct IORequest *)device_req))) {
849 for (a=0;a<cmpsize;a++) {
850 if (verifybuffer[a]!=0) break;
852 if (a==cmpsize) break;
853 lsprintf(infobuf,string_table[STR_FORMAT_VERIFYERROR],track);
854 ret=ERROR_VERIFY;
856 else {
857 lsprintf(infobuf,string_table[STR_FORMAT_FORMATERROR],track);
858 ret=ERROR_FAILED;
861 border_text(reqbase,border,infobuf);
862 if (!(check_error(reqbase,infobuf,STR_RETRY))) {
863 LFreeRemember(&key);
864 return(ret);
869 offset+=tracksize;
871 LFreeRemember(&key);
872 return(0);
875 void write_trashcan(reqbase,border,device)
876 struct RequesterBase *reqbase;
877 Object_Border *border;
878 char *device;
880 struct DiskObject *trashcan;
881 BPTR lock;
882 char name[80];
884 if (!IconBase) return;
886 border_text(reqbase,border,string_table[STR_FORMAT_MAKINGTRASHCAN]);
888 lsprintf(name,"%sTrashcan",device);
889 if (!(lock=CreateDir(name))) return;
890 UnLock(lock);
892 if (IconBase->lib_Version>36 &&
893 (trashcan=GetDefDiskObject(WBGARBAGE))) {
894 PutDiskObject(name,trashcan);
895 FreeDiskObject(trashcan);
897 else PutDiskObject(name,&trashcanicon_icon);