2 * fat.handler - FAT12/16/32 filesystem handler
4 * Copyright © 2006 Marek Szyprowski
5 * Copyright © 2007-2008 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
) {
27 struct NotifyMessage
*nm
;
29 D(bug("[fat] notifying for '%s'\n", nr
->nr_FullName
));
31 /* signals are a doddle */
32 if (nr
->nr_Flags
& NRF_SEND_SIGNAL
) {
33 D(bug("[fat] sending signal %ld to task 0x%08x\n", nr
->nr_stuff
.nr_Signal
.nr_SignalNum
, nr
->nr_stuff
.nr_Signal
.nr_Task
));
35 Signal(nr
->nr_stuff
.nr_Signal
.nr_Task
, 1 << nr
->nr_stuff
.nr_Signal
.nr_SignalNum
);
40 /* if message isn't set, then they screwed up, and there's nothing to do */
41 if (!(nr
->nr_Flags
& NRF_SEND_MESSAGE
)) {
42 D(bug("[fat] weird, request doesn't have SIGNAL or MESSAGE bits set, doing nothing\n"));
46 /* don't send if we're supposed to wait for them to reply and there's
47 * still messages outstanding */
48 if (nr
->nr_Flags
& NRF_WAIT_REPLY
&& nr
->nr_MsgCount
> 0) {
49 D(bug("[fat] request has WAIT_REPLY set and there are %ld messages outstanding, doing nothing\n", nr
->nr_MsgCount
));
56 D(bug("[fat] request now has %ld messages outstanding\n", nr
->nr_MsgCount
));
58 /* allocate and build the message */
59 nm
= AllocVec(sizeof(struct NotifyMessage
), MEMF_PUBLIC
| MEMF_CLEAR
);
60 nm
->nm_ExecMessage
.mn_ReplyPort
= glob
->notifyport
;
61 nm
->nm_ExecMessage
.mn_Length
= sizeof(struct NotifyMessage
);
62 nm
->nm_Class
= NOTIFY_CLASS
;
63 nm
->nm_Code
= NOTIFY_CODE
;
66 D(bug("[fat] sending notify message to port 0x%08x\n", nr
->nr_stuff
.nr_Msg
.nr_Port
));
69 PutMsg(nr
->nr_stuff
.nr_Msg
.nr_Port
, (struct Message
*) nm
);
72 /* send a notification for the file referenced by the passed global lock */
73 void SendNotifyByLock(struct FSSuper
*sb
, struct GlobalLock
*gl
) {
74 struct NotifyNode
*nn
;
76 D(bug("[fat] notifying for lock (%ld/%ld)\n", gl
->dir_cluster
, gl
->dir_entry
));
78 ForeachNode(&sb
->info
->notifies
, nn
)
83 /* send a notification for the file referenced by the passed dir entry */
84 void SendNotifyByDirEntry(struct FSSuper
*sb
, struct DirEntry
*de
) {
85 struct NotifyNode
*nn
;
89 /* Inside the loop we may reuse the dirhandle, so here we explicitly mark it
93 D(bug("[fat] notifying for dir entry (%ld/%ld)\n", de
->cluster
, de
->index
));
95 ForeachNode(&sb
->info
->notifies
, nn
)
97 if (nn
->gl
->dir_cluster
== de
->cluster
&& nn
->gl
->dir_entry
== de
->index
)
102 if (InitDirHandle(sb
, 0, &sdh
, TRUE
) != 0)
105 if (GetDirEntryByPath(&sdh
, nn
->nr
->nr_FullName
, strlen(nn
->nr
->nr_FullName
), &sde
) != 0)
108 if (sde
.cluster
== de
->cluster
&& sde
.index
== de
->index
)
111 ReleaseDirHandle(&sdh
);
115 /* handle returned notify messages */
116 void ProcessNotify(void) {
117 struct NotifyMessage
*nm
;
119 while ((nm
= (struct NotifyMessage
*) GetMsg(glob
->notifyport
)) != NULL
)
121 if (nm
->nm_Class
== NOTIFY_CLASS
&& nm
->nm_Code
== NOTIFY_CODE
) {
122 nm
->nm_NReq
->nr_MsgCount
--;
123 if (nm
->nm_NReq
->nr_MsgCount
< 0)
124 nm
->nm_NReq
->nr_MsgCount
= 0;
126 D(bug("[fat] received notify message reply, %ld messages outstanding for this request\n", nm
->nm_NReq
->nr_MsgCount
));
132 D(bug("[fat] non-notify message received, dropping it\n"));