1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon
3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation
4530d68baSNigel Croxon
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon
7530d68baSNigel Croxon hand.c
8530d68baSNigel Croxon
9530d68baSNigel Croxon Abstract:
10530d68baSNigel Croxon
11530d68baSNigel Croxon
12530d68baSNigel Croxon
13530d68baSNigel Croxon
14530d68baSNigel Croxon Revision History
15530d68baSNigel Croxon
16530d68baSNigel Croxon --*/
17530d68baSNigel Croxon
18530d68baSNigel Croxon #include "lib.h"
19530d68baSNigel Croxon #include "efistdarg.h" // !!!
20530d68baSNigel Croxon
21530d68baSNigel Croxon
22530d68baSNigel Croxon EFI_STATUS
LibLocateProtocol(IN EFI_GUID * ProtocolGuid,OUT VOID ** Interface)23530d68baSNigel Croxon LibLocateProtocol (
24530d68baSNigel Croxon IN EFI_GUID *ProtocolGuid,
25530d68baSNigel Croxon OUT VOID **Interface
26530d68baSNigel Croxon )
27530d68baSNigel Croxon //
28530d68baSNigel Croxon // Find the first instance of this Protocol in the system and return it's interface
29530d68baSNigel Croxon //
30530d68baSNigel Croxon {
31530d68baSNigel Croxon EFI_STATUS Status;
32530d68baSNigel Croxon UINTN NumberHandles, Index;
33530d68baSNigel Croxon EFI_HANDLE *Handles;
34530d68baSNigel Croxon
35530d68baSNigel Croxon
36530d68baSNigel Croxon *Interface = NULL;
37530d68baSNigel Croxon Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
38530d68baSNigel Croxon if (EFI_ERROR(Status)) {
39530d68baSNigel Croxon DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
40530d68baSNigel Croxon return Status;
41530d68baSNigel Croxon }
42530d68baSNigel Croxon
43530d68baSNigel Croxon for (Index=0; Index < NumberHandles; Index++) {
44530d68baSNigel Croxon Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface);
45530d68baSNigel Croxon if (!EFI_ERROR(Status)) {
46530d68baSNigel Croxon break;
47530d68baSNigel Croxon }
48530d68baSNigel Croxon }
49530d68baSNigel Croxon
50530d68baSNigel Croxon if (Handles) {
51530d68baSNigel Croxon FreePool (Handles);
52530d68baSNigel Croxon }
53530d68baSNigel Croxon
54530d68baSNigel Croxon return Status;
55530d68baSNigel Croxon }
56530d68baSNigel Croxon
57530d68baSNigel Croxon EFI_STATUS
LibLocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType,IN EFI_GUID * Protocol OPTIONAL,IN VOID * SearchKey OPTIONAL,IN OUT UINTN * NoHandles,OUT EFI_HANDLE ** Buffer)58530d68baSNigel Croxon LibLocateHandle (
59530d68baSNigel Croxon IN EFI_LOCATE_SEARCH_TYPE SearchType,
60530d68baSNigel Croxon IN EFI_GUID *Protocol OPTIONAL,
61530d68baSNigel Croxon IN VOID *SearchKey OPTIONAL,
62530d68baSNigel Croxon IN OUT UINTN *NoHandles,
63530d68baSNigel Croxon OUT EFI_HANDLE **Buffer
64530d68baSNigel Croxon )
65530d68baSNigel Croxon
66530d68baSNigel Croxon {
67530d68baSNigel Croxon EFI_STATUS Status;
68530d68baSNigel Croxon UINTN BufferSize;
69530d68baSNigel Croxon
70530d68baSNigel Croxon //
71530d68baSNigel Croxon // Initialize for GrowBuffer loop
72530d68baSNigel Croxon //
73530d68baSNigel Croxon
74530d68baSNigel Croxon Status = EFI_SUCCESS;
75530d68baSNigel Croxon *Buffer = NULL;
76530d68baSNigel Croxon BufferSize = 50 * sizeof(EFI_HANDLE);
77530d68baSNigel Croxon
78530d68baSNigel Croxon //
79530d68baSNigel Croxon // Call the real function
80530d68baSNigel Croxon //
81530d68baSNigel Croxon
82530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
83530d68baSNigel Croxon
84530d68baSNigel Croxon Status = uefi_call_wrapper(
85530d68baSNigel Croxon BS->LocateHandle,
86530d68baSNigel Croxon 5,
87530d68baSNigel Croxon SearchType,
88530d68baSNigel Croxon Protocol,
89530d68baSNigel Croxon SearchKey,
90530d68baSNigel Croxon &BufferSize,
91530d68baSNigel Croxon *Buffer
92530d68baSNigel Croxon );
93530d68baSNigel Croxon
94530d68baSNigel Croxon }
95530d68baSNigel Croxon
96530d68baSNigel Croxon *NoHandles = BufferSize / sizeof (EFI_HANDLE);
97530d68baSNigel Croxon if (EFI_ERROR(Status)) {
98530d68baSNigel Croxon *NoHandles = 0;
99530d68baSNigel Croxon }
100530d68baSNigel Croxon
101530d68baSNigel Croxon return Status;
102530d68baSNigel Croxon }
103530d68baSNigel Croxon
104530d68baSNigel Croxon EFI_STATUS
LibLocateHandleByDiskSignature(IN UINT8 MBRType,IN UINT8 SignatureType,IN VOID * Signature,IN OUT UINTN * NoHandles,OUT EFI_HANDLE ** Buffer)105530d68baSNigel Croxon LibLocateHandleByDiskSignature (
106530d68baSNigel Croxon IN UINT8 MBRType,
107530d68baSNigel Croxon IN UINT8 SignatureType,
108530d68baSNigel Croxon IN VOID *Signature,
109530d68baSNigel Croxon IN OUT UINTN *NoHandles,
110530d68baSNigel Croxon OUT EFI_HANDLE **Buffer
111530d68baSNigel Croxon )
112530d68baSNigel Croxon
113530d68baSNigel Croxon {
114530d68baSNigel Croxon EFI_STATUS Status;
115530d68baSNigel Croxon UINTN BufferSize;
116530d68baSNigel Croxon UINTN NoBlockIoHandles;
117530d68baSNigel Croxon EFI_HANDLE *BlockIoBuffer;
118530d68baSNigel Croxon EFI_DEVICE_PATH *DevicePath;
119530d68baSNigel Croxon UINTN Index;
1201ecae7d4SNigel Croxon EFI_DEVICE_PATH *Next, *DevPath;
121530d68baSNigel Croxon HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
122530d68baSNigel Croxon BOOLEAN Match;
123530d68baSNigel Croxon BOOLEAN PreviousNodeIsHardDriveDevicePath;
124530d68baSNigel Croxon
125530d68baSNigel Croxon //
126530d68baSNigel Croxon // Initialize for GrowBuffer loop
127530d68baSNigel Croxon //
128530d68baSNigel Croxon
129530d68baSNigel Croxon Status = EFI_SUCCESS;
130530d68baSNigel Croxon BlockIoBuffer = NULL;
131530d68baSNigel Croxon BufferSize = 50 * sizeof(EFI_HANDLE);
132530d68baSNigel Croxon
133530d68baSNigel Croxon //
134530d68baSNigel Croxon // Call the real function
135530d68baSNigel Croxon //
136530d68baSNigel Croxon
137530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
138530d68baSNigel Croxon
139530d68baSNigel Croxon //
140530d68baSNigel Croxon // Get list of device handles that support the BLOCK_IO Protocol.
141530d68baSNigel Croxon //
142530d68baSNigel Croxon
143530d68baSNigel Croxon Status = uefi_call_wrapper(
144530d68baSNigel Croxon BS->LocateHandle,
145530d68baSNigel Croxon 5,
146530d68baSNigel Croxon ByProtocol,
147530d68baSNigel Croxon &BlockIoProtocol,
148530d68baSNigel Croxon NULL,
149530d68baSNigel Croxon &BufferSize,
150530d68baSNigel Croxon BlockIoBuffer
151530d68baSNigel Croxon );
152530d68baSNigel Croxon
153530d68baSNigel Croxon }
154530d68baSNigel Croxon
155530d68baSNigel Croxon NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
156530d68baSNigel Croxon if (EFI_ERROR(Status)) {
157530d68baSNigel Croxon NoBlockIoHandles = 0;
158530d68baSNigel Croxon }
159530d68baSNigel Croxon
160530d68baSNigel Croxon //
161530d68baSNigel Croxon // If there was an error or there are no device handles that support
162530d68baSNigel Croxon // the BLOCK_IO Protocol, then return.
163530d68baSNigel Croxon //
164530d68baSNigel Croxon
165530d68baSNigel Croxon if (NoBlockIoHandles == 0) {
166530d68baSNigel Croxon FreePool(BlockIoBuffer);
167530d68baSNigel Croxon *NoHandles = 0;
168530d68baSNigel Croxon *Buffer = NULL;
169530d68baSNigel Croxon return Status;
170530d68baSNigel Croxon }
171530d68baSNigel Croxon
172530d68baSNigel Croxon //
173530d68baSNigel Croxon // Loop through all the device handles that support the BLOCK_IO Protocol
174530d68baSNigel Croxon //
175530d68baSNigel Croxon
176530d68baSNigel Croxon *NoHandles = 0;
177530d68baSNigel Croxon
178530d68baSNigel Croxon for(Index=0;Index<NoBlockIoHandles;Index++) {
179530d68baSNigel Croxon
180530d68baSNigel Croxon Status = uefi_call_wrapper(
181530d68baSNigel Croxon BS->HandleProtocol,
182530d68baSNigel Croxon 3,
183530d68baSNigel Croxon BlockIoBuffer[Index],
184530d68baSNigel Croxon &DevicePathProtocol,
185530d68baSNigel Croxon (VOID*)&DevicePath
186530d68baSNigel Croxon );
187530d68baSNigel Croxon
188530d68baSNigel Croxon //
189530d68baSNigel Croxon // Search DevicePath for a Hard Drive Media Device Path node.
190530d68baSNigel Croxon // If one is found, then see if it matches the signature that was
191530d68baSNigel Croxon // passed in. If it does match, and the next node is the End of the
192530d68baSNigel Croxon // device path, and the previous node is not a Hard Drive Media Device
193530d68baSNigel Croxon // Path, then we have found a match.
194530d68baSNigel Croxon //
195530d68baSNigel Croxon
196530d68baSNigel Croxon Match = FALSE;
197530d68baSNigel Croxon
198530d68baSNigel Croxon if (DevicePath != NULL) {
199530d68baSNigel Croxon
200530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = FALSE;
201530d68baSNigel Croxon
202530d68baSNigel Croxon DevPath = DevicePath;
203530d68baSNigel Croxon
204530d68baSNigel Croxon //
205530d68baSNigel Croxon // Check for end of device path type
206530d68baSNigel Croxon //
207530d68baSNigel Croxon
208530d68baSNigel Croxon for (; ;) {
209530d68baSNigel Croxon
210530d68baSNigel Croxon if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
211530d68baSNigel Croxon (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
212530d68baSNigel Croxon
213530d68baSNigel Croxon HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
214530d68baSNigel Croxon
215530d68baSNigel Croxon if (PreviousNodeIsHardDriveDevicePath == FALSE) {
216530d68baSNigel Croxon
217530d68baSNigel Croxon Next = NextDevicePathNode(DevPath);
218530d68baSNigel Croxon if (IsDevicePathEndType(Next)) {
219530d68baSNigel Croxon if ((HardDriveDevicePath->MBRType == MBRType) &&
220530d68baSNigel Croxon (HardDriveDevicePath->SignatureType == SignatureType)) {
221530d68baSNigel Croxon switch(SignatureType) {
222530d68baSNigel Croxon case SIGNATURE_TYPE_MBR:
223530d68baSNigel Croxon if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
224530d68baSNigel Croxon Match = TRUE;
225530d68baSNigel Croxon }
226530d68baSNigel Croxon break;
227530d68baSNigel Croxon case SIGNATURE_TYPE_GUID:
228530d68baSNigel Croxon if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) {
229530d68baSNigel Croxon Match = TRUE;
230530d68baSNigel Croxon }
231530d68baSNigel Croxon break;
232530d68baSNigel Croxon }
233530d68baSNigel Croxon }
234530d68baSNigel Croxon }
235530d68baSNigel Croxon }
236530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = TRUE;
237530d68baSNigel Croxon } else {
238530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = FALSE;
239530d68baSNigel Croxon }
240530d68baSNigel Croxon
241530d68baSNigel Croxon if (IsDevicePathEnd(DevPath)) {
242530d68baSNigel Croxon break;
243530d68baSNigel Croxon }
244530d68baSNigel Croxon
245530d68baSNigel Croxon DevPath = NextDevicePathNode(DevPath);
246530d68baSNigel Croxon }
247530d68baSNigel Croxon
248530d68baSNigel Croxon }
249530d68baSNigel Croxon
250530d68baSNigel Croxon if (Match == FALSE) {
251530d68baSNigel Croxon BlockIoBuffer[Index] = NULL;
252530d68baSNigel Croxon } else {
253530d68baSNigel Croxon *NoHandles = *NoHandles + 1;
254530d68baSNigel Croxon }
255530d68baSNigel Croxon }
256530d68baSNigel Croxon
257530d68baSNigel Croxon //
258530d68baSNigel Croxon // If there are no matches, then return
259530d68baSNigel Croxon //
260530d68baSNigel Croxon
261530d68baSNigel Croxon if (*NoHandles == 0) {
262530d68baSNigel Croxon FreePool(BlockIoBuffer);
263530d68baSNigel Croxon *NoHandles = 0;
264530d68baSNigel Croxon *Buffer = NULL;
265530d68baSNigel Croxon return EFI_SUCCESS;
266530d68baSNigel Croxon }
267530d68baSNigel Croxon
268530d68baSNigel Croxon //
269530d68baSNigel Croxon // Allocate space for the return buffer of device handles.
270530d68baSNigel Croxon //
271530d68baSNigel Croxon
272530d68baSNigel Croxon *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
273530d68baSNigel Croxon
274530d68baSNigel Croxon if (*Buffer == NULL) {
275530d68baSNigel Croxon FreePool(BlockIoBuffer);
276530d68baSNigel Croxon *NoHandles = 0;
277530d68baSNigel Croxon *Buffer = NULL;
278530d68baSNigel Croxon return EFI_OUT_OF_RESOURCES;
279530d68baSNigel Croxon }
280530d68baSNigel Croxon
281530d68baSNigel Croxon //
282530d68baSNigel Croxon // Build list of matching device handles.
283530d68baSNigel Croxon //
284530d68baSNigel Croxon
285530d68baSNigel Croxon *NoHandles = 0;
286530d68baSNigel Croxon for(Index=0;Index<NoBlockIoHandles;Index++) {
287530d68baSNigel Croxon if (BlockIoBuffer[Index] != NULL) {
288530d68baSNigel Croxon (*Buffer)[*NoHandles] = BlockIoBuffer[Index];
289530d68baSNigel Croxon *NoHandles = *NoHandles + 1;
290530d68baSNigel Croxon }
291530d68baSNigel Croxon }
292530d68baSNigel Croxon
293530d68baSNigel Croxon FreePool(BlockIoBuffer);
294530d68baSNigel Croxon
295530d68baSNigel Croxon return EFI_SUCCESS;
296530d68baSNigel Croxon }
297530d68baSNigel Croxon
298530d68baSNigel Croxon EFI_FILE_HANDLE
LibOpenRoot(IN EFI_HANDLE DeviceHandle)299530d68baSNigel Croxon LibOpenRoot (
300530d68baSNigel Croxon IN EFI_HANDLE DeviceHandle
301530d68baSNigel Croxon )
302530d68baSNigel Croxon {
303530d68baSNigel Croxon EFI_STATUS Status;
304530d68baSNigel Croxon EFI_FILE_IO_INTERFACE *Volume;
305530d68baSNigel Croxon EFI_FILE_HANDLE File;
306530d68baSNigel Croxon
307530d68baSNigel Croxon
308530d68baSNigel Croxon //
309530d68baSNigel Croxon // File the file system interface to the device
310530d68baSNigel Croxon //
311530d68baSNigel Croxon
312530d68baSNigel Croxon Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
313530d68baSNigel Croxon
314530d68baSNigel Croxon //
315530d68baSNigel Croxon // Open the root directory of the volume
316530d68baSNigel Croxon //
317530d68baSNigel Croxon
318530d68baSNigel Croxon if (!EFI_ERROR(Status)) {
319530d68baSNigel Croxon Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File);
320530d68baSNigel Croxon }
321530d68baSNigel Croxon
322530d68baSNigel Croxon //
323530d68baSNigel Croxon // Done
324530d68baSNigel Croxon //
325530d68baSNigel Croxon
326530d68baSNigel Croxon return EFI_ERROR(Status) ? NULL : File;
327530d68baSNigel Croxon }
328530d68baSNigel Croxon
329530d68baSNigel Croxon EFI_FILE_INFO *
LibFileInfo(IN EFI_FILE_HANDLE FHand)330530d68baSNigel Croxon LibFileInfo (
331530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand
332530d68baSNigel Croxon )
333530d68baSNigel Croxon {
334530d68baSNigel Croxon EFI_STATUS Status;
335530d68baSNigel Croxon EFI_FILE_INFO *Buffer;
336530d68baSNigel Croxon UINTN BufferSize;
337530d68baSNigel Croxon
338530d68baSNigel Croxon //
339530d68baSNigel Croxon // Initialize for GrowBuffer loop
340530d68baSNigel Croxon //
341530d68baSNigel Croxon
342530d68baSNigel Croxon Status = EFI_SUCCESS;
343530d68baSNigel Croxon Buffer = NULL;
344530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
345530d68baSNigel Croxon
346530d68baSNigel Croxon //
347530d68baSNigel Croxon // Call the real function
348530d68baSNigel Croxon //
349530d68baSNigel Croxon
350530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
351530d68baSNigel Croxon Status = uefi_call_wrapper(
352530d68baSNigel Croxon FHand->GetInfo,
353530d68baSNigel Croxon 4,
354530d68baSNigel Croxon FHand,
355530d68baSNigel Croxon &GenericFileInfo,
356530d68baSNigel Croxon &BufferSize,
357530d68baSNigel Croxon Buffer
358530d68baSNigel Croxon );
359530d68baSNigel Croxon }
360530d68baSNigel Croxon
361530d68baSNigel Croxon return Buffer;
362530d68baSNigel Croxon }
363530d68baSNigel Croxon
364530d68baSNigel Croxon
365530d68baSNigel Croxon EFI_FILE_SYSTEM_INFO *
LibFileSystemInfo(IN EFI_FILE_HANDLE FHand)366530d68baSNigel Croxon LibFileSystemInfo (
367530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand
368530d68baSNigel Croxon )
369530d68baSNigel Croxon {
370530d68baSNigel Croxon EFI_STATUS Status;
371530d68baSNigel Croxon EFI_FILE_SYSTEM_INFO *Buffer;
372530d68baSNigel Croxon UINTN BufferSize;
373530d68baSNigel Croxon
374530d68baSNigel Croxon //
375530d68baSNigel Croxon // Initialize for GrowBuffer loop
376530d68baSNigel Croxon //
377530d68baSNigel Croxon
378530d68baSNigel Croxon Status = EFI_SUCCESS;
379530d68baSNigel Croxon Buffer = NULL;
380530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
381530d68baSNigel Croxon
382530d68baSNigel Croxon //
383530d68baSNigel Croxon // Call the real function
384530d68baSNigel Croxon //
385530d68baSNigel Croxon
386530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
387530d68baSNigel Croxon Status = uefi_call_wrapper(
388530d68baSNigel Croxon FHand->GetInfo,
389530d68baSNigel Croxon 4,
390530d68baSNigel Croxon FHand,
391530d68baSNigel Croxon &FileSystemInfo,
392530d68baSNigel Croxon &BufferSize,
393530d68baSNigel Croxon Buffer
394530d68baSNigel Croxon );
395530d68baSNigel Croxon }
396530d68baSNigel Croxon
397530d68baSNigel Croxon return Buffer;
398530d68baSNigel Croxon }
399530d68baSNigel Croxon
400530d68baSNigel Croxon EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
LibFileSystemVolumeLabelInfo(IN EFI_FILE_HANDLE FHand)401530d68baSNigel Croxon LibFileSystemVolumeLabelInfo (
402530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand
403530d68baSNigel Croxon )
404530d68baSNigel Croxon {
405530d68baSNigel Croxon EFI_STATUS Status;
406530d68baSNigel Croxon EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
407530d68baSNigel Croxon UINTN BufferSize;
408530d68baSNigel Croxon
409530d68baSNigel Croxon //
410530d68baSNigel Croxon // Initialize for GrowBuffer loop
411530d68baSNigel Croxon //
412530d68baSNigel Croxon
413530d68baSNigel Croxon Status = EFI_SUCCESS;
414530d68baSNigel Croxon Buffer = NULL;
415530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
416530d68baSNigel Croxon
417530d68baSNigel Croxon //
418530d68baSNigel Croxon // Call the real function
419530d68baSNigel Croxon //
420530d68baSNigel Croxon
421530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
422530d68baSNigel Croxon Status = uefi_call_wrapper(
423530d68baSNigel Croxon FHand->GetInfo,
424530d68baSNigel Croxon 4,
425530d68baSNigel Croxon FHand,
426530d68baSNigel Croxon &FileSystemVolumeLabelInfo,
427530d68baSNigel Croxon &BufferSize,
428530d68baSNigel Croxon Buffer
429530d68baSNigel Croxon );
430530d68baSNigel Croxon }
431530d68baSNigel Croxon
432530d68baSNigel Croxon return Buffer;
433530d68baSNigel Croxon }
434530d68baSNigel Croxon
435530d68baSNigel Croxon
436530d68baSNigel Croxon
437530d68baSNigel Croxon EFI_STATUS
LibInstallProtocolInterfaces(IN OUT EFI_HANDLE * Handle,...)438530d68baSNigel Croxon LibInstallProtocolInterfaces (
439530d68baSNigel Croxon IN OUT EFI_HANDLE *Handle,
440530d68baSNigel Croxon ...
441530d68baSNigel Croxon )
442530d68baSNigel Croxon {
443530d68baSNigel Croxon va_list args;
444530d68baSNigel Croxon EFI_STATUS Status;
445530d68baSNigel Croxon EFI_GUID *Protocol;
446530d68baSNigel Croxon VOID *Interface;
447530d68baSNigel Croxon EFI_TPL OldTpl;
448530d68baSNigel Croxon UINTN Index;
449530d68baSNigel Croxon EFI_HANDLE OldHandle;
450530d68baSNigel Croxon
451530d68baSNigel Croxon //
452530d68baSNigel Croxon // Syncronize with notifcations
453530d68baSNigel Croxon //
454530d68baSNigel Croxon
455530d68baSNigel Croxon OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
456530d68baSNigel Croxon OldHandle = *Handle;
457530d68baSNigel Croxon
458530d68baSNigel Croxon //
459530d68baSNigel Croxon // Install the protocol interfaces
460530d68baSNigel Croxon //
461530d68baSNigel Croxon
462530d68baSNigel Croxon Index = 0;
463530d68baSNigel Croxon Status = EFI_SUCCESS;
464530d68baSNigel Croxon va_start (args, Handle);
465530d68baSNigel Croxon
466530d68baSNigel Croxon while (!EFI_ERROR(Status)) {
467530d68baSNigel Croxon
468530d68baSNigel Croxon //
469530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list
470530d68baSNigel Croxon //
471530d68baSNigel Croxon
472530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *);
473530d68baSNigel Croxon if (!Protocol) {
474530d68baSNigel Croxon break;
475530d68baSNigel Croxon }
476530d68baSNigel Croxon
477530d68baSNigel Croxon Interface = va_arg(args, VOID *);
478530d68baSNigel Croxon
479530d68baSNigel Croxon //
480530d68baSNigel Croxon // Install it
481530d68baSNigel Croxon //
482530d68baSNigel Croxon
483530d68baSNigel Croxon DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
484530d68baSNigel Croxon Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
485530d68baSNigel Croxon if (EFI_ERROR(Status)) {
486530d68baSNigel Croxon break;
487530d68baSNigel Croxon }
488530d68baSNigel Croxon
489530d68baSNigel Croxon Index += 1;
490530d68baSNigel Croxon }
4910ec661b3SHeinrich Schuchardt va_end (args);
492530d68baSNigel Croxon
493530d68baSNigel Croxon //
494530d68baSNigel Croxon // If there was an error, remove all the interfaces that were
495530d68baSNigel Croxon // installed without any errors
496530d68baSNigel Croxon //
497530d68baSNigel Croxon
498530d68baSNigel Croxon if (EFI_ERROR(Status)) {
499530d68baSNigel Croxon va_start (args, Handle);
500530d68baSNigel Croxon while (Index) {
501530d68baSNigel Croxon
502530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *);
503530d68baSNigel Croxon Interface = va_arg(args, VOID *);
504530d68baSNigel Croxon uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface);
505530d68baSNigel Croxon
506530d68baSNigel Croxon Index -= 1;
507530d68baSNigel Croxon }
508530d68baSNigel Croxon
509530d68baSNigel Croxon *Handle = OldHandle;
5100ec661b3SHeinrich Schuchardt va_end (args);
511530d68baSNigel Croxon }
512530d68baSNigel Croxon
513530d68baSNigel Croxon //
514530d68baSNigel Croxon // Done
515530d68baSNigel Croxon //
516530d68baSNigel Croxon
517530d68baSNigel Croxon uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
518530d68baSNigel Croxon return Status;
519530d68baSNigel Croxon }
520530d68baSNigel Croxon
521530d68baSNigel Croxon
522530d68baSNigel Croxon VOID
LibUninstallProtocolInterfaces(IN EFI_HANDLE Handle,...)523530d68baSNigel Croxon LibUninstallProtocolInterfaces (
524530d68baSNigel Croxon IN EFI_HANDLE Handle,
525530d68baSNigel Croxon ...
526530d68baSNigel Croxon )
527530d68baSNigel Croxon {
528530d68baSNigel Croxon va_list args;
529530d68baSNigel Croxon EFI_STATUS Status;
530530d68baSNigel Croxon EFI_GUID *Protocol;
531530d68baSNigel Croxon VOID *Interface;
532530d68baSNigel Croxon
533530d68baSNigel Croxon
534530d68baSNigel Croxon va_start (args, Handle);
535530d68baSNigel Croxon for (; ;) {
536530d68baSNigel Croxon
537530d68baSNigel Croxon //
538530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list
539530d68baSNigel Croxon //
540530d68baSNigel Croxon
541530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *);
542530d68baSNigel Croxon if (!Protocol) {
543530d68baSNigel Croxon break;
544530d68baSNigel Croxon }
545530d68baSNigel Croxon
546530d68baSNigel Croxon Interface = va_arg(args, VOID *);
547530d68baSNigel Croxon
548530d68baSNigel Croxon //
549530d68baSNigel Croxon // Uninstall it
550530d68baSNigel Croxon //
551530d68baSNigel Croxon
552530d68baSNigel Croxon Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface);
553530d68baSNigel Croxon if (EFI_ERROR(Status)) {
554530d68baSNigel Croxon DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
555530d68baSNigel Croxon }
556530d68baSNigel Croxon }
5570ec661b3SHeinrich Schuchardt va_end (args);
558530d68baSNigel Croxon }
559530d68baSNigel Croxon
560530d68baSNigel Croxon
561530d68baSNigel Croxon EFI_STATUS
LibReinstallProtocolInterfaces(IN OUT EFI_HANDLE * Handle,...)562530d68baSNigel Croxon LibReinstallProtocolInterfaces (
563530d68baSNigel Croxon IN OUT EFI_HANDLE *Handle,
564530d68baSNigel Croxon ...
565530d68baSNigel Croxon )
566530d68baSNigel Croxon {
567530d68baSNigel Croxon va_list args;
568530d68baSNigel Croxon EFI_STATUS Status;
569530d68baSNigel Croxon EFI_GUID *Protocol;
570530d68baSNigel Croxon VOID *OldInterface, *NewInterface;
571530d68baSNigel Croxon EFI_TPL OldTpl;
572530d68baSNigel Croxon UINTN Index;
573530d68baSNigel Croxon
574530d68baSNigel Croxon //
575530d68baSNigel Croxon // Syncronize with notifcations
576530d68baSNigel Croxon //
577530d68baSNigel Croxon
578530d68baSNigel Croxon OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
579530d68baSNigel Croxon
580530d68baSNigel Croxon //
581530d68baSNigel Croxon // Install the protocol interfaces
582530d68baSNigel Croxon //
583530d68baSNigel Croxon
584530d68baSNigel Croxon Index = 0;
585530d68baSNigel Croxon Status = EFI_SUCCESS;
586530d68baSNigel Croxon va_start (args, Handle);
587530d68baSNigel Croxon
588530d68baSNigel Croxon while (!EFI_ERROR(Status)) {
589530d68baSNigel Croxon
590530d68baSNigel Croxon //
591530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list
592530d68baSNigel Croxon //
593530d68baSNigel Croxon
594530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *);
595530d68baSNigel Croxon if (!Protocol) {
596530d68baSNigel Croxon break;
597530d68baSNigel Croxon }
598530d68baSNigel Croxon
599530d68baSNigel Croxon OldInterface = va_arg(args, VOID *);
600530d68baSNigel Croxon NewInterface = va_arg(args, VOID *);
601530d68baSNigel Croxon
602530d68baSNigel Croxon //
603530d68baSNigel Croxon // Reinstall it
604530d68baSNigel Croxon //
605530d68baSNigel Croxon
606530d68baSNigel Croxon Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface);
607530d68baSNigel Croxon if (EFI_ERROR(Status)) {
608530d68baSNigel Croxon break;
609530d68baSNigel Croxon }
610530d68baSNigel Croxon
611530d68baSNigel Croxon Index += 1;
612530d68baSNigel Croxon }
613*70402aa9SHeinrich Schuchardt va_end (args);
614530d68baSNigel Croxon
615530d68baSNigel Croxon //
616530d68baSNigel Croxon // If there was an error, undo all the interfaces that were
617530d68baSNigel Croxon // reinstalled without any errors
618530d68baSNigel Croxon //
619530d68baSNigel Croxon
620530d68baSNigel Croxon if (EFI_ERROR(Status)) {
621530d68baSNigel Croxon va_start (args, Handle);
622530d68baSNigel Croxon while (Index) {
623530d68baSNigel Croxon
624530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *);
625530d68baSNigel Croxon OldInterface = va_arg(args, VOID *);
626530d68baSNigel Croxon NewInterface = va_arg(args, VOID *);
627530d68baSNigel Croxon
628530d68baSNigel Croxon uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface);
629530d68baSNigel Croxon
630530d68baSNigel Croxon Index -= 1;
631530d68baSNigel Croxon }
632*70402aa9SHeinrich Schuchardt va_end (args);
633530d68baSNigel Croxon }
634530d68baSNigel Croxon
635530d68baSNigel Croxon //
636530d68baSNigel Croxon // Done
637530d68baSNigel Croxon //
638530d68baSNigel Croxon
639530d68baSNigel Croxon uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
640530d68baSNigel Croxon return Status;
641530d68baSNigel Croxon }
642