]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
Add comment to explain use of the types "int" and "unsigned int" in the implementatio...
[mirror_edk2.git] / MdePkg / Library / UefiDevicePathLibDevicePathProtocol / UefiDevicePathLib.c
CommitLineData
e386b444 1/** @file\r
f008fc32 2 Library instance that implement UEFI Device Path Library class based on protocol\r
3 gEfiDevicePathUtilitiesProtocolGuid.\r
e386b444 4\r
373ade0e 5 Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
e386b444 6 All rights reserved. This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
e386b444 14**/\r
15\r
c892d846 16\r
c7d265a9 17#include <Uefi.h>\r
c892d846 18\r
c7d265a9 19#include <Protocol/DevicePathUtilities.h>\r
20#include <Protocol/DevicePath.h>\r
c892d846 21\r
c7d265a9 22#include <Library/DevicePathLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/BaseLib.h>\r
25#include <Library/MemoryAllocationLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/UefiBootServicesTableLib.h>\r
e386b444 28\r
fe467413 29EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathUtilities = NULL;\r
e386b444 30\r
31/**\r
32 The constructor function caches the pointer to DevicePathUtilites protocol.\r
33 \r
34 The constructor function locates DevicePathUtilities protocol from protocol database.\r
35 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
36\r
37 @param ImageHandle The firmware allocated handle for the EFI image.\r
38 @param SystemTable A pointer to the EFI System Table.\r
39 \r
40 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
41\r
42**/\r
43EFI_STATUS\r
44EFIAPI\r
45DevicePathLibConstructor (\r
46 IN EFI_HANDLE ImageHandle,\r
47 IN EFI_SYSTEM_TABLE *SystemTable\r
48 )\r
49{\r
50 EFI_STATUS Status;\r
51\r
52 Status = gBS->LocateProtocol (\r
53 &gEfiDevicePathUtilitiesProtocolGuid,\r
54 NULL,\r
55 (VOID**) &mDevicePathUtilities\r
56 );\r
57 ASSERT_EFI_ERROR (Status);\r
58 ASSERT (mDevicePathUtilities != NULL);\r
59\r
60 return Status;\r
61}\r
62\r
63/**\r
64 Returns the size of a device path in bytes.\r
65\r
66 This function returns the size, in bytes, of the device path data structure specified by\r
67 DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned.\r
68\r
69 @param DevicePath A pointer to a device path data structure.\r
3e5c3238 70 \r
71 @retval 0 If DevicePath is NULL.\r
72 @retval Others The size of a device path in bytes.\r
e386b444 73\r
74**/\r
75UINTN\r
76EFIAPI\r
77GetDevicePathSize (\r
78 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
79 )\r
80{\r
81 return mDevicePathUtilities->GetDevicePathSize (DevicePath);\r
82}\r
83\r
84/**\r
6a3f4ef9 85 Creates a new copy of an existing device path.\r
e386b444 86\r
87 This function allocates space for a new copy of the device path specified by DevicePath. If\r
88 DevicePath is NULL, then NULL is returned. If the memory is successfully allocated, then the\r
89 contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer\r
90 is returned. Otherwise, NULL is returned. \r
3e5c3238 91 The memory for the new device path is allocated from EFI boot services memory. \r
92 It is the responsibility of the caller to free the memory allocated. \r
e386b444 93 \r
94 @param DevicePath A pointer to a device path data structure.\r
95\r
3e5c3238 96 @retval NULL If DevicePath is NULL.\r
97 @retval Others A pointer to the duplicated device path.\r
98 \r
e386b444 99**/\r
100EFI_DEVICE_PATH_PROTOCOL *\r
101EFIAPI\r
102DuplicateDevicePath (\r
103 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
104 )\r
105{\r
106 return mDevicePathUtilities->DuplicateDevicePath (DevicePath);\r
107}\r
108\r
109/**\r
110 Creates a new device path by appending a second device path to a first device path.\r
111\r
112 This function creates a new device path by appending a copy of SecondDevicePath to a copy of\r
113 FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from\r
114 SecondDevicePath is retained. The newly created device path is returned. \r
115 If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned. \r
116 If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned. \r
98a14db6 117 If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is\r
118 returned. \r
e386b444 119 If there is not enough memory for the newly allocated buffer, then NULL is returned.\r
120 The memory for the new device path is allocated from EFI boot services memory. It is the\r
121 responsibility of the caller to free the memory allocated.\r
122\r
123 @param FirstDevicePath A pointer to a device path data structure.\r
124 @param SecondDevicePath A pointer to a device path data structure.\r
3e5c3238 125 \r
126 @retval NULL If there is not enough memory for the newly allocated buffer.\r
127 @retval Others A pointer to the new device path if success.\r
128 Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.\r
e386b444 129\r
130**/\r
131EFI_DEVICE_PATH_PROTOCOL *\r
132EFIAPI\r
133AppendDevicePath (\r
134 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL\r
135 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL\r
136 )\r
137{\r
138 return mDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);\r
139}\r
140\r
141/**\r
142 Creates a new path by appending the device node to the device path.\r
143\r
144 This function creates a new device path by appending a copy of the device node specified by\r
145 DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer.\r
146 The end-of-device-path device node is moved after the end of the appended device node.\r
98a14db6 147 If DevicePathNode is NULL then a copy of DevicePath is returned.\r
6336a895 148 If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device path device\r
149 node is returned.\r
98a14db6 150 If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path device node\r
151 is returned.\r
e386b444 152 If there is not enough memory to allocate space for the new device path, then NULL is returned. \r
153 The memory is allocated from EFI boot services memory. It is the responsibility of the caller to\r
154 free the memory allocated.\r
155\r
156 @param DevicePath A pointer to a device path data structure.\r
157 @param DevicePathNode A pointer to a single device path node.\r
158\r
3e5c3238 159 @retval NULL If there is not enough memory for the new device path.\r
160 @retval Others A pointer to the new device path if success.\r
161 A copy of DevicePathNode followed by an end-of-device-path node \r
162 if both FirstDevicePath and SecondDevicePath are NULL.\r
163 A copy of an end-of-device-path node if both FirstDevicePath and SecondDevicePath are NULL.\r
e386b444 164\r
165**/\r
166EFI_DEVICE_PATH_PROTOCOL *\r
167EFIAPI\r
168AppendDevicePathNode (\r
169 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL\r
170 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL\r
171 )\r
172{\r
173 return mDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);\r
174}\r
175\r
176/**\r
177 Creates a new device path by appending the specified device path instance to the specified device\r
178 path.\r
179 \r
180 This function creates a new device path by appending a copy of the device path instance specified\r
181 by DevicePathInstance to a copy of the device path secified by DevicePath in a allocated buffer.\r
182 The end-of-device-path device node is moved after the end of the appended device path instance\r
183 and a new end-of-device-path-instance node is inserted between. \r
184 If DevicePath is NULL, then a copy if DevicePathInstance is returned.\r
185 If DevicePathInstance is NULL, then NULL is returned.\r
186 If there is not enough memory to allocate space for the new device path, then NULL is returned. \r
187 The memory is allocated from EFI boot services memory. It is the responsibility of the caller to\r
188 free the memory allocated.\r
189 \r
190 @param DevicePath A pointer to a device path data structure.\r
191 @param DevicePathInstance A pointer to a device path instance.\r
192\r
193 @return A pointer to the new device path.\r
194\r
195**/\r
196EFI_DEVICE_PATH_PROTOCOL *\r
197EFIAPI\r
198AppendDevicePathInstance (\r
199 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL\r
200 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL\r
201 )\r
202{\r
203 return mDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);\r
204}\r
205\r
206/**\r
207 Creates a copy of the current device path instance and returns a pointer to the next device path\r
208 instance.\r
209\r
210 This function creates a copy of the current device path instance. It also updates DevicePath to\r
211 point to the next device path instance in the device path (or NULL if no more) and updates Size\r
212 to hold the size of the device path instance copy.\r
213 If DevicePath is NULL, then NULL is returned.\r
214 If there is not enough memory to allocate space for the new device path, then NULL is returned. \r
215 The memory is allocated from EFI boot services memory. It is the responsibility of the caller to\r
216 free the memory allocated.\r
217 If Size is NULL, then ASSERT().\r
218 \r
219 @param DevicePath On input, this holds the pointer to the current device path\r
220 instance. On output, this holds the pointer to the next device\r
221 path instance or NULL if there are no more device path\r
222 instances in the device path pointer to a device path data\r
223 structure.\r
224 @param Size On output, this holds the size of the device path instance, in\r
225 bytes or zero, if DevicePath is NULL.\r
226\r
227 @return A pointer to the current device path instance.\r
228\r
229**/\r
230EFI_DEVICE_PATH_PROTOCOL *\r
231EFIAPI\r
232GetNextDevicePathInstance (\r
233 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
234 OUT UINTN *Size\r
235 )\r
236{\r
237 ASSERT (Size != NULL);\r
238 return mDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);\r
239}\r
240\r
241/**\r
3e5c3238 242 Creates a device node.\r
e386b444 243\r
244 This function creates a new device node in a newly allocated buffer of size NodeLength and\r
245 initializes the device path node header with NodeType and NodeSubType. The new device path node\r
246 is returned.\r
247 If NodeLength is smaller than a device path header, then NULL is returned. \r
248 If there is not enough memory to allocate space for the new device path, then NULL is returned. \r
249 The memory is allocated from EFI boot services memory. It is the responsibility of the caller to\r
250 free the memory allocated.\r
251\r
252 @param NodeType The device node type for the new device node.\r
253 @param NodeSubType The device node sub-type for the new device node.\r
254 @param NodeLength The length of the new device node.\r
255\r
3e5c3238 256 @return The new device path.\r
e386b444 257\r
258**/\r
259EFI_DEVICE_PATH_PROTOCOL *\r
260EFIAPI\r
261CreateDeviceNode (\r
262 IN UINT8 NodeType,\r
263 IN UINT8 NodeSubType,\r
264 IN UINT16 NodeLength\r
265 )\r
266{\r
267 return mDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);\r
268}\r
269\r
270/**\r
271 Determines if a device path is single or multi-instance.\r
272\r
273 This function returns TRUE if the device path specified by DevicePath is multi-instance.\r
274 Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned.\r
275\r
276 @param DevicePath A pointer to a device path data structure.\r
277\r
278 @retval TRUE DevicePath is multi-instance.\r
279 @retval FALSE DevicePath is not multi-instance or DevicePath is NULL.\r
280\r
281**/\r
282BOOLEAN\r
283EFIAPI\r
284IsDevicePathMultiInstance (\r
285 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
286 )\r
287{\r
288 return mDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);\r
289}\r
290\r
291/**\r
292 Retrieves the device path protocol from a handle.\r
293\r
294 This function returns the device path protocol from the handle specified by Handle. If Handle is\r
295 NULL or Handle does not contain a device path protocol, then NULL is returned.\r
296 \r
297 @param Handle The handle from which to retrieve the device path protocol.\r
298\r
299 @return The device path protocol from the handle specified by Handle.\r
300\r
301**/\r
302EFI_DEVICE_PATH_PROTOCOL *\r
303EFIAPI\r
304DevicePathFromHandle (\r
305 IN EFI_HANDLE Handle\r
306 )\r
307{\r
308 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
309 EFI_STATUS Status;\r
310\r
311 Status = gBS->HandleProtocol (\r
312 Handle,\r
313 &gEfiDevicePathProtocolGuid,\r
314 (VOID *) &DevicePath\r
315 );\r
316 if (EFI_ERROR (Status)) {\r
317 DevicePath = NULL;\r
318 }\r
319 return DevicePath;\r
320}\r
321\r
322/**\r
323 Allocates a device path for a file and appends it to an existing device path.\r
324\r
325 If Device is a valid device handle that contains a device path protocol, then a device path for\r
326 the file specified by FileName is allocated and appended to the device path associated with the\r
327 handle Device. The allocated device path is returned. If Device is NULL or Device is a handle\r
328 that does not support the device path protocol, then a device path containing a single device\r
329 path node for the file specified by FileName is allocated and returned.\r
3e5c3238 330 The memory for the new device path is allocated from EFI boot services memory. It is the responsibility\r
331 of the caller to free the memory allocated.\r
332 \r
e386b444 333 If FileName is NULL, then ASSERT().\r
3e5c3238 334 If FileName is not aligned on a 16-bit boundary, then ASSERT().\r
e386b444 335\r
336 @param Device A pointer to a device handle. This parameter is optional and\r
337 may be NULL.\r
338 @param FileName A pointer to a Null-terminated Unicode string.\r
339\r
3e5c3238 340 @return The allocated device path.\r
e386b444 341\r
342**/\r
343EFI_DEVICE_PATH_PROTOCOL *\r
344EFIAPI\r
345FileDevicePath (\r
346 IN EFI_HANDLE Device, OPTIONAL\r
347 IN CONST CHAR16 *FileName\r
348 )\r
349{\r
350 UINTN Size;\r
351 FILEPATH_DEVICE_PATH *FilePath;\r
352 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
353 EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;\r
354\r
355 DevicePath = NULL;\r
356\r
357 Size = StrSize (FileName);\r
e5dab016 358 FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);\r
e386b444 359 if (FileDevicePath != NULL) {\r
360 FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;\r
361 FilePath->Header.Type = MEDIA_DEVICE_PATH;\r
362 FilePath->Header.SubType = MEDIA_FILEPATH_DP;\r
363 CopyMem (&FilePath->PathName, FileName, Size);\r
364 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);\r
365 SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));\r
366\r
367 if (Device != NULL) {\r
368 DevicePath = DevicePathFromHandle (Device);\r
369 }\r
370\r
371 DevicePath = AppendDevicePath (DevicePath, FileDevicePath);\r
372 FreePool (FileDevicePath);\r
373 }\r
374\r
375 return DevicePath;\r
376}\r