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
)
34 struct DosPacket
*pkt
;
36 while ((msg
= GetMsg(glob
->ourport
)) != NULL
)
41 pkt
= (struct DosPacket
*)msg
->mn_Node
.ln_Name
;
45 case ACTION_LOCATE_OBJECT
:
47 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
48 LONG access
= pkt
->dp_Arg3
;
51 bug("[fat] LOCATE_OBJECT: lock 0x%08x (dir %ld/%ld) name '",
52 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
53 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
54 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
),
55 AROS_BSTR_strlen(pkt
->dp_Arg2
));
56 bug("' type %s\n", pkt
->dp_Arg3
== EXCLUSIVE_LOCK
?
57 "EXCLUSIVE" : "SHARED");
60 if ((err
= TestLock(fl
, glob
)))
63 if ((err
= OpLockFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
),
64 AROS_BSTR_strlen(pkt
->dp_Arg2
), access
, &lock
,
66 res
= (IPTR
) MKBADDR(lock
);
71 case ACTION_FREE_LOCK
:
73 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
75 D(bug("[fat] FREE_LOCK: lock 0x%08x (dir %ld/%ld)\n",
77 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
78 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
80 OpUnlockFile(fl
, glob
);
87 case ACTION_COPY_DIR_FH
:
89 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
91 D(bug("[fat] COPY_DIR: lock 0x%08x (dir %ld/%ld)\n",
93 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
94 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
96 if ((err
= TestLock(fl
, glob
)))
99 if ((err
= OpCopyLock(fl
, &lock
, glob
)) == 0)
100 res
= (IPTR
) MKBADDR(lock
);
106 case ACTION_PARENT_FH
:
108 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
110 D(bug("[fat] ACTION_PARENT: lock 0x%08x (dir %ld/%ld)\n",
112 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
113 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
115 if ((err
= TestLock(fl
, glob
)))
118 if ((err
= OpLockParent(fl
, &lock
, glob
)) == 0)
119 res
= (IPTR
) MKBADDR(lock
);
124 case ACTION_SAME_LOCK
:
126 struct ExtFileLock
*fl1
= BADDR(pkt
->dp_Arg1
);
127 struct ExtFileLock
*fl2
= BADDR(pkt
->dp_Arg2
);
129 D(bug("[fat] ACTION_SAME_LOCK: lock #1 0x%08x (dir %ld/%ld)"
130 " lock #2 0x%08x (dir %ld/%ld)\n",
132 fl1
!= NULL
? fl1
->gl
->dir_cluster
: 0,
133 fl1
!= NULL
? fl1
->gl
->dir_entry
: 0, pkt
->dp_Arg2
,
134 fl2
!= NULL
? fl2
->gl
->dir_cluster
: 0,
135 fl2
!= NULL
? fl2
->gl
->dir_entry
: 0));
139 if (fl1
== fl2
|| fl1
->gl
== fl2
->gl
)
145 case ACTION_EXAMINE_OBJECT
:
146 case ACTION_EXAMINE_FH
:
148 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
149 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
151 D(bug("[fat] EXAMINE_OBJECT: lock 0x%08x (dir %ld/%ld)\n",
153 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
154 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
156 if ((err
= TestLock(fl
, glob
)))
159 if ((err
= FillFIB(fl
, fib
, glob
)) == 0)
165 case ACTION_EXAMINE_NEXT
:
167 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
;
168 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
172 D(bug("[fat] EXAMINE_NEXT: lock 0x%08x (dir %ld/%ld)\n",
174 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
175 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
177 if ((err
= TestLock(fl
, glob
)))
180 if ((err
= InitDirHandle(glob
->sb
, fl
->ioh
.first_cluster
, &dh
,
184 dh
.cur_index
= fib
->fib_DiskKey
;
186 if ((err
= GetNextDirEntry(&dh
, &de
, glob
)) != 0)
188 if (err
== ERROR_OBJECT_NOT_FOUND
)
189 err
= ERROR_NO_MORE_ENTRIES
;
190 ReleaseDirHandle(&dh
, glob
);
194 if ((err
= LockFile(fl
->ioh
.first_cluster
, dh
.cur_index
,
195 SHARED_LOCK
, &lock
, glob
)) != 0)
197 ReleaseDirHandle(&dh
, glob
);
201 if (!(err
= FillFIB(lock
, fib
, glob
)))
203 fib
->fib_DiskKey
= dh
.cur_index
;
207 FreeLock(lock
, glob
);
208 ReleaseDirHandle(&dh
, glob
);
213 case ACTION_FINDINPUT
:
214 case ACTION_FINDOUTPUT
:
215 case ACTION_FINDUPDATE
:
217 struct FileHandle
*fh
= BADDR(pkt
->dp_Arg1
);
218 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
219 struct ExtFileLock
*lock
;
222 bug("[fat] %s: lock 0x%08x (dir %ld/%ld) path '",
223 pkt
->dp_Type
== ACTION_FINDINPUT
? "FINDINPUT" :
224 pkt
->dp_Type
== ACTION_FINDOUTPUT
? "FINDOUTPUT" :
227 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
228 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
229 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
),
230 AROS_BSTR_strlen(pkt
->dp_Arg3
));
234 if ((err
= TestLock(fl
, glob
)))
237 if ((err
= OpOpenFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
),
238 AROS_BSTR_strlen(pkt
->dp_Arg3
), pkt
->dp_Type
,
242 fh
->fh_Arg1
= (IPTR
) MKBADDR(lock
);
243 fh
->fh_Port
= DOSFALSE
;
252 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
253 APTR buffer
= (APTR
) pkt
->dp_Arg2
;
254 ULONG want
= pkt
->dp_Arg3
, read
;
256 D(bug("[fat] READ: lock 0x%08x (dir %ld/%ld pos %ld)"
258 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
259 fl
!= NULL
? fl
->gl
->dir_entry
: 0, fl
->pos
, want
));
261 if ((err
= TestLock(fl
, glob
)))
267 if ((err
= OpRead(fl
, buffer
, want
, &read
, glob
)) != 0)
277 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
278 APTR buffer
= (APTR
) pkt
->dp_Arg2
;
279 ULONG want
= pkt
->dp_Arg3
, written
;
281 D(bug("[fat] WRITE: lock 0x%08x (dir %ld/%ld pos %ld)"
283 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
284 fl
!= NULL
? fl
->gl
->dir_entry
: 0, fl
->pos
, want
));
286 if ((err
= TestLock(fl
, glob
)))
292 if ((err
= OpWrite(fl
, buffer
, want
, &written
, glob
)) != 0)
302 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
303 LONG offset
= pkt
->dp_Arg2
;
304 ULONG whence
= pkt
->dp_Arg3
;
306 D(bug("[fat] SEEK: lock 0x%08x (dir %ld/%ld pos %ld)"
307 " offset %ld whence %s\n",
308 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
309 fl
!= NULL
? fl
->gl
->dir_entry
: 0, fl
->pos
, offset
,
310 whence
== OFFSET_BEGINNING
? "BEGINNING" :
311 whence
== OFFSET_END
? "END" :
312 whence
== OFFSET_CURRENT
? "CURRENT" :
315 if ((err
= TestLock(fl
, glob
)))
324 if (whence
== OFFSET_BEGINNING
325 && offset
>= 0 && offset
<= fl
->gl
->size
)
327 else if (whence
== OFFSET_CURRENT
328 && offset
+ fl
->pos
>= 0
329 && offset
+ fl
->pos
<= fl
->gl
->size
)
331 else if (whence
== OFFSET_END
332 && offset
<= 0 && fl
->gl
->size
+ offset
>= 0)
333 fl
->pos
= fl
->gl
->size
+ offset
;
337 err
= ERROR_SEEK_ERROR
;
343 case ACTION_SET_FILE_SIZE
:
345 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
346 LONG offset
= pkt
->dp_Arg2
;
347 LONG whence
= pkt
->dp_Arg3
;
350 D(bug("[fat] SET_FILE_SIZE: lock 0x%08x"
351 " (dir %ld/%ld pos %ld) offset %ld whence %s\n",
352 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
353 fl
!= NULL
? fl
->gl
->dir_entry
: 0, fl
->pos
, offset
,
354 whence
== OFFSET_BEGINNING
? "BEGINNING" :
355 whence
== OFFSET_END
? "END" :
356 whence
== OFFSET_CURRENT
? "CURRENT" :
359 if ((err
= TestLock(fl
, glob
)))
365 if ((err
= OpSetFileSize(fl
, offset
, whence
, &newsize
,
376 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
378 D(bug("[fat] END: lock 0x%08x (dir %ld/%ld)\n",
380 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
381 fl
!= NULL
? fl
->gl
->dir_entry
: 0));
383 if ((err
= TestLock(fl
, glob
)))
392 case ACTION_IS_FILESYSTEM
:
393 D(bug("[fat] IS_FILESYSTEM\n"));
398 case ACTION_CURRENT_VOLUME
:
400 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
402 D(bug("[fat] CURRENT_VOLUME: lock 0x%08x\n", pkt
->dp_Arg1
));
404 res
= (IPTR
) ((fl
) ? fl
->fl_Volume
: ((glob
->sb
!= NULL
) ?
405 MKBADDR(glob
->sb
->doslist
) : BNULL
));
410 case ACTION_DISK_INFO
:
414 if (pkt
->dp_Type
== ACTION_INFO
)
416 struct FileLock
*fl
= BADDR(pkt
->dp_Arg1
);
418 D(bug("[fat] INFO: lock 0x%08x\n", pkt
->dp_Arg1
));
420 if (fl
&& (glob
->sb
== NULL
421 || fl
->fl_Volume
!= MKBADDR(glob
->sb
->doslist
)))
423 err
= ERROR_DEVICE_NOT_MOUNTED
;
427 id
= BADDR(pkt
->dp_Arg2
);
431 D(bug("[fat] DISK_INFO\n"));
433 id
= BADDR(pkt
->dp_Arg1
);
436 FillDiskInfo(id
, glob
);
444 LONG inhibit
= pkt
->dp_Arg1
;
446 D(bug("[fat] INHIBIT: %sinhibit\n",
447 inhibit
== DOSTRUE
? "" : "un"));
449 if (inhibit
== DOSTRUE
)
451 glob
->disk_inhibited
++;
452 if (glob
->disk_inhibited
== 1)
455 else if (glob
->disk_inhibited
!= 0)
457 glob
->disk_inhibited
--;
458 if (glob
->disk_inhibited
== 0)
459 ProcessDiskChange(glob
);
469 struct NotifyNode
*nn
;
471 D(bug("[fat] DIE\n"));
473 /* Clear our message port from notification requests so DOS
474 * won't send notification-end packets to us after we're gone */
475 ForeachNode(&glob
->sblist
, sb
)
477 ForeachNode(&sb
->info
->notifies
, nn
)
479 nn
->nr
->nr_Handler
= NULL
;
483 if ((glob
->sb
!= NULL
484 && !(IsListEmpty(&glob
->sb
->info
->locks
)
485 && IsListEmpty(&glob
->sb
->info
->notifies
))))
488 D(bug("\tThere are remaining locks or notification "
489 "requests. Shutting down is not possible\n"));
491 err
= ERROR_OBJECT_IN_USE
;
495 D(bug("\tNothing pending. Shutting down the handler\n"));
497 /* Risky, because of async. volume remove, but works */
501 glob
->death_packet
= pkt
;
502 glob
->devnode
->dol_Task
= NULL
;
509 /* XXX: AROS needs these ACTION_ headers defined in dos/dosextens.h */
511 case ACTION_GET_DISK_FSSM
:
513 D(bug("\nGot ACTION_GET_DISK_FSSM\n"));
515 res
= (ULONG
) glob
->fssm
;
519 case ACTION_FREE_DISK_FSSM
:
521 D(bug("\nGot ACTION_FREE_DISK_FSSM\n"));
529 case ACTION_DISK_CHANGE
: /* Internal */
531 struct DosList
*vol
= (struct DosList
*)pkt
->dp_Arg2
;
532 struct VolumeInfo
*vol_info
=
533 BADDR(vol
->dol_misc
.dol_volume
.dol_LockList
);
534 ULONG type
= pkt
->dp_Arg3
;
536 D(bug("[fat] DISK_CHANGE [INTERNAL]\n"));
538 if (pkt
->dp_Arg1
== ID_FAT_DISK
) /* Security check */
540 if (AttemptLockDosList(LDF_VOLUMES
| LDF_WRITE
))
542 if (type
== ACTION_VOLUME_ADD
)
545 UnLockDosList(LDF_VOLUMES
| LDF_WRITE
);
547 SendEvent(IECLASS_DISKINSERTED
, glob
);
549 D(bug("\tVolume added\n"));
551 else if (type
== ACTION_VOLUME_REMOVE
)
554 DeletePool(vol_info
->mem_pool
);
555 UnLockDosList(LDF_VOLUMES
| LDF_WRITE
);
557 SendEvent(IECLASS_DISKREMOVED
, glob
);
559 D(bug("\tVolume removed\n"));
562 FreeDosObject(DOS_STDPKT
, pkt
); /* Cleanup */
565 D(bug("Packet destroyed\n"));
570 D(bug("\tDosList is locked\n"));
572 PutMsg(glob
->ourport
, pkt
->dp_Link
);
574 D(bug("Message moved to the end of the queue\n"));
578 err
= ERROR_OBJECT_WRONG_TYPE
;
583 case ACTION_RENAME_DISK
:
587 bug("[fat] RENAME_DISK: name '");
588 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
589 AROS_BSTR_strlen(pkt
->dp_Arg1
));
593 if (glob
->sb
->doslist
== NULL
)
595 err
= glob
->disk_inserted
?
596 ERROR_NOT_A_DOS_DISK
: ERROR_NO_DISK
;
600 while (!AttemptLockDosList(LDF_VOLUMES
| LDF_WRITE
))
601 ProcessPackets(glob
);
603 err
= SetVolumeName(glob
->sb
, AROS_BSTR_ADDR(pkt
->dp_Arg1
),
604 AROS_BSTR_strlen(pkt
->dp_Arg1
));
605 UnLockDosList(LDF_VOLUMES
| LDF_WRITE
);
609 #ifdef AROS_FAST_BPTR
610 /* ReadFATSuper() sets a null byte after the
611 * string, so this should be fine */
612 CopyMem(glob
->sb
->volume
.name
+ 1,
613 glob
->sb
->doslist
->dol_Name
,
614 glob
->sb
->volume
.name
[0] + 1);
616 CopyMem(glob
->sb
->volume
.name
,
617 BADDR(glob
->sb
->doslist
->dol_Name
),
618 glob
->sb
->volume
.name
[0] + 2);
621 CopyMem(glob
->sb
->volume
.name
,
622 glob
->sb
->info
->root_lock
.name
,
623 glob
->sb
->volume
.name
[0] + 1);
633 bug("[fat] FORMAT: name '");
634 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
635 AROS_BSTR_strlen(pkt
->dp_Arg1
));
639 if (!glob
->disk_inserted
)
645 err
= FormatFATVolume(AROS_BSTR_ADDR(pkt
->dp_Arg1
),
646 AROS_BSTR_strlen(pkt
->dp_Arg1
), glob
);
650 SendEvent(IECLASS_DISKINSERTED
, glob
);
657 case ACTION_DELETE_OBJECT
:
659 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
662 bug("[fat] DELETE_OBJECT:"
663 " lock 0x%08x (dir %ld/%ld) path '",
664 pkt
->dp_Arg1
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
665 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
666 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
),
667 AROS_BSTR_strlen(pkt
->dp_Arg2
));
671 if ((err
= TestLock(fl
, glob
)))
674 err
= OpDeleteFile(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
),
675 AROS_BSTR_strlen(pkt
->dp_Arg2
), glob
);
682 case ACTION_RENAME_OBJECT
:
684 struct ExtFileLock
*sfl
= BADDR(pkt
->dp_Arg1
), *dfl
=
688 bug("[fat] RENAME_OBJECT:"
689 " srclock 0x%08x (dir %ld/%ld) name '",
691 sfl
!= NULL
? sfl
->gl
->dir_cluster
: 0,
692 sfl
!= NULL
? sfl
->gl
->dir_entry
: 0);
693 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
),
694 AROS_BSTR_strlen(pkt
->dp_Arg2
));
695 bug("' destlock 0x%08x (dir %ld/%ld) name '",
697 dfl
!= NULL
? dfl
->gl
->dir_cluster
: 0,
698 dfl
!= NULL
? dfl
->gl
->dir_entry
: 0);
699 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg4
),
700 AROS_BSTR_strlen(pkt
->dp_Arg4
));
704 if ((err
= TestLock(sfl
, glob
)) != 0
705 || (err
= TestLock(dfl
, glob
)) != 0)
708 err
= OpRenameFile(sfl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
),
709 AROS_BSTR_strlen(pkt
->dp_Arg2
), dfl
,
710 AROS_BSTR_ADDR(pkt
->dp_Arg4
),
711 AROS_BSTR_strlen(pkt
->dp_Arg4
), glob
);
718 case ACTION_CREATE_DIR
:
720 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *new;
723 bug("[fat] CREATE_DIR: lock 0x%08x (dir %ld/%ld) name '",
725 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
726 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
727 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg2
),
728 AROS_BSTR_strlen(pkt
->dp_Arg2
));
732 if ((err
= TestLock(fl
, glob
)))
735 if ((err
= OpCreateDir(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg2
),
736 AROS_BSTR_strlen(pkt
->dp_Arg2
), &new, glob
)) == 0)
737 res
= (IPTR
) MKBADDR(new);
742 case ACTION_SET_PROTECT
:
744 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
745 ULONG prot
= pkt
->dp_Arg4
;
748 bug("[fat] SET_PROTECT: lock 0x%08x (dir %ld/%ld) name '",
749 pkt
->dp_Arg2
, fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
750 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
751 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
),
752 AROS_BSTR_strlen(pkt
->dp_Arg3
));
753 bug("' prot 0x%08x\n", prot
);
755 if ((err
= TestLock(fl
, glob
)))
758 err
= OpSetProtect(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
),
759 AROS_BSTR_strlen(pkt
->dp_Arg3
), prot
, glob
);
764 case ACTION_SET_DATE
:
766 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
767 struct DateStamp
*ds
= (struct DateStamp
*)pkt
->dp_Arg4
;
769 #if defined(DEBUG) && DEBUG != 0
772 char datestr
[LEN_DATSTRING
];
775 dt
.dat_Format
= FORMAT_DOS
;
777 dt
.dat_StrDay
= NULL
;
778 dt
.dat_StrDate
= datestr
;
779 dt
.dat_StrTime
= NULL
;
783 bug("[fat] SET_DATE: lock 0x%08x (dir %ld/%ld) name '",
785 fl
!= NULL
? fl
->gl
->dir_cluster
: 0,
786 fl
!= NULL
? fl
->gl
->dir_entry
: 0);
787 RawPutChars(AROS_BSTR_ADDR(pkt
->dp_Arg3
),
788 AROS_BSTR_strlen(pkt
->dp_Arg3
));
789 bug("' ds '%s'\n", datestr
);
794 if ((err
= TestLock(fl
, glob
)))
797 err
= OpSetDate(fl
, AROS_BSTR_ADDR(pkt
->dp_Arg3
),
798 AROS_BSTR_strlen(pkt
->dp_Arg3
), ds
, glob
);
803 case ACTION_ADD_NOTIFY
:
805 struct NotifyRequest
*nr
=
806 (struct NotifyRequest
*)pkt
->dp_Arg1
;
808 D(bug("[fat] ADD_NOTIFY: nr 0x%08x name '%s'\n", nr
,
811 err
= OpAddNotify(nr
, glob
);
816 case ACTION_REMOVE_NOTIFY
:
818 struct NotifyRequest
*nr
=
819 (struct NotifyRequest
*)pkt
->dp_Arg1
;
821 D(bug("[fat] REMOVE_NOTIFY: nr 0x%08x name '%s'\n", nr
,
824 err
= OpRemoveNotify(nr
, glob
);
830 D(bug("[fat] got unknown packet type %ld\n", pkt
->dp_Type
));
832 err
= ERROR_ACTION_NOT_KNOWN
;
841 D(bug("[fat] replying to packet: result 0x%lx, error %ld\n",
843 ReplyPacket(pkt
, SysBase
);
853 void ReplyPacket(struct DosPacket
*dp
, struct ExecBase
*SysBase
)
860 dp
->dp_Port
= &((struct Process
*)FindTask(NULL
))->pr_MsgPort
;