unit CertificateManager;

interface

uses
  System.Classes; // No usamos System.Generics.Collections

type
  TCertificateInfo = class
  public
    FriendlyName: string;
    Context: Pointer;
  end;

  TCertificateLoader = class
  public
    class function GetPersonalCertificates: TList; // <-- USA TList
  end;

implementation

uses
  System.SysUtils, Winapi.Windows, Wincrypt;

class function TCertificateLoader.GetPersonalCertificates: TList; // <-- USA TList
var
  hStore: HCERTSTORE;
  pContext: PCCERT_CONTEXT;
  CertInfo: TCertificateInfo;
  ResultList: TList; // <-- USA TList
  FriendlyName: array[0..255] of WideChar;
  cbData: DWORD;
begin
  ResultList := TList.Create; // <-- USA TList

  hStore := CertOpenSystemStore(0, 'MY');
  if hStore = nil then
  begin
    Exit(ResultList);
  end;
  try
    pContext := nil;
    repeat
      pContext := CertFindCertificateInStore(hStore,
        X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, nil, pContext);

      if pContext <> nil then
      begin
        cbData := 0;
        if CertGetCertificateContextProperty(pContext, CERT_KEY_PROV_INFO_PROP_ID, nil, cbData) and (cbData > 0) then
        begin
          CertInfo := TCertificateInfo.Create;
          if CertGetNameString(pContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, nil, FriendlyName, SizeOf(FriendlyName)) > 1 then
            CertInfo.FriendlyName := String(FriendlyName)
          else if CertGetNameString(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, FriendlyName, SizeOf(FriendlyName)) > 1 then
            CertInfo.FriendlyName := String(FriendlyName)
          else
            CertInfo.FriendlyName := 'Certificado sin nombre';
          CertInfo.Context := CertDuplicateCertificateContext(pContext);
          ResultList.Add(CertInfo);
        end;
      end;
    until pContext = nil;
  finally
    CertCloseStore(hStore, 0);
  end;
  Result := ResultList;
end;

end.
