]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/Uefi/Devices/UefiShell/daShell.c
Add Socket Libraries.
[mirror_edk2.git] / StdLib / LibC / Uefi / Devices / UefiShell / daShell.c
CommitLineData
53e1e5c6 1/** @file\r
2 Abstract device driver for the UEFI Shell-hosted environment.\r
3\r
4 In a Shell-hosted environment, this is the driver that is called\r
5 when no other driver matches.\r
6\r
7 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
8 This program and the accompanying materials are licensed and made available under\r
9 the terms and conditions of the BSD License that accompanies this distribution.\r
10 The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17#include <Uefi.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/ShellLib.h>\r
22\r
23#include <LibConfig.h>\r
24#include <sys/EfiSysCall.h>\r
25\r
26#include <errno.h>\r
27#include <string.h>\r
28#include <stdlib.h>\r
29#include <wctype.h>\r
30#include <wchar.h>\r
31#include <sys/fcntl.h>\r
d7ce7006 32#include <sys/syslimits.h>\r
53e1e5c6 33#include <kfile.h>\r
34#include <Device/Device.h>\r
35#include <MainData.h>\r
36#include <Efi/SysEfi.h>\r
37\r
38static\r
39int\r
40EFIAPI\r
41da_ShellClose(\r
42 IN struct __filedes *Fp\r
43)\r
44{\r
45 EFIerrno = ShellCloseFile( (SHELL_FILE_HANDLE *)&Fp->devdata);\r
46 if(RETURN_ERROR(EFIerrno)) {\r
47 return -1;\r
48 }\r
49 return 0;\r
50}\r
51\r
52static\r
53int\r
54EFIAPI\r
55da_ShellDelete(\r
56 struct __filedes *filp\r
57 )\r
58{\r
59 RETURN_STATUS Status;\r
60\r
61 Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&filp->devdata);\r
62 if(Status != RETURN_SUCCESS) {\r
63 errno = EFI2errno(Status);\r
64 EFIerrno = Status;\r
65 return -1;\r
66 }\r
67 return 0;\r
68}\r
69\r
70static\r
71off_t\r
72EFIAPI\r
73da_ShellSeek(\r
74 struct __filedes *filp,\r
75 off_t offset,\r
76 int whence\r
77)\r
78{\r
79 __off_t CurPos = -1;\r
80 RETURN_STATUS Status = RETURN_SUCCESS;\r
81 SHELL_FILE_HANDLE FileHandle;\r
82\r
83 FileHandle = (SHELL_FILE_HANDLE)filp->devdata;\r
84\r
85 if(whence != SEEK_SET) {\r
86 // We are doing a relative seek\r
87 if(whence == SEEK_END) {\r
88 // seeking relative to EOF, so position there first.\r
89 Status = ShellSetFilePosition( FileHandle, 0xFFFFFFFFFFFFFFFFULL);\r
90 }\r
91 if(Status == RETURN_SUCCESS) {\r
92 // Now, determine our current position.\r
93 Status = ShellGetFilePosition( FileHandle, (UINT64 *)&CurPos);\r
94 }\r
95 }\r
96 else {\r
97 CurPos = 0; // offset is an absolute position for SEEK_SET\r
98 if(offset < 0) {\r
99 Status = RETURN_INVALID_PARAMETER;\r
100 }\r
101 }\r
102 if(Status == RETURN_SUCCESS) {\r
103 /* CurPos now indicates the point we are seeking from, so seek... */\r
104 Status = ShellSetFilePosition( FileHandle, (UINT64)(CurPos + offset));\r
105 if(Status == RETURN_SUCCESS) {\r
106 // Now, determine our final position.\r
107 Status = ShellGetFilePosition( FileHandle, (UINT64 *)&CurPos);\r
108 }\r
109 }\r
110 if(Status != RETURN_SUCCESS) {\r
111 if(Status == EFI_UNSUPPORTED) {\r
112 errno = EISDIR;\r
113 }\r
114 else {\r
115 errno = EFI2errno(Status);\r
116 }\r
117 EFIerrno = Status;\r
118 CurPos = EOF;\r
119 }\r
120 return CurPos;\r
121}\r
122\r
123/** The directory path is created with the access permissions specified by\r
124 perms.\r
125\r
126 The directory is closed after it is created.\r
127\r
128 @retval 0 The directory was created successfully.\r
129 @retval -1 An error occurred and an error code is stored in errno.\r
130**/\r
131static\r
132int\r
133EFIAPI\r
134da_ShellMkdir(\r
135 const char *path,\r
136 __mode_t perms\r
137 )\r
138{\r
139 SHELL_FILE_HANDLE FileHandle;\r
140 RETURN_STATUS Status;\r
141 EFI_FILE_INFO *FileInfo;\r
142 wchar_t *NewPath;\r
143 int retval = -1;\r
144\r
145 // Convert name from MBCS to WCS and change '/' to '\\'\r
146 NewPath = NormalizePath( path);\r
147\r
148 if(NewPath != NULL) {\r
149 Status = ShellCreateDirectory( NewPath, &FileHandle);\r
150 if(Status == RETURN_SUCCESS) {\r
151 FileInfo = ShellGetFileInfo( FileHandle);\r
152 Status = RETURN_ABORTED; // In case ShellGetFileInfo() failed\r
153 if(FileInfo != NULL) {\r
154 FileInfo->Attribute = Omode2EFI(perms);\r
155 Status = ShellSetFileInfo( FileHandle, FileInfo);\r
156 FreePool(FileInfo);\r
157 if(Status == RETURN_SUCCESS) {\r
158 (void)ShellCloseFile(&FileHandle);\r
159 retval = 0;\r
160 }\r
161 }\r
162 }\r
163 errno = EFI2errno(Status);\r
164 EFIerrno = Status;\r
165 free(NewPath);\r
166 }\r
167 return retval;\r
168}\r
169\r
170static\r
171ssize_t\r
172EFIAPI\r
173da_ShellRead(\r
174 IN OUT struct __filedes *filp,\r
175 IN OUT off_t *offset,\r
176 IN size_t BufferSize,\r
177 OUT VOID *Buffer\r
178)\r
179{\r
180 ssize_t BufSize;\r
181 SHELL_FILE_HANDLE FileHandle;\r
182 RETURN_STATUS Status;\r
183\r
184 if(offset != NULL) {\r
185 BufSize = (ssize_t)da_ShellSeek(filp, *offset, SEEK_SET);\r
186 if(BufSize >= 0) {\r
187 filp->f_offset = BufSize;\r
188 }\r
189 }\r
190\r
191 BufSize = (ssize_t)BufferSize;\r
192 FileHandle = (SHELL_FILE_HANDLE)filp->devdata;\r
193\r
194 Status = ShellReadFile( FileHandle, (UINTN *)&BufSize, Buffer);\r
195 if(Status != RETURN_SUCCESS) {\r
196 EFIerrno = Status;\r
197 errno = EFI2errno(Status);\r
198 if(Status == RETURN_BUFFER_TOO_SMALL) {\r
199 BufSize = -BufSize;\r
200 }\r
201 else {\r
202 BufSize = -1;\r
203 }\r
204 }\r
205 else {\r
206 filp->f_offset += BufSize; // Advance to where we want to read next.\r
207 }\r
208 return BufSize;\r
209}\r
210\r
211static\r
212ssize_t\r
213EFIAPI\r
214da_ShellWrite(\r
215 IN struct __filedes *filp,\r
216 IN off_t *offset,\r
217 IN size_t BufferSize,\r
218 IN const void *Buffer\r
219 )\r
220{\r
221 ssize_t BufSize;\r
222 SHELL_FILE_HANDLE FileHandle;\r
223 RETURN_STATUS Status;\r
224 off_t Position = 0;\r
225 int How = SEEK_SET;\r
226\r
227\r
228 if((offset != NULL) || (filp->Oflags & O_APPEND)) {\r
229 if(filp->Oflags & O_APPEND) {\r
230 Position = 0;\r
231 How = SEEK_END;\r
232 }\r
233 else {\r
234 Position = *offset;\r
235 How = SEEK_SET;\r
236 }\r
237 BufSize = (ssize_t)da_ShellSeek(filp, Position, How);\r
238 if(BufSize >= 0) {\r
239 filp->f_offset = BufSize;\r
240 }\r
241 }\r
242\r
243 BufSize = (ssize_t)BufferSize;\r
244 FileHandle = (SHELL_FILE_HANDLE)filp->devdata;\r
245\r
246 Status = ShellWriteFile( FileHandle, (UINTN *)&BufSize, (void *)Buffer);\r
247\r
248 if(Status != RETURN_SUCCESS) {\r
249 EFIerrno = Status;\r
250 errno = EFI2errno(Status);\r
251 if(Status == EFI_UNSUPPORTED) {\r
252 errno = EISDIR;\r
253 }\r
254 BufSize = -1;\r
255 }\r
256 else {\r
257 filp->f_offset += BufSize; // Advance to where we want to write next.\r
258 }\r
259\r
260 return BufSize;\r
261}\r
262\r
263static\r
264int\r
265EFIAPI\r
266da_ShellStat(\r
267 struct __filedes *filp,\r
268 struct stat *statbuf,\r
269 void *Something\r
270 )\r
271{\r
272 SHELL_FILE_HANDLE FileHandle;\r
273 EFI_FILE_INFO *FileInfo = NULL;\r
274 UINT64 Attributes;\r
275 RETURN_STATUS Status;\r
276 mode_t newmode;\r
277\r
278 FileHandle = (SHELL_FILE_HANDLE)filp->devdata;\r
279\r
280 FileInfo = ShellGetFileInfo( FileHandle);\r
281\r
282 if(FileInfo != NULL) {\r
283 // Got the info, now populate statbuf with it\r
284 statbuf->st_blksize = S_BLKSIZE;\r
285 statbuf->st_size = FileInfo->FileSize;\r
286 statbuf->st_physsize = FileInfo->PhysicalSize;\r
287 statbuf->st_birthtime = Efi2Time( &FileInfo->CreateTime);\r
288 statbuf->st_atime = Efi2Time( &FileInfo->LastAccessTime);\r
289 statbuf->st_mtime = Efi2Time( &FileInfo->ModificationTime);\r
290 Attributes = FileInfo->Attribute;\r
291 newmode = (mode_t)(Attributes << S_EFISHIFT) | S_ACC_READ;\r
292 if((Attributes & EFI_FILE_DIRECTORY) == 0) {\r
293 newmode |= _S_IFREG;\r
294 if((Attributes & EFI_FILE_READ_ONLY) == 0) {\r
295 newmode |= S_ACC_WRITE;\r
296 }\r
297 }\r
298 else {\r
299 newmode |= _S_IFDIR;\r
300 }\r
301 statbuf->st_mode = newmode;\r
302 Status = RETURN_SUCCESS;\r
303 }\r
304 else {\r
305 Status = RETURN_DEVICE_ERROR;\r
306 }\r
307 errno = EFI2errno(Status);\r
308 EFIerrno = Status;\r
309\r
310 if(FileInfo != NULL) {\r
311 FreePool(FileInfo); // Release the buffer allocated by the GetInfo function\r
312 }\r
313 return errno? -1 : 0;\r
314}\r
315\r
316static\r
317int\r
318EFIAPI\r
319da_ShellIoctl(\r
320 struct __filedes *filp,\r
321 ULONGN cmd,\r
322 void *argp ///< May be a pointer or a value\r
323 )\r
324{\r
d7ce7006 325 return -EPERM;\r
53e1e5c6 326}\r
327\r
328/** Open an abstract Shell File.\r
329**/\r
330int\r
331EFIAPI\r
332da_ShellOpen(\r
d7ce7006 333 DeviceNode *DevNode,\r
53e1e5c6 334 struct __filedes *filp,\r
d7ce7006 335 int DevInstance, /* Not used by Shell */\r
53e1e5c6 336 wchar_t *Path,\r
d7ce7006 337 wchar_t *MPath\r
53e1e5c6 338 )\r
339{\r
340 UINT64 OpenMode;\r
341 UINT64 Attributes;\r
342 SHELL_FILE_HANDLE FileHandle;\r
343 GenericInstance *Gip;\r
344 char *NPath;\r
d7ce7006 345 wchar_t *WPath;\r
53e1e5c6 346 RETURN_STATUS Status;\r
347 int oflags;\r
d7ce7006 348 int retval;\r
53e1e5c6 349\r
350 EFIerrno = RETURN_SUCCESS;\r
351\r
352 //Attributes = Omode2EFI(mode);\r
353 Attributes = 0;\r
354\r
355 // Convert oflags to Attributes\r
356 oflags = filp->Oflags;\r
357 OpenMode = Oflags2EFI(oflags);\r
358 if(OpenMode == 0) {\r
359 errno = EINVAL;\r
360 return -1;\r
361 }\r
362\r
d7ce7006 363 /* Re-create the full mapped path for the shell. */\r
364 if(MPath != NULL) {\r
365 WPath = AllocateZeroPool(PATH_MAX * sizeof(wchar_t) + 1);\r
366 if(WPath == NULL) {\r
367 errno = ENOMEM;\r
368 EFIerrno = RETURN_OUT_OF_RESOURCES;\r
369 return -1;\r
370 }\r
371 wcsncpy(WPath, MPath, NAME_MAX); /* Get the Map Name */\r
372 wcsncat(WPath, Path, (PATH_MAX - NAME_MAX)); /* Append the path */\r
373 }\r
374 else {\r
375 WPath = Path;\r
376 }\r
377\r
378 retval = -1; /* Initially assume failure. */\r
379\r
53e1e5c6 380 /* Do we care if the file already exists?\r
381 If O_TRUNC, then delete the file. It will be created anew subsequently.\r
382 If O_EXCL, then error if the file exists and O_CREAT is set.\r
383\r
384 !!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file\r
385 !!!!!!!!! instead of deleting and re-creating it.\r
386 */\r
d7ce7006 387 do { /* Do fake exception handling */\r
53e1e5c6 388 if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {\r
d7ce7006 389 Status = ShellIsFile( WPath );\r
53e1e5c6 390 if(Status == RETURN_SUCCESS) {\r
391 // The file exists\r
392 if(oflags & O_TRUNC) {\r
d7ce7006 393 NPath = AllocateZeroPool(PATH_MAX);\r
53e1e5c6 394 if(NPath == NULL) {\r
395 errno = ENOMEM;\r
396 EFIerrno = RETURN_OUT_OF_RESOURCES;\r
d7ce7006 397 break;\r
53e1e5c6 398 }\r
d7ce7006 399 wcstombs(NPath, WPath, PATH_MAX);\r
53e1e5c6 400 // We do a truncate by deleting the existing file and creating a new one.\r
401 if(unlink(NPath) != 0) {\r
402 filp->f_iflags = 0; // Release our reservation on this FD\r
403 FreePool(NPath);\r
d7ce7006 404 break;\r
53e1e5c6 405 }\r
406 FreePool(NPath);\r
407 }\r
408 else if((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) {\r
409 errno = EEXIST;\r
410 EFIerrno = RETURN_ACCESS_DENIED;\r
411 filp->f_iflags = 0; // Release our reservation on this FD\r
d7ce7006 412 break;\r
53e1e5c6 413 }\r
414 }\r
415 }\r
416\r
417 // Call the EFI Shell's Open function\r
d7ce7006 418 Status = ShellOpenFileByName( WPath, &FileHandle, OpenMode, Attributes);\r
53e1e5c6 419 if(RETURN_ERROR(Status)) {\r
420 filp->f_iflags = 0; // Release our reservation on this FD\r
421 // Set errno based upon Status\r
422 errno = EFI2errno(Status);\r
423 EFIerrno = Status;\r
d7ce7006 424 break;\r
53e1e5c6 425 }\r
d7ce7006 426 retval = 0;\r
53e1e5c6 427 // Successfully got a regular File\r
428 filp->f_iflags |= S_IFREG;\r
429\r
430 // Update the info in the fd\r
431 filp->devdata = (void *)FileHandle;\r
432\r
d7ce7006 433 Gip = (GenericInstance *)DevNode->InstanceList;\r
53e1e5c6 434 filp->f_offset = 0;\r
435 filp->f_ops = &Gip->Abstraction;\r
d7ce7006 436 // filp->devdata = FileHandle;\r
437 } while(FALSE);\r
53e1e5c6 438\r
d7ce7006 439 /* If we get this far, WPath is not NULL.\r
440 If MPath is not NULL, then WPath was allocated so we need to free it.\r
441 */\r
442 if(MPath != NULL) {\r
443 FreePool(WPath);\r
444 }\r
445 return retval;\r
53e1e5c6 446}\r
447\r
448#include <sys/poll.h>\r
449/* Returns a bit mask describing which operations could be completed immediately.\r
450\r
451 For now, assume the file system, via the shell, is always ready.\r
452\r
453 (POLLIN | POLLRDNORM) The file system is ready to be read.\r
454 (POLLOUT) The file system is ready for output.\r
455\r
456*/\r
457static\r
458short\r
459EFIAPI\r
460da_ShellPoll(\r
461 struct __filedes *filp,\r
462 short events\r
463 )\r
464{\r
465 UINT32 RdyMask;\r
466 short retval = 0;\r
467\r
468 RdyMask = (UINT32)filp->Oflags;\r
469\r
470 switch(RdyMask & O_ACCMODE) {\r
471 case O_RDONLY:\r
472 retval = (POLLIN | POLLRDNORM);\r
473 break;\r
474\r
475 case O_WRONLY:\r
476 retval = POLLOUT;\r
477 break;\r
478\r
479 case O_RDWR:\r
480 retval = (POLLIN | POLLRDNORM | POLLOUT);\r
481 break;\r
482\r
483 default:\r
484 retval = POLLERR;\r
485 break;\r
486 }\r
487 return (retval & (events | POLL_RETONLY));\r
488}\r
489\r
490static\r
491int\r
492EFIAPI\r
493da_ShellRename(\r
494 const char *from,\r
495 const char *to\r
496 )\r
497{\r
498 RETURN_STATUS Status;\r
499 EFI_FILE_INFO *NewFileInfo;\r
500 EFI_FILE_INFO *OldFileInfo;\r
d7ce7006 501 wchar_t *NewFn;\r
53e1e5c6 502 int OldFd;\r
503 SHELL_FILE_HANDLE FileHandle;\r
d7ce7006 504 wchar_t *NormalizedPath;\r
53e1e5c6 505\r
506 // Open old file\r
507 OldFd = open(from, O_RDWR, 0);\r
508 if(OldFd >= 0) {\r
509 FileHandle = (SHELL_FILE_HANDLE)gMD->fdarray[OldFd].devdata;\r
510\r
511 NewFileInfo = malloc(sizeof(EFI_FILE_INFO) + PATH_MAX);\r
512 if(NewFileInfo != NULL) {\r
513 OldFileInfo = ShellGetFileInfo( FileHandle);\r
514 if(OldFileInfo != NULL) {\r
515 // Copy the Old file info into our new buffer, and free the old.\r
d7ce7006 516 memcpy(NewFileInfo, OldFileInfo, sizeof(EFI_FILE_INFO));\r
53e1e5c6 517 FreePool(OldFileInfo);\r
d7ce7006 518 // Normalize path and convert to WCS.\r
519 NormalizedPath = NormalizePath(to);\r
520 if (NormalizedPath != NULL) {\r
53e1e5c6 521 // Strip off all but the file name portion of new\r
d7ce7006 522 NewFn = GetFileNameFromPath(NormalizedPath);\r
53e1e5c6 523 // Copy the new file name into our new file info buffer\r
d7ce7006 524 wcsncpy(NewFileInfo->FileName, NewFn, wcslen(NewFn) + 1);\r
525 // Update the size of the structure.\r
526 NewFileInfo->Size = sizeof(EFI_FILE_INFO) + StrSize(NewFn);\r
53e1e5c6 527 // Apply the new file name\r
528 Status = ShellSetFileInfo(FileHandle, NewFileInfo);\r
d7ce7006 529 free(NormalizedPath);\r
53e1e5c6 530 free(NewFileInfo);\r
531 if(Status == EFI_SUCCESS) {\r
532 // File has been successfully renamed. We are DONE!\r
533 return 0;\r
534 }\r
535 errno = EFI2errno( Status );\r
536 EFIerrno = Status;\r
537 }\r
538 else {\r
d7ce7006 539 free(NewFileInfo);\r
540 errno = ENOMEM;\r
541 }\r
542 }\r
543 else {\r
544 free(NewFileInfo);\r
53e1e5c6 545 errno = EIO;\r
546 }\r
547 }\r
548 else {\r
549 errno = ENOMEM;\r
550 }\r
551 }\r
552 return -1;\r
553}\r
554\r
555static\r
556int\r
557EFIAPI\r
558da_ShellRmdir(\r
559 struct __filedes *filp\r
560 )\r
561{\r
562 SHELL_FILE_HANDLE FileHandle;\r
563 RETURN_STATUS Status = RETURN_SUCCESS;\r
564 EFI_FILE_INFO *FileInfo = NULL;\r
565 int Count = 0;\r
566 BOOLEAN NoFile = FALSE;\r
567\r
568 errno = 0; // Make it easier to see if we have an error later\r
569\r
570 FileHandle = (SHELL_FILE_HANDLE)filp->devdata;\r
571\r
572 FileInfo = ShellGetFileInfo(FileHandle);\r
573 if(FileInfo != NULL) {\r
574 if((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {\r
575 errno = ENOTDIR;\r
576 }\r
577 else {\r
578 // See if the directory has any entries other than ".." and ".".\r
579 FreePool(FileInfo); // Free up the buffer from ShellGetFileInfo()\r
580 Status = ShellFindFirstFile( FileHandle, &FileInfo);\r
581 if(Status == RETURN_SUCCESS) {\r
582 ++Count;\r
583 while(Count < 3) {\r
584 Status = ShellFindNextFile( FileHandle, FileInfo, &NoFile);\r
585 if(Status == RETURN_SUCCESS) {\r
586 if(NoFile) {\r
587 break;\r
588 }\r
589 ++Count;\r
590 }\r
591 else {\r
592 Count = 99;\r
593 }\r
594 }\r
595 FreePool(FileInfo); // Free buffer from ShellFindFirstFile()\r
596 if(Count < 3) {\r
597 // Directory is empty\r
598 Status = ShellDeleteFile( &FileHandle);\r
599 if(Status == RETURN_SUCCESS) {\r
600 EFIerrno = RETURN_SUCCESS;\r
601 return 0;\r
602 /* ######## SUCCESSFUL RETURN ######## */\r
603 }\r
604 }\r
605 else {\r
606 if(Count == 99) {\r
607 errno = EIO;\r
608 }\r
609 else {\r
610 errno = ENOTEMPTY;\r
611 }\r
612 }\r
613 }\r
614 }\r
615 }\r
616 else {\r
617 errno = EIO;\r
618 }\r
619 EFIerrno = Status;\r
620 if(errno == 0) {\r
621 errno = EFI2errno( Status );\r
622 }\r
623 return -1;\r
624}\r
625\r
626/** Construct an instance of the abstract Shell device.\r
627\r
628 Allocate the instance structure and populate it with the information for\r
629 the device.\r
630**/\r
631RETURN_STATUS\r
632EFIAPI\r
633__ctor_DevShell(\r
634 IN EFI_HANDLE ImageHandle,\r
635 IN EFI_SYSTEM_TABLE *SystemTable\r
636)\r
637{\r
638 GenericInstance *Stream;\r
639 DeviceNode *Node;\r
640 RETURN_STATUS Status;\r
641\r
642 Stream = (GenericInstance *)AllocateZeroPool(sizeof(GenericInstance));\r
643 if(Stream == NULL) {\r
644 return RETURN_OUT_OF_RESOURCES;\r
645 }\r
646\r
647 Stream->Cookie = CON_COOKIE;\r
648 Stream->InstanceNum = 1;\r
649 Stream->Dev = NULL;\r
650 Stream->Abstraction.fo_close = &da_ShellClose;\r
651 Stream->Abstraction.fo_read = &da_ShellRead;\r
652 Stream->Abstraction.fo_write = &da_ShellWrite;\r
653 Stream->Abstraction.fo_fcntl = &fnullop_fcntl;\r
654 Stream->Abstraction.fo_poll = &da_ShellPoll;\r
655 Stream->Abstraction.fo_flush = &fnullop_flush;\r
656 Stream->Abstraction.fo_stat = &da_ShellStat;\r
d7ce7006 657 Stream->Abstraction.fo_ioctl = &da_ShellIoctl;\r
53e1e5c6 658 Stream->Abstraction.fo_delete = &da_ShellDelete;\r
659 Stream->Abstraction.fo_rmdir = &da_ShellRmdir;\r
660 Stream->Abstraction.fo_mkdir = &da_ShellMkdir;\r
661 Stream->Abstraction.fo_rename = &da_ShellRename;\r
662 Stream->Abstraction.fo_lseek = &da_ShellSeek;\r
663\r
664 Node = __DevRegister(NULL, NULL, &da_ShellOpen, Stream, 1, sizeof(GenericInstance), O_RDWR);\r
665 Status = EFIerrno;\r
666 Stream->Parent = Node;\r
667\r
668 return Status;\r
669}\r
670\r
671RETURN_STATUS\r
672EFIAPI\r
673__dtor_DevShell(\r
674 IN EFI_HANDLE ImageHandle,\r
675 IN EFI_SYSTEM_TABLE *SystemTable\r
676)\r
677{\r
678 if(daDefaultDevice != NULL) {\r
679 if(daDefaultDevice->InstanceList != NULL) {\r
680 FreePool(daDefaultDevice->InstanceList);\r
681 }\r
682 FreePool(daDefaultDevice);\r
683 }\r
684 return RETURN_SUCCESS;\r
685}\r