]> git.proxmox.com Git - efi-boot-shim.git/blob - lib/execute.c
MokManager: handle the error status from ReadKeyStroke
[efi-boot-shim.git] / lib / execute.c
1 /*
2 * Copyright 2012 <James.Bottomley@HansenPartnership.com>
3 *
4 * see COPYING file
5 *
6 * --
7 *
8 * generate_path is a cut and paste from
9 *
10 * git://github.com/mjg59/shim.git
11 *
12 * Code Copyright 2012 Red Hat, Inc <mjg@redhat.com>
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
37 * OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 */
40
41 #include <efi.h>
42 #include <efilib.h>
43
44 #include <guid.h>
45 #include <execute.h>
46
47 EFI_STATUS
48 generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16 **PathName)
49 {
50 unsigned int pathlen;
51 EFI_STATUS efi_status = EFI_SUCCESS;
52 CHAR16 *devpathstr = DevicePathToStr(li->FilePath),
53 *found = NULL;
54 int i;
55
56 for (i = 0; i < StrLen(devpathstr); i++) {
57 if (devpathstr[i] == '/')
58 devpathstr[i] = '\\';
59 if (devpathstr[i] == '\\')
60 found = &devpathstr[i];
61 }
62 if (!found) {
63 pathlen = 0;
64 } else {
65 while (*(found - 1) == '\\')
66 --found;
67 *found = '\0';
68 pathlen = StrLen(devpathstr);
69 }
70
71 if (name[0] != '\\')
72 pathlen++;
73
74 *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16));
75
76 if (!*PathName) {
77 Print(L"Failed to allocate path buffer\n");
78 efi_status = EFI_OUT_OF_RESOURCES;
79 goto error;
80 }
81
82 StrCpy(*PathName, devpathstr);
83
84 if (name[0] != '\\')
85 StrCat(*PathName, L"\\");
86 StrCat(*PathName, name);
87
88 *path = FileDevicePath(li->DeviceHandle, *PathName);
89
90 error:
91 FreePool(devpathstr);
92
93 return efi_status;
94 }
95
96 EFI_STATUS
97 execute(EFI_HANDLE image, CHAR16 *name)
98 {
99 EFI_STATUS status;
100 EFI_HANDLE h;
101 EFI_LOADED_IMAGE *li;
102 EFI_DEVICE_PATH *devpath;
103 CHAR16 *PathName;
104
105 status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
106 &IMAGE_PROTOCOL, (void **)&li);
107 if (status != EFI_SUCCESS)
108 return status;
109
110
111 status = generate_path(name, li, &devpath, &PathName);
112 if (status != EFI_SUCCESS)
113 return status;
114
115 status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
116 devpath, NULL, 0, &h);
117 if (status != EFI_SUCCESS)
118 goto out;
119
120 status = uefi_call_wrapper(BS->StartImage, 3, h, NULL, NULL);
121 uefi_call_wrapper(BS->UnloadImage, 1, h);
122
123 out:
124 FreePool(PathName);
125 FreePool(devpath);
126 return status;
127 }