"pointer passing convention" 在 UEFI 模块中
"pointer passing convention" in UEFI module
我想知道何时需要释放从 EFI 函数返回的指针
EFI_DEVICE_PATH_PROTOCOL *
BmExpandFileDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_DEVICE_PATH_PROTOCOL *FullPath
)
{
EFI_STATUS Status;
UINTN Index;
UINTN HandleCount;
EFI_HANDLE *Handles;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
UINTN MediaType;
EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
BOOLEAN GetNext;
EfiBootManagerConnectAll ();
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
if (EFI_ERROR (Status)) {
HandleCount = 0;
Handles = NULL;
}
GetNext = (BOOLEAN)(FullPath == NULL);
NextFullPath = NULL;
//
// Enumerate all removable media devices followed by all fixed media devices,
// followed by media devices which don't layer on block io.
//
for (MediaType = 0; MediaType < 3; MediaType++) {
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (Handles[Index], &gEfiBlockIoProtocolGuid, (VOID *) &BlockIo);
if (EFI_ERROR (Status)) {
BlockIo = NULL;
}
if ((MediaType == 0 && BlockIo != NULL && BlockIo->Media->RemovableMedia) ||
(MediaType == 1 && BlockIo != NULL && !BlockIo->Media->RemovableMedia) ||
(MediaType == 2 && BlockIo == NULL)
) {
NextFullPath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);
if (GetNext) {
break;
} else {
GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
FreePool (NextFullPath);
NextFullPath = NULL;
}
}
}
if (NextFullPath != NULL) {
break;
}
}
if (Handles != NULL) {
FreePool (Handles);
}
return NextFullPath;
}
例如,在这段代码中,我可以在调用 HandleProtocol
后释放 Handles
并且仍然可以使用 BlockIo
吗?
是否有文档解释 edk2 函数的“指针传递约定”?
谢谢。
您必须查看 specification,如果您负责释放指针,请注意。
对于您的 LocateHandleBuffer 示例:
Buffer
A pointer to the buffer to return the requested array of handles that
support Protocol. This buffer is allocated with a call to the Boot
Service EFI_BOOT_SERVICES.AllocatePool(). It is the caller's
responsibility to call the Boot Service EFI_BOOT_SERVICES.FreePool()
when the caller no longer requires the contents of Buffer."
您可以在释放缓冲区后使用 BlockIO 协议,您不会释放句柄实例(这将是一个非常糟糕的主意),而是释放它们的数组。
我想知道何时需要释放从 EFI 函数返回的指针
EFI_DEVICE_PATH_PROTOCOL *
BmExpandFileDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_DEVICE_PATH_PROTOCOL *FullPath
)
{
EFI_STATUS Status;
UINTN Index;
UINTN HandleCount;
EFI_HANDLE *Handles;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
UINTN MediaType;
EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
BOOLEAN GetNext;
EfiBootManagerConnectAll ();
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
if (EFI_ERROR (Status)) {
HandleCount = 0;
Handles = NULL;
}
GetNext = (BOOLEAN)(FullPath == NULL);
NextFullPath = NULL;
//
// Enumerate all removable media devices followed by all fixed media devices,
// followed by media devices which don't layer on block io.
//
for (MediaType = 0; MediaType < 3; MediaType++) {
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (Handles[Index], &gEfiBlockIoProtocolGuid, (VOID *) &BlockIo);
if (EFI_ERROR (Status)) {
BlockIo = NULL;
}
if ((MediaType == 0 && BlockIo != NULL && BlockIo->Media->RemovableMedia) ||
(MediaType == 1 && BlockIo != NULL && !BlockIo->Media->RemovableMedia) ||
(MediaType == 2 && BlockIo == NULL)
) {
NextFullPath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);
if (GetNext) {
break;
} else {
GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
FreePool (NextFullPath);
NextFullPath = NULL;
}
}
}
if (NextFullPath != NULL) {
break;
}
}
if (Handles != NULL) {
FreePool (Handles);
}
return NextFullPath;
}
例如,在这段代码中,我可以在调用 HandleProtocol
后释放 Handles
并且仍然可以使用 BlockIo
吗?
是否有文档解释 edk2 函数的“指针传递约定”?
谢谢。
您必须查看 specification,如果您负责释放指针,请注意。
对于您的 LocateHandleBuffer 示例:
Buffer
A pointer to the buffer to return the requested array of handles that support Protocol. This buffer is allocated with a call to the Boot Service EFI_BOOT_SERVICES.AllocatePool(). It is the caller's responsibility to call the Boot Service EFI_BOOT_SERVICES.FreePool() when the caller no longer requires the contents of Buffer."
您可以在释放缓冲区后使用 BlockIO 协议,您不会释放句柄实例(这将是一个非常糟糕的主意),而是释放它们的数组。