7 #include <exec/types.h>
8 #include <exec/memory.h>
9 #include <intuition/intuition.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
13 #include <dos/filehandler.h>
18 enum mode mode
= repair
; /* check, repair, unformat or search */
20 struct Window
*CheckRepairWnd
;
27 static BOOL verbose
= FALSE
;
29 static BOOL directscsi
= FALSE
;
30 static BOOL inhibited
= FALSE
;
32 static const char *accessmodes
[] = { "", "Standard", "Direct SCSI", "TD64", "NSD" };
34 void dummyMsg(char *message
)
38 void guiMsg(const char *format
, ...)
41 va_start (parms
, format
);
42 vprintf (format
, parms
);
46 void guiUpdateStats(void)
50 void guiStatus(int level
, char *message
, long maxval
)
52 printf("%s...\n", message
);
55 void guiProgress(int level
, long progress
)
59 int guiAskUser(char *message
, char *okstr
, char *cancelstr
)
63 printf("%s\n", message
);
64 printf("1=<%s> 0=<%s>\n", okstr
, cancelstr
);
73 #define OV_Flags LDF_DEVICES|LDF_VOLUMES
74 static BOOL
OpenVolume(void)
82 /* get device doslist */
83 dl
= LockDosList (OV_Flags
|LDF_READ
);
84 dl
= FindDosEntry(dl
, targetdevice
.name
, OV_Flags
);
86 if (dl
&& dl
->dol_Type
== DLT_VOLUME
)
91 di
= (struct DosInfo
*)BADDR(((struct RootNode
*)DOSBase
->dl_Root
)->rn_Info
);
92 for (dl2
= (struct DosList
*)BADDR(di
->di_DevInfo
);
94 dl2
= (struct DosList
*)BADDR(dl2
->dol_Next
))
96 if (dl2
->dol_Type
== DLT_DEVICE
&& dl
->dol_Task
== dl2
->dol_Task
)
101 dname
= (char *)BADDR(dl
->dol_Name
);
102 strncpy(targetdevice
.name
, dname
+1, *dname
);
103 targetdevice
.name
[*dname
] = 0;
109 if (!dl
|| dl
->dol_Type
== DLT_VOLUME
)
111 UnLockDosList(OV_Flags
|LDF_READ
);
112 guiMsg("DEVICE "); guiMsg(targetdevice
.name
);
113 guiMsg(" not found\nEXITING ...\n\n");
117 UnLockDosList(OV_Flags
|LDF_READ
);
120 targetdevice
.name
[strlen(targetdevice
.name
)] = ':';
121 targetdevice
.name
[strlen(targetdevice
.name
)] = 0;
122 if (!(inhibited
= Inhibit(targetdevice
.name
, DOSTRUE
)))
124 guiMsg("Device could not be inhibited.\nEXITING ...\n\n");
128 /* init volume structure */
129 memset(&volume
, 0, sizeof(volume
));
130 volume
.fssm
= (struct FileSysStartupMsg
*)BADDR(dl
->dol_misc
.dol_handler
.dol_Startup
);
131 volume
.dosenvec
= (struct DosEnvec
*)BADDR(volume
.fssm
->fssm_Environ
);
132 strcpy(volume
.devicename
, targetdevice
.name
);
133 cylsectors
= volume
.dosenvec
->de_Surfaces
* volume
.dosenvec
->de_BlocksPerTrack
;
134 volume
.firstblock
= volume
.dosenvec
->de_LowCyl
* cylsectors
;
135 volume
.lastblock
= (volume
.dosenvec
->de_HighCyl
+ 1) * cylsectors
- 1;
136 b
= volume
.blocksize
= volume
.dosenvec
->de_SizeBlock
<< 2;
139 volume
.blockshift
= i
;
140 volume
.rescluster
= 0;
141 volume
.disksize
= volume
.lastblock
- volume
.firstblock
+ 1;
142 volume
.lastreserved
= volume
.disksize
- 256; /* temp value, calculated later */
144 volume
.status
= guiStatus
;
145 volume
.showmsg
= guiMsg
;
146 volume
.askuser
= guiAskUser
;
147 volume
.progress
= guiProgress
;
148 volume
.updatestats
= guiUpdateStats
;
149 volume
.getblock
= vol_GetBlock
;
150 volume
.writeblock
= vol_WriteBlock
;
151 BCPLtoCString(volume
.execdevice
, (UBYTE
*)BADDR(volume
.fssm
->fssm_Device
));
152 volume
.execunit
= volume
.fssm
->fssm_Unit
;
156 BCPLtoCString(name
, (UBYTE
*)BADDR(volume
.fssm
->fssm_Device
));
157 volume
.showmsg("Device: %s:%lu\n", name
, volume
.fssm
->fssm_Unit
);
158 volume
.showmsg("Firstblock: %lu\n", volume
.firstblock
);
159 volume
.showmsg("Lastblock : %lu\n", volume
.lastblock
);
160 volume
.showmsg("Blocksize : %lu\n", volume
.blocksize
);
164 if (!OpenDiskDevice(volume
.fssm
, &volume
.port
, &volume
.request
, &t
))
166 guiMsg("Device could not be opened.\nEXITING ...\n\n");
170 InitCache(64, 32); /* make this configurable ? */
172 detectbuf
= AllocVec(volume
.blocksize
, MEMF_PUBLIC
);
174 printf("Could not allocated %ld byte buffer.\n", volume
.blocksize
);
177 if (!DetectAccessmode(detectbuf
, directscsi
)) {
178 printf("PFSDoctor failed to access this disk\n"
179 "above the 4G boundary after attempting\n"
180 "TD64, NSD and Direct SCSI\n");
185 printf("Autodetected disk access mode: %s\n", accessmodes
[volume
.accessmode
]);
187 if (volume
.accessmode
== ACCESS_DS
)
189 volume
.getrawblocks
= dev_GetBlocksDS
;
190 volume
.writerawblocks
= dev_WriteBlocksDS
;
194 if (volume
.accessmode
== ACCESS_TD64
)
195 volume
.td64mode
= TRUE
;
196 else if (volume
.accessmode
== ACCESS_NSD
)
197 volume
.nsdmode
= TRUE
;
198 volume
.getrawblocks
= dev_GetBlocks
;
199 volume
.writerawblocks
= dev_WriteBlocks
;
203 volume
.writerawblocks
= dev_WriteBlocksDummy
;
208 static void CloseVolume(void)
213 Inhibit(targetdevice
.name
, FALSE
);
217 if (!(CheckIO((struct IORequest
*)volume
.request
)))
218 AbortIO((struct IORequest
*)volume
.request
);
220 WaitIO((struct IORequest
*)volume
.request
);
221 CloseDevice((struct IORequest
*)volume
.request
);
225 DeleteIORequest(volume
.request
);
228 DeleteMsgPort(volume
.port
);
230 volume
.request
= NULL
;
234 #define TEMPLATE "DEVICE/A,CHECK/S,REPAIR/S,SEARCH/S,UNFORMAT/S,VERBOSE/S,LOGFILE/K,DIRECTSCSI/S"
236 #define ARGS_DEVICE 0
238 #define ARGS_REPAIR 2
239 #define ARGS_SEARCH 3
240 #define ARGS_UNFORMAT 4
241 #define ARGS_VERBOSE 5
242 #define ARGS_LOGFILE 6
243 #define ARGS_DIRECTSCSI 7
246 int main(int argc
, char *argv
[])
248 struct RDArgs
*rdarg
;
249 LONG args
[ARGS_SIZE
] = { 0 };
253 if (!(rdarg
= ReadArgs (TEMPLATE
, args
, NULL
)))
255 PrintFault (ERROR_REQUIRED_ARG_MISSING
, "pfsdoctor");
259 strcpy(targetdevice
.name
, (char*)args
[ARGS_DEVICE
]);
261 if (args
[ARGS_VERBOSE
])
264 if (args
[ARGS_CHECK
]) {
268 if (args
[ARGS_REPAIR
]) {
272 if (args
[ARGS_SEARCH
]) {
276 if (args
[ARGS_UNFORMAT
]) {
281 if (args
[ARGS_DIRECTSCSI
]) {
286 printf("CHECK, REPAIR, SEARCH or UNFORMAT required.\n");
290 printf("Only one command (CHECK, REPAIR, SEARCH, UNFORMAT) parameter allowed.\n");
294 if (args
[ARGS_LOGFILE
]) {
295 logfh
= fopen((char*)args
[ARGS_LOGFILE
], "w");
297 printf("Could not open log file '%s'\n", (char*)args
[ARGS_LOGFILE
]);
303 opties
= SSF_FIX
|SSF_ANALYSE
|SSF_GEN_BMMASK
;
304 else if (mode
== unformat
)
305 opties
= SSF_UNFORMAT
|SSF_FIX
|SSF_ANALYSE
|SSF_GEN_BMMASK
;
307 opties
= SSF_CHECK
|SSF_ANALYSE
|SSF_GEN_BMMASK
;
310 opties
|= SSF_VERBOSE
;
313 StandardScan(opties
);