Subversion Repositories HelenOS

Rev

Rev 2726 | Details | Compare with Previous | Last modification | View Log | RSS feed

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