1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - FS - libraries
3   File:     archive.h
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 
20 #ifndef NITRO_FS_ARCHIVE_H_
21 #define NITRO_FS_ARCHIVE_H_
22 
23 
24 #include <nitro/fs/types.h>
25 #include <nitro/fs/romfat.h>
26 #include <nitro/os/common/thread.h>
27 
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 
34 /*---------------------------------------------------------------------------*/
35 /* Declarations */
36 
37 // Archive command interface
38 typedef struct FSArchiveInterface
39 {
40     // Commands that are compatible with the old specifications
41     FSResult (*ReadFile)(struct FSArchive*, struct FSFile*, void *buffer, u32 *length);
42     FSResult (*WriteFile)(struct FSArchive*, struct FSFile*, const void *buffer, u32 *length);
43     FSResult (*SeekDirectory)(struct FSArchive*, struct FSFile*, u32 id, u32 position);
44     FSResult (*ReadDirectory)(struct FSArchive*, struct FSFile*, FSDirectoryEntryInfo *info);
45     FSResult (*FindPath)(struct FSArchive*, u32 base_dir_id, const char *path, u32 *target_id, BOOL target_is_directory);
46     FSResult (*GetPath)(struct FSArchive*, struct FSFile*, BOOL is_directory, char *buffer, u32 *length);
47     FSResult (*OpenFileFast)(struct FSArchive*, struct FSFile*, u32 id, u32 mode);
48     FSResult (*OpenFileDirect)(struct FSArchive*, struct FSFile*, u32 top, u32 bottom, u32 *id);
49     FSResult (*CloseFile)(struct FSArchive*, struct FSFile*);
50     void (*Activate)(struct FSArchive*);
51     void (*Idle)(struct FSArchive*);
52     void (*Suspend)(struct FSArchive*);
53     void (*Resume)(struct FSArchive*);
54     // New commands that are compatible with the old specifications
55     FSResult (*OpenFile)(struct FSArchive*, struct FSFile*, u32 base_dir_id, const char *path, u32 mode);
56     FSResult (*SeekFile)(struct FSArchive*, struct FSFile*, int *offset, FSSeekFileMode from);
57     FSResult (*GetFileLength)(struct FSArchive*, struct FSFile*, u32 *length);
58     FSResult (*GetFilePosition)(struct FSArchive*, struct FSFile*, u32 *position);
59     // Extended commands in the new specifications
60     void (*Mount)(struct FSArchive*);
61     void (*Unmount)(struct FSArchive*);
62     FSResult (*GetArchiveCaps)(struct FSArchive*, u32 *caps);
63     FSResult (*CreateFile)(struct FSArchive*, u32 baseid, const char *relpath, u32 permit);
64     FSResult (*DeleteFile)(struct FSArchive*, u32 baseid, const char *relpath);
65     FSResult (*RenameFile)(struct FSArchive*, u32 baseid_src, const char *relpath_src, u32 baseid_dst, const char *relpath_dst);
66     FSResult (*GetPathInfo)(struct FSArchive*, u32 baseid, const char *relpath, FSPathInfo *info);
67     FSResult (*SetPathInfo)(struct FSArchive*, u32 baseid, const char *relpath, FSPathInfo *info);
68     FSResult (*CreateDirectory)(struct FSArchive*, u32 baseid, const char *relpath, u32 permit);
69     FSResult (*DeleteDirectory)(struct FSArchive*, u32 baseid, const char *relpath);
70     FSResult (*RenameDirectory)(struct FSArchive*, u32 baseid, const char *relpath_src, u32 baseid_dst, const char *relpath_dst);
71     FSResult (*GetArchiveResource)(struct FSArchive*, FSArchiveResource *resource);
72     void   *unused_29;
73     FSResult (*FlushFile)(struct FSArchive*, struct FSFile*);
74     FSResult (*SetFileLength)(struct FSArchive*, struct FSFile*, u32 length);
75     FSResult (*OpenDirectory)(struct FSArchive*, struct FSFile*, u32 base_dir_id, const char *path, u32 mode);
76     FSResult (*CloseDirectory)(struct FSArchive*, struct FSFile*);
77     FSResult (*SetSeekCache)(struct FSArchive*, struct FSFile*, void* buf, u32 buf_size);
78     // Reserved for future extensions
79     u8      reserved[116];
80 }
81 FSArchiveInterface;
82 
83 SDK_COMPILER_ASSERT(sizeof(FSArchiveInterface) == 256);
84 
85 
86 typedef struct FSArchive
87 {
88 // private:
89 
90     // A unique name to identify the archive.
91     // It uses 1-3 alphanumeric characters and is case insensitive.
92     union
93     {
94         char    ptr[FS_ARCHIVE_NAME_LEN_MAX + 1];
95         u32     pack;
96     }
97     name;
98     struct FSArchive   *next;       // Archive registration list
99     struct FSFile      *list;       // Process wait command list
100     OSThreadQueue       queue;      // General-purpose queue to wait for events
101     u32                 flag;       // Internal status flags (FS_ARCHIVE_FLAG_*)
102     FSCommandType       command;    // The most recent command
103     FSResult            result;     // The most recent processing result
104     void               *userdata;   // User-defined pointer
105     const FSArchiveInterface *vtbl; // Command interface
106 
107     union
108     {
109         // Data that can be freely used in user-defined archives
110         u8      reserved2[52];
111         // Data to use in ROMFAT archives (maintained for compatibility)
112         struct  FS_ROMFAT_CONTEXT_DEFINITION();
113     };
114 }
115 FSArchive;
116 
117 // NITRO-SDK compatibility is taken seriously; at the moment, it strictly forbidden to change the size.
118 SDK_COMPILER_ASSERT(sizeof(FSArchive) == 92);
119 
120 
121 /*---------------------------------------------------------------------------*/
122 /* Functions */
123 
124 /*---------------------------------------------------------------------------*
125   Name:         FS_FindArchive
126 
127   Description:  Searches for an archive name.
128                 Returns NULL if there is no matching name.
129 
130   Arguments:    name: String with the archive name to search for
131                 name_len: Length of the 'name' string
132 
133   Returns:      Pointer to the archive that was found, or NULL.
134  *---------------------------------------------------------------------------*/
135 FSArchive *FS_FindArchive(const char *name, int name_len);
136 
137 /*---------------------------------------------------------------------------*
138   Name:         FS_NormalizePath
139 
140   Description:  Normalizes the specified path name with the current directory, as follows: (archive pointer) + (base directory ID) + (path name).
141 
142 
143 
144   Arguments:    path:        Non-normalized path string.
145                 baseid: Location to store the base directory ID, or NULL
146                 relpath: Location to store the converted path name, or NULL
147 
148   Returns:      An archive pointer or NULL.
149  *---------------------------------------------------------------------------*/
150 FSArchive* FS_NormalizePath(const char *path, u32 *baseid, char *relpath);
151 
152 /*---------------------------------------------------------------------------*
153   Name:         FS_GetCurrentDirectory
154 
155   Description:  Gets the current directory as a path name.
156 
157   Arguments:    None.
158 
159   Returns:      String that indicates the current directory.
160  *---------------------------------------------------------------------------*/
161 const char *FS_GetCurrentDirectory(void);
162 
163 /*---------------------------------------------------------------------------*
164   Name:         FS_GetLastArchiveCommand
165 
166   Description:  Gets the most recent command processed by an archive.
167 
168   Arguments:    arc: FSArchive structure
169 
170   Returns:      The result of the most recent command processed by the archive.
171  *---------------------------------------------------------------------------*/
FS_GetLastArchiveCommand(const FSArchive * arc)172 SDK_INLINE FSCommandType FS_GetLastArchiveCommand(const FSArchive *arc)
173 {
174     return arc->command;
175 }
176 
177 /*---------------------------------------------------------------------------*
178   Name:         FS_GetArchiveResultCode
179 
180   Description:  Gets the most recent error code for the specified archive.
181 
182   Arguments:    path_or_archive: The FSArchive structure or path string that indicates the target archive.
183 
184 
185   Returns:      The most recent error code for the specified archive.
186                 FS_RESULT_ERROR when the applicable archive does not exist.
187  *---------------------------------------------------------------------------*/
188 FSResult FS_GetArchiveResultCode(const void *path_or_archive);
189 
190 /*---------------------------------------------------------------------------*
191   Name:         FSi_EndArchive
192 
193   Description:  Shuts down and releases all archives.
194 
195   Arguments:    None.
196 
197   Returns:      None.
198  *---------------------------------------------------------------------------*/
199 void    FSi_EndArchive(void);
200 
201 /*---------------------------------------------------------------------------*
202   Name:         FS_InitArchive
203 
204   Description:  Initialize archive structure
205 
206   Arguments:    arc: Archive to initialize.
207 
208   Returns:      None.
209  *---------------------------------------------------------------------------*/
210 void    FS_InitArchive(FSArchive *arc);
211 
212 /*---------------------------------------------------------------------------*
213   Name:         FS_GetArchiveName
214 
215   Description:  Acquire archive name
216 
217   Arguments:    arc: Archive from which to get a name
218 
219   Returns:      The archive name registered in the file system.
220  *---------------------------------------------------------------------------*/
221 const char *FS_GetArchiveName(const FSArchive *arc);
222 
223 /*---------------------------------------------------------------------------*
224   Name:         FS_IsArchiveLoaded
225 
226   Description:  Determines whether the archive is completely loaded into the the current file system
227 
228   Arguments:    arc: Archive to check
229 
230   Returns:      TRUE if it has already been loaded into the file system.
231  *---------------------------------------------------------------------------*/
FS_IsArchiveLoaded(volatile const FSArchive * arc)232 SDK_INLINE BOOL FS_IsArchiveLoaded(volatile const FSArchive *arc)
233 {
234     return ((arc->flag & FS_ARCHIVE_FLAG_LOADED) != 0);
235 }
236 
237 /*---------------------------------------------------------------------------*
238   Name:         FS_IsArchiveSuspended
239 
240   Description:  Determines whether the archive is currently suspended.
241 
242   Arguments:    arc: Archive to check
243 
244   Returns:      TRUE if it is currently suspended.
245  *---------------------------------------------------------------------------*/
FS_IsArchiveSuspended(volatile const FSArchive * arc)246 SDK_INLINE BOOL FS_IsArchiveSuspended(volatile const FSArchive *arc)
247 {
248     return ((arc->flag & FS_ARCHIVE_FLAG_SUSPEND) != 0);
249 }
250 
251 /*---------------------------------------------------------------------------*
252   Name:         FS_GetArchiveUserData
253 
254   Description:  Gets the user-defined pointer associated with an archive.
255 
256   Arguments:    arc: FSArchive structure
257 
258   Returns:      User-defined pointer
259  *---------------------------------------------------------------------------*/
FS_GetArchiveUserData(const FSArchive * arc)260 SDK_INLINE void* FS_GetArchiveUserData(const FSArchive *arc)
261 {
262     return arc->userdata;
263 }
264 
265 /*---------------------------------------------------------------------------*
266   Name:         FS_RegisterArchiveName
267 
268   Description:  Registers and associates an archive name with the file system.
269                 The archive itself is still not loaded into the file system.
270                 The archive name "rom" is reserved by the file system.
271 
272   Arguments:    arc: Archive to associate with the name
273                 name: String of the name to register
274                 name_len: Length of the 'name' string
275 
276   Returns:      None.
277  *---------------------------------------------------------------------------*/
278 BOOL    FS_RegisterArchiveName(FSArchive *arc, const char *name, u32 name_len);
279 
280 /*---------------------------------------------------------------------------*
281   Name:         FS_ReleaseArchiveName
282 
283   Description:  Releases a registered archive name.
284 
285   Arguments:    arc: Archive with a name to release
286 
287   Returns:      None.
288  *---------------------------------------------------------------------------*/
289 void    FS_ReleaseArchiveName(FSArchive *arc);
290 
291 /*---------------------------------------------------------------------------*
292   Name:         FS_MountArchive
293 
294   Description:  Mounts an archive.
295 
296   Arguments:    arc: Archive to mount
297                 userdata: User-defined variable to associate with the archive
298                 vtbl: Command interface
299                 reserved: Reserved for future use (always specify 0)
300 
301 
302   Returns:      TRUE if it was mounted successfully.
303  *---------------------------------------------------------------------------*/
304 BOOL    FS_MountArchive(FSArchive *arc, void *userdata,
305                         const FSArchiveInterface *vtbl, u32 reserved);
306 
307 /*---------------------------------------------------------------------------*
308   Name:         FS_UnmountArchive
309 
310   Description:  Unmounts an archive.
311 
312   Arguments:    arc: Archive to unmount
313 
314   Returns:      TRUE if it was unmounted successfully.
315  *---------------------------------------------------------------------------*/
316 BOOL    FS_UnmountArchive(FSArchive *arc);
317 
318 /*---------------------------------------------------------------------------*
319   Name:         FS_SuspendArchive
320 
321   Description:  Stops the archive processing mechanism itself.
322                 This will wait for running processes to complete.
323 
324   Arguments:    arc: Archive to stop
325 
326   Returns:      TRUE if it was not suspended before the function call.
327  *---------------------------------------------------------------------------*/
328 BOOL    FS_SuspendArchive(FSArchive *arc);
329 
330 /*---------------------------------------------------------------------------*
331   Name:         FS_ResumeArchive
332 
333   Description:  Resumes suspended archive processing.
334 
335   Arguments:    arc: Archive to resume
336 
337   Returns:      TRUE if it was not suspended before the function call.
338  *---------------------------------------------------------------------------*/
339 BOOL    FS_ResumeArchive(FSArchive *arc);
340 
341 /*---------------------------------------------------------------------------*
342   Name:         FS_NotifyArchiveAsyncEnd
343 
344   Description:  This is called from the archive implementation to send a notification when asynchronous archive processing is complete.
345 
346 
347   Arguments:    arc: Archive for which to send a notification of completion
348                 ret: Processing result
349 
350   Returns:      None.
351  *---------------------------------------------------------------------------*/
352 void    FS_NotifyArchiveAsyncEnd(FSArchive *arc, FSResult ret);
353 
354 
355 /*---------------------------------------------------------------------------*/
356 
357 
358 #ifdef __cplusplus
359 } /* extern "C" */
360 #endif
361 
362 
363 #endif /* NITRO_FS_ARCHIVE_H_ */
364