]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/FatPei/FatLiteApi.c
FatPkg: Add FAT PEIM
[mirror_edk2.git] / FatPkg / FatPei / FatLiteApi.c
CommitLineData
2f4dfa84
JJ
1/** @file\r
2 FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.\r
3\r
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
5\r
6This program and the accompanying materials are licensed and made available\r
7under the terms and conditions of the BSD License which accompanies this\r
8distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "FatLitePeim.h"\r
17\r
18PEI_FAT_PRIVATE_DATA *mPrivateData = NULL;\r
19\r
20/**\r
21 BlockIo installation nofication function. Find out all the current BlockIO\r
22 PPIs in the system and add them into private data. Assume there is\r
23\r
24 @param PeiServices General purpose services available to every \r
25 PEIM. \r
26 @param NotifyDescriptor The typedef structure of the notification \r
27 descriptor. Not used in this function. \r
28 @param Ppi The typedef structure of the PPI descriptor. \r
29 Not used in this function. \r
30\r
31 @retval EFI_SUCCESS The function completed successfully.\r
32\r
33**/\r
34EFI_STATUS\r
35EFIAPI\r
36BlockIoNotifyEntry (\r
37 IN EFI_PEI_SERVICES **PeiServices,\r
38 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
39 IN VOID *Ppi\r
40 );\r
41\r
42\r
43/**\r
44 Discover all the block I/O devices to find the FAT volume.\r
45\r
46 @param PrivateData Global memory map for accessing global \r
47 variables. \r
48\r
49 @retval EFI_SUCCESS The function completed successfully.\r
50\r
51**/\r
52EFI_STATUS\r
53UpdateBlocksAndVolumes (\r
54 IN OUT PEI_FAT_PRIVATE_DATA *PrivateData\r
55 )\r
56{\r
57 EFI_STATUS Status;\r
58 EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;\r
59 UINTN BlockIoPpiInstance;\r
60 EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;\r
61 UINTN NumberBlockDevices;\r
62 UINTN Index;\r
63 EFI_PEI_BLOCK_IO_MEDIA Media;\r
64 PEI_FAT_VOLUME Volume;\r
65 EFI_PEI_SERVICES **PeiServices;\r
66\r
67 PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();\r
68\r
69 //\r
70 // Clean up caches\r
71 //\r
72 for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {\r
73 PrivateData->CacheBuffer[Index].Valid = FALSE;\r
74 }\r
75\r
76 PrivateData->BlockDeviceCount = 0;\r
77\r
78 //\r
79 // Find out all Block Io Ppi instances within the system\r
80 // Assuming all device Block Io Peims are dispatched already\r
81 //\r
82 for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {\r
83 Status = PeiServicesLocatePpi (\r
84 &gEfiPeiVirtualBlockIoPpiGuid,\r
85 BlockIoPpiInstance,\r
86 &TempPpiDescriptor,\r
87 (VOID **) &BlockIoPpi\r
88 );\r
89 if (EFI_ERROR (Status)) {\r
90 //\r
91 // Done with all Block Io Ppis\r
92 //\r
93 break;\r
94 }\r
95\r
96 Status = BlockIoPpi->GetNumberOfBlockDevices (\r
97 PeiServices,\r
98 BlockIoPpi,\r
99 &NumberBlockDevices\r
100 );\r
101 if (EFI_ERROR (Status)) {\r
102 continue;\r
103 }\r
104\r
105 for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {\r
106\r
107 Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
108 PeiServices,\r
109 BlockIoPpi,\r
110 Index,\r
111 &Media\r
112 );\r
113 if (EFI_ERROR (Status) || !Media.MediaPresent) {\r
114 continue;\r
115 }\r
116\r
117 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize;\r
118 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;\r
119 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;\r
120 //\r
121 // Not used here\r
122 //\r
123 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical = FALSE;\r
124 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE;\r
125\r
126 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi;\r
127 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8) Index;\r
128 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;\r
129\r
130 PrivateData->BlockDeviceCount++;\r
131 }\r
132 }\r
133 //\r
134 // Find out all logical devices\r
135 //\r
136 FatFindPartitions (PrivateData);\r
137\r
138 //\r
139 // Build up file system volume array\r
140 //\r
141 PrivateData->VolumeCount = 0;\r
142 for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {\r
143 Volume.BlockDeviceNo = Index;\r
144 Status = FatGetBpbInfo (PrivateData, &Volume);\r
145 if (Status == EFI_SUCCESS) {\r
146 //\r
147 // Add the detected volume to the volume array\r
148 //\r
149 CopyMem (\r
150 (UINT8 *) &(PrivateData->Volume[PrivateData->VolumeCount]),\r
151 (UINT8 *) &Volume,\r
152 sizeof (PEI_FAT_VOLUME)\r
153 );\r
154 PrivateData->VolumeCount += 1;\r
155 if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) {\r
156 break;\r
157 }\r
158 }\r
159 }\r
160\r
161 return EFI_SUCCESS;\r
162}\r
163\r
164\r
165/**\r
166 BlockIo installation notification function. Find out all the current BlockIO\r
167 PPIs in the system and add them into private data. Assume there is\r
168\r
169 @param PeiServices General purpose services available to every \r
170 PEIM. \r
171 @param NotifyDescriptor The typedef structure of the notification \r
172 descriptor. Not used in this function. \r
173 @param Ppi The typedef structure of the PPI descriptor. \r
174 Not used in this function. \r
175\r
176 @retval EFI_SUCCESS The function completed successfully.\r
177\r
178**/\r
179EFI_STATUS\r
180EFIAPI\r
181BlockIoNotifyEntry (\r
182 IN EFI_PEI_SERVICES **PeiServices,\r
183 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
184 IN VOID *Ppi\r
185 )\r
186{\r
187 UpdateBlocksAndVolumes (mPrivateData);\r
188\r
189 return EFI_SUCCESS;\r
190}\r
191\r
192\r
193/**\r
194 Installs the Device Recovery Module PPI, Initialize BlockIo Ppi\r
195 installation notification\r
196\r
197 @param FileHandle Handle of the file being invoked. Type \r
198 EFI_PEI_FILE_HANDLE is defined in \r
199 FfsFindNextFile(). \r
200 @param PeiServices Describes the list of possible PEI Services. \r
201\r
202 @retval EFI_SUCCESS The entry point was executed successfully. \r
203 @retval EFI_OUT_OF_RESOURCES There is no enough memory to complete the \r
204 operations.\r
205\r
206**/\r
207EFI_STATUS\r
208EFIAPI\r
209FatPeimEntry (\r
210 IN EFI_PEI_FILE_HANDLE FileHandle,\r
211 IN CONST EFI_PEI_SERVICES **PeiServices\r
212 )\r
213{\r
214 EFI_STATUS Status;\r
215 EFI_PHYSICAL_ADDRESS Address;\r
216 PEI_FAT_PRIVATE_DATA *PrivateData;\r
217\r
218 Status = PeiServicesRegisterForShadow (FileHandle);\r
219 if (!EFI_ERROR (Status)) {\r
220 return Status;\r
221 }\r
222\r
223 Status = PeiServicesAllocatePages (\r
224 EfiBootServicesCode,\r
225 (sizeof (PEI_FAT_PRIVATE_DATA) - 1) / PEI_FAT_MEMMORY_PAGE_SIZE + 1,\r
226 &Address\r
227 );\r
228 if (EFI_ERROR (Status)) {\r
229 return EFI_OUT_OF_RESOURCES;\r
230 }\r
231\r
232 PrivateData = (PEI_FAT_PRIVATE_DATA *) (UINTN) Address;\r
233\r
234 //\r
235 // Initialize Private Data (to zero, as is required by subsequent operations)\r
236 //\r
237 ZeroMem ((UINT8 *) PrivateData, sizeof (PEI_FAT_PRIVATE_DATA));\r
238\r
239 PrivateData->Signature = PEI_FAT_PRIVATE_DATA_SIGNATURE;\r
240\r
241 //\r
242 // Installs Ppi\r
243 //\r
244 PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules = GetNumberRecoveryCapsules;\r
245 PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo = GetRecoveryCapsuleInfo;\r
246 PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule = LoadRecoveryCapsule;\r
247\r
248 PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
249 PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid;\r
250 PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;\r
251\r
252 Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);\r
253 if (EFI_ERROR (Status)) {\r
254 return EFI_OUT_OF_RESOURCES;\r
255 }\r
256 //\r
257 // Other initializations\r
258 //\r
259 PrivateData->BlockDeviceCount = 0;\r
260\r
261 UpdateBlocksAndVolumes (PrivateData);\r
262\r
263 //\r
264 // PrivateData is allocated now, set it to the module variable\r
265 //\r
266 mPrivateData = PrivateData;\r
267\r
268 //\r
269 // Installs Block Io Ppi notification function\r
270 //\r
271 PrivateData->NotifyDescriptor.Flags =\r
272 (\r
273 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |\r
274 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST\r
275 );\r
276 PrivateData->NotifyDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid;\r
277 PrivateData->NotifyDescriptor.Notify = BlockIoNotifyEntry;\r
278 return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);\r
279}\r
280\r
281\r
282/**\r
283 Returns the number of DXE capsules residing on the device.\r
284\r
285 This function searches for DXE capsules from the associated device and returns\r
286 the number and maximum size in bytes of the capsules discovered. Entry 1 is \r
287 assumed to be the highest load priority and entry N is assumed to be the lowest \r
288 priority.\r
289\r
290 @param[in] PeiServices General-purpose services that are available \r
291 to every PEIM\r
292 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
293 instance.\r
294 @param[out] NumberRecoveryCapsules Pointer to a caller-allocated UINTN. On \r
295 output, *NumberRecoveryCapsules contains \r
296 the number of recovery capsule images \r
297 available for retrieval from this PEIM \r
298 instance.\r
299\r
300 @retval EFI_SUCCESS One or more capsules were discovered.\r
301 @retval EFI_DEVICE_ERROR A device error occurred.\r
302 @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.\r
303\r
304**/\r
305EFI_STATUS\r
306EFIAPI\r
307GetNumberRecoveryCapsules (\r
308 IN EFI_PEI_SERVICES **PeiServices,\r
309 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,\r
310 OUT UINTN *NumberRecoveryCapsules\r
311 )\r
312{\r
313 EFI_STATUS Status;\r
314 PEI_FAT_PRIVATE_DATA *PrivateData;\r
315 UINTN Index;\r
316 UINTN RecoveryCapsuleCount;\r
317 PEI_FILE_HANDLE Handle;\r
318\r
319 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);\r
320\r
321 //\r
322 // Search each volume in the root directory for the Recovery capsule\r
323 //\r
324 RecoveryCapsuleCount = 0;\r
325 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
326 Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
327 if (EFI_ERROR (Status)) {\r
328 continue;\r
329 }\r
330\r
331 RecoveryCapsuleCount++;\r
332 }\r
333\r
334 *NumberRecoveryCapsules = RecoveryCapsuleCount;\r
335\r
336 if (*NumberRecoveryCapsules == 0) {\r
337 return EFI_NOT_FOUND;\r
338 }\r
339\r
340 return EFI_SUCCESS;\r
341}\r
342\r
343\r
344/**\r
345 Returns the size and type of the requested recovery capsule.\r
346\r
347 This function gets the size and type of the capsule specified by CapsuleInstance.\r
348\r
349 @param[in] PeiServices General-purpose services that are available to every PEIM\r
350 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI \r
351 instance.\r
352 @param[in] CapsuleInstance Specifies for which capsule instance to retrieve \r
353 the information. This parameter must be between \r
354 one and the value returned by GetNumberRecoveryCapsules() \r
355 in NumberRecoveryCapsules.\r
356 @param[out] Size A pointer to a caller-allocated UINTN in which \r
357 the size of the requested recovery module is \r
358 returned.\r
359 @param[out] CapsuleType A pointer to a caller-allocated EFI_GUID in which \r
360 the type of the requested recovery capsule is \r
361 returned. The semantic meaning of the value \r
362 returned is defined by the implementation.\r
363\r
364 @retval EFI_SUCCESS One or more capsules were discovered.\r
365 @retval EFI_DEVICE_ERROR A device error occurred.\r
366 @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.\r
367\r
368**/\r
369EFI_STATUS\r
370EFIAPI\r
371GetRecoveryCapsuleInfo (\r
372 IN EFI_PEI_SERVICES **PeiServices,\r
373 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,\r
374 IN UINTN CapsuleInstance,\r
375 OUT UINTN *Size,\r
376 OUT EFI_GUID *CapsuleType\r
377 )\r
378{\r
379 EFI_STATUS Status;\r
380 PEI_FAT_PRIVATE_DATA *PrivateData;\r
381 UINTN Index;\r
382 UINTN BlockDeviceNo;\r
383 UINTN RecoveryCapsuleCount;\r
384 PEI_FILE_HANDLE Handle;\r
385 UINTN NumberRecoveryCapsules;\r
386\r
387 Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);\r
388\r
389 if (EFI_ERROR (Status)) {\r
390 return Status;\r
391 }\r
392\r
393 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
394 CapsuleInstance = CapsuleInstance + 1;\r
395 }\r
396\r
397 if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {\r
398 return EFI_NOT_FOUND;\r
399 }\r
400\r
401 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);\r
402\r
403 //\r
404 // Search each volume in the root directory for the Recovery capsule\r
405 //\r
406 RecoveryCapsuleCount = 0;\r
407 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
408 Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
409\r
410 if (EFI_ERROR (Status)) {\r
411 continue;\r
412 }\r
413\r
414 if (CapsuleInstance - 1 == RecoveryCapsuleCount) {\r
415 //\r
416 // Get file size\r
417 //\r
418 *Size = (UINTN) (((PEI_FAT_FILE *) Handle)->FileSize);\r
419\r
420 //\r
421 // Find corresponding physical block device\r
422 //\r
423 BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo;\r
424 while (PrivateData->BlockDevice[BlockDeviceNo].Logical && BlockDeviceNo < PrivateData->BlockDeviceCount) {\r
425 BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo;\r
426 }\r
427 //\r
428 // Fill in the Capsule Type GUID according to the block device type\r
429 //\r
430 if (BlockDeviceNo < PrivateData->BlockDeviceCount) {\r
431 switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {\r
432 case LegacyFloppy:\r
433 CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);\r
434 break;\r
435\r
436 case IdeCDROM:\r
437 case IdeLS120:\r
438 CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
439 break;\r
440\r
441 case UsbMassStorage:\r
442 CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
443 break;\r
444\r
445 default:\r
446 break;\r
447 }\r
448 }\r
449\r
450 return EFI_SUCCESS;\r
451 }\r
452\r
453 RecoveryCapsuleCount++;\r
454 }\r
455\r
456 return EFI_NOT_FOUND;\r
457}\r
458\r
459\r
460/**\r
461 Loads a DXE capsule from some media into memory.\r
462\r
463 This function, by whatever mechanism, retrieves a DXE capsule from some device\r
464 and loads it into memory. Note that the published interface is device neutral.\r
465\r
466 @param[in] PeiServices General-purpose services that are available \r
467 to every PEIM\r
468 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
469 instance.\r
470 @param[in] CapsuleInstance Specifies which capsule instance to retrieve.\r
471 @param[out] Buffer Specifies a caller-allocated buffer in which \r
472 the requested recovery capsule will be returned.\r
473\r
474 @retval EFI_SUCCESS The capsule was loaded correctly.\r
475 @retval EFI_DEVICE_ERROR A device error occurred.\r
476 @retval EFI_NOT_FOUND A requested recovery DXE capsule cannot be found.\r
477\r
478**/\r
479EFI_STATUS\r
480EFIAPI\r
481LoadRecoveryCapsule (\r
482 IN EFI_PEI_SERVICES **PeiServices,\r
483 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,\r
484 IN UINTN CapsuleInstance,\r
485 OUT VOID *Buffer\r
486 )\r
487{\r
488 EFI_STATUS Status;\r
489 PEI_FAT_PRIVATE_DATA *PrivateData;\r
490 UINTN Index;\r
491 UINTN RecoveryCapsuleCount;\r
492 PEI_FILE_HANDLE Handle;\r
493 UINTN NumberRecoveryCapsules;\r
494\r
495 Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);\r
496\r
497 if (EFI_ERROR (Status)) {\r
498 return Status;\r
499 }\r
500\r
501 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
502 CapsuleInstance = CapsuleInstance + 1;\r
503 }\r
504\r
505 if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {\r
506 return EFI_NOT_FOUND;\r
507 }\r
508\r
509 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);\r
510\r
511 //\r
512 // Search each volume in the root directory for the Recovery capsule\r
513 //\r
514 RecoveryCapsuleCount = 0;\r
515 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
516 Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
517 if (EFI_ERROR (Status)) {\r
518 continue;\r
519 }\r
520\r
521 if (CapsuleInstance - 1 == RecoveryCapsuleCount) {\r
522\r
523 Status = FatReadFile (\r
524 PrivateData,\r
525 Handle,\r
526 (UINTN) (((PEI_FAT_FILE *) Handle)->FileSize),\r
527 Buffer\r
528 );\r
529 return Status;\r
530 }\r
531\r
532 RecoveryCapsuleCount++;\r
533 }\r
534\r
535 return EFI_NOT_FOUND;\r
536}\r
537\r
538\r
539/**\r
540 Finds the recovery file on a FAT volume.\r
541 This function finds the the recovery file named FileName on a specified FAT volume and returns\r
542 its FileHandle pointer.\r
543\r
544 @param PrivateData Global memory map for accessing global \r
545 variables. \r
546 @param VolumeIndex The index of the volume. \r
547 @param FileName The recovery file name to find. \r
548 @param Handle The output file handle. \r
549\r
550 @retval EFI_DEVICE_ERROR Some error occured when operating the FAT \r
551 volume. \r
552 @retval EFI_NOT_FOUND The recovery file was not found. \r
553 @retval EFI_SUCCESS The recovery file was successfully found on the \r
554 FAT volume.\r
555\r
556**/\r
557EFI_STATUS\r
558FindRecoveryFile (\r
559 IN PEI_FAT_PRIVATE_DATA *PrivateData,\r
560 IN UINTN VolumeIndex,\r
561 IN CHAR16 *FileName,\r
562 OUT PEI_FILE_HANDLE *Handle\r
563 )\r
564{\r
565 EFI_STATUS Status;\r
566 PEI_FAT_FILE Parent;\r
567 PEI_FAT_FILE *File;\r
568\r
569 File = &PrivateData->File;\r
570\r
571 //\r
572 // VolumeIndex must be less than PEI_FAT_MAX_VOLUME because PrivateData->VolumeCount\r
573 // cannot be larger than PEI_FAT_MAX_VOLUME when detecting recovery volume.\r
574 //\r
575 ASSERT (VolumeIndex < PEI_FAT_MAX_VOLUME);\r
576\r
577 //\r
578 // Construct root directory file\r
579 //\r
580 Parent.IsFixedRootDir = (BOOLEAN) ((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);\r
581 Parent.Attributes = FAT_ATTR_DIRECTORY;\r
582 Parent.CurrentPos = 0;\r
583 Parent.CurrentCluster = Parent.IsFixedRootDir ? 0 : PrivateData->Volume[VolumeIndex].RootDirCluster;\r
584 Parent.StartingCluster = Parent.CurrentCluster;\r
585 Parent.Volume = &PrivateData->Volume[VolumeIndex];\r
586\r
587 Status = FatSetFilePos (PrivateData, &Parent, 0);\r
588 if (EFI_ERROR (Status)) {\r
589 return EFI_DEVICE_ERROR;\r
590 }\r
591 //\r
592 // Search for recovery capsule in root directory\r
593 //\r
594 Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);\r
595 while (Status == EFI_SUCCESS) {\r
596 if (EngStriColl (PrivateData, FileName, File->FileName)) {\r
597 break;\r
598 }\r
599\r
600 Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);\r
601 }\r
602\r
603 if (EFI_ERROR (Status)) {\r
604 return EFI_NOT_FOUND;\r
605 }\r
606\r
607 *Handle = File;\r
608\r
609 return EFI_SUCCESS;\r
610\r
611}\r