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 |