1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     FsSampleFile.cpp
4 
5   Copyright (C)2009-2012 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: 47596 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "FsSampleFile.h"
17 #include <string.h>
18 #include <sstream>
19 
20 
21 namespace
22 {
23     // File path
24     const std::wstring  pathNameRomW            = L"rom:/test.txt";
25     const std::wstring  pathNameSaveDataW       = L"data:/test.txt";
26     const std::wstring  pathNameExtSaveDataW    = L"extdata:/test.txt";
27     const std::wstring  pathNameSdmcWriteOnlyW  = L"sdmcwo:/test.txt";
28 
29     const std::wstring  pathNameIcnFileW        = L"rom:/ExtSaveData.icn";
30 
31     /* Please see man pages for details
32 
33 
34 
35 
36 
37 
38     */
FsSampleReadRomFileImple()39     nn::Result FsSampleReadRomFileImple()
40     {
41         // Open the file
42         nn::fs::FileInputStream f(pathNameRomW.c_str());
43 
44         // Prepare buffer
45         size_t size = f.GetSize();
46         void* buf = FsSampleAllocateMemory(size);
47         if(!buf)
48         {
49             NN_LOG("Cannot allocate memory : size=%d\n", size);
50             return ResultAppOutOfMemory();
51         }
52 
53         // Load file
54         f.Read(buf, size);
55 
56         // Close the file
57         f.Finalize();   // Can be called even in the destructor
58         FsSampleFreeMemory(buf);
59 
60         return nn::ResultSuccess();
61     }
62 
63     /* Please see man pages for details
64 
65 
66 
67 
68 
69 
70     */
FsSampleCreateSaveDataFileImpl()71     nn::Result FsSampleCreateSaveDataFileImpl()
72     {
73         const s64   size = 1024;
74 
75         // Creates files and opens them.
76         nn::fs::FileOutputStream    f;
77         nn::Result result = f.TryInitialize(pathNameSaveDataW.c_str(), true);
78         if(result.IsFailure())
79         {
80             NN_LOG("TryInitialize() failed!\n");
81             return result;
82         }
83 
84         // Expands the file size (0 when created)
85         // When a file is created with nn::fs::TryCreateFile, this process is unnecessary since processing includes up to size expansion
86         result = f.TrySetSize(size);
87         if(result.IsFailure())
88         {
89             NN_LOG("TrySetSize() failed!\n");
90             return result;
91         }
92 
93         // Prepares data.
94         s32     out;
95         bit8*   pData = static_cast<bit8*>(FsSampleAllocateMemory(size));
96         if(!pData)
97         {
98             NN_LOG("Cannot allocate memory : size=%d\n", size);
99             return ResultAppOutOfMemory();
100         }
101 
102         for(s32 i = 0; i < size; ++i)
103         {
104             pData[i] = i;
105         }
106 
107         // Write to file
108         result = f.TryWrite(&out, pData, size, true);
109         if(result.IsFailure())
110         {
111             NN_LOG("TryWrite() failed!\n");
112             FsSampleFreeMemory(pData);
113             return result;
114         }
115 /*
116         // Flush the file cache
117         // When flush=false is specified in the TryWrite argument, TryFlush must be called before closing the file
118         result = f.TryFlush();
119         if(result.IsFailure())
120         {
121             NN_LOG("TryFlush() failed!\n");
122             FsSampleFreeMemory(pData);
123             return result;
124         }
125 */
126         // Close the file
127         f.Finalize();   // Can be called even in the destructor
128         FsSampleFreeMemory(pData);
129 
130         return nn::ResultSuccess();
131     }
132 
133     /* Please see man pages for details
134 
135 
136 
137 
138 
139 
140     */
FsSampleReadSaveDataFileImpl()141     nn::Result FsSampleReadSaveDataFileImpl()
142     {
143         // Open file
144         nn::fs::FileInputStream  f;
145         nn::Result result = f.TryInitialize(pathNameSaveDataW.c_str());
146         if(result.IsFailure())
147         {
148             NN_LOG("TryInitialize() failed!\n");
149             return result;
150         }
151 
152         // Prepare buffer
153         s64 size;
154         result = f.TryGetSize(&size);
155         if(result.IsFailure())
156         {
157             NN_LOG("TryGetSize() failed!\n");
158             return result;
159         }
160 
161         void* buf = FsSampleAllocateMemory(size);
162         if(!buf)
163         {
164             NN_LOG("Cannot allocate memory!\n");
165             return ResultAppOutOfMemory();
166         }
167 
168         // Load file
169         s32 out;
170         result = f.TryRead(&out, buf, size);
171         if(result.IsFailure())
172         {
173             NN_LOG("TryRead() failed!\n");
174             FsSampleFreeMemory(buf);
175             return result;
176         }
177 
178         // Close the file
179         f.Finalize();   // Can be called even in the destructor
180         FsSampleFreeMemory(buf);
181 
182         return nn::ResultSuccess();
183     }
184 
185     /* Please see man pages for details
186 
187 
188 
189 
190 
191 
192 
193     */
FsSampleCreateExtSaveDataFileImpl()194     nn::Result FsSampleCreateExtSaveDataFileImpl()
195     {
196         const s64   size = 1024;
197 
198         // Create a file
199         // Use nn::fs::TryCreateFile to create a file to the expanded save data
200         nn::Result  result = nn::fs::TryCreateFile(pathNameExtSaveDataW.c_str(), size);
201         if(result.IsFailure() && !nn::fs::ResultAlreadyExists::Includes(result))
202         {
203             // For TryCreateFile, an error is returned if the file already exists
204             NN_LOG("TryCreateFile() failed!\n");
205             return result;
206         }
207 
208         nn::fs::FileOutputStream    f;
209         result = f.TryInitialize(pathNameExtSaveDataW.c_str(), false);
210         if(result.IsFailure())
211         {
212             NN_LOG("TryInitialize() failed!\n");
213             return result;
214         }
215 
216         // Prepares data.
217         s32     out;
218         bit8*   pData = static_cast<bit8*>(FsSampleAllocateMemory(size));
219         if(!pData)
220         {
221             NN_LOG("Cannot allocate memory!\n");
222             return result;
223         }
224 
225         for(s32 i = 0; i < size; ++i)
226         {
227             pData[i] = i;
228         }
229 
230         // Write to file
231         result = f.TryWrite(&out, pData, size, true);
232         if(result.IsFailure())
233         {
234             NN_LOG("TryWrite() failed!\n");
235             FsSampleFreeMemory(pData);
236             return result;
237         }
238 /*
239         // Flush the file cache
240         // When flush=false is specified in the TryWrite argument, TryFlush must be called before closing the file
241         result = f.TryFlush();
242         if(result.IsFailure())
243         {
244             NN_LOG("TryFlush() failed!\n");
245             FsSampleFreeMemory(pData);
246             return result;
247         }
248 */
249         // Close the file
250         f.Finalize();   // Can be called even in the destructor
251         FsSampleFreeMemory(pData);
252 
253         return nn::ResultSuccess();
254     }
255 
256     /* Please see man pages for details
257 
258 
259 
260 
261 
262 
263     */
FsSampleReadExtSaveDataFileImpl()264     nn::Result FsSampleReadExtSaveDataFileImpl()
265     {
266         // Open file
267         nn::fs::FileInputStream  f;
268         nn::Result result = f.TryInitialize(pathNameExtSaveDataW.c_str());
269         if(result.IsFailure())
270         {
271             NN_LOG("TryInitialize() failed!\n");
272             return result;
273         }
274 
275         // Prepare buffer
276         s64 size;
277         result = f.TryGetSize(&size);
278         if(result.IsFailure())
279         {
280             NN_LOG("TryGetSize() failed!\n");
281             return result;
282         }
283 
284         void* buf = FsSampleAllocateMemory(size);
285         if(!buf)
286         {
287             NN_LOG("Cannot allocate memory!\n");
288             return ResultAppOutOfMemory();
289         }
290 
291         // Load file
292         s32 out;
293         result = f.TryRead(&out, buf, size);
294         if(result.IsFailure())
295         {
296             NN_LOG("TryRead() failed!\n");
297             FsSampleFreeMemory(buf);
298             return result;
299         }
300 
301         // Close the file
302         f.Finalize();   // Can be called even in the destructor
303         FsSampleFreeMemory(buf);
304 
305         return nn::ResultSuccess();
306     }
307 
308     /* Please see man pages for details
309 
310 
311 
312 
313 
314 
315 
316 
317     */
FsSampleCreateSdmcWriteOnlyFileImpl()318     nn::Result FsSampleCreateSdmcWriteOnlyFileImpl()
319     {
320         const s64   size = 1024;
321 
322         // Creates files and opens them.
323         nn::fs::FileOutputStream    f;
324         nn::Result result = f.TryInitialize(pathNameSdmcWriteOnlyW.c_str(), true);
325         if(result.IsFailure())
326         {
327             NN_LOG("TryInitialize() failed!\n");
328             return result;
329         }
330 
331         // Expands the file size (0 when created)
332         // When a file is created with nn::fs::TryCreateFile, this process is unnecessary since processing includes up to size expansion
333         result = f.TrySetSize(size);
334         if(result.IsFailure())
335         {
336             NN_LOG("TrySetSize() failed!\n");
337             return result;
338         }
339 
340         // Prepares data.
341         s32     out;
342         bit8*   pData = static_cast<bit8*>(FsSampleAllocateMemory(size));
343         if(!pData)
344         {
345             NN_LOG("Cannot allocate memory!\n");
346             return result;
347         }
348 
349         for(s32 i = 0; i < size; ++i)
350         {
351             pData[i] = i;
352         }
353 
354         // Write to file
355         result = f.TryWrite(&out, pData, size, true);
356         if(result.IsFailure())
357         {
358             NN_LOG("TryWrite() failed!\n");
359             FsSampleFreeMemory(pData);
360             return result;
361         }
362 
363         // Close the file
364         f.Finalize();   // Can be called even in the destructor
365         FsSampleFreeMemory(pData);
366 
367         return nn::ResultSuccess();
368     }
369 }
370 
371 
372 
FsSampleReadRomFile()373 bool FsSampleReadRomFile()
374 {
375     NN_LOG("FsSampleRomFile() start.\n");
376 
377     if(FsSampleReadRomFileImple().IsFailure())
378     {
379         return false;
380     }
381 
382     NN_LOG("FsSampleRomFile() succeed.\n");
383     return true;
384 }
385 
FsSampleCreateSaveDataFile()386 bool FsSampleCreateSaveDataFile()
387 {
388     NN_LOG("FsSampleCreateSaveDataFile() start.\n");
389 
390     nn::Result result = FsSampleCreateSaveDataFileImpl();
391     if(result.IsFailure())
392     {
393         NN_DBG_PRINT_RESULT(result);
394 
395         if(result <= nn::fs::ResultNotFound())
396         {
397             // The archive could not be found (not mounted)
398             // This error should not occur in the production version
399             return false;
400         }
401         else if(result <= nn::fs::ResultVerificationFailed())
402         {
403             // The file system or directory entry is either corrupted or has been altered
404             // It is necessary to reformat
405             return false;
406         }
407         else if(result <= nn::fs::ResultOperationDenied())
408         {
409             // It may be possible that a directory with the same name exists or the directory is already opened
410             // This error should not occur in the production version
411             return false;
412         }
413         else if(result <= nn::fs::ResultNotEnoughSpace())
414         {
415             // Not enough free space
416             // This error should not occur in the production version
417             return false;
418         }
419         else if(result == ResultAppOutOfMemory())
420         {
421             // Insufficient memory (application-specific defined error)
422             // This error should not occur in the production version
423             return false;
424         }
425         else
426         {
427             // Unexpected errors
428             NN_ERR_THROW_FATAL_ALL(result);
429         }
430     }
431 
432     NN_LOG("FsSampleCreateSaveDataFile() succeed.\n");
433     return true;
434 }
435 
FsSampleReadSaveDataFile()436 bool FsSampleReadSaveDataFile()
437 {
438     NN_LOG("FsSampleReadSaveDataFile() start.\n");
439 
440     nn::Result result = FsSampleReadSaveDataFileImpl();
441     if(result.IsFailure())
442     {
443         NN_DBG_PRINT_RESULT(result);
444 
445         if(result <= nn::fs::ResultNotFound())
446         {
447             // File or archive cannot be found
448             return false;
449         }
450         else if(result <= nn::fs::ResultVerificationFailed())
451         {
452             // File is either destroyed or altered
453             // ・Requires reformatting when automatic redundancy is enabled.
454             // ・If automatic redundancy is disabled, the file must be deleted and created again
455             //   The file could be corrupted due to causes like the media being removed when saving
456             return false;
457         }
458         else if(result <= nn::fs::ResultOperationDenied())
459         {
460             // It may be possible that a directory with the same name exists or the directory is already opened in write mode
461             // This error should not occur in the production version
462             return false;
463         }
464         else if(result == ResultAppOutOfMemory())
465         {
466             // Insufficient memory (application-specific defined error)
467             // This error should not occur in the production version
468             return false;
469         }
470         else
471         {
472             // Unexpected errors
473             NN_ERR_THROW_FATAL_ALL(result);
474         }
475     }
476 
477     NN_LOG("FsSampleReadSaveDataFile() succeed.\n");
478     return true;
479 }
480 
FsSampleCreateExtSaveDataFile()481 bool FsSampleCreateExtSaveDataFile()
482 {
483     NN_LOG("FsSampleCreateExtSaveDataFile() start.\n");
484 
485     nn::Result result = FsSampleCreateExtSaveDataFileImpl();
486     if(result.IsFailure())
487     {
488         NN_DBG_PRINT_RESULT(result);
489 
490         if(result <= nn::fs::ResultNotFound())
491         {
492             if(result <= nn::fs::ResultMediaNotFound())
493             {
494                 // The SD Card may have been removed
495             }
496             else
497             {
498                 // The archive could not be found (not mounted)
499                 // This error should not occur in the production version
500             }
501 
502             return false;
503         }
504         else if(result <= nn::fs::ResultVerificationFailed())
505         {
506             // The file system or directory entry is either corrupted or has been altered
507             // It is necessary to reformat
508             return false;
509         }
510         else if(result <= nn::fs::ResultArchiveInvalidated())
511         {
512             // The SD Card may have been removed
513             return false;
514         }
515         else if(result <= nn::fs::ResultOperationDenied())
516         {
517             if(result <= nn::fs::ResultWriteProtected())
518             {
519                 // SD Card has been write protected
520             }
521             else
522             {
523                 // It may be possible that a directory with the same name exists or the directory is already opened
524                 // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
525             }
526 
527             return false;
528         }
529         else if(result <= nn::fs::ResultNotEnoughSpace())
530         {
531             // Not enough free space
532             // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
533             return false;
534         }
535         else if(result == ResultAppOutOfMemory())
536         {
537             // Insufficient memory (application-specific defined error)
538             // This error should not occur in the production version
539             return false;
540         }
541         else
542         {
543             // Unexpected errors
544             return false;
545         }
546     }
547 
548     NN_LOG("FsSampleCreateExtSaveDataFile() succeed.\n");
549     return true;
550 }
551 
FsSampleReadExtSaveDataFile()552 bool FsSampleReadExtSaveDataFile()
553 {
554     NN_LOG("FsSampleReadExtSaveDataFile() start.\n");
555 
556     nn::Result result = FsSampleReadExtSaveDataFileImpl();
557     if(result.IsFailure())
558     {
559         NN_DBG_PRINT_RESULT(result);
560 
561         if(result <= nn::fs::ResultNotFound())
562         {
563             if(result <= nn::fs::ResultMediaNotFound())
564             {
565                 // The SD Card may have been removed
566             }
567             else
568             {
569                 // File or archive cannot be found
570                 // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
571             }
572 
573             return false;
574         }
575         else if(result <= nn::fs::ResultArchiveInvalidated())
576         {
577             // The SD Card may have been removed
578             return false;
579         }
580         else if(result <= nn::fs::ResultVerificationFailed())
581         {
582             // File is either destroyed or altered
583             // The file must be deleted and created again
584             // The file could be corrupted due to causes like the media being removed when saving
585             return false;
586         }
587         else if(result <= nn::fs::ResultOperationDenied())
588         {
589             if(result <= nn::fs::ResultWriteProtected())
590             {
591                 // SD Card has been write protected
592             }
593             else
594             {
595                 // It may be possible that a directory with the same name exists or the directory is already opened in write mode
596                 // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
597             }
598 
599             return false;
600         }
601         else if(result == ResultAppOutOfMemory())
602         {
603             // Insufficient memory (application-specific defined error)
604             // This error should not occur in the production version
605             return false;
606         }
607         else
608         {
609             // Unexpected errors
610             return false;
611         }
612     }
613 
614     NN_LOG("FsSampleReadExtSaveDataFile() succeed.\n");
615     return true;
616 }
617 
FsSampleCreateSdmcWriteOnlyFile()618 bool FsSampleCreateSdmcWriteOnlyFile()
619 {
620     NN_LOG("FsSampleCreateSdmcWriteOnlyFile() start.\n");
621 
622     nn::Result result = FsSampleCreateSdmcWriteOnlyFileImpl();
623     if(result.IsFailure())
624     {
625         NN_DBG_PRINT_RESULT(result);
626 
627         if(result <= nn::fs::ResultNotFound())
628         {
629             if(result <= nn::fs::ResultMediaNotFound())
630             {
631                 // The SD Card may have been removed
632             }
633             else
634             {
635                 // The archive could not be found (not mounted)
636                 // This error should not occur in the production version
637             }
638 
639             return false;
640         }
641         else if(result <= nn::fs::ResultArchiveInvalidated())
642         {
643             // The SD Card may have been removed
644             return false;
645         }
646         else if(result <= nn::fs::ResultOperationDenied())
647         {
648             if(result <= nn::fs::ResultWriteProtected())
649             {
650                 // SD Card has been write protected
651             }
652             else
653             {
654                 // It may be possible that a directory with the same name exists or the directory is already opened
655                 // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
656             }
657 
658             return false;
659         }
660         else if(result <= nn::fs::ResultNotEnoughSpace())
661         {
662             // Not enough free space
663             // Because the data on the SD Card can be manipulated on the computer, this may also occur in the product
664             return false;
665         }
666         else if(result == ResultAppOutOfMemory())
667         {
668             // Insufficient memory (application-specific defined error)
669             // This error should not occur in the production version
670             return false;
671         }
672         else
673         {
674             // Unexpected errors
675             return false;
676         }
677     }
678 
679     NN_LOG("FsSampleCreateSdmcWriteOnlyFile() succeed.\n");
680     return true;
681 }
682 
683 
684 
685 /* Please see man pages for details
686 
687 
688 
689 
690 
691 
692 
693 
694 
695 
696 */
FsSampleReadIcnData(void ** ppData,size_t * pSize)697 bool FsSampleReadIcnData(void** ppData, size_t* pSize)
698 {
699     // Open the *.icn file
700     nn::fs::FileInputStream f(pathNameIcnFileW.c_str());
701 
702     // Allocate buffer
703     size_t size = f.GetSize();
704     void* p = FsSampleAllocateMemory(size);
705     if(!p)
706     {
707         return false;
708     }
709 
710     // Load data
711     f.Read(p, size);
712 
713     *pSize  = size;
714     *ppData = p;
715     return true;
716 }
717 
718 /* Please see man pages for details
719 
720 
721 
722 */
FsSampleFreeIcnData(void * p)723 void FsSampleFreeIcnData(void* p)
724 {
725     FsSampleFreeMemory(p);
726 }
727 
728