}\r
\r
/**\r
- Checks if a command is already on the list.\r
+ Find a dynamic command protocol instance given a command name string\r
+\r
+ @param CommandString the command name string\r
+\r
+ @return instance the command protocol instance, if dynamic command instance found\r
+ @retval NULL no dynamic command protocol instance found for name\r
+**/\r
+CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *\r
+EFIAPI\r
+ShellCommandFindDynamicCommand (\r
+ IN CONST CHAR16 *CommandString\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *CommandHandleList;\r
+ EFI_HANDLE *NextCommand;\r
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;\r
+\r
+ CommandHandleList = GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid);\r
+ if (CommandHandleList == NULL) {\r
+ //\r
+ // not found or out of resources\r
+ //\r
+ return NULL; \r
+ }\r
+\r
+ for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {\r
+ Status = gBS->HandleProtocol(\r
+ *NextCommand,\r
+ &gEfiShellDynamicCommandProtocolGuid,\r
+ (VOID **)&DynamicCommand\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (gUnicodeCollation->StriColl(\r
+ gUnicodeCollation,\r
+ (CHAR16*)CommandString,\r
+ (CHAR16*)DynamicCommand->CommandName) == 0 \r
+ ){\r
+ FreePool(CommandHandleList);\r
+ return (DynamicCommand);\r
+ }\r
+ }\r
+\r
+ FreePool(CommandHandleList);\r
+ return (NULL);\r
+}\r
+\r
+/**\r
+ Checks if a command exists as a dynamic command protocol instance\r
\r
@param[in] CommandString The command string to check for on the list.\r
**/\r
BOOLEAN\r
EFIAPI\r
-ShellCommandIsCommandOnList (\r
- IN CONST CHAR16 *CommandString\r
+ShellCommandDynamicCommandExists (\r
+ IN CONST CHAR16 *CommandString\r
+ )\r
+{\r
+ return (ShellCommandFindDynamicCommand(CommandString) != NULL);\r
+}\r
+\r
+/**\r
+ Checks if a command is already on the internal command list.\r
+\r
+ @param[in] CommandString The command string to check for on the list.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellCommandIsCommandOnInternalList(\r
+ IN CONST CHAR16 *CommandString\r
)\r
{\r
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;\r
}\r
\r
/**\r
- Get the help text for a command.\r
+ Checks if a command exists, either internally or through the dynamic command protocol.\r
+\r
+ @param[in] CommandString The command string to check for on the list.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellCommandIsCommandOnList(\r
+ IN CONST CHAR16 *CommandString\r
+ )\r
+{\r
+ if (ShellCommandIsCommandOnInternalList(CommandString)) {\r
+ return TRUE;\r
+ }\r
+\r
+ return ShellCommandDynamicCommandExists(CommandString);\r
+}\r
+\r
+/**\r
+ Get the help text for a dynamic command.\r
+\r
+ @param[in] CommandString The command name.\r
+\r
+ @retval NULL No help text was found.\r
+ @return String of help text. Caller required to free.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+ShellCommandGetDynamicCommandHelp(\r
+ IN CONST CHAR16 *CommandString\r
+ )\r
+{\r
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;\r
+\r
+ DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *)ShellCommandFindDynamicCommand(CommandString);\r
+ if (DynamicCommand == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
+ //\r
+ // TODO: how to get proper language?\r
+ //\r
+ return DynamicCommand->GetHelp(DynamicCommand, "en"); \r
+}\r
+\r
+/**\r
+ Get the help text for an internal command.\r
\r
@param[in] CommandString The command name.\r
\r
**/\r
CHAR16*\r
EFIAPI\r
-ShellCommandGetCommandHelp (\r
+ShellCommandGetInternalCommandHelp(\r
IN CONST CHAR16 *CommandString\r
)\r
{\r
return (NULL);\r
}\r
\r
+/**\r
+ Get the help text for a command.\r
+\r
+ @param[in] CommandString The command name.\r
+\r
+ @retval NULL No help text was found.\r
+ @return String of help text.Caller reuiqred to free.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+ShellCommandGetCommandHelp (\r
+ IN CONST CHAR16 *CommandString\r
+ )\r
+{\r
+ CHAR16 *HelpStr;\r
+ HelpStr = ShellCommandGetInternalCommandHelp(CommandString);\r
+\r
+ if (HelpStr == NULL) {\r
+ HelpStr = ShellCommandGetDynamicCommandHelp(CommandString);\r
+ }\r
+\r
+ return HelpStr;\r
+}\r
+\r
+\r
/**\r
Registers handlers of type SHELL_RUN_COMMAND and\r
SHELL_GET_MAN_FILENAME for each shell command.\r
IN OUT BOOLEAN *CanAffectLE OPTIONAL\r
)\r
{\r
- SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;\r
+ SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;\r
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;\r
\r
//\r
// assert for NULL parameters\r
gUnicodeCollation,\r
(CHAR16*)CommandString,\r
Node->CommandString) == 0\r
- ){\r
+ ){\r
if (CanAffectLE != NULL) {\r
*CanAffectLE = Node->LastError;\r
}\r
return (RETURN_SUCCESS);\r
}\r
}\r
+\r
+ //\r
+ // An internal command was not found, try to find a dynamic command\r
+ //\r
+ DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *)ShellCommandFindDynamicCommand(CommandString);\r
+ if (DynamicCommand != NULL) {\r
+ if (RetVal != NULL) {\r
+ *RetVal = DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);\r
+ } else {\r
+ DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);\r
+ }\r
+ return (RETURN_SUCCESS);\r
+ }\r
+\r
return (RETURN_NOT_FOUND);\r
}\r
\r
}\r
\r
return (EFI_SUCCESS);\r
-}
-
-/**
- Add mappings for any devices without one. Do not change any existing maps.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-EFIAPI
-ShellCommandUpdateMapping (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleList;
- UINTN Count;
- EFI_DEVICE_PATH_PROTOCOL **DevicePathList;
- CHAR16 *NewDefaultName;
- CHAR16 *NewConsistName;
- EFI_DEVICE_PATH_PROTOCOL **ConsistMappingTable;
-
- HandleList = NULL;
- Status = EFI_SUCCESS;
-
- //
- // remove mappings that represent removed devices.
- //
-
- //
- // Find each handle with Simple File System
- //
- HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);
- if (HandleList != NULL) {
- //
- // Do a count of the handles
- //
- for (Count = 0 ; HandleList[Count] != NULL ; Count++);
-
- //
- // Get all Device Paths
- //
- DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
- ASSERT(DevicePathList != NULL);
-
- for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
- DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
- }
-
- //
- // Sort all DevicePaths
- //
- PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
-
- ShellCommandConsistMappingInitialize(&ConsistMappingTable);
-
- //
- // Assign new Mappings to remainders
- //
- for (Count = 0 ; HandleList[Count] != NULL && !EFI_ERROR(Status); Count++) {
- //
- // Skip ones that already have
- //
- if (gEfiShellProtocol->GetMapFromDevicePath(&DevicePathList[Count]) != NULL) {
- continue;
- }
- //
- // Get default name
- //
- NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);
- ASSERT(NewDefaultName != NULL);
-
- //
- // Call shell protocol SetMap function now...
- //
- Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewDefaultName);
-
- if (!EFI_ERROR(Status)) {
- //
- // Now do consistent name
- //
- NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);
- if (NewConsistName != NULL) {
- Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewConsistName);
- FreePool(NewConsistName);
- }
- }
-
- FreePool(NewDefaultName);
- }
- ShellCommandConsistMappingUnInitialize(ConsistMappingTable);
- SHELL_FREE_NON_NULL(HandleList);
- SHELL_FREE_NON_NULL(DevicePathList);
-
- HandleList = NULL;
- } else {
- Count = (UINTN)-1;
- }
- //
- // Do it all over again for gEfiBlockIoProtocolGuid
- //
-
- return (Status);
-}
-
-/**
- Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.
-
- @param[in] Handle The SHELL_FILE_HANDLE to convert.
+}\r
+\r
+/**\r
+ Add mappings for any devices without one. Do not change any existing maps.\r
+\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellCommandUpdateMapping (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *HandleList;\r
+ UINTN Count;\r
+ EFI_DEVICE_PATH_PROTOCOL **DevicePathList;\r
+ CHAR16 *NewDefaultName;\r
+ CHAR16 *NewConsistName;\r
+ EFI_DEVICE_PATH_PROTOCOL **ConsistMappingTable;\r
+\r
+ HandleList = NULL;\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // remove mappings that represent removed devices.\r
+ //\r
+\r
+ //\r
+ // Find each handle with Simple File System\r
+ //\r
+ HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);\r
+ if (HandleList != NULL) {\r
+ //\r
+ // Do a count of the handles\r
+ //\r
+ for (Count = 0 ; HandleList[Count] != NULL ; Count++);\r
+\r
+ //\r
+ // Get all Device Paths\r
+ //\r
+ DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);\r
+ ASSERT(DevicePathList != NULL);\r
+\r
+ for (Count = 0 ; HandleList[Count] != NULL ; Count++) {\r
+ DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);\r
+ }\r
+\r
+ //\r
+ // Sort all DevicePaths\r
+ //\r
+ PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);\r
+\r
+ ShellCommandConsistMappingInitialize(&ConsistMappingTable);\r
+\r
+ //\r
+ // Assign new Mappings to remainders\r
+ //\r
+ for (Count = 0 ; HandleList[Count] != NULL && !EFI_ERROR(Status); Count++) {\r
+ //\r
+ // Skip ones that already have\r
+ //\r
+ if (gEfiShellProtocol->GetMapFromDevicePath(&DevicePathList[Count]) != NULL) {\r
+ continue;\r
+ }\r
+ //\r
+ // Get default name\r
+ //\r
+ NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);\r
+ ASSERT(NewDefaultName != NULL);\r
+\r
+ //\r
+ // Call shell protocol SetMap function now...\r
+ //\r
+ Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewDefaultName);\r
+\r
+ if (!EFI_ERROR(Status)) {\r
+ //\r
+ // Now do consistent name\r
+ //\r
+ NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);\r
+ if (NewConsistName != NULL) {\r
+ Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewConsistName);\r
+ FreePool(NewConsistName);\r
+ }\r
+ }\r
+\r
+ FreePool(NewDefaultName);\r
+ }\r
+ ShellCommandConsistMappingUnInitialize(ConsistMappingTable);\r
+ SHELL_FREE_NON_NULL(HandleList);\r
+ SHELL_FREE_NON_NULL(DevicePathList);\r
+\r
+ HandleList = NULL;\r
+ } else {\r
+ Count = (UINTN)-1;\r
+ }\r
+ //\r
+ // Do it all over again for gEfiBlockIoProtocolGuid\r
+ //\r
+\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.\r
+\r
+ @param[in] Handle The SHELL_FILE_HANDLE to convert.\r
\r
@return a EFI_FILE_PROTOCOL* representing the same file.\r
**/\r