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