]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
Update to support EFI_SIMPLE_INPUT_EX protocol
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitter.c
index dc391e33bced6ffddaea977b0a8da446f42bfcc7..93edf82ed6da6cb0584d9854437640f324487778 100644 (file)
@@ -43,6 +43,21 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
   0,\r
   (EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,\r
   0,\r
+  {\r
+    ConSplitterTextInResetEx,\r
+    ConSplitterTextInReadKeyStrokeEx,\r
+    (EFI_EVENT) NULL,\r
+    ConSplitterTextInSetState,\r
+    ConSplitterTextInRegisterKeyNotify,\r
+    ConSplitterTextInUnregisterKeyNotify\r
+  },\r
+  0,\r
+  (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **) NULL,\r
+  0,\r
+  {\r
+    (struct _LIST_ENTRY     *) NULL,\r
+    (struct _LIST_ENTRY     *) NULL\r
+  },\r
 \r
   {\r
     ConSplitterSimplePointerReset,\r
@@ -367,6 +382,8 @@ Returns:
                     &mConIn.VirtualHandle,\r
                     &gEfiSimpleTextInProtocolGuid,\r
                     &mConIn.TextIn,\r
+                    &gEfiSimpleTextInputExProtocolGuid,\r
+                    &mConIn.TextInEx,\r
                     &gEfiSimplePointerProtocolGuid,\r
                     &mConIn.SimplePointer,\r
                     &gEfiPrimaryConsoleInDeviceGuid,\r
@@ -514,6 +531,30 @@ Returns:
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Buffer for Simple Text Input Ex Protocol\r
+  //  \r
+  Status = ConSplitterGrowBuffer (\r
+             sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
+             &ConInPrivate->TextInExListCount,\r
+             (VOID **) &ConInPrivate->TextInExList\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_WAIT,\r
+                  TPL_NOTIFY,\r
+                  ConSplitterTextInWaitForKey,\r
+                  ConInPrivate,\r
+                  &ConInPrivate->TextInEx.WaitForKeyEx\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  InitializeListHead (&ConInPrivate->NotifyList); \r
+\r
+\r
   ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
 \r
   Status = ConSplitterGrowBuffer (\r
@@ -898,6 +939,7 @@ Returns:
 {\r
   EFI_STATUS                     Status;\r
   EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
 \r
   //\r
   // Start ConSplitter on ControllerHandle, and create the virtual\r
@@ -915,6 +957,23 @@ Returns:
     return Status;\r
   }\r
 \r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  (VOID **) &TextInEx,\r
+                  This->DriverBindingHandle,\r
+                  mConIn.VirtualHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }  \r
+\r
   return ConSplitterTextInAddDevice (&mConIn, TextIn);\r
 }\r
 \r
@@ -1195,10 +1254,29 @@ Returns:
   EFI_STATUS                     Status;\r
   EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
 \r
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
   if (NumberOfChildren == 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  (VOID **) &TextInEx,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = ConSplitterTextInExDeleteDevice (&mConIn, TextInEx);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  \r
   Status = ConSplitterStop (\r
             This,\r
             ControllerHandle,\r
@@ -1512,6 +1590,66 @@ Returns:
   return EFI_NOT_FOUND;\r
 }\r
 \r
+EFI_STATUS\r
+ConSplitterTextInExAddDevice (\r
+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA         *Private,\r
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL     *TextInEx\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // If the TextInEx List is full, enlarge it by calling growbuffer().\r
+  //\r
+  if (Private->CurrentNumberOfExConsoles >= Private->TextInExListCount) {\r
+    Status = ConSplitterGrowBuffer (\r
+              sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
+              &Private->TextInExListCount,\r
+              (VOID **) &Private->TextInExList\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+  //\r
+  // Add the new text-in device data structure into the Text In List.\r
+  //\r
+  Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;\r
+  Private->CurrentNumberOfExConsoles++;\r
+\r
+  //\r
+  // Extra CheckEvent added to reduce the double CheckEvent() in UI.c\r
+  //\r
+  gBS->CheckEvent (TextInEx->WaitForKeyEx);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ConSplitterTextInExDeleteDevice (\r
+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA         *Private,\r
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL     *TextInEx\r
+  )\r
+{\r
+  UINTN Index;\r
+  //\r
+  // Remove the specified text-in device data structure from the Text In List,\r
+  // and rearrange the remaining data structures in the Text In List.\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+    if (Private->TextInExList[Index] == TextInEx) {\r
+      for (Index = Index; Index < Private->CurrentNumberOfExConsoles - 1; Index++) {\r
+        Private->TextInExList[Index] = Private->TextInExList[Index + 1];\r
+      }\r
+\r
+      Private->CurrentNumberOfExConsoles--;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
 EFI_STATUS\r
 ConSplitterSimplePointerAddDevice (\r
   IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,\r
@@ -2760,6 +2898,433 @@ Returns:
   }\r
 }\r
 \r
+\r
+STATIC\r
+BOOLEAN\r
+IsKeyRegistered (\r
+  IN EFI_KEY_DATA  *RegsiteredData,\r
+  IN EFI_KEY_DATA  *InputData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+  RegsiteredData    - A pointer to a buffer that is filled in with the keystroke \r
+                      state data for the key that was registered.\r
+  InputData         - A pointer to a buffer that is filled in with the keystroke \r
+                      state data for the key that was pressed.\r
+\r
+Returns:\r
+  TRUE              - Key be pressed matches a registered key.\r
+  FLASE             - Match failed. \r
+  \r
+--*/\r
+{\r
+  ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+  \r
+  if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||\r
+      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+    return FALSE;  \r
+  }      \r
+  \r
+  //\r
+  // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
+  //\r
+  if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
+      RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
+    return FALSE;    \r
+  }   \r
+  if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
+      RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+    return FALSE;    \r
+  }     \r
+  \r
+  return TRUE;\r
+\r
+}\r
+\r
+//\r
+// Simple Text Input Ex protocol functions\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInResetEx (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN BOOLEAN                            ExtendedVerification\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reset the input device and optionaly run diagnostics\r
+\r
+  Arguments:\r
+    This                 - Protocol instance pointer.\r
+    ExtendedVerification - Driver may perform diagnostics on reset.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The device was reset.\r
+    EFI_DEVICE_ERROR      - The device is not functioning properly and could \r
+                            not be reset.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    ReturnStatus;\r
+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+  UINTN                         Index;\r
+\r
+  Private                       = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  Private->KeyEventSignalState  = FALSE;\r
+\r
+  //\r
+  // return the worst status met\r
+  //\r
+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+    Status = Private->TextInExList[Index]->Reset (\r
+                                             Private->TextInExList[Index],\r
+                                             ExtendedVerification\r
+                                             );\r
+    if (EFI_ERROR (Status)) {\r
+      ReturnStatus = Status;\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInReadKeyStrokeEx (\r
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+  OUT EFI_KEY_DATA                      *KeyData\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reads the next keystroke from the input device. The WaitForKey Event can \r
+    be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    KeyData    - A pointer to a buffer that is filled in with the keystroke \r
+                 state data for the key that was pressed.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The keystroke information was returned.\r
+    EFI_NOT_READY         - There was no keystroke data availiable.\r
+    EFI_DEVICE_ERROR      - The keystroke information was not returned due to \r
+                            hardware errors.\r
+    EFI_INVALID_PARAMETER - KeyData is NULL.                        \r
+\r
+--*/\r
+{\r
+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         Index;\r
+  EFI_KEY_DATA                  CurrentKeyData;\r
+\r
+  \r
+  if (KeyData == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+  if (Private->PasswordEnabled) {\r
+    //\r
+    // If StdIn Locked return not ready\r
+    //\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  Private->KeyEventSignalState = FALSE;\r
+\r
+  KeyData->Key.UnicodeChar  = 0;\r
+  KeyData->Key.ScanCode     = SCAN_NULL;\r
+\r
+  //\r
+  // if no physical console input device exists, return EFI_NOT_READY;\r
+  // if any physical console input device has key input,\r
+  // return the key and EFI_SUCCESS.\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+    Status = Private->TextInExList[Index]->ReadKeyStrokeEx (\r
+                                          Private->TextInExList[Index],\r
+                                          &CurrentKeyData\r
+                                          );\r
+    if (!EFI_ERROR (Status)) {\r
+      CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_READY;  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInSetState (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_KEY_TOGGLE_STATE               *KeyToggleState\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set certain state for the input device.\r
+\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    KeyToggleState        - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+                            state for the input device.\r
+                          \r
+  Returns:                \r
+    EFI_SUCCESS           - The device state was set successfully.\r
+    EFI_DEVICE_ERROR      - The device is not functioning correctly and could \r
+                            not have the setting adjusted.\r
+    EFI_UNSUPPORTED       - The device does not have the ability to set its state.\r
+    EFI_INVALID_PARAMETER - KeyToggleState is NULL.                       \r
+\r
+--*/   \r
+{\r
+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         Index;\r
+\r
+  if (KeyToggleState == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // if no physical console input device exists, return EFI_SUCCESS;\r
+  // otherwise return the status of setting state of physical console input device\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+    Status = Private->TextInExList[Index]->SetState (\r
+                                             Private->TextInExList[Index],\r
+                                             KeyToggleState\r
+                                             );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;  \r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInRegisterKeyNotify (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_KEY_DATA                       *KeyData,\r
+  IN EFI_KEY_NOTIFY_FUNCTION            KeyNotificationFunction,\r
+  OUT EFI_HANDLE                        *NotifyHandle\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Register a notification function for a particular keystroke for the input device.\r
+\r
+  Arguments:\r
+    This                    - Protocol instance pointer.\r
+    KeyData                 - A pointer to a buffer that is filled in with the keystroke \r
+                              information data for the key that was pressed.\r
+    KeyNotificationFunction - Points to the function to be called when the key \r
+                              sequence is typed specified by KeyData.                        \r
+    NotifyHandle            - Points to the unique handle assigned to the registered notification.                          \r
+\r
+  Returns:\r
+    EFI_SUCCESS             - The notification function was registered successfully.\r
+    EFI_OUT_OF_RESOURCES    - Unable to allocate resources for necesssary data structures.\r
+    EFI_INVALID_PARAMETER   - KeyData or NotifyHandle is NULL.                       \r
+                              \r
+--*/   \r
+{\r
+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         Index;\r
+  TEXT_IN_EX_SPLITTER_NOTIFY    *NewNotify;\r
+  LIST_ENTRY                    *Link;\r
+  TEXT_IN_EX_SPLITTER_NOTIFY    *CurrentNotify;  \r
+  \r
+\r
+  if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // if no physical console input device exists, \r
+  // return EFI_SUCCESS directly.\r
+  //\r
+  if (Private->CurrentNumberOfExConsoles <= 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
+  //\r
+  for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+    CurrentNotify = CR (\r
+                      Link, \r
+                      TEXT_IN_EX_SPLITTER_NOTIFY, \r
+                      NotifyEntry, \r
+                      TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE\r
+                      );\r
+    if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+      if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+        *NotifyHandle = CurrentNotify->NotifyHandle;        \r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Allocate resource to save the notification function\r
+  //  \r
+  NewNotify = (TEXT_IN_EX_SPLITTER_NOTIFY *) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY));\r
+  if (NewNotify == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  NewNotify->NotifyHandleList = (EFI_HANDLE *) AllocateZeroPool (sizeof (EFI_HANDLE) * Private->CurrentNumberOfExConsoles);\r
+  if (NewNotify->NotifyHandleList == NULL) {\r
+    gBS->FreePool (NewNotify);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  NewNotify->Signature         = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;     \r
+  NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+  CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
+  \r
+  //\r
+  // Return the wrong status of registering key notify of \r
+  // physical console input device if meet problems\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+    Status = Private->TextInExList[Index]->RegisterKeyNotify (\r
+                                             Private->TextInExList[Index],\r
+                                             KeyData,\r
+                                             KeyNotificationFunction,\r
+                                             &NewNotify->NotifyHandleList[Index]\r
+                                             );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePool (NewNotify->NotifyHandleList);\r
+      gBS->FreePool (NewNotify);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
+  //  \r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &NewNotify->NotifyHandle,\r
+                  &gSimpleTextInExNotifyGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  InsertTailList (&mConIn.NotifyList, &NewNotify->NotifyEntry);\r
+  \r
+  *NotifyHandle                = NewNotify->NotifyHandle;  \r
+  \r
+  return EFI_SUCCESS;  \r
+  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInUnregisterKeyNotify (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_HANDLE                         NotificationHandle\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Remove a registered notification function from a particular keystroke.\r
+\r
+  Arguments:\r
+    This                    - Protocol instance pointer.    \r
+    NotificationHandle      - The handle of the notification function being unregistered.\r
+\r
+  Returns:\r
+    EFI_SUCCESS             - The notification function was unregistered successfully.\r
+    EFI_INVALID_PARAMETER   - The NotificationHandle is invalid.\r
+    EFI_NOT_FOUND           - Can not find the matching entry in database.  \r
+                              \r
+--*/   \r
+{\r
+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         Index;\r
+  TEXT_IN_EX_SPLITTER_NOTIFY    *CurrentNotify;\r
+  LIST_ENTRY                    *Link;            \r
+\r
+  if (NotificationHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  NotificationHandle,\r
+                  &gSimpleTextInExNotifyGuid,\r
+                  NULL,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // if no physical console input device exists, \r
+  // return EFI_SUCCESS directly.\r
+  //\r
+  if (Private->CurrentNumberOfExConsoles <= 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+    CurrentNotify = CR (Link, TEXT_IN_EX_SPLITTER_NOTIFY, NotifyEntry, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE);\r
+    if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+      for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+        Status = Private->TextInExList[Index]->UnregisterKeyNotify (\r
+                                                 Private->TextInExList[Index], \r
+                                                 CurrentNotify->NotifyHandleList[Index]\r
+                                                 );\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }        \r
+      }\r
+      RemoveEntryList (&CurrentNotify->NotifyEntry);      \r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                      CurrentNotify->NotifyHandle,\r
+                      &gSimpleTextInExNotifyGuid,\r
+                      NULL,\r
+                      NULL\r
+                      );\r
+      ASSERT_EFI_ERROR (Status);\r
+      gBS->FreePool (CurrentNotify->NotifyHandleList);\r
+      gBS->FreePool (CurrentNotify);\r
+      return EFI_SUCCESS;      \r
+    }    \r
+  }\r
+\r
+  return EFI_NOT_FOUND;    \r
+  \r
+}\r
+\r
+\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterSimplePointerReset (\r