aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2012-12-06 10:15:22 +0000
committerJames Bottomley <JBottomley@Parallels.com>2012-12-06 10:16:11 +0000
commit5c16c88aac783e9110123a39c2bd4de4ef5cd978 (patch)
tree143793d73a0be822d6f3e7da6e4bdf5737471511
parent002eb978a0e8da7962eeb189b0ab535d31d86788 (diff)
downloadefitools-5c16c88aac783e9110123a39c2bd4de4ef5cd978.tar.gz
execute: add capability to execute via Boot Services
plus split generate_path() out of simple_file
-rw-r--r--include/execute.h5
-rw-r--r--include/simple_file.h2
-rw-r--r--lib/Makefile2
-rw-r--r--lib/execute.c168
-rw-r--r--lib/simple_file.c128
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;