/** Validate input console variable data. If found the device path is not a valid device path, remove the variable. @param VariableName Input console variable name. **/ VOID BdsFormalizeConsoleVariable ( IN CHAR16 *VariableName ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN VariableSize; EFI_STATUS Status; GetEfiGlobalVariable2 (VariableName, (VOID **) &DevicePath, &VariableSize); if ((DevicePath != NULL) && !IsDevicePathValid (DevicePath, VariableSize)) { Status = gRT->SetVariable ( VariableName, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); // // Deleting variable with current variable implementation shouldn't fail. // ASSERT_EFI_ERROR (Status); } if (DevicePath != NULL) { FreePool (DevicePath); } }
/** Returns the size of a device path in bytes. This function returns the size, in bytes, of the device path data structure specified by DevicePath including the end of device path node. If DevicePath is NULL or invalid, then 0 is returned. @param DevicePath A pointer to a device path data structure. @retval 0 If DevicePath is NULL or invalid. @retval Others The size of a device path in bytes. **/ UINTN EFIAPI UefiDevicePathLibGetDevicePathSize ( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CONST EFI_DEVICE_PATH_PROTOCOL *Start; if (DevicePath == NULL) { return 0; } if (!IsDevicePathValid (DevicePath, 0)) { return 0; } // // Search for the end of the device path structure // Start = DevicePath; while (!IsDevicePathEnd (DevicePath)) { DevicePath = NextDevicePathNode (DevicePath); } // // Compute the size and add back in the size of the end device path structure // return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath); }
/** Validate input console variable data. If found the device path is not a valid device path, remove the variable. @param VariableName Input console variable name. **/ VOID BdsFormalizeConsoleVariable ( IN CHAR16 *VariableName ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN VariableSize; // EFI_STATUS Status; DevicePath = BdsLibGetVariableAndSize ( VariableName, &gEfiGlobalVariableGuid, &VariableSize ); if ((DevicePath != NULL) && !IsDevicePathValid (DevicePath, VariableSize)) { /*Status = */gRT->SetVariable ( VariableName, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); // ASSERT_EFI_ERROR (Status); } }
EFIAPI GetNextDevicePathInstance ( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT UINTN *Size ) { EFI_DEVICE_PATH_PROTOCOL *DevPath; EFI_DEVICE_PATH_PROTOCOL *ReturnValue; UINT8 Temp; ASSERT (Size != NULL); if (DevicePath == NULL || *DevicePath == NULL) { *Size = 0; return NULL; } if (!IsDevicePathValid (*DevicePath, 0)) { return NULL; } // // Find the end of the device path instance // DevPath = *DevicePath; while (!IsDevicePathEndType (DevPath)) { DevPath = NextDevicePathNode (DevPath); } // // Compute the size of the device path instance // *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL); // // Make a copy and return the device path instance // Temp = DevPath->SubType; DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; ReturnValue = DuplicateDevicePath (*DevicePath); DevPath->SubType = Temp; // // If DevPath is the end of an entire device path, then another instance // does not follow, so *DevicePath is set to NULL. // if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { *DevicePath = NULL; } else { *DevicePath = NextDevicePathNode (DevPath); } return ReturnValue; }
/** Internal check for device path. @param[in] VariablePropery Pointer to variable property. @param[in] DataSize Data size. @param[in] Data Pointer to data buffer. @retval EFI_SUCCESS The SetVariable check result was success. @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path. **/ EFI_STATUS EFIAPI InternalVarCheckDevicePath ( IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery, IN UINTN DataSize, IN VOID *Data ) { if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) { return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }
/** Internal check for load option. @param[in] VariablePropery Pointer to variable property. @param[in] DataSize Data size. @param[in] Data Pointer to data buffer. @retval EFI_SUCCESS The SetVariable check result was success. @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option. **/ EFI_STATUS EFIAPI InternalVarCheckLoadOption ( IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery, IN UINTN DataSize, IN VOID *Data ) { UINT16 FilePathListLength; CHAR16 *Description; EFI_DEVICE_PATH_PROTOCOL *FilePathList; FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32))); // // Check Description // Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16)); while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) { if (*Description == L'\0') { break; } Description++; } if ((UINTN) Description >= ((UINTN) Data + DataSize)) { return EFI_INVALID_PARAMETER; } Description++; // // Check FilePathList // FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description; if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) { return EFI_INVALID_PARAMETER; } if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) { return EFI_INVALID_PARAMETER; } if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { return EFI_INVALID_PARAMETER; } if (!IsDevicePathValid (FilePathList, FilePathListLength)) { return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }