Home | History | Annotate | Download | only in UefiShellDriver1CommandsLib
      1 /** @file
      2   Main file for Disconnect shell Driver1 function.
      3 
      4   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
      5   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
      6   Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
      7   This program and the accompanying materials
      8   are licensed and made available under the terms and conditions of the BSD License
      9   which accompanies this distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include "UefiShellDriver1CommandsLib.h"
     18 
     19 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
     20   {L"-r", TypeFlag},
     21   {L"-nc", TypeFlag},
     22   {NULL, TypeMax}
     23   };
     24 
     25 /**
     26   Disconnect everything.
     27 
     28   @retval EFI_SUCCESS     The operation was successful.
     29 **/
     30 EFI_STATUS
     31 DisconnectAll(
     32   VOID
     33   )
     34 {
     35   //
     36   // Stolen from UEFI 2.3 spec (May 2009 version)
     37   // Pages 171/172
     38   // Removed gBS local definition
     39   //
     40 
     41   //
     42   // Disconnect All Handles Example
     43   // The following example recusively disconnects all drivers from all
     44   // controllers in a platform.
     45   //
     46   EFI_STATUS Status;
     47 //  EFI_BOOT_SERVICES *gBS;
     48   UINTN HandleCount;
     49   EFI_HANDLE *HandleBuffer;
     50   UINTN HandleIndex;
     51   //
     52   // Retrieve the list of all handles from the handle database
     53   //
     54   Status = gBS->LocateHandleBuffer (
     55     AllHandles,
     56     NULL,
     57     NULL,
     58     &HandleCount,
     59     &HandleBuffer
     60    );
     61   if (!EFI_ERROR (Status)) {
     62     for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
     63       Status = gBS->DisconnectController (
     64         HandleBuffer[HandleIndex],
     65         NULL,
     66         NULL
     67        );
     68     }
     69     gBS->FreePool(HandleBuffer);
     70     //
     71     // end of stealing
     72     //
     73   }
     74   return (EFI_SUCCESS);
     75 }
     76 
     77 /**
     78   Function for 'disconnect' command.
     79 
     80   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
     81   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
     82 **/
     83 SHELL_STATUS
     84 EFIAPI
     85 ShellCommandRunDisconnect (
     86   IN EFI_HANDLE        ImageHandle,
     87   IN EFI_SYSTEM_TABLE  *SystemTable
     88   )
     89 {
     90   EFI_STATUS          Status;
     91   LIST_ENTRY          *Package;
     92   CHAR16              *ProblemParam;
     93   SHELL_STATUS        ShellStatus;
     94   CONST CHAR16        *Param1;
     95   CONST CHAR16        *Param2;
     96   CONST CHAR16        *Param3;
     97   EFI_HANDLE          Handle1;
     98   EFI_HANDLE          Handle2;
     99   EFI_HANDLE          Handle3;
    100   UINT64              Intermediate1;
    101   UINT64              Intermediate2;
    102   UINT64              Intermediate3;
    103 
    104   ShellStatus         = SHELL_SUCCESS;
    105 
    106   //
    107   // initialize the shell lib (we must be in non-auto-init...)
    108   //
    109   Status = ShellInitialize();
    110   ASSERT_EFI_ERROR(Status);
    111 
    112   Status = CommandInit();
    113   ASSERT_EFI_ERROR(Status);
    114 
    115   //
    116   // parse the command line
    117   //
    118   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
    119   if (EFI_ERROR(Status)) {
    120     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
    121       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"disconnect", ProblemParam);
    122       FreePool(ProblemParam);
    123       ShellStatus = SHELL_INVALID_PARAMETER;
    124     } else {
    125       ASSERT(FALSE);
    126     }
    127   } else {
    128     if (ShellCommandLineGetFlag(Package, L"-r")){
    129       if (ShellCommandLineGetCount(Package) > 1){
    130         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"disconnect");
    131         ShellStatus = SHELL_INVALID_PARAMETER;
    132       } else if (ShellCommandLineGetCount(Package) < 1) {
    133         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect");
    134         ShellStatus = SHELL_INVALID_PARAMETER;
    135       } else {
    136          Status = DisconnectAll ();
    137          //
    138          // Reconnect all consoles if -nc is not provided
    139          //
    140          if (!ShellCommandLineGetFlag (Package, L"-nc")){
    141            ShellConnectFromDevPaths (L"ConInDev");
    142            ShellConnectFromDevPaths (L"ConOutDev");
    143            ShellConnectFromDevPaths (L"ErrOutDev");
    144            ShellConnectFromDevPaths (L"ErrOut");
    145            ShellConnectFromDevPaths (L"ConIn");
    146            ShellConnectFromDevPaths (L"ConOut");
    147          }
    148       }
    149     } else if (ShellCommandLineGetFlag (Package, L"-nc")) {
    150       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect");
    151       ShellStatus = SHELL_INVALID_PARAMETER;
    152     } else {
    153       if (ShellCommandLineGetCount(Package) > 4){
    154         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"disconnect");
    155         ShellStatus = SHELL_INVALID_PARAMETER;
    156       } else if (ShellCommandLineGetCount(Package) < 2) {
    157         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect");
    158         ShellStatus = SHELL_INVALID_PARAMETER;
    159       } else {
    160         //
    161         // must have between 1 and 3 handles passed in ...
    162         //
    163         Param1  = ShellCommandLineGetRawValue(Package, 1);
    164         Param2  = ShellCommandLineGetRawValue(Package, 2);
    165         Param3  = ShellCommandLineGetRawValue(Package, 3);
    166         ShellConvertStringToUint64(Param1, &Intermediate1, TRUE, FALSE);
    167         Handle1 = Param1!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate1):NULL;
    168         ShellConvertStringToUint64(Param2, &Intermediate2, TRUE, FALSE);
    169         Handle2 = Param2!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate2):NULL;
    170         ShellConvertStringToUint64(Param3, &Intermediate3, TRUE, FALSE);
    171         Handle3 = Param3!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate3):NULL;
    172 
    173         if (Param1 != NULL && Handle1 == NULL) {
    174           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param1);
    175           ShellStatus = SHELL_INVALID_PARAMETER;
    176         } else if (Param2 != NULL && Handle2 == NULL) {
    177           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param2);
    178           ShellStatus = SHELL_INVALID_PARAMETER;
    179         } else if (Param3 != NULL && Handle3 == NULL) {
    180           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param3);
    181           ShellStatus = SHELL_INVALID_PARAMETER;
    182         } else if (Handle2 != NULL && EFI_ERROR(gBS->OpenProtocol(Handle2, &gEfiDriverBindingProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    183           ASSERT(Param2 != NULL);
    184           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_NOT), gShellDriver1HiiHandle, L"disconnect", ShellStrToUintn(Param2), L"driver handle");
    185           ShellStatus = SHELL_INVALID_PARAMETER;
    186         } else {
    187           ASSERT(Param1 != NULL);
    188           Status = gBS->DisconnectController(Handle1, Handle2, Handle3);
    189           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_3P_RESULT), gShellDriver1HiiHandle, L"Disconnect", (UINTN)Intermediate1, (UINTN)Intermediate2, (UINTN)Intermediate3, Status);
    190         }
    191       }
    192     }
    193   }
    194   if (ShellStatus == SHELL_SUCCESS) {
    195     if (Status == EFI_SECURITY_VIOLATION) {
    196       ShellStatus = SHELL_SECURITY_VIOLATION;
    197     } else if (Status == EFI_INVALID_PARAMETER) {
    198       ShellStatus = SHELL_INVALID_PARAMETER;
    199     } else if (EFI_ERROR(Status)) {
    200       ShellStatus = SHELL_NOT_FOUND;
    201     }
    202   }
    203   return (ShellStatus);
    204 }
    205