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(IPTR
, 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 doesn't build filesystems with 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) {
91 /* first setup the error format and work out which args we need */
93 /* Volume FOO: is not validated */
94 case ERROR_DISK_NOT_VALIDATED
:
95 format
= DosGetString(STRING_DISK_NOT_VALIDATED
);
99 /* Volume FOO: is write protected */
100 case ERROR_DISK_WRITE_PROTECTED
:
101 format
= DosGetString(STRING_DISK_WRITE_PROTECTED
);
105 /* Please (insert|replace) volume FOO: in ... */
106 case ERROR_DEVICE_NOT_MOUNTED
:
107 if (type
== REPORT_INSERT
) {
108 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_INSERT
);
111 else if (type
== REPORT_STREAM
) {
112 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET
);
113 want_volume
= want_device
= TRUE
;
116 format
= DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE
);
119 idcmp
= IDCMP_DISKINSERTED
;
122 /* Volume FOO: is full */
123 case ERROR_DISK_FULL
:
124 format
= DosGetString(STRING_DISK_FULL
);
128 /* Not a DOS disk in ...*/
129 case ERROR_NOT_A_DOS_DISK
:
130 format
= DosGetString(STRING_NOT_A_DOS_DISK
);
134 /* No disk present in ...*/
136 format
= DosGetString(STRING_NO_DISK
);
140 /* You MUST replace volume FOO: in ... */
142 format
= DosGetString(STRING_ABORT_BUSY
);
143 want_volume
= want_device
= TRUE
;
144 idcmp
= IDCMP_DISKINSERTED
;
147 /* Volume FOO: has a read/write error */
148 case ABORT_DISK_ERROR
:
149 format
= DosGetString(STRING_ABORT_DISK_ERROR
);
153 /* do nothing with other errors */
158 /* now we need to determine the volume name. if they gave it to use
159 * (REPORT_INSERT), we just use it. otherwise, we get it from the device
160 * list (REPORT_VOLUME). if we don't have one, we use the handler/unit
168 handler
= ((struct FileHandle
*) BADDR(arg1
))->fh_Device
;
169 unit
= ((struct FileHandle
*) BADDR(arg1
))->fh_Unit
;
173 /* XXX what is this? */
178 /* if they provided a lock, just use it */
180 handler
= ((struct FileHandle
*) BADDR(arg1
))->fh_Device
;
181 unit
= ((struct FileHandle
*) BADDR(arg1
))->fh_Unit
;
184 /* otherwise we use the secondary device, and we look through the
185 * doslist to determine the unit */
187 handler
= (struct Device
*) device
;
189 /* find the doslist entry */
190 dol
= LockDosList(LDF_READ
| LDF_ALL
);
191 while (dol
!= NULL
&& (dol
->dol_Type
!= DLT_VOLUME
||
192 dol
->dol_Ext
.dol_AROS
.dol_Device
!= handler
))
195 /* found it, steal its unit */
197 unit
= dol
->dol_Ext
.dol_AROS
.dol_Unit
;
199 UnLockDosList(LDF_READ
| LDF_ALL
);
201 /* if we didn't find it, there's not much more we can do */
208 /* a volume, ie a DeviceList */
213 dl
= (struct DeviceList
*) arg1
;
216 /* raw volume name */
221 volname
= (STRPTR
) arg1
;
222 /* rip off any trailing stuff, if its there */
223 if (SplitName(volname
, ':', buf
, 0, sizeof(buf
)-1) == -1)
227 /* do nothing with other types */
232 /* get the name if we don't already have it */
233 if (volname
== NULL
) {
235 /* just use the volume pointer if we already have it */
237 volname
= dl
->dl_Ext
.dl_AROS
.dol_DevName
;
239 /* otherwise we have to get it from the handler */
241 /* XXX for packets we'd just call ACTION_CURRENT_DEVICE */
243 struct FileHandle
*fh
;
246 /* remember the current error just in case this fails. I don't know if
247 * this is actually necessary but I'm trying to keep side-effects to a
251 /* make a fake lock (filehandle) */
252 if ((fh
= AllocDosObject(DOS_FILEHANDLE
, 0)) == NULL
) {
257 fh
->fh_Device
= handler
;
260 /* get the handler to give us the name */
261 if (NameFromLock(MKBADDR(fh
), buf
, 127) != DOSTRUE
) {
262 FreeDosObject(fh
, DOS_FILEHANDLE
);
268 FreeDosObject(fh
, DOS_FILEHANDLE
);
271 /* find the volume seperator */
272 for (p
= buf
; *p
!= ':' && *p
!= '\0'; p
++);
274 /* not there. can this happen? */
278 /* overwrite it, and we have a volume name */
285 /* for the device name we need the doslist entry */
287 /* XXX for packets we just search the doslist for a DLT_DEVICE with
288 * the same task pointer. no need to worry about multiple units */
290 /* remember the current error in case we have to bail out */
293 /* get the entry for the volume */
294 if ((dvp
= GetDeviceProc(volname
, NULL
)) == NULL
) {
299 /* search the list for a device node with the same handler/port as the
301 dol
= LockDosList(LDF_READ
| LDF_ALL
);
302 while (dol
!= NULL
&& (dol
->dol_Type
!= DLT_DEVICE
||
303 dol
->dol_Ext
.dol_AROS
.dol_Device
!= (struct Device
*) dvp
->dvp_Port
||
304 dol
->dol_Ext
.dol_AROS
.dol_Unit
!= dvp
->dvp_DevNode
->dol_Ext
.dol_AROS
.dol_Unit
))
309 devname
= dol
->dol_Ext
.dol_AROS
.dol_DevName
;
311 /* XXX can this happen? */
315 UnLockDosList(LDF_READ
| LDF_ALL
);
320 /* have all we need, now to build the arg array */
326 else if (want_device
)
329 /* display it. idcmp is set further up to catch "disk insert" events if
330 * we're waiting for them to insert something */
332 res
= DisplayError(format
, idcmp
, &args
);
336 return res
== 0 ? DOSFALSE
: DOSTRUE
;