Use more appropriate types for pt_regs struct, e.g. 16-bit types for 16-bit
[cake.git] / rom / dos / errorreport.c
blob101d0ebf4a2a80ffd034cc9171e2564f2120e5d3
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include "dos_intern.h"
10 #include <dos/dos.h>
11 #include <dos/dosextens.h>
12 #include <intuition/intuition.h>
13 #include <exec/ports.h>
15 #include <aros/debug.h>
17 /*****************************************************************************
19 NAME */
20 #include <proto/dos.h>
22 AROS_LH4(BOOL, ErrorReport,
24 /* SYNOPSIS */
25 AROS_LHA(LONG , code , D1),
26 AROS_LHA(LONG , type , D2),
27 AROS_LHA(IPTR , arg1 , D3),
28 AROS_LHA(struct MsgPort *, device, D4),
30 /* LOCATION */
31 struct DosLibrary *, DOSBase, 80, Dos)
33 /* FUNCTION
34 Displays a requester with Retry/Cancel buttons for an error.
35 IoErr() is set to "code".
37 INPUTS
39 code -- The error to put up the requester for
40 type -- Type of request
42 REPORT_LOCK -- arg1 is a lock (BPTR).
43 REPORT_FH -- arg1 is a filehandle (BPTR).
44 REPORT_VOLUME -- arg1 is a volumenode (C pointer).
45 REPORT_INSERT -- arg1 is the string for the volumename
47 arg1 -- Argument according to type (see above)
48 device -- Optional handler task address (obsolete!)
50 RESULT
51 DOSFALSE - user has selected "Retry"
52 DOSTRUE - user has selected "Cancel" or code wasn't understood or
53 pr_WindowPtr is -1 or if an attempt to open the requester fails.
55 NOTES
57 Locks and filehandles are the same in AROS so there is redundancy in
58 the parameters. Furthermore, the 'device' argument is not cared about
59 as AROS doesn't build filesystems with handlers.
61 EXAMPLE
63 BUGS
65 SEE ALSO
67 INTERNALS
69 *****************************************************************************/
71 AROS_LIBFUNC_INIT
73 struct Process *me = (struct Process *) FindTask(NULL);
74 STRPTR format;
75 BOOL want_volume = FALSE;
76 BOOL want_device = FALSE;
77 STRPTR volname = NULL;
78 STRPTR devname = NULL;
79 struct DeviceList *dl = NULL;
80 struct Device *handler = NULL;
81 struct Unit *unit = NULL;
82 char buf[128];
83 struct DevProc *dvp;
84 struct DosList *dol;
85 APTR args[2];
86 ULONG idcmp = 0;
87 LONG err;
88 LONG res;
90 /* do nothing if errors are disabled */
91 if (me->pr_WindowPtr == (APTR) -1) {
92 SetIoErr(code);
93 return DOSTRUE;
96 /* first setup the error format and work out which args we need */
97 switch (code) {
98 /* Volume FOO: is not validated */
99 case ERROR_DISK_NOT_VALIDATED:
100 format = DosGetString(STRING_DISK_NOT_VALIDATED);
101 want_volume = TRUE;
102 break;
104 /* Volume FOO: is write protected */
105 case ERROR_DISK_WRITE_PROTECTED:
106 format = DosGetString(STRING_DISK_WRITE_PROTECTED);
107 want_volume = TRUE;
108 break;
110 /* Please (insert|replace) volume FOO: in ... */
111 case ERROR_DEVICE_NOT_MOUNTED:
112 if (type == REPORT_INSERT) {
113 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_INSERT);
114 want_volume = TRUE;
116 else if (type == REPORT_STREAM) {
117 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET);
118 want_volume = want_device = TRUE;
120 else {
121 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE);
122 want_volume = TRUE;
124 idcmp = IDCMP_DISKINSERTED;
125 break;
127 /* Volume FOO: is full */
128 case ERROR_DISK_FULL:
129 format = DosGetString(STRING_DISK_FULL);
130 want_volume = TRUE;
131 break;
133 /* Not a DOS disk in ...*/
134 case ERROR_NOT_A_DOS_DISK:
135 format = DosGetString(STRING_NOT_A_DOS_DISK);
136 want_device = TRUE;
137 break;
139 /* No disk present in ...*/
140 case ERROR_NO_DISK:
141 format = DosGetString(STRING_NO_DISK);
142 want_device = TRUE;
143 break;
145 /* You MUST replace volume FOO: in ... */
146 case ABORT_BUSY:
147 format = DosGetString(STRING_ABORT_BUSY);
148 want_volume = want_device = TRUE;
149 idcmp = IDCMP_DISKINSERTED;
150 break;
152 /* Volume FOO: has a read/write error */
153 case ABORT_DISK_ERROR:
154 format = DosGetString(STRING_ABORT_DISK_ERROR);
155 want_volume = TRUE;
156 break;
158 /* do nothing with other errors */
159 default:
160 return DOSTRUE;
163 /* now we need to determine the volume name. if they gave it to use
164 * (REPORT_INSERT), we just use it. otherwise, we get it from the device
165 * list (REPORT_VOLUME). if we don't have one, we use the handler/unit
166 * pair to find it */
167 switch (type) {
168 /* a filehandle */
169 case REPORT_STREAM:
170 if (arg1 == (IPTR)NULL)
171 return DOSTRUE;
173 handler = ((struct FileHandle *) BADDR(arg1))->fh_Device;
174 unit = ((struct FileHandle *) BADDR(arg1))->fh_Unit;
175 break;
177 case REPORT_TASK:
178 /* XXX what is this? */
179 return DOSTRUE;
181 /* a lock */
182 case REPORT_LOCK:
183 /* if they provided a lock, just use it */
184 if (arg1 != (IPTR)NULL) {
185 handler = ((struct FileHandle *) BADDR(arg1))->fh_Device;
186 unit = ((struct FileHandle *) BADDR(arg1))->fh_Unit;
189 /* otherwise we use the secondary device, and we look through the
190 * doslist to determine the unit */
191 else {
192 handler = (struct Device *) device;
194 /* find the doslist entry */
195 dol = LockDosList(LDF_READ | LDF_ALL);
196 while (dol != NULL && (dol->dol_Type != DLT_VOLUME ||
197 dol->dol_Ext.dol_AROS.dol_Device != handler))
198 dol = dol->dol_Next;
200 /* found it, steal its unit */
201 if (dol != NULL)
202 unit = dol->dol_Ext.dol_AROS.dol_Unit;
204 UnLockDosList(LDF_READ | LDF_ALL);
206 /* if we didn't find it, there's not much more we can do */
207 if (dol == NULL)
208 return DOSTRUE;
211 break;
213 /* a volume, ie a DeviceList */
214 case REPORT_VOLUME:
215 if (arg1 == (IPTR)NULL)
216 return DOSTRUE;
218 dl = (struct DeviceList *) arg1;
219 break;
221 /* raw volume name */
222 case REPORT_INSERT:
223 if (arg1 == (IPTR)NULL)
224 return DOSTRUE;
226 volname = (STRPTR) arg1;
227 /* rip off any trailing stuff, if its there */
228 if (SplitName(volname, ':', buf, 0, sizeof(buf)-1) == -1)
229 volname = buf;
230 break;
232 /* do nothing with other types */
233 default:
234 return DOSTRUE;
237 /* get the name if we don't already have it */
238 if (volname == NULL) {
240 /* just use the volume pointer if we already have it */
241 if (dl != NULL)
242 volname = dl->dl_Ext.dl_AROS.dol_DevName;
244 /* otherwise we have to get it from the handler */
245 else {
246 /* XXX for packets we'd just call ACTION_CURRENT_DEVICE */
248 struct FileHandle *fh;
249 char *p;
251 /* remember the current error just in case this fails. I don't know if
252 * this is actually necessary but I'm trying to keep side-effects to a
253 * minimum */
254 err = IoErr();
256 /* make a fake lock (filehandle) */
257 if ((fh = AllocDosObject(DOS_FILEHANDLE, 0)) == NULL) {
258 SetIoErr(err);
259 return DOSTRUE;
262 fh->fh_Device = handler;
263 fh->fh_Unit = unit;
265 /* get the handler to give us the name */
266 if (!NameFromLock(MKBADDR(fh), buf, 127)) {
267 FreeDosObject(DOS_FILEHANDLE, fh);
268 SetIoErr(err);
269 return DOSTRUE;
272 /* cleanup */
273 FreeDosObject(DOS_FILEHANDLE, fh);
274 SetIoErr(err);
276 /* find the volume seperator */
277 for (p = buf; *p != ':' && *p != '\0'; p++);
279 /* not there. can this happen? */
280 if (*p == '\0')
281 return DOSTRUE;
283 /* overwrite it, and we have a volume name */
284 *p = '\0';
286 volname = buf;
290 /* for the device name we need the doslist entry */
291 if (want_device) {
292 /* XXX for packets we just search the doslist for a DLT_DEVICE with
293 * the same task pointer. no need to worry about multiple units */
295 /* remember the current error in case we have to bail out */
296 err = IoErr();
298 /* get the entry for the volume */
299 if ((dvp = GetDeviceProc(volname, NULL)) == NULL) {
300 SetIoErr(err);
301 return DOSTRUE;
304 /* search the list for a device node with the same handler/port as the
305 * volume */
306 dol = LockDosList(LDF_READ | LDF_ALL);
307 while (dol != NULL && (dol->dol_Type != DLT_DEVICE ||
308 dol->dol_Ext.dol_AROS.dol_Device != (struct Device *) dvp->dvp_Port ||
309 dol->dol_Ext.dol_AROS.dol_Unit != dvp->dvp_DevNode->dol_Ext.dol_AROS.dol_Unit))
310 dol = dol->dol_Next;
312 /* found it */
313 if (dol != NULL)
314 devname = dol->dol_Ext.dol_AROS.dol_DevName;
316 /* XXX can this happen? */
317 else
318 devname = "???";
320 UnLockDosList(LDF_READ | LDF_ALL);
322 FreeDeviceProc(dvp);
325 /* have all we need, now to build the arg array */
326 if (want_volume) {
327 args[0] = volname;
328 if (want_device)
329 args[1] = devname;
331 else if (want_device)
332 args[0] = devname;
334 /* display it. idcmp is set further up to catch "disk insert" events if
335 * we're waiting for them to insert something */
337 res = DisplayError(format, idcmp, &args);
339 SetIoErr(code);
341 return res == 0 ? DOSFALSE : DOSTRUE;
343 AROS_LIBFUNC_EXIT
344 } /* ErrorReport */