1 /*---------------------------------------------------------------------------*
2   Project:      Sample demo program for NAND library
3   File:         cancel.c
4   Programmer:   HIRATSU Daisuke
5 
6   Copyright (C) 2007 Nintendo.  All rights reserved.
7 
8   These coded instructions, statements, and computer programs contain
9   proprietary information of Nintendo of America Inc. and/or Nintendo
10   Company Ltd., and are protected by Federal copyright law.  They may
11   not be disclosed to third parties or copied or duplicated in any form,
12   in whole or in part, without the prior written consent of Nintendo.
13 
14   $Log: cancel.c,v $
15   Revision 1.3  2007/05/07 12:50:54  hiratsu
16   Modified copy buffer size.
17 
18   Revision 1.2  2007/05/04 02:05:51  hiratsu
19   Removed retry error handling.
20 
21   Revision 1.1  2007/04/23 06:50:08  hiratsu
22   Sample demo program for NANDSimpleSafeCancel().
23 
24  *---------------------------------------------------------------------------*/
25 
26 
27 #include <string.h>
28 #include <stdlib.h>
29 #include <revolution.h>
30 
31 #include "util.h"
32 
33 #define FILENAME "cancel.txt"
34 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE)    // Owner can read/write
35 #define ATTR          0x00                                     // No attributes.
36 #define DATASIZE       256   // byte
37 
38 #define STATUS_SUCCESS   0
39 #define STATUS_FAILURE  -1
40 #define STATUS_BROKEN   -2
41 
42 
43 static BOOL isBrokenDataError(s32 err);
44 static BOOL prepareFile(void);
45 static int  updateFile(void);
46 static BOOL cleanUpFile(void);
47 static void tryCancel(NANDFileInfo *info);
48 
49 
main(void)50 int main(void)
51 {
52     if(!prepareFile())
53     {
54         OSReport("Failed to prepare file.\n");
55         return EXIT_FAILURE;
56     }
57 
58     switch(updateFile())
59     {
60     case STATUS_SUCCESS:
61         break;
62     case STATUS_FAILURE:
63         OSReport("Failed to update file.\n");
64         return EXIT_FAILURE;
65         break;
66     case STATUS_BROKEN:
67         OSReport("Original file is broken.\n");
68         OSReport("Application program should ask a player to delete the file.\n");
69         return EXIT_FAILURE;
70     default:
71         OSHalt("Never reach here...");
72         break;
73     }
74 
75     if(!cleanUpFile())
76     {
77         OSReport("Failed to clean up file.\n");
78         return EXIT_FAILURE;
79     }
80 
81     OSHalt("Cancel demo program finished with success.");
82     return EXIT_SUCCESS;     // Never reach here.
83 }
84 
85 
isBrokenDataError(s32 err)86 static BOOL isBrokenDataError(s32 err)
87 {
88     if(err==NAND_RESULT_AUTHENTICATION || err==NAND_RESULT_ECC_CRIT)
89     {
90         return TRUE;
91     }
92     else
93     {
94         return FALSE;
95     }
96 }
97 
98 
prepareFile(void)99 static BOOL prepareFile(void)
100 {
101     NANDFileInfo info;
102     s32 ret = NAND_RESULT_FATAL_ERROR;
103     char data[DATASIZE] ATTRIBUTE_ALIGN(32);
104     memset(data, 'A', DATASIZE);
105 
106     ret = NANDCreate(FILENAME, PERM, ATTR);
107     if(ret==NAND_RESULT_OK || ret==NAND_RESULT_EXISTS)
108     {
109         // No problem.
110     }
111     else
112     {
113         printErrMsg(ret);
114         OSReport("NANDCreate() failed.\n");
115         return FALSE;
116     }
117 
118     ret = NANDOpen(FILENAME, &info, NAND_ACCESS_WRITE | NAND_ACCESS_READ);
119     if(ret != NAND_RESULT_OK)
120     {
121         printErrMsg(ret);
122         OSReport("NANDOpen() failed.  Result code: %d\n", ret);
123         return FALSE;
124     }
125 
126     ret = NANDWrite(&info, data, DATASIZE);
127     if(ret != DATASIZE)
128     {
129         printErrMsg(ret);
130         OSReport("NANDWrite() failed.\n");
131         NANDClose(&info);
132         return FALSE;
133     }
134 
135     ret = NANDClose(&info);
136     if(ret != NAND_RESULT_OK)
137     {
138         printErrMsg(ret);
139         OSReport("NANDClose() failed.\n");
140         return FALSE;
141     }
142 
143     return TRUE;
144 }
145 
146 
updateFile(void)147 static int updateFile(void)
148 {
149     NANDFileInfo info;
150     u8 copyBuf[NAND_FSBLOCK_SIZE] ATTRIBUTE_ALIGN(32);
151     char dataB[DATASIZE] ATTRIBUTE_ALIGN(32);
152     memset(dataB, 'B', DATASIZE);
153 
154     while(1)
155     {
156         // Opening phase
157         s32 ret = NANDSimpleSafeOpen(FILENAME, &info, NAND_ACCESS_WRITE, copyBuf, NAND_FSBLOCK_SIZE);
158         if(ret == NAND_RESULT_OK)
159         {
160             // No problem.
161         }
162         else if(isBrokenDataError(ret))
163         {
164             // Original file is broken.  Application program shuould consider delete this file.
165             tryCancel(&info);
166             return STATUS_BROKEN;
167         }
168         else
169         {
170             printErrMsg(ret);
171             return STATUS_FAILURE;
172         }
173 
174         // Writing phase
175         ret = NANDWrite(&info, dataB, DATASIZE);
176         if(ret==DATASIZE)
177         {
178             // No problem.
179         }
180         else if(isBrokenDataError(ret))
181         {
182             tryCancel(&info);
183             continue;
184         }
185         else
186         {
187             printErrMsg(ret);
188             return STATUS_FAILURE;
189         }
190 
191         // Closing phase
192         ret = NANDSimpleSafeClose(&info);
193         if(ret==NAND_RESULT_OK)
194         {
195             break;
196         }
197         else
198         {
199             printErrMsg(ret);
200             return STATUS_FAILURE;
201         }
202     }
203 
204     return STATUS_SUCCESS;
205 }
206 
207 
cleanUpFile(void)208 static BOOL cleanUpFile(void)
209 {
210     s32 ret = NANDDelete(FILENAME);
211     if(ret != NAND_RESULT_OK)
212     {
213         printErrMsg(ret);
214         OSReport("NANDDelete() failed.\n");
215         return FALSE;
216     }
217     else
218     {
219         return TRUE;
220     }
221 }
222 
223 
tryCancel(NANDFileInfo * info)224 static void tryCancel(NANDFileInfo *info)
225 {
226     s32 ret = NANDSimpleSafeCancel(info);
227     if(ret==NAND_RESULT_OK)
228     {
229         return;
230     }
231     else
232     {
233         printErrMsg(ret);
234         OSHalt("NANDSimpleSafeCancel() failed.  Stop.");
235     }
236 }
237