Subversion Repositories HelenOS

Rev

Rev 2726 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2726 Rev 4687
1
/*++
1
/*++
2
 
2
 
3
Copyright (c) 1998  Intel Corporation
3
Copyright (c) 1998  Intel Corporation
4
 
4
 
5
Module Name:
5
Module Name:
6
 
6
 
7
    dpath.c
7
    dpath.c
8
 
8
 
9
Abstract:
9
Abstract:
10
    MBR & Device Path functions
10
    MBR & Device Path functions
11
 
11
 
12
 
12
 
13
 
13
 
14
Revision History
14
Revision History
15
 
15
 
16
--*/
16
--*/
17
 
17
 
18
#include "lib.h"
18
#include "lib.h"
19
 
19
 
20
#define ALIGN_SIZE(a)   ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
20
#define ALIGN_SIZE(a)   ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
21
 
21
 
22
 
22
 
23
 
23
 
24
EFI_DEVICE_PATH *
24
EFI_DEVICE_PATH *
25
DevicePathFromHandle (
25
DevicePathFromHandle (
26
    IN EFI_HANDLE       Handle
26
    IN EFI_HANDLE       Handle
27
    )
27
    )
28
{
28
{
29
    EFI_STATUS          Status;
29
    EFI_STATUS          Status;
30
    EFI_DEVICE_PATH     *DevicePath;
30
    EFI_DEVICE_PATH     *DevicePath;
31
 
31
 
32
    Status = BS->HandleProtocol (Handle, &DevicePathProtocol, (VOID*)&DevicePath);
32
    Status = BS->HandleProtocol (Handle, &DevicePathProtocol, (VOID*)&DevicePath);
33
    if (EFI_ERROR(Status)) {
33
    if (EFI_ERROR(Status)) {
34
        DevicePath = NULL;
34
        DevicePath = NULL;
35
    }
35
    }
36
 
36
 
37
    return DevicePath;
37
    return DevicePath;
38
}
38
}
39
 
39
 
40
 
40
 
41
EFI_DEVICE_PATH *
41
EFI_DEVICE_PATH *
42
DevicePathInstance (
42
DevicePathInstance (
43
    IN OUT EFI_DEVICE_PATH  **DevicePath,
43
    IN OUT EFI_DEVICE_PATH  **DevicePath,
44
    OUT UINTN               *Size
44
    OUT UINTN               *Size
45
    )
45
    )
46
{
46
{
47
    EFI_DEVICE_PATH         *Start, *Next, *DevPath;
47
    EFI_DEVICE_PATH         *Start, *Next, *DevPath;
48
    UINTN                   Count;
48
    UINTN                   Count;
49
 
49
 
50
    DevPath = *DevicePath;
50
    DevPath = *DevicePath;
51
    Start = DevPath;
51
    Start = DevPath;
52
 
52
 
53
    if (!DevPath) {
53
    if (!DevPath) {
54
        return NULL;
54
        return NULL;
55
    }
55
    }
56
 
56
 
57
    //
57
    //
58
    // Check for end of device path type
58
    // Check for end of device path type
59
    //    
59
    //    
60
 
60
 
61
    for (Count = 0; ; Count++) {
61
    for (Count = 0; ; Count++) {
62
        Next = NextDevicePathNode(DevPath);
62
        Next = NextDevicePathNode(DevPath);
63
 
63
 
64
        if (IsDevicePathEndType(DevPath)) {
64
        if (IsDevicePathEndType(DevPath)) {
65
            break;
65
            break;
66
        }
66
        }
67
 
67
 
68
        if (Count > 01000) {
68
        if (Count > 01000) {
69
            //
69
            //
70
            // BugBug: Debug code to catch bogus device paths
70
            // BugBug: Debug code to catch bogus device paths
71
            //
71
            //
72
            DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
72
            DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
73
            DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
73
            DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
74
            break;
74
            break;
75
        }
75
        }
76
 
76
 
77
        DevPath = Next;
77
        DevPath = Next;
78
    }
78
    }
79
 
79
 
80
    ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
80
    ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
81
            DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
81
            DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
82
 
82
 
83
    //
83
    //
84
    // Set next position
84
    // Set next position
85
    //
85
    //
86
 
86
 
87
    if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
87
    if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
88
        Next = NULL;
88
        Next = NULL;
89
    }
89
    }
90
 
90
 
91
    *DevicePath = Next;
91
    *DevicePath = Next;
92
 
92
 
93
    //
93
    //
94
    // Return size and start of device path instance
94
    // Return size and start of device path instance
95
    //
95
    //
96
 
96
 
97
    *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
97
    *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
98
    return Start;
98
    return Start;
99
}
99
}
100
 
100
 
101
UINTN
101
UINTN
102
DevicePathInstanceCount (
102
DevicePathInstanceCount (
103
    IN EFI_DEVICE_PATH      *DevicePath
103
    IN EFI_DEVICE_PATH      *DevicePath
104
    )
104
    )
105
{
105
{
106
    UINTN       Count, Size;
106
    UINTN       Count, Size;
107
 
107
 
108
    Count = 0;
108
    Count = 0;
109
    while (DevicePathInstance(&DevicePath, &Size)) {
109
    while (DevicePathInstance(&DevicePath, &Size)) {
110
        Count += 1;
110
        Count += 1;
111
    }
111
    }
112
 
112
 
113
    return Count;
113
    return Count;
114
}
114
}
115
 
115
 
116
 
116
 
117
EFI_DEVICE_PATH *
117
EFI_DEVICE_PATH *
118
AppendDevicePath (
118
AppendDevicePath (
119
    IN EFI_DEVICE_PATH  *Src1,
119
    IN EFI_DEVICE_PATH  *Src1,
120
    IN EFI_DEVICE_PATH  *Src2
120
    IN EFI_DEVICE_PATH  *Src2
121
    )
121
    )
122
// Src1 may have multiple "instances" and each instance is appended
122
// Src1 may have multiple "instances" and each instance is appended
123
// Src2 is appended to each instance is Src1.  (E.g., it's possible
123
// Src2 is appended to each instance is Src1.  (E.g., it's possible
124
// to append a new instance to the complete device path by passing 
124
// to append a new instance to the complete device path by passing 
125
// it in Src2)
125
// it in Src2)
126
{
126
{
127
    UINTN               Src1Size, Src1Inst, Src2Size, Size;
127
    UINTN               Src1Size, Src1Inst, Src2Size, Size;
128
    EFI_DEVICE_PATH     *Dst, *Inst;
128
    EFI_DEVICE_PATH     *Dst, *Inst;
129
    UINT8               *DstPos;
129
    UINT8               *DstPos;
130
 
130
 
131
    //
131
    //
132
    // If there's only 1 path, just duplicate it
132
    // If there's only 1 path, just duplicate it
133
    //
133
    //
134
 
134
 
135
    if (!Src1) {
135
    if (!Src1) {
136
        ASSERT (!IsDevicePathUnpacked (Src2));
136
        ASSERT (!IsDevicePathUnpacked (Src2));
137
        return DuplicateDevicePath (Src2);
137
        return DuplicateDevicePath (Src2);
138
    }
138
    }
139
 
139
 
140
    if (!Src2) {
140
    if (!Src2) {
141
        ASSERT (!IsDevicePathUnpacked (Src1));
141
        ASSERT (!IsDevicePathUnpacked (Src1));
142
        return DuplicateDevicePath (Src1);
142
        return DuplicateDevicePath (Src1);
143
    }
143
    }
144
 
144
 
145
    //
145
    //
146
    // Verify we're not working with unpacked paths
146
    // Verify we're not working with unpacked paths
147
    //
147
    //
148
 
148
 
149
//    ASSERT (!IsDevicePathUnpacked (Src1));
149
//    ASSERT (!IsDevicePathUnpacked (Src1));
150
//    ASSERT (!IsDevicePathUnpacked (Src2));
150
//    ASSERT (!IsDevicePathUnpacked (Src2));
151
 
151
 
152
    //
152
    //
153
    // Append Src2 to every instance in Src1
153
    // Append Src2 to every instance in Src1
154
    //
154
    //
155
 
155
 
156
    Src1Size = DevicePathSize(Src1);
156
    Src1Size = DevicePathSize(Src1);
157
    Src1Inst = DevicePathInstanceCount(Src1);
157
    Src1Inst = DevicePathInstanceCount(Src1);
158
    Src2Size = DevicePathSize(Src2);
158
    Src2Size = DevicePathSize(Src2);
159
    Size = Src1Size * Src1Inst + Src2Size;
159
    Size = Src1Size * Src1Inst + Src2Size;
160
   
160
   
161
    Dst = AllocatePool (Size);
161
    Dst = AllocatePool (Size);
162
    if (Dst) {
162
    if (Dst) {
163
        DstPos = (UINT8 *) Dst;
163
        DstPos = (UINT8 *) Dst;
164
 
164
 
165
        //
165
        //
166
        // Copy all device path instances
166
        // Copy all device path instances
167
        //
167
        //
168
 
168
 
169
        while ((Inst = DevicePathInstance (&Src1, &Size))) {
169
        while ((Inst = DevicePathInstance (&Src1, &Size))) {
170
 
170
 
171
            CopyMem(DstPos, Inst, Size);
171
            CopyMem(DstPos, Inst, Size);
172
            DstPos += Size;
172
            DstPos += Size;
173
 
173
 
174
            CopyMem(DstPos, Src2, Src2Size);
174
            CopyMem(DstPos, Src2, Src2Size);
175
            DstPos += Src2Size;
175
            DstPos += Src2Size;
176
 
176
 
177
            CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
177
            CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
178
            DstPos += sizeof(EFI_DEVICE_PATH);
178
            DstPos += sizeof(EFI_DEVICE_PATH);
179
        }
179
        }
180
 
180
 
181
        // Change last end marker
181
        // Change last end marker
182
        DstPos -= sizeof(EFI_DEVICE_PATH);
182
        DstPos -= sizeof(EFI_DEVICE_PATH);
183
        CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
183
        CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
184
    }
184
    }
185
 
185
 
186
    return Dst;
186
    return Dst;
187
}
187
}
188
 
188
 
189
 
189
 
190
EFI_DEVICE_PATH *
190
EFI_DEVICE_PATH *
191
AppendDevicePathNode (
191
AppendDevicePathNode (
192
    IN EFI_DEVICE_PATH  *Src1,
192
    IN EFI_DEVICE_PATH  *Src1,
193
    IN EFI_DEVICE_PATH  *Src2
193
    IN EFI_DEVICE_PATH  *Src2
194
    )
194
    )
195
// Src1 may have multiple "instances" and each instance is appended
195
// Src1 may have multiple "instances" and each instance is appended
196
// Src2 is a signal device path node (without a terminator) that is
196
// Src2 is a signal device path node (without a terminator) that is
197
// appended to each instance is Src1.
197
// appended to each instance is Src1.
198
{
198
{
199
    EFI_DEVICE_PATH     *Temp, *Eop;
199
    EFI_DEVICE_PATH     *Temp, *Eop;
200
    UINTN               Length;
200
    UINTN               Length;
201
 
201
 
202
    //
202
    //
203
    // Build a Src2 that has a terminator on it
203
    // Build a Src2 that has a terminator on it
204
    //
204
    //
205
 
205
 
206
    Length = DevicePathNodeLength(Src2);
206
    Length = DevicePathNodeLength(Src2);
207
    Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
207
    Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
208
    if (!Temp) {
208
    if (!Temp) {
209
        return NULL;
209
        return NULL;
210
    }
210
    }
211
 
211
 
212
    CopyMem (Temp, Src2, Length);
212
    CopyMem (Temp, Src2, Length);
213
    Eop = NextDevicePathNode(Temp);
213
    Eop = NextDevicePathNode(Temp);
214
    SetDevicePathEndNode(Eop);
214
    SetDevicePathEndNode(Eop);
215
 
215
 
216
    //
216
    //
217
    // Append device paths
217
    // Append device paths
218
    //
218
    //
219
 
219
 
220
    Src1 = AppendDevicePath (Src1, Temp);
220
    Src1 = AppendDevicePath (Src1, Temp);
221
    FreePool (Temp);
221
    FreePool (Temp);
222
    return Src1;
222
    return Src1;
223
}
223
}
224
 
224
 
225
 
225
 
226
EFI_DEVICE_PATH *
226
EFI_DEVICE_PATH *
227
FileDevicePath (
227
FileDevicePath (
228
    IN EFI_HANDLE       Device  OPTIONAL,
228
    IN EFI_HANDLE       Device  OPTIONAL,
229
    IN CHAR16           *FileName
229
    IN CHAR16           *FileName
230
    )
230
    )
231
/*++
231
/*++
232
 
232
 
233
    N.B. Results are allocated from pool.  The caller must FreePool
233
    N.B. Results are allocated from pool.  The caller must FreePool
234
    the resulting device path structure
234
    the resulting device path structure
235
 
235
 
236
--*/
236
--*/
237
{
237
{
238
    UINTN                   Size;
238
    UINTN                   Size;
239
    FILEPATH_DEVICE_PATH    *FilePath;
239
    FILEPATH_DEVICE_PATH    *FilePath;
240
    EFI_DEVICE_PATH         *Eop, *DevicePath;    
240
    EFI_DEVICE_PATH         *Eop, *DevicePath;    
241
 
241
 
242
    Size = StrSize(FileName);
242
    Size = StrSize(FileName);
243
    FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
243
    FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
244
    DevicePath = NULL;
244
    DevicePath = NULL;
245
 
245
 
246
    if (FilePath) {
246
    if (FilePath) {
247
 
247
 
248
        //
248
        //
249
        // Build a file path
249
        // Build a file path
250
        //
250
        //
251
 
251
 
252
        FilePath->Header.Type = MEDIA_DEVICE_PATH;
252
        FilePath->Header.Type = MEDIA_DEVICE_PATH;
253
        FilePath->Header.SubType = MEDIA_FILEPATH_DP;
253
        FilePath->Header.SubType = MEDIA_FILEPATH_DP;
254
        SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
254
        SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
255
        CopyMem (FilePath->PathName, FileName, Size);
255
        CopyMem (FilePath->PathName, FileName, Size);
256
        Eop = NextDevicePathNode(&FilePath->Header);
256
        Eop = NextDevicePathNode(&FilePath->Header);
257
        SetDevicePathEndNode(Eop);
257
        SetDevicePathEndNode(Eop);
258
 
258
 
259
        //
259
        //
260
        // Append file path to device's device path
260
        // Append file path to device's device path
261
        //
261
        //
262
 
262
 
263
        DevicePath = (EFI_DEVICE_PATH *) FilePath;
263
        DevicePath = (EFI_DEVICE_PATH *) FilePath;
264
        if (Device) {
264
        if (Device) {
265
            DevicePath = AppendDevicePath (
265
            DevicePath = AppendDevicePath (
266
                            DevicePathFromHandle(Device),
266
                            DevicePathFromHandle(Device),
267
                            DevicePath
267
                            DevicePath
268
                            );
268
                            );
269
 
269
 
270
            FreePool(FilePath);
270
            FreePool(FilePath);
271
        }
271
        }
272
    }
272
    }
273
 
273
 
274
    return DevicePath;
274
    return DevicePath;
275
}
275
}
276
 
276
 
277
 
277
 
278
 
278
 
279
UINTN
279
UINTN
280
DevicePathSize (
280
DevicePathSize (
281
    IN EFI_DEVICE_PATH  *DevPath
281
    IN EFI_DEVICE_PATH  *DevPath
282
    )
282
    )
283
{
283
{
284
    EFI_DEVICE_PATH     *Start;
284
    EFI_DEVICE_PATH     *Start;
285
 
285
 
286
    //
286
    //
287
    // Search for the end of the device path structure
287
    // Search for the end of the device path structure
288
    //    
288
    //    
289
 
289
 
290
    Start = DevPath;
290
    Start = DevPath;
291
    while (!IsDevicePathEnd(DevPath)) {
291
    while (!IsDevicePathEnd(DevPath)) {
292
        DevPath = NextDevicePathNode(DevPath);
292
        DevPath = NextDevicePathNode(DevPath);
293
    }
293
    }
294
 
294
 
295
    //
295
    //
296
    // Compute the size
296
    // Compute the size
297
    //
297
    //
298
 
298
 
299
    return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
299
    return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
300
}
300
}
301
 
301
 
302
EFI_DEVICE_PATH *
302
EFI_DEVICE_PATH *
303
DuplicateDevicePath (
303
DuplicateDevicePath (
304
    IN EFI_DEVICE_PATH  *DevPath
304
    IN EFI_DEVICE_PATH  *DevPath
305
    )
305
    )
306
{
306
{
307
    EFI_DEVICE_PATH     *NewDevPath;
307
    EFI_DEVICE_PATH     *NewDevPath;
308
    UINTN               Size;    
308
    UINTN               Size;    
309
 
309
 
310
 
310
 
311
    //
311
    //
312
    // Compute the size
312
    // Compute the size
313
    //
313
    //
314
 
314
 
315
    Size = DevicePathSize (DevPath);
315
    Size = DevicePathSize (DevPath);
316
 
316
 
317
    //
317
    //
318
    // Make a copy
318
    // Make a copy
319
    //
319
    //
320
 
320
 
321
    NewDevPath = AllocatePool (Size);
321
    NewDevPath = AllocatePool (Size);
322
    if (NewDevPath) {
322
    if (NewDevPath) {
323
        CopyMem (NewDevPath, DevPath, Size);
323
        CopyMem (NewDevPath, DevPath, Size);
324
    }
324
    }
325
 
325
 
326
    return NewDevPath;
326
    return NewDevPath;
327
}
327
}
328
 
328
 
329
EFI_DEVICE_PATH *
329
EFI_DEVICE_PATH *
330
UnpackDevicePath (
330
UnpackDevicePath (
331
    IN EFI_DEVICE_PATH  *DevPath
331
    IN EFI_DEVICE_PATH  *DevPath
332
    )
332
    )
333
{
333
{
334
    EFI_DEVICE_PATH     *Src, *Dest, *NewPath;
334
    EFI_DEVICE_PATH     *Src, *Dest, *NewPath;
335
    UINTN               Size;
335
    UINTN               Size;
336
   
336
   
337
    //
337
    //
338
    // Walk device path and round sizes to valid boundries
338
    // Walk device path and round sizes to valid boundries
339
    //    
339
    //    
340
 
340
 
341
    Src = DevPath;
341
    Src = DevPath;
342
    Size = 0;
342
    Size = 0;
343
    for (; ;) {
343
    for (; ;) {
344
        Size += DevicePathNodeLength(Src);
344
        Size += DevicePathNodeLength(Src);
345
        Size += ALIGN_SIZE(Size);
345
        Size += ALIGN_SIZE(Size);
346
 
346
 
347
        if (IsDevicePathEnd(Src)) {
347
        if (IsDevicePathEnd(Src)) {
348
            break;
348
            break;
349
        }
349
        }
350
 
350
 
351
        Src = NextDevicePathNode(Src);
351
        Src = NextDevicePathNode(Src);
352
    }
352
    }
353
 
353
 
354
 
354
 
355
    //
355
    //
356
    // Allocate space for the unpacked path
356
    // Allocate space for the unpacked path
357
    //
357
    //
358
 
358
 
359
    NewPath = AllocateZeroPool (Size);
359
    NewPath = AllocateZeroPool (Size);
360
    if (NewPath) {
360
    if (NewPath) {
361
 
361
 
362
        ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);
362
        ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);
363
 
363
 
364
        //
364
        //
365
        // Copy each node
365
        // Copy each node
366
        //
366
        //
367
 
367
 
368
        Src = DevPath;
368
        Src = DevPath;
369
        Dest = NewPath;
369
        Dest = NewPath;
370
        for (; ;) {
370
        for (; ;) {
371
            Size = DevicePathNodeLength(Src);
371
            Size = DevicePathNodeLength(Src);
372
            CopyMem (Dest, Src, Size);
372
            CopyMem (Dest, Src, Size);
373
            Size += ALIGN_SIZE(Size);
373
            Size += ALIGN_SIZE(Size);
374
            SetDevicePathNodeLength (Dest, Size);
374
            SetDevicePathNodeLength (Dest, Size);
375
            Dest->Type |= EFI_DP_TYPE_UNPACKED;
375
            Dest->Type |= EFI_DP_TYPE_UNPACKED;
376
            Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);
376
            Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);
377
 
377
 
378
            if (IsDevicePathEnd(Src)) {
378
            if (IsDevicePathEnd(Src)) {
379
                break;
379
                break;
380
            }
380
            }
381
 
381
 
382
            Src = NextDevicePathNode(Src);
382
            Src = NextDevicePathNode(Src);
383
        }
383
        }
384
    }
384
    }
385
 
385
 
386
    return NewPath;
386
    return NewPath;
387
}
387
}
388
 
388
 
389
 
389
 
390
EFI_DEVICE_PATH*
390
EFI_DEVICE_PATH*
391
AppendDevicePathInstance (
391
AppendDevicePathInstance (
392
    IN EFI_DEVICE_PATH  *Src,
392
    IN EFI_DEVICE_PATH  *Src,
393
    IN EFI_DEVICE_PATH  *Instance
393
    IN EFI_DEVICE_PATH  *Instance
394
    )
394
    )
395
{
395
{
396
    UINT8           *Ptr;
396
    UINT8           *Ptr;
397
    EFI_DEVICE_PATH *DevPath;
397
    EFI_DEVICE_PATH *DevPath;
398
    UINTN           SrcSize;
398
    UINTN           SrcSize;
399
    UINTN           InstanceSize;
399
    UINTN           InstanceSize;
400
 
400
 
401
    if (Src == NULL) {
401
    if (Src == NULL) {
402
        return DuplicateDevicePath (Instance);
402
        return DuplicateDevicePath (Instance);
403
    }
403
    }
404
    SrcSize = DevicePathSize(Src);
404
    SrcSize = DevicePathSize(Src);
405
    InstanceSize = DevicePathSize(Instance);
405
    InstanceSize = DevicePathSize(Instance);
406
    Ptr = AllocatePool (SrcSize + InstanceSize);
406
    Ptr = AllocatePool (SrcSize + InstanceSize);
407
    DevPath = (EFI_DEVICE_PATH *)Ptr;
407
    DevPath = (EFI_DEVICE_PATH *)Ptr;
408
    ASSERT(DevPath);
408
    ASSERT(DevPath);
409
 
409
 
410
    CopyMem (Ptr, Src, SrcSize);
410
    CopyMem (Ptr, Src, SrcSize);
411
//    FreePool (Src);
411
//    FreePool (Src);
412
   
412
   
413
    while (!IsDevicePathEnd(DevPath)) {
413
    while (!IsDevicePathEnd(DevPath)) {
414
        DevPath = NextDevicePathNode(DevPath);
414
        DevPath = NextDevicePathNode(DevPath);
415
    }
415
    }
416
    //
416
    //
417
    // Convert the End to an End Instance, since we are
417
    // Convert the End to an End Instance, since we are
418
    //  appending another instacne after this one its a good
418
    //  appending another instacne after this one its a good
419
    //  idea.
419
    //  idea.
420
    //
420
    //
421
    DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
421
    DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
422
   
422
   
423
    DevPath = NextDevicePathNode(DevPath);
423
    DevPath = NextDevicePathNode(DevPath);
424
    CopyMem (DevPath, Instance, InstanceSize);
424
    CopyMem (DevPath, Instance, InstanceSize);
425
    return (EFI_DEVICE_PATH *)Ptr;
425
    return (EFI_DEVICE_PATH *)Ptr;
426
}
426
}
427
 
427
 
428
EFI_STATUS
428
EFI_STATUS
429
LibDevicePathToInterface (
429
LibDevicePathToInterface (
430
    IN EFI_GUID             *Protocol,
430
    IN EFI_GUID             *Protocol,
431
    IN EFI_DEVICE_PATH      *FilePath,
431
    IN EFI_DEVICE_PATH      *FilePath,
432
    OUT VOID                **Interface
432
    OUT VOID                **Interface
433
    )
433
    )
434
{
434
{
435
    EFI_STATUS              Status;
435
    EFI_STATUS              Status;
436
    EFI_HANDLE              Device;
436
    EFI_HANDLE              Device;
437
 
437
 
438
    Status = BS->LocateDevicePath (Protocol, &FilePath, &Device);
438
    Status = BS->LocateDevicePath (Protocol, &FilePath, &Device);
439
 
439
 
440
    if (!EFI_ERROR(Status)) {
440
    if (!EFI_ERROR(Status)) {
441
 
441
 
442
        // If we didn't get a direct match return not found
442
        // If we didn't get a direct match return not found
443
        Status = EFI_NOT_FOUND;
443
        Status = EFI_NOT_FOUND;
444
 
444
 
445
        if (IsDevicePathEnd(FilePath)) {
445
        if (IsDevicePathEnd(FilePath)) {
446
 
446
 
447
            //
447
            //
448
            // It was a direct match, lookup the protocol interface
448
            // It was a direct match, lookup the protocol interface
449
            //
449
            //
450
 
450
 
451
            Status = BS->HandleProtocol (Device, Protocol, Interface);
451
            Status = BS->HandleProtocol (Device, Protocol, Interface);
452
        }
452
        }
453
    }
453
    }
454
 
454
 
455
    //
455
    //
456
    // If there was an error, do not return an interface
456
    // If there was an error, do not return an interface
457
    //
457
    //
458
 
458
 
459
    if (EFI_ERROR(Status)) {
459
    if (EFI_ERROR(Status)) {
460
        *Interface = NULL;
460
        *Interface = NULL;
461
    }
461
    }
462
 
462
 
463
    return Status;
463
    return Status;
464
}
464
}
465
 
465
 
466
VOID
466
VOID
467
_DevPathPci (
467
_DevPathPci (
468
    IN OUT POOL_PRINT       *Str,
468
    IN OUT POOL_PRINT       *Str,
469
    IN VOID                 *DevPath
469
    IN VOID                 *DevPath
470
    )
470
    )
471
{
471
{
472
    PCI_DEVICE_PATH         *Pci;
472
    PCI_DEVICE_PATH         *Pci;
473
 
473
 
474
    Pci = DevPath;
474
    Pci = DevPath;
475
    CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
475
    CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
476
}
476
}
477
 
477
 
478
VOID
478
VOID
479
_DevPathPccard (
479
_DevPathPccard (
480
    IN OUT POOL_PRINT       *Str,
480
    IN OUT POOL_PRINT       *Str,
481
    IN VOID                 *DevPath
481
    IN VOID                 *DevPath
482
    )
482
    )
483
{
483
{
484
    PCCARD_DEVICE_PATH      *Pccard;
484
    PCCARD_DEVICE_PATH      *Pccard;
485
 
485
 
486
    Pccard = DevPath;  
486
    Pccard = DevPath;  
487
    CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber);
487
    CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber);
488
}
488
}
489
 
489
 
490
VOID
490
VOID
491
_DevPathMemMap (
491
_DevPathMemMap (
492
    IN OUT POOL_PRINT       *Str,
492
    IN OUT POOL_PRINT       *Str,
493
    IN VOID                 *DevPath
493
    IN VOID                 *DevPath
494
    )
494
    )
495
{
495
{
496
    MEMMAP_DEVICE_PATH      *MemMap;
496
    MEMMAP_DEVICE_PATH      *MemMap;
497
 
497
 
498
    MemMap = DevPath;  
498
    MemMap = DevPath;  
499
    CatPrint(Str, L"MemMap(%d:%x-%x)",
499
    CatPrint(Str, L"MemMap(%d:%x-%x)",
500
        MemMap->MemoryType,
500
        MemMap->MemoryType,
501
        MemMap->StartingAddress,
501
        MemMap->StartingAddress,
502
        MemMap->EndingAddress
502
        MemMap->EndingAddress
503
        );
503
        );
504
}
504
}
505
 
505
 
506
VOID
506
VOID
507
_DevPathController (
507
_DevPathController (
508
    IN OUT POOL_PRINT       *Str,
508
    IN OUT POOL_PRINT       *Str,
509
    IN VOID                 *DevPath
509
    IN VOID                 *DevPath
510
    )
510
    )
511
{
511
{
512
    CONTROLLER_DEVICE_PATH  *Controller;
512
    CONTROLLER_DEVICE_PATH  *Controller;
513
 
513
 
514
    Controller = DevPath;
514
    Controller = DevPath;
515
    CatPrint(Str, L"Ctrl(%d)",
515
    CatPrint(Str, L"Ctrl(%d)",
516
        Controller->Controller
516
        Controller->Controller
517
        );
517
        );
518
}
518
}
519
 
519
 
520
VOID
520
VOID
521
_DevPathVendor (
521
_DevPathVendor (
522
    IN OUT POOL_PRINT       *Str,
522
    IN OUT POOL_PRINT       *Str,
523
    IN VOID                 *DevPath
523
    IN VOID                 *DevPath
524
    )
524
    )
525
{
525
{
526
    VENDOR_DEVICE_PATH                  *Vendor;
526
    VENDOR_DEVICE_PATH                  *Vendor;
527
    CHAR16                              *Type;
527
    CHAR16                              *Type;
528
    UNKNOWN_DEVICE_VENDOR_DEVICE_PATH   *UnknownDevPath;
528
    UNKNOWN_DEVICE_VENDOR_DEVICE_PATH   *UnknownDevPath;
529
 
529
 
530
    Vendor = DevPath;
530
    Vendor = DevPath;
531
    switch (DevicePathType(&Vendor->Header)) {
531
    switch (DevicePathType(&Vendor->Header)) {
532
    case HARDWARE_DEVICE_PATH:  Type = L"Hw";        break;
532
    case HARDWARE_DEVICE_PATH:  Type = L"Hw";        break;
533
    case MESSAGING_DEVICE_PATH: Type = L"Msg";       break;
533
    case MESSAGING_DEVICE_PATH: Type = L"Msg";       break;
534
    case MEDIA_DEVICE_PATH:     Type = L"Media";     break;
534
    case MEDIA_DEVICE_PATH:     Type = L"Media";     break;
535
    default:                    Type = L"?";         break;
535
    default:                    Type = L"?";         break;
536
    }                            
536
    }                            
537
 
537
 
538
    CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
538
    CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
539
    if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
539
    if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
540
        //
540
        //
541
        // GUID used by EFI to enumerate an EDD 1.1 device
541
        // GUID used by EFI to enumerate an EDD 1.1 device
542
        //
542
        //
543
        UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
543
        UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
544
        CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
544
        CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
545
    } else {
545
    } else {
546
        CatPrint(Str, L")");
546
        CatPrint(Str, L")");
547
    }
547
    }
548
}
548
}
549
 
549
 
550
 
550
 
551
VOID
551
VOID
552
_DevPathAcpi (
552
_DevPathAcpi (
553
    IN OUT POOL_PRINT       *Str,
553
    IN OUT POOL_PRINT       *Str,
554
    IN VOID                 *DevPath
554
    IN VOID                 *DevPath
555
    )
555
    )
556
{
556
{
557
    ACPI_HID_DEVICE_PATH        *Acpi;
557
    ACPI_HID_DEVICE_PATH        *Acpi;
558
 
558
 
559
    Acpi = DevPath;
559
    Acpi = DevPath;
560
    if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
560
    if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
561
        CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
561
        CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
562
    } else {
562
    } else {
563
        CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
563
        CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
564
    }
564
    }
565
}
565
}
566
 
566
 
567
 
567
 
568
VOID
568
VOID
569
_DevPathAtapi (
569
_DevPathAtapi (
570
    IN OUT POOL_PRINT       *Str,
570
    IN OUT POOL_PRINT       *Str,
571
    IN VOID                 *DevPath
571
    IN VOID                 *DevPath
572
    )
572
    )
573
{
573
{
574
    ATAPI_DEVICE_PATH       *Atapi;
574
    ATAPI_DEVICE_PATH       *Atapi;
575
 
575
 
576
    Atapi = DevPath;
576
    Atapi = DevPath;
577
    CatPrint(Str, L"Ata(%s,%s)",
577
    CatPrint(Str, L"Ata(%s,%s)",
578
        Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
578
        Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
579
        Atapi->SlaveMaster ? L"Slave" : L"Master"
579
        Atapi->SlaveMaster ? L"Slave" : L"Master"
580
        );
580
        );
581
}
581
}
582
 
582
 
583
VOID
583
VOID
584
_DevPathScsi (
584
_DevPathScsi (
585
    IN OUT POOL_PRINT       *Str,
585
    IN OUT POOL_PRINT       *Str,
586
    IN VOID                 *DevPath
586
    IN VOID                 *DevPath
587
    )
587
    )
588
{
588
{
589
    SCSI_DEVICE_PATH        *Scsi;
589
    SCSI_DEVICE_PATH        *Scsi;
590
 
590
 
591
    Scsi = DevPath;
591
    Scsi = DevPath;
592
    CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
592
    CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
593
}
593
}
594
 
594
 
595
 
595
 
596
VOID
596
VOID
597
_DevPathFibre (
597
_DevPathFibre (
598
    IN OUT POOL_PRINT       *Str,
598
    IN OUT POOL_PRINT       *Str,
599
    IN VOID                 *DevPath
599
    IN VOID                 *DevPath
600
    )
600
    )
601
{
601
{
602
    FIBRECHANNEL_DEVICE_PATH    *Fibre;
602
    FIBRECHANNEL_DEVICE_PATH    *Fibre;
603
 
603
 
604
    Fibre = DevPath;
604
    Fibre = DevPath;
605
    CatPrint(Str, L"Fibre(%lx)", Fibre->WWN);
605
    CatPrint(Str, L"Fibre(%lx)", Fibre->WWN);
606
}
606
}
607
 
607
 
608
VOID
608
VOID
609
_DevPath1394 (
609
_DevPath1394 (
610
    IN OUT POOL_PRINT       *Str,
610
    IN OUT POOL_PRINT       *Str,
611
    IN VOID                 *DevPath
611
    IN VOID                 *DevPath
612
    )
612
    )
613
{
613
{
614
    F1394_DEVICE_PATH       *F1394;
614
    F1394_DEVICE_PATH       *F1394;
615
 
615
 
616
    F1394 = DevPath;
616
    F1394 = DevPath;
617
    CatPrint(Str, L"1394(%g)", &F1394->Guid);
617
    CatPrint(Str, L"1394(%g)", &F1394->Guid);
618
}
618
}
619
 
619
 
620
 
620
 
621
 
621
 
622
VOID
622
VOID
623
_DevPathUsb (
623
_DevPathUsb (
624
    IN OUT POOL_PRINT       *Str,
624
    IN OUT POOL_PRINT       *Str,
625
    IN VOID                 *DevPath
625
    IN VOID                 *DevPath
626
    )
626
    )
627
{
627
{
628
    USB_DEVICE_PATH         *Usb;
628
    USB_DEVICE_PATH         *Usb;
629
 
629
 
630
    Usb = DevPath;
630
    Usb = DevPath;
631
    CatPrint(Str, L"Usb(%x)", Usb->Port);
631
    CatPrint(Str, L"Usb(%x)", Usb->Port);
632
}
632
}
633
 
633
 
634
 
634
 
635
VOID
635
VOID
636
_DevPathI2O (
636
_DevPathI2O (
637
    IN OUT POOL_PRINT       *Str,
637
    IN OUT POOL_PRINT       *Str,
638
    IN VOID                 *DevPath
638
    IN VOID                 *DevPath
639
    )
639
    )
640
{
640
{
641
    I2O_DEVICE_PATH         *I2O;
641
    I2O_DEVICE_PATH         *I2O;
642
 
642
 
643
    I2O = DevPath;
643
    I2O = DevPath;
644
    CatPrint(Str, L"I2O(%x)", I2O->Tid);
644
    CatPrint(Str, L"I2O(%x)", I2O->Tid);
645
}
645
}
646
 
646
 
647
VOID
647
VOID
648
_DevPathMacAddr (
648
_DevPathMacAddr (
649
    IN OUT POOL_PRINT       *Str,
649
    IN OUT POOL_PRINT       *Str,
650
    IN VOID                 *DevPath
650
    IN VOID                 *DevPath
651
    )
651
    )
652
{
652
{
653
    MAC_ADDR_DEVICE_PATH    *MAC;
653
    MAC_ADDR_DEVICE_PATH    *MAC;
654
    UINTN                   HwAddressSize;
654
    UINTN                   HwAddressSize;
655
    UINTN                   Index;
655
    UINTN                   Index;
656
 
656
 
657
    MAC = DevPath;
657
    MAC = DevPath;
658
 
658
 
659
    HwAddressSize = sizeof(EFI_MAC_ADDRESS);
659
    HwAddressSize = sizeof(EFI_MAC_ADDRESS);
660
    if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
660
    if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
661
        HwAddressSize = 6;
661
        HwAddressSize = 6;
662
    }
662
    }
663
   
663
   
664
    CatPrint(Str, L"Mac(");
664
    CatPrint(Str, L"Mac(");
665
 
665
 
666
    for(Index = 0; Index < HwAddressSize; Index++) {
666
    for(Index = 0; Index < HwAddressSize; Index++) {
667
        CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
667
        CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
668
    }
668
    }
669
    CatPrint(Str, L")");
669
    CatPrint(Str, L")");
670
}
670
}
671
 
671
 
672
VOID
672
VOID
673
_DevPathIPv4 (
673
_DevPathIPv4 (
674
    IN OUT POOL_PRINT       *Str,
674
    IN OUT POOL_PRINT       *Str,
675
    IN VOID                 *DevPath
675
    IN VOID                 *DevPath
676
    )
676
    )
677
{
677
{
678
    IPv4_DEVICE_PATH     *IP;
678
    IPv4_DEVICE_PATH     *IP;
679
 
679
 
680
    IP = DevPath;
680
    IP = DevPath;
681
    CatPrint(Str, L"IPv4(not-done)");
681
    CatPrint(Str, L"IPv4(not-done)");
682
}
682
}
683
 
683
 
684
VOID
684
VOID
685
_DevPathIPv6 (
685
_DevPathIPv6 (
686
    IN OUT POOL_PRINT       *Str,
686
    IN OUT POOL_PRINT       *Str,
687
    IN VOID                 *DevPath
687
    IN VOID                 *DevPath
688
    )
688
    )
689
{
689
{
690
    IPv6_DEVICE_PATH     *IP;
690
    IPv6_DEVICE_PATH     *IP;
691
 
691
 
692
    IP = DevPath;
692
    IP = DevPath;
693
    CatPrint(Str, L"IP-v6(not-done)");
693
    CatPrint(Str, L"IP-v6(not-done)");
694
}
694
}
695
 
695
 
696
VOID
696
VOID
697
_DevPathInfiniBand (
697
_DevPathInfiniBand (
698
    IN OUT POOL_PRINT       *Str,
698
    IN OUT POOL_PRINT       *Str,
699
    IN VOID                 *DevPath
699
    IN VOID                 *DevPath
700
    )
700
    )
701
{
701
{
702
    INFINIBAND_DEVICE_PATH  *InfiniBand;
702
    INFINIBAND_DEVICE_PATH  *InfiniBand;
703
 
703
 
704
    InfiniBand = DevPath;
704
    InfiniBand = DevPath;
705
    CatPrint(Str, L"InfiniBand(not-done)");
705
    CatPrint(Str, L"InfiniBand(not-done)");
706
}
706
}
707
 
707
 
708
VOID
708
VOID
709
_DevPathUart (
709
_DevPathUart (
710
    IN OUT POOL_PRINT       *Str,
710
    IN OUT POOL_PRINT       *Str,
711
    IN VOID                 *DevPath
711
    IN VOID                 *DevPath
712
    )
712
    )
713
{
713
{
714
    UART_DEVICE_PATH  *Uart;
714
    UART_DEVICE_PATH  *Uart;
715
    CHAR8             Parity;
715
    CHAR8             Parity;
716
 
716
 
717
    Uart = DevPath;
717
    Uart = DevPath;
718
    switch (Uart->Parity) {
718
    switch (Uart->Parity) {
719
        case 0  : Parity = 'D'; break;
719
        case 0  : Parity = 'D'; break;
720
        case 1  : Parity = 'N'; break;
720
        case 1  : Parity = 'N'; break;
721
        case 2  : Parity = 'E'; break;
721
        case 2  : Parity = 'E'; break;
722
        case 3  : Parity = 'O'; break;
722
        case 3  : Parity = 'O'; break;
723
        case 4  : Parity = 'M'; break;
723
        case 4  : Parity = 'M'; break;
724
        case 5  : Parity = 'S'; break;
724
        case 5  : Parity = 'S'; break;
725
        default : Parity = 'x'; break;
725
        default : Parity = 'x'; break;
726
    }
726
    }
727
 
727
 
728
    if (Uart->BaudRate == 0) {
728
    if (Uart->BaudRate == 0) {
729
        CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
729
        CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
730
    } else {
730
    } else {
731
        CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
731
        CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
732
    }
732
    }
733
 
733
 
734
    if (Uart->DataBits == 0) {
734
    if (Uart->DataBits == 0) {
735
        CatPrint(Str, L"D");
735
        CatPrint(Str, L"D");
736
    } else {
736
    } else {
737
        CatPrint(Str, L"%d",Uart->DataBits);
737
        CatPrint(Str, L"%d",Uart->DataBits);
738
    }
738
    }
739
 
739
 
740
    switch (Uart->StopBits) {
740
    switch (Uart->StopBits) {
741
        case 0  : CatPrint(Str, L"D)");   break;
741
        case 0  : CatPrint(Str, L"D)");   break;
742
        case 1  : CatPrint(Str, L"1)");   break;
742
        case 1  : CatPrint(Str, L"1)");   break;
743
        case 2  : CatPrint(Str, L"1.5)"); break;
743
        case 2  : CatPrint(Str, L"1.5)"); break;
744
        case 3  : CatPrint(Str, L"2)");   break;
744
        case 3  : CatPrint(Str, L"2)");   break;
745
        default : CatPrint(Str, L"x)");   break;
745
        default : CatPrint(Str, L"x)");   break;
746
    }
746
    }
747
}
747
}
748
 
748
 
749
 
749
 
750
VOID
750
VOID
751
_DevPathHardDrive (
751
_DevPathHardDrive (
752
    IN OUT POOL_PRINT       *Str,
752
    IN OUT POOL_PRINT       *Str,
753
    IN VOID                 *DevPath
753
    IN VOID                 *DevPath
754
    )
754
    )
755
{
755
{
756
    HARDDRIVE_DEVICE_PATH   *Hd;
756
    HARDDRIVE_DEVICE_PATH   *Hd;
757
 
757
 
758
    Hd = DevPath;
758
    Hd = DevPath;
759
    switch (Hd->SignatureType) {
759
    switch (Hd->SignatureType) {
760
        case SIGNATURE_TYPE_MBR:
760
        case SIGNATURE_TYPE_MBR:
761
            CatPrint(Str, L"HD(Part%d,Sig%08X)",
761
            CatPrint(Str, L"HD(Part%d,Sig%08X)",
762
                Hd->PartitionNumber,
762
                Hd->PartitionNumber,
763
                *((UINT32 *)(&(Hd->Signature[0])))
763
                *((UINT32 *)(&(Hd->Signature[0])))
764
                );
764
                );
765
            break;
765
            break;
766
        case SIGNATURE_TYPE_GUID:
766
        case SIGNATURE_TYPE_GUID:
767
            CatPrint(Str, L"HD(Part%d,Sig%g)",
767
            CatPrint(Str, L"HD(Part%d,Sig%g)",
768
                Hd->PartitionNumber,
768
                Hd->PartitionNumber,
769
                (EFI_GUID *) &(Hd->Signature[0])    
769
                (EFI_GUID *) &(Hd->Signature[0])    
770
                );
770
                );
771
            break;
771
            break;
772
        default:
772
        default:
773
            CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
773
            CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
774
                Hd->PartitionNumber,
774
                Hd->PartitionNumber,
775
                Hd->MBRType,
775
                Hd->MBRType,
776
                Hd->SignatureType
776
                Hd->SignatureType
777
                );
777
                );
778
            break;
778
            break;
779
    }
779
    }
780
}
780
}
781
 
781
 
782
VOID
782
VOID
783
_DevPathCDROM (
783
_DevPathCDROM (
784
    IN OUT POOL_PRINT       *Str,
784
    IN OUT POOL_PRINT       *Str,
785
    IN VOID                 *DevPath
785
    IN VOID                 *DevPath
786
    )
786
    )
787
{
787
{
788
    CDROM_DEVICE_PATH       *Cd;
788
    CDROM_DEVICE_PATH       *Cd;
789
 
789
 
790
    Cd = DevPath;
790
    Cd = DevPath;
791
    CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry);
791
    CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry);
792
}
792
}
793
 
793
 
794
VOID
794
VOID
795
_DevPathFilePath (
795
_DevPathFilePath (
796
    IN OUT POOL_PRINT       *Str,
796
    IN OUT POOL_PRINT       *Str,
797
    IN VOID                 *DevPath
797
    IN VOID                 *DevPath
798
    )
798
    )
799
{
799
{
800
    FILEPATH_DEVICE_PATH    *Fp;  
800
    FILEPATH_DEVICE_PATH    *Fp;  
801
 
801
 
802
    Fp = DevPath;
802
    Fp = DevPath;
803
    CatPrint(Str, L"%s", Fp->PathName);
803
    CatPrint(Str, L"%s", Fp->PathName);
804
}
804
}
805
 
805
 
806
VOID
806
VOID
807
_DevPathMediaProtocol (
807
_DevPathMediaProtocol (
808
    IN OUT POOL_PRINT       *Str,
808
    IN OUT POOL_PRINT       *Str,
809
    IN VOID                 *DevPath
809
    IN VOID                 *DevPath
810
    )
810
    )
811
{
811
{
812
    MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
812
    MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
813
 
813
 
814
    MediaProt = DevPath;
814
    MediaProt = DevPath;
815
    CatPrint(Str, L"%g", &MediaProt->Protocol);
815
    CatPrint(Str, L"%g", &MediaProt->Protocol);
816
}
816
}
817
 
817
 
818
VOID
818
VOID
819
_DevPathBssBss (
819
_DevPathBssBss (
820
    IN OUT POOL_PRINT       *Str,
820
    IN OUT POOL_PRINT       *Str,
821
    IN VOID                 *DevPath
821
    IN VOID                 *DevPath
822
    )
822
    )
823
{
823
{
824
    BBS_BBS_DEVICE_PATH     *Bss;
824
    BBS_BBS_DEVICE_PATH     *Bss;
825
    CHAR16                  *Type;
825
    CHAR16                  *Type;
826
 
826
 
827
    Bss = DevPath;
827
    Bss = DevPath;
828
    switch (Bss->DeviceType) {
828
    switch (Bss->DeviceType) {
829
    case BBS_TYPE_FLOPPY:               Type = L"Floppy";       break;
829
    case BBS_TYPE_FLOPPY:               Type = L"Floppy";       break;
830
    case BBS_TYPE_HARDDRIVE:            Type = L"Harddrive";    break;
830
    case BBS_TYPE_HARDDRIVE:            Type = L"Harddrive";    break;
831
    case BBS_TYPE_CDROM:                Type = L"CDROM";        break;
831
    case BBS_TYPE_CDROM:                Type = L"CDROM";        break;
832
    case BBS_TYPE_PCMCIA:               Type = L"PCMCIA";       break;
832
    case BBS_TYPE_PCMCIA:               Type = L"PCMCIA";       break;
833
    case BBS_TYPE_USB:                  Type = L"Usb";          break;
833
    case BBS_TYPE_USB:                  Type = L"Usb";          break;
834
    case BBS_TYPE_EMBEDDED_NETWORK:     Type = L"Net";          break;
834
    case BBS_TYPE_EMBEDDED_NETWORK:     Type = L"Net";          break;
835
    default:                            Type = L"?";            break;
835
    default:                            Type = L"?";            break;
836
    }
836
    }
837
 
837
 
838
    CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
838
    CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
839
}
839
}
840
 
840
 
841
 
841
 
842
VOID
842
VOID
843
_DevPathEndInstance (
843
_DevPathEndInstance (
844
    IN OUT POOL_PRINT       *Str,
844
    IN OUT POOL_PRINT       *Str,
845
    IN VOID                 *DevPath
845
    IN VOID                 *DevPath
846
    )
846
    )
847
{
847
{
848
    CatPrint(Str, L",");
848
    CatPrint(Str, L",");
849
}
849
}
850
 
850
 
851
VOID
851
VOID
852
_DevPathNodeUnknown (
852
_DevPathNodeUnknown (
853
    IN OUT POOL_PRINT       *Str,
853
    IN OUT POOL_PRINT       *Str,
854
    IN VOID                 *DevPath
854
    IN VOID                 *DevPath
855
    )
855
    )
856
{
856
{
857
    CatPrint(Str, L"?");
857
    CatPrint(Str, L"?");
858
}
858
}
859
 
859
 
860
 
860
 
861
struct {
861
struct {
862
    UINT8   Type;
862
    UINT8   Type;
863
    UINT8   SubType;
863
    UINT8   SubType;
864
    VOID    (*Function)(POOL_PRINT *, VOID *);    
864
    VOID    (*Function)(POOL_PRINT *, VOID *);    
865
} DevPathTable[] = {
865
} DevPathTable[] = {
866
    { HARDWARE_DEVICE_PATH,   HW_PCI_DP,                        _DevPathPci},
866
    { HARDWARE_DEVICE_PATH,   HW_PCI_DP,                        _DevPathPci},
867
    { HARDWARE_DEVICE_PATH,   HW_PCCARD_DP,                     _DevPathPccard},
867
    { HARDWARE_DEVICE_PATH,   HW_PCCARD_DP,                     _DevPathPccard},
868
    { HARDWARE_DEVICE_PATH,   HW_MEMMAP_DP,                     _DevPathMemMap},
868
    { HARDWARE_DEVICE_PATH,   HW_MEMMAP_DP,                     _DevPathMemMap},
869
    { HARDWARE_DEVICE_PATH,   HW_VENDOR_DP,                     _DevPathVendor},
869
    { HARDWARE_DEVICE_PATH,   HW_VENDOR_DP,                     _DevPathVendor},
870
    { HARDWARE_DEVICE_PATH,   HW_CONTROLLER_DP,                 _DevPathController},
870
    { HARDWARE_DEVICE_PATH,   HW_CONTROLLER_DP,                 _DevPathController},
871
    { ACPI_DEVICE_PATH,       ACPI_DP,                          _DevPathAcpi},
871
    { ACPI_DEVICE_PATH,       ACPI_DP,                          _DevPathAcpi},
872
    { MESSAGING_DEVICE_PATH,  MSG_ATAPI_DP,                     _DevPathAtapi},
872
    { MESSAGING_DEVICE_PATH,  MSG_ATAPI_DP,                     _DevPathAtapi},
873
    { MESSAGING_DEVICE_PATH,  MSG_SCSI_DP,                      _DevPathScsi},
873
    { MESSAGING_DEVICE_PATH,  MSG_SCSI_DP,                      _DevPathScsi},
874
    { MESSAGING_DEVICE_PATH,  MSG_FIBRECHANNEL_DP,              _DevPathFibre},
874
    { MESSAGING_DEVICE_PATH,  MSG_FIBRECHANNEL_DP,              _DevPathFibre},
875
    { MESSAGING_DEVICE_PATH,  MSG_1394_DP,                      _DevPath1394},
875
    { MESSAGING_DEVICE_PATH,  MSG_1394_DP,                      _DevPath1394},
876
    { MESSAGING_DEVICE_PATH,  MSG_USB_DP,                       _DevPathUsb},
876
    { MESSAGING_DEVICE_PATH,  MSG_USB_DP,                       _DevPathUsb},
877
    { MESSAGING_DEVICE_PATH,  MSG_I2O_DP,                       _DevPathI2O},
877
    { MESSAGING_DEVICE_PATH,  MSG_I2O_DP,                       _DevPathI2O},
878
    { MESSAGING_DEVICE_PATH,  MSG_MAC_ADDR_DP,                  _DevPathMacAddr},
878
    { MESSAGING_DEVICE_PATH,  MSG_MAC_ADDR_DP,                  _DevPathMacAddr},
879
    { MESSAGING_DEVICE_PATH,  MSG_IPv4_DP,                      _DevPathIPv4},
879
    { MESSAGING_DEVICE_PATH,  MSG_IPv4_DP,                      _DevPathIPv4},
880
    { MESSAGING_DEVICE_PATH,  MSG_IPv6_DP,                      _DevPathIPv6},
880
    { MESSAGING_DEVICE_PATH,  MSG_IPv6_DP,                      _DevPathIPv6},
881
    { MESSAGING_DEVICE_PATH,  MSG_INFINIBAND_DP,                _DevPathInfiniBand},
881
    { MESSAGING_DEVICE_PATH,  MSG_INFINIBAND_DP,                _DevPathInfiniBand},
882
    { MESSAGING_DEVICE_PATH,  MSG_UART_DP,                      _DevPathUart},
882
    { MESSAGING_DEVICE_PATH,  MSG_UART_DP,                      _DevPathUart},
883
    { MESSAGING_DEVICE_PATH,  MSG_VENDOR_DP,                    _DevPathVendor},
883
    { MESSAGING_DEVICE_PATH,  MSG_VENDOR_DP,                    _DevPathVendor},
884
    { MEDIA_DEVICE_PATH,      MEDIA_HARDDRIVE_DP,               _DevPathHardDrive},
884
    { MEDIA_DEVICE_PATH,      MEDIA_HARDDRIVE_DP,               _DevPathHardDrive},
885
    { MEDIA_DEVICE_PATH,      MEDIA_CDROM_DP,                   _DevPathCDROM},
885
    { MEDIA_DEVICE_PATH,      MEDIA_CDROM_DP,                   _DevPathCDROM},
886
    { MEDIA_DEVICE_PATH,      MEDIA_VENDOR_DP,                  _DevPathVendor},
886
    { MEDIA_DEVICE_PATH,      MEDIA_VENDOR_DP,                  _DevPathVendor},
887
    { MEDIA_DEVICE_PATH,      MEDIA_FILEPATH_DP,                _DevPathFilePath},
887
    { MEDIA_DEVICE_PATH,      MEDIA_FILEPATH_DP,                _DevPathFilePath},
888
    { MEDIA_DEVICE_PATH,      MEDIA_PROTOCOL_DP,                _DevPathMediaProtocol},
888
    { MEDIA_DEVICE_PATH,      MEDIA_PROTOCOL_DP,                _DevPathMediaProtocol},
889
    { BBS_DEVICE_PATH,        BBS_BBS_DP,                       _DevPathBssBss},
889
    { BBS_DEVICE_PATH,        BBS_BBS_DP,                       _DevPathBssBss},
890
    { END_DEVICE_PATH_TYPE,   END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
890
    { END_DEVICE_PATH_TYPE,   END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
891
    { 0,                      0,                          NULL}
891
    { 0,                      0,                          NULL}
892
};
892
};
893
 
893
 
894
 
894
 
895
CHAR16 *
895
CHAR16 *
896
DevicePathToStr (
896
DevicePathToStr (
897
    EFI_DEVICE_PATH     *DevPath
897
    EFI_DEVICE_PATH     *DevPath
898
    )
898
    )
899
/*++
899
/*++
900
 
900
 
901
    Turns the Device Path into a printable string.  Allcoates
901
    Turns the Device Path into a printable string.  Allcoates
902
    the string from pool.  The caller must FreePool the returned
902
    the string from pool.  The caller must FreePool the returned
903
    string.
903
    string.
904
 
904
 
905
--*/
905
--*/
906
{
906
{
907
    POOL_PRINT          Str;
907
    POOL_PRINT          Str;
908
    EFI_DEVICE_PATH     *DevPathNode;
908
    EFI_DEVICE_PATH     *DevPathNode;
909
    VOID                (*DumpNode)(POOL_PRINT *, VOID *);    
909
    VOID                (*DumpNode)(POOL_PRINT *, VOID *);    
910
    UINTN               Index, NewSize;
910
    UINTN               Index, NewSize;
911
 
911
 
912
    ZeroMem(&Str, sizeof(Str));
912
    ZeroMem(&Str, sizeof(Str));
913
 
913
 
914
    //
914
    //
915
    // Unpacked the device path
915
    // Unpacked the device path
916
    //
916
    //
917
 
917
 
918
    DevPath = UnpackDevicePath(DevPath);
918
    DevPath = UnpackDevicePath(DevPath);
919
    ASSERT (DevPath);
919
    ASSERT (DevPath);
920
 
920
 
921
 
921
 
922
    //
922
    //
923
    // Process each device path node
923
    // Process each device path node
924
    //    
924
    //    
925
 
925
 
926
    DevPathNode = DevPath;
926
    DevPathNode = DevPath;
927
    while (!IsDevicePathEnd(DevPathNode)) {
927
    while (!IsDevicePathEnd(DevPathNode)) {
928
        //
928
        //
929
        // Find the handler to dump this device path node
929
        // Find the handler to dump this device path node
930
        //
930
        //
931
 
931
 
932
        DumpNode = NULL;
932
        DumpNode = NULL;
933
        for (Index = 0; DevPathTable[Index].Function; Index += 1) {
933
        for (Index = 0; DevPathTable[Index].Function; Index += 1) {
934
 
934
 
935
            if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
935
            if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
936
                DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
936
                DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
937
                DumpNode = DevPathTable[Index].Function;
937
                DumpNode = DevPathTable[Index].Function;
938
                break;
938
                break;
939
            }
939
            }
940
        }
940
        }
941
 
941
 
942
        //
942
        //
943
        // If not found, use a generic function
943
        // If not found, use a generic function
944
        //
944
        //
945
 
945
 
946
        if (!DumpNode) {
946
        if (!DumpNode) {
947
            DumpNode = _DevPathNodeUnknown;
947
            DumpNode = _DevPathNodeUnknown;
948
        }
948
        }
949
 
949
 
950
        //
950
        //
951
        //  Put a path seperator in if needed
951
        //  Put a path seperator in if needed
952
        //
952
        //
953
 
953
 
954
        if (Str.len  &&  DumpNode != _DevPathEndInstance) {
954
        if (Str.len  &&  DumpNode != _DevPathEndInstance) {
955
            CatPrint (&Str, L"/");
955
            CatPrint (&Str, L"/");
956
        }
956
        }
957
 
957
 
958
        //
958
        //
959
        // Print this node of the device path
959
        // Print this node of the device path
960
        //
960
        //
961
 
961
 
962
        DumpNode (&Str, DevPathNode);
962
        DumpNode (&Str, DevPathNode);
963
 
963
 
964
        //
964
        //
965
        // Next device path node
965
        // Next device path node
966
        //
966
        //
967
 
967
 
968
        DevPathNode = NextDevicePathNode(DevPathNode);
968
        DevPathNode = NextDevicePathNode(DevPathNode);
969
    }
969
    }
970
 
970
 
971
    //
971
    //
972
    // Shrink pool used for string allocation
972
    // Shrink pool used for string allocation
973
    //
973
    //
974
 
974
 
975
    FreePool (DevPath);
975
    FreePool (DevPath);
976
    NewSize = (Str.len + 1) * sizeof(CHAR16);
976
    NewSize = (Str.len + 1) * sizeof(CHAR16);
977
    Str.str = ReallocatePool (Str.str, NewSize, NewSize);
977
    Str.str = ReallocatePool (Str.str, NewSize, NewSize);
978
    Str.str[Str.len] = 0;
978
    Str.str[Str.len] = 0;
979
    return Str.str;
979
    return Str.str;
980
}
980
}
981
 
981
 
982
BOOLEAN
982
BOOLEAN
983
LibMatchDevicePaths (
983
LibMatchDevicePaths (
984
    IN  EFI_DEVICE_PATH *Multi,
984
    IN  EFI_DEVICE_PATH *Multi,
985
    IN  EFI_DEVICE_PATH *Single
985
    IN  EFI_DEVICE_PATH *Single
986
    )
986
    )
987
{
987
{
988
    EFI_DEVICE_PATH     *DevicePath, *DevicePathInst;
988
    EFI_DEVICE_PATH     *DevicePath, *DevicePathInst;
989
    UINTN               Size;
989
    UINTN               Size;
990
 
990
 
991
    if (!Multi || !Single) {
991
    if (!Multi || !Single) {
992
        return FALSE;
992
        return FALSE;
993
    }
993
    }
994
 
994
 
995
    DevicePath = Multi;
995
    DevicePath = Multi;
996
    while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
996
    while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
997
        if (CompareMem (Single, DevicePathInst, Size) == 0) {
997
        if (CompareMem (Single, DevicePathInst, Size) == 0) {
998
            return TRUE;
998
            return TRUE;
999
        }
999
        }
1000
    }
1000
    }
1001
    return FALSE;
1001
    return FALSE;
1002
}
1002
}
1003
 
1003
 
1004
EFI_DEVICE_PATH *
1004
EFI_DEVICE_PATH *
1005
LibDuplicateDevicePathInstance (
1005
LibDuplicateDevicePathInstance (
1006
    IN EFI_DEVICE_PATH  *DevPath
1006
    IN EFI_DEVICE_PATH  *DevPath
1007
    )
1007
    )
1008
{
1008
{
1009
    EFI_DEVICE_PATH     *NewDevPath,*DevicePathInst,*Temp;
1009
    EFI_DEVICE_PATH     *NewDevPath,*DevicePathInst,*Temp;
1010
    UINTN               Size;    
1010
    UINTN               Size;    
1011
 
1011
 
1012
    //
1012
    //
1013
    // get the size of an instance from the input
1013
    // get the size of an instance from the input
1014
    //
1014
    //
1015
 
1015
 
1016
    Temp = DevPath;
1016
    Temp = DevPath;
1017
    DevicePathInst = DevicePathInstance (&Temp, &Size);
1017
    DevicePathInst = DevicePathInstance (&Temp, &Size);
1018
   
1018
   
1019
    //
1019
    //
1020
    // Make a copy and set proper end type
1020
    // Make a copy and set proper end type
1021
    //
1021
    //
1022
    NewDevPath = NULL;
1022
    NewDevPath = NULL;
1023
    if (Size) {
1023
    if (Size) {
1024
        NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
1024
        NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
1025
    }
1025
    }
1026
 
1026
 
1027
    if (NewDevPath) {
1027
    if (NewDevPath) {
1028
        CopyMem (NewDevPath, DevicePathInst, Size);
1028
        CopyMem (NewDevPath, DevicePathInst, Size);
1029
        Temp = NextDevicePathNode(NewDevPath);
1029
        Temp = NextDevicePathNode(NewDevPath);
1030
        SetDevicePathEndNode(Temp);
1030
        SetDevicePathEndNode(Temp);
1031
    }
1031
    }
1032
 
1032
 
1033
    return NewDevPath;
1033
    return NewDevPath;
1034
}
1034
}
1035
 
1035
 
1036
 
1036