1 /*---------------------------------------------------------------------------*
2 Project: NitroSDK - WFS - libraries
3 File: wfs_archive.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 *---------------------------------------------------------------------------*/
14
15
16 #include <nitro/wfs/client.h>
17
18
19 /*---------------------------------------------------------------------------*/
20 /* Functions */
21
22 /*---------------------------------------------------------------------------*
23 Name: WFSi_ArchiveReadCallback
24
25 Description: Child WFS archive read access callback.
26
27 Arguments: archive: FSArchive structure
28 buffer: Transfer destination
29 offset: Transfer source
30 length: Transfer size
31
32 Returns: Process result.
33 *---------------------------------------------------------------------------*/
WFSi_ArchiveReadCallback(FSArchive * archive,void * buffer,u32 offset,u32 length)34 static FSResult WFSi_ArchiveReadCallback(FSArchive *archive, void *buffer, u32 offset, u32 length)
35 {
36 FSResult result = FS_RESULT_ERROR;
37 WFSClientContext * const context = (WFSClientContext*)FS_GetArchiveBase(archive);
38 const WFSTableFormat * const table = WFS_GetTableFormat(context);
39 if (table)
40 {
41 MI_CpuCopy8(&table->buffer[offset], buffer, length);
42 result = FS_RESULT_SUCCESS;
43 }
44 return result;
45 }
46
47 /*---------------------------------------------------------------------------*
48 Name: WFSi_ArchiveReadDoneCallback
49
50 Description: Child WFS archive read completion callback.
51
52 Arguments: context: WFSClientContext structure
53 succeeded: TRUE if the read succeeded, FALSE if it failed
54 arg: Argument specified in the callback
55
56 Returns: None.
57 *---------------------------------------------------------------------------*/
WFSi_ArchiveReadDoneCallback(WFSClientContext * context,BOOL succeeded,void * arg)58 static void WFSi_ArchiveReadDoneCallback(WFSClientContext *context, BOOL succeeded, void *arg)
59 {
60 FSFile * const file = (FSFile*)arg;
61 FSResult result = FS_RESULT_ERROR;
62 if (succeeded)
63 {
64 file->prop.file.pos += file->arg.readfile.len;
65 result = FS_RESULT_SUCCESS;
66 }
67 FS_NotifyArchiveAsyncEnd(FS_GetAttachedArchive(file), result);
68 (void)context;
69 }
70
71 /*---------------------------------------------------------------------------*
72 Name: WFSi_RomArchiveProc
73
74 Description: User procedure for a child ROM archive.
75
76 Arguments: file: FSFile structure
77 command: Command
78
79 Returns: Process result.
80 *---------------------------------------------------------------------------*/
WFSi_RomArchiveProc(FSFile * file,FSCommandType command)81 static FSResult WFSi_RomArchiveProc(FSFile *file, FSCommandType command)
82 {
83 FSResult result = FS_RESULT_ERROR;
84 switch (command)
85 {
86 case FS_COMMAND_READFILE:
87 {
88 void *buffer = file->arg.readfile.dst;
89 u32 offset = file->prop.file.pos;
90 u32 length = file->arg.readfile.len;
91 if (length == 0)
92 {
93 result = FS_RESULT_SUCCESS;
94 }
95 else
96 {
97 FSArchive * const archive = FS_GetAttachedArchive(file);
98 WFSClientContext * const context = (WFSClientContext*)FS_GetArchiveBase(archive);
99 const WFSTableFormat * const table = WFS_GetTableFormat(context);
100 if (table != NULL)
101 {
102 WFS_RequestClientRead(context, buffer, offset, length,
103 WFSi_ArchiveReadDoneCallback, file);
104 result = FS_RESULT_PROC_ASYNC;
105 }
106 }
107 }
108 break;
109 case FS_COMMAND_WRITEFILE:
110 result = FS_RESULT_UNSUPPORTED;
111 break;
112 default:
113 result = FS_RESULT_PROC_UNKNOWN;
114 break;
115 }
116 return result;
117 }
118
119 /*---------------------------------------------------------------------------*
120 Name: WFSi_EmptyArchiveProc
121
122 Description: This is an empty procedure that follows a call to WFS_EndClient().
123
124 Arguments: file: FSFile structure
125 command: Command
126
127 Returns: Processing result
128 *---------------------------------------------------------------------------*/
WFSi_EmptyArchiveProc(FSFile * file,FSCommandType command)129 static FSResult WFSi_EmptyArchiveProc(FSFile *file, FSCommandType command)
130 {
131 FSResult result = FS_RESULT_PROC_UNKNOWN;
132 // Output a warning message and generate an error for commands that cannot be ignored without causing a problem.
133 if ((command != FS_COMMAND_CLOSEFILE) &&
134 ((command < FS_COMMAND_STATUS_BEGIN) || (command >= FS_COMMAND_STATUS_END)))
135 {
136 static BOOL once = FALSE;
137 if (!once)
138 {
139 once = TRUE;
140 OS_TWarning("WFS-Client has been finalized. (all the commands will fail)\n");
141 }
142 result = FS_RESULT_ERROR;
143 }
144 (void)file;
145 return result;
146 }
147
148 /*---------------------------------------------------------------------------*
149 Name: WFSi_RestoreRomArchive
150
151 Description: This is an unmount callback invoked when WFS_EndClient() is called.
152
153 Arguments: context: WFSClientContext structure
154
155 Returns: None.
156 *---------------------------------------------------------------------------*/
WFSi_RestoreRomArchive(WFSClientContext * context)157 static void WFSi_RestoreRomArchive(WFSClientContext *context)
158 {
159 FSArchive *archive = FS_FindArchive("rom", 3);
160 (void)FS_SuspendArchive(archive);
161 FS_SetArchiveProc(archive, WFSi_EmptyArchiveProc, (u32)FS_ARCHIVE_PROC_ALL);
162 (void)FS_ResumeArchive(archive);
163 (void)context;
164 }
165
166 /*---------------------------------------------------------------------------*
167 Name: WFS_ReplaceRomArchive
168
169 Description: Mounts the WFS archive.
170
171 Arguments: context: WFSClientContext structure
172
173 Returns: None.
174 *---------------------------------------------------------------------------*/
WFS_ReplaceRomArchive(WFSClientContext * context)175 void WFS_ReplaceRomArchive(WFSClientContext *context)
176 {
177 const WFSTableFormat * const table = WFS_GetTableFormat(context);
178 if (table != NULL)
179 {
180 FSArchive *archive = FS_FindArchive("rom", 3);
181 if (FS_IsArchiveLoaded(archive))
182 {
183 (void)FS_UnloadArchive(archive);
184 }
185 FS_SetArchiveProc(archive, WFSi_RomArchiveProc, (u32)FS_ARCHIVE_PROC_ALL);
186 context->unmount_callback = WFSi_RestoreRomArchive;
187 (void)FS_LoadArchive(archive, (u32)context,
188 table->region[WFS_TABLE_REGION_FAT].offset,
189 table->region[WFS_TABLE_REGION_FAT].length,
190 table->region[WFS_TABLE_REGION_FNT].offset,
191 table->region[WFS_TABLE_REGION_FNT].length,
192 WFSi_ArchiveReadCallback, NULL);
193 FS_AttachOverlayTable(MI_PROCESSOR_ARM9,
194 table->buffer +
195 table->region[WFS_TABLE_REGION_OV9].offset,
196 table->region[WFS_TABLE_REGION_OV9].length);
197 FS_AttachOverlayTable(MI_PROCESSOR_ARM7,
198 table->buffer +
199 table->region[WFS_TABLE_REGION_OV7].offset,
200 table->region[WFS_TABLE_REGION_OV7].length);
201 }
202 }
203
204
205 /*---------------------------------------------------------------------------*
206 $Log: wfs_archive.c,v $
207 Revision 1.1 2007/06/11 06:38:39 yosizaki
208 Initial upload.
209
210 $NoKeywords: $
211 *---------------------------------------------------------------------------*/
212