1 | /*++ |
---|
2 | |
---|
3 | Copyright (c) 1998 Intel Corporation |
---|
4 | |
---|
5 | Module Name: |
---|
6 | |
---|
7 | hand.c |
---|
8 | |
---|
9 | Abstract: |
---|
10 | |
---|
11 | |
---|
12 | |
---|
13 | |
---|
14 | Revision History |
---|
15 | |
---|
16 | --*/ |
---|
17 | |
---|
18 | #include "lib.h" |
---|
19 | #include "efistdarg.h" // !!! |
---|
20 | |
---|
21 | |
---|
22 | EFI_STATUS |
---|
23 | LibLocateProtocol ( |
---|
24 | IN EFI_GUID *ProtocolGuid, |
---|
25 | OUT VOID **Interface |
---|
26 | ) |
---|
27 | // |
---|
28 | // Find the first instance of this Protocol in the system and return it's interface |
---|
29 | // |
---|
30 | { |
---|
31 | EFI_STATUS Status; |
---|
32 | UINTN NumberHandles, Index; |
---|
33 | EFI_HANDLE *Handles; |
---|
34 | |
---|
35 | |
---|
36 | *Interface = NULL; |
---|
37 | Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles); |
---|
38 | if (EFI_ERROR(Status)) { |
---|
39 | DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n")); |
---|
40 | return Status; |
---|
41 | } |
---|
42 | |
---|
43 | for (Index=0; Index < NumberHandles; Index++) { |
---|
44 | Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface); |
---|
45 | if (!EFI_ERROR(Status)) { |
---|
46 | break; |
---|
47 | } |
---|
48 | } |
---|
49 | |
---|
50 | if (Handles) { |
---|
51 | FreePool (Handles); |
---|
52 | } |
---|
53 | |
---|
54 | return Status; |
---|
55 | } |
---|
56 | |
---|
57 | EFI_STATUS |
---|
58 | LibLocateHandle ( |
---|
59 | IN EFI_LOCATE_SEARCH_TYPE SearchType, |
---|
60 | IN EFI_GUID *Protocol OPTIONAL, |
---|
61 | IN VOID *SearchKey OPTIONAL, |
---|
62 | IN OUT UINTN *NoHandles, |
---|
63 | OUT EFI_HANDLE **Buffer |
---|
64 | ) |
---|
65 | |
---|
66 | { |
---|
67 | EFI_STATUS Status; |
---|
68 | UINTN BufferSize; |
---|
69 | |
---|
70 | // |
---|
71 | // Initialize for GrowBuffer loop |
---|
72 | // |
---|
73 | |
---|
74 | Status = EFI_SUCCESS; |
---|
75 | *Buffer = NULL; |
---|
76 | BufferSize = 50 * sizeof(EFI_HANDLE); |
---|
77 | |
---|
78 | // |
---|
79 | // Call the real function |
---|
80 | // |
---|
81 | |
---|
82 | while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) { |
---|
83 | |
---|
84 | Status = uefi_call_wrapper( |
---|
85 | BS->LocateHandle, |
---|
86 | 5, |
---|
87 | SearchType, |
---|
88 | Protocol, |
---|
89 | SearchKey, |
---|
90 | &BufferSize, |
---|
91 | *Buffer |
---|
92 | ); |
---|
93 | |
---|
94 | } |
---|
95 | |
---|
96 | *NoHandles = BufferSize / sizeof (EFI_HANDLE); |
---|
97 | if (EFI_ERROR(Status)) { |
---|
98 | *NoHandles = 0; |
---|
99 | } |
---|
100 | |
---|
101 | return Status; |
---|
102 | } |
---|
103 | |
---|
104 | EFI_STATUS |
---|
105 | LibLocateHandleByDiskSignature ( |
---|
106 | IN UINT8 MBRType, |
---|
107 | IN UINT8 SignatureType, |
---|
108 | IN VOID *Signature, |
---|
109 | IN OUT UINTN *NoHandles, |
---|
110 | OUT EFI_HANDLE **Buffer |
---|
111 | ) |
---|
112 | |
---|
113 | { |
---|
114 | EFI_STATUS Status; |
---|
115 | UINTN BufferSize; |
---|
116 | UINTN NoBlockIoHandles; |
---|
117 | EFI_HANDLE *BlockIoBuffer; |
---|
118 | EFI_DEVICE_PATH *DevicePath; |
---|
119 | UINTN Index; |
---|
120 | EFI_DEVICE_PATH *Start, *Next, *DevPath; |
---|
121 | HARDDRIVE_DEVICE_PATH *HardDriveDevicePath; |
---|
122 | BOOLEAN Match; |
---|
123 | BOOLEAN PreviousNodeIsHardDriveDevicePath; |
---|
124 | |
---|
125 | // |
---|
126 | // Initialize for GrowBuffer loop |
---|
127 | // |
---|
128 | |
---|
129 | Status = EFI_SUCCESS; |
---|
130 | BlockIoBuffer = NULL; |
---|
131 | BufferSize = 50 * sizeof(EFI_HANDLE); |
---|
132 | |
---|
133 | // |
---|
134 | // Call the real function |
---|
135 | // |
---|
136 | |
---|
137 | while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) { |
---|
138 | |
---|
139 | // |
---|
140 | // Get list of device handles that support the BLOCK_IO Protocol. |
---|
141 | // |
---|
142 | |
---|
143 | Status = uefi_call_wrapper( |
---|
144 | BS->LocateHandle, |
---|
145 | 5, |
---|
146 | ByProtocol, |
---|
147 | &BlockIoProtocol, |
---|
148 | NULL, |
---|
149 | &BufferSize, |
---|
150 | BlockIoBuffer |
---|
151 | ); |
---|
152 | |
---|
153 | } |
---|
154 | |
---|
155 | NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE); |
---|
156 | if (EFI_ERROR(Status)) { |
---|
157 | NoBlockIoHandles = 0; |
---|
158 | } |
---|
159 | |
---|
160 | // |
---|
161 | // If there was an error or there are no device handles that support |
---|
162 | // the BLOCK_IO Protocol, then return. |
---|
163 | // |
---|
164 | |
---|
165 | if (NoBlockIoHandles == 0) { |
---|
166 | FreePool(BlockIoBuffer); |
---|
167 | *NoHandles = 0; |
---|
168 | *Buffer = NULL; |
---|
169 | return Status; |
---|
170 | } |
---|
171 | |
---|
172 | // |
---|
173 | // Loop through all the device handles that support the BLOCK_IO Protocol |
---|
174 | // |
---|
175 | |
---|
176 | *NoHandles = 0; |
---|
177 | |
---|
178 | for(Index=0;Index<NoBlockIoHandles;Index++) { |
---|
179 | |
---|
180 | Status = uefi_call_wrapper( |
---|
181 | BS->HandleProtocol, |
---|
182 | 3, |
---|
183 | BlockIoBuffer[Index], |
---|
184 | &DevicePathProtocol, |
---|
185 | (VOID*)&DevicePath |
---|
186 | ); |
---|
187 | |
---|
188 | // |
---|
189 | // Search DevicePath for a Hard Drive Media Device Path node. |
---|
190 | // If one is found, then see if it matches the signature that was |
---|
191 | // passed in. If it does match, and the next node is the End of the |
---|
192 | // device path, and the previous node is not a Hard Drive Media Device |
---|
193 | // Path, then we have found a match. |
---|
194 | // |
---|
195 | |
---|
196 | Match = FALSE; |
---|
197 | |
---|
198 | if (DevicePath != NULL) { |
---|
199 | |
---|
200 | PreviousNodeIsHardDriveDevicePath = FALSE; |
---|
201 | |
---|
202 | DevPath = DevicePath; |
---|
203 | Start = DevPath; |
---|
204 | |
---|
205 | // |
---|
206 | // Check for end of device path type |
---|
207 | // |
---|
208 | |
---|
209 | for (; ;) { |
---|
210 | |
---|
211 | if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) && |
---|
212 | (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) { |
---|
213 | |
---|
214 | HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath); |
---|
215 | |
---|
216 | if (PreviousNodeIsHardDriveDevicePath == FALSE) { |
---|
217 | |
---|
218 | Next = NextDevicePathNode(DevPath); |
---|
219 | if (IsDevicePathEndType(Next)) { |
---|
220 | if ((HardDriveDevicePath->MBRType == MBRType) && |
---|
221 | (HardDriveDevicePath->SignatureType == SignatureType)) { |
---|
222 | switch(SignatureType) { |
---|
223 | case SIGNATURE_TYPE_MBR: |
---|
224 | if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) { |
---|
225 | Match = TRUE; |
---|
226 | } |
---|
227 | break; |
---|
228 | case SIGNATURE_TYPE_GUID: |
---|
229 | if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) { |
---|
230 | Match = TRUE; |
---|
231 | } |
---|
232 | break; |
---|
233 | } |
---|
234 | } |
---|
235 | } |
---|
236 | } |
---|
237 | PreviousNodeIsHardDriveDevicePath = TRUE; |
---|
238 | } else { |
---|
239 | PreviousNodeIsHardDriveDevicePath = FALSE; |
---|
240 | } |
---|
241 | |
---|
242 | if (IsDevicePathEnd(DevPath)) { |
---|
243 | break; |
---|
244 | } |
---|
245 | |
---|
246 | DevPath = NextDevicePathNode(DevPath); |
---|
247 | } |
---|
248 | |
---|
249 | } |
---|
250 | |
---|
251 | if (Match == FALSE) { |
---|
252 | BlockIoBuffer[Index] = NULL; |
---|
253 | } else { |
---|
254 | *NoHandles = *NoHandles + 1; |
---|
255 | } |
---|
256 | } |
---|
257 | |
---|
258 | // |
---|
259 | // If there are no matches, then return |
---|
260 | // |
---|
261 | |
---|
262 | if (*NoHandles == 0) { |
---|
263 | FreePool(BlockIoBuffer); |
---|
264 | *NoHandles = 0; |
---|
265 | *Buffer = NULL; |
---|
266 | return EFI_SUCCESS; |
---|
267 | } |
---|
268 | |
---|
269 | // |
---|
270 | // Allocate space for the return buffer of device handles. |
---|
271 | // |
---|
272 | |
---|
273 | *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE)); |
---|
274 | |
---|
275 | if (*Buffer == NULL) { |
---|
276 | FreePool(BlockIoBuffer); |
---|
277 | *NoHandles = 0; |
---|
278 | *Buffer = NULL; |
---|
279 | return EFI_OUT_OF_RESOURCES; |
---|
280 | } |
---|
281 | |
---|
282 | // |
---|
283 | // Build list of matching device handles. |
---|
284 | // |
---|
285 | |
---|
286 | *NoHandles = 0; |
---|
287 | for(Index=0;Index<NoBlockIoHandles;Index++) { |
---|
288 | if (BlockIoBuffer[Index] != NULL) { |
---|
289 | (*Buffer)[*NoHandles] = BlockIoBuffer[Index]; |
---|
290 | *NoHandles = *NoHandles + 1; |
---|
291 | } |
---|
292 | } |
---|
293 | |
---|
294 | FreePool(BlockIoBuffer); |
---|
295 | |
---|
296 | return EFI_SUCCESS; |
---|
297 | } |
---|
298 | |
---|
299 | EFI_FILE_HANDLE |
---|
300 | LibOpenRoot ( |
---|
301 | IN EFI_HANDLE DeviceHandle |
---|
302 | ) |
---|
303 | { |
---|
304 | EFI_STATUS Status; |
---|
305 | EFI_FILE_IO_INTERFACE *Volume; |
---|
306 | EFI_FILE_HANDLE File; |
---|
307 | |
---|
308 | |
---|
309 | // |
---|
310 | // File the file system interface to the device |
---|
311 | // |
---|
312 | |
---|
313 | Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume); |
---|
314 | |
---|
315 | // |
---|
316 | // Open the root directory of the volume |
---|
317 | // |
---|
318 | |
---|
319 | if (!EFI_ERROR(Status)) { |
---|
320 | Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File); |
---|
321 | } |
---|
322 | |
---|
323 | // |
---|
324 | // Done |
---|
325 | // |
---|
326 | |
---|
327 | return EFI_ERROR(Status) ? NULL : File; |
---|
328 | } |
---|
329 | |
---|
330 | EFI_FILE_INFO * |
---|
331 | LibFileInfo ( |
---|
332 | IN EFI_FILE_HANDLE FHand |
---|
333 | ) |
---|
334 | { |
---|
335 | EFI_STATUS Status; |
---|
336 | EFI_FILE_INFO *Buffer; |
---|
337 | UINTN BufferSize; |
---|
338 | |
---|
339 | // |
---|
340 | // Initialize for GrowBuffer loop |
---|
341 | // |
---|
342 | |
---|
343 | Status = EFI_SUCCESS; |
---|
344 | Buffer = NULL; |
---|
345 | BufferSize = SIZE_OF_EFI_FILE_INFO + 200; |
---|
346 | |
---|
347 | // |
---|
348 | // Call the real function |
---|
349 | // |
---|
350 | |
---|
351 | while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { |
---|
352 | Status = uefi_call_wrapper( |
---|
353 | FHand->GetInfo, |
---|
354 | 4, |
---|
355 | FHand, |
---|
356 | &GenericFileInfo, |
---|
357 | &BufferSize, |
---|
358 | Buffer |
---|
359 | ); |
---|
360 | } |
---|
361 | |
---|
362 | return Buffer; |
---|
363 | } |
---|
364 | |
---|
365 | |
---|
366 | EFI_FILE_SYSTEM_INFO * |
---|
367 | LibFileSystemInfo ( |
---|
368 | IN EFI_FILE_HANDLE FHand |
---|
369 | ) |
---|
370 | { |
---|
371 | EFI_STATUS Status; |
---|
372 | EFI_FILE_SYSTEM_INFO *Buffer; |
---|
373 | UINTN BufferSize; |
---|
374 | |
---|
375 | // |
---|
376 | // Initialize for GrowBuffer loop |
---|
377 | // |
---|
378 | |
---|
379 | Status = EFI_SUCCESS; |
---|
380 | Buffer = NULL; |
---|
381 | BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200; |
---|
382 | |
---|
383 | // |
---|
384 | // Call the real function |
---|
385 | // |
---|
386 | |
---|
387 | while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { |
---|
388 | Status = uefi_call_wrapper( |
---|
389 | FHand->GetInfo, |
---|
390 | 4, |
---|
391 | FHand, |
---|
392 | &FileSystemInfo, |
---|
393 | &BufferSize, |
---|
394 | Buffer |
---|
395 | ); |
---|
396 | } |
---|
397 | |
---|
398 | return Buffer; |
---|
399 | } |
---|
400 | |
---|
401 | EFI_FILE_SYSTEM_VOLUME_LABEL_INFO * |
---|
402 | LibFileSystemVolumeLabelInfo ( |
---|
403 | IN EFI_FILE_HANDLE FHand |
---|
404 | ) |
---|
405 | { |
---|
406 | EFI_STATUS Status; |
---|
407 | EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer; |
---|
408 | UINTN BufferSize; |
---|
409 | |
---|
410 | // |
---|
411 | // Initialize for GrowBuffer loop |
---|
412 | // |
---|
413 | |
---|
414 | Status = EFI_SUCCESS; |
---|
415 | Buffer = NULL; |
---|
416 | BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200; |
---|
417 | |
---|
418 | // |
---|
419 | // Call the real function |
---|
420 | // |
---|
421 | |
---|
422 | while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { |
---|
423 | Status = uefi_call_wrapper( |
---|
424 | FHand->GetInfo, |
---|
425 | 4, |
---|
426 | FHand, |
---|
427 | &FileSystemVolumeLabelInfo, |
---|
428 | &BufferSize, |
---|
429 | Buffer |
---|
430 | ); |
---|
431 | } |
---|
432 | |
---|
433 | return Buffer; |
---|
434 | } |
---|
435 | |
---|
436 | |
---|
437 | |
---|
438 | EFI_STATUS |
---|
439 | LibInstallProtocolInterfaces ( |
---|
440 | IN OUT EFI_HANDLE *Handle, |
---|
441 | ... |
---|
442 | ) |
---|
443 | { |
---|
444 | va_list args; |
---|
445 | EFI_STATUS Status; |
---|
446 | EFI_GUID *Protocol; |
---|
447 | VOID *Interface; |
---|
448 | EFI_TPL OldTpl; |
---|
449 | UINTN Index; |
---|
450 | EFI_HANDLE OldHandle; |
---|
451 | |
---|
452 | // |
---|
453 | // Syncronize with notifcations |
---|
454 | // |
---|
455 | |
---|
456 | OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY); |
---|
457 | OldHandle = *Handle; |
---|
458 | |
---|
459 | // |
---|
460 | // Install the protocol interfaces |
---|
461 | // |
---|
462 | |
---|
463 | Index = 0; |
---|
464 | Status = EFI_SUCCESS; |
---|
465 | va_start (args, Handle); |
---|
466 | |
---|
467 | while (!EFI_ERROR(Status)) { |
---|
468 | |
---|
469 | // |
---|
470 | // If protocol is NULL, then it's the end of the list |
---|
471 | // |
---|
472 | |
---|
473 | Protocol = va_arg(args, EFI_GUID *); |
---|
474 | if (!Protocol) { |
---|
475 | break; |
---|
476 | } |
---|
477 | |
---|
478 | Interface = va_arg(args, VOID *); |
---|
479 | |
---|
480 | // |
---|
481 | // Install it |
---|
482 | // |
---|
483 | |
---|
484 | DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface)); |
---|
485 | Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); |
---|
486 | if (EFI_ERROR(Status)) { |
---|
487 | break; |
---|
488 | } |
---|
489 | |
---|
490 | Index += 1; |
---|
491 | } |
---|
492 | |
---|
493 | // |
---|
494 | // If there was an error, remove all the interfaces that were |
---|
495 | // installed without any errors |
---|
496 | // |
---|
497 | |
---|
498 | if (EFI_ERROR(Status)) { |
---|
499 | va_start (args, Handle); |
---|
500 | while (Index) { |
---|
501 | |
---|
502 | Protocol = va_arg(args, EFI_GUID *); |
---|
503 | Interface = va_arg(args, VOID *); |
---|
504 | uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface); |
---|
505 | |
---|
506 | Index -= 1; |
---|
507 | } |
---|
508 | |
---|
509 | *Handle = OldHandle; |
---|
510 | } |
---|
511 | |
---|
512 | // |
---|
513 | // Done |
---|
514 | // |
---|
515 | |
---|
516 | uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); |
---|
517 | return Status; |
---|
518 | } |
---|
519 | |
---|
520 | |
---|
521 | VOID |
---|
522 | LibUninstallProtocolInterfaces ( |
---|
523 | IN EFI_HANDLE Handle, |
---|
524 | ... |
---|
525 | ) |
---|
526 | { |
---|
527 | va_list args; |
---|
528 | EFI_STATUS Status; |
---|
529 | EFI_GUID *Protocol; |
---|
530 | VOID *Interface; |
---|
531 | |
---|
532 | |
---|
533 | va_start (args, Handle); |
---|
534 | for (; ;) { |
---|
535 | |
---|
536 | // |
---|
537 | // If protocol is NULL, then it's the end of the list |
---|
538 | // |
---|
539 | |
---|
540 | Protocol = va_arg(args, EFI_GUID *); |
---|
541 | if (!Protocol) { |
---|
542 | break; |
---|
543 | } |
---|
544 | |
---|
545 | Interface = va_arg(args, VOID *); |
---|
546 | |
---|
547 | // |
---|
548 | // Uninstall it |
---|
549 | // |
---|
550 | |
---|
551 | Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface); |
---|
552 | if (EFI_ERROR(Status)) { |
---|
553 | DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle)); |
---|
554 | } |
---|
555 | } |
---|
556 | } |
---|
557 | |
---|
558 | |
---|
559 | EFI_STATUS |
---|
560 | LibReinstallProtocolInterfaces ( |
---|
561 | IN OUT EFI_HANDLE *Handle, |
---|
562 | ... |
---|
563 | ) |
---|
564 | { |
---|
565 | va_list args; |
---|
566 | EFI_STATUS Status; |
---|
567 | EFI_GUID *Protocol; |
---|
568 | VOID *OldInterface, *NewInterface; |
---|
569 | EFI_TPL OldTpl; |
---|
570 | UINTN Index; |
---|
571 | |
---|
572 | // |
---|
573 | // Syncronize with notifcations |
---|
574 | // |
---|
575 | |
---|
576 | OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY); |
---|
577 | |
---|
578 | // |
---|
579 | // Install the protocol interfaces |
---|
580 | // |
---|
581 | |
---|
582 | Index = 0; |
---|
583 | Status = EFI_SUCCESS; |
---|
584 | va_start (args, Handle); |
---|
585 | |
---|
586 | while (!EFI_ERROR(Status)) { |
---|
587 | |
---|
588 | // |
---|
589 | // If protocol is NULL, then it's the end of the list |
---|
590 | // |
---|
591 | |
---|
592 | Protocol = va_arg(args, EFI_GUID *); |
---|
593 | if (!Protocol) { |
---|
594 | break; |
---|
595 | } |
---|
596 | |
---|
597 | OldInterface = va_arg(args, VOID *); |
---|
598 | NewInterface = va_arg(args, VOID *); |
---|
599 | |
---|
600 | // |
---|
601 | // Reinstall it |
---|
602 | // |
---|
603 | |
---|
604 | Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface); |
---|
605 | if (EFI_ERROR(Status)) { |
---|
606 | break; |
---|
607 | } |
---|
608 | |
---|
609 | Index += 1; |
---|
610 | } |
---|
611 | |
---|
612 | // |
---|
613 | // If there was an error, undo all the interfaces that were |
---|
614 | // reinstalled without any errors |
---|
615 | // |
---|
616 | |
---|
617 | if (EFI_ERROR(Status)) { |
---|
618 | va_start (args, Handle); |
---|
619 | while (Index) { |
---|
620 | |
---|
621 | Protocol = va_arg(args, EFI_GUID *); |
---|
622 | OldInterface = va_arg(args, VOID *); |
---|
623 | NewInterface = va_arg(args, VOID *); |
---|
624 | |
---|
625 | uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface); |
---|
626 | |
---|
627 | Index -= 1; |
---|
628 | } |
---|
629 | } |
---|
630 | |
---|
631 | // |
---|
632 | // Done |
---|
633 | // |
---|
634 | |
---|
635 | uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); |
---|
636 | return Status; |
---|
637 | } |
---|