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