2 Main file for endfor and for shell level 1 functions.
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellLevel1CommandsLib.h"
16 #include <Library/PrintLib.h>
19 Determine if a valid string is a valid number for the 'for' command.
21 @param[in] Number The pointer to the string representation of the number to test.
23 @retval TRUE The number is valid.
24 @retval FALSE The number is not valid.
28 ShellIsValidForNumber (
29 IN CONST CHAR16
*Number
32 if (Number
== NULL
|| *Number
== CHAR_NULL
) {
36 if (*Number
== L
'-') {
40 if (StrLen(Number
) == 0) {
44 if (StrLen(Number
) >= 7) {
45 if (StrStr(Number
, L
" ") != NULL
&& (StrStr(Number
, L
" ") - Number
) >= 7) {
50 if (!ShellIsDecimalDigitCharacter(*Number
)) {
58 Function for 'endfor' command.
60 @param[in] ImageHandle Handle to the Image (NULL if Internal).
61 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
65 ShellCommandRunEndFor (
66 IN EFI_HANDLE ImageHandle
,
67 IN EFI_SYSTEM_TABLE
*SystemTable
73 Status
= CommandInit();
74 ASSERT_EFI_ERROR(Status
);
76 if (!gEfiShellProtocol
->BatchIsActive()) {
77 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"EndFor");
78 return (SHELL_UNSUPPORTED
);
81 if (gEfiShellParametersProtocol
->Argc
> 1) {
82 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
83 return (SHELL_INVALID_PARAMETER
);
86 Found
= MoveToTag(GetPreviousNode
, L
"for", L
"endfor", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, FALSE
, FALSE
);
93 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
94 gShellLevel1HiiHandle
,
97 ShellCommandGetCurrentScriptFile()!=NULL
98 &&ShellCommandGetCurrentScriptFile()->CurrentCommand
!=NULL
99 ?ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
:0);
100 return (SHELL_NOT_FOUND
);
102 return (SHELL_SUCCESS
);
110 CHAR16
*ReplacementName
;
111 CHAR16
*CurrentValue
;
112 BOOLEAN RemoveSubstAlias
;
115 #define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
116 #define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
119 Update the value of a given alias on the list. If the alias is not there then add it.
121 @param[in] Alias The alias to test for.
122 @param[in] CommandString The updated command string.
123 @param[in,out] List The list to search.
125 @retval EFI_SUCCESS The operation was completed successfully.
126 @retval EFI_OUT_OF_RESOURCES There was not enough free memory.
130 InternalUpdateAliasOnList(
131 IN CONST CHAR16
*Alias
,
132 IN CONST CHAR16
*CommandString
,
133 IN OUT LIST_ENTRY
*List
140 // assert for NULL parameter
142 ASSERT(Alias
!= NULL
);
145 // check for the Alias
147 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
), Found
= FALSE
148 ; !IsNull(List
, &Node
->Link
)
149 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
151 ASSERT(Node
->CommandString
!= NULL
);
152 ASSERT(Node
->Alias
!= NULL
);
153 if (StrCmp(Node
->Alias
, Alias
)==0) {
154 FreePool(Node
->CommandString
);
155 Node
->CommandString
= NULL
;
156 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
162 Node
= AllocateZeroPool(sizeof(ALIAS_LIST
));
164 return (EFI_OUT_OF_RESOURCES
);
166 ASSERT(Node
->Alias
== NULL
);
167 Node
->Alias
= StrnCatGrow(&Node
->Alias
, NULL
, Alias
, 0);
168 ASSERT(Node
->CommandString
== NULL
);
169 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
170 InsertTailList(List
, &Node
->Link
);
172 return (EFI_SUCCESS
);
176 Find out if an alias is on the given list.
178 @param[in] Alias The alias to test for.
179 @param[in] List The list to search.
181 @retval TRUE The alias is on the list.
182 @retval FALSE The alias is not on the list.
186 InternalIsAliasOnList(
187 IN CONST CHAR16
*Alias
,
188 IN CONST LIST_ENTRY
*List
194 // assert for NULL parameter
196 ASSERT(Alias
!= NULL
);
199 // check for the Alias
201 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
202 ; !IsNull(List
, &Node
->Link
)
203 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
205 ASSERT(Node
->CommandString
!= NULL
);
206 ASSERT(Node
->Alias
!= NULL
);
207 if (StrCmp(Node
->Alias
, Alias
)==0) {
215 Remove an alias from the given list.
217 @param[in] Alias The alias to remove.
218 @param[in,out] List The list to search.
222 InternalRemoveAliasFromList(
223 IN CONST CHAR16
*Alias
,
224 IN OUT LIST_ENTRY
*List
230 // assert for NULL parameter
232 ASSERT(Alias
!= NULL
);
235 // check for the Alias
237 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
238 ; !IsNull(List
, &Node
->Link
)
239 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
241 ASSERT(Node
->CommandString
!= NULL
);
242 ASSERT(Node
->Alias
!= NULL
);
243 if (StrCmp(Node
->Alias
, Alias
)==0) {
244 RemoveEntryList(&Node
->Link
);
245 FreePool(Node
->Alias
);
246 FreePool(Node
->CommandString
);
255 Function for 'for' command.
257 @param[in] ImageHandle Handle to the Image (NULL if Internal).
258 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
263 IN EFI_HANDLE ImageHandle
,
264 IN EFI_SYSTEM_TABLE
*SystemTable
268 SHELL_STATUS ShellStatus
;
269 SCRIPT_FILE
*CurrentScriptFile
;
271 CHAR16
*ArgSetWalker
;
274 SHELL_FOR_INFO
*Info
;
278 EFI_SHELL_FILE_INFO
*Node
;
279 EFI_SHELL_FILE_INFO
*FileList
;
284 ShellStatus
= SHELL_SUCCESS
;
290 // initialize the shell lib (we must be in non-auto-init...)
292 Status
= ShellInitialize();
293 ASSERT_EFI_ERROR(Status
);
295 Status
= CommandInit();
296 ASSERT_EFI_ERROR(Status
);
298 if (!gEfiShellProtocol
->BatchIsActive()) {
299 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"For");
300 return (SHELL_UNSUPPORTED
);
303 if (gEfiShellParametersProtocol
->Argc
< 4) {
304 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
);
305 return (SHELL_INVALID_PARAMETER
);
308 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
309 ASSERT(CurrentScriptFile
!= NULL
);
311 if (CurrentScriptFile
->CurrentCommand
->Data
== NULL
) {
315 // Make sure that an End exists.
317 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
322 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
323 gShellLevel1HiiHandle
,
326 CurrentScriptFile
->CurrentCommand
!=NULL
327 ?CurrentScriptFile
->CurrentCommand
->Line
:0);
328 return (SHELL_DEVICE_ERROR
);
334 if (gEfiShellParametersProtocol
->Argv
[1][0] != L
'%' || gEfiShellParametersProtocol
->Argv
[1][2] != CHAR_NULL
335 ||!((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'a' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'z')
336 ||(gEfiShellParametersProtocol
->Argv
[1][1] >= L
'A' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'Z'))
338 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_INV_VAR
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[1]);
339 return (SHELL_INVALID_PARAMETER
);
342 if (gUnicodeCollation
->StriColl(
345 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
346 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
347 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
348 if (ArgSet
== NULL
) {
349 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
351 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
353 if (StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"*") != NULL
354 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"?") != NULL
355 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"[") != NULL
356 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"]") != NULL
) {
358 Status
= ShellOpenFileMetaArg ((CHAR16
*)gEfiShellParametersProtocol
->Argv
[LoopVar
], EFI_FILE_MODE_READ
, &FileList
);
359 if (EFI_ERROR(Status
) || FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
360 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
362 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
363 ; !IsNull(&FileList
->Link
, &Node
->Link
)
364 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
366 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
367 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Node
->FullName
, 0);
368 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
370 ShellCloseFileMetaArg(&FileList
);
373 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
375 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
378 // set up for an 'in' for loop
380 NewSize
= StrSize(ArgSet
);
381 NewSize
+= sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]);
382 Info
= AllocateZeroPool(NewSize
);
383 ASSERT(Info
!= NULL
);
384 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
385 CopyMem(Info
->Set
, ArgSet
, StrSize(ArgSet
));
386 NewSize
= StrSize(gEfiShellParametersProtocol
->Argv
[1]);
387 CopyMem(Info
->Set
+(StrSize(ArgSet
)/sizeof(Info
->Set
[0])), gEfiShellParametersProtocol
->Argv
[1], NewSize
);
388 Info
->ReplacementName
= Info
->Set
+StrSize(ArgSet
)/sizeof(Info
->Set
[0]);
389 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
394 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
395 Info
->RemoveSubstAlias
= FALSE
;
397 Info
->RemoveSubstAlias
= TRUE
;
399 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
400 } else if (gUnicodeCollation
->StriColl(
403 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
404 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
405 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
406 if (ArgSet
== NULL
) {
407 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
409 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
411 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
412 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
415 // set up for a 'run' for loop
417 Info
= AllocateZeroPool(sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]));
418 ASSERT(Info
!= NULL
);
419 CopyMem(Info
->Set
, gEfiShellParametersProtocol
->Argv
[1], StrSize(gEfiShellParametersProtocol
->Argv
[1]));
420 Info
->ReplacementName
= Info
->Set
;
421 Info
->CurrentValue
= NULL
;
422 ArgSetWalker
= ArgSet
;
423 if (ArgSetWalker
[0] != L
'(') {
424 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
425 ShellStatus
= SHELL_INVALID_PARAMETER
;
427 TempSpot
= StrStr(ArgSetWalker
, L
")");
428 if (TempSpot
!= NULL
) {
429 TempString
= TempSpot
+1;
430 if (*(TempString
) != CHAR_NULL
) {
431 while(TempString
!= NULL
&& *TempString
== L
' ') {
434 if (StrLen(TempString
) > 0) {
439 if (TempSpot
== NULL
) {
440 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
441 ShellStatus
= SHELL_INVALID_PARAMETER
;
443 *TempSpot
= CHAR_NULL
;
445 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
448 if (!ShellIsValidForNumber(ArgSetWalker
)) {
449 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
450 ShellStatus
= SHELL_INVALID_PARAMETER
;
452 if (ArgSetWalker
[0] == L
'-') {
453 Info
->Current
= 0 - (INTN
)ShellStrToUintn(ArgSetWalker
+1);
455 Info
->Current
= (INTN
)ShellStrToUintn(ArgSetWalker
);
457 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
458 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
461 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
462 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
463 ShellStatus
= SHELL_INVALID_PARAMETER
;
465 if (ArgSetWalker
[0] == L
'-') {
466 Info
->End
= 0 - (INTN
)ShellStrToUintn(ArgSetWalker
+1);
468 Info
->End
= (INTN
)ShellStrToUintn(ArgSetWalker
);
470 if (Info
->Current
< Info
->End
) {
476 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
477 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
480 if (ArgSetWalker
!= NULL
&& *ArgSetWalker
!= CHAR_NULL
) {
481 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
482 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
483 ShellStatus
= SHELL_INVALID_PARAMETER
;
485 if (*ArgSetWalker
== L
')') {
486 ASSERT(Info
->Step
== 1 || Info
->Step
== -1);
488 if (ArgSetWalker
[0] == L
'-') {
489 Info
->Step
= 0 - (INTN
)ShellStrToUintn(ArgSetWalker
+1);
491 Info
->Step
= (INTN
)ShellStrToUintn(ArgSetWalker
);
494 if (StrStr(ArgSetWalker
, L
" ") != NULL
) {
495 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
496 ShellStatus
= SHELL_INVALID_PARAMETER
;
506 if (ShellStatus
== SHELL_SUCCESS
) {
507 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
508 Info
->RemoveSubstAlias
= FALSE
;
510 Info
->RemoveSubstAlias
= TRUE
;
513 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
515 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
), gShellLevel1HiiHandle
, ArgSet
, ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
516 ShellStatus
= SHELL_INVALID_PARAMETER
;
520 // These need to be NULL since they are used to determine if this is the first pass later on...
522 ASSERT(ArgSetWalker
== NULL
);
523 ASSERT(ArgSet
== NULL
);
526 Info
= (SHELL_FOR_INFO
*)CurrentScriptFile
->CurrentCommand
->Data
;
527 if (CurrentScriptFile
->CurrentCommand
->Reset
) {
528 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
530 CurrentScriptFile
->CurrentCommand
->Reset
= FALSE
;
532 if (ShellStatus
== SHELL_SUCCESS
) {
533 ASSERT(Info
!= NULL
);
534 if (Info
->Step
!= 0) {
536 // only advance if not the first pass
540 // sequence version of for loop...
542 Info
->Current
+= Info
->Step
;
545 TempString
= AllocateZeroPool(50*sizeof(CHAR16
));
546 UnicodeSPrint(TempString
, 50*sizeof(CHAR16
), L
"%d", Info
->Current
);
547 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
548 FreePool(TempString
);
550 if ((Info
->Step
> 0 && Info
->Current
> Info
->End
) || (Info
->Step
< 0 && Info
->Current
< Info
->End
)) {
551 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
553 // find the matching endfor (we're done with the loop)
555 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
556 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"EndFor", L
"For", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
557 ShellStatus
= SHELL_DEVICE_ERROR
;
559 if (Info
->RemoveSubstAlias
) {
561 // remove item from list
563 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
569 // Must be in 'in' version of for loop...
571 ASSERT(Info
->Set
!= NULL
);
572 if (Info
->CurrentValue
!= NULL
&& *Info
->CurrentValue
!= CHAR_NULL
) {
573 if (Info
->CurrentValue
[0] == L
'\"') {
574 Info
->CurrentValue
++;
576 // while (Info->CurrentValue[0] == L' ') {
577 // Info->CurrentValue++;
579 if (Info
->CurrentValue
[0] == L
'\"') {
580 Info
->CurrentValue
++;
583 // do the next one of the set
585 ASSERT(TempString
== NULL
);
586 TempString
= StrnCatGrow(&TempString
, NULL
, Info
->CurrentValue
, 0);
587 TempSpot
= StrStr(TempString
, L
"\" \"");
588 if (TempSpot
!= NULL
) {
589 *TempSpot
= CHAR_NULL
;
591 while (TempString
[StrLen(TempString
)-1] == L
'\"') {
592 TempString
[StrLen(TempString
)-1] = CHAR_NULL
;
594 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
595 Info
->CurrentValue
+= StrLen(TempString
);
597 if (Info
->CurrentValue
[0] == L
'\"') {
598 Info
->CurrentValue
++;
600 while (Info
->CurrentValue
[0] == L
' ') {
601 Info
->CurrentValue
++;
603 if (Info
->CurrentValue
[0] == L
'\"') {
604 Info
->CurrentValue
++;
606 FreePool(TempString
);
609 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
611 // find the matching endfor (we're done with the loop)
613 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
614 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"EndFor", L
"For", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
615 ShellStatus
= SHELL_DEVICE_ERROR
;
617 if (Info
->RemoveSubstAlias
) {
619 // remove item from list
621 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
627 if (ArgSet
!= NULL
) {
630 return (ShellStatus
);