2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
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"
20 /*****************************************************************************
23 #include <proto/dos.h>
25 AROS_LH4(BOOL
, ErrorReport
,
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
),
34 struct DosLibrary
*, DOSBase
, 80, Dos
)
37 Displays a requester with Retry/Cancel buttons for an error.
38 IoErr() is set to "code".
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!)
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
67 *****************************************************************************/
71 struct Process
*me
= (struct Process
*) FindTask(NULL
);
73 BOOL want_volume
= FALSE
;
74 BOOL want_device
= FALSE
;
75 STRPTR volname
= NULL
;
76 STRPTR devname
= NULL
;
77 struct DeviceList
*dl
= NULL
;
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) {
97 /* first setup the error format and work out which args we need */
99 /* Volume FOO: is not validated */
100 case ERROR_DISK_NOT_VALIDATED
:
101 format
= DosGetString(MSG_STRING_DISK_NOT_VALIDATED
);
105 /* Volume FOO: is write protected */
106 case ERROR_DISK_WRITE_PROTECTED
:
107 format
= DosGetString(MSG_STRING_DISK_WRITE_PROTECTED
);
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
);
117 else if (type
== REPORT_STREAM
) {
118 format
= DosGetString(MSG_STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET
);
119 want_volume
= want_device
= TRUE
;
122 format
= DosGetString(MSG_STRING_DEVICE_NOT_MOUNTED_REPLACE
);
125 idcmp
= IDCMP_DISKINSERTED
;
128 /* Volume FOO: is full */
129 case ERROR_DISK_FULL
:
130 format
= DosGetString(MSG_STRING_DISK_FULL
);
134 /* Not a DOS disk in ...*/
135 case ERROR_NOT_A_DOS_DISK
:
136 format
= DosGetString(MSG_STRING_NOT_A_DOS_DISK
);
140 /* No disk present in ...*/
142 format
= DosGetString(MSG_STRING_NO_DISK
);
146 /* You MUST replace volume FOO: in ... */
148 format
= DosGetString(MSG_STRING_ABORT_BUSY
);
149 want_volume
= want_device
= TRUE
;
150 idcmp
= IDCMP_DISKINSERTED
;
153 /* Volume FOO: has a read/write error */
154 case ABORT_DISK_ERROR
:
155 format
= DosGetString(MSG_STRING_ABORT_DISK_ERROR
);
159 /* do nothing with other errors */
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
171 if (arg1
== (IPTR
)NULL
)
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
));
176 volname
= AROS_BSTR_ADDR(dl
->dl_Name
);
180 /* XXX what is this? */
186 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, 0);
189 /* if they provided a lock, just use it */
190 if (arg1
!= (IPTR
)NULL
) {
191 msgport
= ((struct FileLock
*) BADDR(arg1
))->fl_Task
;
195 if (dopacket2(DOSBase
, NULL
, msgport
, ACTION_EXAMINE_OBJECT
, arg1
, (SIPTR
)MKBADDR(fib
))) {
197 strncpy(buf
, fib
->fib_FileName
, sizeof (buf
) - 1);
198 buf
[sizeof(buf
) - 1] = 0;
200 FreeDosObject(DOS_FIB
, fib
);
207 /* a volume, ie a DeviceList */
209 if (arg1
== (IPTR
)NULL
)
212 dl
= (struct DeviceList
*) arg1
;
213 volname
= AROS_BSTR_ADDR(dl
->dl_Name
);
214 msgport
= dl
->dl_Task
;
217 /* raw volume name */
219 if (arg1
== (IPTR
)NULL
)
221 if (!getpacketinfo(DOSBase
, (STRPTR
)arg1
, &phs
))
224 volname
= (STRPTR
) arg1
;
225 /* rip off any trailing stuff, if its there */
226 if (SplitName(volname
, ':', buf
, 0, sizeof(buf
)-1) == -1)
228 freepacketinfo(DOSBase
, &phs
);
231 /* do nothing with other types */
236 /* for the device name we need the doslist entry */
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 */
244 /* get the entry for the volume */
245 if ((dvp
= GetDeviceProc(volname
, NULL
)) == NULL
) {
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
);
257 devname
= (char*)dol
->dol_Name
+ 1;
259 /* XXX can this happen? */
263 UnLockDosList(LDF_READ
| LDF_ALL
);
268 /* have all we need, now to build the arg array */
274 else if (want_device
)
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
);
284 return res
== 0 ? DOSFALSE
: DOSTRUE
;