1 /** @file
2   Main file for OpenInfo shell Driver1 function.
3 
4   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this 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,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "UefiShellDriver1CommandsLib.h"
17 
18 STATIC CONST CHAR16 StringHandProt[]  = L"HandProt ";
19 STATIC CONST CHAR16 StringGetProt[]   = L"GetProt  ";
20 STATIC CONST CHAR16 StringTestProt[]  = L"TestProt ";
21 STATIC CONST CHAR16 StringChild[]     = L"Child    ";
22 STATIC CONST CHAR16 StringDriver[]    = L"Driver   ";
23 STATIC CONST CHAR16 StringExclusive[] = L"Exclusive";
24 STATIC CONST CHAR16 StringDriverEx[]  = L"DriverEx ";
25 STATIC CONST CHAR16 StringUnknown[]   = L"Unknown  ";
26 
27 /**
28   Open the database and print out all the info about TheHandle.
29 
30   @param[in] TheHandle      The handle to print info on.
31 
32   @retval EFI_SUCCESS           The operation was successful.
33   @retval EFI_INVALID_PARAMETER TheHandle was NULL.
34 **/
35 EFI_STATUS
TraverseHandleDatabase(IN CONST EFI_HANDLE TheHandle)36 TraverseHandleDatabase (
37   IN CONST EFI_HANDLE TheHandle
38   )
39 {
40   EFI_STATUS                          Status;
41   EFI_GUID                            **ProtocolGuidArray;
42   UINTN                               ArrayCount;
43   UINTN                               ProtocolIndex;
44   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
45   UINTN                               OpenInfoCount;
46   UINTN                               OpenInfoIndex;
47   CONST CHAR16                        *OpenTypeString;
48   CHAR16                              *TempString;
49   UINTN                               HandleIndex;
50   CONST CHAR16                        *Name;
51   UINTN                               ControllerIndex;
52 
53   if (TheHandle == NULL) {
54     return (EFI_INVALID_PARAMETER);
55   }
56 
57   //
58   // Retrieve the list of all the protocols on the handle
59   //
60   Status = gBS->ProtocolsPerHandle (
61                 TheHandle,
62                 &ProtocolGuidArray,
63                 &ArrayCount
64                );
65   ASSERT_EFI_ERROR(Status);
66   if (!EFI_ERROR (Status)) {
67 
68     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
69       //
70       // print out the human readable name for this one.
71       //
72       TempString = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], NULL);
73       if (TempString == NULL) {
74         continue;
75       }
76       ShellPrintEx(-1, -1, L"%H%s%N\r\n", TempString);
77       FreePool(TempString);
78 
79       //
80       // Retrieve the list of agents that have opened each protocol
81       //
82       Status = gBS->OpenProtocolInformation (
83                     TheHandle,
84                     ProtocolGuidArray[ProtocolIndex],
85                     &OpenInfo,
86                     &OpenInfoCount
87                    );
88       ASSERT_EFI_ERROR(Status);
89       if (!EFI_ERROR (Status)) {
90         for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
91           switch (OpenInfo[OpenInfoIndex].Attributes) {
92             case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:  OpenTypeString = StringHandProt;  break;
93             case EFI_OPEN_PROTOCOL_GET_PROTOCOL:        OpenTypeString = StringGetProt;   break;
94             case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:       OpenTypeString = StringTestProt;  break;
95             case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER: OpenTypeString = StringChild;     break;
96             case EFI_OPEN_PROTOCOL_BY_DRIVER:           OpenTypeString = StringDriver;    break;
97             case EFI_OPEN_PROTOCOL_EXCLUSIVE:           OpenTypeString = StringExclusive; break;
98             case EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE:
99                                                         OpenTypeString = StringDriverEx;  break;
100             default:                                    OpenTypeString = StringUnknown;   break;
101           }
102           HandleIndex     = ConvertHandleToHandleIndex(OpenInfo[OpenInfoIndex].AgentHandle);
103           Name            = GetStringNameFromHandle(OpenInfo[OpenInfoIndex].AgentHandle, NULL);
104           ControllerIndex = ConvertHandleToHandleIndex(OpenInfo[OpenInfoIndex].ControllerHandle);
105           if (ControllerIndex != 0) {
106             ShellPrintHiiEx(
107               -1,
108               -1,
109               NULL,
110               STRING_TOKEN(STR_OPENINFO_LINE),
111               gShellDriver1HiiHandle,
112               HandleIndex,
113               ControllerIndex,
114               OpenInfo[OpenInfoIndex].OpenCount,
115               OpenTypeString,
116               Name
117              );
118           } else {
119             ShellPrintHiiEx(
120               -1,
121               -1,
122               NULL,
123               STRING_TOKEN(STR_OPENINFO_MIN_LINE),
124               gShellDriver1HiiHandle,
125               HandleIndex,
126               OpenInfo[OpenInfoIndex].OpenCount,
127               OpenTypeString,
128               Name
129              );
130           }
131         }
132         FreePool (OpenInfo);
133       }
134     }
135     FreePool (ProtocolGuidArray);
136   }
137 
138   return Status;
139 }
140 
141 /**
142   Function for 'openinfo' command.
143 
144   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
145   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
146 **/
147 SHELL_STATUS
148 EFIAPI
ShellCommandRunOpenInfo(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)149 ShellCommandRunOpenInfo (
150   IN EFI_HANDLE        ImageHandle,
151   IN EFI_SYSTEM_TABLE  *SystemTable
152   )
153 {
154   EFI_STATUS          Status;
155   LIST_ENTRY          *Package;
156   CHAR16              *ProblemParam;
157   SHELL_STATUS        ShellStatus;
158   EFI_HANDLE          TheHandle;
159   CONST CHAR16        *Param1;
160   UINT64              Intermediate;
161 
162   ShellStatus         = SHELL_SUCCESS;
163 
164   //
165   // initialize the shell lib (we must be in non-auto-init...)
166   //
167   Status = ShellInitialize();
168   ASSERT_EFI_ERROR(Status);
169 
170   Status = CommandInit();
171   ASSERT_EFI_ERROR(Status);
172 
173   //
174   // parse the command line
175   //
176   Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
177   if (EFI_ERROR(Status)) {
178     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
179       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"openinfo", ProblemParam);
180       FreePool(ProblemParam);
181       ShellStatus = SHELL_INVALID_PARAMETER;
182     } else {
183       ASSERT(FALSE);
184     }
185   } else {
186     if (ShellCommandLineGetCount(Package) > 2){
187       //
188       // error for too many parameters
189       //
190       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"openinfo");
191       ShellStatus = SHELL_INVALID_PARAMETER;
192     } else if (ShellCommandLineGetCount(Package) == 0) {
193       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"openinfo");
194       ShellStatus = SHELL_INVALID_PARAMETER;
195     } else {
196       Param1 = ShellCommandLineGetRawValue(Package, 1);
197       Status = ShellConvertStringToUint64(Param1, &Intermediate, TRUE, FALSE);
198       if (EFI_ERROR(Status) || Param1 == NULL || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL){
199         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"openinfo", Param1);
200         ShellStatus = SHELL_INVALID_PARAMETER;
201       } else {
202         TheHandle = ConvertHandleIndexToHandle((UINTN)Intermediate);
203         ASSERT(TheHandle != NULL);
204         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_OPENINFO_HEADER_LINE), gShellDriver1HiiHandle, (UINTN)Intermediate, TheHandle);
205 
206         Status = TraverseHandleDatabase (TheHandle);
207         if (!EFI_ERROR(Status)) {
208         } else {
209           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"openinfo", Param1);
210           ShellStatus = SHELL_NOT_FOUND;
211         }
212       }
213     }
214   }
215   return (ShellStatus);
216 }
217