Commit graph

1178 commits

Author SHA1 Message Date
Pierre Gondois
e8036a9fbb ShellPkg/UefiShellLevel1: Return if ShellCommandLineParse() failed
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Return directly if ShellCommandLineParse() returned an error Status.
In such case, the "Package" that should be allocated by
ShellCommandLineParse() is already freed in:
ShellCommandLineParse()
\-ShellCommandLineParseEx()
\-InternalCommandLineParse()
so there is no need to free it with ShellCommandLineFreeVarList().

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-30 12:14:33 +00:00
Pierre Gondois
12e26dc213 ShellPkg/TimeDate: Extract GetTimeZoneFromString() helper
Extract a GetTimeZoneFromString() function to decrease the
size of MainCmdTime().

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
c062ff8487 ShellPkg/TimeDate: Extract PrintDaylight() helper
Extract a PrintDaylight() function to decrease the
size of MainCmdTime().

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
a366d6f8fe ShellPkg/TimeDate: Extract PrintTime() helper
Extract a PrintTime() function to factorize the code.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
0f69afa295 ShellPkg/TimeDate: Extract GetCurrentTime() helper
Extract a GetCurrentTime() function to factorize error
messages.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
be6ce32cd0 ShellPkg/Ls: Extract PrintLsOutputCurr() function
Extract a PrintLsOutputCurr() function to decrease
the size of PrintLsOutput().

The patch also rationalize the usage of the Found
parameter:
- Found is updated only when a valid MetaFile is found
- a IsRecursive variable is created to distinguish
  the first PrintLsOutput() call from the other
  recursive ones.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
636761d3ca ShellPkg/Ls: Lower PrintLsOutputRec() indentation level
Invert some conditions in PrintLsOutputRec() to lower
the indentation level.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
da54ab306a ShellPkg/Ls: Extract PrintLsOutputRec() function
Extract a PrintLsOutputRec() function to decrease
the size of PrintLsOutput().

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
08bc059570 ShellPkg/Ls: Remove unused TimeZone parameter
The TimeZone parameter is not used. Remove it.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
78b550f43d ShellPkg/Ls: Hard-code number of files if none found
If no file/directory has been found, the number of
files/directories must be 0.
Hard-code these values to avoid depending on the
FileCount/FileSize/DirCount variables.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
273edd9e01 ShellPkg/Ls: Extract GetCorrectedPath() function
Extract a GetCorrectedPath() function to decrease
the size of PrintLsOutput().

Also free the CorrectedPath in PrintLsOutput() before
re-allocating it to prepare for follow-up factorization.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
9171edd4d4 ShellPkg/Ls: Move FileMetaArg closing logic
Move ShellCloseFileMetaArg() calls to close the
MetaArg whenever its usage is not needed anymore.
This prepares for follow-up factorization.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
c45e930ad5 ShellPkg/Ls: Extract UpdateFileLocalTime() function
Extract a UpdateFileLocalTime() function to decrease
the size of PrintLsOutput().

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
6829285f88 ShellPkg/Rm: Extract DeleteDirectory() function
Extract a DeleteDirectory() function to decrease
the size of CascadeDelete().

The extracted logic is slighly modified to lower
the indendation level.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
420dab0b24 ShellPkg/UefiShellLib: Add IsDotOrDotDot() function
Replace existing checks against L"." and L".." by
a named function.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
4afe895a77 ShellPkg/SerMode: Add ValidDataBits() function
Add a ValidDataBits() utility function to check
the Data Bits are valid.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
65288416df ShellPkg/SerMode: Add GetStopBits() function
Add a GetStopBits() utility function to convert
the StopBits to the EFI_STOP_BITS_TYPE type.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
5e8b0d6de5 ShellPkg/SerMode: Lower indentation level in DisplaySettings()
Invert error handling to lower the indentation level
in DisplaySettings().

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
a5e74cdedb ShellPkg/SerMode: Add GetParityType() function
Add a GetParityType() utility function to convert
the Parity to the EFI_PARITY_TYPE type.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Pierre Gondois
06372c8df1 ShellPkg/SerMode: Add name conversion arrays for parity/stop bits
Add name conversion arrays:
- ParityBitName
- StopBitsName
to seamlessly convert parity/stop bits to a matching name.

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-24 18:18:47 +00:00
Andre Przywara
db38e5031a ShellPkg/AcpiView: Update MPAM table "MMIO size" field check
The "ACPI for Memory System Resource Partitioning and Monitoring" spec
(Arm DEN0065, [1]) in version 2.0 described the "MMIO size" field in the
"MPAM MSC node" subtable as being always 0 if the the "PCC" interface type
is used for that MSC. Version 3.0 of the spec changes that field to convey
the enablement status of that MSC: "If set to 1, this MSC is accessible
... If set to 0, this MSC is non-functional...."
Relax the strict check for this value being 0 in the acpiview validation
checks, to also allow the new value of "1".

[1] https://developer.arm.com/documentation/den0065/3-0/

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2026-04-20 07:34:34 +00:00
Pierre Gondois
76406ef119 ShellPkg/UefiShellDriver1: Remove unused Status
Status is set but never used.
Remove the variable.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
c14647a483 ShellPkg/UefiShellDriver1: Flatten some functions
Flatten the following functions to make them easier to read:
- TraverseHandleDatabase()
- GetDeviceHandleInfo()
- DoDecodeByProtocol()

No functional change.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
1ab251c770 ShellPkg/UefiShellDriver1/Drivers: Fix memory leaks
Free Language/FormatString before exiting the function.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
becbdb4e27 ShellPkg/UefiShellDriver1: Lower indentation level in MainCmdXXX()
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Lower the indentation level in the newly created MainCmdXXX()
functions.

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
4de99ebb92 ShellPkg/UefiShellDriver1: Extract MainCmdXXX() function
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Extract a MainCmdXXX() function for each shell command.
This command contains the possible operations the command aims
to operate. The ShellCommandRunXXX() function from which it
is extracted is only responsible of:
- initializing the shell/command environment
- parsing the command parameter and creating a Package
- freeing the Package

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
51cdb08cdb ShellPkg/UefiShellDriver1: Return if ShellCommandLineParse() failed
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Return directly if ShellCommandLineParse() returned an error Status.
In such case, the "Package" that should be allocated by
ShellCommandLineParse() is already freed in:
ShellCommandLineParse()
\-ShellCommandLineParseEx()
\-InternalCommandLineParse()
so there is no need to free it with ShellCommandLineFreeVarList().

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Pierre Gondois
cfcb4eee91 ShellPkg/UefiShellDriver1: Fix memory leaks
Package must be freed before exiting. Free the pointer.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2026-04-09 11:13:08 +00:00
Gaurav Pandya
bd8ec21280 ShellPkg/AcpiView: Avoid mutating HEST hardware bank count during parse
Remove post-parse write to mHestIA32HardwareBankCount.
Keep HEST parsing read-only.

*mHestIA32HardwareBankCount = 0, line in code corrupts the
ACPI HEST table data Hardware bank count to zero.

mHestIA32HardwareBankCount points into the parsed HEST table
data (input buffer). Writing through it modifies ACPI table
contents during parsing, which should be read-only behavior.

Signed-off-by: Gaurav Pandya <Gaurav.Pandya@amd.com>
2026-04-09 06:31:41 +00:00
Bob Morgan
c4d29cb621 ShellPkg/UefiHandleParsingLib: support handle list growth
Refactor GetHandleListByProtocol() to support
additions to the handle list during its execution.
Replace LocateHandle() with LocateHandleBuffer() to
avoid the possibility that the buffer allocated for
LocateHandle() is too small if additional handles
are added during GetHandleListByProtocol() execution.

Note that the previous implementation did not detect
the handle list growth and would cause memory
corruption when writing the terminating NULL handle
to the allocated buffer.

Signed-off-by: Bob Morgan <bobm@nvidia.com>
2026-03-26 17:36:35 +00:00
Michael D Kinney
3657a4fc9f ShellPkg/SmbiosView: Fix clang compatibility issue
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
2026-03-07 02:50:50 +00:00
Yang Gang
2bfde627ff ShellPkg/SmbiosView: Support print Protocol Records of SMBIOS type42
SmbiosView tool changes for Protocol Records info decode and print.

This commit adds the following decoding functionality:
First, it prints the `MCHostInterfaceProtocol Number`,
then print the `ProtocolType` with the prefix #x(0 based index),
and finally dump `ProtocolTypeData` as hex.

Signed-off-by: Yang Gang <yanggang@byosoft.com.cn>
2026-03-06 08:35:45 +00:00
Alexander Gryanko
27528b48db ShellPkg: fix UNI string formatting and line endings to match UNI Spec
Changes include:
* Added missing \r\n line endings inside string literals
* Fixed inconsistent indentation in multi-line string entries
* Removed duplicated #language en-US directive
* Aligned string formatting to match the UNI specification

Updated files:
ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni
ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni

The issues were identified during testing of the parser
https://github.com/xpahos/edk2-idea.

Signed-off-by: Alexander Gryanko <xpahos@gmail.com>
2026-03-02 19:32:17 +00:00
Alexander Gryanko
ad44b8d552 ShellPkg: align UNI file headers with UNI Spec standard
The Uni file standard specifies that comments begin with the
characters "//". The following files contained incorrectly
formatted C-style comments and have been updated:

ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni

The problems were identified during testing of the parser
https://github.com/xpahos/edk2-idea.

Signed-off-by: Alexander Gryanko <xpahos@gmail.com>
2026-03-02 19:32:17 +00:00
Werner Lewis
7746ec4dde ShellPkg/SmbiosView: Add Type45 entry to query table
The type field for Smbios tables in smbiosview is set from values in
this query table. An entry is added to correctly display the Type 45
table name rather than "Undefined Value" in smbiosview output.

Signed-off-by: Varshit Pandya <varshit.pandya@arm.com>
2026-02-25 11:05:46 +00:00
Michael Kubacki
8472271dae ShellPkg: Replace include guards with #pragma once
Replace traditional `#ifndef`/`#define`/`#endif` include guards with
`#pragma` once.

`#pragma once` is a widely supported preprocessor directive that
prevents header files from being included multiple times. It is
supported by all toolchains used to build edk2: GCC, Clang/LLVM, and
MSVC.

Compared to macro-based include guards, `#pragma once`:

- Eliminates the risk of macro name collisions or copy/paste errors
  where two headers inadvertently use the same guard macro.
- Eliminate inconsistency in the way include guard macros are named
  (e.g., some files use `__FILE_H__`, others use `FILE_H_`, etc.).
- Reduces boilerplate (three lines replaced by one).
- Avoids polluting the macro namespace with guard symbols.
- Can improve build times as the preprocessor can skip re-opening the
  file entirely, rather than re-reading it to find the matching
  `#endif` ("multiple-include optimization").
  - Note that some compilers may already optimize traditional include
    guards, by recognzining the idiomatic pattern.

This change is made acknowledging that overall portability of the
code will technically be reduced, as `#pragma once` is not part of the
C/C++ standards.

However, this is considered acceptable given:

1. edk2 already defines a subset of supported compilers in
   BaseTools/Conf/tools_def.template, all of which have supported
   `#pragma once` for over two decades.
2. There have been concerns raised to the project about inconsistent
   include guard naming and potential macro collisions.

Approximate compiler support dates:

- MSVC: Supported since Visual C++ 4.2 (1996)
- GCC: Supported since 3.4 (2004)
  (http://gnu.ist.utl.pt/software/gcc/gcc-3.4/changes.html)
- Clang (LLVM based): Since initial release in 2007

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
2026-02-23 21:01:28 +00:00
Ren Yang (楊壹任)
96572d4d72 ShellPkg: SMBIOS type 20 Extended Starting/Ending Address print type error
Wrong structure is used to print the SMBIOS type 20 Extended
Starting/Ending Address in SmbiosView

Signed-off-by: Ren Yang <RenYang@ami.com>
2026-02-03 23:20:58 +00:00
Abdul Lateef Attar
539c53375e ShellPkg/AcpiView: Adds FPDT Parser
Add a new parser for the Firmware Performance Data Table (FPDT),
as per the ACPI6.5 specification.

Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
2026-01-29 10:32:54 +00:00
Ard Biesheuvel
3bc03ff552 ShellPkg/AcpiView: Fix unused variable warnings in RimtParser
Clang complains about unused variables:

ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c:21:60: error: variable 'mRimtNodeHeader' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
   21 | STATIC EFI_ACPI_6_6_RIMT_NODE_HEADER_STRUCTURE             mRimtNodeHeader;
      |                                                            ^~~~~~~~~~~~~~~
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c:25:60: error: variable 'mRimtIdMappingNode' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
   25 | STATIC EFI_ACPI_6_6_RIMT_ID_MAPPING_STRUCTURE              mRimtIdMappingNode;
      |                                                            ^~~~~~~~~~~~~~~~~~
   28 | STATIC EFI_ACPI_6_6_RIMT_PCIE_ROOT_COMPLEX_NODE_STRUCTURE  mRimtPcieRootComplexNode;
      |                                                            ^~~~~~~~~~~~~~~~~~~~~~~~
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c:29:60: error: variable 'mRimtIommuNode' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
   29 | STATIC EFI_ACPI_6_6_RIMT_IOMMU_NODE_STRUCTURE              mRimtIommuNode;
      |                                                            ^~~~~~~~~~~~~~
4 errors generated.

This is because these variables are only used to take the size of their
fields using the sizeof() operator, which does not support type names
directly.

So create a helper macro SIZE_OF_T () that provides the functionality we
need, and drop the unused variables.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2025-12-04 08:43:02 +00:00
Mingjie Shen
2b47c81fe6 ShellPkg/For: Remove redundant null/empty checks on ArgSetWalker
Fix CodeQL cpp/redundant-null-check-simple warning in
ShellPkg/Library/UefiShellLevel1CommandsLib/For.c at line 571 by
removing redundant null and empty-string checks on ArgSetWalker. The
outer guard at line 570 ensures that ArgSetWalker is non-NULL and
non-empty, so the inner condition only needs
ShellIsValidForNumber(ArgSetWalker).

Signed-off-by: Mingjie Shen <shen497@purdue.edu>
2025-12-03 17:41:35 +00:00
Mingjie Shen
ee0084a071 ShellPkg/Mv: Harden and optimize trailing-slash trimming
- Remove redundant null check in IsValidMove() per CodeQL
  cpp/redundant-null-check-simple. Specifically, drop the
  "DestPathWalker != NULL" condition from the trimming loop.
  Rationale: "DestPathCopy" is allocated at line 181 and checked for
  NULL at lines 182–183; "DestPathWalker" is initialized from
  "DestPathCopy" at line 186, so it cannot be NULL.
- Cache length once in IsValidMove() and ValidateAndMoveFiles() so the
  trimming loop avoids repeated StrLen() calls.
- Guard the zero-length case before indexing the last character to
  prevent out-of-bounds access.

Signed-off-by: Mingjie Shen <shen497@purdue.edu>
2025-12-03 17:41:35 +00:00
Pierre Gondois
19c62fd3ac ShellPkg/UefiShellLevel2: Fix CodeQl issues
Fix CodeQl issue triggered by the previous patches.
- Rm: FileList might be NULL

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
95476665c4 ShellPkg/UefiShellLevel2/Ls: Remove ShellStatus check in MainCmdLs()
Remove a check against ShellStatus in MainCmdLs() as there are
two consecutive checks without any modification of ShellStatus.

Suggested-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
8e822d5d26 ShellPkg/UefiShellLevel2/Ls: Bail out early in MainCmdLs()
If RootPath is NULL, PrintLsOutput() will return an error code
of SHELL_OUT_OF_RESOURCES and not print anything:
PrintLsOutput()
\-StrnCatGrow()
  if (Source == NULL) {
    return (*Destination);
  }

Remove paths where FullPath ends up being NULL and bail out
early.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
0b982813c7 ShellPkg/UefiShellLevel2/Ls: Flatten MainCmdLs()
Remove some of the success handling conditions to flatten
the MainCmdLs() function.

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
5b1530e5ad ShellPkg/UefiShellLevel2: Lower indentation level in MainCmdXXX()
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Lower the indentation level in the newly created MainCmdXXX()
functions.

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
531b0aa002 ShellPkg/UefiShellLevel2: Extract MainCmdXXX() function
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Extract a MainCmdXXX() function for each shell command.
This command contains the possible operations the command aims
to operate. The ShellCommandRunXXX() function from which it
is extracted is only responsible of:
- initializing the shell/command environment
- parsing the command parameter and creating a Package
- freeing the Package

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Pierre Gondois
ce88903374 ShellPkg/UefiShellLevel2: Return if ShellCommandLineParse() failed
This patch aims to help breaking down the long function present in
the ShellPkg and reduce complexity/nested code and conditions.

Return directly if ShellCommandLineParse() returned an error Status.
In such case, the "Package" that should be allocated by
ShellCommandLineParse() is already freed in:
ShellCommandLineParse()
\-ShellCommandLineParseEx()
  \-InternalCommandLineParse()
so there is no need to free it with ShellCommandLineFreeVarList().

Note:
Cd:
Return directly if ShellCommandLineParse() returned an error
Status. The initial code was ignoring the error status.

Cp:
Only check for ShellGetExecutionBreakFlag() if
ShellCommandLineParse() returned successfully. If the command
line failed to be parsed, there should be no need to check for
the execution break flag.

No functional change should be induced by this patch.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
2025-12-02 09:00:53 +01:00
Krzysztof Drobinski
7e9901887e ShellPkg,acpiview: Add RIMT (RISC-V IO Mapping Table) parser
Implementation tested on Qemu-10.1 virt machine with IOMMU enabled.

Signed-off-by: Krzysztof Drobiński <krzysztof@plasteli.net>
2025-11-23 21:20:54 +00:00
Gowtham M
40d461d25f ShellPkg/Library: Remove ScsiPassThruProtocolGuid
The legacy ScsiPassThruProtocol has been removed as per
the UEFI 2.10A specification.
This commit, removes references to ScsiPassThruProtocol and
transitions the implementation to only use ExtScsiPassThruProtocol,
which provides enhanced support for device enumeration,
target/LUN discovery, and broader SCSI compatibility.

Cc: Sachin Ganesh <sachinganesh@ami.com>
Signed-off-by: Gowtham M <gowthamm@ami.com>
2025-11-23 18:40:59 +00:00