2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
9 #include "dos_intern.h"
11 #include <dos/dosextens.h>
12 #include <intuition/intuition.h>
13 #include <exec/ports.h>
15 #include <aros/debug.h>
17 /*****************************************************************************
20 #include <proto/dos.h>
22 AROS_LH4(BOOL
, ErrorReport
,
25 AROS_LHA(LONG
, code
, D1
),
26 AROS_LHA(LONG
, type
, D2
),
27 AROS_LHA(ULONG
, arg1
, D3
),
28 AROS_LHA(struct MsgPort
*, device
, D4
),
31 struct DosLibrary
*, DOSBase
, 80, Dos
)
37 code -- The error to put up the requester for
38 type -- Type of request
40 REPORT_LOCK -- arg1 is a lock (BPTR).
41 REPORT_FH -- arg1 is a filehandle (BPTR).
42 REPORT_VOLUME -- arg1 is a volumenode (C pointer).
43 REPORT_INSERT -- arg1 is the string for the volumename
45 arg1 -- Argument according to type (see above)
46 device -- Optional handler task address (obsolete!)
52 Locks and filehandles are the same in AROS so there is redundancy in
53 the parameters. Furthermore, the 'device' argument is not cared about
54 as AROS don't build filesystems via handlers.
64 *****************************************************************************/
68 struct Process
*me
= (struct Process
*) FindTask(NULL
);
70 BOOL want_volume
= FALSE
;
71 BOOL want_device
= FALSE
;
72 STRPTR volname
= NULL
;
73 STRPTR devname
= NULL
;
74 struct DeviceList
*dl
= NULL
;
75 struct Device
*handler
= NULL
;
76 struct Unit
*unit
= NULL
;
85 /* do nothing if errors are disabled */
86 if (me
->pr_WindowPtr
== (APTR
) -1)
89 /* first setup the error format and work out which args we need */
91 /* Volume FOO: is not validated */
92 case ERROR_DISK_NOT_VALIDATED
:
93 format
= DosGetString(STRING_DISK_NOT_VALIDATED
);
97 /* Volume FOO: is write protected */
98 case ERROR_DISK_WRITE_PROTECTED
:
99 format
= DosGetString(STRING_DISK_WRITE_PROTECTED
);
103 /* Please (insert|replace) volume FOO: in ... */
104 case ERROR_DEVICE_NOT_MOUNTED
:
105 if (type
== REPORT_INSERT
) {
106 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_INSERT
);
109 else if (type
== REPORT_STREAM
) {
110 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET
);
111 want_volume
= want_device
= TRUE
;
114 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE
);
117 idcmp
= IDCMP_DISKINSERTED
;
120 /* Volume FOO: is full */
121 case ERROR_DISK_FULL
:
122 format
= DosGetString(STRING_DISK_FULL
);
126 /* Not a DOS disk in ...*/
127 case ERROR_NOT_A_DOS_DISK
:
128 format
= DosGetString(STRING_NOT_A_DOS_DISK
);
132 /* No disk present in ...*/
134 format
= DosGetString(STRING_NO_DISK
);
138 /* You MUST replace volume FOO: in ... */
140 format
= DosGetString(STRING_ABORT_BUSY
);
141 want_volume
= want_device
= TRUE
;
142 idcmp
= IDCMP_DISKINSERTED
;
145 /* Volume FOO: has a read/write error */
146 case ABORT_DISK_ERROR
:
147 format
= DosGetString(STRING_ABORT_DISK_ERROR
);
151 /* do nothing with other errors */
156 /* now we need to determine the volume name. if they gave it to use
157 * (REPORT_INSERT), we just use it. otherwise, we get it from the device
158 * list (REPORT_VOLUME). if we don't have one, we use the handler/unit
166 handler
= ((struct FileHandle
*) BADDR(arg1
))->fh_Device
;
167 unit
= ((struct FileHandle
*) BADDR(arg1
))->fh_Unit
;
171 /* XXX what is this? */
176 /* if they provided a lock, just use it */
178 handler
= ((struct FileHandle
*) BADDR(arg1
))->fh_Device
;
179 unit
= ((struct FileHandle
*) BADDR(arg1
))->fh_Unit
;
182 /* otherwise we use the secondary device, and we look through the
183 * doslist to determine the unit */
185 handler
= (struct Device
*) device
;
187 /* find the doslist entry */
188 dol
= LockDosList(LDF_READ
| LDF_ALL
);
189 while (dol
!= NULL
&& (dol
->dol_Type
!= DLT_VOLUME
||
190 dol
->dol_Ext
.dol_AROS
.dol_Device
!= handler
))
193 /* found it, steal its unit */
195 unit
= dol
->dol_Ext
.dol_AROS
.dol_Unit
;
197 UnLockDosList(LDF_READ
| LDF_ALL
);
199 /* if we didn't find it, there's not much more we can do */
206 /* a volume, ie a DeviceList */
211 dl
= (struct DeviceList
*) arg1
;
214 /* raw volume name */
219 volname
= (STRPTR
) arg1
;
220 /* rip off any trailing stuff, if its there */
221 if (SplitName(volname
, ':', buf
, 0, sizeof(buf
)-1) == -1)
225 /* do nothing with other types */
230 /* get the name if we don't already have it */
231 if (volname
== NULL
) {
233 /* just use the volume pointer if we already have it */
235 volname
= dl
->dl_Ext
.dl_AROS
.dol_DevName
;
237 /* otherwise we have to get it from the handler */
239 /* XXX for packets we'd just call ACTION_CURRENT_DEVICE */
241 struct FileHandle
*fh
;
244 /* remember the current error just in case this fails. I don't know if
245 * this is actually necessary but I'm trying to keep side-effects to a
249 /* make a fake lock (filehandle) */
250 if ((fh
= AllocDosObject(DOS_FILEHANDLE
, 0)) == NULL
) {
255 fh
->fh_Device
= handler
;
258 /* get the handler to give us the name */
259 if (NameFromLock(MKBADDR(fh
), buf
, 127) != DOSTRUE
) {
260 FreeDosObject(fh
, DOS_FILEHANDLE
);
266 FreeDosObject(fh
, DOS_FILEHANDLE
);
269 /* find the volume seperator */
270 for (p
= buf
; *p
!= ':' && *p
!= '\0'; p
++);
272 /* not there. can this happen? */
276 /* overwrite it, and we have a volume name */
283 /* for the device name we need the doslist entry */
285 /* XXX for packets we just search the doslist for a DLT_DEVICE with
286 * the same task pointer. no need to worry about multiple units */
288 /* remember the current error in case we have to bail out */
291 /* get the entry for the volume */
292 if ((dvp
= GetDeviceProc(volname
, NULL
)) == NULL
) {
297 /* search the list for a device node with the same handler/port as the
299 dol
= LockDosList(LDF_READ
| LDF_ALL
);
300 while (dol
!= NULL
&& (dol
->dol_Type
!= DLT_DEVICE
||
301 dol
->dol_Ext
.dol_AROS
.dol_Device
!= (struct Device
*) dvp
->dvp_Port
||
302 dol
->dol_Ext
.dol_AROS
.dol_Unit
!= dvp
->dvp_DevNode
->dol_Ext
.dol_AROS
.dol_Unit
))
307 devname
= dol
->dol_Ext
.dol_AROS
.dol_DevName
;
309 /* XXX can this happen? */
313 UnLockDosList(LDF_READ
| LDF_ALL
);
318 /* have all we need, now to build the arg array */
324 else if (want_device
)
327 /* display it. idcmp is set further up to catch "disk insert" events if
328 * we're waiting for them to insert something */
330 res
= DisplayError(format
, idcmp
, &args
);
334 return res
== 0 ? DOSFALSE
: DOSTRUE
;