- Ignore any volume/device name in paths given as input.
[AROS.git] / rom / filesys / fat / packet.c
bloba08aa5359b07b899d9bf5a70de7ba81490365005
1 /*
2 * fat.handler - FAT12/16/32 filesystem handler
4 * Copyright © 2006 Marek Szyprowski
5 * Copyright © 2007-2014 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.
10 * $Id$
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>
23 #include <string.h>
25 #include "fat_fs.h"
26 #include "fat_protos.h"
28 #define DEBUG DEBUG_PACKETS
29 #include "debug.h"
31 void ProcessPackets(void) {
32 struct Message *msg;
33 struct DosPacket *pkt;
35 while ((msg = GetMsg(glob->ourport)) != NULL) {
36 IPTR res = DOSFALSE;
37 LONG err = 0;
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 UBYTE *path = BADDR(pkt->dp_Arg2);
45 LONG access = pkt->dp_Arg3;
47 D(bug("[FAT] LOCATE_OBJECT: lock 0x%08x (dir %ld/%ld) name '", pkt->dp_Arg1,
48 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
49 RawPutChars(AROS_BSTR_ADDR(path), AROS_BSTR_strlen(path)); bug("' type %s\n",
50 pkt->dp_Arg3 == EXCLUSIVE_LOCK ? "EXCLUSIVE" : "SHARED"));
52 if ((err = TestLock(fl)))
53 break;
55 if ((err = OpLockFile(fl, AROS_BSTR_ADDR(path), AROS_BSTR_strlen(path), access, &lock)) == 0)
56 res = (IPTR)MKBADDR(lock);
58 break;
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",
65 pkt->dp_Arg1,
66 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
68 OpUnlockFile(fl);
70 res = DOSTRUE;
71 break;
74 case ACTION_COPY_DIR:
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",
79 pkt->dp_Arg1,
80 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
82 if ((err = TestLock(fl)))
83 break;
85 if ((err = OpCopyLock(fl, &lock)) == 0)
86 res = (IPTR)MKBADDR(lock);
88 break;
91 case ACTION_PARENT:
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",
96 pkt->dp_Arg1,
97 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
99 if ((err = TestLock(fl)))
100 break;
102 if ((err = OpLockParent(fl, &lock)) == 0)
103 res = (IPTR)MKBADDR(lock);
105 break;
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",
113 pkt->dp_Arg1,
114 fl1 != NULL ? fl1->gl->dir_cluster : 0, fl1 != NULL ? fl1->gl->dir_entry : 0,
115 pkt->dp_Arg2,
116 fl2 != NULL ? fl2->gl->dir_cluster : 0, fl2 != NULL ? fl2->gl->dir_entry : 0));
118 err = 0;
120 if (fl1 == fl2 || fl1->gl == fl2->gl)
121 res = DOSTRUE;
123 break;
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",
132 pkt->dp_Arg1,
133 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
135 if ((err = TestLock(fl)))
136 break;
138 if ((err = FillFIB(fl, fib)) == 0)
139 res = DOSTRUE;
141 break;
144 case ACTION_EXAMINE_NEXT: {
145 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1), *lock;
146 struct FileInfoBlock *fib = BADDR(pkt->dp_Arg2);
147 struct DirHandle dh;
148 struct DirEntry de;
150 D(bug("[FAT] EXAMINE_NEXT: lock 0x%08x (dir %ld/%ld)\n",
151 pkt->dp_Arg1,
152 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
154 if ((err = TestLock(fl)))
155 break;
157 if ((err = InitDirHandle(glob->sb, fl->ioh.first_cluster, &dh, FALSE)) != 0)
158 break;
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);
166 break;
169 if ((err = LockFile(fl->ioh.first_cluster, dh.cur_index, SHARED_LOCK, &lock)) != 0) {
170 ReleaseDirHandle(&dh);
171 break;
174 if (!(err = FillFIB(lock, fib))) {
175 fib->fib_DiskKey = dh.cur_index;
176 res = DOSTRUE;
179 FreeLock(lock);
180 ReleaseDirHandle(&dh);
182 break;
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 UBYTE *path = BADDR(pkt->dp_Arg3);
191 struct ExtFileLock *lock;
193 D(bug("[FAT] %s: lock 0x%08x (dir %ld/%ld) path '",
194 pkt->dp_Type == ACTION_FINDINPUT ? "FINDINPUT" :
195 pkt->dp_Type == ACTION_FINDOUTPUT ? "FINDOUTPUT" :
196 "FINDUPDATE",
197 pkt->dp_Arg2,
198 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
199 RawPutChars(AROS_BSTR_ADDR(path), AROS_BSTR_strlen(path)); bug("'\n"));
201 if ((err = TestLock(fl)))
202 break;
204 if ((err = OpOpenFile(fl, AROS_BSTR_ADDR(path), AROS_BSTR_strlen(path), pkt->dp_Type, &lock)) != 0)
205 break;
207 fh->fh_Arg1 = (IPTR)MKBADDR(lock);
208 fh->fh_Port = DOSFALSE;
210 res = DOSTRUE;
212 break;
215 case ACTION_READ: {
216 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
217 APTR buffer = (APTR)pkt->dp_Arg2;
218 ULONG want = pkt->dp_Arg3, read;
220 D(bug("[FAT] READ: lock 0x%08x (dir %ld/%ld pos %ld) want %ld\n",
221 pkt->dp_Arg1,
222 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0,
223 fl->pos,
224 want));
226 if ((err = TestLock(fl))) {
227 res = -1;
228 break;
231 if ((err = OpRead(fl, buffer, want, &read)) != 0)
232 res = -1;
233 else
234 res = read;
236 break;
239 case ACTION_WRITE: {
240 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
241 APTR buffer = (APTR)pkt->dp_Arg2;
242 ULONG want = pkt->dp_Arg3, written;
244 D(bug("[FAT] WRITE: lock 0x%08x (dir %ld/%ld pos %ld) want %ld\n",
245 pkt->dp_Arg1,
246 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0,
247 fl->pos,
248 want));
250 if ((err = TestLock(fl))) {
251 res = -1;
252 break;
255 if ((err = OpWrite(fl, buffer, want, &written)) != 0)
256 res = -1;
257 else
258 res = written;
260 break;
263 case ACTION_SEEK: {
264 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
265 LONG offset = pkt->dp_Arg2;
266 ULONG whence = pkt->dp_Arg3;
268 D(bug("[FAT] SEEK: lock 0x%08x (dir %ld/%ld pos %ld) offset %ld whence %s\n",
269 pkt->dp_Arg1,
270 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0,
271 fl->pos,
272 offset,
273 whence == OFFSET_BEGINNING ? "BEGINNING" :
274 whence == OFFSET_END ? "END" :
275 whence == OFFSET_CURRENT ? "CURRENT" :
276 "(unknown)"));
278 if ((err = TestLock(fl))) {
279 res = -1;
280 break;
283 res = fl->pos;
284 err = 0;
286 if (whence == OFFSET_BEGINNING &&
287 offset >= 0 &&
288 offset <= fl->gl->size)
289 fl->pos = offset;
290 else if (whence == OFFSET_CURRENT &&
291 offset + fl->pos >= 0 &&
292 offset + fl->pos <= fl->gl->size)
293 fl->pos += offset;
294 else if (whence == OFFSET_END
295 && offset <= 0
296 && fl->gl->size + offset >= 0)
297 fl->pos = fl->gl->size + offset;
298 else {
299 res = -1;
300 err = ERROR_SEEK_ERROR;
303 break;
306 case ACTION_SET_FILE_SIZE: {
307 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
308 LONG offset = pkt->dp_Arg2;
309 LONG whence = pkt->dp_Arg3;
310 LONG newsize;
312 D(bug("[FAT] SET_FILE_SIZE: lock 0x%08x (dir %ld/%ld pos %ld) offset %ld whence %s\n",
313 pkt->dp_Arg1,
314 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0,
315 fl->pos,
316 offset,
317 whence == OFFSET_BEGINNING ? "BEGINNING" :
318 whence == OFFSET_END ? "END" :
319 whence == OFFSET_CURRENT ? "CURRENT" :
320 "(unknown)"));
322 if ((err = TestLock(fl))) {
323 res = -1;
324 break;
327 if ((err = OpSetFileSize(fl, offset, whence, &newsize)) != 0)
328 res = -1;
329 else
330 res = newsize;
332 break;
335 case ACTION_END: {
336 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
338 D(bug("[FAT] END: lock 0x%08x (dir %ld/%ld)\n",
339 pkt->dp_Arg1,
340 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0));
342 if ((err = TestLock(fl)))
343 break;
345 FreeLock(fl);
347 res = DOSTRUE;
348 break;
351 case ACTION_IS_FILESYSTEM:
352 D(bug("[FAT] IS_FILESYSTEM\n"));
354 res = DOSTRUE;
355 break;
357 case ACTION_CURRENT_VOLUME: {
358 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
360 D(bug("[FAT] CURRENT_VOLUME: lock 0x%08x\n",
361 pkt->dp_Arg1));
363 res = (IPTR)((fl) ? fl->fl_Volume : ((glob->sb != NULL) ? MKBADDR(glob->sb->doslist) : BNULL));
364 break;
367 case ACTION_INFO:
368 case ACTION_DISK_INFO: {
369 struct InfoData *id;
371 if (pkt->dp_Type == ACTION_INFO) {
372 struct FileLock *fl = BADDR(pkt->dp_Arg1);
374 D(bug("[FAT] INFO: lock 0x%08x\n",
375 pkt->dp_Arg1));
377 if (fl && (glob->sb == NULL || fl->fl_Volume != MKBADDR(glob->sb->doslist))) {
378 err = ERROR_DEVICE_NOT_MOUNTED;
379 break;
382 id = BADDR(pkt->dp_Arg2);
384 else {
385 D(bug("[FAT] DISK_INFO\n"));
387 id = BADDR(pkt->dp_Arg1);
390 FillDiskInfo(id);
392 res = DOSTRUE;
393 break;
396 case ACTION_INHIBIT: {
397 LONG inhibit = pkt->dp_Arg1;
399 D(bug("[FAT] INHIBIT: %sinhibit\n",
400 inhibit == DOSTRUE ? "" : "un"));
402 if (inhibit == DOSTRUE) {
403 glob->disk_inhibited++;
404 if (glob->disk_inhibited == 1)
405 DoDiskRemove();
407 else if (glob->disk_inhibited) {
408 glob->disk_inhibited--;
409 if (glob->disk_inhibited == 0)
410 ProcessDiskChange();
413 res = DOSTRUE;
414 break;
417 case ACTION_DIE: {
418 struct FSSuper *sb;
419 struct NotifyNode *nn;
421 D(bug("[FAT] DIE\n"));
423 /* clear our message port from notification requests so DOS won't send
424 * notification-end packets to us after we're gone */
425 ForeachNode(&glob->sblist, sb) {
426 ForeachNode(&sb->info->notifies, nn) {
427 nn->nr->nr_Handler = NULL;
431 if ((glob->sb != NULL
432 && !(IsListEmpty(&glob->sb->info->locks)
433 && IsListEmpty(&glob->sb->info->notifies)))) {
435 D(bug("\tThere are remaining locks or notification "
436 "requests. Shutting down is not possible\n"));
438 err = ERROR_OBJECT_IN_USE;
439 break;
442 D(bug("\tNothing pending. Shutting down the handler\n"));
444 DoDiskRemove(); /* risky, because of async. volume remove, but works */
446 glob->quit = TRUE;
447 glob->death_packet = pkt;
448 glob->devnode->dol_Task = NULL;
450 res = DOSTRUE;
451 break;
454 #if 0
455 /* XXX AROS needs these ACTION_ headers defined in dos/dosextens.h */
457 case ACTION_GET_DISK_FSSM: {
458 D(bug("\nGot ACTION_GET_DISK_FSSM\n"));
460 res = (ULONG) glob->fssm;
461 break;
464 case ACTION_FREE_DISK_FSSM: {
465 D(bug("\nGot ACTION_FREE_DISK_FSSM\n"));
467 res = DOSTRUE;
468 break;
471 #endif
473 case ACTION_DISK_CHANGE: { /* internal */
474 struct DosList *vol = (struct DosList *)pkt->dp_Arg2;
475 struct VolumeInfo *vol_info =
476 BADDR(vol->dol_misc.dol_volume.dol_LockList);
477 ULONG type = pkt->dp_Arg3;
479 D(bug("[FAT] DISK_CHANGE [INTERNAL]\n"));
481 if (pkt->dp_Arg1 == ID_FAT_DISK) { /* security check */
483 if (AttemptLockDosList(LDF_VOLUMES|LDF_WRITE)) {
485 if (type == ACTION_VOLUME_ADD) {
486 AddDosEntry(vol);
487 UnLockDosList(LDF_VOLUMES|LDF_WRITE);
489 SendEvent(IECLASS_DISKINSERTED);
491 D(bug("\tVolume added successfuly\n"));
493 else if (type == ACTION_VOLUME_REMOVE) {
494 RemDosEntry(vol);
495 DeletePool(vol_info->mem_pool);
496 UnLockDosList(LDF_VOLUMES|LDF_WRITE);
498 SendEvent(IECLASS_DISKREMOVED);
500 D(bug("\tVolume removed successfuly.\n"));
503 FreeDosObject(DOS_STDPKT, pkt); /* cleanup */
505 pkt = NULL;
506 D(bug("Packet destroyed\n"));
509 else {
510 D(bug("\tDosList is locked\n"));
511 Delay(5);
512 PutMsg(glob->ourport, pkt->dp_Link);
513 pkt = NULL;
514 D(bug("Message moved to the end of the queue\n"));
517 else
518 err = ERROR_OBJECT_WRONG_TYPE;
520 break;
523 case ACTION_RENAME_DISK: {
524 UBYTE *name = BADDR(pkt->dp_Arg1);
526 D(bug("[FAT] RENAME_DISK: name '"); RawPutChars(AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name)); bug("'\n"));
528 if (glob->sb->doslist == NULL) {
529 err = glob->disk_inserted ? ERROR_NOT_A_DOS_DISK : ERROR_NO_DISK;
530 break;
533 while (! AttemptLockDosList(LDF_VOLUMES | LDF_WRITE))
534 ProcessPackets();
536 err = SetVolumeName(glob->sb, name);
537 UnLockDosList(LDF_VOLUMES | LDF_WRITE);
538 if (err != 0)
539 break;
541 #ifdef AROS_FAST_BPTR
542 /* ReadFATSuper() sets a null byte after the
543 * string, so this should be fine */
544 CopyMem(glob->sb->volume.name + 1, glob->sb->doslist->dol_Name,
545 glob->sb->volume.name[0] + 1);
546 #else
547 CopyMem(glob->sb->volume.name, BADDR(glob->sb->doslist->dol_Name),
548 glob->sb->volume.name[0] + 2);
549 #endif
551 SendEvent(IECLASS_DISKINSERTED);
553 res = DOSTRUE;
555 break;
558 case ACTION_DELETE_OBJECT: {
559 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1);
560 UBYTE *name = BADDR(pkt->dp_Arg2);
562 D(bug("[FAT] DELETE_OBJECT: lock 0x%08x (dir %ld/%ld) path '",
563 pkt->dp_Arg1,
564 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
565 RawPutChars(AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name)); bug("'\n"));
567 if ((err = TestLock(fl)))
568 break;
570 err = OpDeleteFile(fl, AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name));
571 if (err == 0)
572 res = DOSTRUE;
574 break;
577 case ACTION_RENAME_OBJECT: {
578 struct ExtFileLock *sfl = BADDR(pkt->dp_Arg1), *dfl = BADDR(pkt->dp_Arg3);
579 UBYTE *sname = BADDR(pkt->dp_Arg2), *dname = BADDR(pkt->dp_Arg4);
581 D(bug("[FAT] RENAME_OBJECT: srclock 0x%08x (dir %ld/%ld) name '",
582 pkt->dp_Arg1,
583 sfl != NULL ? sfl->gl->dir_cluster : 0, sfl != NULL ? sfl->gl->dir_entry : 0);
584 RawPutChars(AROS_BSTR_ADDR(sname), AROS_BSTR_strlen(sname)); bug("' destlock 0x%08x (dir %ld/%ld) name '",
585 pkt->dp_Arg3,
586 dfl != NULL ? dfl->gl->dir_cluster : 0, dfl != NULL ? dfl->gl->dir_entry : 0);
587 RawPutChars(AROS_BSTR_ADDR(dname), AROS_BSTR_strlen(dname)); bug("'\n"));
589 if ((err = TestLock(sfl)) != 0 || (err = TestLock(dfl)) != 0)
590 break;
592 err = OpRenameFile(sfl, AROS_BSTR_ADDR(sname), AROS_BSTR_strlen(sname), dfl, AROS_BSTR_ADDR(dname), AROS_BSTR_strlen(dname));
593 if (err == 0)
594 res = DOSTRUE;
596 break;
599 case ACTION_CREATE_DIR: {
600 struct ExtFileLock *fl = BADDR(pkt->dp_Arg1), *new;
601 UBYTE *name = BADDR(pkt->dp_Arg2);
603 D(bug("[FAT] CREATE_DIR: lock 0x%08x (dir %ld/%ld) name '",
604 pkt->dp_Arg1,
605 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
606 RawPutChars(AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name)); bug("'\n"));
608 if ((err = TestLock(fl)))
609 break;
611 if ((err = OpCreateDir(fl, AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name), &new)) == 0)
612 res = (IPTR)MKBADDR(new);
614 break;
617 case ACTION_SET_PROTECT: {
618 struct ExtFileLock *fl = BADDR(pkt->dp_Arg2);
619 UBYTE *name = BADDR(pkt->dp_Arg3);
620 ULONG prot = pkt->dp_Arg4;
622 D(bug("[FAT] SET_PROTECT: lock 0x%08x (dir %ld/%ld) name '", pkt->dp_Arg2,
623 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
624 RawPutChars(AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name)); bug("' prot 0x%08x\n", prot));
625 if ((err = TestLock(fl)))
626 break;
628 err = OpSetProtect(fl, AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name), prot);
630 break;
633 case ACTION_SET_DATE: {
634 struct ExtFileLock *fl = BADDR(pkt->dp_Arg2);
635 UBYTE *name = BADDR(pkt->dp_Arg3);
636 struct DateStamp *ds = (struct DateStamp *)pkt->dp_Arg4;
638 #if defined(DEBUG) && DEBUG != 0
640 struct DateTime dt;
641 char datestr[LEN_DATSTRING];
643 dt.dat_Stamp = *ds;
644 dt.dat_Format = FORMAT_DOS;
645 dt.dat_Flags = 0;
646 dt.dat_StrDay = NULL;
647 dt.dat_StrDate = datestr;
648 dt.dat_StrTime = NULL;
649 DateToStr(&dt);
651 D(bug("[FAT] SET_DATE: lock 0x%08x (dir %ld/%ld) name '",
652 pkt->dp_Arg2,
653 fl != NULL ? fl->gl->dir_cluster : 0, fl != NULL ? fl->gl->dir_entry : 0);
654 RawPutChars(AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name)); bug("' ds '%s'\n", datestr));
656 #endif
658 if ((err = TestLock(fl)))
659 break;
661 err = OpSetDate(fl, AROS_BSTR_ADDR(name), AROS_BSTR_strlen(name), ds);
663 break;
666 case ACTION_ADD_NOTIFY: {
667 struct NotifyRequest *nr = (struct NotifyRequest *)pkt->dp_Arg1;
669 D(bug("[FAT] ADD_NOTIFY: nr 0x%08x name '%s'\n", nr, nr->nr_FullName));
671 err = OpAddNotify(nr);
673 break;
676 case ACTION_REMOVE_NOTIFY: {
677 struct NotifyRequest *nr = (struct NotifyRequest *)pkt->dp_Arg1;
679 D(bug("[FAT] REMOVE_NOTIFY: nr 0x%08x name '%s'\n", nr, nr->nr_FullName));
681 err = OpRemoveNotify(nr);
683 break;
686 default:
687 D(bug("[FAT] got unknown packet type %ld\n", pkt->dp_Type));
689 err = ERROR_ACTION_NOT_KNOWN;
692 if (pkt != NULL) {
693 pkt->dp_Res1 = res;
694 pkt->dp_Res2 = err;
695 if (!glob->quit) {
696 D(bug("[FAT] replying to packet: result 0x%x, error 0x%x\n",
697 res, err));
698 ReplyPacket(pkt);
702 RestartTimer();
706 void ReplyPacket(struct DosPacket *pkt) {
707 struct MsgPort *rp;
709 rp = pkt->dp_Port;
711 pkt->dp_Port = glob->ourport;
713 PutMsg(rp, pkt->dp_Link);