6a91cfbb4a1205a370f4493698ee025bf12048ee
[efi/fat/.git] / FatPkg / EnhancedFatDxe / Misc.c
1 /*++\r
2 \r
3 Copyright (c) 2005, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the Software\r
6 License Agreement which accompanies this distribution.\r
7 \r
8 \r
9 Module Name:\r
10 \r
11   Misc.c\r
12 \r
13 Abstract:\r
14 \r
15   Miscellaneous functions\r
16 \r
17 Revision History\r
18 \r
19 --*/\r
20 \r
21 #include "Fat.h"\r
22 \r
23 EFI_STATUS\r
24 FatAccessVolumeDirty (\r
25   IN FAT_VOLUME       *Volume,\r
26   IN IO_MODE          IoMode,\r
27   IN VOID             *DirtyValue\r
28   )\r
29 /*++\r
30 \r
31 Routine Description:\r
32 \r
33   Set the volume as dirty or not\r
34 \r
35 Arguments:\r
36 \r
37   Volume                - FAT file system volume.\r
38   IoMode                - The access mode.\r
39   DirtyValue            - Set the volume as dirty or not.\r
40 \r
41 Returns:\r
42 \r
43   EFI_SUCCESS           - Set the new FAT entry value sucessfully.\r
44   other                 - An error occurred when operation the FAT entries.\r
45 \r
46 --*/\r
47 {\r
48   UINTN WriteCount;\r
49 \r
50   WriteCount = Volume->FatEntrySize;\r
51   return FatDiskIo (Volume, IoMode, Volume->FatPos + WriteCount, WriteCount, DirtyValue);\r
52 }\r
53 \r
54 EFI_STATUS\r
55 FatDiskIo (\r
56   IN     FAT_VOLUME       *Volume,\r
57   IN     IO_MODE          IoMode,\r
58   IN     UINT64           Offset,\r
59   IN     UINTN            BufferSize,\r
60   IN OUT VOID             *Buffer\r
61   )\r
62 /*++\r
63 \r
64 Routine Description:\r
65 \r
66   General disk access function\r
67 \r
68 Arguments:\r
69 \r
70   Volume                - FAT file system volume.\r
71   IoMode                - The access mode (disk read/write or cache access).\r
72   Offset                - The starting byte offset to read from.\r
73   BufferSize            - Size of Buffer.\r
74   Buffer                - Buffer containing read data.\r
75 \r
76 Returns:\r
77 \r
78   EFI_SUCCESS           - The operation is performed successfully.\r
79   EFI_VOLUME_CORRUPTED  - The accesss is\r
80   Others                - The status of read/write the disk\r
81 \r
82 --*/\r
83 {\r
84   EFI_STATUS            Status;\r
85   EFI_DISK_IO_PROTOCOL  *DiskIo;\r
86   EFI_DISK_READ         IoFunction;\r
87 \r
88   //\r
89   // Verify the IO is in devices range\r
90   //\r
91   Status = EFI_VOLUME_CORRUPTED;\r
92   if (Offset + BufferSize <= Volume->VolumeSize) {\r
93     if (CACHE_ENABLED (IoMode)) {\r
94       //\r
95       // Access cache\r
96       //\r
97       Status = FatAccessCache (Volume, CACHE_TYPE (IoMode), RAW_ACCESS (IoMode), Offset, BufferSize, Buffer);\r
98     } else {\r
99       //\r
100       // Access disk directly\r
101       //\r
102       DiskIo      = Volume->DiskIo;\r
103       IoFunction  = (IoMode == READ_DISK) ? DiskIo->ReadDisk : DiskIo->WriteDisk;\r
104       Status      = IoFunction (DiskIo, Volume->MediaId, Offset, BufferSize, Buffer);\r
105     }\r
106   }\r
107 \r
108   if (EFI_ERROR (Status)) {\r
109     Volume->DiskError = TRUE;\r
110     DEBUG ((EFI_D_INFO, "FatDiskIo: error %r\n", Status));\r
111   }\r
112 \r
113   return Status;\r
114 }\r
115 \r
116 VOID\r
117 FatAcquireLock (\r
118   VOID\r
119   )\r
120 /*++\r
121 \r
122 Routine Description:\r
123 \r
124   Lock the volume.\r
125 \r
126 Arguments:\r
127 \r
128   None.\r
129 \r
130 Returns:\r
131 \r
132   None.\r
133 \r
134 --*/\r
135 {\r
136   EfiAcquireLock (&FatFsLock);\r
137 }\r
138 \r
139 BOOLEAN\r
140 FatIsLocked (\r
141   VOID\r
142   )\r
143 /*++\r
144 \r
145 Routine Description:\r
146 \r
147   Get the locking status of the volume.\r
148 \r
149 Arguments:\r
150 \r
151   None.\r
152 \r
153 Returns:\r
154 \r
155   TRUE                  - The volume is locked.\r
156   FALSE                 - The volume is not locked.\r
157 \r
158 --*/\r
159 {\r
160   return (BOOLEAN) (FatFsLock.Lock);\r
161 }\r
162 \r
163 VOID\r
164 FatReleaseLock (\r
165   VOID\r
166   )\r
167 /*++\r
168 \r
169 Routine Description:\r
170 \r
171   Unlock the volume.\r
172 \r
173 Arguments:\r
174 \r
175   Null.\r
176 \r
177 Returns:\r
178 \r
179   None.\r
180 \r
181 --*/\r
182 {\r
183   EfiReleaseLock (&FatFsLock);\r
184 }\r
185 \r
186 VOID\r
187 FatFreeDirEnt (\r
188   IN FAT_DIRENT       *DirEnt\r
189   )\r
190 /*++\r
191 \r
192 Routine Description:\r
193 \r
194   Free directory entry.\r
195 \r
196 Arguments:\r
197 \r
198   DirEnt                - The directory entry to be freed.\r
199 \r
200 Returns:\r
201 \r
202   None.\r
203 \r
204 --*/\r
205 {\r
206   if (DirEnt->FileString != NULL) {\r
207     FreePool (DirEnt->FileString);\r
208   }\r
209 \r
210   FreePool (DirEnt);\r
211 }\r
212 \r
213 VOID\r
214 FatFreeVolume (\r
215   IN FAT_VOLUME       *Volume\r
216   )\r
217 /*++\r
218 \r
219 Routine Description:\r
220 \r
221   Free volume structure (including the contents of directory cache and disk cache).\r
222 \r
223 Arguments:\r
224 \r
225   Volume                - The volume structure to be freed.\r
226 \r
227 Returns:\r
228 \r
229   None.\r
230 \r
231 --*/\r
232 {\r
233   //\r
234   // Free disk cache\r
235   //\r
236   if (Volume->CacheBuffer != NULL) {\r
237     FreePool (Volume->CacheBuffer);\r
238   }\r
239   //\r
240   // Free directory cache\r
241   //\r
242   FatCleanupODirCache (Volume);\r
243   FreePool (Volume);\r
244 }\r
245 \r
246 VOID\r
247 FatEfiTimeToFatTime (\r
248   IN  EFI_TIME        *ETime,\r
249   OUT FAT_DATE_TIME   *FTime\r
250   )\r
251 /*++\r
252 \r
253 Routine Description:\r
254 \r
255   Translate EFI time to FAT time.\r
256 \r
257 Arguments:\r
258 \r
259   ETime                 - The time of EFI_TIME.\r
260   FTime                 - The time of FAT_DATE_TIME.\r
261 \r
262 Returns:\r
263 \r
264   None.\r
265 \r
266 --*/\r
267 {\r
268   //\r
269   // ignores timezone info in source ETime\r
270   //\r
271   if (ETime->Year > 1980) {\r
272     FTime->Date.Year = (UINT16) (ETime->Year - 1980);\r
273   }\r
274 \r
275   if (ETime->Year >= 1980 + FAT_MAX_YEAR_FROM_1980) {\r
276     FTime->Date.Year = FAT_MAX_YEAR_FROM_1980;\r
277   }\r
278 \r
279   FTime->Date.Month         = ETime->Month;\r
280   FTime->Date.Day           = ETime->Day;\r
281   FTime->Time.Hour          = ETime->Hour;\r
282   FTime->Time.Minute        = ETime->Minute;\r
283   FTime->Time.DoubleSecond  = (UINT16) (ETime->Second / 2);\r
284 }\r
285 \r
286 VOID\r
287 FatFatTimeToEfiTime (\r
288   IN  FAT_DATE_TIME     *FTime,\r
289   OUT EFI_TIME          *ETime\r
290   )\r
291 /*++\r
292 \r
293 Routine Description:\r
294 \r
295   Translate Fat time to EFI time.\r
296 \r
297 Arguments:\r
298 \r
299   FTime                 - The time of FAT_DATE_TIME.\r
300   ETime                 - The time of EFI_TIME.\r
301 \r
302 Returns:\r
303 \r
304   None.\r
305 \r
306 --*/\r
307 {\r
308   ETime->Year       = (UINT16) (FTime->Date.Year + 1980);\r
309   ETime->Month      = (UINT8) FTime->Date.Month;\r
310   ETime->Day        = (UINT8) FTime->Date.Day;\r
311   ETime->Hour       = (UINT8) FTime->Time.Hour;\r
312   ETime->Minute     = (UINT8) FTime->Time.Minute;\r
313   ETime->Second     = (UINT8) (FTime->Time.DoubleSecond * 2);\r
314   ETime->Nanosecond = 0;\r
315   ETime->TimeZone   = EFI_UNSPECIFIED_TIMEZONE;\r
316   ETime->Daylight   = 0;\r
317 }\r
318 \r
319 VOID\r
320 FatGetCurrentFatTime (\r
321   OUT FAT_DATE_TIME   *FatNow\r
322   )\r
323 /*++\r
324 \r
325 Routine Description:\r
326 \r
327   Get Current FAT time.\r
328 \r
329 Arguments:\r
330 \r
331   FatNow                - Current FAT time.\r
332 \r
333 Returns:\r
334 \r
335   None.\r
336 \r
337 --*/\r
338 {\r
339   EFI_TIME  Now;\r
340   gRT->GetTime (&Now, NULL);\r
341   FatEfiTimeToFatTime (&Now, FatNow);\r
342 }\r
343 \r
344 BOOLEAN\r
345 FatIsValidTime (\r
346   IN EFI_TIME         *Time\r
347   )\r
348 /*++\r
349 \r
350 Routine Description:\r
351 \r
352   Check whether a time is valid.\r
353 \r
354 Arguments:\r
355 \r
356   Time                  - The time of EFI_TIME.\r
357 \r
358 Returns:\r
359 \r
360   TRUE                  - The time is valid.\r
361   FALSE                 - The time is not valid.\r
362 \r
363 --*/\r
364 {\r
365   static UINT8  MonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
366   UINTN         Day;\r
367   BOOLEAN       ValidTime;\r
368 \r
369   ValidTime = TRUE;\r
370 \r
371   //\r
372   // Check the fields for range problems\r
373   // Fat can only support from 1980\r
374   //\r
375   if (Time->Year < 1980 ||\r
376       Time->Month < 1 ||\r
377       Time->Month > 12 ||\r
378       Time->Day < 1 ||\r
379       Time->Day > 31 ||\r
380       Time->Hour > 23 ||\r
381       Time->Minute > 59 ||\r
382       Time->Second > 59 ||\r
383       Time->Nanosecond > 999999999\r
384       ) {\r
385 \r
386     ValidTime = FALSE;\r
387 \r
388   } else {\r
389     //\r
390     // Perform a more specific check of the day of the month\r
391     //\r
392     Day = MonthDays[Time->Month - 1];\r
393     if (Time->Month == 2 && IS_LEAP_YEAR (Time->Year)) {\r
394       Day += 1;\r
395       //\r
396       // 1 extra day this month\r
397       //\r
398     }\r
399     if (Time->Day > Day) {\r
400       ValidTime = FALSE;\r
401     }\r
402   }\r
403 \r
404   return ValidTime;\r
405 }\r