]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/Uefi/Devices/Console/daConsole.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / LibC / Uefi / Devices / Console / daConsole.c
diff --git a/StdLib/LibC/Uefi/Devices/Console/daConsole.c b/StdLib/LibC/Uefi/Devices/Console/daConsole.c
deleted file mode 100644 (file)
index 56571af..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-/** @file\r
-  Abstract device driver for the UEFI Console.\r
-\r
-  Manipulates abstractions for stdin, stdout, stderr.\r
-\r
-  This device is a WIDE device and this driver returns WIDE\r
-  characters.  It this the responsibility of the caller to convert between\r
-  narrow and wide characters in order to perform the desired operations.\r
-\r
-  The devices status as a wide device is indicatd by _S_IWTTY being set in\r
-  f_iflags.\r
-\r
-  Copyright (c) 2016, Daryl McDaniel. All rights reserved.<BR>\r
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials are licensed and made available under\r
-  the terms and conditions of the BSD License that accompanies this distribution.\r
-  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#include  <Uefi.h>\r
-#include  <Library/BaseLib.h>\r
-#include  <Library/MemoryAllocationLib.h>\r
-#include  <Library/UefiBootServicesTableLib.h>\r
-#include  <Library/DebugLib.h>\r
-#include  <Protocol/SimpleTextIn.h>\r
-#include  <Protocol/SimpleTextOut.h>\r
-\r
-#include  <LibConfig.h>\r
-\r
-#include  <errno.h>\r
-#include  <wctype.h>\r
-#include  <wchar.h>\r
-#include  <stdarg.h>\r
-#include  <sys/fcntl.h>\r
-#include  <unistd.h>\r
-#include  <sys/termios.h>\r
-#include  <Efi/SysEfi.h>\r
-#include  <kfile.h>\r
-#include  <Device/Device.h>\r
-#include  <Device/IIO.h>\r
-#include  <MainData.h>\r
-\r
-static const CHAR16* const\r
-stdioNames[NUM_SPECIAL]   = {\r
-  L"stdin:", L"stdout:", L"stderr:"\r
-};\r
-\r
-static const int stdioFlags[NUM_SPECIAL] = {\r
-  O_RDONLY,             // stdin\r
-  O_WRONLY,             // stdout\r
-  O_WRONLY              // stderr\r
-};\r
-\r
-static DeviceNode    *ConNode[NUM_SPECIAL];\r
-static ConInstance   *ConInstanceList;\r
-\r
-static cIIO          *IIO;\r
-\r
-/* Flags settable by Ioctl */\r
-static BOOLEAN        TtyCooked;\r
-static BOOLEAN        TtyEcho;\r
-\r
-/** Convert string from MBCS to WCS and translate \n to \r\n.\r
-\r
-    It is the caller's responsibility to ensure that dest is\r
-    large enough to hold the converted results.  It is guaranteed\r
-    that there will be fewer than n characters placed in dest.\r
-\r
-    @param[out]     dest    WCS buffer to receive the converted string.\r
-    @param[in]      buf     MBCS string to convert to WCS.\r
-    @param[in]      n       Number of BYTES contained in buf.\r
-    @param[in,out]  Cs      Pointer to the character state object for this stream\r
-\r
-    @return   The number of BYTES consumed from buf.\r
-**/\r
-ssize_t\r
-WideTtyCvt( CHAR16 *dest, const char *buf, ssize_t n, mbstate_t *Cs)\r
-{\r
-  ssize_t i     = 0;\r
-  int     numB  = 0;\r
-  wchar_t wc[2];\r
-\r
-  while(n > 0) {\r
-    numB = (int)mbrtowc(wc, buf, MIN(MB_LEN_MAX,n), Cs);\r
-    if( numB == 0) {\r
-      break;\r
-    };\r
-    if(numB < 0) {    // If an unconvertable character, replace it.\r
-      wc[0] = BLOCKELEMENT_LIGHT_SHADE;\r
-      numB = 1;\r
-    }\r
-    if(wc[0] == L'\n') {\r
-      *dest++ = L'\r';\r
-      ++i;\r
-    }\r
-    *dest++ = (CHAR16)wc[0];\r
-    i += numB;\r
-    n -= numB;\r
-    buf += numB;\r
-  }\r
-  *dest = 0;\r
-  return i;\r
-}\r
-\r
-/** Position the console cursor to the coordinates specified by Position.\r
-\r
-    @param[in]  filp      Pointer to the file descriptor structure for this file.\r
-    @param[in]  Position  A value containing the target X and Y coordinates.\r
-    @param[in]  whence    Ignored by the Console device.\r
-\r
-    @retval   Position    Success.  Returns a copy of the Position argument.\r
-    @retval   -1          filp is not associated with a valid console stream.\r
-    @retval   -1          This console stream is attached to stdin.\r
-    @retval   -1          The SetCursorPosition operation failed.\r
-**/\r
-static\r
-off_t\r
-EFIAPI\r
-da_ConSeek(\r
-  struct __filedes   *filp,\r
-  off_t               Position,\r
-  int                 whence      ///< Ignored by Console\r
-)\r
-{\r
-  ConInstance                       *Stream;\r
-  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *Proto;\r
-  XY_OFFSET                          CursorPos;\r
-\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return -1;    // Looks like a bad This pointer\r
-  }\r
-  if(Stream->InstanceNum == STDIN_FILENO) {\r
-    // Seek is not valid for stdin\r
-    EFIerrno = RETURN_UNSUPPORTED;\r
-    return -1;\r
-  }\r
-  // Everything is OK to do the final verification and "seek".\r
-  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
-  CursorPos.Offset = Position;\r
-\r
-  EFIerrno = Proto->SetCursorPosition(Proto,\r
-                                      (INTN)CursorPos.XYpos.Column,\r
-                                      (INTN)CursorPos.XYpos.Row);\r
-\r
-  if(RETURN_ERROR(EFIerrno)) {\r
-    return -1;\r
-  }\r
-  else {\r
-    return Position;\r
-  }\r
-}\r
-\r
-/* Write a NULL terminated WCS to the EFI console.\r
-\r
-  NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters received\r
-        by da_ConWrite are WIDE characters.  It is the responsibility of the\r
-        higher-level function(s) to perform any necessary conversions.\r
-\r
-  @param[in,out]  BufferSize  Number of characters in Buffer.\r
-  @param[in]      Buffer      The WCS string to be displayed\r
-\r
-  @return   The number of Characters written.\r
-*/\r
-static\r
-ssize_t\r
-EFIAPI\r
-da_ConWrite(\r
-  IN  struct __filedes     *filp,\r
-  IN  off_t                *Position,\r
-  IN  size_t                BufferSize,\r
-  IN  const void           *Buffer\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;\r
-  ConInstance                        *Stream;\r
-  ssize_t                             NumChar;\r
-  XY_OFFSET                          CursorPos;\r
-\r
-  NumChar = -1;\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return -1;    // Looks like a bad This pointer\r
-  }\r
-  if(Stream->InstanceNum == STDIN_FILENO) {\r
-    // Write is not valid for stdin\r
-    EFIerrno = RETURN_UNSUPPORTED;\r
-    return -1;\r
-  }\r
-  // Everything is OK to do the write.\r
-  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
-\r
-  Status = EFI_SUCCESS;\r
-  if(Position != NULL) {\r
-    CursorPos.Offset = *Position;\r
-\r
-    Status = Proto->SetCursorPosition(Proto,\r
-                                      (INTN)CursorPos.XYpos.Column,\r
-                                      (INTN)CursorPos.XYpos.Row);\r
-\r
-  }\r
-  if(!RETURN_ERROR(Status)) {\r
-  // Send the Unicode buffer to the console\r
-    Status = Proto->OutputString( Proto, (CHAR16 *)Buffer);\r
-  }\r
-\r
-  // Depending on status, update BufferSize and return\r
-  if(!RETURN_ERROR(Status)) {\r
-    NumChar = BufferSize;\r
-    Stream->NumWritten += NumChar;\r
-  }\r
-  EFIerrno = Status;      // Make error reason available to caller\r
-  return NumChar;\r
-}\r
-\r
-/** Read a wide character from the console input device.\r
-\r
-    Returns NUL or a translated input character.\r
-\r
-    @param[in]      filp          Pointer to file descriptor for this file.\r
-    @param[out]     Buffer        Buffer in which to place the read character.\r
-\r
-    @retval    EFI_DEVICE_ERROR   A hardware error has occurred.\r
-    @retval    EFI_NOT_READY      No data is available.  Try again later.\r
-    @retval    EFI_SUCCESS        One wide character has been placed in Character\r
-                                    - 0x0000  NUL, ignore this\r
-                                    - Otherwise, should be a good wide character in Character\r
-**/\r
-static\r
-EFI_STATUS\r
-da_ConRawRead (\r
-  IN OUT  struct __filedes   *filp,\r
-     OUT  wchar_t            *Character\r
-)\r
-{\r
-  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *Proto;\r
-  ConInstance                      *Stream;\r
-  cIIO                             *Self;\r
-  EFI_STATUS                        Status;\r
-  EFI_INPUT_KEY                     Key = {0,0};\r
-  wchar_t                           RetChar;\r
-\r
-  Self    = (cIIO *)filp->devdata;\r
-  Stream  = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  Proto   = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
-\r
-  if(Stream->UnGetKey == CHAR_NULL) {\r
-    Status = Proto->ReadKeyStroke(Proto, &Key);\r
-  }\r
-  else {\r
-    Status  = EFI_SUCCESS;\r
-    // Use the data in the Un-get buffer\r
-    // Guaranteed that ScanCode and UnicodeChar are not both NUL\r
-    Key.ScanCode        = SCAN_NULL;\r
-    Key.UnicodeChar     = Stream->UnGetKey;\r
-    Stream->UnGetKey    = CHAR_NULL;\r
-  }\r
-  if(Status == EFI_SUCCESS) {\r
-    // Translate the Escape Scan Code to an ESC character\r
-    if (Key.ScanCode != 0) {\r
-      if (Key.ScanCode == SCAN_ESC) {\r
-        RetChar = CHAR_ESC;\r
-      }\r
-      else if((Self->Termio.c_iflag & IGNSPEC) != 0) {\r
-        // If we are ignoring special characters, return a NUL\r
-        RetChar = 0;\r
-      }\r
-      else {\r
-        // Must be a control, function, or other non-printable key.\r
-        // Map it into the Platform portion of the Unicode private use area\r
-        RetChar = TtyFunKeyMax - Key.ScanCode;\r
-      }\r
-    }\r
-    else {\r
-      RetChar = Key.UnicodeChar;\r
-    }\r
-    *Character = RetChar;\r
-  }\r
-  else {\r
-    *Character = 0;\r
-  }\r
-  return Status;\r
-}\r
-\r
-/** Read a wide character from the console input device.\r
-\r
-  NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters returned\r
-        by da_ConRead are WIDE characters.  It is the responsibility of the\r
-        higher-level function(s) to perform any necessary conversions.\r
-\r
-    A NUL character, 0x0000, is never returned.  In the event that such a character\r
-    is encountered, the read is either retried or -1 is returned with errno set\r
-    to EAGAIN.\r
-\r
-    @param[in]      filp          Pointer to file descriptor for this file.\r
-    @param[in]      offset        Ignored.\r
-    @param[in]      BufferSize    Buffer size, in bytes.\r
-    @param[out]     Buffer        Buffer in which to place the read characters.\r
-\r
-    @retval    -1   An error has occurred.  Reason in errno and EFIerrno.\r
-    @retval    -1   No data is available.  errno is set to EAGAIN\r
-    @retval     1   One wide character has been placed in Buffer\r
-**/\r
-static\r
-ssize_t\r
-EFIAPI\r
-da_ConRead(\r
-  IN OUT  struct __filedes   *filp,\r
-  IN OUT  off_t              *offset,         // Console ignores this\r
-  IN      size_t              BufferSize,\r
-     OUT  VOID               *Buffer\r
-)\r
-{\r
-  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *Proto;\r
-  ConInstance                      *Stream;\r
-  //cIIO                              *Self;\r
-  EFI_STATUS                        Status;\r
-  UINTN                             Edex;\r
-  ssize_t                           NumRead;\r
-  BOOLEAN                           BlockingMode;\r
-  wchar_t                           RetChar;\r
-\r
-  NumRead = -1;\r
-  if(BufferSize < sizeof(wchar_t)) {\r
-    errno = EINVAL;     // Buffer is too small to hold one character\r
-  }\r
-  else {\r
-    Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-    Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
-    BlockingMode = (BOOLEAN)((filp->Oflags & O_NONBLOCK) == 0);\r
-\r
-    do {\r
-      Status = EFI_SUCCESS;\r
-      if(BlockingMode) {\r
-        // Read a byte in Blocking mode\r
-        Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);\r
-      }\r
-\r
-      /*  WaitForEvent should not be able to fail since\r
-            NumberOfEvents is set to constant 1 so is never 0\r
-            Event is set by the Simple Text Input protocol so should never be EVT_NOTIFY_SIGNAL\r
-            Current TPL should be TPL_APPLICATION.\r
-          ASSERT so that we catch any problems during development.\r
-      */\r
-      ASSERT(Status == EFI_SUCCESS);\r
-\r
-      Status = da_ConRawRead (filp, &RetChar);\r
-    } while ( BlockingMode &&\r
-             (RetChar == 0) &&\r
-             (Status != EFI_DEVICE_ERROR));\r
-\r
-    EFIerrno = Status;\r
-    if(Status == EFI_SUCCESS) {\r
-      // Got a keystroke.\r
-      NumRead = 1;   // Indicate that Key holds the data\r
-    }\r
-    else if(Status == EFI_NOT_READY) {\r
-      // Keystroke data is not available\r
-      errno = EAGAIN;\r
-    }\r
-    else {\r
-      // Hardware error\r
-      errno = EIO;\r
-    }\r
-    if (RetChar == 0) {\r
-      NumRead = -1;\r
-      errno = EAGAIN;\r
-    }\r
-    else {\r
-      *((wchar_t *)Buffer) = RetChar;\r
-    }\r
-  }\r
-  return NumRead;\r
-}\r
-\r
-/** Console-specific helper function for the fstat() function.\r
-\r
-    st_size       Set to number of characters read for stdin and number written for stdout and stderr.\r
-    st_physsize   1 for stdin, 0 if QueryMode error, else max X and Y coordinates for the current mode.\r
-    st_curpos     0 for stdin, current X & Y coordinates for stdout and stderr\r
-    st_blksize    Set to 1 since this is a character device\r
-\r
-    All other members of the stat structure are left unchanged.\r
-\r
-    @param[in]      filp          Pointer to file descriptor for this file.\r
-    @param[out]     Buffer        Pointer to a stat structure to receive the information.\r
-    @param[in,out]  Something     Ignored.\r
-\r
-    @retval   0   Successful completion.\r
-    @retval   -1  Either filp is not associated with a console stream, or\r
-                  Buffer is NULL.  errno is set to EINVAL.\r
-**/\r
-static\r
-int\r
-EFIAPI\r
-da_ConStat(\r
-  struct __filedes   *filp,\r
-  struct stat        *Buffer,\r
-  void               *Something\r
-  )\r
-{\r
-  ConInstance                        *Stream;\r
-  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;\r
-  XY_OFFSET                           CursorPos;\r
-  INT32                               OutMode;\r
-  UINTN                               ModeCol;\r
-  UINTN                               ModeRow;\r
-\r
-// ConGetInfo\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if ((Stream->Cookie != CON_COOKIE) ||    // Cookie == 'IoAb'\r
-      (Buffer == NULL))\r
-  {\r
-    errno     = EINVAL;\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return -1;\r
-  }\r
-  // All of our parameters are correct, so fill in the information.\r
-  Buffer->st_blksize  = 0;   // Character device, not a block device\r
-  Buffer->st_mode     = filp->f_iflags;\r
-\r
-// ConGetPosition\r
-  if(Stream->InstanceNum == STDIN_FILENO) {\r
-    // This is stdin\r
-    Buffer->st_curpos    = 0;\r
-    Buffer->st_size      = (off_t)Stream->NumRead;\r
-    Buffer->st_physsize  = 1;\r
-  }\r
-  else {\r
-    Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
-    CursorPos.XYpos.Column  = (UINT32)Proto->Mode->CursorColumn;\r
-    CursorPos.XYpos.Row     = (UINT32)Proto->Mode->CursorRow;\r
-    Buffer->st_curpos       = (off_t)CursorPos.Offset;\r
-    Buffer->st_size         = (off_t)Stream->NumWritten;\r
-\r
-    OutMode  = Proto->Mode->Mode;\r
-    EFIerrno = Proto->QueryMode(Proto, (UINTN)OutMode, &ModeCol, &ModeRow);\r
-    if(RETURN_ERROR(EFIerrno)) {\r
-      Buffer->st_physsize = 0;\r
-    }\r
-    else {\r
-      CursorPos.XYpos.Column  = (UINT32)ModeCol;\r
-      CursorPos.XYpos.Row     = (UINT32)ModeRow;\r
-      Buffer->st_physsize     = (off_t)CursorPos.Offset;\r
-    }\r
-  }\r
-  return 0;\r
-}\r
-\r
-/** Console-specific helper for the ioctl system call.\r
-\r
-    The console device does not directly participate in ioctl operations.\r
-    This function completes the device abstraction and returns an error value\r
-    to indicate that the function is not supported for this device.\r
-\r
-    @retval   -1    Function is not supported for this device.\r
-**/\r
-static\r
-int\r
-EFIAPI\r
-da_ConIoctl(\r
-  struct __filedes   *filp,\r
-  ULONGN              cmd,\r
-  va_list             argp\r
-  )\r
-{\r
-  errno   = ENODEV;\r
-  return  -1;\r
-}\r
-\r
-/** Open an abstract Console Device.\r
-\r
-    @param[in]    DevNode       Pointer to the Device control structure for this stream.\r
-    @param[in]    filp          Pointer to the new file control structure for this stream.\r
-    @param[in]    DevInstance   Not used for the console device.\r
-    @param[in]    Path          Not used for the console device.\r
-    @param[in]    MPath         Not used for the console device.\r
-\r
-    @retval   0   This console stream has been successfully opened.\r
-    @retval   -1  The DevNode or filp pointer is NULL.\r
-    @retval   -1  DevNode does not point to a valid console stream device.\r
-**/\r
-int\r
-EFIAPI\r
-da_ConOpen(\r
-  DeviceNode         *DevNode,\r
-  struct __filedes   *filp,\r
-  int                 DevInstance,    // Not used for console devices\r
-  wchar_t            *Path,           // Not used for console devices\r
-  wchar_t            *MPath           // Not used for console devices\r
-  )\r
-{\r
-  ConInstance    *Stream;\r
-  UINT32          Instance;\r
-  int             RetVal = -1;\r
-\r
-  if((filp    != NULL)    &&\r
-      (DevNode != NULL))\r
-  {\r
-  Stream = (ConInstance *)DevNode->InstanceList;\r
-  // Quick check to see if Stream looks reasonable\r
-    if(Stream->Cookie == CON_COOKIE)\r
-    {\r
-      Instance = Stream->InstanceNum;\r
-      if(Instance < NUM_SPECIAL) {\r
-        gMD->StdIo[Instance] = Stream;\r
-        filp->f_iflags |= (_S_IFCHR | _S_ITTY | _S_IWTTY | _S_ICONSOLE);\r
-        filp->f_offset = 0;\r
-        filp->f_ops = &Stream->Abstraction;\r
-        filp->devdata = (void *)IIO;\r
-        RetVal = 0;\r
-      }\r
-    }\r
-  }\r
-  if (RetVal < 0) {\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    errno = EINVAL;\r
-  }\r
-  return RetVal;\r
-\r
-}\r
-\r
-/** Flush a console device's IIO buffers.\r
-\r
-    Flush the IIO Input or Output buffers associated with the specified file.\r
-\r
-    If the console is open for output, write any unwritten data in the associated\r
-    output buffer (stdout or stderr) to the console.\r
-\r
-    If the console is open for input, discard any remaining data\r
-    in the input buffer.\r
-\r
-    @param[in]    filp    Pointer to the target file's descriptor structure.\r
-\r
-    @retval     0     Always succeeds\r
-**/\r
-static\r
-int\r
-EFIAPI\r
-da_ConFlush(\r
-  struct __filedes *filp\r
-)\r
-{\r
-  cFIFO      *OutBuf;\r
-  ssize_t     NumProc;\r
-  int         Flags;\r
-\r
-\r
-    if(filp->MyFD == STDERR_FILENO) {\r
-      OutBuf = IIO->ErrBuf;\r
-    }\r
-    else {\r
-      OutBuf = IIO->OutBuf;\r
-    }\r
-\r
-    Flags = filp->Oflags & O_ACCMODE;   // Get the device's open mode\r
-    if (Flags != O_WRONLY)  {   // (Flags == O_RDONLY) || (Flags == O_RDWR)\r
-      // Readable so discard the contents of the input buffer\r
-      IIO->InBuf->Flush(IIO->InBuf, UNICODE_STRING_MAX);\r
-    }\r
-    if (Flags != O_RDONLY)  {   // (Flags == O_WRONLY) || (Flags == O_RDWR)\r
-      // Writable so flush the output buffer\r
-      // At this point, the characters to write are in OutBuf\r
-      // First, linearize and consume the buffer\r
-      NumProc = OutBuf->Read(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);\r
-      if (NumProc > 0) {  // Optimization -- Nothing to do if no characters\r
-        gMD->UString[NumProc] = 0;   // Ensure that the buffer is terminated\r
-\r
-        /*  OutBuf always contains wide characters.\r
-            The UEFI Console (this device) always expects wide characters.\r
-            There is no need to handle devices that expect narrow characters\r
-            like the device-independent functions do.\r
-        */\r
-        // Do the actual write of the data to the console\r
-        (void) da_ConWrite(filp, NULL, NumProc, gMD->UString);\r
-        // Paranoia -- Make absolutely sure that OutBuf is empty in case fo_write\r
-        // wasn't able to consume everything.\r
-        OutBuf->Flush(OutBuf, UNICODE_STRING_MAX);\r
-      }\r
-    }\r
-  return 0;\r
-}\r
-\r
-/** Close an open file.\r
-\r
-    @param[in]  filp    Pointer to the file descriptor structure for this file.\r
-\r
-    @retval   0     The file has been successfully closed.\r
-    @retval   -1    filp does not point to a valid console descriptor.\r
-**/\r
-static\r
-int\r
-EFIAPI\r
-da_ConClose(\r
-  IN      struct __filedes   *filp\r
-)\r
-{\r
-  ConInstance    *Stream;\r
-\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
-    errno     = EINVAL;\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return -1;    // Looks like a bad File Descriptor pointer\r
-  }\r
-  // Stream and filp look OK, so continue.\r
-  // Flush the I/O buffers\r
-  (void) da_ConFlush(filp);\r
-\r
-  // Break the connection to IIO\r
-  filp->devdata = NULL;\r
-\r
-  gMD->StdIo[Stream->InstanceNum] = NULL;   // Mark the stream as closed\r
-  return 0;\r
-}\r
-\r
-#include  <sys/poll.h>\r
-/*  Returns a bit mask describing which operations could be completed immediately.\r
-\r
-    Testable Events for this device are:\r
-    (POLLIN | POLLRDNORM)   A Unicode character is available to read\r
-    (POLLIN)                A ScanCode is ready.\r
-    (POLLOUT)               The device is ready for output - always set on stdout and stderr.\r
-\r
-    Non-testable Events which are only valid in return values are:\r
-      POLLERR                 The specified device is not one of stdin, stdout, or stderr.\r
-      POLLHUP                 The specified stream has been disconnected\r
-      POLLNVAL                da_ConPoll was called with an invalid parameter.\r
-\r
-  NOTE: The "Events" handled by this function are not UEFI events.\r
-\r
-    @param[in]  filp      Pointer to the file control structure for this stream.\r
-    @param[in]  events    A bit mask identifying the events to be examined\r
-                          for this device.\r
-\r
-    @return   Returns a bit mask comprised of both testable and non-testable\r
-              event codes indicating both the state of the operation and the\r
-              status of the device.\r
-*/\r
-static\r
-short\r
-EFIAPI\r
-da_ConPoll(\r
-  struct __filedes   *filp,\r
-  short              events\r
-  )\r
-{\r
-  ConInstance                      *Stream;\r
-  EFI_STATUS                        Status = RETURN_SUCCESS;\r
-  short                             RdyMask = 0;\r
-\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
-    errno     = EINVAL;\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return POLLNVAL;    // Looks like a bad filp pointer\r
-  }\r
-  if(Stream->InstanceNum == 0) {\r
-    // STDIN: Only input is supported for this device\r
-    Status = da_ConRawRead (filp, &Stream->UnGetKey);\r
-    if(Status == RETURN_SUCCESS) {\r
-      RdyMask = POLLIN;\r
-      if ((Stream->UnGetKey <  TtyFunKeyMin)   ||\r
-          (Stream->UnGetKey >= TtyFunKeyMax))\r
-      {\r
-        RdyMask |= POLLRDNORM;\r
-      }\r
-    }\r
-    else {\r
-      Stream->UnGetKey  = CHAR_NULL;\r
-    }\r
-  }\r
-  else if(Stream->InstanceNum < NUM_SPECIAL) {  // Not 0, is it 1 or 2?\r
-    // (STDOUT || STDERR): Only output is supported for this device\r
-    RdyMask = POLLOUT;\r
-  }\r
-  else {\r
-    RdyMask = POLLERR;    // Not one of the standard streams\r
-  }\r
-  EFIerrno = Status;\r
-\r
-  return (RdyMask & (events | POLL_RETONLY));\r
-}\r
-\r
-/** Construct the Console stream devices: stdin, stdout, stderr.\r
-\r
-    Allocate the instance structure and populate it with the information for\r
-    each stream device.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-__Cons_construct(\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-)\r
-{\r
-  ConInstance    *Stream;\r
-  RETURN_STATUS   Status;\r
-  int             i;\r
-\r
-  Status = RETURN_OUT_OF_RESOURCES;\r
-  ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));\r
-  if(ConInstanceList != NULL) {\r
-    IIO = New_cIIO();\r
-    if(IIO == NULL) {\r
-      FreePool(ConInstanceList);\r
-    }\r
-    else {\r
-      Status = RETURN_SUCCESS;\r
-      for( i = 0; i < NUM_SPECIAL; ++i) {\r
-        // Get pointer to instance.\r
-        Stream = &ConInstanceList[i];\r
-\r
-        Stream->Cookie      = CON_COOKIE;\r
-        Stream->InstanceNum = i;\r
-        Stream->CharState.A = 0;    // Start in the initial state\r
-\r
-        switch(i) {\r
-          case STDIN_FILENO:\r
-            Stream->Dev = SystemTable->ConIn;\r
-            break;\r
-          case STDOUT_FILENO:\r
-            Stream->Dev = SystemTable->ConOut;\r
-            break;\r
-          case STDERR_FILENO:\r
-            if(SystemTable->StdErr == NULL) {\r
-              Stream->Dev = SystemTable->ConOut;\r
-            }\r
-            else {\r
-              Stream->Dev = SystemTable->StdErr;\r
-            }\r
-            break;\r
-          default:\r
-            return RETURN_VOLUME_CORRUPTED;     // This is a "should never happen" case.\r
-        }\r
-\r
-        Stream->Abstraction.fo_close    = &da_ConClose;\r
-        Stream->Abstraction.fo_read     = &da_ConRead;\r
-        Stream->Abstraction.fo_write    = &da_ConWrite;\r
-        Stream->Abstraction.fo_stat     = &da_ConStat;\r
-        Stream->Abstraction.fo_lseek    = &da_ConSeek;\r
-        Stream->Abstraction.fo_fcntl    = &fnullop_fcntl;\r
-        Stream->Abstraction.fo_ioctl    = &da_ConIoctl;\r
-        Stream->Abstraction.fo_poll     = &da_ConPoll;\r
-        Stream->Abstraction.fo_flush    = &da_ConFlush;\r
-        Stream->Abstraction.fo_delete   = &fbadop_delete;\r
-        Stream->Abstraction.fo_mkdir    = &fbadop_mkdir;\r
-        Stream->Abstraction.fo_rmdir    = &fbadop_rmdir;\r
-        Stream->Abstraction.fo_rename   = &fbadop_rename;\r
-\r
-        Stream->NumRead     = 0;\r
-        Stream->NumWritten  = 0;\r
-        Stream->UnGetKey    = CHAR_NULL;\r
-\r
-        if(Stream->Dev == NULL) {\r
-          continue;                 // No device for this stream.\r
-        }\r
-            ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream,\r
-                                       1, sizeof(ConInstance), stdioFlags[i]);\r
-        if(ConNode[i] == NULL) {\r
-              Status = EFIerrno;    // Grab error code that DevRegister produced.\r
-          break;\r
-        }\r
-        Stream->Parent = ConNode[i];\r
-      }\r
-      /* Initialize Ioctl flags until Ioctl is really implemented. */\r
-      TtyCooked = TRUE;\r
-      TtyEcho   = TRUE;\r
-    }\r
-  }\r
-  return  Status;\r
-}\r
-\r
-RETURN_STATUS\r
-EFIAPI\r
-__Cons_deconstruct(\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-)\r
-{\r
-  int   i;\r
-\r
-  for(i = 0; i < NUM_SPECIAL; ++i) {\r
-    if(ConNode[i] != NULL) {\r
-      FreePool(ConNode[i]);\r
-    }\r
-  }\r
-  if(ConInstanceList != NULL) {\r
-    FreePool(ConInstanceList);\r
-  }\r
-  if(IIO != NULL) {\r
-    IIO->Delete(IIO);\r
-    IIO = NULL;\r
-  }\r
-\r
-  return RETURN_SUCCESS;\r
-}\r
-\r
-/* ######################################################################### */\r
-#if 0 /* Not implemented (yet?) for Console */\r
-\r
-static\r
-int\r
-EFIAPI\r
-da_ConCntl(\r
-  struct __filedes *filp,\r
-  UINT32,\r
-  void *,\r
-  void *\r
-  )\r
-{\r
-}\r
-#endif  /* Not implemented for Console */\r