static EFI_STATUS launch_or_fallback(enum targets target, CHAR8 *cmdline)
{
	EFI_STATUS ret;
	CHAR8 saved_cmdline[(cmdline ? strlena(cmdline) : 0) + 1];

	if (cmdline) {
		CopyMem(saved_cmdline, cmdline, strlena(cmdline) + 1);
		FreePool(cmdline);
	} else
		saved_cmdline[0] = '\0';

	do {
		target = em_fallback_target(target);

		ret = loader_ops.populate_indicators();
		if (EFI_ERROR(ret))
			return ret;

		ret = loader_ops.save_target_mode(target);
		if (EFI_ERROR(ret))
			warning(L"Failed to save the target_mode: %r\n", ret);

		ret = loader_ops.load_target(target, saved_cmdline);

		target = fallback_target(target);
	} while (target != TARGET_UNKNOWN);

	return EFI_INVALID_PARAMETER;
}
Beispiel #2
0
char *
AsciiStrCat(char *Destination, char *Source)
{
	UINTN dest_len = strlena((CHAR8 *)Destination);
	UINTN i;

	for (i = 0; Source[i] != '\0'; i++)
		Destination[dest_len + i] = Source[i];
	Destination[dest_len + i] = '\0';

	return Destination;
}
Beispiel #3
0
VOID
SmbiosGetPendingString (
  IN  SMBIOS_STRUCTURE_POINTER      *Smbios,
  IN  UINT16                        StringNumber,
  OUT CHAR8                         *Buffer
  )
{
  CHAR8 *String;
  if (Buffer == NULL) {
    PrintToken (STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUF_SPEC_WHEN_STRUCT), HiiHandle);
    return ;
  }
  //
  // Get string and copy to buffer.
  // Caller should provide the buffer.
  //
  String = LibGetSmbiosString (Smbios, StringNumber);
  if (String != NULL) {
    CopyMem (Buffer, String, strlena (String));
  } else {
    Buffer = NULL;
  }
}
Beispiel #4
0
/**
 * Open file
 *
 * @v This			File handle
 * @ret new			New file handle
 * @v Name			File name
 * @v Mode			File mode
 * @v Attributes	File attributes (for newly-created files)
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileOpen(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New,
		CHAR16 *Name, UINT64 Mode, UINT64 Attributes)
{
	EFI_STATUS Status;
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);
	EFI_GRUB_FILE *NewFile;

	// TODO: Use dynamic buffers?
	char path[MAX_PATH], clean_path[MAX_PATH], *dirname;
	INTN i, len;
	BOOLEAN AbsolutePath = (*Name == L'\\');

	PrintInfo(L"Open(%llx%s, \"%s\")\n", (UINT64) This,
			IS_ROOT(File)?L" <ROOT>":L"", Name);

	/* Fail unless opening read-only */
	if (Mode != EFI_FILE_MODE_READ) {
		PrintWarning(L"File '%s' can only be opened in read-only mode\n", Name);
		return EFI_WRITE_PROTECTED;
	}

	/* Additional failures */
	if ((StrCmp(Name, L"..") == 0) && IS_ROOT(File)) {
		PrintInfo(L"Trying to open <ROOT>'s parent\n");
		return EFI_NOT_FOUND;
	}

	/* See if we're trying to reopen current (which the EFI Shell insists on doing) */
	if ((*Name == 0) || (StrCmp(Name, L".") == 0)) {
		PrintInfo(L"  Reopening %s\n", IS_ROOT(File)?L"<ROOT>":FileName(File));
		File->RefCount++;
		*New = This;
		PrintInfo(L"  RET: %llx\n", (UINT64) *New);
		return EFI_SUCCESS;
	}

	/* If we have an absolute path, don't bother completing with the parent */
	if (AbsolutePath) {
		len = 0;
	} else {
		strcpya(path, File->path);
		len = strlena(path);
		/* Add delimiter if needed */
		if ((len == 0) || (path[len-1] != '/'))
			path[len++] = '/';
	}

	/* Copy the rest of the path (converted to UTF-8) */
	Status = Utf16ToUtf8NoAlloc(Name, &path[len], sizeof(path) - len);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not convert path to UTF-8");
		return Status;
	}
	/* Convert the delimiters */
	for (i = strlena(path) - 1 ; i >= len; i--) {
		if (path[i] == '\\')
			path[i] = '/';
	}

	/* We only want to handle with absolute paths */
	clean_path[0] = '/';
	/* Find out if we're dealing with root by removing the junk */
	CopyPathRelative(&clean_path[1], path, MAX_PATH - 1);
	if (clean_path[1] == 0) {
		/* We're dealing with the root */
		PrintInfo(L"  Reopening <ROOT>\n");
		*New = &File->FileSystem->RootFile->EfiFile;
		/* Must make sure that DirIndex is reset too (NB: no concurrent access!) */
		File->FileSystem->RootFile->DirIndex = 0;
		PrintInfo(L"  RET: %llx\n", (UINT64) *New);
		return EFI_SUCCESS;
	}

	// TODO: eventually we should seek for already opened files and increase RefCount */
	/* Allocate and initialise an instance of a file */
	Status = GrubCreateFile(&NewFile, File->FileSystem);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not instantiate file");
		return Status;
	}

	NewFile->path = AllocatePool(strlena(clean_path)+1);
	if (NewFile->path == NULL) {
		GrubDestroyFile(NewFile);
		PrintError(L"Could not instantiate path\n");
		return EFI_OUT_OF_RESOURCES;
	}
	strcpya(NewFile->path, clean_path);

	/* Isolate the basename and dirname */
	// TODO: would be nicer to have those if path.c
	for (i = strlena(clean_path) - 1; i >= 0; i--) {
		if (clean_path[i] == '/') {
			clean_path[i] = 0;
			break;
		}
	}
	dirname = (i <= 0) ? "/" : clean_path;
	NewFile->basename = &NewFile->path[i+1];

	/* Find if we're working with a directory and fill the grub timestamp */
	Status = GrubDir(NewFile, dirname, InfoHook, (VOID *) NewFile);
	if (EFI_ERROR(Status)) {
		if (Status != EFI_NOT_FOUND)
			PrintStatusError(Status, L"Could not get file attributes for '%s'", Name);
		FreePool(NewFile->path);
		GrubDestroyFile(NewFile);
		return Status;
	}

	/* Finally we can call on GRUB open() if it's a regular file */
	if (!NewFile->IsDir) {
		Status = GrubOpen(NewFile);
		if (EFI_ERROR(Status)) {
			if (Status != EFI_NOT_FOUND)
				PrintStatusError(Status, L"Could not open file '%s'", Name);
			FreePool(NewFile->path);
			GrubDestroyFile(NewFile);
			return Status;
		}
	}

	NewFile->RefCount++;
	*New = &NewFile->EfiFile;

	PrintInfo(L"  RET: %llx\n", (UINT64) *New);
	return EFI_SUCCESS;
}
Beispiel #5
0
/**
 * Read directory entry
 *
 * @v file			EFI file
 * @v Len			Length to read
 * @v Data			Data buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS
FileReadDir(EFI_GRUB_FILE *File, UINTN *Len, VOID *Data)
{
	EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
	EFI_STATUS Status;
	/* We temporarily repurpose the FileSize as a *signed* entry index */
	INT64 *Index = (INT64 *) &Info->FileSize;
	/* And PhysicalSize as a pointer to our filename */
	CHAR8 **basename = (CHAR8 **) &Info->PhysicalSize;
	CHAR8 path[MAX_PATH];
	EFI_GRUB_FILE *TmpFile = NULL;
	INTN len;

	/* Unless we can fit our maximum size, forget it */
	if (*Len < MINIMUM_INFO_LENGTH) {
		*Len = MINIMUM_INFO_LENGTH;
		return EFI_BUFFER_TOO_SMALL;
	}

	/* Populate our Info template */
	ZeroMem(Data, *Len);
	Info->Size = *Len;
	*Index = File->DirIndex;
	strcpya(path, File->path);
	len = strlena(path);
	if (path[len-1] != '/')
		path[len++] = '/';
	*basename = &path[len];

	/* Invoke GRUB's directory listing */
	Status = GrubDir(File, File->path, DirHook, Data);
	if (*Index >= 0) {
		/* No more entries */
		*Len = 0;
		return EFI_SUCCESS;
	}

	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Directory listing failed");
		return Status;
	}

	/* Our Index/FileSize must be reset */
	Info->FileSize = 0;
	Info->PhysicalSize = 0;

	/* For regular files, we still need to fill the size */
	if (!(Info->Attribute & EFI_FILE_DIRECTORY)) {
		/* Open the file and read its size */
		Status = GrubCreateFile(&TmpFile, File->FileSystem);
		if (EFI_ERROR(Status)) {
			PrintStatusError(Status, L"Unable to create temporary file");
			return Status;
		}
		TmpFile->path = path;

		Status = GrubOpen(TmpFile);
		if (EFI_ERROR(Status)) {
			// TODO: EFI_NO_MAPPING is returned for links...
			PrintStatusError(Status, L"Unable to obtain the size of '%s'", Info->FileName);
			/* Non fatal error */
		} else {
			Info->FileSize = GrubGetFileSize(TmpFile);
			Info->PhysicalSize = GrubGetFileSize(TmpFile);
			GrubClose(TmpFile);
		}
		GrubDestroyFile(TmpFile);
	}

	*Len = (UINTN) Info->Size;
	/* Advance to the next entry */
	File->DirIndex++;

//	PrintInfo(L"  Entry[%d]: '%s' %s\n", File->DirIndex-1, Info->FileName,
//			(Info->Attribute&EFI_FILE_DIRECTORY)?L"<DIR>":L"");

	return EFI_SUCCESS;
}
Beispiel #6
0
VOID CopyPathRelative(CHAR8 *dest, CHAR8 *src, INTN len)
{
	CHAR8* o = dest;
	CHAR8* p = src;

	*o = '\0';

	while(*p && *p == PATH_CHAR) ++p;
	for(; len && *p;)
	{
		src = p;
		p = strchra(src, PATH_CHAR);
		if(!p) p = src+strlena(src);

		/* . => skip */
		if(p-src == 1 && *src == '.' )
		{
			if(*p) src = ++p;
		}
		/* .. => pop one */
		else if(p-src == 2 && *src == '.' && src[1] == '.')
		{
			if(o != dest)
			{
				CHAR8* tmp;
				*o = '\0';
				tmp = strrchra(dest, PATH_CHAR);
				if(!tmp)
				{
					len += o-dest;
					o = dest;
					if(*p) ++p;
				}
				else
				{
					len += o-tmp;
					o = tmp;
					if(*p) ++p;
				}
			}
			else /* nothing to pop */
				if(*p) ++p;
		}
		else
		{
			INTN copy;
			if(o != dest)
			{
				--len;
				*o++ = PATH_CHAR;
			}
			copy = MIN(p-src,len);
			CopyMem(o, src, copy);
			len -= copy;
			src += copy;
			o += copy;
			if(*p) ++p;
		}
		while(*p && *p == PATH_CHAR) ++p;
	}
	o[len?0:-1] = '\0';
}
Beispiel #7
0
UINTN
AsciiStrSize(CHAR8 *string)
{
	return strlena(string) + 1;
}
Beispiel #8
0
CHAR8 *
strcata(IN CHAR8 *dst,IN CHAR8 *src)
{   
    return strcpya(dst+strlena(dst), src);
}
Beispiel #9
0
EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, UINTN *addrs,
                                  UINTN *offsets, UINTN *sizes)
{
        EFI_FILE_HANDLE handle;
        struct DosFileHeader dos;
        uint8_t magic[4];
        struct PeFileHeader pe;
        UINTN len;
        UINTN i;
        EFI_STATUS err;

        err = uefi_call_wrapper(dir->Open, 5, dir, &handle, path, EFI_FILE_MODE_READ, 0ULL);
        if (EFI_ERROR(err))
                return err;

        /* MS-DOS stub */
        len = sizeof(dos);
        err = uefi_call_wrapper(handle->Read, 3, handle, &len, &dos);
        if (EFI_ERROR(err))
                goto out;
        if (len != sizeof(dos)) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        if (CompareMem(dos.Magic, "MZ", 2) != 0) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader);
        if (EFI_ERROR(err))
                goto out;

        /* PE header */
        len = sizeof(magic);
        err = uefi_call_wrapper(handle->Read, 3, handle, &len, &magic);
        if (EFI_ERROR(err))
                goto out;
        if (len != sizeof(magic)) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        if (CompareMem(magic, "PE\0\0", 2) != 0) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        len = sizeof(pe);
        err = uefi_call_wrapper(handle->Read, 3, handle, &len, &pe);
        if (EFI_ERROR(err))
                goto out;
        if (len != sizeof(pe)) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        /* PE32+ Subsystem type */
        if (pe.Machine != PE_HEADER_MACHINE_X64 && pe.Machine != PE_HEADER_MACHINE_I386) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        if (pe.NumberOfSections > 96) {
                err = EFI_LOAD_ERROR;
                goto out;
        }

        /* the sections start directly after the headers */
        err =
            uefi_call_wrapper(handle->SetPosition,
                              2,
                              handle,
                              dos.ExeHeader + sizeof(magic) + sizeof(pe) + pe.SizeOfOptionalHeader);
        if (EFI_ERROR(err))
                goto out;

        for (i = 0; i < pe.NumberOfSections; i++) {
                struct PeSectionHeader sect;
                UINTN j;

                len = sizeof(sect);
                err = uefi_call_wrapper(handle->Read, 3, handle, &len, &sect);
                if (EFI_ERROR(err))
                        goto out;
                if (len != sizeof(sect)) {
                        err = EFI_LOAD_ERROR;
                        goto out;
                }
                for (j = 0; sections[j]; j++) {
                        if (CompareMem(sect.Name, sections[j], strlena(sections[j])) != 0)
                                continue;

                        if (addrs)
                                addrs[j] = (UINTN)sect.VirtualAddress;
                        if (offsets)
                                offsets[j] = (UINTN)sect.PointerToRawData;
                        if (sizes)
                                sizes[j] = (UINTN)sect.VirtualSize;
                }
        }

out:
        uefi_call_wrapper(handle->Close, 1, handle);
        return err;
}