]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
49dc7077b7f4da034c1ee62c98493d75e4a1af3d
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / UdfDxe / Udf.c
1 /** @file
2 UDF/ECMA-167 file system driver.
3
4 Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
5
6 This program and the accompanying materials are licensed and made available
7 under the terms and conditions of the BSD License which accompanies this
8 distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
12 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 **/
14
15 #include "Udf.h"
16
17 //
18 // UDF filesystem driver's Global Variables.
19 //
20 EFI_DRIVER_BINDING_PROTOCOL gUdfDriverBinding = {
21 UdfDriverBindingSupported,
22 UdfDriverBindingStart,
23 UdfDriverBindingStop,
24 0x10,
25 NULL,
26 NULL
27 };
28
29 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gUdfSimpleFsTemplate = {
30 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
31 UdfOpenVolume
32 };
33
34 /**
35 Test to see if this driver supports ControllerHandle. Any ControllerHandle
36 than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be
37 supported.
38
39 @param[in] This Protocol instance pointer.
40 @param[in] ControllerHandle Handle of device to test.
41 @param[in] RemainingDevicePath Optional parameter use to pick a specific
42 child device to start.
43
44 @retval EFI_SUCCESS This driver supports this device.
45 @retval EFI_ALREADY_STARTED This driver is already running on this device.
46 @retval other This driver does not support this device.
47
48 **/
49 EFI_STATUS
50 EFIAPI
51 UdfDriverBindingSupported (
52 IN EFI_DRIVER_BINDING_PROTOCOL *This,
53 IN EFI_HANDLE ControllerHandle,
54 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
55 )
56 {
57 EFI_STATUS Status;
58 EFI_DISK_IO_PROTOCOL *DiskIo;
59
60 //
61 // Open DiskIo protocol on ControllerHandle
62 //
63 Status = gBS->OpenProtocol (
64 ControllerHandle,
65 &gEfiDiskIoProtocolGuid,
66 (VOID **)&DiskIo,
67 This->DriverBindingHandle,
68 ControllerHandle,
69 EFI_OPEN_PROTOCOL_BY_DRIVER
70 );
71 if (EFI_ERROR (Status)) {
72 return Status;
73 }
74
75 //
76 // Close DiskIo protocol on ControllerHandle
77 //
78 gBS->CloseProtocol (
79 ControllerHandle,
80 &gEfiDiskIoProtocolGuid,
81 This->DriverBindingHandle,
82 ControllerHandle
83 );
84
85 //
86 // Test whether ControllerHandle supports BlockIo protocol
87 //
88 Status = gBS->OpenProtocol (
89 ControllerHandle,
90 &gEfiBlockIoProtocolGuid,
91 NULL,
92 This->DriverBindingHandle,
93 ControllerHandle,
94 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
95 );
96
97 return Status;
98 }
99
100 /**
101 Start this driver on ControllerHandle by opening a Block IO or a Block IO2
102 or both, and Disk IO protocol, reading Device Path, and creating a child
103 handle with a Disk IO and device path protocol.
104
105 @param[in] This Protocol instance pointer.
106 @param[in] ControllerHandle Handle of device to bind driver to
107 @param[in] RemainingDevicePath Optional parameter use to pick a specific
108 child device to start.
109
110 @retval EFI_SUCCESS This driver is added to ControllerHandle.
111 @retval EFI_ALREADY_STARTED This driver is already running on
112 ControllerHandle.
113 @retval other This driver does not support this device.
114
115 **/
116 EFI_STATUS
117 EFIAPI
118 UdfDriverBindingStart (
119 IN EFI_DRIVER_BINDING_PROTOCOL *This,
120 IN EFI_HANDLE ControllerHandle,
121 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
122 )
123 {
124 EFI_TPL OldTpl;
125 EFI_STATUS Status;
126 EFI_BLOCK_IO_PROTOCOL *BlockIo;
127 EFI_DISK_IO_PROTOCOL *DiskIo;
128 PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
129
130 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
131
132 //
133 // Open BlockIo protocol on ControllerHandle
134 //
135 Status = gBS->OpenProtocol (
136 ControllerHandle,
137 &gEfiBlockIoProtocolGuid,
138 (VOID **)&BlockIo,
139 This->DriverBindingHandle,
140 ControllerHandle,
141 EFI_OPEN_PROTOCOL_GET_PROTOCOL
142 );
143 ASSERT_EFI_ERROR (Status);
144
145 //
146 // Open DiskIo protocol on ControllerHandle
147 //
148 Status = gBS->OpenProtocol (
149 ControllerHandle,
150 &gEfiDiskIoProtocolGuid,
151 (VOID **)&DiskIo,
152 This->DriverBindingHandle,
153 ControllerHandle,
154 EFI_OPEN_PROTOCOL_BY_DRIVER
155 );
156 ASSERT_EFI_ERROR (Status);
157
158 //
159 // Check if ControllerHandle supports an UDF file system
160 //
161 Status = SupportUdfFileSystem (This, ControllerHandle);
162 if (EFI_ERROR (Status)) {
163 goto Exit;
164 }
165
166 //
167 // Initialize private file system structure
168 //
169 PrivFsData =
170 (PRIVATE_UDF_SIMPLE_FS_DATA *)
171 AllocateZeroPool (sizeof (PRIVATE_UDF_SIMPLE_FS_DATA));
172 if (PrivFsData == NULL) {
173 Status = EFI_OUT_OF_RESOURCES;
174 goto Exit;
175 }
176
177 //
178 // Create new child handle
179 //
180 PrivFsData->Signature = PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE;
181 PrivFsData->BlockIo = BlockIo;
182 PrivFsData->DiskIo = DiskIo;
183 PrivFsData->Handle = ControllerHandle;
184
185 //
186 // Set up SimpleFs protocol
187 //
188 CopyMem ((VOID *)&PrivFsData->SimpleFs, (VOID *)&gUdfSimpleFsTemplate,
189 sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL));
190
191 //
192 // Install child handle
193 //
194 Status = gBS->InstallMultipleProtocolInterfaces (
195 &PrivFsData->Handle,
196 &gEfiSimpleFileSystemProtocolGuid,
197 &PrivFsData->SimpleFs,
198 NULL
199 );
200
201 Exit:
202 if (EFI_ERROR (Status)) {
203 //
204 // Close DiskIo protocol on ControllerHandle
205 //
206 gBS->CloseProtocol (
207 ControllerHandle,
208 &gEfiDiskIoProtocolGuid,
209 This->DriverBindingHandle,
210 ControllerHandle
211 );
212 //
213 // Close BlockIo protocol on ControllerHandle
214 //
215 gBS->CloseProtocol (
216 ControllerHandle,
217 &gEfiBlockIoProtocolGuid,
218 This->DriverBindingHandle,
219 ControllerHandle
220 );
221 }
222
223 gBS->RestoreTPL (OldTpl);
224
225 return Status;
226 }
227
228 /**
229 Stop this driver on ControllerHandle. Support stopping any child handles
230 created by this driver.
231
232 @param This Protocol instance pointer.
233 @param ControllerHandle Handle of device to stop driver on
234 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
235 children is zero stop the entire bus driver.
236 @param ChildHandleBuffer List of Child Handles to Stop.
237
238 @retval EFI_SUCCESS This driver is removed ControllerHandle
239 @retval other This driver was not removed from this device
240
241 **/
242 EFI_STATUS
243 EFIAPI
244 UdfDriverBindingStop (
245 IN EFI_DRIVER_BINDING_PROTOCOL *This,
246 IN EFI_HANDLE ControllerHandle,
247 IN UINTN NumberOfChildren,
248 IN EFI_HANDLE *ChildHandleBuffer
249 )
250 {
251 PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
252 EFI_STATUS Status;
253 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
254
255 //
256 // Open SimpleFs protocol on ControllerHandle
257 //
258 Status = gBS->OpenProtocol (
259 ControllerHandle,
260 &gEfiSimpleFileSystemProtocolGuid,
261 (VOID **)&SimpleFs,
262 This->DriverBindingHandle,
263 ControllerHandle,
264 EFI_OPEN_PROTOCOL_GET_PROTOCOL
265 );
266 if (!EFI_ERROR (Status)) {
267 PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (SimpleFs);
268
269 //
270 // Uninstall child handle
271 //
272 Status = gBS->UninstallMultipleProtocolInterfaces (
273 PrivFsData->Handle,
274 &gEfiSimpleFileSystemProtocolGuid,
275 &PrivFsData->SimpleFs,
276 NULL
277 );
278
279 //
280 // Check if there's any open file. If so, clean them up.
281 //
282 if (PrivFsData->OpenFiles > 0) {
283 CleanupVolumeInformation (&PrivFsData->Volume);
284 }
285
286 FreePool ((VOID *)PrivFsData);
287 }
288
289 if (!EFI_ERROR (Status)) {
290 //
291 // Close DiskIo protocol on ControllerHandle
292 //
293 gBS->CloseProtocol (
294 ControllerHandle,
295 &gEfiDiskIoProtocolGuid,
296 This->DriverBindingHandle,
297 ControllerHandle
298 );
299 //
300 // Close BlockIo protocol on ControllerHandle
301 //
302 gBS->CloseProtocol (
303 ControllerHandle,
304 &gEfiBlockIoProtocolGuid,
305 This->DriverBindingHandle,
306 ControllerHandle
307 );
308 }
309
310 return Status;
311 }
312
313 /**
314 The user Entry Point for UDF file system driver. The user code starts with
315 this function.
316
317 @param[in] ImageHandle The firmware allocated handle for the EFI image.
318 @param[in] SystemTable A pointer to the EFI System Table.
319
320 @retval EFI_SUCCESS The entry point is executed successfully.
321 @retval other Some error occurs when executing this entry point.
322
323 **/
324 EFI_STATUS
325 EFIAPI
326 InitializeUdf (
327 IN EFI_HANDLE ImageHandle,
328 IN EFI_SYSTEM_TABLE *SystemTable
329 )
330 {
331 EFI_STATUS Status;
332
333 Status = EfiLibInstallDriverBindingComponentName2 (
334 ImageHandle,
335 SystemTable,
336 &gUdfDriverBinding,
337 ImageHandle,
338 &gUdfComponentName,
339 &gUdfComponentName2
340 );
341 ASSERT_EFI_ERROR (Status);
342
343 return Status;
344 }