2 * Format -- disk formatting and file-system creation program
3 * Copyright (C) 1999 Ben Hutchings <womble@zzumbouk.demon.co.uk>
4 * Copyright (C) 2008 Pavel Fedin <sonic_amiga@rambler.ru>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <devices/trackdisk.h>
22 #include <devices/newstyle.h>
24 #include <dos/dosextens.h>
25 #include <dos/filehandler.h>
26 #include <exec/devices.h>
27 #include <exec/errors.h>
29 #include <exec/libraries.h>
30 #include <exec/memory.h>
31 #include <exec/resident.h>
32 #include <graphics/gfxbase.h>
33 #include <intuition/intuition.h>
34 #include <workbench/workbench.h>
38 #include <proto/dos.h>
39 #include <proto/exec.h>
40 #include <proto/icon.h>
41 #include <proto/intuition.h>
46 #ifndef AROS_BSTR_ADDR
47 #define AROS_BSTR_ADDR(x) (char *)BADDR(x) + 1
50 static void WordWrapSz( char * psz
);
51 static BOOL
bTransferCylinder(
52 APTR pBuffer
, ULONG icyl
, UWORD cmd64
, UWORD cmd32
);
54 char szDosDevice
[MAX_FS_NAME_LEN
+2];
55 char * pchDosDeviceColon
;
56 ULLONG ibyStart
, ibyEnd
;
61 static char szVolume
[MAX_FS_NAME_LEN
+2] __attribute__((aligned (4)));
62 static char * pszExecDevice
;
63 static ULONG ExecUnit
, ExecDeviceFlags
;
64 static ULONG BufMemType
;
65 static ULONG fstCurrent
;
67 static ULONG devfCurrent
;
69 static struct FileSysStartupMsg
* pfssm
;
70 static ULLONG cbyTrack
, cbyCylinder
;
71 static struct MsgPort
* pmpDiskIO
;
72 static struct IOStdReq
* piosDisk
;
73 static BOOL bExecDevOpen
;
74 static BOOL bSuspectIDE
= FALSE
;
75 static BOOL bInhibited
;
76 static ULONG
* paulWriteBuffer
, * paulReadBuffer
;
77 static ULONG cbyTransfer
;
80 const char szVersion
[] = "$VER: BHFormat 43.8 (" ADATE
")";
84 int rc
= _WBenchMsg
? rcGuiMain() : rcCliMain();
90 void ReportErrSz( ErrorType ert
, LONG err
, const char * pszMessage
, ... )
92 static const char * apszErrorTypes
[3];
93 apszErrorTypes
[0] = _(MSG_ERRORS_WARNING
);
94 apszErrorTypes
[1] = _(MSG_ERRORS_ERROR
);
95 apszErrorTypes
[2] = _(MSG_ERRORS_FAILURE
);
97 char szSysMessage
[FAULT_MAX
];
99 static char szOutput
[1024];
102 va_start(args
, pszMessage
);
105 (void) Fault( err
? err
: IoErr(),
106 (_WBenchMsg
&& !pszMessage
) ? 0 : "",
107 szSysMessage
, FAULT_MAX
);
109 strcpy( szFormat
, _(MSG_FORMAT
) );
110 strcat( szFormat
, apszErrorTypes
[ert
] );
116 strcat( szFormat
, " - " );
117 strcat( szFormat
, pszMessage
);
119 strcat( szFormat
, szSysMessage
);
120 strcat( szFormat
, "\n" );
121 RawDoVFmtSz( szOutput
, szFormat
, args
);
122 WordWrapSz(szOutput
);
123 (void) FPuts( bpfhStdErr
, szOutput
);
125 else if(IntuitionBase
)
127 struct EasyStruct es
;
129 char * pszBodyFormat
= szFormat
+ strlen(szFormat
) + 1;
132 strcpy( pszBodyFormat
, pszMessage
);
133 strcat( pszBodyFormat
, szSysMessage
);
135 es
.es_StructSize
= sizeof(struct EasyStruct
);
137 es
.es_Title
= szFormat
;
138 es
.es_TextFormat
= "%s";
139 es
.es_GadgetFormat
= (ert
== ertFailure
) ? _(MSG_CANCEL
) : _(MSG_OK
);
140 RawDoVFmtSz( szOutput
, pszBodyFormat
, args
);
141 WordWrapSz(szOutput
);
142 (void) EasyRequest( 0, &es
, 0, (IPTR
)szOutput
);
144 /* else we can't report the error */
148 static void WordWrapSz( char * psz
)
150 char * pszLine
, * pchSpace
, * pchLastSpace
;
152 pchLastSpace
= pszLine
-1;
153 while( (pchSpace
= strchr( pchLastSpace
+1, ' ' )) != 0 )
155 size_t cch
= pchSpace
- pszLine
;
159 if( cch
== 60 || pchLastSpace
< pszLine
)
160 pchLastSpace
= pchSpace
;
162 *pchLastSpace
= '\n';
163 pszLine
= pchLastSpace
+1;
166 pchLastSpace
= pchSpace
;
171 BOOL
bSetSzDosDeviceFromSz( const char * pszDevice
)
173 /* Check the length of the device name - it may be followed by a
174 colon, and possibly some junk which we must ignore */
175 char * pszEnd
= strchr( pszDevice
, ':' );
176 size_t cch
= pszEnd
? (pszEnd
- pszDevice
) : strlen(pszDevice
);
178 if( cch
!= 0 && cch
<= MAX_FS_NAME_LEN
)
180 /* Make a copy, without the colon */
181 strncpy( szDosDevice
, pszDevice
, cch
);
182 pchDosDeviceColon
= &szDosDevice
[cch
]; /* need to put it back later */
183 *pchDosDeviceColon
= 0;
184 *(pchDosDeviceColon
+1) = 0;
188 ReportErrSz( ertError
, ERROR_INVALID_COMPONENT_NAME
, 0 );
193 BOOL
bSetSzVolumeFromSz( const char * pszVolume
)
195 /* Check the length and validity of the volume name */
196 size_t cch
= strlen(pszVolume
);
198 if( cch
!= 0 && cch
<= MAX_FS_NAME_LEN
&& strpbrk( pszVolume
, ":/" ) == 0 )
200 /* Make a copy with a length prefix because v36 Format function
201 incorrectly expects a BSTR */
203 strcpy( &szVolume
[1], pszVolume
);
207 ReportErrSz( ertError
, ERROR_INVALID_COMPONENT_NAME
, 0 );
212 BOOL
bSetFstFromSz( const char * pszFileSysType
)
218 if( *pszFileSysType
== 0 )
224 /* Look for a C-style number as used in Mountlists. */
225 fstCurrent
= strtoul( pszFileSysType
, &pszEnd
, 0 );
232 /* Look for a type in the standard-ish format of text with
233 \-escaped numbers. These numbers normally have only one
234 digit, so it's a bit hard to decide what base they are
235 in. I have specified 8 here because that's what C uses
236 for \-escaped character numbers. */
239 while( (ub
= (unsigned char)*pszFileSysType
++) != 0 )
241 if( ub
== (unsigned char)'\\' )
243 ub
= strtoul( pszFileSysType
, (char **)&pszFileSysType
, 8 );
250 fstCurrent
= (fstCurrent
<< 8) + ub
;
259 ReportErrSz( ertError
, -1, _(MSG_ERROR_INVALID_DOSTYPE
) );
264 BOOL
bSetDevfFromSz( const char * pszDevFlags
)
266 if( *pszDevFlags
== 0 )
272 devfCurrent
= strtoul( pszDevFlags
, (char **)&pszDevFlags
, 0 );
273 if( *pszDevFlags
== 0 )
279 ReportErrSz( ertError
, ERROR_BAD_NUMBER
, 0 );
284 BOOL
bGetDosDevice(struct DosList
*pdlDevice
, ULONG flags
)
286 struct DosList
*pdlList
;
287 struct DosEnvec
* pdenDevice
;
290 flags
= LDF_DEVICES
|LDF_READ
;
291 pdlList
= LockDosList(flags
);
292 D(Printf( "LockDosList( LDF_DEVICES | LDF_READ ) = 0x%08lx\n", (ULONG
)pdlList
));
293 *pchDosDeviceColon
= 0;
294 pdlDevice
= FindDosEntry( pdlList
, szDosDevice
, LDF_DEVICES
);
295 D(Printf("FindDosEntry( 0x%08lx, \"%s\", LDF_DEVICES ) = 0x%08lx\n",
296 (ULONG
)pdlList
, (ULONG
)szDosDevice
, (ULONG
)pdlDevice
));
299 UnLockDosList(flags
);
300 ReportErrSz( ertError
, ERROR_DEVICE_NOT_MOUNTED
, 0 );
305 /* Find startup message and verify file-system settings. Use
306 TypeOfMem to protect against devices that use integer or string
308 if( (pfssm
= (struct FileSysStartupMsg
*)
309 BADDR(pdlDevice
->dol_misc
.dol_handler
.dol_Startup
)) == 0
310 || TypeOfMem(pfssm
) == 0
311 || pfssm
->fssm_Device
== 0
312 || (pdenDevice
= (struct DosEnvec
*)BADDR(pfssm
->fssm_Environ
)) == 0
313 || TypeOfMem(pdenDevice
) == 0
314 || pdenDevice
->de_TableSize
< DE_DOSTYPE
315 /* Check that parameters that should always be 0, are */
316 || pdenDevice
->de_SecOrg
!= 0
317 || pdenDevice
->de_Interleave
!= 0 )
319 UnLockDosList(flags
);
320 ReportErrSz( ertError
, ERROR_OBJECT_WRONG_TYPE
, 0 );
324 /* Get the device name with the original correct case */
325 RawDoFmtSz( szDosDevice
, "%b", pdlDevice
->dol_Name
);
327 /* Unlike most BCPL strings, this one is guaranteed to be null-
329 pszExecDevice
= AROS_BSTR_ADDR(pfssm
->fssm_Device
);
330 ExecUnit
= pfssm
->fssm_Unit
;
331 ExecDeviceFlags
= pfssm
->fssm_Flags
;
332 MaxTransfer
= pdenDevice
->de_MaxTransfer
;
333 BufMemType
= pdenDevice
->de_BufMemType
;
334 LowCyl
= pdenDevice
->de_LowCyl
;
335 HighCyl
= pdenDevice
->de_HighCyl
;
336 DosType
= pdenDevice
->de_DosType
;
338 cbyTrack
= (ULLONG
)pdenDevice
->de_BlocksPerTrack
* (ULLONG
)(pdenDevice
->de_SizeBlock
* sizeof(LONG
));
339 cbyCylinder
= cbyTrack
* pdenDevice
->de_Surfaces
;
341 ibyStart
= pdenDevice
->de_LowCyl
* cbyCylinder
;
342 ibyEnd
= (pdenDevice
->de_HighCyl
+ 1) * cbyCylinder
;
344 #if defined(__mc68000) && !defined(__AROS__)
345 /* If the device has a native Amiga file-system, we can check for
346 various limitations and also apply the various command-line
347 flags that specify which variant to use for the new volume. */
349 if( pdenDevice
->de_DosType
>= 0x444F5300
350 && pdenDevice
->de_DosType
<= 0x444F5305 )
352 const struct Resident
* prt
;
355 /* I'd prefer to do this properly by reading the segment size
356 and going through the segment list, but the fake ROM
357 "segment lists" don't have valid segment sizes set so that
358 would be a bit pointless. Perhaps I should use TypeOfMem
359 to decide whether the segment is in ROM or RAM first? */
361 prt
= (struct Resident
*)((char *)BADDR(
362 pdlDevice
->dol_misc
.dol_handler
.dol_SegList
) + 4);
363 while( prt
->rt_MatchWord
!= RTC_MATCHWORD
364 || prt
->rt_MatchTag
!= prt
)
365 prt
= (struct Resident
*)((UWORD
*)prt
+ 1);
366 verFS
= prt
->rt_Version
;
367 D(Printf( "found RomTag at 0x%08lx; rt_Version = %lu\n",
368 (ULONG
)prt
, (ULONG
)verFS
));
370 /* check that the fs can handle this device correctly */
372 if( ibyEnd
- ibyStart
> 0x100000000ULL
373 && verFS
<= 43 ) /* perhaps v44 will change this? ;-) */
375 UnLockDosList(flags
);
379 _(MSG_ERROR_TOO_LARGE_1
) );
382 if( ibyEnd
> 0x100000000ULL
&& verFS
< 43 )
384 UnLockDosList(flags
);
388 _(MSG_ERROR_TOO_LARGE_2
) );
392 if( ibyEnd
- ibyStart
> 0x80000000ULL
&& verFS
< 40 )
394 UnLockDosList( LDF_DEVICES
| LDF_READ
);
398 _(MSG_ERROR_TOO_LARGE_3
) );
404 UnLockDosList(flags
);
407 /* Certain documentation says MEMF_PUBLIC doesn't matter, and
408 certain progams don't bother setting it by default. They
409 are wrong and should be fixed!
410 Unfortunately MorphOS mounts builtin filesystems without
411 this flag and this can't be changed. So we disable this check
413 if( !(BufMemType
& MEMF_PUBLIC
) )
418 _(MSG_ERROR_TOO_LARGE_4
) );
419 BufMemType
|= MEMF_PUBLIC
;
427 void FreeDosDevice(void)
431 *pchDosDeviceColon
= ':';
432 D(Printf( "Inhibit( \"%s\", DOSFALSE );\n", (ULONG
)szDosDevice
));
433 (void) Inhibit( szDosDevice
, DOSFALSE
);
439 BOOL
bGetExecDevice( BOOL bWillVerify
)
441 *pchDosDeviceColon
= ':';
442 D(Printf( "Inhibit( \"%s\", DOSTRUE );\n", (ULONG
)szDosDevice
));
443 if(!Inhibit( szDosDevice
, DOSTRUE
))
445 /* This is a bit stupid, but compatible with v40 Format */
446 ReportErrSz( ertFailure
, ERROR_OBJECT_WRONG_TYPE
, 0 );
451 if( (pmpDiskIO
= CreateMsgPort()) == 0
452 || (piosDisk
= (struct IOStdReq
*)
453 CreateIORequest( pmpDiskIO
, sizeof(struct IOStdReq
) )) == 0 )
455 D(Printf("pmpDiskIO = 0x%08lX, piosDisk = 0x%08lX\n", pmpDiskIO
, piosDisk
));
456 ReportErrSz( ertFailure
, ERROR_NO_FREE_STORE
, 0 );
461 BYTE derr
= OpenDevice( pszExecDevice
,
463 (struct IORequest
*)piosDisk
,
464 bDevfSet
? devfCurrent
: ExecDeviceFlags
);
468 ertFailure
, -1, _(MSG_ERROR_DEVICE
), (ULONG
)derr
);
476 /* This is an attempt to spot a scsi.device that is really an
477 IDE driver. If we have a card slot (A600/A1200) or AGA
478 (A1200/A4000/A4000T/CD32/clones) then it probably is. If
479 the version number is lower than 40 then it does not limit
480 transfers to 128 blocks as required for correct operation
482 struct GfxBase
* GfxBase
= (struct GfxBase
*)
483 OpenLibrary( "graphics.library", 39 );
484 if( !strcmp( pszExecDevice
, "scsi.device" )
485 && piosDisk
->io_Device
->dd_Library
.lib_Version
< 40
486 && (OpenResource("card.resource")
487 || (GfxBase
&& (GfxBase
->ChipRevBits0
& GFXF_AA_ALICE
)) ))
490 if( MaxTransfer
> 0x10000 )
492 MaxTransfer
= 0x10000;
500 CloseLibrary((struct Library
*)GfxBase
);
504 if( ibyEnd
> 0x100000000ULL
)
506 static struct NSDeviceQueryResult nsdqr
; /* must be in public memory */
508 BOOL bDoes64Bit
= FALSE
;
510 piosDisk
->io_Command
= NSCMD_DEVICEQUERY
;
511 piosDisk
->io_Data
= &nsdqr
;
512 piosDisk
->io_Length
= sizeof(nsdqr
);
513 nsdqr
.DevQueryFormat
= 0;
514 nsdqr
.SizeAvailable
= 0;
516 switch( derr
= DoIO((struct IORequest
*)piosDisk
) )
519 if( piosDisk
->io_Actual
== sizeof(nsdqr
) )
521 if( nsdqr
.DeviceType
== NSDEVTYPE_TRACKDISK
)
523 /* Look for 64-bit trackdisk commands - any one will
524 do, as drivers must implement all or none of them. */
526 for( pcmd
= nsdqr
.SupportedCommands
; *pcmd
!= 0; ++pcmd
)
527 if( *pcmd
== NSCMD_TD_READ64
)
532 /* How odd... it's not trackdisk-like */
533 ReportErrSz( ertError
, ERROR_OBJECT_WRONG_TYPE
, 0 );
546 _(MSG_ERROR_DEVICE_QUERY
),
556 _(MSG_ERROR_64BIT
) );
561 /* We need two buffers - one for writing and one for reading back to
563 D(Printf("Allocating buffers, size %lu bytes\n", cbyCylinder
));
564 if( (paulWriteBuffer
= AllocMem( cbyCylinder
,
567 && (paulReadBuffer
= AllocMem( cbyCylinder
, BufMemType
)) == 0) )
569 ReportErrSz( ertFailure
, ERROR_NO_FREE_STORE
, 0 );
574 /* Fill a buffer with junk, just like the official Format
575 does. Perhaps this is meant to make the verification a
577 ULONG
* pulFill
= paulWriteBuffer
;
578 ULONG
* pulLimit
= (ULONG
*)((char *)paulWriteBuffer
+ cbyCylinder
);
579 while( pulFill
< pulLimit
)
582 for( i
= 0; i
< 16 && pulFill
< pulLimit
; ++i
)
584 ULONG ul
= 0x444F5300 + ((i
>> 2) << 10);
585 for( j
= 0; j
< 256 && pulFill
< pulLimit
; ++j
)
591 /* For most drives, the geometry is totally fake and the drive can
592 never be formatted by the user. The driver will really treat
593 TD_FORMAT the same as CMD_READ. However, for some drives, we
594 will be doing a real format using the real geometry. In that
595 case we *must* write a whole track at a time. So what if
596 MaxTransfer is smaller than one track?
598 * MaxTransfer happens to be useful for working round firmware
599 bugs in some IDE drives which scsi.device versions < 40
600 didn't work around, but that's not its purpose. We've
601 already spotted problematic drivers and we know that they
602 don't really format the disk, so we should apply the limit
605 * As far as I can see, MaxTransfer is really there to limit the
606 time that the I/O bus may be tied up with DMA transfers. If
607 we have to write more than that to format the disk, so be it.
609 Ideally, we want to write whole cylinders at once, since longer
610 transfers are fastest. We do this if the length of a cylinder
611 is less than or equal to MaxTransfer.
612 Otherwise, we write a track each time, unless we have a suspect
613 IDE drive and the length of a track is greater than MaxTransfer
614 - in which case we write at most MaxTransfer each time. */
616 cbyTransfer
= (cbyCylinder
<= MaxTransfer
) ?
618 ((!bSuspectIDE
|| cbyTrack
<= MaxTransfer
) ?
619 cbyTrack
: MaxTransfer
);
625 void FreeExecDevice(void)
629 FreeMem( paulWriteBuffer
, cbyCylinder
);
634 FreeMem( paulReadBuffer
, cbyCylinder
);
639 CloseDevice((struct IORequest
*)piosDisk
);
640 bExecDevOpen
= FALSE
;
644 DeleteIORequest((struct IORequest
*)piosDisk
);
649 DeleteMsgPort(pmpDiskIO
);
655 BOOL
bFormatCylinder( ULONG icyl
)
659 /* put a "BAD\0" marker at the beginning in case format is aborted */
660 /* put normal "DOS\0" marker at the beginning of other cylinders */
662 (icyl
== LowCyl
) ? 0x42414400 : 0x444F5300;
664 if( !bTransferCylinder( paulWriteBuffer
, icyl
,
665 NSCMD_TD_FORMAT64
, TD_FORMAT
) )
668 /* Write out and invalidate the track buffer */
669 piosDisk
->io_Command
= CMD_UPDATE
;
670 derr
= DoIO((struct IORequest
*)piosDisk
);
673 piosDisk
->io_Command
= CMD_CLEAR
;
674 derr
= DoIO((struct IORequest
*)piosDisk
);
679 ReportErrSz( ertFailure
, -1,
680 _(MSG_ERROR_DEVICE_RETURN
),
681 (piosDisk
->io_Command
== CMD_UPDATE
) ?
682 _(MSG_ERROR_FLUSH
) : _(MSG_ERROR_INVALIDATE
),
688 BOOL
bVerifyCylinder( ULONG icyl
)
690 if( !bTransferCylinder( paulReadBuffer
, icyl
,
691 NSCMD_TD_READ64
, CMD_READ
) )
694 if( memcmp( paulWriteBuffer
, paulReadBuffer
, cbyCylinder
) != 0 )
696 ReportErrSz( ertFailure
, -1, _(MSG_ERROR_VERIFY
) );
704 static BOOL
bTransferCylinder(
705 APTR pBuffer
, ULONG icyl
, UWORD cmd64
, UWORD cmd32
)
707 ULLONG ibyOffset
= (ULLONG
)icyl
* (ULLONG
)cbyCylinder
;
708 ULLONG cbyLeft
= cbyCylinder
;
712 ULONG cbyLength
= (cbyTransfer
<= cbyLeft
) ? cbyTransfer
: cbyLeft
;
714 if( ibyOffset
+ cbyLength
>= 0x100000000ULL
)
716 piosDisk
->io_Command
= cmd64
;
717 piosDisk
->io_Actual
= ibyOffset
>> 32;
720 piosDisk
->io_Command
= cmd32
;
722 piosDisk
->io_Offset
= ibyOffset
;
723 piosDisk
->io_Length
= cbyLength
;
724 piosDisk
->io_Data
= pBuffer
;
726 D(Printf( "DoIO() Cmd=%2lu Act=0x%08lx Len=0x%08lx "
727 "Data=0x%08lx Off=0x%08lx\n",
728 piosDisk
->io_Command
,
731 (ULONG
)piosDisk
->io_Data
,
732 piosDisk
->io_Offset
));
734 if( DoIO((struct IORequest
*)piosDisk
) != 0 )
736 const char * pszCommand
= NULL
;
737 switch(piosDisk
->io_Command
)
739 case NSCMD_TD_FORMAT64
:
740 pszCommand
= _(MSG_COMMAND_FORMAT64
); break;
742 pszCommand
= _(MSG_COMMAND_FORMAT
); break;
743 case NSCMD_TD_READ64
:
744 pszCommand
= _(MSG_COMMAND_READ64
); break;
746 pszCommand
= _(MSG_COMMAND_READ
); break;
748 ReportErrSz( ertFailure
, -1,
749 _(MSG_ERROR_DEVICE_RETURN
),
750 pszCommand
, (ULONG
)piosDisk
->io_Error
);
754 ibyOffset
+= cbyLength
;
755 pBuffer
= (char *)pBuffer
+ cbyLength
;
756 cbyLeft
-= cbyLength
;
758 while( cbyLeft
!= 0 );
764 BOOL
bMakeFileSys( BOOL bFFS
, BOOL bOFS
, BOOL bIntl
, BOOL bNoIntl
,
765 BOOL bDirCache
, BOOL bNoDirCache
)
769 fstCurrent
= DosType
;
771 if( fstCurrent
>= 0x444F5300 && fstCurrent
<= 0x444F5305 )
773 /* Adjust the file-system type according to command-line
774 switches or check-boxes (this exactly matches the logic of the
775 official version 40 Format command). */
777 if(bFFS
) fstCurrent
|= 1;
778 if(bOFS
) fstCurrent
&= ~1;
779 if( !(fstCurrent
& 2) )
781 if(bDirCache
) fstCurrent
|= 4;
782 if(bNoDirCache
) fstCurrent
&= ~4;
784 if( !(fstCurrent
& 4) )
786 if(bIntl
) fstCurrent
|= 2;
787 if(bNoIntl
) fstCurrent
&= ~2;
789 } /* if( fstCurrent >= 0x444F5300 && fstCurrent <= 0x444F5305 ) */
794 *pchDosDeviceColon
= ':';
795 D(Printf( "Inhibit( \"%s\", DOSTRUE );\n", (ULONG
)szDosDevice
));
796 if(!Inhibit( szDosDevice
, DOSTRUE
))
798 /* This is a bit stupid, but compatible with v40 Format */
799 ReportErrSz( ertFailure
, ERROR_OBJECT_WRONG_TYPE
, 0 );
805 D(Printf( "Format( \"%s\", \"%s\", 0x%08lx );\n",
806 (ULONG
)szDosDevice
, (ULONG
)(szVolume
+ 1), fstCurrent
));
807 if( !Format( szDosDevice
,
808 (DOSBase
->dl_lib
.lib_Version
== 36) ?
809 (char *)MKBADDR(szVolume
) : szVolume
+ 1,
812 ReportErrSz( ertFailure
, 0, 0 );
820 BOOL
bMakeFiles( BOOL bDiskIcon
)
822 struct Library
* IconBase
;
823 BOOL bSuccess
= FALSE
;
825 /* We have to unlock the DOS list and uninhibit the device before we
826 can write files to the new volume! */
829 if( (IconBase
= OpenLibrary( "icon.library", 36 )) != 0 )
832 *pchDosDeviceColon
= ':';
833 if( (bpflRoot
= Lock( szDosDevice
, SHARED_LOCK
)) != 0 )
835 BPTR bpflOldCD
= CurrentDir(bpflRoot
);
836 BPTR bpflTrash
= CreateDir("Trashcan");
840 struct DiskObject
* pdo
;
842 pdo
= GetDefDiskObject(WBGARBAGE
);
846 if( PutDiskObject( "Trashcan", pdo
) )
853 ReportErrSz( ertFailure
,
855 _(MSG_ERROR_TRASHCAN
),
856 (IPTR
)(szVolume
+ 1) );
859 struct DiskObject
* pdo
;
860 char szDefDiskIcon
[12+MAX_FS_NAME_LEN
+4+1];
862 bSuccess
= FALSE
; /* always assume the worst */
864 /* Try to get the icon that DefIcons would use -
865 first, look for a device-specific one; if that
866 fails look for a file-system-specific one; if that
867 fails then get the standard default disk icon. */
868 *pchDosDeviceColon
= 0;
869 RawDoFmtSz( szDefDiskIcon
, "ENV:sys/def_%sdisk", szDosDevice
);
870 if( (pdo
= GetDiskObject(szDefDiskIcon
)) == 0 )
873 strcpy( szDefDiskIcon
, "ENV:sys/def_ disk" );
874 for( i
= 0; i
< 4; ++i
)
876 char chFSType
= ((char *)&fstCurrent
)[i
];
877 szDefDiskIcon
[12+i
] =
878 (chFSType
< 10) ? ('0' + chFSType
) : chFSType
;
880 if( (pdo
= GetDiskObject(szDefDiskIcon
)) == 0 )
881 pdo
= GetDefDiskObject(WBDISK
);
885 if( PutDiskObject( "Disk", pdo
) )
891 ReportErrSz( ertFailure
,
894 (IPTR
)(szVolume
+ 1) );
897 CurrentDir(bpflOldCD
);
900 CloseLibrary(IconBase
);
902 else /* IconBase == 0 */
903 ReportErrSz( ertFailure
, ERROR_INVALID_RESIDENT_LIBRARY
, 0 );
915 #ifndef HAVE_NEWRAWDOFMT
917 static const UWORD AddChSz
[] = {0x16C0, 0x4E75}; /* move.l d0,(a3)+ : rts */
919 void RawDoFmtSz( char * pszBuffer
, const char * pszFormat
, ... )
921 RawDoFmt( (char *)pszFormat
, (APTR
)(&pszFormat
+1),
922 (void (*)())AddChSz
, pszBuffer
);
925 void RawDoVFmtSz( char * pszBuffer
, const char * pszFormat
, APTR pData
)
927 RawDoFmt( (char *)pszFormat
, pData
, (void (*)())AddChSz
, pszBuffer
);
930 #error CPU is not supported