)\r
{\r
ShellFileHandleRemove(FileHandle);\r
- return (FileHandleClose(FileHandle));\r
+ return (FileHandleClose(ConvertShellHandleToEfiFileProtocol(FileHandle)));\r
}\r
\r
/**\r
EFI_HANDLE MapHandle;\r
EFI_STATUS Status;\r
FILEPATH_DEVICE_PATH *FilePath;\r
+ FILEPATH_DEVICE_PATH *AlignedNode;\r
\r
PathForReturn = NULL;\r
PathSize = 0;\r
//\r
ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));\r
PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L"\\", 1);\r
- PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, FilePath->PathName, 0);\r
+\r
+ AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath);\r
+ PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, AlignedNode->PathName, 0);\r
+ FreePool(AlignedNode);\r
}\r
} // for loop of remaining nodes\r
}\r
EFI_HANDLE Handle;\r
EFI_STATUS Status;\r
\r
+ if (Path == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
MapName = NULL;\r
- ASSERT(Path != NULL);\r
+ NewPath = NULL;\r
\r
if (StrStr(Path, L":") == NULL) {\r
Cwd = EfiShellGetCurDir(NULL);\r
NewPath = AllocateZeroPool(Size);\r
ASSERT(NewPath != NULL);\r
StrCpy(NewPath, Cwd);\r
- if (NewPath[StrLen(NewPath)-1] == Path[0] == (CHAR16)L'\\') {\r
+ if ((Path[0] == (CHAR16)L'\\') &&\r
+ (NewPath[StrLen(NewPath)-1] == (CHAR16)L'\\')\r
+ ) {\r
((CHAR16*)NewPath)[StrLen(NewPath)-1] = CHAR_NULL;\r
}\r
StrCat(NewPath, Path);\r
}\r
if (Language == NULL) {\r
Lang = AllocatePool(AsciiStrSize(CompName2->SupportedLanguages));\r
+ if (Lang == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
AsciiStrCpy(Lang, CompName2->SupportedLanguages);\r
TempChar = AsciiStrStr(Lang, ";");\r
if (TempChar != NULL){\r
}\r
} else {\r
Lang = AllocatePool(AsciiStrSize(Language));\r
+ if (Lang == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
AsciiStrCpy(Lang, Language);\r
}\r
Status = CompName2->GetControllerName(CompName2, DeviceHandle, NULL, Lang, &DeviceNameToReturn);\r
FreePool(HandleList);\r
}\r
if (DeviceNameToReturn != NULL){\r
- ASSERT(BestDeviceName == NULL);\r
+ ASSERT(BestDeviceName != NULL);\r
StrnCatGrow(BestDeviceName, NULL, DeviceNameToReturn, 0);\r
return (EFI_SUCCESS);\r
}\r
could not be opened.\r
@retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted.\r
@retval EFI_DEVICE_ERROR The device had an error\r
+ @retval EFI_INVALID_PARAMETER FileHandle is NULL.\r
**/\r
EFI_STATUS\r
EFIAPI\r
EFI_STATUS Status;\r
EFI_HANDLE Handle;\r
\r
+ if (FileHandle == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
//\r
// find the handle of the device with that device handle and the file system\r
//\r
EFI_FILE_PROTOCOL *Handle1;\r
EFI_FILE_PROTOCOL *Handle2;\r
EFI_DEVICE_PATH_PROTOCOL *DpCopy;\r
+ FILEPATH_DEVICE_PATH *AlignedNode;\r
\r
- ASSERT(FileHandle != NULL);\r
- *FileHandle = NULL;\r
- Handle1 = NULL;\r
- DpCopy = DevicePath;\r
+ if (FileHandle == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ *FileHandle = NULL;\r
+ Handle1 = NULL;\r
+ Handle2 = NULL;\r
+ Handle = NULL;\r
+ DpCopy = DevicePath;\r
+ ShellHandle = NULL;\r
+ FilePathNode = NULL;\r
+ AlignedNode = NULL;\r
\r
Status = EfiShellOpenRoot(DevicePath, &ShellHandle);\r
\r
if (!EFI_ERROR(Status)) {\r
Handle1 = ConvertShellHandleToEfiFileProtocol(ShellHandle);\r
- //\r
- // chop off the begining part before the file system part...\r
- //\r
- ///@todo BlockIo?\r
- Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid,\r
- &DevicePath,\r
- &Handle);\r
- if (!EFI_ERROR(Status)) {\r
+ if (Handle1 != NULL) {\r
//\r
- // To access as a file system, the file path should only\r
- // contain file path components. Follow the file path nodes\r
- // and find the target file\r
+ // chop off the begining part before the file system part...\r
//\r
- for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath\r
- ; !IsDevicePathEnd (&FilePathNode->Header)\r
- ; FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header)\r
- ){\r
- //\r
- // For file system access each node should be a file path component\r
- //\r
- if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||\r
- DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP\r
- ) {\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
- }\r
-\r
- //\r
- // Open this file path node\r
- //\r
- Handle2 = Handle1;\r
- Handle1 = NULL;\r
-\r
+ ///@todo BlockIo?\r
+ Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid,\r
+ &DevicePath,\r
+ &Handle);\r
+ if (!EFI_ERROR(Status)) {\r
//\r
- // if this is the last node in the DevicePath always create (if that was requested).\r
+ // To access as a file system, the file path should only\r
+ // contain file path components. Follow the file path nodes\r
+ // and find the target file\r
//\r
- if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) {\r
- Status = Handle2->Open (\r
- Handle2,\r
- &Handle1,\r
- FilePathNode->PathName,\r
- OpenMode,\r
- Attributes\r
- );\r
- } else {\r
-\r
+ for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath\r
+ ; !IsDevicePathEnd (&FilePathNode->Header)\r
+ ; FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header)\r
+ ){\r
+ SHELL_FREE_NON_NULL(AlignedNode);\r
+ AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePathNode), FilePathNode);\r
//\r
- // This is not the last node and we dont want to 'create' existing\r
- // directory entries...\r
+ // For file system access each node should be a file path component\r
//\r
+ if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||\r
+ DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP\r
+ ) {\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+ }\r
\r
//\r
- // open without letting it create\r
- // prevents error on existing files/directories\r
+ // Open this file path node\r
//\r
- Status = Handle2->Open (\r
- Handle2,\r
- &Handle1,\r
- FilePathNode->PathName,\r
- OpenMode &~EFI_FILE_MODE_CREATE,\r
- Attributes\r
- );\r
+ Handle2 = Handle1;\r
+ Handle1 = NULL;\r
+\r
//\r
- // if above failed now open and create the 'item'\r
- // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above)\r
+ // if this is the last node in the DevicePath always create (if that was requested).\r
//\r
- if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {\r
+ if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) {\r
Status = Handle2->Open (\r
Handle2,\r
&Handle1,\r
- FilePathNode->PathName,\r
+ AlignedNode->PathName,\r
OpenMode,\r
Attributes\r
);\r
+ } else {\r
+\r
+ //\r
+ // This is not the last node and we dont want to 'create' existing\r
+ // directory entries...\r
+ //\r
+\r
+ //\r
+ // open without letting it create\r
+ // prevents error on existing files/directories\r
+ //\r
+ Status = Handle2->Open (\r
+ Handle2,\r
+ &Handle1,\r
+ AlignedNode->PathName,\r
+ OpenMode &~EFI_FILE_MODE_CREATE,\r
+ Attributes\r
+ );\r
+ //\r
+ // if above failed now open and create the 'item'\r
+ // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above)\r
+ //\r
+ if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {\r
+ Status = Handle2->Open (\r
+ Handle2,\r
+ &Handle1,\r
+ AlignedNode->PathName,\r
+ OpenMode,\r
+ Attributes\r
+ );\r
+ }\r
}\r
- }\r
- //\r
- // Close the last node\r
- //\r
- Handle2->Close (Handle2);\r
+ //\r
+ // Close the last node\r
+ //\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2);\r
\r
- //\r
- // If there's been an error, stop\r
- //\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- } // for loop\r
+ //\r
+ // If there's been an error, stop\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ } // for loop\r
+ }\r
}\r
}\r
+ SHELL_FREE_NON_NULL(AlignedNode);\r
if (EFI_ERROR(Status)) {\r
if (Handle1 != NULL) {\r
- Handle1->Close(Handle1);\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile(Handle1);\r
}\r
} else {\r
*FileHandle = ConvertEfiFileProtocolToShellHandle(Handle1, ShellFileHandleGetPath(ShellHandle));\r
If FileHandle is a file and matches all of the remaining Pattern (which would be\r
on its last node), then add a EFI_SHELL_FILE_INFO object for this file to fileList.\r
\r
- if FileList is NULL, then ASSERT\r
- if FilePattern is NULL, then ASSERT\r
- if UnicodeCollation is NULL, then ASSERT\r
- if FileHandle is NULL, then ASSERT\r
-\r
Upon a EFI_SUCCESS return fromt he function any the caller is responsible to call\r
FreeFileList with FileList.\r
\r
@param[in] FileHandle The FileHandle to start with\r
@param[in,out] FileList pointer to pointer to list of found files.\r
@param[in] ParentNode The node for the parent. Same file as identified by HANDLE.\r
+ @param[in] MapName The file system name this file is on.\r
\r
@retval EFI_SUCCESS all files were found and the FileList contains a list.\r
@retval EFI_NOT_FOUND no files were found\r
IN EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation,\r
IN SHELL_FILE_HANDLE FileHandle,\r
IN OUT EFI_SHELL_FILE_INFO **FileList,\r
- IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL\r
+ IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL,\r
+ IN CONST CHAR16 *MapName\r
)\r
{\r
EFI_STATUS Status;\r
EFI_SHELL_FILE_INFO *ShellInfoNode;\r
EFI_SHELL_FILE_INFO *NewShellNode;\r
BOOLEAN Directory;\r
+ CHAR16 *NewFullName;\r
+ UINTN Size;\r
\r
if ( FilePattern == NULL\r
|| UnicodeCollation == NULL\r
; ShellInfoNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ShellInfo->Link, &ShellInfoNode->Link)\r
){\r
if (UnicodeCollation->MetaiMatch(UnicodeCollation, (CHAR16*)ShellInfoNode->FileName, CurrentFilePattern)){\r
- if (Directory){\r
+ if (ShellInfoNode->FullName != NULL && StrStr(ShellInfoNode->FullName, L":") == NULL) {\r
+ Size = StrSize(ShellInfoNode->FullName);\r
+ Size += StrSize(MapName) + sizeof(CHAR16);\r
+ NewFullName = AllocateZeroPool(Size);\r
+ if (NewFullName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ StrCpy(NewFullName, MapName);\r
+ StrCat(NewFullName, ShellInfoNode->FullName+1);\r
+ FreePool((VOID*)ShellInfoNode->FullName);\r
+ ShellInfoNode->FullName = NewFullName;\r
+ }\r
+ }\r
+ if (Directory && !EFI_ERROR(Status) && ShellInfoNode->FullName != NULL && ShellInfoNode->FileName != NULL){\r
//\r
// should be a directory\r
//\r
//\r
//\r
//\r
- ASSERT_EFI_ERROR(Status);\r
if (EFI_ERROR(Status)) {\r
break;\r
}\r
//\r
// recurse with the next part of the pattern\r
//\r
- Status = ShellSearchHandle(NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode);\r
+ Status = ShellSearchHandle(NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode, MapName);\r
}\r
- } else {\r
+ } else if (!EFI_ERROR(Status)) {\r
//\r
// should be a file\r
//\r
; *PatternCurrentLocation != ':'\r
; PatternCurrentLocation++);\r
PatternCurrentLocation++;\r
- Status = ShellSearchHandle(PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL);\r
+ Status = ShellSearchHandle(PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL, MapName);\r
}\r
FreePool(RootDevicePath);\r
}\r
}\r
\r
- if (PatternCopy != NULL) {\r
- FreePool(PatternCopy);\r
- }\r
- if (MapName != NULL) {\r
- FreePool(MapName);\r
- }\r
+ SHELL_FREE_NON_NULL(PatternCopy);\r
+ SHELL_FREE_NON_NULL(MapName);\r
\r
return(Status);\r
}\r
Size += 2*sizeof(CHAR16);\r
\r
Buffer = AllocateZeroPool(Size);\r
+ if (Buffer == NULL) {\r
+ if (!IsListEmpty (&List)) {\r
+ FreeEnvironmentVariableList(&List);\r
+ }\r
+ return (NULL);\r
+ }\r
CurrentWriteLocation = (CHAR16*)Buffer;\r
\r
for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)\r
//\r
// Free the list...\r
//\r
- FreeEnvironmentVariableList(&List);\r
+ if (!IsListEmpty (&List)) {\r
+ FreeEnvironmentVariableList(&List);\r
+ }\r
} else {\r
//\r
// We are doing a specific environment variable\r
TempString = NULL;\r
DirectoryName = NULL;\r
\r
- if (FileSystem == NULL && Dir == NULL) {\r
+ if ((FileSystem == NULL && Dir == NULL) || Dir == NULL) {\r
return (EFI_INVALID_PARAMETER);\r
}\r
\r
RetSize = 0;\r
RetVal = NULL;\r
\r
+ if (VariableName == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
VariableName[0] = CHAR_NULL;\r
\r
while (TRUE) {\r
\r
This must be removed via calling CleanUpShellProtocol().\r
\r
- @param[in,out] NewShell The pointer to the pointer to the structure \r
+ @param[in,out] NewShell The pointer to the pointer to the structure\r
to install.\r
\r
@retval EFI_SUCCESS The operation was successful.\r
UINTN HandleCounter;\r
SHELL_PROTOCOL_HANDLE_LIST *OldProtocolNode;\r
\r
+ if (NewShell == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
BufferSize = 0;\r
Buffer = NULL;\r
OldProtocolNode = NULL;\r
InitializeListHead(&ShellInfoObject.OldShellList.Link);\r
\r
- ASSERT(NewShell != NULL);\r
-\r
//\r
// Initialize EfiShellProtocol object...\r
//\r
- *NewShell = &mShellProtocol;\r
Status = gBS->CreateEvent(0,\r
0,\r
NULL,\r
NULL,\r
&mShellProtocol.ExecutionBreak);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
\r
//\r
// Get the size of the buffer we need.\r
// Allocate and recall with buffer of correct size\r
//\r
Buffer = AllocateZeroPool(BufferSize);\r
- ASSERT(Buffer != NULL);\r
+ if (Buffer == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
Status = gBS->LocateHandle(ByProtocol,\r
&gEfiShellProtocolGuid,\r
NULL,\r
&BufferSize,\r
Buffer);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (EFI_ERROR(Status)) {\r
+ FreePool(Buffer);\r
+ return (Status);\r
+ }\r
//\r
// now overwrite each of them, but save the info to restore when we end.\r
//\r
OldProtocolNode->Handle,\r
&gEfiShellProtocolGuid,\r
OldProtocolNode->Interface,\r
- (VOID*)(*NewShell));\r
+ (VOID*)(&mShellProtocol));\r
if (!EFI_ERROR(Status)) {\r
//\r
// we reinstalled sucessfully. log this so we can reverse it later.\r
&gImageHandle,\r
&gEfiShellProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
- (VOID*)(*NewShell));\r
+ (VOID*)(&mShellProtocol));\r
}\r
\r
if (PcdGetBool(PcdShellSupportOldProtocols)){\r
///@todo do we need to support ShellEnvironment (not ShellEnvironment2) also?\r
}\r
\r
+ if (!EFI_ERROR(Status)) {\r
+ *NewShell = &mShellProtocol;\r
+ }\r
return (Status);\r
}\r
\r
/**\r
- Opposite of CreatePopulateInstallShellProtocol. \r
+ Opposite of CreatePopulateInstallShellProtocol.\r
\r
Free all memory and restore the system to the state it was in before calling\r
CreatePopulateInstallShellProtocol.\r
IN OUT EFI_SHELL_PROTOCOL *NewShell\r
)\r
{\r
- EFI_STATUS Status;\r
- SHELL_PROTOCOL_HANDLE_LIST *Node2;\r
+ EFI_STATUS Status;\r
+ SHELL_PROTOCOL_HANDLE_LIST *Node2;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
\r
//\r
// if we need to restore old protocols...\r
&gEfiShellProtocolGuid,\r
NewShell,\r
Node2->Interface);\r
- ASSERT_EFI_ERROR(Status);\r
FreePool(Node2);\r
}\r
} else {\r
Status = gBS->UninstallProtocolInterface(gImageHandle,\r
&gEfiShellProtocolGuid,\r
NewShell);\r
- ASSERT_EFI_ERROR(Status);\r
}\r
Status = gBS->CloseEvent(NewShell->ExecutionBreak);\r
+ NewShell->ExecutionBreak = NULL;\r
+\r
+ Status = gBS->OpenProtocol(\r
+ gST->ConsoleInHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID**)&SimpleEx,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+\r
+ Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle1);\r
+ Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle2);\r
\r
return (Status);\r
}\r
\r
+/**\r
+ Notification function for keystrokes.\r
+\r
+ @param[in] KeyData The key that was pressed.\r
\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotificationFunction(\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {\r
+ return (EFI_UNSUPPORTED);\r
+ }\r
+ return (gBS->SignalEvent(ShellInfoObject.NewEfiShellProtocol->ExecutionBreak));\r
+}\r
+\r
+/**\r
+ Function to start monitoring for CTRL-C using SimpleTextInputEx. This \r
+ feature's enabled state was not known when the shell initially launched.\r
+\r
+ @retval EFI_SUCCESS The feature is enabled.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InernalEfiShellStartMonitor(\r
+ VOID\r
+ )\r
+{\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
+ EFI_KEY_DATA KeyData;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->OpenProtocol(\r
+ gST->ConsoleInHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID**)&SimpleEx,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(\r
+ -1, \r
+ -1, \r
+ NULL,\r
+ STRING_TOKEN (STR_SHELL_NO_IN_EX),\r
+ ShellInfoObject.HiiHandle);\r
+ return (EFI_SUCCESS);\r
+ }\r
+\r
+ if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {\r
+ return (EFI_UNSUPPORTED);\r
+ }\r
+\r
+ KeyData.KeyState.KeyToggleState = 0;\r
+ KeyData.Key.ScanCode = 0;\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+ KeyData.Key.UnicodeChar = L'c';\r
+\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle1);\r
+ \r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle2);\r
+ }\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+ KeyData.Key.UnicodeChar = 3;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle3);\r
+ }\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle4);\r
+ }\r
+ return (Status);\r
+}\r