1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - FS - libraries
3   File:     fs_proc_mem.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-12-04#$
14   $Rev: 9513 $
15   $Author: yosizaki $
16 
17  *---------------------------------------------------------------------------*/
18 
19 
20 #include <nitro/fs/romfat.h>
21 #include <nitro/fs/api.h>
22 
23 #include "../include/util.h"
24 #include "../include/command.h"
25 
26 
27 #if defined(FS_IMPLEMENT)
28 
29 /*---------------------------------------------------------------------------*/
30 /* Variables */
31 
32 // Memory mapped file archive
33 static FSArchive fsi_arc_mem;
34 static BOOL fsi_mem_init;
35 
36 
37 /*---------------------------------------------------------------------------*/
38 /* functions */
39 
40 /*---------------------------------------------------------------------------*
41   Name:         FSi_MemArchiveProc
42 
43   Description:  Memory mapped file archive procedure
44 
45   Arguments:    p_file:           FSFile structure that stores command information.
46                 cmd:              Command type.
47 
48   Returns:      Command processing result.
49  *---------------------------------------------------------------------------*/
FSi_MemArchiveProc(FSFile * p_file,FSCommandType cmd)50 static FSResult FSi_MemArchiveProc(FSFile *p_file, FSCommandType cmd)
51 {
52 #pragma unused(p_file)
53 
54     switch (cmd)
55     {
56     case FS_COMMAND_READDIR:
57         {
58             FSResult    result;
59             FSDirEntry *entry = p_file->arg.readdir.p_entry;
60             FSArchive  *current = (FSArchive *)p_file->prop.dir.pos.pos;
61             if (current == NULL)
62             {
63                 entry->name_len = 0;
64                 entry->is_directory = 0;
65                 result = FS_RESULT_FAILURE;
66             }
67             else
68             {
69                 const char *arcname = FS_GetArchiveName(current);
70                 entry->name_len = (u32)(STD_GetStringLength(arcname) + 1);
71                 entry->is_directory = TRUE;
72                 if (!p_file->arg.readdir.skip_string)
73                 {
74                     (void)STD_TSPrintf(entry->name, "%s:", arcname);
75                     entry->dir_id.arc = p_file->arc;
76                     entry->dir_id.own_id = 0;
77                     entry->dir_id.index = 0;
78                     entry->dir_id.pos = 0;
79                 }
80                 result = FS_RESULT_SUCCESS;
81                 p_file->prop.dir.pos.pos = (u32)current->next;
82             }
83             return result;
84         }
85     case FS_COMMAND_SEEKDIR:
86     case FS_COMMAND_FINDPATH:
87     case FS_COMMAND_GETPATH:
88     case FS_COMMAND_OPENFILEFAST:
89         return FS_RESULT_UNSUPPORTED;
90     default:
91         return FS_RESULT_PROC_UNKNOWN;
92     }
93 }
94 
95 /*---------------------------------------------------------------------------*
96   Name:         FSi_InitMemArchive
97 
98   Description:  Initializes a memory mapped file archive.
99 
100   Arguments:    None.
101 
102   Returns:      None.
103  *---------------------------------------------------------------------------*/
FSi_InitMemArchive(void)104 static void FSi_InitMemArchive(void)
105 {
106     OSIntrMode bak_cpsr = OS_DisableInterrupts();
107 
108     if (!fsi_mem_init || !FS_IsArchiveLoaded(&fsi_arc_mem))
109     {
110         FS_InitArchive(&fsi_arc_mem);
111         FS_SetArchiveProc(&fsi_arc_mem, FSi_MemArchiveProc, (u32)FS_ARCHIVE_PROC_ALL);
112         if (!FS_LoadArchive(&fsi_arc_mem, 0, 0, 0, 0, 0, NULL, NULL))
113         {
114             OS_TPanic("failed to load memory-mapping archive!");
115         }
116         fsi_mem_init = TRUE;
117     }
118 
119     (void)OS_RestoreInterrupts(bak_cpsr);
120 }
121 
122 /*---------------------------------------------------------------------------*
123   Name:         FS_CreateFileFromMemory
124 
125   Description:  Temporarily generates file that maps memory region.
126 
127   Arguments:    p_file:           FSFile structure that stores file handle
128                 buf:              Memory that is target of READ and WRITE
129                 size:            Byte size of buf
130 
131   Returns:      None.
132  *---------------------------------------------------------------------------*/
FS_CreateFileFromMemory(FSFile * p_file,void * buf,u32 size)133 BOOL FS_CreateFileFromMemory(FSFile *p_file, void *buf, u32 size)
134 {
135     FSi_InitMemArchive();
136     return FS_OpenFileDirect(p_file, &fsi_arc_mem, (u32)buf, (u32)buf + size, 0);
137 }
138 
139 /*---------------------------------------------------------------------------*
140   Name:         FS_OpenTopLevelDirectory
141 
142   Description:  Opens the special high-level directory that can enumerate the archive name
143 
144   Arguments:    dir:           FSFile structure that stores directory handle
145 
146   Returns:      If successful, TRUE.
147  *---------------------------------------------------------------------------*/
FS_OpenTopLevelDirectory(FSFile * dir)148 BOOL FS_OpenTopLevelDirectory(FSFile *dir)
149 {
150     FSi_InitMemArchive();
151     FS_InitFile(dir);
152     dir->prop.dir.pos.pos = (u32)FSi_GetArchiveChain();
153     FS_SetDirectoryHandle(dir, &fsi_arc_mem, &dir->prop);
154     return TRUE;
155 }
156 
157 
158 #endif /* FS_IMPLEMENT */
159