1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fs_FileSystemBase.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  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   $Rev: 34216 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FS_CTR_MPCORE_FS_FILESYSTEMBASE_H_
17 #define NN_FS_CTR_MPCORE_FS_FILESYSTEMBASE_H_
18 
19 #include <nn/Handle.h>
20 #include <nn/fs/CTR/MPCore/fs_UserFileSystem.h>
21 
22 namespace nn { namespace fs { namespace detail {
23 
24 class FileSystemBaseImpl : public nn::fs::CTR::MPCore::detail::UserFileSystem
25 {
26 };
27 
28 }}}
29 
30 namespace nn { namespace fs {
31 
32 //----------------------------------------
33 //! @name ROM アーカイブ
34 //@{
35 
36 /*!
37     @brief      rom アーカイブのマウントに必要なメモリサイズを取得します。
38 
39                 ビルド時に生成される ROMFS を参照する rom アーカイブのマウントに必要なメモリサイズを計算して返します。@n
40                 このサイズは、maxFile で指定される数のファイルと、maxDirectory で指定される数のディレクトリを同時に開くことがで
41                 きるだけのメモリのサイズが返されます。@n
42                 useCache を true に設定することで、ROMFS のメタデータをメモリにキャッシュするのに必要なメモリサイズも含まれるよ
43                 うになります。
44 
45     @param[in] maxFile          同時に開くファイルの最大数
46     @param[in] maxDirectory     同時に開くディレクトリの最大数
47     @param[in] useCache         メタ情報をメモリにキャッシュするなら true、しないなら false
48 
49     @return     計算したメモリサイズを返します。rom アーカイブをマウントすることができない状態の場合、0 を返します。
50 */
51 s32 GetRomRequiredMemorySize(size_t maxFile, size_t maxDirectory, bool useCache = true);
52 
53 /*!
54     @brief      rom アーカイブをマウントします。
55 
56                 ビルド時に生成される ROMFS を参照する rom アーカイブをマウントします。@n
57                 rom アーカイブに対し、maxFile で指定された数のファイルを同時に開くことができ、maxDirectory で指定された数のディ
58                 レクトリを同時に開けるようになります。@n
59 
60                 workingMemory で渡される領域は、@ref GetRomRequiredMemorySize 関数で計算されたサイズ以上である必要があります。@n
61                 useCache を true に設定することで、ROMFS のメタデータをメモリにキャッシュします。これにより、ファイルを開いたり、
62                 ディレクトリの走査をするのにかかる時間が短縮されます。但し、必要なメモリサイズは増加します。
63 
64     @param[in] archiveName          アーカイブ名を指定します(省略するオーバロードでは "rom:" が暗黙的に指定されます)
65     @param[in] maxFile              同時に開くファイルの最大数
66     @param[in] maxDirectory         同時に開くディレクトリの最大数
67     @param[in] workingMemory        rom アーカイブの動作に使用するメモリ領域の先頭アドレス
68     @param[in] workingMemorySize    rom アーカイブの動作に使用するメモリ領域のサイズ
69     @param[in] useCache             メタ情報をメモリにキャッシュするなら true、しないなら false
70 
71     @return 処理の結果を返します。
72     @retval 成功                    処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
73     @retval ResultNotFound          ROMFS が存在しません。RSF ファイルが正しく記述されているか確かめてください。@n
74                                     製品では発生しないようにするべきエラーです。
75     @retval ResultAlreadyExists     指定したアーカイブ名は、既にマウントされています。@n
76                                     製品では発生しないようにするべきエラーです。
77     @retval ResultNotEnoughSpace    workingMemory に指定したメモリのサイズが足りません。@n
78                                     製品では発生しないようにするべきエラーです。
79     @retval 上記以外                想定外のエラー、もしくは致命的なエラーが発生しました。
80 */
81 Result MountRom(const char* archiveName, size_t maxFile, size_t maxDirectory, void* workingMemory, size_t workingMemorySize, bool useCache = true);
82 Result MountRom(size_t maxFile, size_t maxDirectory, void* workingMemory, size_t workingMemorySize, bool useCache = true);
83 
84 //@}
85 
86 //----------------------------------------
87 //! @name セーブデータアーカイブ
88 //@{
89 
90 /*!
91     @brief      セーブデータ領域をフォーマットします。
92 
93                 アプリケーション固有の領域であるセーブデータ領域をフォーマットします。この関数を呼ぶと、既存のセーブデータがあっ
94                 た場合には消去されます。
95 
96                 フォーマットの際には、このセーブデータ領域が持つことのできるファイルの最大数と、ディレクトリの最大数を指定する
97                 ことができます。この数を超えて、ファイルやディレクトリを作成することはできませんので注意してください。
98 
99                 isDuplicateAll を true にしてフォーマットした場合、セーブデータをアンマウントする前に必ず @ref CommitSaveData
100                 を呼び出してください。
101 
102     @param[in] maxFiles         ファイルの最大数を指定します
103     @param[in] maxDirectories   ディレクトリの最大数を指定します
104     @param[in] isDuplicateAll   セーブデータ領域全体を二重化するかどうかを指定します
105 
106     @return 処理の結果を返します。
107     @retval 成功                    処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
108     @retval ResultNotEnoughSpace    セーブデータのサイズに対して、maxFiles, maxDirectories の値が大きすぎます。@n
109                                     製品では発生しないようにするべきエラーです。
110     @retval 上記以外                想定外のエラー、もしくは致命的なエラーが発生しました。
111 */
112 Result FormatSaveData(size_t maxFiles, size_t maxDirectories, bool isDuplicateAll = false);
113 
114 /*!
115     @brief      セーブデータアーカイブをマウントします。
116 
117                 アプリケーション固有の領域であるセーブデータ領域を、指定されたアーカイブ名でマウントします。セーブデータ領域を
118                 使用する前には、セーブデータ領域をフォーマットする必要があります。
119 
120                 この関数を呼んだ際には必ず戻り値の判定を行い、セーブデータ領域が不正な状態でないか判断をしてください。不正な状
121                 態の場合は、@ref FormatSaveData を呼び出してセーブデータ領域の初期化をしてください。その後、もう一度この関数を
122                 呼び出してマウントしてください。
123 
124     @param[in] archiveName      アーカイブ名を指定します(省略した際は "data:" が指定されます)
125 
126     @return 処理の結果を返します。
127     @retval 成功                        処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
128     @retval ResultAlreadyExists         指定したアーカイブ名は、既にマウントされています。@n
129                                         製品では発生しないようにするべきエラーです。
130     @retval ResultNotFormatted          フォーマットされていません。@ref FormatSaveData を呼び出してフォーマットしてください。
131     @retval ResultBadFormat             不正なフォーマットです。@ref FormatSaveData を呼び出してフォーマットしてください。
132     @retval ResultVerificationFailed    検証に失敗、または改竄を検出しました。@ref FormatSaveData を呼び出してフォーマットしてください。
133     @retval 上記以外                    アプリケーション側の不具合、もしくは想定外のエラーです。
134 */
135 Result MountSaveData(const char* archiveName = "data:");
136 
137 /*!
138     @brief      セーブデータの変更をコミットします。
139 
140                 指定のアーカイブ名でマウントされたセーブデータ領域をコミットし、セーブデータへの変更を確実なものとします。@n
141                 この関数を呼ばずにアーカイブをアンマウントしたり、プログラムが停止した場合、前回のコミットからこれまでのセーブ
142                 データへの変更は全て巻き戻されます。
143 
144                 この関数が正常に返ってきた場合、セーブデータへの変更が正しく行われたことが保障されます。この関数の実行中にプロ
145                 グラムが中断した場合のセーブデータの状態は、「以前コミットが行われた状態か」もしくは「全ての変更が反映された状
146                 態」のどちらかになります。破損したり、中途半端な状態になることはありません。
147 
148     @param[in] archiveName      アーカイブ名を指定します(省略した際は "data:" が指定されます)
149 
150     @return 処理の結果を返します。
151     @retval 成功                処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
152     @retval ResultNotFound      指定したアーカイブはマウントされていません。@n
153                                 製品では発生しないようにするべきエラーです。
154     @retval 上記以外            アプリケーション側の不具合、もしくは想定外のエラーです。
155 */
156 Result CommitSaveData(const char* archiveName = "data:");
157 
158 //@}
159 
160 //----------------------------------------
161 //! @name 拡張セーブデータアーカイブ
162 //@{
163 
164 /*!
165     @brief      拡張セーブデータ領域を作成します。
166 
167                 id に対応した拡張セーブデータ領域を作成します。引数の拡張セーブデータ ID には、RSF で指定した拡張セーブデータ番
168                 号を指定してください。
169 
170                 この関数を呼ぶ前には必ず @ref MountExtSaveData を呼び出して、すでに同じ ID の領域が作成されていないか確認を行っ
171                 てください。フォーマットを行う場合は、@ref DeleteExtSaveData を呼び出して削除を行なった後、この関数を呼び出して
172                 ください。
173 
174                 アイコンデータには、ctr_makebunner32 により出力された icn ファイルを指定してください。
175 
176                 拡張セーブデータを作り直さない限り、ここで指定したディレクトリ数、ファイル数、データサイズを超えた書き込みは行
177                 うことができません。拡張的な使用を行う場合は注意してください。
178 
179                 拡張セーブデータ上に作られるファイルは、サイズ変更が不可です。よって @ref FileStream::TryInitialize などでファ
180                 イルを作成することができません。ファイルを作成するときは、サイズ指定が可能な @ref TryCreateFile を使用してくだ
181                 さい。
182 
183     @param[in]  id              拡張セーブデータの ID を指定します。
184     @param[in]  iconData        アイコンデータを指定します。
185     @param[in]  iconDataSize    アイコンデータのサイズを指定します。
186     @param[in]  entryDirectory  この拡張セーブデータ領域に格納したいディレクトリ数を指定します。
187     @param[in]  entryFile       この拡張セーブデータ領域に格納したいファイル数を指定します。
188 
189     @return 処理の結果を返します。
190     @retval 成功                        処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
191     @retval ResultMediaNotFound         SD カードが見つからないか、もしくは認識できません。@n
192     @retval ResultNotEnoughSpace        SD カードに必要な空き容量がありません。
193     @retval ResultArchiveInvalidated    作成中に SD カードが抜かれた可能性があります。
194     @retval ResultWriteProtected        SD カードが書き込み禁止になっています。
195     @retval ResultMediaAccessError      接触不良などの要因により、SD カードアクセス中にエラーが発生しました。
196     @retval ResultNotFormatted          エラーにより、作成が中断されました。この状態でマウントを行うと同じエラーが返ります。
197     @retval ResultBadFormat             SD カードのフォーマットが不正です。SD カードをフォーマットする必要があります。
198     @retval 上記以外                    アプリケーション側の不具合、もしくは想定外のエラーです。
199 */
200 Result CreateExtSaveData(nn::fs::ExtSaveDataId id, const void* iconData, size_t iconDataSize, u32 entryDirectory, u32 entryFile);
201 
202 /*!
203     @brief      拡張セーブデータをマウントします。
204 
205                 指定した拡張セーブデータ ID の拡張セーブデータ領域を、アーカイブとしてマウントします。
206 
207                 この関数を呼んだ際には必ず戻り値の判定を行い、拡張セーブデータ領域が不正な状態でないか判断をしてください。不正
208                 な状態の場合は、@ref DeleteExtSaveData を呼び出して削除を行なった後、@ref CreateExtSaveData 関数を呼び出して拡
209                 張セーブデータ領域を作り直してください。その後、もう一度この関数を呼び出してマウントしてください。
210 
211                 この関数は、メタ情報と実データの間に食い違いが生じている場合に、内部で復旧処理を行うことがあります。このときに、
212                 SD カードが書き込み禁止にされていた場合、エラーとして @ref ResultWriteProtected が返ります。また、SD カード上の
213                 ファイル、もしくはディレクトリが、読み取り専用属性にされていた場合、エラーとして @ref ResultOperationDenied が
214                 返ります。
215 
216     @param[in]  archiveName アーカイブ名を指定します。
217     @param[in]  id          拡張セーブデータの ID を指定します。
218 
219     @return 処理の結果を返します。
220     @retval 成功                        処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
221     @retval ResultNotFound              拡張セーブデータが見つかりません。@ref CreateExtSaveData を呼び出して作成してください。@n
222                                         開発中は、id の値が正しいか確認をしてください。
223     @retval ResultMediaNotFound         SD カードが見つからないか、もしくは認識できません。
224     @retval ResultOperationDenied       操作が拒否されました。@n
225                                         このエラーは、内部で復旧処理が行われたときにのみ返ります。
226     @retval ResultWriteProtected        SD カードが書き込み禁止になっています。@n
227                                         このエラーは、内部で復旧処理が行われたときにのみ返ります。
228     @retval ResultMediaAccessError      接触不良などの要因により、SD カードアクセス中にエラーが発生しました。
229     @retval ResultNotFormatted          作成中に失敗した状態です。一旦削除した後、@ref CreateExtSaveData を呼び出して作り直してください。
230     @retval ResultBadFormat             不正なフォーマットです。一旦削除した後、@ref CreateExtSaveData を呼び出して作り直してください。
231                                         解決しない場合は、SD カードのフォーマットが必要です。
232     @retval ResultVerificationFailed    検証に失敗、または改竄を検出しました。一旦削除した後、@ref CreateExtSaveData を呼び出して作り直してください。
233     @retval 上記以外                    アプリケーション側の不具合、もしくは想定外のエラーです。
234 */
235 Result MountExtSaveData(const char* archiveName, nn::fs::ExtSaveDataId id);
236 
237 /*!
238     @brief      拡張セーブデータを削除します。
239 
240                 引数の拡張セーブデータ ID には、RSF で指定した拡張セーブデータ番号を指定してください。
241 
242     @param[in]  id          削除する拡張セーブデータの ID を指定します。
243 
244     @return 処理の結果を返します。
245     @retval 成功                        処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
246     @retval ResultNotFound              拡張セーブデータが見つかりません。@ref CreateExtSaveData を呼び出して作成してください。@n
247                                         開発中は、ExtSaveDataId が正しいか確認をしてください。
248     @retval ResultMediaNotFound         SD カードが見つからないか、もしくは認識できません。
249     @retval ResultArchiveInvalidated    削除中に SD カードが抜かれた可能性があります。
250     @retval ResultOperationDenied       指定した拡張セーブデータは現在マウント中のため、操作は途中で失敗しました。
251     @retval ResultWriteProtected        SD カードが書き込み禁止になっています。
252     @retval ResultMediaAccessError      接触不良などの要因により、SD カードアクセス中にエラーが発生しました。
253     @retval ResultBadFormat             SD カードのフォーマットが不正です。SD カードをフォーマットする必要があります。
254     @retval 上記以外                    アプリケーション側の不具合、もしくは想定外のエラーです。
255 */
256 Result DeleteExtSaveData(ExtSaveDataId id);
257 
258 
259 //@}
260 
261 /*!
262     @brief      アーカイブをアンマウントします。
263 
264                 マウントしたアーカイブが必要なくなった場合は、この関数を呼び出して領域をアンマウントをしてください。
265 
266                 アンマウントを実行する前に、セーブデータを二重化している場合は @ref CommitSaveData の呼び出しを忘れずに行ってく
267                 ださい。
268 
269                 アンマウントするアーカイブから開いているファイル・ディレクトリは、全て Finalize を呼び出してから アンマウントす
270                 るようにしてください。Flush を行わずに書き込みを行ったファイルを閉じるときは、Flush を忘れずに行なうようにして
271                 ください。
272 
273     @param[in] archiveName      アーカイブ名を指定します
274 
275     @return 処理の結果を返します。
276     @retval 成功                処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
277     @retval ResultNotFound      指定したアーカイブはマウントされていません。@n
278                                 製品では発生しないようにするべきエラーです。
279     @retval 上記以外            アプリケーション側の不具合、もしくは想定外のエラーです。
280 */
281 Result Unmount(const char* archiveName);
282 
283 
284 //----------------------------------------
285 //! @name デバッグ用
286 //@{
287 
288 /*!
289     @brief      SD カードを直接参照するアーカイブをマウントします(デバッグ用)。
290 
291                 挿入されている SD カードを直接参照するアーカイブをマウントします。SD カードが挿入されていない場合や SD カードが
292                 フォーマットされていない場合は失敗します。マウントしていた SD カードが抜かれ、再挿入された SD カードをマウント
293                 する場合は、@ref nn::fs::Unmount 関数によりアンマウントした後、再度 @ref nn::fs::MountSdmc 関数を実行する必要が
294                 あります。
295 
296                 基本的にデバッグ用途専用であり、製品版ではアクセスすることはできませんのでご注意ください。
297 
298     @param[in] archiveName      アーカイブ名を指定します(省略した際は "sdmc:" が指定されます)
299 
300     @return 処理の結果を返します。
301     @retval 成功                        処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
302     @retval ResultMediaNotFound         SD カードが見つからないか、もしくは認識できません。
303     @retval ResultAlreadyExists         指定したアーカイブ名は、既にマウントされています。@n
304                                         製品では発生しないようにするべきエラーです。
305     @retval ResultArchiveInvalidated    マウント中に SD カードが抜かれた可能性があります。
306     @retval ResultMediaAccessError      接触不良などの要因により、SD カードアクセス中にエラーが発生しました。
307     @retval ResultBadFormat             SD カードのフォーマットが不正です。SD カードをフォーマットする必要があります。
308     @retval 上記以外                    アプリケーション側の不具合、もしくは想定外のエラーです。
309 */
310 Result MountSdmc(const char* archiveName = "sdmc:");
311 
312 /*!
313     @brief     不揮発性メモリデバイスが劣化した際の動作を擬似的に再現させます(デバッグ用)。
314 
315                ゲームカード、NAND、SDメモリカードへアクセスする際、劣化したデバイスで生じるウェイト時間を擬似的に再現させます。
316                (ウェイト時間は リード毎に 0~100ms、ライト毎に 0~380ms です)
317 
318                このエミュレーション機能は debug ビルド、または development ビルドでは常に有効ですが、release ビルド時にはデフォ
319                ルトでは無効になるため、入念にデバッグする場合はこの関数で明示的に指定する必要があります。
320 
321                なお、明示的にエミュレーション機能を OFF にするには、@ref nn::fs::ForceDisableLatencyEmulation 関数を使用します。
322 */
323 void ForceEnableLatencyEmulation( void );
324 
325 /*!
326     @brief     不揮発性メモリデバイスが劣化した際の動作を擬似的に再現させないようにします(デバッグ用)。
327 
328                ゲームカード、NAND、SDメモリカードへアクセスする際、劣化したデバイスで生じるウェイト時間を擬似的に再現させる機能
329                を明示的に OFF にします。
330 
331                このエミュレーション機能は release ビルド時にはデフォルトでは無効ですが、debug ビルド、または development ビルド
332                では有効になっているため、この機能の影響を受けたくない場合にはこの関数で明示的に指定する必要があります。
333 
334                なお、明示的にエミュレーション機能を ON にするには、@ref nn::fs::ForceEnableLatencyEmulation 関数を使用します。
335 */
336 void ForceDisableLatencyEmulation( void );
337 
338 //@}
339 
340 // TODO: その他細かいもの
341 
342 
343 /*!
344     @brief      アーカイブの空き容量を取得します。
345 
346                 この関数は、セーブデータアーカイブに対してのみ使用できます。
347 
348                 セーブデータ領域は、512 バイトの固定サイズでデータの管理を行っています。よって、この関数が返す値は 512 バイトの
349                 倍数になっています。@n
350                 この関数が 1024 を返したとき、512 バイトのファイルを 2 つ作ることができますが、513 バイトのファイルを 1 つ作成
351                 すると空き容量は 0 になります。
352 
353     @param[out] pOut            アーカイブの空き容量を返します。
354     @param[in]  archiveName     アーカイブ名を指定します。
355 
356     @return 処理の結果を返します。
357     @retval 成功                処理に成功しました。戻り値の IsSuccess 関数が true を返す状態です。
358     @retval ResultNotFound      指定したアーカイブはマウントされていません。@n
359                                 製品では発生しないようにするべきエラーです。
360     @retval 上記以外            アプリケーション側の不具合、もしくは想定外のエラーです。
361 */
362 Result GetArchiveFreeBytes(s64* pOut, const char* archiveName);
363 
364 }}
365 
366 
367 namespace nn { namespace fs {
368 
369     /*! @brief PC 上のファイルに直接アクセスするための関数を含んだ名前空間です(デバッグ用)。
370 
371         @ref nn::fs::hio 名前空間内にある関数やクラスを使うためには、libnn_fshio をリンクした上で、予め @ref nn::hio::CTR::Initialize
372         を呼んでおく必要があります。
373 
374         基本的にデバッグ用途専用であり、製品版ではアクセスすることはできませんのでご注意ください。
375     */
376     namespace hio {
377 
378 /*!
379     @brief      hio アーカイブをマウントします。
380 
381                 hio アーカイブは hostPath で指定される PC 上の特定のディレクトリ以下を一つのアーカイブと見なすためのアーカイブ
382                 で、デバッグ用途にのみ使用することができます。
383 
384                 この関数を使用するためには libnn_fshio をリンクした上で、あらかじめ @ref nn::hio::CTR::Initialize を呼んで HIO
385                 を初期化しておく必要があります。HIO の初期化には連続メモリである DeviceMemory を使用してください。
386 
387     @param[in] archiveName          アーカイブ名を指定します。
388     @param[in] hostPath             PC 上のルートディレクトリを指定します。
389     @param[in] maxFile              同時に開くファイルの最大数を指定します。
390     @param[in] maxDirectory         同時に開くディレクトリの最大数を指定します。
391     @param[in] workingMemory        アーカイブの動作に使用するメモリ領域の先頭アドレスを指定します。
392     @param[in] workingMemorySize    アーカイブの動作に使用するメモリ領域のサイズを指定します。
393 
394     @return 処理の結果を返します。
395 */
396 Result MountHioArchive(const char* archiveName, const wchar_t* hostPath, size_t maxFile, size_t maxDirectory, void* workingMemory, size_t workingMemorySize);
397 
398 /*!
399     @brief      hio アーカイブのマウントに必要なメモリサイズを取得します。
400 
401                 hio アーカイブのマウントに必要なメモリサイズを計算して返します。このサイズは、maxFile で指定される数のファイル
402                 と、maxDirectory で指定される数のディレクトリを、同時に開くことができるだけのメモリのサイズも含まれます。
403 
404     @param[in] maxFile          同時に開くファイルの最大数
405     @param[in] maxDirectory     同時に開くディレクトリの最大数
406 
407     @return     計算したメモリサイズを返します。
408 */
409 s32 GetHioRequiredMemorySize(size_t maxFile, size_t maxDirectory);
410 
411 }}}
412 
413 #endif
414