]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
MdeModulePkg/UDF: Fix creation of UDF logical partition
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / PartitionDxe / Udf.c
CommitLineData
8aafec2c
PA
1/** @file\r
2 Scan for an UDF file system on a formatted media.\r
3\r
4 Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>\r
5\r
6 This program and the accompanying materials are licensed and made available\r
7 under the terms and conditions of the BSD License which accompanies this\r
8 distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
12 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13**/\r
14\r
15#include "Partition.h"\r
16\r
17//\r
18// C5BD4D42-1A76-4996-8956-73CDA326CD0A\r
19//\r
20#define EFI_UDF_DEVICE_PATH_GUID \\r
21 { 0xC5BD4D42, 0x1A76, 0x4996, \\r
22 { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \\r
23 }\r
24\r
25typedef struct {\r
26 VENDOR_DEVICE_PATH DevicePath;\r
27 EFI_DEVICE_PATH_PROTOCOL End;\r
28} UDF_DEVICE_PATH;\r
29\r
3f92b104
HW
30//\r
31// Vendor-Defined Device Path GUID for UDF file system\r
32//\r
33EFI_GUID gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;\r
34\r
8aafec2c
PA
35//\r
36// Vendor-Defined Media Device Path for UDF file system\r
37//\r
38UDF_DEVICE_PATH gUdfDevicePath = {\r
39 { { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
40 { sizeof (VENDOR_DEVICE_PATH), 0 } },\r
41 EFI_UDF_DEVICE_PATH_GUID\r
42 },\r
43 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
44 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
45 }\r
46};\r
47\r
077f8c43
HW
48/**\r
49 Find the anchor volume descriptor pointer.\r
50\r
51 @param[in] BlockIo BlockIo interface.\r
52 @param[in] DiskIo DiskIo interface.\r
53 @param[out] AnchorPoint Anchor volume descriptor pointer.\r
54\r
55 @retval EFI_SUCCESS Anchor volume descriptor pointer found.\r
56 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
57 @retval other Anchor volume descriptor pointer not found.\r
58\r
59**/\r
8aafec2c
PA
60EFI_STATUS\r
61FindAnchorVolumeDescriptorPointer (\r
62 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
63 IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
64 OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint\r
65 )\r
66{\r
baaa3cee
PA
67 EFI_STATUS Status;\r
68 UINT32 BlockSize;\r
69 EFI_LBA EndLBA;\r
70 EFI_LBA DescriptorLBAs[4];\r
71 UINTN Index;\r
72 UDF_DESCRIPTOR_TAG *DescriptorTag;\r
8aafec2c 73\r
c05cae55
DB
74 BlockSize = BlockIo->Media->BlockSize;\r
75 EndLBA = BlockIo->Media->LastBlock;\r
76 DescriptorLBAs[0] = 256;\r
77 DescriptorLBAs[1] = EndLBA - 256;\r
78 DescriptorLBAs[2] = EndLBA;\r
79 DescriptorLBAs[3] = 512;\r
80\r
8aafec2c
PA
81 for (Index = 0; Index < ARRAY_SIZE (DescriptorLBAs); Index++) {\r
82 Status = DiskIo->ReadDisk (\r
83 DiskIo,\r
84 BlockIo->Media->MediaId,\r
85 MultU64x32 (DescriptorLBAs[Index], BlockSize),\r
86 sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER),\r
87 (VOID *)AnchorPoint\r
88 );\r
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
baaa3cee
PA
92\r
93 DescriptorTag = &AnchorPoint->DescriptorTag;\r
94\r
8aafec2c
PA
95 //\r
96 // Check if read LBA has a valid AVDP descriptor.\r
97 //\r
baaa3cee 98 if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {\r
8aafec2c
PA
99 return EFI_SUCCESS;\r
100 }\r
101 }\r
102 //\r
103 // No AVDP found.\r
104 //\r
105 return EFI_VOLUME_CORRUPTED;\r
106}\r
107\r
108/**\r
baaa3cee 109 Find UDF volume identifiers in a Volume Recognition Sequence.\r
8aafec2c 110\r
baaa3cee
PA
111 @param[in] BlockIo BlockIo interface.\r
112 @param[in] DiskIo DiskIo interface.\r
8aafec2c 113\r
baaa3cee
PA
114 @retval EFI_SUCCESS UDF volume identifiers were found.\r
115 @retval EFI_NOT_FOUND UDF volume identifiers were not found.\r
116 @retval other Failed to perform disk I/O.\r
8aafec2c
PA
117\r
118**/\r
119EFI_STATUS\r
baaa3cee 120FindUdfVolumeIdentifiers (\r
8aafec2c
PA
121 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
122 IN EFI_DISK_IO_PROTOCOL *DiskIo\r
123 )\r
124{\r
125 EFI_STATUS Status;\r
126 UINT64 Offset;\r
127 UINT64 EndDiskOffset;\r
128 CDROM_VOLUME_DESCRIPTOR VolDescriptor;\r
129 CDROM_VOLUME_DESCRIPTOR TerminatingVolDescriptor;\r
8aafec2c
PA
130\r
131 ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));\r
132\r
133 //\r
134 // Start Volume Recognition Sequence\r
135 //\r
136 EndDiskOffset = MultU64x32 (BlockIo->Media->LastBlock,\r
137 BlockIo->Media->BlockSize);\r
138\r
139 for (Offset = UDF_VRS_START_OFFSET; Offset < EndDiskOffset;\r
140 Offset += UDF_LOGICAL_SECTOR_SIZE) {\r
141 //\r
142 // Check if block device has a Volume Structure Descriptor and an Extended\r
143 // Area.\r
144 //\r
145 Status = DiskIo->ReadDisk (\r
146 DiskIo,\r
147 BlockIo->Media->MediaId,\r
148 Offset,\r
149 sizeof (CDROM_VOLUME_DESCRIPTOR),\r
150 (VOID *)&VolDescriptor\r
151 );\r
152 if (EFI_ERROR (Status)) {\r
153 return Status;\r
154 }\r
155\r
156 if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
157 (VOID *)UDF_BEA_IDENTIFIER,\r
158 sizeof (VolDescriptor.Unknown.Id)) == 0) {\r
159 break;\r
160 }\r
161\r
162 if ((CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
163 (VOID *)CDVOL_ID,\r
164 sizeof (VolDescriptor.Unknown.Id)) != 0) ||\r
165 (CompareMem ((VOID *)&VolDescriptor,\r
166 (VOID *)&TerminatingVolDescriptor,\r
167 sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {\r
baaa3cee 168 return EFI_NOT_FOUND;\r
8aafec2c
PA
169 }\r
170 }\r
171\r
172 //\r
173 // Look for "NSR0{2,3}" identifiers in the Extended Area.\r
174 //\r
175 Offset += UDF_LOGICAL_SECTOR_SIZE;\r
176 if (Offset >= EndDiskOffset) {\r
baaa3cee 177 return EFI_NOT_FOUND;\r
8aafec2c
PA
178 }\r
179\r
180 Status = DiskIo->ReadDisk (\r
181 DiskIo,\r
182 BlockIo->Media->MediaId,\r
183 Offset,\r
184 sizeof (CDROM_VOLUME_DESCRIPTOR),\r
185 (VOID *)&VolDescriptor\r
186 );\r
187 if (EFI_ERROR (Status)) {\r
188 return Status;\r
189 }\r
190\r
191 if ((CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
192 (VOID *)UDF_NSR2_IDENTIFIER,\r
193 sizeof (VolDescriptor.Unknown.Id)) != 0) &&\r
194 (CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
195 (VOID *)UDF_NSR3_IDENTIFIER,\r
196 sizeof (VolDescriptor.Unknown.Id)) != 0)) {\r
baaa3cee 197 return EFI_NOT_FOUND;\r
8aafec2c
PA
198 }\r
199\r
200 //\r
201 // Look for "TEA01" identifier in the Extended Area\r
202 //\r
203 Offset += UDF_LOGICAL_SECTOR_SIZE;\r
204 if (Offset >= EndDiskOffset) {\r
baaa3cee 205 return EFI_NOT_FOUND;\r
8aafec2c
PA
206 }\r
207\r
208 Status = DiskIo->ReadDisk (\r
209 DiskIo,\r
210 BlockIo->Media->MediaId,\r
211 Offset,\r
212 sizeof (CDROM_VOLUME_DESCRIPTOR),\r
213 (VOID *)&VolDescriptor\r
214 );\r
215 if (EFI_ERROR (Status)) {\r
216 return Status;\r
217 }\r
218\r
219 if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
220 (VOID *)UDF_TEA_IDENTIFIER,\r
221 sizeof (VolDescriptor.Unknown.Id)) != 0) {\r
baaa3cee
PA
222 return EFI_NOT_FOUND;\r
223 }\r
224\r
225 return EFI_SUCCESS;\r
226}\r
227\r
228/**\r
229 Check if Logical Volume Descriptor is supported by current EDK2 UDF file\r
230 system implementation.\r
231\r
232 @param[in] LogicalVolDesc Logical Volume Descriptor pointer.\r
233\r
234 @retval TRUE Logical Volume Descriptor is supported.\r
235 @retval FALSE Logical Volume Descriptor is not supported.\r
236\r
237**/\r
238BOOLEAN\r
239IsLogicalVolumeDescriptorSupported (\r
240 UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc\r
241 )\r
242{\r
243 //\r
244 // Check for a valid UDF revision range\r
245 //\r
246 switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {\r
247 case 0x0102:\r
248 case 0x0150:\r
249 case 0x0200:\r
250 case 0x0201:\r
251 case 0x0250:\r
252 case 0x0260:\r
253 break;\r
254 default:\r
255 return FALSE;\r
256 }\r
257\r
258 //\r
259 // Check for a single Partition Map\r
260 //\r
261 if (LogicalVolDesc->NumberOfPartitionMaps > 1) {\r
262 return FALSE;\r
263 }\r
264 //\r
265 // UDF 1.02 revision supports only Type 1 (Physical) partitions, but\r
266 // let's check it any way.\r
267 //\r
268 // PartitionMap[0] -> type\r
269 // PartitionMap[1] -> length (in bytes)\r
270 //\r
271 if (LogicalVolDesc->PartitionMaps[0] != 1 ||\r
272 LogicalVolDesc->PartitionMaps[1] != 6) {\r
273 return FALSE;\r
274 }\r
275\r
276 return TRUE;\r
277}\r
278\r
279/**\r
280 Find UDF logical volume location and whether it is supported by current EDK2\r
281 UDF file system implementation.\r
282\r
283 @param[in] BlockIo BlockIo interface.\r
284 @param[in] DiskIo DiskIo interface.\r
285 @param[in] AnchorPoint Anchor volume descriptor pointer.\r
286 @param[out] MainVdsStartBlock Main VDS starting block number.\r
287 @param[out] MainVdsEndBlock Main VDS ending block number.\r
288\r
289 @retval EFI_SUCCESS UDF logical volume was found.\r
290 @retval EFI_VOLUME_CORRUPTED UDF file system structures are corrupted.\r
291 @retval EFI_UNSUPPORTED UDF logical volume is not supported.\r
292 @retval other Failed to perform disk I/O.\r
293\r
294**/\r
295EFI_STATUS\r
296FindLogicalVolumeLocation (\r
297 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
298 IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
299 IN UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint,\r
300 OUT UINT64 *MainVdsStartBlock,\r
301 OUT UINT64 *MainVdsEndBlock\r
302 )\r
303{\r
304 EFI_STATUS Status;\r
305 UINT32 BlockSize;\r
306 EFI_LBA LastBlock;\r
307 UDF_EXTENT_AD *ExtentAd;\r
308 UINT64 SeqBlocksNum;\r
309 UINT64 SeqStartBlock;\r
310 UINT64 GuardMainVdsStartBlock;\r
311 VOID *Buffer;\r
312 UINT64 SeqEndBlock;\r
313 BOOLEAN StopSequence;\r
314 UINTN LvdsCount;\r
315 UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;\r
316 UDF_DESCRIPTOR_TAG *DescriptorTag;\r
317\r
318 BlockSize = BlockIo->Media->BlockSize;\r
319 LastBlock = BlockIo->Media->LastBlock;\r
320 ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;\r
321\r
322 //\r
323 // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent\r
324 //\r
325 // The Main Volume Descriptor Sequence Extent shall have a minimum length of\r
326 // 16 logical sectors.\r
327 //\r
328 // Also make sure it does not exceed maximum number of blocks in the disk.\r
329 //\r
330 SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);\r
331 if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {\r
332 return EFI_VOLUME_CORRUPTED;\r
333 }\r
334\r
335 //\r
336 // Check for valid Volume Descriptor Sequence starting block number\r
337 //\r
338 SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;\r
339 if (SeqStartBlock > LastBlock ||\r
340 SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {\r
341 return EFI_VOLUME_CORRUPTED;\r
342 }\r
343\r
344 GuardMainVdsStartBlock = SeqStartBlock;\r
345\r
346 //\r
347 // Allocate buffer for reading disk blocks\r
348 //\r
349 Buffer = AllocateZeroPool ((UINTN)BlockSize);\r
350 if (Buffer == NULL) {\r
351 return EFI_OUT_OF_RESOURCES;\r
352 }\r
353\r
354 SeqEndBlock = SeqStartBlock + SeqBlocksNum;\r
355 StopSequence = FALSE;\r
356 LvdsCount = 0;\r
357 Status = EFI_VOLUME_CORRUPTED;\r
358 //\r
359 // Start Main Volume Descriptor Sequence\r
360 //\r
361 for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {\r
362 //\r
363 // Read disk block\r
364 //\r
365 Status = BlockIo->ReadBlocks (\r
366 BlockIo,\r
367 BlockIo->Media->MediaId,\r
368 SeqStartBlock,\r
369 BlockSize,\r
370 Buffer\r
371 );\r
372 if (EFI_ERROR (Status)) {\r
373 goto Out_Free;\r
374 }\r
375\r
376 DescriptorTag = Buffer;\r
377\r
378 //\r
379 // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence\r
380 //\r
381 // - A Volume Descriptor Sequence shall contain one or more Primary Volume\r
382 // Descriptors.\r
383 // - A Volume Descriptor Sequence shall contain zero or more Implementation\r
384 // Use Volume Descriptors.\r
385 // - A Volume Descriptor Sequence shall contain zero or more Partition\r
386 // Descriptors.\r
387 // - A Volume Descriptor Sequence shall contain zero or more Logical Volume\r
388 // Descriptors.\r
389 // - A Volume Descriptor Sequence shall contain zero or more Unallocated\r
390 // Space Descriptors.\r
391 //\r
392 switch (DescriptorTag->TagIdentifier) {\r
393 case UdfPrimaryVolumeDescriptor:\r
394 case UdfImplemenationUseVolumeDescriptor:\r
395 case UdfPartitionDescriptor:\r
396 case UdfUnallocatedSpaceDescriptor:\r
397 break;\r
398\r
399 case UdfLogicalVolumeDescriptor:\r
400 LogicalVolDesc = Buffer;\r
401\r
402 //\r
403 // Check for existence of a single LVD and whether it is supported by\r
404 // current EDK2 UDF file system implementation.\r
405 //\r
406 if (++LvdsCount > 1 ||\r
407 !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {\r
408 Status = EFI_UNSUPPORTED;\r
409 StopSequence = TRUE;\r
410 }\r
411\r
412 break;\r
413\r
414 case UdfTerminatingDescriptor:\r
415 //\r
416 // Stop the sequence when we find a Terminating Descriptor\r
417 // (aka Unallocated Sector), se we don't have to walk all the unallocated\r
418 // area unnecessarily.\r
419 //\r
420 StopSequence = TRUE;\r
421 break;\r
422\r
423 default:\r
424 //\r
425 // An invalid Volume Descriptor has been found in the sequece. Volume is\r
426 // corrupted.\r
427 //\r
428 Status = EFI_VOLUME_CORRUPTED;\r
429 goto Out_Free;\r
430 }\r
431 }\r
432\r
433 //\r
434 // Check if LVD was found\r
435 //\r
436 if (!EFI_ERROR (Status) && LvdsCount == 1) {\r
437 *MainVdsStartBlock = GuardMainVdsStartBlock;\r
438 //\r
439 // We do not need to read either LVD or PD descriptors to know the last\r
440 // valid block in the found UDF file system. It's already LastBlock.\r
441 //\r
442 *MainVdsEndBlock = LastBlock;\r
443\r
444 Status = EFI_SUCCESS;\r
445 }\r
446\r
447Out_Free:\r
448 //\r
449 // Free block read buffer\r
450 //\r
451 FreePool (Buffer);\r
452\r
453 return Status;\r
454}\r
455\r
456/**\r
457 Find a supported UDF file system in block device.\r
458\r
459 @param[in] BlockIo BlockIo interface.\r
460 @param[in] DiskIo DiskIo interface.\r
461 @param[out] StartingLBA UDF file system starting LBA.\r
462 @param[out] EndingLBA UDF file system starting LBA.\r
463\r
464 @retval EFI_SUCCESS UDF file system was found.\r
465 @retval other UDF file system was not found.\r
466\r
467**/\r
468EFI_STATUS\r
469FindUdfFileSystem (\r
470 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
471 IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
472 OUT EFI_LBA *StartingLBA,\r
473 OUT EFI_LBA *EndingLBA\r
474 )\r
475{\r
476 EFI_STATUS Status;\r
477 UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint;\r
478\r
479 //\r
480 // Find UDF volume identifiers\r
481 //\r
482 Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);\r
483 if (EFI_ERROR (Status)) {\r
484 return Status;\r
8aafec2c
PA
485 }\r
486\r
baaa3cee
PA
487 //\r
488 // Find Anchor Volume Descriptor Pointer\r
489 //\r
8aafec2c
PA
490 Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);\r
491 if (EFI_ERROR (Status)) {\r
baaa3cee 492 return Status;\r
8aafec2c
PA
493 }\r
494\r
baaa3cee
PA
495 //\r
496 // Find Logical Volume location\r
497 //\r
498 Status = FindLogicalVolumeLocation (\r
499 BlockIo,\r
500 DiskIo,\r
501 &AnchorPoint,\r
502 (UINT64 *)StartingLBA,\r
503 (UINT64 *)EndingLBA\r
504 );\r
505\r
506 return Status;\r
8aafec2c
PA
507}\r
508\r
509/**\r
510 Install child handles if the Handle supports UDF/ECMA-167 volume format.\r
511\r
512 @param[in] This Calling context.\r
513 @param[in] Handle Parent Handle.\r
514 @param[in] DiskIo Parent DiskIo interface.\r
515 @param[in] DiskIo2 Parent DiskIo2 interface.\r
516 @param[in] BlockIo Parent BlockIo interface.\r
517 @param[in] BlockIo2 Parent BlockIo2 interface.\r
518 @param[in] DevicePath Parent Device Path\r
519\r
520\r
521 @retval EFI_SUCCESS Child handle(s) was added.\r
522 @retval EFI_MEDIA_CHANGED Media changed Detected.\r
523 @retval other no child handle was added.\r
524\r
525**/\r
526EFI_STATUS\r
527PartitionInstallUdfChildHandles (\r
528 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
529 IN EFI_HANDLE Handle,\r
530 IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
531 IN EFI_DISK_IO2_PROTOCOL *DiskIo2,\r
532 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
533 IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,\r
534 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
535 )\r
536{\r
b19aeeb9 537 UINT32 RemainderByMediaBlockSize;\r
8aafec2c
PA
538 EFI_STATUS Status;\r
539 EFI_BLOCK_IO_MEDIA *Media;\r
8aafec2c 540 EFI_PARTITION_INFO_PROTOCOL PartitionInfo;\r
baaa3cee
PA
541 EFI_LBA StartingLBA;\r
542 EFI_LBA EndingLBA;\r
8aafec2c
PA
543\r
544 Media = BlockIo->Media;\r
545\r
546 //\r
547 // Check if UDF logical block size is multiple of underlying device block size\r
548 //\r
b19aeeb9
LE
549 DivU64x32Remainder (\r
550 UDF_LOGICAL_SECTOR_SIZE, // Dividend\r
551 Media->BlockSize, // Divisor\r
552 &RemainderByMediaBlockSize // Remainder\r
553 );\r
b4e5807d 554 if (RemainderByMediaBlockSize != 0) {\r
8aafec2c
PA
555 return EFI_NOT_FOUND;\r
556 }\r
557\r
8aafec2c 558 //\r
baaa3cee 559 // Search for an UDF file system on block device\r
8aafec2c 560 //\r
baaa3cee 561 Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);\r
8aafec2c
PA
562 if (EFI_ERROR (Status)) {\r
563 return EFI_NOT_FOUND;\r
564 }\r
565\r
566 //\r
567 // Create Partition Info protocol for UDF file system\r
568 //\r
569 ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));\r
570 PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;\r
571 PartitionInfo.Type = PARTITION_TYPE_OTHER;\r
572\r
573 //\r
574 // Install partition child handle for UDF file system\r
575 //\r
576 Status = PartitionInstallChildHandle (\r
577 This,\r
578 Handle,\r
579 DiskIo,\r
580 DiskIo2,\r
581 BlockIo,\r
582 BlockIo2,\r
583 DevicePath,\r
584 (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,\r
585 &PartitionInfo,\r
baaa3cee
PA
586 StartingLBA,\r
587 EndingLBA,\r
8aafec2c
PA
588 Media->BlockSize\r
589 );\r
8aafec2c
PA
590\r
591 return Status;\r
592}\r