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 #define AROS_ALMOST_COMPATIBLE
15 #include <exec/types.h>
17 #include <dos/notify.h>
18 #include <proto/exec.h>
21 #include "fat_protos.h"
23 #define DEBUG DEBUG_NOTIFY
26 void SendNotify(struct NotifyRequest
*nr
, struct Globals
*glob
)
28 struct NotifyMessage
*nm
;
30 D(bug("[fat] notifying for '%s'\n", nr
->nr_FullName
));
32 /* Signals are a doddle */
33 if (nr
->nr_Flags
& NRF_SEND_SIGNAL
)
35 D(bug("[fat] sending signal %ld to task 0x%08x\n",
36 nr
->nr_stuff
.nr_Signal
.nr_SignalNum
,
37 nr
->nr_stuff
.nr_Signal
.nr_Task
));
39 Signal(nr
->nr_stuff
.nr_Signal
.nr_Task
,
40 1 << nr
->nr_stuff
.nr_Signal
.nr_SignalNum
);
45 /* If message isn't set, then they screwed up, and there's nothing to do */
46 if (!(nr
->nr_Flags
& NRF_SEND_MESSAGE
))
48 D(bug("[fat] weird, request doesn't have SIGNAL or MESSAGE bits set,"
53 /* Don't send if we're supposed to wait for them to reply and there are
54 * still messages outstanding */
55 if (nr
->nr_Flags
& NRF_WAIT_REPLY
&& nr
->nr_MsgCount
> 0)
57 D(bug("[fat] request has WAIT_REPLY set and there are %ld messages"
58 " outstanding, doing nothing\n", nr
->nr_MsgCount
));
65 D(bug("[fat] request now has %ld messages outstanding\n",
68 /* Allocate and build the message */
69 nm
= AllocVec(sizeof(struct NotifyMessage
), MEMF_PUBLIC
| MEMF_CLEAR
);
70 nm
->nm_ExecMessage
.mn_ReplyPort
= glob
->notifyport
;
71 nm
->nm_ExecMessage
.mn_Length
= sizeof(struct NotifyMessage
);
72 nm
->nm_Class
= NOTIFY_CLASS
;
73 nm
->nm_Code
= NOTIFY_CODE
;
76 D(bug("[fat] sending notify message to port 0x%08x\n",
77 nr
->nr_stuff
.nr_Msg
.nr_Port
));
80 PutMsg(nr
->nr_stuff
.nr_Msg
.nr_Port
, (struct Message
*)nm
);
83 /* Send a notification for the file referenced by the passed global lock */
84 void SendNotifyByLock(struct FSSuper
*sb
, struct GlobalLock
*gl
)
86 struct Globals
*glob
= sb
->glob
;
87 struct NotifyNode
*nn
;
89 D(bug("[fat] notifying for lock (%ld/%ld)\n", gl
->dir_cluster
,
92 ForeachNode(&sb
->info
->notifies
, nn
)
94 SendNotify(nn
->nr
, glob
);
97 /* Send a notification for the file referenced by the passed dir entry */
98 void SendNotifyByDirEntry(struct FSSuper
*sb
, struct DirEntry
*de
)
100 struct Globals
*glob
= sb
->glob
;
101 struct NotifyNode
*nn
;
102 struct DirHandle sdh
;
105 /* Inside the loop we may reuse the dirhandle, so here we explicitly mark
106 it as uninitialised */
109 D(bug("[fat] notifying for dir entry (%ld/%ld)\n", de
->cluster
,
112 ForeachNode(&sb
->info
->notifies
, nn
)
116 if (nn
->gl
->dir_cluster
== de
->cluster
117 && nn
->gl
->dir_entry
== de
->index
)
118 SendNotify(nn
->nr
, glob
);
122 if (InitDirHandle(sb
, 0, &sdh
, TRUE
, glob
) != 0)
125 if (GetDirEntryByPath(&sdh
, nn
->nr
->nr_FullName
,
126 strlen(nn
->nr
->nr_FullName
), &sde
, glob
) != 0)
129 if (sde
.cluster
== de
->cluster
&& sde
.index
== de
->index
)
130 SendNotify(nn
->nr
, glob
);
132 ReleaseDirHandle(&sdh
, glob
);
137 /* Handle returned notify messages */
138 void ProcessNotify(struct Globals
*glob
)
140 struct NotifyMessage
*nm
;
142 while ((nm
= (struct NotifyMessage
*)GetMsg(glob
->notifyport
)) != NULL
)
144 if (nm
->nm_Class
== NOTIFY_CLASS
&& nm
->nm_Code
== NOTIFY_CODE
)
146 nm
->nm_NReq
->nr_MsgCount
--;
147 if (nm
->nm_NReq
->nr_MsgCount
< 0)
148 nm
->nm_NReq
->nr_MsgCount
= 0;
150 D(bug("[fat] received notify message reply,"
151 " %ld messages outstanding for this request\n",
152 nm
->nm_NReq
->nr_MsgCount
));
157 D(bug("[fat] non-notify message received, dropping it\n"));