OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcDevicePropertyLib.c
Go to the documentation of this file.
1
15#include <AppleMacEfi.h>
16
17#include <Guid/AppleVariable.h>
18
19#include <Protocol/DevicePath.h>
21
22#include <Library/BaseLib.h>
23#include <Library/BaseMemoryLib.h>
24#include <Library/BaseOverflowLib.h>
25#include <Library/DebugLib.h>
26#include <Library/DevicePathLib.h>
27#include <Library/MemoryAllocationLib.h>
28#include <Library/PcdLib.h>
29#include <Library/PrintLib.h>
30#include <Library/UefiBootServicesTableLib.h>
31#include <Library/UefiRuntimeServicesTableLib.h>
32#include <Library/OcMiscLib.h>
33
34#define DEVICE_PATH_PROPERTY_DATA_SIGNATURE \
35 SIGNATURE_32 ('D', 'p', 'p', 'P')
36
37// PROPERTY_DATABASE_FROM_PROTOCOL
38#define PROPERTY_DATABASE_FROM_PROTOCOL(This) \
39 CR ( \
40 This, \
41 DEVICE_PATH_PROPERTY_DATA, \
42 Protocol, \
43 DEVICE_PATH_PROPERTY_DATA_SIGNATURE \
44 )
45
46// DEVICE_PATH_PROPERTY_DATABASE
53
54#define APPLE_PATH_PROPERTIES_VARIABLE_NAME L"AAPL,PathProperties"
55#define APPLE_PATH_PROPERTY_VARIABLE_MAX_SIZE 768
56#define APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM 0x10000
57
58#define EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE \
59 SIGNATURE_32 ('D', 'p', 'n', '\0')
60
61#define PROPERTY_NODE_FROM_LIST_ENTRY(Entry) \
62 ((EFI_DEVICE_PATH_PROPERTY_NODE *)( \
63 CR ( \
64 Entry, \
65 EFI_DEVICE_PATH_PROPERTY_NODE_HDR, \
66 Link, \
67 EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE \
68 ) \
69 ))
70
71#define EFI_DEVICE_PATH_PROPERTY_NODE_SIZE(Node) \
72 (sizeof (EFI_DEVICE_PATH_PROPERTY_BUFFER_NODE_HDR) + GetDevicePathSize (&(Node)->DevicePath))
73
74// EFI_DEVICE_PATH_PROPERTY_NODE_HDR
75typedef struct {
76 UINTN Signature;
77 LIST_ENTRY Link;
79 LIST_ENTRY Properties;
81
82// DEVICE_PATH_PROPERTY_NODE
87
88#define EFI_DEVICE_PATH_PROPERTY_SIGNATURE \
89 SIGNATURE_32 ('D', 'p', 'p', '\0')
90
91#define EFI_DEVICE_PATH_PROPERTY_DATABASE_VERSION 1
92
93#define EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY(Entry) \
94 (CR ( \
95 (Entry), \
96 EFI_DEVICE_PATH_PROPERTY, \
97 Link, \
98 EFI_DEVICE_PATH_PROPERTY_SIGNATURE \
99 ))
100
101#define EFI_DEVICE_PATH_PROPERTY_SIZE(Property) \
102 ((Property)->Name->Size + (Property)->Value->Size)
103
104#define EFI_DEVICE_PATH_PROPERTY_VALUE_SIZE(Property) \
105 ((Property)->Value->Size - sizeof (*(Property)->Value))
106
107#define NEXT_EFI_DEVICE_PATH_PROPERTY(Property) \
108 (EFI_DEVICE_PATH_PROPERTY *)( \
109 (UINTN)(Property) + EFI_DEVICE_PATH_PROPERTY_SIZE (Property) \
110 )
111
112// EFI_DEVICE_PATH_PROPERTY
119
120// TODO: Move to own header
121// C649D4F3-D502-4DAA-A139-394ACCF2A63B
122// This protocol describes every thunderbolt device:
123// - Thunderbolt Inter-domain Boundary
124// - Thunderbolt Device
125// TODO: explore this. Need to RE Vendor/Apple/ThunderboltPkg drivers, ThunderboltNhi in particular.
126#define APPLE_THUNDERBOLT_NATIVE_HOST_INTERFACE_PROTOCOL_GUID \
127 { 0xC649D4F3, 0xD502, 0x4DAA, \
128 { 0xA1, 0x39, 0x39, 0x4A, 0xCC, 0xF2, 0xA6, 0x3B } }
129
131
132// InternalGetPropertyNode
133STATIC
136 IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData,
137 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
138 )
139{
140 LIST_ENTRY *Node;
141 UINTN DevicePathSize;
142 UINTN DevicePathSize2;
143
144 Node = GetFirstNode (&DevicePathPropertyData->Nodes);
145 DevicePathSize = GetDevicePathSize (DevicePath);
146
147 while (!IsNull (&DevicePathPropertyData->Nodes, Node)) {
148 DevicePathSize2 = GetDevicePathSize (&PROPERTY_NODE_FROM_LIST_ENTRY (Node)->DevicePath);
149
150 if ( (DevicePathSize == DevicePathSize2)
151 && (CompareMem (DevicePath, &PROPERTY_NODE_FROM_LIST_ENTRY (Node)->DevicePath, DevicePathSize) == 0))
152 {
153 return PROPERTY_NODE_FROM_LIST_ENTRY (Node);
154 }
155
156 Node = GetNextNode (&DevicePathPropertyData->Nodes, Node);
157 }
158
159 return NULL;
160}
161
162// InternalGetProperty
163STATIC
167 IN CONST CHAR16 *Name
168 )
169{
170 LIST_ENTRY *Property;
171
172 Property = GetFirstNode (&Node->Hdr.Properties);
173
174 while (!IsNull (&Node->Hdr.Properties, Property)) {
175 if (StrCmp (Name, (CONST CHAR16 *)&EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY (Property)->Name->Data[0]) == 0) {
177 }
178
179 Property = GetNextNode (&Node->Hdr.Properties, Property);
180 }
181
182 return NULL;
183}
184
185// InternalSyncWithThunderboltDevices
186STATIC
187VOID
189 VOID
190 )
191{
192 EFI_STATUS Status;
193 UINTN NumberHandles;
194 EFI_HANDLE *Buffer;
195 UINTN Index;
196 VOID *Interface;
197
198 Buffer = NULL;
199 Status = gBS->LocateHandleBuffer (
200 ByProtocol,
202 NULL,
203 &NumberHandles,
204 &Buffer
205 );
206
207 if (!EFI_ERROR (Status)) {
208 for (Index = 0; Index < NumberHandles; ++Index) {
209 Status = gBS->HandleProtocol (
210 Buffer[Index],
212 &Interface
213 );
214
215 if (!EFI_ERROR (Status)) {
216 if (*(UINT32 *)((UINTN)Interface + sizeof (UINT32)) == 0) {
217 (*(VOID (EFIAPI **)(VOID *))((UINTN)Interface + 232))(Interface);
218 }
219 }
220 }
221
222 FreePool (Buffer);
223 }
224}
225
226// DppDbGetProperty
227
249EFI_STATUS
250EFIAPI
253 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
254 IN CONST CHAR16 *Name,
255 OUT VOID *Value OPTIONAL,
256 IN OUT UINTN *Size
257 )
258{
261 EFI_DEVICE_PATH_PROPERTY *Property;
262 UINTN PropertySize;
263 BOOLEAN BufferTooSmall;
264
265 Database = PROPERTY_DATABASE_FROM_PROTOCOL (This);
266 Node = InternalGetPropertyNode (Database, DevicePath);
267 if (Node == NULL) {
268 return EFI_NOT_FOUND;
269 }
270
271 Property = InternalGetProperty (Node, Name);
272 if (Property == NULL) {
273 return EFI_NOT_FOUND;
274 }
275
276 PropertySize = EFI_DEVICE_PATH_PROPERTY_VALUE_SIZE (Property);
277 BufferTooSmall = PropertySize > *Size;
278 *Size = PropertySize;
279
280 if (!BufferTooSmall) {
281 CopyMem (Value, &Property->Value->Data[0], PropertySize);
282 return EFI_SUCCESS;
283 }
284
285 return EFI_BUFFER_TOO_SMALL;
286}
287
288// DppDbSetProperty
289
304EFI_STATUS
305EFIAPI
308 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
309 IN CONST CHAR16 *Name,
310 IN VOID *Value,
311 IN UINTN Size
312 )
313{
316 UINTN DevicePathSize;
317 EFI_DEVICE_PATH_PROPERTY *Property;
318 UINTN PropertyNameSize;
319 UINTN PropertyValueSize;
320 EFI_DEVICE_PATH_PROPERTY_DATA *PropertyName;
321 EFI_DEVICE_PATH_PROPERTY_DATA *PropertyValue;
322
323 Database = PROPERTY_DATABASE_FROM_PROTOCOL (This);
324 Node = InternalGetPropertyNode (Database, DevicePath);
325
326 if (Node == NULL) {
327 DevicePathSize = GetDevicePathSize (DevicePath);
328 Node = AllocateZeroPool (sizeof (*Node) + DevicePathSize);
329
330 if (Node == NULL) {
331 return EFI_OUT_OF_RESOURCES;
332 }
333
335
336 InitializeListHead (&Node->Hdr.Properties);
337
338 CopyMem (
339 &Node->DevicePath,
340 DevicePath,
341 DevicePathSize
342 );
343
344 InsertTailList (&Database->Nodes, &Node->Hdr.Link);
345
346 Database->Modified = TRUE;
347 }
348
349 Property = InternalGetProperty (Node, Name);
350
351 if (Property != NULL) {
352 if ( (Property->Value->Size == Size + sizeof (UINT32))
353 && (CompareMem (&Property->Value->Data[0], Value, Size) == 0))
354 {
355 return EFI_SUCCESS;
356 }
357
358 RemoveEntryList (&Property->Link);
359
360 --Node->Hdr.NumberOfProperties;
361
362 FreePool (Property->Name);
363 FreePool (Property->Value);
364 FreePool (Property);
365 }
366
367 Database->Modified = TRUE;
368 Property = AllocateZeroPool (sizeof (*Property));
369
370 if (Property == NULL) {
371 return EFI_OUT_OF_RESOURCES;
372 }
373
374 PropertyNameSize = sizeof (*PropertyName) + StrSize (Name);
375 PropertyName = AllocateZeroPool (PropertyNameSize);
376 Property->Name = PropertyName;
377 if (PropertyName == NULL) {
378 FreePool (Property);
379 return EFI_OUT_OF_RESOURCES;
380 }
381
382 PropertyValueSize = sizeof (*PropertyValue) + Size;
383 PropertyValue = AllocateZeroPool (PropertyValueSize);
384 Property->Value = PropertyValue;
385
386 if (PropertyValue == NULL) {
387 FreePool (PropertyName);
388 FreePool (Property);
389 return EFI_OUT_OF_RESOURCES;
390 }
391
393
394 CopyMem (&Property->Name->Data[0], Name, PropertyNameSize - sizeof (*PropertyName));
395 Property->Name->Size = (UINT32)PropertyNameSize;
396
397 CopyMem (&Property->Value->Data[0], Value, Size);
398 Property->Value->Size = (UINT32)PropertyValueSize;
399
400 InsertTailList (&Node->Hdr.Properties, &Property->Link);
401
402 ++Node->Hdr.NumberOfProperties;
403
404 return EFI_SUCCESS;
405}
406
407// DppDbRemoveProperty
408
420EFI_STATUS
421EFIAPI
424 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
425 IN CONST CHAR16 *Name
426 )
427{
428 DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData;
430 EFI_DEVICE_PATH_PROPERTY *Property;
431
432 DevicePathPropertyData = PROPERTY_DATABASE_FROM_PROTOCOL (This);
433 Node = InternalGetPropertyNode (DevicePathPropertyData, DevicePath);
434 if (Node == NULL) {
435 return EFI_NOT_FOUND;
436 }
437
438 Property = InternalGetProperty (Node, Name);
439 if (Property == NULL) {
440 return EFI_NOT_FOUND;
441 }
442
443 DevicePathPropertyData->Modified = TRUE;
444
445 RemoveEntryList (&Property->Link);
446
447 --Node->Hdr.NumberOfProperties;
448
449 FreePool (Property->Name);
450 FreePool (Property->Value);
451 FreePool (Property);
452
453 if (Node->Hdr.NumberOfProperties == 0) {
454 RemoveEntryList (&Node->Hdr.Link);
455
456 FreePool (Node);
457 }
458
459 return EFI_SUCCESS;
460}
461
462// DppDbGetPropertyBuffer
463
479EFI_STATUS
480EFIAPI
484 IN OUT UINTN *Size
485 )
486{
487 LIST_ENTRY *Nodes;
488 LIST_ENTRY *NodeWalker;
489 UINTN BufferSize;
490 LIST_ENTRY *Property;
491 UINT32 NumberOfNodes;
493 UINT8 *BufferPtr;
494 BOOLEAN BufferTooSmall;
495
496 Nodes = &(PROPERTY_DATABASE_FROM_PROTOCOL (This))->Nodes;
497
498 if (IsListEmpty (Nodes)) {
499 *Size = 0;
500 return EFI_SUCCESS;
501 }
502
503 if (PcdGetBool (PcdEnableAppleThunderboltSync)) {
505 }
506
507 NodeWalker = GetFirstNode (Nodes);
508 BufferSize = sizeof (*Buffer);
509 NumberOfNodes = 0;
510
511 while (!IsNull (Nodes, NodeWalker)) {
512 Property = GetFirstNode (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties);
513
514 while (!IsNull (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties, Property)) {
516 Property = GetNextNode (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties, Property);
517 }
518
520
521 NodeWalker = GetNextNode (Nodes, NodeWalker);
522
523 ++NumberOfNodes;
524 }
525
526 DEBUG ((DEBUG_VERBOSE, "Saving to %p, given %u, requested %u\n", Buffer, (UINT32)*Size, (UINT32)BufferSize));
527
528 BufferTooSmall = *Size < BufferSize;
529 *Size = BufferSize;
530 if (BufferTooSmall) {
531 return EFI_BUFFER_TOO_SMALL;
532 }
533
534 Buffer->Size = (UINT32)BufferSize;
536 Buffer->NumberOfNodes = NumberOfNodes;
537
538 NodeWalker = GetFirstNode (Nodes);
539
540 BufferNode = &Buffer->Nodes[0];
541
542 while (!IsNull (Nodes, NodeWalker)) {
543 BufferSize = GetDevicePathSize (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->DevicePath);
544
545 CopyMem (
546 &BufferNode->DevicePath,
547 &PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->DevicePath,
548 BufferSize
549 );
550
551 BufferNode->Hdr.NumberOfProperties = (UINT32)PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.NumberOfProperties;
552
553 Property = GetFirstNode (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties);
554
555 BufferSize += sizeof (BufferNode->Hdr);
556 BufferPtr = (UINT8 *)BufferNode + BufferSize;
557
558 while (!IsNull (&PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties, Property)) {
559 CopyMem (
560 BufferPtr,
562 EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY (Property)->Name->Size
563 );
564
565 CopyMem (
566 BufferPtr + (EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY (Property))->Name->Size,
568 EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY (Property)->Value->Size
569 );
570
573 Property = GetNextNode (
574 &PROPERTY_NODE_FROM_LIST_ENTRY (NodeWalker)->Hdr.Properties,
575 Property
576 );
577 }
578
579 BufferNode->Hdr.Size = (UINT32)BufferSize;
581 (UINTN)BufferNode + BufferSize
582 );
583
584 NodeWalker = GetNextNode (Nodes, NodeWalker);
585 }
586
587 return EFI_SUCCESS;
588}
589
590// InternalReadEfiVariableProperties
591STATIC
592EFI_STATUS
594 IN EFI_GUID *VendorGuid,
595 IN BOOLEAN DeleteVariables,
596 IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData
597 )
598{
599 EFI_STATUS Status;
600
601 CHAR16 IndexBuffer[5];
602 UINT32 NumberOfVariables;
603 UINT32 VariableIndex;
604 CHAR16 VariableName[64];
605 UINTN DataSize;
606 UINTN BufferSize;
607 UINTN CurrentBufferSize;
609 UINT8 *BufferPtr;
611 UINTN NodeIndex;
612 UINTN Index;
615 UINT32 Attributes;
616
617 NumberOfVariables = 0;
618 BufferSize = 0;
619 Status = EFI_BUFFER_TOO_SMALL;
620
621 while (Status == EFI_BUFFER_TOO_SMALL && NumberOfVariables < APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM) {
622 UnicodeSPrint (
623 &IndexBuffer[0],
624 sizeof (IndexBuffer),
625 L"%04x",
626 NumberOfVariables
627 );
628
629 StrCpyS (VariableName, ARRAY_SIZE (VariableName), APPLE_PATH_PROPERTIES_VARIABLE_NAME);
630 StrCatS (VariableName, ARRAY_SIZE (VariableName), IndexBuffer);
631
632 DataSize = 0;
633 Status = gRT->GetVariable (
634 VariableName,
635 VendorGuid,
636 NULL,
637 &DataSize,
638 NULL
639 );
640
641 ++NumberOfVariables;
642 if (BaseOverflowAddUN (BufferSize, DataSize, &BufferSize)) {
643 //
644 // Should never trigger due to BufferSize being 4G at least.
645 //
646 return EFI_OUT_OF_RESOURCES;
647 }
648
649 //
650 // NumberOfVariables check is an extra caution here, writing 0x10000 variables
651 // to NVRAM is pretty much impossible.
652 //
653 }
654
655 //
656 // Discard low size with forced approval.
657 //
658 if (BufferSize < sizeof (EFI_DEVICE_PATH_PROPERTY_BUFFER)) {
659 return EFI_SUCCESS;
660 }
661
662 Buffer = AllocateZeroPool (BufferSize);
663 if (Buffer == NULL) {
664 return EFI_OUT_OF_RESOURCES;
665 }
666
667 BufferPtr = (UINT8 *)Buffer;
668 CurrentBufferSize = BufferSize;
669 Status = EFI_SUCCESS;
670
671 for (VariableIndex = 0; VariableIndex < NumberOfVariables; ++VariableIndex) {
672 UnicodeSPrint (
673 &IndexBuffer[0],
674 sizeof (IndexBuffer),
675 L"%04x",
676 VariableIndex
677 );
678
679 StrCpyS (VariableName, ARRAY_SIZE (VariableName), APPLE_PATH_PROPERTIES_VARIABLE_NAME);
680 StrCatS (VariableName, ARRAY_SIZE (VariableName), IndexBuffer);
681
682 DataSize = CurrentBufferSize;
683 Status = gRT->GetVariable (
684 VariableName,
685 VendorGuid,
686 &Attributes,
687 &DataSize,
688 BufferPtr
689 );
690
691 if (EFI_ERROR (Status)) {
692 break;
693 }
694
695 if (DeleteVariables) {
696 Status = gRT->SetVariable (VariableName, VendorGuid, Attributes, 0, NULL);
697
698 if (EFI_ERROR (Status)) {
699 break;
700 }
701 }
702
703 BufferPtr += DataSize;
704 CurrentBufferSize -= DataSize;
705 }
706
707 //
708 // Force success on format mismatch, this slightly differs from Apple implementation,
709 // where variable read failure results in error unless EFI_NOT_FOUND.
710 //
711 if ( (Buffer->Size != BufferSize)
713 || (Buffer->NumberOfNodes == 0))
714 {
715 FreePool (Buffer);
716 return EFI_SUCCESS;
717 }
718
719 if (EFI_ERROR (Status)) {
720 FreePool (Buffer);
721 return Status;
722 }
723
724 //
725 // TODO: while this does not seem exploitable, we should sanity check the input data.
726 //
727
728 BufferNode = &Buffer->Nodes[0];
729 for (NodeIndex = 0; NodeIndex < Buffer->NumberOfNodes; ++NodeIndex) {
730 DataSize = GetDevicePathSize (&BufferNode->DevicePath);
731
732 if (BufferNode->Hdr.NumberOfProperties > 0) {
733 NameData = (EFI_DEVICE_PATH_PROPERTY_DATA *)(
734 (UINTN)BufferNode + DataSize + sizeof (*Buffer)
735 );
736
737 ValueData = (EFI_DEVICE_PATH_PROPERTY_DATA *)(
738 (UINTN)NameData + NameData->Size
739 );
740
741 for (Index = 0; Index < BufferNode->Hdr.NumberOfProperties; ++Index) {
742 //
743 // Apple implementation does check for an error here, and returns failure
744 // if all the writes failed. This is illogical, so we just ignore it.
745 //
746 DevicePathPropertyData->Protocol.SetProperty (
747 &DevicePathPropertyData->Protocol,
748 &BufferNode->DevicePath,
749 (CHAR16 *)&NameData->Data,
750 (VOID *)&ValueData->Data,
751 (UINTN)(
752 ValueData->Size
753 - sizeof (ValueData->Size)
754 )
755 );
756
757 NameData = (EFI_DEVICE_PATH_PROPERTY_DATA *)(
758 (UINTN)ValueData + ValueData->Size
759 );
760
761 ValueData =
763 (UINTN)ValueData + ValueData->Size + NameData->Size
764 );
765 }
766 }
767
769 (UINTN)BufferNode + (UINTN)BufferNode->Hdr.Size
770 );
771 }
772
773 FreePool (Buffer);
774
775 return EFI_SUCCESS;
776}
777
785
788 IN BOOLEAN Reinstall
789 )
790{
791 EFI_STATUS Status;
792
795 UINT8 *BufferPtr;
796 DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData;
797 UINTN DataSize;
798 UINT32 VariableIndex;
799 CHAR16 IndexBuffer[5];
800 CHAR16 VariableName[64];
801 UINTN VariableSize;
802 UINT32 Attributes;
803 EFI_HANDLE Handle;
804
805 if (Reinstall) {
807 if (EFI_ERROR (Status)) {
808 DEBUG ((DEBUG_ERROR, "OCDP: Uninstall failed - %r\n", Status));
809 return NULL;
810 }
811 } else {
812 Status = gBS->LocateProtocol (
814 NULL,
815 (VOID *)&Protocol
816 );
817
818 if (!EFI_ERROR (Status)) {
819 return Protocol;
820 }
821 }
822
823 DevicePathPropertyData = AllocateZeroPool (sizeof (*DevicePathPropertyData));
824 if (DevicePathPropertyData == NULL) {
825 return NULL;
826 }
827
828 DevicePathPropertyData->Signature = DEVICE_PATH_PROPERTY_DATA_SIGNATURE;
829
830 CopyMem (
831 &DevicePathPropertyData->Protocol,
833 sizeof (DppDbProtocolTemplate)
834 );
835
836 InitializeListHead (&DevicePathPropertyData->Nodes);
837
838 if (PcdGetBool (PcNvramInitDevicePropertyDatabase)) {
841 FALSE,
842 DevicePathPropertyData
843 );
844
845 if (EFI_ERROR (Status)) {
846 FreePool (DevicePathPropertyData);
847 return NULL;
848 }
849
850 DevicePathPropertyData->Modified = FALSE;
851
854 TRUE,
855 DevicePathPropertyData
856 );
857
858 if (EFI_ERROR (Status)) {
859 FreePool (DevicePathPropertyData);
860 return NULL;
861 }
862
863 if (DevicePathPropertyData->Modified) {
864 DataSize = 0;
865 Status = DppDbGetPropertyBuffer (
866 &DevicePathPropertyData->Protocol,
867 NULL,
868 &DataSize
869 );
870
871 if (Status != EFI_BUFFER_TOO_SMALL) {
872 FreePool (DevicePathPropertyData);
873 return NULL;
874 }
875
876 Buffer = AllocateZeroPool (DataSize);
877 if (Buffer == NULL) {
878 FreePool (DevicePathPropertyData);
879 return NULL;
880 }
881
882 Status = DppDbGetPropertyBuffer (
883 &DevicePathPropertyData->Protocol,
884 Buffer,
885 &DataSize
886 );
887 if (EFI_ERROR (Status)) {
888 FreePool (Buffer);
889 FreePool (DevicePathPropertyData);
890 return NULL;
891 }
892
893 VariableIndex = 0;
894 Attributes = (EFI_VARIABLE_NON_VOLATILE
895 | EFI_VARIABLE_BOOTSERVICE_ACCESS
896 | EFI_VARIABLE_RUNTIME_ACCESS);
897 BufferPtr = (UINT8 *)Buffer;
898
899 while (VariableIndex < APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM && DataSize > 0) {
900 UnicodeSPrint (
901 &IndexBuffer[0],
902 sizeof (IndexBuffer),
903 L"%04x",
904 VariableIndex
905 );
906
907 StrCpyS (VariableName, ARRAY_SIZE (VariableName), APPLE_PATH_PROPERTIES_VARIABLE_NAME);
908 StrCatS (VariableName, ARRAY_SIZE (VariableName), IndexBuffer);
909
910 VariableSize = MIN (
911 DataSize,
913 );
914
915 Status = gRT->SetVariable (
916 VariableName,
918 Attributes,
919 VariableSize,
920 BufferPtr
921 );
922
923 if (EFI_ERROR (Status)) {
924 break;
925 }
926
927 BufferPtr += VariableSize;
928 DataSize -= VariableSize;
929 ++VariableIndex;
930 }
931
932 FreePool (Buffer);
933 if (EFI_ERROR (Status) || (DataSize != 0)) {
934 FreePool (DevicePathPropertyData);
935 return NULL;
936 }
937
938 while (!EFI_ERROR (Status) && VariableIndex < APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM) {
939 UnicodeSPrint (
940 &IndexBuffer[0],
941 sizeof (IndexBuffer),
942 L"%04x",
943 VariableIndex
944 );
945
946 StrCpyS (VariableName, ARRAY_SIZE (VariableName), APPLE_PATH_PROPERTIES_VARIABLE_NAME);
947 StrCatS (VariableName, ARRAY_SIZE (VariableName), IndexBuffer);
948
949 VariableSize = 0;
950 Status = gRT->GetVariable (
951 VariableName,
953 &Attributes,
954 &VariableSize,
955 NULL
956 );
957
958 if (Status != EFI_BUFFER_TOO_SMALL) {
959 Status = EFI_SUCCESS;
960 break;
961 }
962
963 Status = gRT->SetVariable (
964 VariableName,
966 Attributes,
967 0,
968 NULL
969 );
970
971 ++VariableIndex;
972 }
973
974 if (EFI_ERROR (Status)) {
975 FreePool (DevicePathPropertyData);
976 return NULL;
977 }
978 }
979
980 DevicePathPropertyData->Modified = FALSE;
981 }
982
983 Handle = NULL;
984 Status = gBS->InstallProtocolInterface (
985 &Handle,
987 EFI_NATIVE_INTERFACE,
988 &DevicePathPropertyData->Protocol
989 );
990
991 if (EFI_ERROR (Status)) {
992 return NULL;
993 }
994
995 return &DevicePathPropertyData->Protocol;
996}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
SMBIOS_STRUCTURE Hdr
Definition AppleSmBios.h:51
EFI_GUID gAppleBootVariableGuid
EFI_GUID gAppleVendorVariableGuid
EFI_GUID gEfiDevicePathPropertyDatabaseProtocolGuid
#define EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL_REVISION
DMG_SIZE_DEVICE_PATH Size
EFI_BOOT_SERVICES * gBS
#define PROPERTY_DATABASE_FROM_PROTOCOL(This)
STATIC EFI_DEVICE_PATH_PROPERTY_NODE * InternalGetPropertyNode(IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
STATIC VOID InternalSyncWithThunderboltDevices(VOID)
STATIC EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL DppDbProtocolTemplate
#define EFI_DEVICE_PATH_PROPERTY_SIZE(Property)
STATIC EFI_STATUS InternalReadEfiVariableProperties(IN EFI_GUID *VendorGuid, IN BOOLEAN DeleteVariables, IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData)
#define APPLE_THUNDERBOLT_NATIVE_HOST_INTERFACE_PROTOCOL_GUID
#define APPLE_PATH_PROPERTY_VARIABLE_MAX_SIZE
#define EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE
EFI_STATUS EFIAPI DppDbGetPropertyBuffer(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, OUT EFI_DEVICE_PATH_PROPERTY_BUFFER *Buffer OPTIONAL, IN OUT UINTN *Size)
#define PROPERTY_NODE_FROM_LIST_ENTRY(Entry)
#define EFI_DEVICE_PATH_PROPERTY_NODE_SIZE(Node)
EFI_STATUS EFIAPI DppDbGetProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name, OUT VOID *Value OPTIONAL, IN OUT UINTN *Size)
#define APPLE_PATH_PROPERTIES_VARIABLE_NAME
#define DEVICE_PATH_PROPERTY_DATA_SIGNATURE
#define EFI_DEVICE_PATH_PROPERTY_VALUE_SIZE(Property)
EFI_STATUS EFIAPI DppDbSetProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name, IN VOID *Value, IN UINTN Size)
STATIC EFI_DEVICE_PATH_PROPERTY * InternalGetProperty(IN EFI_DEVICE_PATH_PROPERTY_NODE *Node, IN CONST CHAR16 *Name)
#define EFI_DEVICE_PATH_PROPERTY_DATABASE_VERSION
EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL * OcDevicePathPropertyInstallProtocol(IN BOOLEAN Reinstall)
#define EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY(Entry)
EFI_GUID mAppleThunderboltNativeHostInterfaceProtocolGuid
EFI_STATUS EFIAPI DppDbRemoveProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name)
#define EFI_DEVICE_PATH_PROPERTY_SIGNATURE
#define APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
STATIC VOID DeleteVariables(IN BOOLEAN PreserveBoot)
#define MIN(a, b)
Definition deflate.c:1673
EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL Protocol
UINT32 NumberOfProperties
The size, in bytes, of the entire node.
The structure defining the header of a Device Property node.
EFI_DEVICE_PATH_PROTOCOL DevicePath
The device path for the current node.
EFI_DEVICE_PATH_PROPERTY_BUFFER_NODE_HDR Hdr
The node header structure.
The structure defining the header of a Device Property Buffer.
The structure exposed by the EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL.
The structure defining the header of a Device Path Property.
UINT32 Size
The size, in bytes, of the current data set.
EFI_DEVICE_PATH_PROTOCOL DevicePath
EFI_DEVICE_PATH_PROPERTY_NODE_HDR Hdr
EFI_DEVICE_PATH_PROPERTY_DATA * Value
EFI_DEVICE_PATH_PROPERTY_DATA * Name