conplatform.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 948 行 · 第 1/2 页
C
948 行
//
// Get the Device Path Protocol so the environment variables can be updated
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **)&DevicePath,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
//
// Remove DevicePath from ConInDev, ConOutDev, and StdErrDev
//
Status = ConPlatformUpdateDeviceVariable (
VarConsoleInpDev,
DevicePath,
FALSE
);
Status = ConPlatformUpdateDeviceVariable (
VarConsoleOutDev,
DevicePath,
FALSE
);
Status = ConPlatformUpdateDeviceVariable (
VarErrorOutDev,
DevicePath,
FALSE
);
}
}
//
// Uninstall the Console Device GUIDs from Controller Handle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiConsoleInDeviceGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Status = gBS->UninstallMultipleProtocolInterfaces (
ControllerHandle,
&gEfiConsoleInDeviceGuid, NULL,
NULL
);
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiConsoleOutDeviceGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Status = gBS->UninstallMultipleProtocolInterfaces (
ControllerHandle,
&gEfiConsoleOutDeviceGuid, NULL,
NULL
);
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiStandardErrorDeviceGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Status = gBS->UninstallMultipleProtocolInterfaces (
ControllerHandle,
&gEfiStandardErrorDeviceGuid, NULL,
NULL
);
}
//
// Close the Simple Input and Simple Text Output Protocols
//
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleTextInProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleTextOutProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
VOID *
ConPlatformGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
/*++
Routine Description:
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. On failure return NULL.
Arguments:
Name - String part of EFI variable name
VendorGuid - GUID part of EFI variable name
VariableSize - Returns the size of the EFI variable that was read
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is repsoncible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
VOID *Buffer;
//
// Allocate a small buffer to test if the variable exists.
//
*VariableSize = 1;
Status = gBS->AllocatePool (EfiBootServicesData, *VariableSize, &Buffer);
if (EFI_ERROR (Status)) {
*VariableSize = 0;
return NULL;
}
//
// Test to see if the variable exists. If it doesn't then free Buffer
// and return NULL.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, VariableSize, Buffer);
if (Status == EFI_SUCCESS) {
return Buffer;
} else if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
gBS->FreePool (Buffer);
Status = gBS->AllocatePool (EfiBootServicesData, *VariableSize, &Buffer);
if (EFI_ERROR (Status)) {
*VariableSize = 0;
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, VariableSize, Buffer);
if (EFI_ERROR (Status)) {
*VariableSize = 0;
gBS->FreePool (Buffer);
return NULL;
}
return Buffer;
} else {
//
// Variable not found or other errors met.
//
*VariableSize = 0;
gBS->FreePool (Buffer);
return NULL;
}
}
EFI_STATUS
ConPlatformMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single,
IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
IN BOOLEAN Delete
)
/*++
Routine Description:
Function compares a device path data structure to that of all the nodes of a
second device path instance.
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
points to the remaining device path data structure.
(remaining device path = Multi - Single.)
Delete - If TRUE, means removing Single from Multi.
If FALSE, the routine just check whether Single matches
with any instance in Multi.
Returns:
The function returns EFI_SUCCESS if the Single is contained within Multi.
Otherwise, EFI_NOT_FOUND is returned.
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
//
// if performing Delete operation, the NewDevicePath must not be NULL.
//
if (Delete) {
if (NewDevicePath == NULL) {
return EFI_INVALID_PARAMETER;
}
*NewDevicePath = NULL;
}
if (!Multi || !Single) {
return EFI_NOT_FOUND;
}
DevicePath = Multi;
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
//
// search for the match of 'Single' in 'Multi'
//
while (DevicePathInst != NULL) {
if (EfiCompareMem (Single, DevicePathInst, Size) == 0) {
if (!Delete) {
return EFI_SUCCESS;
}
} else {
if (Delete) {
TempDevicePath = EfiAppendDevicePathInstance (*NewDevicePath,
DevicePathInst);
if (*NewDevicePath) {
gBS->FreePool (*NewDevicePath);
}
*NewDevicePath = TempDevicePath;
}
}
gBS->FreePool(DevicePathInst);
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
}
if (Delete) {
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
EFI_STATUS
ConPlatformCheckVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT8 *Variable;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
EFI_STATUS Status;
Variable = NULL;
//
// Get Variable and its size according to variable name.
// The memory for Variable is allocated within ConPlatformGetVaribleAndSize(),
// it is the caller's responsibility to free the memory before return.
//
Variable = ConPlatformGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
//
// The Variable was not found
//
if (Variable == NULL) {
return EFI_SUCCESS;
}
//
// Variable is found.
//
VariableDevicePath = (EFI_DEVICE_PATH_PROTOCOL*)Variable;
//
// Check whether the specified DevicePath is contained in the Variable
//
Status = ConPlatformMatchDevicePaths (VariableDevicePath,
DevicePath,
NULL,
FALSE);
if (Variable) {
gBS->FreePool (Variable);
}
return Status;
}
EFI_STATUS
ConPlatformUpdateDeviceVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN BOOLEAN Append
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
UINT8 *Variable;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;
if (DevicePath == NULL) {
return EFI_INVALID_PARAMETER;
}
Variable = NULL;
NewVariableDevicePath = NULL;
//
// Get Variable and its size according to variable name.
// The memory for Variable is allocated within ConPlatformGetVaribleAndSize(),
// it is the caller's responsibility to free the memory before return.
//
Variable = ConPlatformGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
VariableDevicePath = (EFI_DEVICE_PATH_PROTOCOL*)Variable;
if (Append) {
Status = ConPlatformMatchDevicePaths (VariableDevicePath,
DevicePath,
&NewVariableDevicePath,
FALSE);
if (!EFI_ERROR(Status)) {
//
// The device path has already in the variable
//
if (Variable) {
gBS->FreePool (Variable);
}
if (NewVariableDevicePath) {
gBS->FreePool (NewVariableDevicePath);
}
return EFI_SUCCESS;
}
//
// Append DevicePath to the environment variable that
// is a multi-instance device path.
//
NewVariableDevicePath = EfiAppendDevicePathInstance (VariableDevicePath,
DevicePath);
if (NewVariableDevicePath == NULL) {
if (Variable) {
gBS->FreePool (Variable);
}
return EFI_OUT_OF_RESOURCES;
}
} else {
//
// Remove DevicePath from the environment variable that
// is a multi-instance device path.
//
Status = ConPlatformMatchDevicePaths (VariableDevicePath,
DevicePath,
&NewVariableDevicePath,
TRUE);
if (EFI_ERROR (Status)) {
if (Variable) {
gBS->FreePool (Variable);
}
return Status;
}
}
if (NewVariableDevicePath) {
VariableSize = EfiDevicePathSize (NewVariableDevicePath);
} else {
VariableSize = 0;
}
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
VariableSize,
NewVariableDevicePath
);
if (NewVariableDevicePath) {
gBS->FreePool (NewVariableDevicePath);
}
if (Variable) {
gBS->FreePool (Variable);
}
return Status;
}
BOOLEAN
IsHotPlugDevice (
EFI_HANDLE DriverBindingHandle,
EFI_HANDLE ControllerHandle
)
{
EFI_STATUS Status;
//
// HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiHotPlugDeviceGuid,
NULL,
DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR(Status)) {
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?