[BOOTLIB]
[reactos.git] / reactos / boot / environ / lib / misc / bcd.c
index 31c76c5..12a94ae 100644 (file)
@@ -24,7 +24,7 @@ BiNotifyEnumerationError (
     UNREFERENCED_PARAMETER(ObjectHandle);
     UNREFERENCED_PARAMETER(ElementName);
     UNREFERENCED_PARAMETER(Status);
-    EfiPrintf(L"Error in BiNotify\r\n");
+    EfiPrintf(L"Error in BiNotify: %lx for element %s\r\n", Status, ElementName);
 }
 
 ULONG
@@ -556,6 +556,66 @@ Quickie:
     return Status;
 }
 
+NTSTATUS
+BcdDeleteElement (
+    _In_ HANDLE ObjectHandle,
+    _In_ ULONG Type
+    )
+{
+    NTSTATUS Status;
+    HANDLE ElementsHandle, ElementHandle;
+    WCHAR TypeString[22];
+
+    /* Open the elements key */
+    Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
+    if (NT_SUCCESS(Status))
+    {
+        /* Convert the element ID into a string */
+        if (!_ultow(Type, TypeString, 16))
+        {
+            /* Failed to do so */
+            Status = STATUS_UNSUCCESSFUL;
+        }
+        else
+        {
+            /* Open the element specifically */
+            Status = BiOpenKey(ElementsHandle, TypeString, &ElementHandle);
+            if (NT_SUCCESS(Status))
+            {
+                /* Delete it */
+                Status = BiDeleteKey(ElementHandle);
+                if (NT_SUCCESS(Status))
+                {
+                    /* No point in closing the handle anymore */
+                    ElementHandle = NULL;
+                }
+            }
+            else
+            {
+                /* The element doesn't exist */
+                Status = STATUS_NOT_FOUND;
+            }
+
+            /* Check if we should close the key */
+            if (ElementHandle)
+            {
+                /* Do it */
+                BiCloseKey(ElementHandle);
+            }
+        }
+    }
+
+    /* Check if we should close the elements handle */
+    if (ElementsHandle)
+    {
+        /* Do it */
+        BiCloseKey(ElementsHandle);
+    }
+
+    /* Return whatever the result was */
+    return Status;
+}
+
 NTSTATUS
 BiEnumerateSubElements (
     _In_ HANDLE BcdHandle,
@@ -758,7 +818,7 @@ BiEnumerateElements (
     ULONG i;
     PVOID ElementData, SubObjectList, RegistryElementData;
     BcdElementType ElementType;
-    PBCD_PACKED_ELEMENT PreviousElement;
+    PBCD_PACKED_ELEMENT PreviousElement, ElementsStart;
     ULONG SubElementCount, SubKeyCount, SubObjectCount, ElementDataLength;
     PWCHAR ElementName;
     PWCHAR* SubKeys;
@@ -779,6 +839,7 @@ BiEnumerateElements (
     ElementDataLength = 0;
     SubObjectCount = 0;
     RemainingLength = 0;
+    ElementsStart = Elements;
 
     /* Open the root object key's elements */
     Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
@@ -802,6 +863,8 @@ BiEnumerateElements (
         Status = BiOpenKey(ElementsHandle, ElementName, &ElementHandle);
         if (!NT_SUCCESS(Status))
         {
+            EfiPrintf(L"ELEMENT ERROR: %lx\r\n", Status);
+            EfiStall(100000);
             break;
         }
 
@@ -809,22 +872,22 @@ BiEnumerateElements (
         ElementType.PackedValue = wcstoul(SubKeys[i], NULL, 16);
         if (!(ElementType.PackedValue) || (ElementType.PackedValue == -1))
         {
-            EfiPrintf(L"Value invald\r\n");
+            EfiPrintf(L"Value invalid\r\n");
             BiCloseKey(ElementHandle);
-            ElementHandle = 0;
+            ElementHandle = NULL;
             continue;
         }
 
         /* Read the appropriate registry value type for this element */
         Status = BiGetRegistryValue(ElementHandle,
                                     L"Element",
-                                    NULL,
                                     BiConvertElementFormatToValueType(
                                     ElementType.Format),
                                     &RegistryElementData,
                                     &RegistryElementDataLength);
         if (!NT_SUCCESS(Status))
         {
+            EfiPrintf(L"Element invalid\r\n");
             break;
         }
 
@@ -885,7 +948,7 @@ BiEnumerateElements (
         if (RemainingLength >= TotalLength)
         {
             /* Set the next pointer */
-            Elements->NextEntry = (PBCD_PACKED_ELEMENT)((ULONG_PTR)Elements + TotalLength);
+            Elements->NextEntry = (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart + TotalLength);
 
             /* Fill this one out */
             Elements->RootType.PackedValue = RootElementType;
@@ -945,7 +1008,7 @@ BiEnumerateElements (
                         /* Link the subelements into the chain */
                         PreviousElement = Elements;
                         PreviousElement->NextEntry =
-                            (PBCD_PACKED_ELEMENT)((ULONG_PTR)Elements +
+                            (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart +
                                                   TotalLength);
                         Elements = PreviousElement->NextEntry;
                     }
@@ -1112,6 +1175,69 @@ BiAddStoreFromFile (
     return Status;
 }
 
+NTSTATUS
+BiGetObjectDescription (
+    _In_ HANDLE ObjectHandle,
+    _Out_ PBCD_OBJECT_DESCRIPTION Description
+    )
+{
+    NTSTATUS Status;
+    HANDLE DescriptionHandle;
+    PULONG Data;
+    ULONG Length;
+
+    /* Initialize locals */
+    Data = NULL;
+    DescriptionHandle = NULL;
+
+    /* Open the description key */
+    Status = BiOpenKey(ObjectHandle, L"Description", &DescriptionHandle);
+    if (NT_SUCCESS(Status))
+    {
+        /* It exists */
+        Description->Valid = TRUE;
+
+        /* Read the type */
+        Length = 0;
+        Status = BiGetRegistryValue(DescriptionHandle,
+                                    L"Type", 
+                                    REG_DWORD,
+                                    (PVOID*)&Data,
+                                    &Length);
+        if (NT_SUCCESS(Status))
+        {
+            /* Make sure it's the length we expected it to be */
+            if (Length == sizeof(Data))
+            {
+                /* Return the type that is stored there */
+                Description->Type = *Data;
+            }
+            else
+            {
+                /* Invalid type value */
+                Status = STATUS_OBJECT_TYPE_MISMATCH;
+            }
+        }
+    }
+
+    /* Did we have a handle open? */
+    if (DescriptionHandle)
+    {
+        /* Close it */
+        BiCloseKey(DescriptionHandle);
+    }
+
+    /* Did we have data allocated? */
+    if (Data)
+    {
+        /* Free it */
+        BlMmFreeHeap(Data);
+    }
+
+    /* Return back to caller */
+    return Status;
+}
+
 NTSTATUS
 BcdEnumerateAndUnpackElements (
     _In_ HANDLE BcdHandle,