2 * fat-handler - FAT12/16/32 filesystem handler
4 * Copyright © 2006 Marek Szyprowski
5 * Copyright © 2007-2015 The AROS Development Team
7 * This program is free software; you can redistribute it and/or modify it
8 * under the same terms as AROS itself.
13 #include <exec/types.h>
14 #include <exec/execbase.h>
15 #include <dos/dosextens.h>
16 #include <dos/filehandler.h>
17 #include <dos/notify.h>
18 #include <devices/inputevent.h>
20 #include <proto/exec.h>
21 #include <proto/dos.h>
26 #include "fat_protos.h"
28 #define DEBUG DEBUG_PACKETS
31 void ProcessPackets(struct Globals
*glob
) {
33 struct DosPacket
*pkt
;
35 while ((msg
= GetMsg(glob
->ourport
)) != NULL
) {
39 pkt
= (struct DosPacket
*) msg
->mn_Node
.ln_Name
;
41 switch(pkt
->dp_Type
) {
42 case ACTION_LOCATE_OBJECT
: {
43 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
44 LONG access
= pkt
->dp_Arg3
;
46 D(bug("[FAT] LOCATE_OBJECT: lock 0x%08x (dir %ld/%ld) name '", pkt
->dp_Arg1
,
47 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
48 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
),
49 AROS_BSTR_strlen(pkt
->dp_Arg2
)); bug("' type %s\n",
50 pkt
->dp_Arg3
== EXCLUSIVE_LOCK
? "EXCLUSIVE" : "SHARED"));
52 if ((err
= TestLock(fl
, glob
)))
55 if ((err
= OpLockFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
), access
, &lock
, glob
)) == 0)
56 res
= (IPTR
)MKBADDR(lock
);
61 case ACTION_FREE_LOCK
: {
62 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
64 D(bug("[FAT] FREE_LOCK: lock 0x%08x (dir %ld/%ld)\n",
66 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
68 OpUnlockFile(fl
, glob
);
75 case ACTION_COPY_DIR_FH
: {
76 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
78 D(bug("[FAT] COPY_DIR: lock 0x%08x (dir %ld/%ld)\n",
80 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
82 if ((err
= TestLock(fl
, glob
)))
85 if ((err
= OpCopyLock(fl
, &lock
, glob
)) == 0)
86 res
= (IPTR
)MKBADDR(lock
);
92 case ACTION_PARENT_FH
: {
93 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
95 D(bug("[FAT] ACTION_PARENT: lock 0x%08x (dir %ld/%ld)\n",
97 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
99 if ((err
= TestLock(fl
, glob
)))
102 if ((err
= OpLockParent(fl
, &lock
, glob
)) == 0)
103 res
= (IPTR
)MKBADDR(lock
);
108 case ACTION_SAME_LOCK
: {
109 struct ExtFileLock
*fl1
= BADDR(pkt
->dp_Arg1
);
110 struct ExtFileLock
*fl2
= BADDR(pkt
->dp_Arg2
);
112 D(bug("[FAT] ACTION_SAME_LOCK: lock #1 0x%08x (dir %ld/%ld) lock #2 0x%08x (dir %ld/%ld)\n",
114 fl1
!= NULL
? fl1
->gl
->dir_cluster
: 0, fl1
!= NULL
? fl1
->gl
->dir_entry
: 0,
116 fl2
!= NULL
? fl2
->gl
->dir_cluster
: 0, fl2
!= NULL
? fl2
->gl
->dir_entry
: 0));
120 if (fl1
== fl2
|| fl1
->gl
== fl2
->gl
)
126 case ACTION_EXAMINE_OBJECT
:
127 case ACTION_EXAMINE_FH
: {
128 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
129 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
131 D(bug("[FAT] EXAMINE_OBJECT: lock 0x%08x (dir %ld/%ld)\n",
133 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
135 if ((err
= TestLock(fl
, glob
)))
138 if ((err
= FillFIB(fl
, fib
, glob
)) == 0)
144 case ACTION_EXAMINE_NEXT
: {
145 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
146 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
150 D(bug("[FAT] EXAMINE_NEXT: lock 0x%08x (dir %ld/%ld)\n",
152 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
154 if ((err
= TestLock(fl
, glob
)))
157 if ((err
= InitDirHandle(glob
->sb
, fl
->ioh
.first_cluster
, &dh
, FALSE
)) != 0)
160 dh
.cur_index
= fib
->fib_DiskKey
;
162 if ((err
= GetNextDirEntry(&dh
, &de
)) != 0) {
163 if (err
== ERROR_OBJECT_NOT_FOUND
)
164 err
= ERROR_NO_MORE_ENTRIES
;
165 ReleaseDirHandle(&dh
);
169 if ((err
= LockFile(fl
->ioh
.first_cluster
, dh
.cur_index
, SHARED_LOCK
, &lock
, glob
)) != 0) {
170 ReleaseDirHandle(&dh
);
174 if (!(err
= FillFIB(lock
, fib
, glob
))) {
175 fib
->fib_DiskKey
= dh
.cur_index
;
179 FreeLock(lock
, glob
);
180 ReleaseDirHandle(&dh
);
185 case ACTION_FINDINPUT
:
186 case ACTION_FINDOUTPUT
:
187 case ACTION_FINDUPDATE
: {
188 struct FileHandle
*fh
= BADDR(pkt
->dp_Arg1
);
189 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
190 struct ExtFileLock
*lock
;
192 D(bug("[FAT] %s: lock 0x%08x (dir %ld/%ld) path '",
193 pkt
->dp_Type
== ACTION_FINDINPUT
? "FINDINPUT" :
194 pkt
->dp_Type
== ACTION_FINDOUTPUT
? "FINDOUTPUT" :
197 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
198 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
)); bug("'\n"));
200 if ((err
= TestLock(fl
, glob
)))
203 if ((err
= OpOpenFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
), pkt
->dp_Type
, &lock
, glob
)) != 0)
206 fh
->fh_Arg1
= (IPTR
)MKBADDR(lock
);
207 fh
->fh_Port
= DOSFALSE
;
215 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
216 APTR buffer
= (APTR
)pkt
->dp_Arg2
;
217 ULONG want
= pkt
->dp_Arg3
, read
;
219 D(bug("[FAT] READ: lock 0x%08x (dir %ld/%ld pos %ld) want %ld\n",
221 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0,
225 if ((err
= TestLock(fl
, glob
))) {
230 if ((err
= OpRead(fl
, buffer
, want
, &read
, glob
)) != 0)
239 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
240 APTR buffer
= (APTR
)pkt
->dp_Arg2
;
241 ULONG want
= pkt
->dp_Arg3
, written
;
243 D(bug("[FAT] WRITE: lock 0x%08x (dir %ld/%ld pos %ld) want %ld\n",
245 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0,
249 if ((err
= TestLock(fl
, glob
))) {
254 if ((err
= OpWrite(fl
, buffer
, want
, &written
, glob
)) != 0)
263 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
264 LONG offset
= pkt
->dp_Arg2
;
265 ULONG whence
= pkt
->dp_Arg3
;
267 D(bug("[FAT] SEEK: lock 0x%08x (dir %ld/%ld pos %ld) offset %ld whence %s\n",
269 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0,
272 whence
== OFFSET_BEGINNING
? "BEGINNING" :
273 whence
== OFFSET_END
? "END" :
274 whence
== OFFSET_CURRENT
? "CURRENT" :
277 if ((err
= TestLock(fl
, glob
))) {
285 if (whence
== OFFSET_BEGINNING
&&
287 offset
<= fl
->gl
->size
)
289 else if (whence
== OFFSET_CURRENT
&&
290 offset
+ fl
->pos
>= 0 &&
291 offset
+ fl
->pos
<= fl
->gl
->size
)
293 else if (whence
== OFFSET_END
295 && fl
->gl
->size
+ offset
>= 0)
296 fl
->pos
= fl
->gl
->size
+ offset
;
299 err
= ERROR_SEEK_ERROR
;
305 case ACTION_SET_FILE_SIZE
: {
306 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
307 LONG offset
= pkt
->dp_Arg2
;
308 LONG whence
= pkt
->dp_Arg3
;
311 D(bug("[FAT] SET_FILE_SIZE: lock 0x%08x (dir %ld/%ld pos %ld) offset %ld whence %s\n",
313 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0,
316 whence
== OFFSET_BEGINNING
? "BEGINNING" :
317 whence
== OFFSET_END
? "END" :
318 whence
== OFFSET_CURRENT
? "CURRENT" :
321 if ((err
= TestLock(fl
, glob
))) {
326 if ((err
= OpSetFileSize(fl
, offset
, whence
, &newsize
, glob
)) != 0)
335 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
337 D(bug("[FAT] END: lock 0x%08x (dir %ld/%ld)\n",
339 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0));
341 if ((err
= TestLock(fl
, glob
)))
350 case ACTION_IS_FILESYSTEM
:
351 D(bug("[FAT] IS_FILESYSTEM\n"));
356 case ACTION_CURRENT_VOLUME
: {
357 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
359 D(bug("[FAT] CURRENT_VOLUME: lock 0x%08x\n",
362 res
= (IPTR
)((fl
) ? fl
->fl_Volume
: ((glob
->sb
!= NULL
) ? MKBADDR(glob
->sb
->doslist
) : BNULL
));
367 case ACTION_DISK_INFO
: {
370 if (pkt
->dp_Type
== ACTION_INFO
) {
371 struct FileLock
*fl
= BADDR(pkt
->dp_Arg1
);
373 D(bug("[FAT] INFO: lock 0x%08x\n",
376 if (fl
&& (glob
->sb
== NULL
|| fl
->fl_Volume
!= MKBADDR(glob
->sb
->doslist
))) {
377 err
= ERROR_DEVICE_NOT_MOUNTED
;
381 id
= BADDR(pkt
->dp_Arg2
);
384 D(bug("[FAT] DISK_INFO\n"));
386 id
= BADDR(pkt
->dp_Arg1
);
389 FillDiskInfo(id
, glob
);
395 case ACTION_INHIBIT
: {
396 LONG inhibit
= pkt
->dp_Arg1
;
398 D(bug("[FAT] INHIBIT: %sinhibit\n",
399 inhibit
== DOSTRUE
? "" : "un"));
401 if (inhibit
== DOSTRUE
) {
402 glob
->disk_inhibited
++;
403 if (glob
->disk_inhibited
== 1)
406 else if (glob
->disk_inhibited
) {
407 glob
->disk_inhibited
--;
408 if (glob
->disk_inhibited
== 0)
409 ProcessDiskChange(glob
);
418 struct NotifyNode
*nn
;
420 D(bug("[FAT] DIE\n"));
422 /* clear our message port from notification requests so DOS won't send
423 * notification-end packets to us after we're gone */
424 ForeachNode(&glob
->sblist
, sb
) {
425 ForeachNode(&sb
->info
->notifies
, nn
) {
426 nn
->nr
->nr_Handler
= NULL
;
430 if ((glob
->sb
!= NULL
431 && !(IsListEmpty(&glob
->sb
->info
->locks
)
432 && IsListEmpty(&glob
->sb
->info
->notifies
)))) {
434 D(bug("\tThere are remaining locks or notification "
435 "requests. Shutting down is not possible\n"));
437 err
= ERROR_OBJECT_IN_USE
;
441 D(bug("\tNothing pending. Shutting down the handler\n"));
443 DoDiskRemove(glob
); /* risky, because of async. volume remove, but works */
446 glob
->death_packet
= pkt
;
447 glob
->devnode
->dol_Task
= NULL
;
454 /* XXX AROS needs these ACTION_ headers defined in dos/dosextens.h */
456 case ACTION_GET_DISK_FSSM
: {
457 D(bug("\nGot ACTION_GET_DISK_FSSM\n"));
459 res
= (ULONG
) glob
->fssm
;
463 case ACTION_FREE_DISK_FSSM
: {
464 D(bug("\nGot ACTION_FREE_DISK_FSSM\n"));
472 case ACTION_DISK_CHANGE
: { /* internal */
473 struct DosList
*vol
= (struct DosList
*)pkt
->dp_Arg2
;
474 struct VolumeInfo
*vol_info
=
475 BADDR(vol
->dol_misc
.dol_volume
.dol_LockList
);
476 ULONG type
= pkt
->dp_Arg3
;
478 D(bug("[FAT] DISK_CHANGE [INTERNAL]\n"));
480 if (pkt
->dp_Arg1
== ID_FAT_DISK
) { /* security check */
482 if (AttemptLockDosList(LDF_VOLUMES
|LDF_WRITE
)) {
484 if (type
== ACTION_VOLUME_ADD
) {
486 UnLockDosList(LDF_VOLUMES
|LDF_WRITE
);
488 SendEvent(IECLASS_DISKINSERTED
, glob
);
490 D(bug("\tVolume added\n"));
492 else if (type
== ACTION_VOLUME_REMOVE
) {
494 DeletePool(vol_info
->mem_pool
);
495 UnLockDosList(LDF_VOLUMES
|LDF_WRITE
);
497 SendEvent(IECLASS_DISKREMOVED
, glob
);
499 D(bug("\tVolume removed\n"));
502 FreeDosObject(DOS_STDPKT
, pkt
); /* cleanup */
505 D(bug("Packet destroyed\n"));
509 D(bug("\tDosList is locked\n"));
511 PutMsg(glob
->ourport
, pkt
->dp_Link
);
513 D(bug("Message moved to the end of the queue\n"));
517 err
= ERROR_OBJECT_WRONG_TYPE
;
522 case ACTION_RENAME_DISK
: {
524 D(bug("[FAT] RENAME_DISK: name '");
525 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
526 AROS_BSTR_strlen(pkt
->dp_Arg1
)); bug("'\n"));
528 if (glob
->sb
->doslist
== NULL
) {
529 err
= glob
->disk_inserted
? ERROR_NOT_A_DOS_DISK
: ERROR_NO_DISK
;
533 while (! AttemptLockDosList(LDF_VOLUMES
| LDF_WRITE
))
534 ProcessPackets(glob
);
536 err
= SetVolumeName(glob
->sb
, AROS_BSTR_ADDR(pkt
->dp_Arg1
),
537 AROS_BSTR_strlen(pkt
->dp_Arg1
));
538 UnLockDosList(LDF_VOLUMES
| LDF_WRITE
);
542 #ifdef AROS_FAST_BPTR
543 /* ReadFATSuper() sets a null byte after the
544 * string, so this should be fine */
545 CopyMem(glob
->sb
->volume
.name
+ 1, glob
->sb
->doslist
->dol_Name
,
546 glob
->sb
->volume
.name
[0] + 1);
548 CopyMem(glob
->sb
->volume
.name
, BADDR(glob
->sb
->doslist
->dol_Name
),
549 glob
->sb
->volume
.name
[0] + 2);
552 CopyMem(glob
->sb
->volume
.name
, glob
->sb
->info
->root_lock
.name
,
553 glob
->sb
->volume
.name
[0] + 1);
560 case ACTION_FORMAT
: {
561 D(bug("[FAT] FORMAT: name '");
562 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
563 AROS_BSTR_strlen(pkt
->dp_Arg1
)); bug("'\n"));
565 if (!glob
->disk_inserted
) {
570 err
= FormatFATVolume(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
571 AROS_BSTR_strlen(pkt
->dp_Arg1
), glob
);
575 SendEvent(IECLASS_DISKINSERTED
, glob
);
582 case ACTION_DELETE_OBJECT
: {
583 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
585 D(bug("[FAT] DELETE_OBJECT: lock 0x%08x (dir %ld/%ld) path '",
587 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
588 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
)); bug("'\n"));
590 if ((err
= TestLock(fl
, glob
)))
593 err
= OpDeleteFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
), glob
);
600 case ACTION_RENAME_OBJECT
: {
601 struct ExtFileLock
*sfl
= BADDR(pkt
->dp_Arg1
), *dfl
= BADDR(pkt
->dp_Arg3
);
603 D(bug("[FAT] RENAME_OBJECT: srclock 0x%08x (dir %ld/%ld) name '",
605 sfl
!= NULL
? sfl
->gl
->dir_cluster
: 0, sfl
!= NULL
? sfl
->gl
->dir_entry
: 0);
606 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
)); bug("' destlock 0x%08x (dir %ld/%ld) name '",
608 dfl
!= NULL
? dfl
->gl
->dir_cluster
: 0, dfl
!= NULL
? dfl
->gl
->dir_entry
: 0);
609 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg4
), AROS_BSTR_strlen(pkt
->dp_Arg4
)); bug("'\n"));
611 if ((err
= TestLock(sfl
, glob
)) != 0 || (err
= TestLock(dfl
, glob
)) != 0)
614 err
= OpRenameFile(sfl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
), dfl
, AROS_BSTR_ADDR(pkt
->dp_Arg4
), AROS_BSTR_strlen(pkt
->dp_Arg4
), glob
);
621 case ACTION_CREATE_DIR
: {
622 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *new;
624 D(bug("[FAT] CREATE_DIR: lock 0x%08x (dir %ld/%ld) name '",
626 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
627 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
)); bug("'\n"));
629 if ((err
= TestLock(fl
, glob
)))
632 if ((err
= OpCreateDir(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
), AROS_BSTR_strlen(pkt
->dp_Arg2
), &new, glob
)) == 0)
633 res
= (IPTR
)MKBADDR(new);
638 case ACTION_SET_PROTECT
: {
639 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
640 ULONG prot
= pkt
->dp_Arg4
;
642 D(bug("[FAT] SET_PROTECT: lock 0x%08x (dir %ld/%ld) name '", pkt
->dp_Arg2
,
643 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
644 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
)); bug("' prot 0x%08x\n", prot
));
645 if ((err
= TestLock(fl
, glob
)))
648 err
= OpSetProtect(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
), prot
, glob
);
653 case ACTION_SET_DATE
: {
654 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
655 struct DateStamp
*ds
= (struct DateStamp
*)pkt
->dp_Arg4
;
657 #if defined(DEBUG) && DEBUG != 0
660 char datestr
[LEN_DATSTRING
];
663 dt
.dat_Format
= FORMAT_DOS
;
665 dt
.dat_StrDay
= NULL
;
666 dt
.dat_StrDate
= datestr
;
667 dt
.dat_StrTime
= NULL
;
670 D(bug("[FAT] SET_DATE: lock 0x%08x (dir %ld/%ld) name '",
672 fl
!= NULL
? fl
->gl
->dir_cluster
: 0, fl
!= NULL
? fl
->gl
->dir_entry
: 0);
673 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
)); bug("' ds '%s'\n", datestr
));
677 if ((err
= TestLock(fl
, glob
)))
680 err
= OpSetDate(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
), AROS_BSTR_strlen(pkt
->dp_Arg3
), ds
, glob
);
685 case ACTION_ADD_NOTIFY
: {
686 struct NotifyRequest
*nr
= (struct NotifyRequest
*)pkt
->dp_Arg1
;
688 D(bug("[FAT] ADD_NOTIFY: nr 0x%08x name '%s'\n", nr
, nr
->nr_FullName
));
690 err
= OpAddNotify(nr
, glob
);
695 case ACTION_REMOVE_NOTIFY
: {
696 struct NotifyRequest
*nr
= (struct NotifyRequest
*)pkt
->dp_Arg1
;
698 D(bug("[FAT] REMOVE_NOTIFY: nr 0x%08x name '%s'\n", nr
, nr
->nr_FullName
));
700 err
= OpRemoveNotify(nr
, glob
);
706 D(bug("[FAT] got unknown packet type %ld\n", pkt
->dp_Type
));
708 err
= ERROR_ACTION_NOT_KNOWN
;
715 D(bug("[FAT] replying to packet: result 0x%x, error 0x%x\n",
717 ReplyPacket(pkt
, SysBase
);
727 void ReplyPacket(struct DosPacket
*dp
, struct ExecBase
*SysBase
) {
733 mn
->mn_Node
.ln_Name
= (char *)dp
;
734 dp
->dp_Port
= &((struct Process
*)FindTask(NULL
))->pr_MsgPort
;