0%

StartImage-BOOTAA64.EFI

一、实现方法

二、代码链接

链接:https://pan.quark.cn/s/9a8b14b347c4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

EFI_STATUS Status;
UINT32 Index;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer = NULL;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume = NULL;
EFI_FILE_PROTOCOL *RootDir = NULL;
EFI_FILE_PROTOCOL *BootFile = NULL;
EFI_HANDLE NewImageHandle;
UINTN BufferSize=10240*1024;
VOID *Buffer = NULL;
// EFI_FILE_INFO *FileInfo = NULL;
// UINTN FileInfoSize = 0;

Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer);
if (EFI_ERROR(Status)) {
Print(L"Failed to locate handles: %r\n", Status);
return Status;
}
for(Index=0;Index<HandleCount;Index++){
Status = gBS->HandleProtocol(
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID**)&DevicePath
);
if (EFI_ERROR(Status)) {
Print(L"Failed to get device path for handle %u: %r\n", Index, Status);
continue;
}

Status = gBS->HandleProtocol(
HandleBuffer[Index],
&gEfiSimpleFileSystemProtocolGuid,
(VOID**)&Volume
);
if (EFI_ERROR(Status)) {
Print(L"Failed to get file system protocol for handle %u: %r\n", Index, Status);
continue;
}

Status = Volume->OpenVolume(Volume, &RootDir);
if (EFI_ERROR(Status)) {
Print(L"Failed to open volume on handle[%u]: %r\n", Index, Status);
continue;
}
// 打开 BOOTAA64.EFI 文件
Status = RootDir->Open(
RootDir,
&BootFile,
L"\\EFI\\BOOT\\BOOTAA64.EFI",
EFI_FILE_MODE_READ,
0
);
if (EFI_ERROR(Status)) {
Print(L"Failed to open \\EFI\\BOOT\\BOOTAA64.EFI: %r\n", Status);
continue;
}
/*
// 获取文件信息以动态确定文件大小
FileInfoSize = 0;
Status = BootFile->GetInfo(BootFile, &gEfiFileInfoGuid, &FileInfoSize, NULL);
Print(L"120\n");
if (Status == EFI_BUFFER_TOO_SMALL) {
FileInfo = AllocatePool(FileInfoSize);
Print(L"123\n");
if (FileInfo == NULL) {
Print(L"Failed to allocate memory for file info\n");
BootFile->Close(BootFile);
continue;
}

Status = BootFile->GetInfo(BootFile, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);
Print(L"131\n");
if (EFI_ERROR(Status)) {
Print(L"Failed to get file info: %r\n", Status);
FreePool(FileInfo);
BootFile->Close(BootFile);
continue;
}

BufferSize = FileInfo->FileSize;
Print(L"140 %lu\n",BufferSize);
FreePool(FileInfo);
} else {
Print(L"Failed to retrieve file info size: %r\n", Status);
BootFile->Close(BootFile);
continue;
}

// 分配缓冲区
Buffer = AllocatePool(BufferSize);
Print(L"150\n");
if (Buffer == NULL) {
Print(L"Failed to allocate buffer for file content\n");
BootFile->Close(BootFile);
continue;
}
*/
Buffer = AllocatePool(BufferSize);
if (Buffer == NULL) {
Print(L"Failed to allocate buffer for file content\n");
}
// 读取文件内容
Status = BootFile->Read(BootFile, &BufferSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"Failed to read file: %r\n", Status);
FreePool(Buffer);
BootFile->Close(BootFile);
continue;
}

// 加载并启动 BOOTAA64.EFI 文件
Status = gBS->LoadImage(
FALSE,
ImageHandle,
DevicePath,
Buffer,
BufferSize,
&NewImageHandle
);
if (EFI_ERROR(Status)) {
Print(L"Failed to load image: %r\n", Status);
FreePool(Buffer);
BootFile->Close(BootFile);
continue;
}

Status = gBS->StartImage(NewImageHandle, NULL, NULL);
if (EFI_ERROR(Status)) {
Print(L"Failed to start image: %r\n", Status);
} else {
Print(L"Image started successfully\n");
}
// 关闭打开的文件和资源
FreePool(Buffer);
BootFile->Close(BootFile);
// break; // 找到第一个有效的启动文件后退出
}

FreePool(HandleBuffer);
return EFI_SUCCESS;