예제 #1
0
파일: Test.c 프로젝트: jief666/clover
EFI_STATUS
EFIAPI
GetVolumeHandleWithDir(CHAR16 *SearchDir, OUT EFI_HANDLE *Handle)
{
	EFI_STATUS		Status;
	UINTN			HandlesSize;
	UINTN			Idx;
	EFI_HANDLE		*Handles;
	EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FS = NULL;
	EFI_FILE_PROTOCOL				*FP = NULL;
	EFI_FILE_PROTOCOL				*FP2 = NULL;
	
	// get all handles with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
	Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandlesSize, &Handles);
	if (EFI_ERROR(Status)) {
		Print(L"LocateHandleBuffer: %r\n", Status);
		return Status;
	}
	Print(L"LocateHandleBuffer: %r, got %d handles\n", Status, HandlesSize);
	
	// find handle that contains SearchDir 
	for (Idx = 0; Idx < HandlesSize; Idx++) {
		// get EFI_SIMPLE_FILE_SYSTEM_PROTOCOL first
		Print(L"Trying handle: %p\n", Handles[Idx]);
		Status = gBS->OpenProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, (void **)&FS, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
		if (EFI_ERROR(Status)) {
			Print(L"OpenProtocol(gEfiSimpleFileSystemProtocolGuid): %r\n", Status);
			continue;
		}
		// open volume
		Status = FS->OpenVolume(FS, &FP);
		if (EFI_ERROR(Status)) {
			Print(L"OpenVolume(): %r\n", Status);
			gBS->CloseProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, gImageHandle, NULL);
			continue;
		}
		// try to open injection dir
		Status = FP->Open(FP, &FP2, SearchDir, EFI_FILE_MODE_READ, 0);
		if (EFI_ERROR(Status)) {
			Print(L"Open(%s): %r\n", SearchDir, Status);
			FP->Close(FP);
			gBS->CloseProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, gImageHandle, NULL);
			continue;
		}
		// we have found it - close it and return handle
		FP2->Close(FP2);
		FP->Close(FP);
		*Handle = Handles[Idx];
		return EFI_SUCCESS;
	}
	// not found
	return EFI_NOT_FOUND;
}
예제 #2
0
EFI_STATUS
BdsFileSystemLoadImage (
  IN OUT EFI_DEVICE_PATH       **DevicePath,
  IN     EFI_HANDLE            Handle,
  IN     EFI_DEVICE_PATH       *RemainingDevicePath,
  IN     EFI_ALLOCATE_TYPE     Type,
  IN OUT EFI_PHYSICAL_ADDRESS  *Image,
  OUT    UINTN                 *ImageSize
  )
{
  EFI_STATUS                       Status;
  FILEPATH_DEVICE_PATH             *FilePathDevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *FsProtocol;
  EFI_FILE_PROTOCOL                *Fs;
  EFI_FILE_INFO                    *FileInfo;
  EFI_FILE_PROTOCOL                *File;
  UINTN                            Size;

  ASSERT (IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP));

  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)RemainingDevicePath;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID**)&FsProtocol,
                  gImageHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Try to Open the volume and get root directory
  Status = FsProtocol->OpenVolume (FsProtocol, &Fs);
  if (EFI_ERROR (Status)) {
    goto CLOSE_PROTOCOL;
  }

  Status = Fs->Open (Fs, &File, FilePathDevicePath->PathName, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    goto CLOSE_PROTOCOL;
  }

  Size = 0;
  File->GetInfo (File, &gEfiFileInfoGuid, &Size, NULL);
  FileInfo = AllocatePool (Size);
  Status = File->GetInfo (File, &gEfiFileInfoGuid, &Size, FileInfo);
  if (EFI_ERROR (Status)) {
    goto CLOSE_FILE;
  }

  // Get the file size
  Size = FileInfo->FileSize;
  if (ImageSize) {
    *ImageSize = Size;
  }
  FreePool (FileInfo);

  Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
  // Try to allocate in any pages if failed to allocate memory at the defined location
  if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {
    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
  }
  if (!EFI_ERROR (Status)) {
    Status = File->Read (File, &Size, (VOID*)(UINTN)(*Image));
  }

CLOSE_FILE:
  File->Close (File);

CLOSE_PROTOCOL:
  gBS->CloseProtocol (
         Handle,
         &gEfiSimpleFileSystemProtocolGuid,
         gImageHandle,
         Handle);

  return Status;
}
예제 #3
0
EFI_STATUS LoadFile(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* systab,
		CHAR16* filename, VOID** dataPtr, UINTN* size,
		EFI_DEVICE_PATH_PROTOCOL** dev_path)
{
	EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
	EFI_GUID FileInfoGuid = EFI_FILE_INFO_ID;
	EFI_GUID FileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
	EFI_STATUS res;

	EFI_BOOT_SERVICES* BS = systab->BootServices;

	//get image info
	EFI_LOADED_IMAGE_PROTOCOL* img_proto;
	res = BS->HandleProtocol(ImageHandle, &LoadedImageProtocolGuid,
			(void**) &img_proto);

	if (res)
	{
		ErrorPrint(L"Failed to get image protocol. (Error %d)\r\n", res);
		return EFI_LOAD_ERROR ;
	}

	EFI_HANDLE img_device_handle = img_proto->DeviceHandle;

	//Get filesystem protocol from device
	EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs_proto;
	res = BS->HandleProtocol(img_device_handle, &FileSystemGuid,
			(VOID**) &fs_proto);

	if (res)
	{
		ErrorPrint(L"Failed to get file system protocol. (Error %d)\r\n", res);
		return EFI_LOAD_ERROR ;
	}

	//open volume
	EFI_FILE_PROTOCOL* volume;
	res = fs_proto->OpenVolume(fs_proto, &volume);

	if (res)
	{
		ErrorPrint(L"Failed to open file volume. (Error %d)\r\n", res);
		return EFI_LOAD_ERROR ;
	}

	//open file
	EFI_FILE_PROTOCOL* file;
	res = volume->Open(volume, &file, filename, EFI_FILE_MODE_READ, 0);

	if (res)
	{
		//don't print error here
		//ErrorPrint(L"Failed to open file '%s'. (Error %d)\r\n", filename, res);
		return EFI_NOT_FOUND ;
	}

	//get file info, two try process
	EFI_FILE_INFO* file_info = NULL;
	UINTN file_info_size = 0;
	res = file->GetInfo(file, &FileInfoGuid, &file_info_size, NULL );

	if (res != EFI_BUFFER_TOO_SMALL )
	{
		ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res);
		return EFI_NOT_FOUND ;
	}

	res = BS->AllocatePool(EfiLoaderData, file_info_size, (void**) &file_info);

	if (res)
	{
		ErrorPrint(L"Failed to allocate file info memory. (Error %d)\r\n", res);
		return EFI_OUT_OF_RESOURCES ;
	}

	res = file->GetInfo(file, &FileInfoGuid, &file_info_size,
			(void*) file_info);

	if (res)
	{
		BS->FreePool(file_info);
		ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res);
		return EFI_NOT_FOUND ;
	}

	if (dev_path != NULL )
	{
		*dev_path = FileDevicePath(img_device_handle, filename);
	}

	UINT64 file_size = file_info->FileSize;

	BS->FreePool(file_info);
	file_info = NULL;

	void* data = NULL;
	res = BS->AllocatePool(EfiLoaderData, file_size, (void**) &data);

	if (res)
	{
		ErrorPrint(L"Failed to allocate file data memory. (Error %d)\r\n", res);
		return EFI_OUT_OF_RESOURCES ;
	}

	//read the file
	res = file->Read(file, &file_size, (void*) data);

	if (res)
	{
		BS->FreePool(data);
		ErrorPrint(L"Failed to read file '%s'. (Error %d)\r\n", filename, res);
		return EFI_NOT_FOUND ;
	}

	//close the file
	file->Close(file);
	volume->Close(volume);

	//set the pointer and data size
	*dataPtr = data;
	*size = file_size;

	//return success
	return EFI_SUCCESS;
}