1 /*---------------------------------------------------------------------------*
2 Project: Sample demo program for NAND library
3 File: safe.c
4 Programmer: HIRATSU Daisuke
5
6 Copyright (C) 2006 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: safe.c,v $
15 Revision 1.2 08/12/2006 12:00:54 hiratsu
16 Refactoring.
17
18 Revision 1.1 07/24/2006 07:24:03 hiratsu
19 This demo tells differences between normal Open/Close and SafeOpen/SafeClose.
20
21 *---------------------------------------------------------------------------*/
22
23 #include <revolution.h>
24 #include <revolution/nand.h>
25
26 #include <string.h>
27
28 #include "util.h"
29
30
31 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE) // Owner can read/write
32 #define ATTR 0x00 // No attributes.
33 #define COPYBUF_SIZE 4096
34 #define FILE_SIZE (1*1024*1024)
35 #define SAFE_FILENAME "safe.dat"
36 #define UNSAFE_FILENAME "unsafe.dat"
37
38
39 static void checkFileData(const char *filename);
40 static void initFile(const char *filename);
41
42
checkFileData(const char * filename)43 static void checkFileData(const char *filename)
44 {
45 static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
46 int i = 0;
47 NANDFileInfo info;
48 s32 rc = NANDOpen(filename, &info, NAND_ACCESS_READ);
49 if(rc!=NAND_RESULT_OK)
50 {
51 printErrMsg(rc);
52 }
53
54 rc = NANDRead(&info, s_buf, FILE_SIZE);
55 if(rc!=FILE_SIZE)
56 {
57 printErrMsg(rc);
58 }
59
60 rc = NANDClose(&info);
61 if(rc!=NAND_RESULT_OK)
62 {
63 printErrMsg(rc);
64 }
65
66 OSReport("Checking anterior half and last half of %s ... ", filename);
67 if(memcmp(s_buf, s_buf+FILE_SIZE/2, FILE_SIZE/2)==0)
68 {
69 OSReport("Equivalent.\n");
70 }
71 else
72 {
73 OSReport("Different!\n");
74 }
75 }
76
77
initFile(const char * filename)78 static void initFile(const char *filename)
79 {
80 s32 rc = NANDCreate(filename, PERM, ATTR);
81 if(rc==NAND_RESULT_OK)
82 {
83 OSReport("Created %s.\n", filename);
84 }
85
86 if(rc==NAND_RESULT_OK || rc==NAND_RESULT_EXISTS)
87 {
88 static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
89 NANDFileInfo info;
90 rc = NANDOpen(filename, &info, NAND_ACCESS_WRITE);
91 if(rc!=NAND_RESULT_OK)
92 {
93 printErrMsg(rc);
94 }
95
96 memset(s_buf, 'A', FILE_SIZE);
97 rc = NANDWrite(&info, s_buf, FILE_SIZE);
98 if(rc!=FILE_SIZE)
99 {
100 printErrMsg(rc);
101 }
102
103 rc = NANDClose(&info);
104 if(rc!=NAND_RESULT_OK)
105 {
106 printErrMsg(rc);
107 }
108
109 OSReport("Now %s is filled with 'A'.\n", filename);
110 }
111 else
112 {
113 printErrMsg(rc);
114 OSHalt("Unexpected error.");
115 }
116 }
117
118
main(void)119 int main(void)
120 {
121 PADStatus pad[PAD_MAX_CONTROLLERS];
122 NANDFileInfo safeInfo, unsafeInfo;
123 static u8 aryB[FILE_SIZE/2] ATTRIBUTE_ALIGN(32);
124 u8 copyBuf[COPYBUF_SIZE] ATTRIBUTE_ALIGN(32);
125 s32 rc = NAND_RESULT_FATAL_ERROR;
126 u8 type = 0x00;
127
128 NANDInit();
129 PADInit();
130 VIInit();
131
132 memset(aryB, 'B', FILE_SIZE/2);
133
134 rc = NANDGetType(SAFE_FILENAME, &type);
135 if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
136 {
137 checkFileData(SAFE_FILENAME);
138 }
139
140 rc = NANDGetType(SAFE_FILENAME, &type);
141 if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
142 {
143 checkFileData(UNSAFE_FILENAME);
144 }
145
146 initFile(SAFE_FILENAME);
147 initFile(UNSAFE_FILENAME);
148
149 rc = NANDSafeOpen(SAFE_FILENAME, &safeInfo, NAND_ACCESS_RW, copyBuf, COPYBUF_SIZE);
150 if(rc != NAND_RESULT_OK)
151 {
152 printErrMsg(rc);
153 OSHalt("Unexpected error.");
154 }
155
156 rc = NANDOpen(UNSAFE_FILENAME, &unsafeInfo, NAND_ACCESS_RW);
157 if(rc != NAND_RESULT_OK)
158 {
159 printErrMsg(rc);
160 OSHalt("Unexpected error.");
161 }
162
163 // First write
164 rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
165 if(rc != FILE_SIZE/2)
166 {
167 printErrMsg(rc);
168 OSHalt("Unexpected error.");
169 }
170
171 // First write
172 rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
173 if(rc != FILE_SIZE/2)
174 {
175 printErrMsg(rc);
176 OSHalt("Unexpected error.");
177 }
178
179 OSReport("Wrote 'B' to both anterior half area.\n");
180
181 // This operation causes FAT commit.
182 rc = NANDCreate("/tmp/file.tmp", PERM, ATTR);
183 if(rc!=NAND_RESULT_OK)
184 {
185 printErrMsg(rc);
186 OSHalt("create tmp file failed.");
187 }
188
189 OSReport("Press A button to continue writing data.\n");
190 OSReport("Press START button to quit writing data.\n");
191 OSReport("After that, please execute this demo program again.\n");
192 while(1)
193 {
194 PADRead(pad);
195 if(pad[0].button & PAD_BUTTON_A)
196 {
197 break;
198 }
199 if(pad[0].button & PAD_BUTTON_START)
200 {
201 OSHalt("Program is terminated before closing files.");
202 }
203
204 VIWaitForRetrace();
205 }
206
207 // Second write
208 rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
209 if(rc != FILE_SIZE/2)
210 {
211 printErrMsg(rc);
212 OSHalt("Unexpected error.");
213 }
214
215 // Second write
216 rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
217 if(rc != FILE_SIZE/2)
218 {
219 printErrMsg(rc);
220 OSHalt("Unexpected error.");
221 }
222
223 OSReport("Wrote 'B' to both last half area.\n");
224
225 rc = NANDSafeClose(&safeInfo);
226 if(rc != NAND_RESULT_OK)
227 {
228 printErrMsg(rc);
229 OSHalt("Unexpected error.");
230 }
231
232 rc = NANDClose(&unsafeInfo);
233 if(rc != NAND_RESULT_OK)
234 {
235 printErrMsg(rc);
236 OSHalt("Unexpected error.");
237 }
238
239 OSHalt("Program completed normally.");
240 return 0;
241 }
242
243