"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 协议,您不会释放句柄实例(这将是一个非常糟糕的主意),而是释放它们的数组。