Indentation fix, cleanup.
[AROS.git] / rom / dos / errorreport.c
blob672447af74ea1b74b090a2d222a9304f0e383802
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <dos/dos.h>
10 #include <dos/dosextens.h>
11 #include <intuition/intuition.h>
12 #include <exec/ports.h>
13 #include <aros/debug.h>
15 #define CATCOMP_NUMBERS
17 #include "dos_intern.h"
18 #include "strings.h"
20 /*****************************************************************************
22 NAME */
23 #include <proto/dos.h>
25 AROS_LH4(BOOL, ErrorReport,
27 /* SYNOPSIS */
28 AROS_LHA(LONG , code , D1),
29 AROS_LHA(LONG , type , D2),
30 AROS_LHA(IPTR , arg1 , D3),
31 AROS_LHA(struct MsgPort *, device, D4),
33 /* LOCATION */
34 struct DosLibrary *, DOSBase, 80, Dos)
36 /* FUNCTION
37 Displays a requester with Retry/Cancel buttons for an error.
38 IoErr() is set to "code".
40 INPUTS
41 code - The error to put up the requester for
42 type - Type of request:
43 REPORT_LOCK - arg1 is a lock (BPTR).
44 REPORT_FH - arg1 is a filehandle (BPTR).
45 REPORT_VOLUME - arg1 is a volumenode (C pointer).
46 REPORT_INSERT - arg1 is the string for the volume name.
48 arg1 - Argument according to type (see above)
49 device - Optional handler task address (obsolete!)
51 RESULT
52 DOSFALSE - user has selected "Retry"
53 DOSTRUE - user has selected "Cancel" or code wasn't understood or
54 pr_WindowPtr is -1 or if an attempt to open the requester
55 fails.
57 NOTES
59 EXAMPLE
61 BUGS
63 SEE ALSO
65 INTERNALS
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 struct Process *me = (struct Process *) FindTask(NULL);
72 STRPTR format;
73 BOOL want_volume = FALSE;
74 BOOL want_device = FALSE;
75 STRPTR volname = NULL;
76 STRPTR devname = NULL;
77 struct DeviceList *dl = NULL;
78 char buf[128];
79 struct DevProc *dvp;
80 struct DosList *dol;
81 APTR args[2];
82 ULONG idcmp = 0;
83 LONG err;
84 LONG res;
85 struct MsgPort *msgport;
86 struct PacketHelperStruct phs;
88 ASSERT_VALID_PROCESS(me);
90 /* do nothing if errors are disabled */
91 if (me->pr_WindowPtr == (APTR)(SIPTR)-1) {
92 SetIoErr(code);
93 return DOSTRUE;
95 buf[0] = 0;
97 /* first setup the error format and work out which args we need */
98 switch (code) {
99 /* Volume FOO: is not validated */
100 case ERROR_DISK_NOT_VALIDATED:
101 format = DosGetString(MSG_STRING_DISK_NOT_VALIDATED);
102 want_volume = TRUE;
103 break;
105 /* Volume FOO: is write protected */
106 case ERROR_DISK_WRITE_PROTECTED:
107 format = DosGetString(MSG_STRING_DISK_WRITE_PROTECTED);
108 want_volume = TRUE;
109 break;
111 /* Please (insert|replace) volume FOO: in ... */
112 case ERROR_DEVICE_NOT_MOUNTED:
113 if (type == REPORT_INSERT) {
114 format = DosGetString(MSG_STRING_DEVICE_NOT_MOUNTED_INSERT);
115 want_volume = TRUE;
117 else if (type == REPORT_STREAM) {
118 format = DosGetString(MSG_STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET);
119 want_volume = want_device = TRUE;
121 else {
122 format = DosGetString(MSG_STRING_DEVICE_NOT_MOUNTED_REPLACE);
123 want_volume = TRUE;
125 idcmp = IDCMP_DISKINSERTED;
126 break;
128 /* Volume FOO: is full */
129 case ERROR_DISK_FULL:
130 format = DosGetString(MSG_STRING_DISK_FULL);
131 want_volume = TRUE;
132 break;
134 /* Not a DOS disk in ...*/
135 case ERROR_NOT_A_DOS_DISK:
136 format = DosGetString(MSG_STRING_NOT_A_DOS_DISK);
137 want_device = TRUE;
138 break;
140 /* No disk present in ...*/
141 case ERROR_NO_DISK:
142 format = DosGetString(MSG_STRING_NO_DISK);
143 want_device = TRUE;
144 break;
146 /* You MUST replace volume FOO: in ... */
147 case ABORT_BUSY:
148 format = DosGetString(MSG_STRING_ABORT_BUSY);
149 want_volume = want_device = TRUE;
150 idcmp = IDCMP_DISKINSERTED;
151 break;
153 /* Volume FOO: has a read/write error */
154 case ABORT_DISK_ERROR:
155 format = DosGetString(MSG_STRING_ABORT_DISK_ERROR);
156 want_volume = TRUE;
157 break;
159 /* do nothing with other errors */
160 default:
161 return DOSTRUE;
164 /* now we need to determine the volume name. if they gave it to use
165 * (REPORT_INSERT), we just use it. otherwise, we get it from the device
166 * list (REPORT_VOLUME). if we don't have one, we use the handler/unit
167 * pair to find it */
168 switch (type) {
169 /* a filehandle */
170 case REPORT_STREAM:
171 if (arg1 == (IPTR)NULL)
172 return DOSTRUE;
173 msgport = ((struct FileHandle *) BADDR(arg1))->fh_Type;
174 dl = (struct DeviceList*)BADDR(dopacket1(DOSBase, NULL, msgport, ACTION_CURRENT_VOLUME, ((struct FileHandle *) BADDR(arg1))->fh_Arg1));
175 if (dl)
176 volname = AROS_BSTR_ADDR(dl->dl_Name);
177 break;
179 case REPORT_TASK:
180 /* XXX what is this? */
181 return DOSTRUE;
183 /* a lock */
184 case REPORT_LOCK:
186 struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, 0);
187 if (!fib)
188 return DOSTRUE;
189 /* if they provided a lock, just use it */
190 if (arg1 != (IPTR)NULL) {
191 msgport = ((struct FileLock *) BADDR(arg1))->fl_Task;
192 } else {
193 msgport = device;
195 if (dopacket2(DOSBase, NULL, msgport, ACTION_EXAMINE_OBJECT, arg1, (SIPTR)MKBADDR(fib))) {
196 fixfib(fib);
197 strncpy(buf, fib->fib_FileName, sizeof (buf) - 1);
198 buf[sizeof(buf) - 1] = 0;
200 FreeDosObject(DOS_FIB, fib);
201 if (buf[0] == 0)
202 return DOSTRUE;
203 volname = buf;
205 break;
207 /* a volume, ie a DeviceList */
208 case REPORT_VOLUME:
209 if (arg1 == (IPTR)NULL)
210 return DOSTRUE;
212 dl = (struct DeviceList *) arg1;
213 volname = AROS_BSTR_ADDR(dl->dl_Name);
214 msgport = dl->dl_Task;
215 break;
217 /* raw volume name */
218 case REPORT_INSERT:
219 if (arg1 == (IPTR)NULL)
220 return DOSTRUE;
221 if (!getpacketinfo(DOSBase, (STRPTR)arg1, &phs))
222 return DOSTRUE;
223 msgport = phs.port;
224 volname = (STRPTR) arg1;
225 /* rip off any trailing stuff, if its there */
226 if (SplitName(volname, ':', buf, 0, sizeof(buf)-1) == -1)
227 volname = buf;
228 freepacketinfo(DOSBase, &phs);
229 break;
231 /* do nothing with other types */
232 default:
233 return DOSTRUE;
236 /* for the device name we need the doslist entry */
237 if (want_device) {
238 /* XXX for packets we just search the doslist for a DLT_DEVICE with
239 * the same task pointer. no need to worry about multiple units */
241 /* remember the current error in case we have to bail out */
242 err = IoErr();
244 /* get the entry for the volume */
245 if ((dvp = GetDeviceProc(volname, NULL)) == NULL) {
246 SetIoErr(err);
247 return DOSTRUE;
250 /* search the list for a device node with the same port as the volume */
251 dol = LockDosList(LDF_READ | LDF_ALL);
252 while (dol != NULL && (dol->dol_Type != DLT_DEVICE || dol->dol_Task != msgport))
253 dol = BADDR(dol->dol_Next);
255 /* found it */
256 if (dol != NULL)
257 devname = (char*)dol->dol_Name + 1;
259 /* XXX can this happen? */
260 else
261 devname = "???";
263 UnLockDosList(LDF_READ | LDF_ALL);
265 FreeDeviceProc(dvp);
268 /* have all we need, now to build the arg array */
269 if (want_volume) {
270 args[0] = volname;
271 if (want_device)
272 args[1] = devname;
274 else if (want_device)
275 args[0] = devname;
277 /* display it. idcmp is set further up to catch "disk insert" events if
278 * we're waiting for them to insert something */
280 res = DisplayError(format, idcmp, &args);
282 SetIoErr(code);
284 return res == 0 ? DOSFALSE : DOSTRUE;
286 AROS_LIBFUNC_EXIT
287 } /* ErrorReport */