ReactOS  0.4.13-dev-52-g0efcfec
bcd.c File Reference
#include "bl.h"
#include <bcd.h>
Include dependency graph for bcd.c:

Go to the source code of this file.

Functions

VOID BiNotifyEnumerationError (_In_ HANDLE ObjectHandle, _In_ PWCHAR ElementName, _In_ NTSTATUS Status)
 
ULONG BiConvertElementFormatToValueType (_In_ ULONG Format)
 
NTSTATUS BiConvertRegistryDataToElement (_In_ HANDLE ObjectHandle, _In_ PVOID Data, _In_ ULONG DataLength, _In_ BcdElementType ElementType, _Out_ PVOID Element, _Out_ PULONG ElementSize)
 
NTSTATUS BiConvertBcdElements (_In_ PBCD_PACKED_ELEMENT Elements, _Out_opt_ PBCD_ELEMENT Buffer, _Inout_ PULONG BufferSize, _Inout_ PULONG ElementCount)
 
NTSTATUS BcdOpenObject (_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _Out_ PHANDLE ObjectHandle)
 
NTSTATUS BcdDeleteElement (_In_ HANDLE ObjectHandle, _In_ ULONG Type)
 
NTSTATUS BiEnumerateSubElements (_In_ HANDLE BcdHandle, _In_ PVOID Object, _In_ ULONG ElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT *Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
 
NTSTATUS BiEnumerateSubObjectElements (_In_ HANDLE BcdHandle, _Out_ PGUID SubObjectList, _In_ ULONG SubObjectCount, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
 
NTSTATUS BiEnumerateElements (_In_ HANDLE BcdHandle, _In_ HANDLE ObjectHandle, _In_ ULONG RootElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
 
NTSTATUS BiAddStoreFromFile (_In_ PBL_FILE_PATH_DESCRIPTOR FilePath, _Out_ PHANDLE StoreHandle)
 
NTSTATUS BiGetObjectDescription (_In_ HANDLE ObjectHandle, _Out_ PBCD_OBJECT_DESCRIPTION Description)
 
NTSTATUS BcdEnumerateAndUnpackElements (_In_ HANDLE BcdHandle, _In_ HANDLE ObjectHandle, _Out_opt_ PBCD_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
 
NTSTATUS BcdOpenStoreFromFile (_In_ PUNICODE_STRING FileName, _In_ PHANDLE BcdHandle)
 

Function Documentation

◆ BcdDeleteElement()

NTSTATUS BcdDeleteElement ( _In_ HANDLE  ObjectHandle,
_In_ ULONG  Type 
)

Definition at line 560 of file bcd.c.

564 {
566  HANDLE ElementsHandle, ElementHandle;
567  WCHAR TypeString[22];
568 
569  /* Open the elements key */
570  Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
571  if (NT_SUCCESS(Status))
572  {
573  /* Convert the element ID into a string */
574  if (!_ultow(Type, TypeString, 16))
575  {
576  /* Failed to do so */
578  }
579  else
580  {
581  /* Open the element specifically */
582  Status = BiOpenKey(ElementsHandle, TypeString, &ElementHandle);
583  if (NT_SUCCESS(Status))
584  {
585  /* Delete it */
586  Status = BiDeleteKey(ElementHandle);
587  if (NT_SUCCESS(Status))
588  {
589  /* No point in closing the handle anymore */
590  ElementHandle = NULL;
591  }
592  }
593  else
594  {
595  /* The element doesn't exist */
597  }
598 
599  /* Check if we should close the key */
600  if (ElementHandle)
601  {
602  /* Do it */
603  BiCloseKey(ElementHandle);
604  }
605  }
606  }
607 
608  /* Check if we should close the elements handle */
609  if (ElementsHandle)
610  {
611  /* Do it */
612  BiCloseKey(ElementsHandle);
613  }
614 
615  /* Return whatever the result was */
616  return Status;
617 }
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
Type
Definition: Type.h:6
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_NOT_FOUND
Definition: shellext.h:67
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS BiDeleteKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:886
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24

Referenced by BmPurgeOption().

◆ BcdEnumerateAndUnpackElements()

NTSTATUS BcdEnumerateAndUnpackElements ( _In_ HANDLE  BcdHandle,
_In_ HANDLE  ObjectHandle,
_Out_opt_ PBCD_ELEMENT  Elements,
_Inout_ PULONG  ElementSize,
_Out_ PULONG  ElementCount 
)

Definition at line 1241 of file bcd.c.

1248 {
1249  PVOID LocalElements;
1250  NTSTATUS Status;
1251  ULONG LocalElementCount, LocalElementSize;
1252 
1253  /* Make sure required parameters are there */
1254  if (!(ElementSize) || !(ElementCount) || ((Elements) && (!*ElementSize)))
1255  {
1256  return STATUS_INVALID_PARAMETER;
1257  }
1258 
1259  /* Set initial count to zero */
1260  *ElementCount = 0;
1261 
1262  /* Do the initial enumeration to figure out the size required */
1263  LocalElementSize = 0;
1264  LocalElementCount = 0;
1265  Status = BiEnumerateElements(BcdHandle,
1266  ObjectHandle,
1267  0,
1271  NULL,
1272  &LocalElementSize,
1273  &LocalElementCount);
1275  {
1276  return Status;
1277  }
1278 
1279  /* Now allocate a buffer large enough to hold them */
1280  LocalElements = BlMmAllocateHeap(LocalElementSize);
1281  if (!LocalElements)
1282  {
1284  }
1285 
1286  /* Zero out the array and do the real enumeration this time around */
1287  RtlZeroMemory(LocalElements, LocalElementSize);
1288  Status = BiEnumerateElements(BcdHandle,
1289  ObjectHandle,
1290  0,
1294  LocalElements,
1295  &LocalElementSize,
1296  &LocalElementCount);
1297  if (!NT_SUCCESS(Status))
1298  {
1299  return Status;
1300  }
1301 
1302  /* Now we know the real count */
1303  *ElementCount = LocalElementCount;
1304 
1305  /* Now unpack the data */
1306  Status = BiConvertBcdElements(LocalElements,
1307  Elements,
1308  ElementSize,
1309  &LocalElementCount);
1310  if (NT_SUCCESS(Status))
1311  {
1312  /* Not all elements may have been converted */
1313  *ElementCount = LocalElementCount;
1314  }
1315 
1316  /* Free the local (unpacked) buffer and return status */
1317  BlMmFreeHeap(LocalElements);
1318  return Status;
1319 }
NTSTATUS BiEnumerateElements(_In_ HANDLE BcdHandle, _In_ HANDLE ObjectHandle, _In_ ULONG RootElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:804
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BCD_ENUMERATE_FLAG_DEEP
Definition: bcd.h:315
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
smooth NULL
Definition: ftsmooth.c:416
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BCD_ENUMERATE_FLAG_IN_ORDER
Definition: bcd.h:317
Status
Definition: gdiplustypes.h:24
#define BCD_ENUMERATE_FLAG_DEVICES
Definition: bcd.h:316
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS BiConvertBcdElements(_In_ PBCD_PACKED_ELEMENT Elements, _Out_opt_ PBCD_ELEMENT Buffer, _Inout_ PULONG BufferSize, _Inout_ PULONG ElementCount)
Definition: bcd.c:350

Referenced by BmGetOptionList().

◆ BcdOpenObject()

NTSTATUS BcdOpenObject ( _In_ HANDLE  BcdHandle,
_In_ PGUID  ObjectId,
_Out_ PHANDLE  ObjectHandle 
)

Definition at line 506 of file bcd.c.

511 {
513  GUID LocalGuid;
515  HANDLE RootObjectHandle;
516 
517  /* Assume failure */
518  *ObjectHandle = NULL;
519 
520  /* Initialize GUID string */
521  GuidString.Buffer = NULL;
522 
523  /* Open the root "Objects" handle */
524  RootObjectHandle = NULL;
525  Status = BiOpenKey(BcdHandle, L"Objects", &RootObjectHandle);
526  if (!NT_SUCCESS(Status))
527  {
528  goto Quickie;
529  }
530 
531  /* Capture the object ID and convert it into a string */
532  LocalGuid = *ObjectId;
533  Status = RtlStringFromGUID(&LocalGuid, &GuidString);
534  if (!NT_SUCCESS(Status))
535  {
536  goto Quickie;
537  }
538 
539  /* Now open the key containing this object ID */
540  Status = BiOpenKey(RootObjectHandle, GuidString.Buffer, ObjectHandle);
541 
542 Quickie:
543  /* Free the GUID string if we had one allocated */
544  if (GuidString.Buffer)
545  {
547  }
548 
549  /* Close the root handle if it was open */
550  if (RootObjectHandle)
551  {
552  BiCloseKey(RootObjectHandle);
553  }
554 
555  /* Return the final status */
556  return Status;
557 }
static PWSTR GuidString
Definition: apphelp.c:91
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
Status
Definition: gdiplustypes.h:24

Referenced by BiEnumerateSubElements(), BmGetEntryDescription(), BmGetOptionList(), and BmPurgeOption().

◆ BcdOpenStoreFromFile()

NTSTATUS BcdOpenStoreFromFile ( _In_ PUNICODE_STRING  FileName,
_In_ PHANDLE  BcdHandle 
)

Definition at line 1322 of file bcd.c.

1326 {
1327  ULONG Length;
1329  NTSTATUS Status;
1331 
1332  /* Assume failure */
1333  LocalHandle = NULL;
1334 
1335  /* Allocate a path descriptor */
1336  Length = FileName->Length + sizeof(*FilePath);
1338  if (!FilePath)
1339  {
1340  return STATUS_NO_MEMORY;
1341  }
1342 
1343  /* Initialize it */
1344  FilePath->Version = 1;
1345  FilePath->PathType = InternalPath;
1346  FilePath->Length = Length;
1347 
1348  /* Copy the name and NULL-terminate it */
1349  RtlCopyMemory(FilePath->Path, FileName->Buffer, Length);
1350  FilePath->Path[Length / sizeof(WCHAR)] = UNICODE_NULL;
1351 
1352  /* Open the BCD */
1354  if (NT_SUCCESS(Status))
1355  {
1356  /* Return the handle on success */
1357  *BcdHandle = LocalHandle;
1358  }
1359 
1360  /* Free the descriptor and return the status */
1362  return Status;
1363 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BiAddStoreFromFile(_In_ PBL_FILE_PATH_DESCRIPTOR FilePath, _Out_ PHANDLE StoreHandle)
Definition: bcd.c:1143
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
PCWSTR FilePath
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Status
Definition: gdiplustypes.h:24
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
unsigned int ULONG
Definition: retypes.h:1
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1588

Referenced by BmOpenDataStore().

◆ BiAddStoreFromFile()

NTSTATUS BiAddStoreFromFile ( _In_ PBL_FILE_PATH_DESCRIPTOR  FilePath,
_Out_ PHANDLE  StoreHandle 
)

Definition at line 1143 of file bcd.c.

1147 {
1148  NTSTATUS Status;
1149  HANDLE HiveHandle, KeyHandle;
1150 
1151  /* Load the specified hive */
1152  Status = BiLoadHive(FilePath, &HiveHandle);
1153  if (!NT_SUCCESS(Status))
1154  {
1155  return Status;
1156  }
1157 
1158  /* Open the description key to make sure this is really a BCD */
1159  Status = BiOpenKey(HiveHandle, L"Description", &KeyHandle);
1160  if (NT_SUCCESS(Status))
1161  {
1162  /* It is -- close the key as we don't need it */
1164  *StoreHandle = HiveHandle;
1165  }
1166  else
1167  {
1168  /* Failure, drop a reference on the hive and close the key */
1169  BiDereferenceHive(HiveHandle);
1170  BiCloseKey(HiveHandle);
1171  }
1172 
1173  /* Return the status */
1174  return Status;
1175 }
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
LONG NTSTATUS
Definition: precomp.h:26
PCWSTR FilePath
NTSTATUS BiLoadHive(_In_ PBL_FILE_PATH_DESCRIPTOR FilePath, _Out_ PHANDLE HiveHandle)
Definition: bootreg.c:363
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
VOID BiDereferenceHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:117

Referenced by BcdOpenStoreFromFile().

◆ BiConvertBcdElements()

NTSTATUS BiConvertBcdElements ( _In_ PBCD_PACKED_ELEMENT  Elements,
_Out_opt_ PBCD_ELEMENT  Buffer,
_Inout_ PULONG  BufferSize,
_Inout_ PULONG  ElementCount 
)

Definition at line 350 of file bcd.c.

356 {
358  ULONG ElementSize, AlignedElementSize, AlignedDataSize;
360  PVOID Data;
361  BOOLEAN Exists;
362  ULONG i, j, Count;
363 
364  /* Local variable to keep track of objects */
365  Count = 0;
366 
367  /* Safely compute the element bytes needed */
368  Status = RtlULongMult(*ElementCount, sizeof(BCD_ELEMENT), &ElementSize);
369  if (!NT_SUCCESS(Status))
370  {
371  return Status;
372  }
373 
374  /* Safely align the element size */
375  Status = RtlULongAdd(ElementSize,
376  sizeof(ULONG) - 1,
377  &AlignedElementSize);
378  if (!NT_SUCCESS(Status))
379  {
380  return Status;
381  }
382  AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);
383 
384  /* Do a safe version of Add2Ptr to figure out where the headers will start */
385  Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
386  AlignedElementSize,
387  (PULONG_PTR)&Header);
388  if (!NT_SUCCESS(Status))
389  {
390  return Status;
391  }
392 
393  /* Safely compute the header bytes needed */
394  Status = RtlULongMult(*ElementCount,
395  sizeof(BCD_ELEMENT_HEADER),
396  &ElementSize);
397  if (!NT_SUCCESS(Status))
398  {
399  return Status;
400  }
401 
402  /* Safely align the header size */
403  Status = RtlULongAdd(ElementSize,
404  AlignedElementSize + sizeof(ULONG) - 1,
405  &AlignedElementSize);
406  if (!NT_SUCCESS(Status))
407  {
408  return Status;
409  }
410  AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);
411 
412  /* Do a safe version of Add2Ptr */
413  Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
414  AlignedElementSize,
415  (PULONG_PTR)&Data);
416  if (!NT_SUCCESS(Status))
417  {
418  return Status;
419  }
420 
421  /* Iterate over every element */
422  for (i = 0; i < *ElementCount; i++)
423  {
424  /* Safely align the element size */
425  Status = RtlULongAdd(Elements->Size,
426  sizeof(ULONG) - 1,
427  &AlignedDataSize);
428  if (!NT_SUCCESS(Status))
429  {
430  break;
431  }
432  AlignedDataSize = ALIGN_DOWN(AlignedDataSize, ULONG);
433 
434  /* Safely add the size of this data element */
435  Status = RtlULongAdd(AlignedElementSize,
436  AlignedDataSize,
437  &AlignedElementSize);
438  if (!NT_SUCCESS(Status))
439  {
440  break;
441  }
442 
443  /* Do we have enough space left? */
444  if (*BufferSize >= AlignedElementSize)
445  {
446  /* Check if our root is an inherited object */
447  Exists = FALSE;
448  if (Elements->RootType.PackedValue == BcdLibraryObjectList_InheritedObjects)
449  {
450  /* Yes, scan for us in the current buffer */
451  for (j = 0; j < Count; j++)
452  {
453  /* Do we already exist? */
454  while (Buffer[j].Header->Type == Elements->RootType.PackedValue)
455  {
456  /* Yep */
457  Exists = TRUE;
458  break;
459  }
460  }
461  }
462 
463  /* Have we already found ourselves? */
464  if (!Exists)
465  {
466  /* Nope, one more entry */
467  ++Count;
468 
469  /* Write out the unpacked object */
470  Buffer->Body = Data;
471  Buffer->Header = Header;
472 
473  /* Fill out its header */
474  Header->Size = Elements->Size;
475  Header->Type = Elements->Type;
476  Header->Version = Elements->Version;
477 
478  /* And copy the data */
479  RtlCopyMemory(Data, Elements->Data, Header->Size);
480 
481  /* Move to the next unpacked object and header */
482  ++Buffer;
483  ++Header;
484 
485  /* Move to the next data entry */
486  Data = (PVOID)((ULONG_PTR)Data + AlignedDataSize);
487  }
488  }
489  else
490  {
491  /* Nope, set failure code, but keep going so we can return count */
493  }
494 
495  /* Move to the next element entry */
496  Elements = Elements->NextEntry;
497  }
498 
499  /* Return the new final buffer size and count */
500  *BufferSize = AlignedElementSize;
501  *ElementCount = Count;
502  return Status;
503 }
Data(int index, int value)
Definition: sort_test.cpp:78
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: Header.h:8
unsigned char BOOLEAN
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ALIGN_DOWN(size, type)
Definition: umtypes.h:88
#define BufferSize
Definition: classpnp.h:419
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1
uint32_t * PULONG_PTR
Definition: typedefs.h:63
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34

Referenced by BcdEnumerateAndUnpackElements().

◆ BiConvertElementFormatToValueType()

ULONG BiConvertElementFormatToValueType ( _In_ ULONG  Format)

Definition at line 31 of file bcd.c.

34 {
35  /* Strings and objects are strings */
37  {
38  return REG_SZ;
39  }
40 
41  /* Object lists are arrays of strings */
43  {
44  return REG_MULTI_SZ;
45  }
46 
47  /* Everything else is binary */
48  return REG_BINARY;
49 }
#define REG_BINARY
Definition: nt_native.h:1496
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define BCD_TYPE_STRING
Definition: bcd.h:22
#define BCD_TYPE_OBJECT_LIST
Definition: bcd.h:24
#define BCD_TYPE_OBJECT
Definition: bcd.h:23
#define REG_SZ
Definition: layer.c:22

Referenced by BiEnumerateElements().

◆ BiConvertRegistryDataToElement()

NTSTATUS BiConvertRegistryDataToElement ( _In_ HANDLE  ObjectHandle,
_In_ PVOID  Data,
_In_ ULONG  DataLength,
_In_ BcdElementType  ElementType,
_Out_ PVOID  Element,
_Out_ PULONG  ElementSize 
)

Definition at line 52 of file bcd.c.

60 {
64  BOOLEAN NullTerminate;
65  PBCD_DEVICE_OPTION BcdDevice, ElementDevice;
66  PWCHAR BcdString, ElementString;
67  PGUID ElementGuid; UNICODE_STRING GuidString;
68  PULONGLONG ElementInteger;
69  PUSHORT ElementWord; PBOOLEAN BcdBoolean;
70 
71  /* Assume failure */
72  ReturnedLength = 0;
73 
74  /* Check what type of format we are dealing with */
75  switch (ElementType.Format)
76  {
77  /* Devices -- they are in a binary format */
78  case BCD_TYPE_DEVICE:
79 
80  /* First, make sure it's at least big enough for an empty descriptor */
82  DeviceDescriptor.Unknown))
83  {
85  }
86 
87  /* Both the registry and BCD format are the same */
88  BcdDevice = (PBCD_DEVICE_OPTION)Data;
89  ElementDevice = (PBCD_DEVICE_OPTION)Element;
90 
91  /* Make sure the device fits in the registry data */
92  Device = &BcdDevice->DeviceDescriptor;
93  Size = Device->Size;
94  if ((Size + sizeof(BcdDevice->AssociatedEntry)) != DataLength)
95  {
97  }
98 
99  /* Check if this is a locate device */
100  if (Device->DeviceType == LocateDevice)
101  {
102  EfiPrintf(L"Locates not yet supported\r\n");
103  return STATUS_NOT_SUPPORTED;
104  }
105 
106  /* Make sure the caller's buffer can fit the device */
107  ReturnedLength = Size + sizeof(BcdDevice->AssociatedEntry);
108  if (ReturnedLength > *ElementSize)
109  {
111  break;
112  }
113 
114  /* It'll fit -- copy it in */
115  RtlCopyMemory(&ElementDevice->DeviceDescriptor, Device, Size);
116  ElementDevice->AssociatedEntry = BcdDevice->AssociatedEntry;
118  break;
119 
120  /* Strings -- they are stored as is */
121  case BCD_TYPE_STRING:
122 
123  /* Make sure the string isn't empty or misaligned */
124  if (!(DataLength) || (DataLength & 1))
125  {
127  }
128 
129  /* Both the registry and BCD format are the same */
130  BcdString = (PWCHAR)Data;
131  ElementString = (PWCHAR)Element;
132 
133  /* We'll need as much data as the string has to offer */
135 
136  /* If the string isn't NULL-terminated, do it now */
137  NullTerminate = FALSE;
138  if (BcdString[(DataLength / sizeof(WCHAR)) - 1] != UNICODE_NULL)
139  {
140  ReturnedLength += sizeof(UNICODE_NULL);
141  NullTerminate = TRUE;
142  }
143 
144  /* Will we fit in the caller's buffer? */
145  if (ReturnedLength > *ElementSize)
146  {
148  break;
149  }
150 
151  /* Yep -- copy it in, and NULL-terminate if needed */
152  RtlCopyMemory(Element, Data, DataLength);
153  if (NullTerminate)
154  {
155  ElementString[DataLength / sizeof(WCHAR)] = UNICODE_NULL;
156  }
157 
159  break;
160 
161  /* Objects -- they are stored as GUID Strings */
162  case BCD_TYPE_OBJECT:
163 
164  /* Registry data is a string, BCD data is a GUID */
165  BcdString = (PWCHAR)Data;
166  ElementGuid = (PGUID)Element;
167 
168  /* We need a GUID-sized buffer, does the caller have one? */
169  ReturnedLength = sizeof(*ElementGuid);
170  if (*ElementSize < ReturnedLength)
171  {
173  break;
174  }
175 
176  /* Yep, copy the GUID */
177  RtlInitUnicodeString(&GuidString, BcdString);
178  Status = RtlGUIDFromString(&GuidString, ElementGuid);
179  break;
180 
181  /* Object Lists -- they are stored as arrays of GUID strings */
183 
184  /* Assume an empty list*/
185  ReturnedLength = 0;
186  Length = 0;
188 
189  /* Registry data is an array of strings, BCD data is array of GUIDs */
190  BcdString = (PWCHAR)Data;
191  ElementGuid = (PGUID)Element;
192 
193  /* Loop as long as the array still has strings */
194  while (*BcdString)
195  {
196  /* Don't read beyond the registry data */
197  if (Length >= DataLength)
198  {
199  break;
200  }
201 
202  /* One more GUID -- does the caller have space? */
203  ReturnedLength += sizeof(GUID);
204  if (ReturnedLength <= *ElementSize)
205  {
206  /* Convert and add it in */
207  RtlInitUnicodeString(&GuidString, BcdString);
208  Status = RtlGUIDFromString(&GuidString, ElementGuid);
209  if (!NT_SUCCESS(Status))
210  {
211  break;
212  }
213 
214  /* Move to the next GUID in the caller's buffer */
215  ElementGuid++;
216  }
217 
218  /* Move to the next string in the registry array */
219  Size = (wcslen(BcdString) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
220  Length += Size;
221  BcdString = (PWCHAR)((ULONG_PTR)BcdString + Length);
222  }
223 
224  /* Check if we failed anywhere */
225  if (!NT_SUCCESS(Status))
226  {
227  break;
228  }
229 
230  /* Check if we consumed more space than we have */
231  if (ReturnedLength > *ElementSize)
232  {
234  }
235 
236  /* All good here */
237  break;
238 
239  /* Integer -- stored as binary */
240  case BCD_TYPE_INTEGER:
241 
242  /* BCD data is a ULONGLONG, registry data is 8 bytes binary */
243  ElementInteger = (PULONGLONG)Element;
244  ReturnedLength = sizeof(*ElementInteger);
245 
246  /* Make sure the registry data makes sense */
248  {
250  }
251 
252  /* Make sure the caller has space */
253  if (*ElementSize < ReturnedLength)
254  {
256  break;
257  }
258 
259  /* Write the integer result */
260  *ElementInteger = 0;
261  RtlCopyMemory(ElementInteger, Data, DataLength);
263  break;
264 
265  /* Boolean -- stored as binary */
266  case BCD_TYPE_BOOLEAN:
267 
268  /* BCD data is a BOOLEAN, registry data is 2 bytes binary */
269  ElementWord = (PUSHORT)Element;
270  BcdBoolean = (PBOOLEAN)Data;
271  ReturnedLength = sizeof(ElementWord);
272 
273  /* Make sure the registry data makes sense */
274  if (DataLength != sizeof(*BcdBoolean))
275  {
277  }
278 
279  /* Make sure the caller has space */
280  if (*ElementSize < ReturnedLength)
281  {
283  break;
284  }
285 
286  /* Write the boolean result */
287  *ElementWord = 0;
288  *ElementWord = *BcdBoolean != 0;
290  break;
291 
292  /* Integer list --stored as binary */
294 
295  /* BCD Data is n ULONGLONGs, registry data is n*8 bytes binary */
297  if (!(DataLength) || (DataLength & 7))
298  {
300  }
301 
302  /* Make sure the caller has space */
303  if (*ElementSize < ReturnedLength)
304  {
306  break;
307  }
308 
309  /* Write the integer list result */
310  RtlCopyMemory(Element, Data, DataLength);
312  break;
313 
314  /* Arbitrary data */
315  default:
316 
317  /* Registry data is copied binary as-is */
319 
320  /* Make sure it's not empty */
321  if (!DataLength)
322  {
324  }
325 
326  /* Make sure the caller has space */
327  if (*ElementSize < ReturnedLength)
328  {
330  break;
331  }
332 
333  /* Write the result */
334  RtlCopyMemory(Element, Data, DataLength);
336  break;
337  }
338 
339  /* If we got here due to success or space issues, write the size */
341  {
342  *ElementSize = ReturnedLength;
343  }
344 
345  /* All done, return our conversion result */
346  return Status;
347 }
GUID * PGUID
Definition: bdasup.h:12
static PWSTR GuidString
Definition: apphelp.c:91
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define BCD_TYPE_INTEGER
Definition: bcd.h:25
LONG NTSTATUS
Definition: precomp.h:26
#define BCD_TYPE_BOOLEAN
Definition: bcd.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
#define BCD_TYPE_INTEGER_LIST
Definition: bcd.h:27
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
unsigned char BOOLEAN
BL_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: bcd.h:298
#define BCD_TYPE_STRING
Definition: bcd.h:22
const KSDEVICE_DESCRIPTOR DeviceDescriptor
Definition: splitter.c:257
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING, GUID *)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define BCD_TYPE_OBJECT_LIST
Definition: bcd.h:24
char * PBOOLEAN
Definition: retypes.h:11
static const WCHAR L[]
Definition: oid.c:1250
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct _GUID GUID
GUID AssociatedEntry
Definition: bcd.h:297
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define BCD_TYPE_DEVICE
Definition: bcd.h:21
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
struct _BCD_DEVICE_OPTION * PBCD_DEVICE_OPTION
#define BCD_TYPE_OBJECT
Definition: bcd.h:23
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2725
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by BiEnumerateElements().

◆ BiEnumerateElements()

NTSTATUS BiEnumerateElements ( _In_ HANDLE  BcdHandle,
_In_ HANDLE  ObjectHandle,
_In_ ULONG  RootElementType,
_In_ ULONG  Flags,
_Out_opt_ PBCD_PACKED_ELEMENT  Elements,
_Inout_ PULONG  ElementSize,
_Out_ PULONG  ElementCount 
)

Definition at line 804 of file bcd.c.

813 {
814  HANDLE ElementsHandle, ElementHandle;
815  ULONG TotalLength, RegistryElementDataLength, RemainingLength;
817  ULONG i;
818  PVOID ElementData, SubObjectList, RegistryElementData;
819  BcdElementType ElementType;
820  PBCD_PACKED_ELEMENT PreviousElement, ElementsStart;
821  ULONG SubElementCount, SubKeyCount, SubObjectCount, ElementDataLength;
822  PWCHAR ElementName;
823  PWCHAR* SubKeys;
824 
825  /* Assume failure */
826  *ElementCount = 0;
827 
828  /* Initialize all locals that are checked at the end*/
829  SubKeys = NULL;
830  ElementsHandle = NULL;
831  ElementHandle = NULL;
832  ElementData = NULL;
833  RegistryElementData = NULL;
834  PreviousElement = NULL;
835  ElementName = NULL;
836  SubObjectList = NULL;
837  TotalLength = 0;
838  ElementDataLength = 0;
839  SubObjectCount = 0;
840  RemainingLength = 0;
841  ElementsStart = Elements;
842 
843  /* Open the root object key's elements */
844  Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
845  if (!NT_SUCCESS(Status))
846  {
847  goto Quickie;
848  }
849 
850  /* Enumerate all elements */
851  Status = BiEnumerateSubKeys(ElementsHandle, &SubKeys, &SubKeyCount);
852  if (!NT_SUCCESS(Status))
853  {
854  goto Quickie;
855  }
856 
857  /* Iterate over each one */
858  for (i = 0; i < SubKeyCount; i++)
859  {
860  /* Open the element */
861  ElementName = SubKeys[i];
862  Status = BiOpenKey(ElementsHandle, ElementName, &ElementHandle);
863  if (!NT_SUCCESS(Status))
864  {
865  EfiPrintf(L"ELEMENT ERROR: %lx\r\n", Status);
866  EfiStall(100000);
867  break;
868  }
869 
870  /* The name of the element is its data type */
871  ElementType.PackedValue = wcstoul(SubKeys[i], NULL, 16);
872  if (!(ElementType.PackedValue) || (ElementType.PackedValue == -1))
873  {
874  EfiPrintf(L"Value invalid\r\n");
875  BiCloseKey(ElementHandle);
876  ElementHandle = NULL;
877  continue;
878  }
879 
880  /* Read the appropriate registry value type for this element */
881  Status = BiGetRegistryValue(ElementHandle,
882  L"Element",
884  ElementType.Format),
885  &RegistryElementData,
886  &RegistryElementDataLength);
887  if (!NT_SUCCESS(Status))
888  {
889  EfiPrintf(L"Element invalid\r\n");
890  break;
891  }
892 
893  /* Now figure out how much space the converted element will need */
894  ElementDataLength = 0;
895  Status = BiConvertRegistryDataToElement(ObjectHandle,
896  RegistryElementData,
897  RegistryElementDataLength,
898  ElementType,
899  NULL,
900  &ElementDataLength);
902  {
903  break;
904  }
905 
906  /* Allocate a buffer big enough for the converted element */
907  ElementData = BlMmAllocateHeap(ElementDataLength);
908  if (!ElementData)
909  {
911  break;
912  }
913 
914  /* And actually convert it this time around */
915  Status = BiConvertRegistryDataToElement(ObjectHandle,
916  RegistryElementData,
917  RegistryElementDataLength,
918  ElementType,
919  ElementData,
920  &ElementDataLength);
921  if (!NT_SUCCESS(Status))
922  {
923  break;
924  }
925 
926  /* Safely add space for the packed element header */
927  Status = RtlULongAdd(TotalLength,
929  &TotalLength);
930  if (!NT_SUCCESS(Status))
931  {
932  break;
933  }
934 
935  /* Safely add space for the data of the element itself */
936  Status = RtlULongAdd(TotalLength, ElementDataLength, &TotalLength);
937  if (!NT_SUCCESS(Status))
938  {
939  break;
940  }
941 
942  /* One more element */
943  ++*ElementCount;
944 
945  /* See how much space we were given */
946  RemainingLength = *ElementSize;
947  if (RemainingLength >= TotalLength)
948  {
949  /* Set the next pointer */
950  Elements->NextEntry = (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart + TotalLength);
951 
952  /* Fill this one out */
953  Elements->RootType.PackedValue = RootElementType;
954  Elements->Version = 1;
955  Elements->Type = ElementType.PackedValue;
956  Elements->Size = ElementDataLength;
957 
958  /* Add the data */
959  RtlCopyMemory(Elements->Data, ElementData, ElementDataLength);
960  RemainingLength -= TotalLength;
961 
962  /* Move to the next element on the next pass */
963  PreviousElement = Elements;
964  Elements = Elements->NextEntry;
965  }
966  else
967  {
968  /* We're out of space */
969  RemainingLength = 0;
970  }
971 
972  /* Are we enumerating devices, and is this a device? */
974  (ElementType.Format == BCD_TYPE_DEVICE))
975  {
976  /* Yep, so go inside to enumerate it */
977  Status = BiEnumerateSubElements(BcdHandle,
978  ElementData,
979  ElementType.PackedValue,
980  Flags,
981  &Elements,
982  &ElementDataLength,
983  &SubElementCount);
985  {
986  /* Safely add the length of the sub elements */
987  Status = RtlULongAdd(TotalLength,
988  ElementDataLength,
989  &TotalLength);
990  if (!NT_SUCCESS(Status))
991  {
992  break;
993  }
994 
995  /* Add the sub elements to the total */
996  *ElementCount += SubElementCount;
997 
998  /* See if we have enough space*/
999  if (*ElementSize >= TotalLength)
1000  {
1001  /* Were there any subelements? */
1002  if (SubElementCount)
1003  {
1004  /* Update to keep track of these new subelements */
1005  ElementDataLength = *ElementSize - TotalLength;
1006 
1007  /* Link the subelements into the chain */
1008  PreviousElement = Elements;
1009  PreviousElement->NextEntry =
1010  (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart +
1011  TotalLength);
1012  Elements = PreviousElement->NextEntry;
1013  }
1014  }
1015  else
1016  {
1017  /* We're out of space */
1018  ElementDataLength = 0;
1019  }
1020  }
1021  else if ((Status != STATUS_NOT_FOUND) &&
1023  {
1024  /* Fatal error trying to read the data, so fail */
1025  break;
1026  }
1027  }
1028  else if ((Flags & BCD_ENUMERATE_FLAG_DEEP) &&
1030  {
1031  /* Inherited objects are requested, so allocate a buffer for them */
1032  SubObjectList = BlMmAllocateHeap(ElementDataLength);
1033  if (!SubObjectList)
1034  {
1036  break;
1037  }
1038 
1039  /* Copy the elements into the list. They are arrays of GUIDs */
1040  RtlCopyMemory(SubObjectList, ElementData, ElementDataLength);
1041  SubObjectCount = ElementDataLength / sizeof(GUID);
1042  }
1043 
1044  /* Free our local buffers */
1045  BlMmFreeHeap(ElementData);
1046  BlMmFreeHeap(RegistryElementData);
1047  ElementData = NULL;
1048  RegistryElementData = NULL;
1049 
1050  /* Close the key */
1051  BiCloseKey(ElementHandle);
1052  ElementHandle = NULL;
1053  ElementName = NULL;
1054  }
1055 
1056  /* Did we end up here with a sub object list after successful loop parsing? */
1057  if ((i != 0) && (i == SubKeyCount) && (SubObjectList))
1058  {
1059  /* We will actually enumerate it now, at the end */
1061  SubObjectList,
1062  SubObjectCount,
1063  Flags,
1064  Elements,
1065  &RemainingLength,
1066  &SubElementCount);
1068  {
1069  /* Safely add the length of the sub elements */
1070  Status = RtlULongAdd(TotalLength, RemainingLength, &TotalLength);
1071  if ((NT_SUCCESS(Status)) && (SubElementCount))
1072  {
1073  /* Add the sub elements to the total */
1074  *ElementCount += SubElementCount;
1075 
1076  /* Don't touch PreviousElement anymore */
1077  PreviousElement = NULL;
1078  }
1079  }
1080  }
1081 
1082 Quickie:
1083  /* Free the sub object list, if any */
1084  if (SubObjectList)
1085  {
1086  BlMmFreeHeap(SubObjectList);
1087  }
1088 
1089  /* Free any local element data */
1090  if (ElementData)
1091  {
1092  BlMmFreeHeap(ElementData);
1093  }
1094 
1095  /* Free any local registry data */
1096  if (RegistryElementData)
1097  {
1098  BlMmFreeHeap(RegistryElementData);
1099  }
1100 
1101  /* Close the handle if still opened */
1102  if (ElementHandle)
1103  {
1104  BiCloseKey(ElementHandle);
1105  }
1106 
1107  /* Terminate the last element, if any */
1108  if (PreviousElement)
1109  {
1110  PreviousElement->NextEntry = NULL;
1111  }
1112 
1113  /* Close the root handle if still opened */
1114  if (ElementsHandle)
1115  {
1116  BiCloseKey(ElementsHandle);
1117  }
1118 
1119  /* Set failure code if out of space */
1120  if (*ElementSize < TotalLength)
1121  {
1123  }
1124 
1125  /* Other errors will send a notification error */
1127  {
1128  BiNotifyEnumerationError(ObjectHandle, ElementName, Status);
1129  }
1130 
1131  /* Finally free the subkeys array */
1132  if (SubKeys)
1133  {
1134  BlMmFreeHeap(SubKeys);
1135  }
1136 
1137  /* And return the required, final length and status */
1138  *ElementSize = TotalLength;
1139  return Status;
1140 }
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
NTSTATUS BiConvertRegistryDataToElement(_In_ HANDLE ObjectHandle, _In_ PVOID Data, _In_ ULONG DataLength, _In_ BcdElementType ElementType, _Out_ PVOID Element, _Out_ PULONG ElementSize)
Definition: bcd.c:52
#define BCD_ENUMERATE_FLAG_DEEP
Definition: bcd.h:315
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_In_ ULONG TotalLength
Definition: usbdlib.h:145
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _BCD_PACKED_ELEMENT * NextEntry
Definition: bcd.h:283
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS BiGetRegistryValue(_In_ HANDLE KeyHandle, _In_ PWCHAR ValueName, _In_ ULONG Type, _Out_ PVOID *Buffer, _Out_ PULONG ValueLength)
Definition: bootreg.c:651
struct _BCD_PACKED_ELEMENT * PBCD_PACKED_ELEMENT
smooth NULL
Definition: ftsmooth.c:416
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
#define STATUS_NOT_FOUND
Definition: shellext.h:67
ULONG Format
Definition: bcd.h:238
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
struct _GUID GUID
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS BiEnumerateSubElements(_In_ HANDLE BcdHandle, _In_ PVOID Object, _In_ ULONG ElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT *Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:620
NTSTATUS BiEnumerateSubObjectElements(_In_ HANDLE BcdHandle, _Out_ PGUID SubObjectList, _In_ ULONG SubObjectCount, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:688
ULONG BiConvertElementFormatToValueType(_In_ ULONG Format)
Definition: bcd.c:31
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define BCD_TYPE_DEVICE
Definition: bcd.h:21
ULONG PackedValue
Definition: bcd.h:234
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BCD_ENUMERATE_FLAG_DEVICES
Definition: bcd.h:316
VOID BiNotifyEnumerationError(_In_ HANDLE ObjectHandle, _In_ PWCHAR ElementName, _In_ NTSTATUS Status)
Definition: bcd.c:17
NTSTATUS BiEnumerateSubKeys(_In_ HANDLE KeyHandle, _Out_ PWCHAR **SubKeyList, _Out_ PULONG SubKeyCount)
Definition: bootreg.c:717
unsigned int ULONG
Definition: retypes.h:1

Referenced by BcdEnumerateAndUnpackElements(), and BiEnumerateSubElements().

◆ BiEnumerateSubElements()

NTSTATUS BiEnumerateSubElements ( _In_ HANDLE  BcdHandle,
_In_ PVOID  Object,
_In_ ULONG  ElementType,
_In_ ULONG  Flags,
_Out_opt_ PBCD_PACKED_ELEMENT Elements,
_Inout_ PULONG  ElementSize,
_Out_ PULONG  ElementCount 
)

Definition at line 620 of file bcd.c.

629 {
630  NTSTATUS Status;
631  PBCD_PACKED_ELEMENT Element;
632  HANDLE ObjectHandle;
633  ULONG ParsedElements, RequiredSize;
634 
635  /* Assume empty */
636  *ElementCount = 0;
637  RequiredSize = 0;
638  ParsedElements = 0;
639 
640  /* Open the object */
641  Status = BcdOpenObject(BcdHandle, Object, &ObjectHandle);
642  if (!NT_SUCCESS(Status))
643  {
644  goto Quickie;
645  }
646 
647  /* Read the first entry, and the size available */
648  Element = *Elements;
649  RequiredSize = *ElementSize;
650 
651  /* Enumerate the object into the element array */
652  Status = BiEnumerateElements(BcdHandle,
653  ObjectHandle,
654  ElementType,
655  Flags,
656  Element,
657  &RequiredSize,
658  &ParsedElements);
659 
660  /* Close the handle and bail out if we couldn't enumerate */
661  BiCloseKey(ObjectHandle);
662  if (!NT_SUCCESS(Status))
663  {
664  goto Quickie;
665  }
666 
667  /* Check if the and subelements were present */
668  if (ParsedElements)
669  {
670  /* Keep going until the last one */
671  while (Element->NextEntry)
672  {
673  Element = Element->NextEntry;
674  }
675 
676  /* Set the new buffer location to the last element */
677  *Elements = Element;
678  }
679 
680 Quickie:
681  /* Return the number of sub-elements and their size */
682  *ElementCount = ParsedElements;
683  *ElementSize = RequiredSize;
684  return Status;
685 }
NTSTATUS BiEnumerateElements(_In_ HANDLE BcdHandle, _In_ HANDLE ObjectHandle, _In_ ULONG RootElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:804
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
LONG NTSTATUS
Definition: precomp.h:26
struct _BCD_PACKED_ELEMENT * NextEntry
Definition: bcd.h:283
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS BcdOpenObject(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _Out_ PHANDLE ObjectHandle)
Definition: bcd.c:506
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static IUnknown Object
Definition: main.c:512
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1

Referenced by BiEnumerateElements(), and BiEnumerateSubObjectElements().

◆ BiEnumerateSubObjectElements()

NTSTATUS BiEnumerateSubObjectElements ( _In_ HANDLE  BcdHandle,
_Out_ PGUID  SubObjectList,
_In_ ULONG  SubObjectCount,
_In_ ULONG  Flags,
_Out_opt_ PBCD_PACKED_ELEMENT  Elements,
_Inout_ PULONG  ElementSize,
_Out_ PULONG  ElementCount 
)

Definition at line 688 of file bcd.c.

697 {
699  ULONG SubElementCount, TotalSize, RequiredSize, CurrentSize, i;
700  PBCD_PACKED_ELEMENT PreviousElement;
701 
702  /* Assume empty list */
703  *ElementCount = 0;
705 
706  /* Initialize variables */
707  TotalSize = 0;
708  PreviousElement = NULL;
709 
710  /* Set the currently remaining size based on caller's input */
711  CurrentSize = *ElementSize;
712 
713  /* Iterate over every subje object */
714  for (i = 0; i < SubObjectCount; i++)
715  {
716  /* Set the currently remaining buffer space */
717  RequiredSize = CurrentSize;
718 
719  /* Enumerate the inherited sub elements */
720  Status = BiEnumerateSubElements(BcdHandle,
721  &SubObjectList[i],
723  Flags,
724  &Elements,
725  &RequiredSize,
726  &SubElementCount);
728  {
729  /* Safely add the length of the sub elements */
730  Status = RtlULongAdd(TotalSize, RequiredSize, &TotalSize);
731  if (!NT_SUCCESS(Status))
732  {
733  break;
734  }
735 
736  /* Add the sub elements to the total */
737  *ElementCount += SubElementCount;
738 
739  /* See if we have enough space*/
740  if (*ElementSize >= TotalSize)
741  {
742  /* Were there any subelements? */
743  if (SubElementCount)
744  {
745  /* Update to keep track of these new subelements */
746  CurrentSize = *ElementSize - TotalSize;
747 
748  /* Link the subelements into the chain */
749  PreviousElement = Elements;
750  PreviousElement->NextEntry =
751  (PBCD_PACKED_ELEMENT)((ULONG_PTR)Elements + TotalSize);
752  Elements = PreviousElement->NextEntry;
753  }
754  }
755  else
756  {
757  /* We're out of space */
758  CurrentSize = 0;
759  }
760  }
761  else if ((Status != STATUS_NOT_FOUND) &&
763  {
764  /* Some other fatal error, break out */
765  break;
766  }
767  else
768  {
769  /* The sub element was not found, print a warning but keep going */
770  BlStatusPrint(L"Ignoring missing BCD inherit object: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
771  (&SubObjectList[i])->Data1,
772  (&SubObjectList[i])->Data2,
773  (&SubObjectList[i])->Data3,
774  (&SubObjectList[i])->Data4[0],
775  (&SubObjectList[i])->Data4[1],
776  (&SubObjectList[i])->Data4[2],
777  (&SubObjectList[i])->Data4[3],
778  (&SubObjectList[i])->Data4[4],
779  (&SubObjectList[i])->Data4[5],
780  (&SubObjectList[i])->Data4[6],
781  (&SubObjectList[i])->Data4[7]);
783  }
784  }
785 
786  /* Terminate the last element, if one was left */
787  if (PreviousElement)
788  {
789  PreviousElement->NextEntry = NULL;
790  }
791 
792  /* Set failure code if we ran out of space */
793  if (*ElementSize < TotalSize)
794  {
796  }
797 
798  /* Return final length and status */
799  *ElementSize = TotalSize;
800  return Status;
801 }
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _BCD_PACKED_ELEMENT * NextEntry
Definition: bcd.h:283
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _BCD_PACKED_ELEMENT * PBCD_PACKED_ELEMENT
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
#define STATUS_NOT_FOUND
Definition: shellext.h:67
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS BiEnumerateSubElements(_In_ HANDLE BcdHandle, _In_ PVOID Object, _In_ ULONG ElementType, _In_ ULONG Flags, _Out_opt_ PBCD_PACKED_ELEMENT *Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:620
VOID BlStatusPrint(_In_ PCWCH Format,...)
Definition: debug.c:75
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2725

Referenced by BiEnumerateElements().

◆ BiGetObjectDescription()

NTSTATUS BiGetObjectDescription ( _In_ HANDLE  ObjectHandle,
_Out_ PBCD_OBJECT_DESCRIPTION  Description 
)

Definition at line 1178 of file bcd.c.

1182 {
1183  NTSTATUS Status;
1184  HANDLE DescriptionHandle;
1185  PULONG Data;
1186  ULONG Length;
1187 
1188  /* Initialize locals */
1189  Data = NULL;
1190  DescriptionHandle = NULL;
1191 
1192  /* Open the description key */
1193  Status = BiOpenKey(ObjectHandle, L"Description", &DescriptionHandle);
1194  if (NT_SUCCESS(Status))
1195  {
1196  /* It exists */
1197  Description->Valid = TRUE;
1198 
1199  /* Read the type */
1200  Length = 0;
1201  Status = BiGetRegistryValue(DescriptionHandle,
1202  L"Type",
1203  REG_DWORD,
1204  (PVOID*)&Data,
1205  &Length);
1206  if (NT_SUCCESS(Status))
1207  {
1208  /* Make sure it's the length we expected it to be */
1209  if (Length == sizeof(Data))
1210  {
1211  /* Return the type that is stored there */
1212  Description->Type = *Data;
1213  }
1214  else
1215  {
1216  /* Invalid type value */
1218  }
1219  }
1220  }
1221 
1222  /* Did we have a handle open? */
1223  if (DescriptionHandle)
1224  {
1225  /* Close it */
1226  BiCloseKey(DescriptionHandle);
1227  }
1228 
1229  /* Did we have data allocated? */
1230  if (Data)
1231  {
1232  /* Free it */
1233  BlMmFreeHeap(Data);
1234  }
1235 
1236  /* Return back to caller */
1237  return Status;
1238 }
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR Description[]
Definition: oid.c:1266
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BiGetRegistryValue(_In_ HANDLE KeyHandle, _In_ PWCHAR ValueName, _In_ ULONG Type, _Out_ PVOID *Buffer, _Out_ PULONG ValueLength)
Definition: bootreg.c:651
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by BmGetEntryDescription().

◆ BiNotifyEnumerationError()

VOID BiNotifyEnumerationError ( _In_ HANDLE  ObjectHandle,
_In_ PWCHAR  ElementName,
_In_ NTSTATUS  Status 
)

Definition at line 17 of file bcd.c.

22 {
23  /* Stub for now */
24  UNREFERENCED_PARAMETER(ObjectHandle);
25  UNREFERENCED_PARAMETER(ElementName);
27  EfiPrintf(L"Error in BiNotify: %lx for element %s\r\n", Status, ElementName);
28 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126

Referenced by BiEnumerateElements().