1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - FS - libraries
3 File: fs_hook.c
4
5 Copyright 2007-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16
17 *---------------------------------------------------------------------------*/
18
19 #include <nitro/fs/archive.h>
20 #include <nitro/fs/hook.h>
21 #include <nitro/card/common.h>
22 #include <nitro/std/string.h>
23 #ifdef SDK_TWL
24 #include <twl/fatfs/common/types.h>
25 #endif // SDK_TWL
26
27 /*---------------------------------------------------------------------------*/
28 /* Variables */
29
30 // Event hook management information
31 typedef struct FSEventHookContext
32 {
33 FSEventHook *chain;
34 CARDHookContext hook[1];
35 }
36 FSEventHookContext;
37
38 static FSEventHookContext FSiEventHookStaticWork[1];
39
40
41 /*---------------------------------------------------------------------------*/
42 /* functions */
43
44 /*---------------------------------------------------------------------------*
45 Name: FSi_SystemEvents
46
47 Description: System event monitoring callback
48
49 Arguments: userdata Any user-defined data
50 event Occurred event
51 argument Argument for each event
52
53 Returns: None.
54 *---------------------------------------------------------------------------*/
FSi_SystemEvents(void * userdata,CARDEvent event,void * argument)55 static void FSi_SystemEvents(void *userdata, CARDEvent event, void *argument)
56 {
57 FSEventHookContext *context = (FSEventHookContext*)userdata;
58 FSArchive *target = NULL;
59 FSEvent fsevent = FS_EVENT_NONE;
60 (void)argument;
61 // Convert entire media event of the system to each archive event.
62 if (event == CARD_EVENT_SLOTRESET)
63 {
64 target = FS_FindArchive("rom", 3);
65 fsevent = FS_EVENT_MEDIA_INSERTED;
66 }
67 else if (event == CARD_EVENT_PULLEDOUT)
68 {
69 target = FS_FindArchive("rom", 3);
70 fsevent = FS_EVENT_MEDIA_REMOVED;
71 }
72 #ifdef SDK_TWL
73 else if (event == FATFS_EVENT_SD_INSERTED)
74 {
75 target = FS_FindArchive("sdmc", 4);
76 fsevent = FS_EVENT_MEDIA_INSERTED;
77 }
78 else if (event == FATFS_EVENT_SD_REMOVED)
79 {
80 target = FS_FindArchive("sdmc", 4);
81 fsevent = FS_EVENT_MEDIA_REMOVED;
82 }
83 #endif // SDK_TWL
84 if (fsevent != FS_EVENT_NONE)
85 {
86 FSEventHook **pp = &context->chain;
87 while (*pp != NULL)
88 {
89 FSEventHook *hook = *pp;
90 if ((hook->arc == target) && (hook->callback != NULL))
91 {
92 (*hook->callback)(hook->userdata, fsevent, argument);
93 }
94 if (*pp == hook)
95 {
96 pp = &(*pp)->next;
97 }
98 }
99 }
100 }
101
102 /*---------------------------------------------------------------------------*
103 Name: FS_RegisterEventHook
104
105 Description: Registers the hook for events in the archive
106
107 Arguments: arcname Archive of the register target �o�^�Ώۂ̃A�[�J�C�u
108 hook FSEventHook structure to register
109 callback Callback function when an event occurs
110 userdata Arbitrary user defined data (if not necessary, NULL)
111
112 Returns: None.
113 *---------------------------------------------------------------------------*/
FS_RegisterEventHook(const char * arcname,FSEventHook * hook,FSEventFunction callback,void * userdata)114 void FS_RegisterEventHook(const char *arcname, FSEventHook *hook, FSEventFunction callback, void *userdata)
115 {
116 FSEventHookContext *context = FSiEventHookStaticWork;
117 OSIntrMode bak = OS_DisableInterrupts();
118 FSArchive *arc = FS_FindArchive(arcname, STD_GetStringLength(arcname));
119 if (arc)
120 {
121 // If not explicitly used, consider so that the hook feature is not linked
122 if (!context->hook->callback)
123 {
124 CARDi_RegisterHook(context->hook, FSi_SystemEvents, context);
125 }
126 hook->callback = callback;
127 hook->userdata = userdata;
128 hook->arc = arc;
129 hook->next = context->chain;
130 context->chain = hook;
131 }
132 (void)OS_RestoreInterrupts(bak);
133 }
134
135 /*---------------------------------------------------------------------------*
136 Name: FS_UnregisterEventHook
137
138 Description: Releases the hook for events in the registered archive.
139
140 Arguments: hook Registered FSEventHook structure
141
142 Returns: None.
143 *---------------------------------------------------------------------------*/
FS_UnregisterEventHook(FSEventHook * hook)144 void FS_UnregisterEventHook(FSEventHook *hook)
145 {
146 FSEventHookContext *context = FSiEventHookStaticWork;
147 OSIntrMode bak = OS_DisableInterrupts();
148 FSEventHook **pp;
149 for (pp = &context->chain; *pp; pp = &(*pp)->next)
150 {
151 if (*pp == hook)
152 {
153 *pp = (*pp)->next;
154 break;
155 }
156 }
157 (void)OS_RestoreInterrupts(bak);
158 }
159