diff options
author | James Bottomley <JBottomley@Parallels.com> | 2012-12-06 10:15:22 +0000 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-12-06 10:16:11 +0000 |
commit | 5c16c88aac783e9110123a39c2bd4de4ef5cd978 (patch) | |
tree | 143793d73a0be822d6f3e7da6e4bdf5737471511 | |
parent | 002eb978a0e8da7962eeb189b0ab535d31d86788 (diff) | |
download | efitools-5c16c88aac783e9110123a39c2bd4de4ef5cd978.tar.gz |
execute: add capability to execute via Boot Services
plus split generate_path() out of simple_file
-rw-r--r-- | include/execute.h | 5 | ||||
-rw-r--r-- | include/simple_file.h | 2 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/execute.c | 168 | ||||
-rw-r--r-- | lib/simple_file.c | 128 |
5 files changed, 175 insertions, 130 deletions
diff --git a/include/execute.h b/include/execute.h new file mode 100644 index 0000000..9aecbff --- /dev/null +++ b/include/execute.h @@ -0,0 +1,5 @@ +EFI_STATUS +generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, + EFI_DEVICE_PATH **path, CHAR16 **PathName); +EFI_STATUS +execute(EFI_HANDLE image, CHAR16 *name); diff --git a/include/simple_file.h b/include/simple_file.h index bf98b74..57bebb0 100644 --- a/include/simple_file.h +++ b/include/simple_file.h @@ -7,8 +7,6 @@ simple_file_write_all(EFI_FILE *file, UINTN size, void *buffer); void simple_file_close(EFI_FILE *file); EFI_STATUS -generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **grubpath, CHAR16 **PathName); -EFI_STATUS simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **Entries, int *count); EFI_STATUS diff --git a/lib/Makefile b/lib/Makefile index 0ab87e8..8c07c54 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,5 @@ LIBFILES = simple_file.o pecoff.o variables.o guid.o sha256.o console.o \ - security_policy.o + security_policy.o execute.o EFILIBFILES = $(patsubst %.o,%.efi.o,$(LIBFILES)) include ../Make.rules diff --git a/lib/execute.c b/lib/execute.c new file mode 100644 index 0000000..b2c9aff --- /dev/null +++ b/lib/execute.c @@ -0,0 +1,168 @@ +/* + * Copyright 2012 <James.Bottomley@HansenPartnership.com> + * + * see COPYING file + * + * -- + * + * generate_path is a cut and paste from + * + * git://github.com/mjg59/shim.git + * + * Code Copyright 2012 Red Hat, Inc <mjg@redhat.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <efi.h> +#include <efilib.h> + +#include <guid.h> +#include <execute.h> + +EFI_STATUS +generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16 **PathName) +{ + EFI_DEVICE_PATH *devpath; + EFI_HANDLE device; + FILEPATH_DEVICE_PATH *FilePath; + int len; + unsigned int pathlen = 0; + EFI_STATUS efi_status = EFI_SUCCESS; + + device = li->DeviceHandle; + devpath = li->FilePath; + + while (!IsDevicePathEnd(devpath) && + !IsDevicePathEnd(NextDevicePathNode(devpath))) { + FilePath = (FILEPATH_DEVICE_PATH *)devpath; + len = StrLen(FilePath->PathName); + + pathlen += len; + + if (len == 1 && FilePath->PathName[0] == '\\') { + devpath = NextDevicePathNode(devpath); + continue; + } + + /* If no leading \, need to add one */ + if (FilePath->PathName[0] != '\\') + pathlen++; + + /* If trailing \, need to strip it */ + if (FilePath->PathName[len-1] == '\\') + pathlen--; + + devpath = NextDevicePathNode(devpath); + } + + *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16)); + + if (!*PathName) { + Print(L"Failed to allocate path buffer\n"); + efi_status = EFI_OUT_OF_RESOURCES; + goto error; + } + + *PathName[0] = '\0'; + devpath = li->FilePath; + + while (!IsDevicePathEnd(devpath) && + !IsDevicePathEnd(NextDevicePathNode(devpath))) { + CHAR16 *tmpbuffer; + FilePath = (FILEPATH_DEVICE_PATH *)devpath; + len = StrLen(FilePath->PathName); + + if (len == 1 && FilePath->PathName[0] == '\\') { + devpath = NextDevicePathNode(devpath); + continue; + } + + tmpbuffer = AllocatePool((len + 1)*sizeof(CHAR16)); + + if (!tmpbuffer) { + Print(L"Unable to allocate temporary buffer\n"); + return EFI_OUT_OF_RESOURCES; + } + + StrCpy(tmpbuffer, FilePath->PathName); + + /* If no leading \, need to add one */ + if (tmpbuffer[0] != '\\') + StrCat(*PathName, L"\\"); + + /* If trailing \, need to strip it */ + if (tmpbuffer[len-1] == '\\') + tmpbuffer[len-1] = '\0'; + + StrCat(*PathName, tmpbuffer); + FreePool(tmpbuffer); + devpath = NextDevicePathNode(devpath); + } + + if (name[0] != '\\') + StrCat(*PathName, L"\\"); + StrCat(*PathName, name); + + *path = FileDevicePath(device, *PathName); + +error: + return efi_status; +} + +EFI_STATUS +execute(EFI_HANDLE image, CHAR16 *name) +{ + EFI_STATUS status; + EFI_HANDLE h; + EFI_LOADED_IMAGE *li; + EFI_DEVICE_PATH *devpath; + CHAR16 *PathName; + + status = uefi_call_wrapper(BS->HandleProtocol, 3, image, + &IMAGE_PROTOCOL, &li); + if (status != EFI_SUCCESS) + return status; + + + status = generate_path(name, li, &devpath, &PathName); + if (status != EFI_SUCCESS) + return status; + + Print(L"Generated path is %s\n", PathName); + console_get_keystroke(); + + status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image, + devpath, NULL, 0, &h); + if (status != EFI_SUCCESS) + return status; + + status = uefi_call_wrapper(BS->StartImage, 3, h, NULL, NULL); + uefi_call_wrapper(BS->UnloadImage, 1, h); + + return status; +} diff --git a/lib/simple_file.c b/lib/simple_file.c index 3476866..52686ac 100644 --- a/lib/simple_file.c +++ b/lib/simple_file.c @@ -2,51 +2,15 @@ * Copyright 2012 <James.Bottomley@HansenPartnership.com> * * see COPYING file - * - * -- - * - * generate_path is a cut and paste from - * - * git://github.com/mjg59/shim.git - * - * Code Copyright 2012 Red Hat, Inc <mjg@redhat.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * */ - - - #include <efi.h> #include <efilib.h> #include <console.h> #include <simple_file.h> #include <efiauthenticated.h> +#include <execute.h> /* for generate_path() */ static EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL; static EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL; @@ -54,96 +18,6 @@ static EFI_GUID FILE_INFO = EFI_FILE_INFO_ID; static EFI_GUID FS_INFO = EFI_FILE_SYSTEM_INFO_ID; EFI_STATUS -generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **grubpath, CHAR16 **PathName) -{ - EFI_DEVICE_PATH *devpath; - EFI_HANDLE device; - FILEPATH_DEVICE_PATH *FilePath; - int len; - unsigned int pathlen = 0; - EFI_STATUS efi_status = EFI_SUCCESS; - - device = li->DeviceHandle; - devpath = li->FilePath; - - while (!IsDevicePathEnd(devpath) && - !IsDevicePathEnd(NextDevicePathNode(devpath))) { - FilePath = (FILEPATH_DEVICE_PATH *)devpath; - len = StrLen(FilePath->PathName); - - pathlen += len; - - if (len == 1 && FilePath->PathName[0] == '\\') { - devpath = NextDevicePathNode(devpath); - continue; - } - - /* If no leading \, need to add one */ - if (FilePath->PathName[0] != '\\') - pathlen++; - - /* If trailing \, need to strip it */ - if (FilePath->PathName[len-1] == '\\') - pathlen--; - - devpath = NextDevicePathNode(devpath); - } - - *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16)); - - if (!*PathName) { - Print(L"Failed to allocate path buffer\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto error; - } - - *PathName[0] = '\0'; - devpath = li->FilePath; - - while (!IsDevicePathEnd(devpath) && - !IsDevicePathEnd(NextDevicePathNode(devpath))) { - CHAR16 *tmpbuffer; - FilePath = (FILEPATH_DEVICE_PATH *)devpath; - len = StrLen(FilePath->PathName); - - if (len == 1 && FilePath->PathName[0] == '\\') { - devpath = NextDevicePathNode(devpath); - continue; - } - - tmpbuffer = AllocatePool((len + 1)*sizeof(CHAR16)); - - if (!tmpbuffer) { - Print(L"Unable to allocate temporary buffer\n"); - return EFI_OUT_OF_RESOURCES; - } - - StrCpy(tmpbuffer, FilePath->PathName); - - /* If no leading \, need to add one */ - if (tmpbuffer[0] != '\\') - StrCat(*PathName, L"\\"); - - /* If trailing \, need to strip it */ - if (tmpbuffer[len-1] == '\\') - tmpbuffer[len-1] = '\0'; - - StrCat(*PathName, tmpbuffer); - FreePool(tmpbuffer); - devpath = NextDevicePathNode(devpath); - } - - if (name[0] != '\\') - StrCat(*PathName, L"\\"); - StrCat(*PathName, name); - - *grubpath = FileDevicePath(device, *PathName); - -error: - return efi_status; -} - -EFI_STATUS simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UINT64 mode) { EFI_STATUS efi_status; |