1 | /**
|
2 | * creates a new entry (file or directory) at the location indicated by the
|
3 | * input cluster. The input control determines whether a file or a
|
4 | * directory is created
|
5 | * *****ONLY FILES AND DIRECTORY WITH SHORT FILE NAMES ARE SUPPORTED
|
6 | *
|
7 | * @param buf the buffer to be used to access the MMC/SD card
|
8 | * @param entryName pointer to the name of the new entry
|
9 | * @param cluster location of the current directory where the new entry will be added
|
10 | * @param control FILE or DIRECTORY
|
11 | *
|
12 | * @return 0 if an error occurs while adding a new entry
|
13 | * @return ... the location of the first cluster of the new entry
|
14 | **/
|
15 | static unsigned long createNewEntry(const char *entryName, unsigned long cluster, unsigned char *buf, boolean control)
|
16 | {
|
17 | unsigned int offset;
|
18 | unsigned int sectorCount = 0;
|
19 | unsigned int tokenLength = 0;
|
20 | unsigned long sector;
|
21 | unsigned long newCluster;
|
22 | unsigned char i;
|
23 | const char *tempEntryName;
|
24 | boolean done = FALSE;
|
25 |
|
26 | // Note: findEmptyCluster() will mark the returned cluster in the FAT
|
27 | // as used. If we fail for some other reason below, we should really
|
28 | // free the newCluster, but we don't right now. Also, unless we are
|
29 | // creating a directory, we really shouldn't allocate a first cluster
|
30 | // until some data is written to the file. Additionally, if we re-use a
|
31 | // deleted entry, we should re-use the cluster chain, adding clusters as
|
32 | // required, but we don't do that right now either.
|
33 | newCluster = findEmptyCluster(buf);
|
34 | if(newCluster == 0)
|
35 | {
|
36 | return 0; // no more empty cluster
|
37 | }
|
38 |
|
39 | if((cluster == 1) && (fileSys == FAT16))
|
40 | {
|
41 | sector = rootDirectory;
|
42 | }
|
43 | else
|
44 | {
|
45 | sector = (cluster - 2) * sectorsPerCluster + dataStarts;
|
46 | }
|
47 |
|
48 | tempEntryName = entryName;
|
49 |
|
50 | while((*tempEntryName != '.')&&(*tempEntryName)&&(*tempEntryName != 0x5C))
|
51 | {
|
52 | tokenLength++;
|
53 | tempEntryName++;
|
54 | }
|
55 |
|
56 | while(!done)
|
57 | {
|
58 | readSector(sector, buf);
|
59 | i = 0;
|
60 | while(i < 16)
|
61 | {
|
62 | offset = i * 32;
|
63 | if(((buf[offset] & 0xFF) == 0x00) || ( (buf[offset] & 0xFF) == 0xE5) )
|
64 | {
|
65 | done = TRUE;
|
66 | i = 15;
|
67 | }
|
68 | i++;
|
69 | }
|
70 | if(!done)
|
71 | {
|
72 | sectorCount++;
|
73 | if((cluster == 1)&&(fileSys == FAT16))
|
74 | {
|
75 | if(sectorCount < rootSectors)
|
76 | {
|
77 | sector++;
|
78 | }
|
79 | else
|
80 | {
|
81 | return 0; // no more root directory
|
82 | }
|
83 | }
|
84 | else
|
85 | {
|
86 | return 0;
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | if(control == FILE)
|
92 | {
|
93 | buf[offset+11] = 0x20;
|
94 | if(tokenLength < 9)
|
95 | {
|
96 | for(i = 0; i < 8; i++)
|
97 | {
|
98 | if(*entryName != '.')
|
99 | {
|
100 | if((*entryName >= 'a')&&(*entryName <= 'z'))
|
101 | {
|
102 | buf[offset+i] = (*entryName - 32);
|
103 | }
|
104 | else
|
105 | {
|
106 | buf[offset+i] = *entryName ;
|
107 | }
|
108 | entryName++;
|
109 | }
|
110 | else
|
111 | {
|
112 | buf[offset+i] = 0x20;
|
113 | }
|
114 | }
|
115 | entryName++;
|
116 | for(i = 8; i < 11; i++)
|
117 | {
|
118 | if(*entryName)
|
119 | {
|
120 | if((*entryName >= 'a')&&(*entryName <= 'z'))
|
121 | {
|
122 | buf[offset+i] = (*entryName - 32);
|
123 | }
|
124 | else
|
125 | {
|
126 | buf[offset+i] = *entryName ;
|
127 | }
|
128 | entryName++;
|
129 | }
|
130 | else
|
131 | {
|
132 | buf[offset+i] = 0x20;
|
133 | }
|
134 | }
|
135 | }
|
136 | else
|
137 | {
|
138 | // file with long file name
|
139 | return 0;
|
140 | }
|
141 | }
|
142 |
|
143 | buf[offset+12] = 0x00;
|
144 | buf[offset+13] = 0x00;
|
145 |
|
146 | // Set the date and time to January 02, 2005 21:00:00 .
|
147 | // If a real time clock is available, we could use it.
|
148 | buf[offset+14] = (04 >> 1) & 0x1F; // Seconds.
|
149 | buf[offset+14] |= 03 << 5; // Part of minutes.
|
150 | buf[offset+22] = buf[offset+14];
|
151 |
|
152 | buf[offset+15] = (03 >> 3) & 0x07; // More of minutes.
|
153 | buf[offset+15] |= 21 << 3; // Hours.
|
154 | buf[offset+23] = buf[offset+15];
|
155 |
|
156 | buf[offset+16] = 02 & 0x1F; // Day.
|
157 | buf[offset+16] |= (01 << 5) & 0xE0; // Part of month.
|
158 | buf[offset+18] = buf[offset+16];
|
159 | buf[offset+24] = buf[offset+16];
|
160 |
|
161 | buf[offset+17] = (01 >> 3) & 0x01; // More of month.
|
162 | buf[offset+17] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE; // Year.
|
163 | buf[offset+19] = buf[offset+17];
|
164 | buf[offset+25] = buf[offset+17];
|
165 |
|
166 | buf[offset+26] = (newCluster & 0xFF);
|
167 | buf[offset+27] = (newCluster >> 8) & 0xFF;
|
168 |
|
169 | for(i = 28; i < 32; i++)
|
170 | {
|
171 | buf[offset+i] = 0x00;
|
172 | }
|
173 | writeSector(sector, buf);
|
174 |
|
175 | return newCluster;
|
176 | }
|