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