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