Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   WinSCard.dll (https://www.delphipraxis.net/159081-winscard-dll.html)

Dr.MAD 13. Mär 2011 18:39

WinSCard.dll
 
Hallo,

ich bekomm aus der Funktion SCardListReadersA keinen String heraus. :oops:

SmartCard-Leser ist angeschlossen und der Rückgabewert Size = 54 bei mir stimmt schon mal.

Könnte mir jemand weiterhelfen?

Delphi-Quellcode:
type
  SCARDCONTEXT = ULONG_PTR; // Cardinal
  PSCARDCONTEXT = ^SCARDCONTEXT;
  LPSCARDCONTEXT = ^SCARDCONTEXT;


  function SCardListReadersA(hContext: SCARDCONTEXT; mszGroups: LPCSTR; out mszReaders: LPSTR; out pcchReaders: LPDWORD): ULONG; stdcall; external 'Winscard.dll';


...



procedure TForm1.Button1Click(Sender: TObject);
var ret, Size: Cardinal;
    mszReaders: PAnsiChar;
    pcchReaders: PDWORD;
    Readers: String;
begin

  ret:=SCardListReadersA(0, 0, mszReaders, pcchReaders);
  Size:=DWORD(pcchReaders);
  SetString(Readers, mszReaders, Size);

  Memo1.Lines.Add('Ret: '+IntToStr(ret));
  Memo1.Lines.Add('Size: '+IntToStr(Size));
  Memo1.Lines.Add('Readers: '+Readers);

end;
OS: Win7 x64

Die Funktion sollte alle angeschlossenen SmartCard-Leser auflisten (z.B. von Chipdrive (SCM Microsystems)).

Dr.MAD 13. Mär 2011 23:01

AW: WinSCard.dll
 
Jetzt komm ich zwar an den String, aber ganz zufrieden bin ich noch nicht. :?

Das geht:
Delphi-Quellcode:
type
  SCARDCONTEXT = ULONG_PTR; // Cardinal
  PSCARDCONTEXT = ^SCARDCONTEXT;
  LPSCARDCONTEXT = ^SCARDCONTEXT;

  TAnsiAry = Array[0..1023] of AnsiChar;

  function SCardListReadersA(hContext: SCARDCONTEXT; mszGroups: LPCSTR; out mszReaders: TAnsiAry; out pcchReaders: DWORD): ULONG; stdcall; external 'Winscard.dll';

...

procedure TForm1.Button1Click(Sender: TObject);
var X: Integer;
    ret: Cardinal;
    Size: DWORD;
    Readers: TAnsiAry;
begin
  // Größe für Readers holen
  Size:=0;
  ret:=SCardListReadersA(0, 0, Readers, Size);
  Memo1.Lines.Add('Size: '+IntToStr(Size));
  if ret=0 then begin
    ret:=SCardListReadersA(0, 0, Readers, Size);
    if ret=0 then begin
      for X:=0 to Size-1 do begin
        Memo1.Lines.Add(IntToStr(Ord(Readers[X]))+' = '+Readers[X]);
      end;
    end;
  end;
end;


Das geht nicht:
Delphi-Quellcode:
type
  SCARDCONTEXT = ULONG_PTR; // Cardinal
  PSCARDCONTEXT = ^SCARDCONTEXT;
  LPSCARDCONTEXT = ^SCARDCONTEXT;

  TAnsiAry = Array of AnsiChar;

  function SCardListReadersA(hContext: SCARDCONTEXT; mszGroups: LPCSTR; out mszReaders: TAnsiAry; out pcchReaders: DWORD): ULONG; stdcall; external 'Winscard.dll';

...

procedure TForm1.Button1Click(Sender: TObject);
var X: Integer;
    ret: Cardinal;
    Size: DWORD;
    Readers: TAnsiAry;
begin
  // Größe für Readers holen
  Size:=0;
  ret:=SCardListReadersA(0, 0, Readers, Size);
  Memo1.Lines.Add('Size: '+IntToStr(Size));
  if ret=0 then begin
    SetLength(Readers, Size);
    ret:=SCardListReadersA(0, 0, Readers, Size);
    if ret=0 then begin
      for X:=Low(Readers) to High(Readers) do begin
        Memo1.Lines.Add(IntToStr(Ord(Readers[X]))+' = '+Readers[X]);
      end;
    end;
    SetLength(Readers, 0);
  end;
end;
Hat jemand eine Idee, wie man dass mit einem dynamischen Array hinbekommt?

Grüße
Matthias

WM_CLOSE 13. Mär 2011 23:13

AW: WinSCard.dll
 
Ich glaube es geh auch mit einen P(Ansi)Char, aber dann muss man den Speicher selbst allozieren, Man muss alo trotzdem erstmal pauschal eine Puffergröße festlegen.

Dr.MAD 14. Mär 2011 22:34

AW: WinSCard.dll
 
Hast recht! Jetzt funktionierts:

Delphi-Quellcode:
SCARDCONTEXT = ULONG_PTR; // Cardinal
  PSCARDCONTEXT = ^SCARDCONTEXT;
  LPSCARDCONTEXT = ^SCARDCONTEXT;

  function SCardListReadersA(hContext: SCARDCONTEXT; mszGroups: LPCSTR; mszReaders: PAnsiChar; pcchReaders: PDWORD): ULONG; stdcall; external 'WinSCard.dll';

...

function GetSmartCardReadersList(var SmartCardReaders: TStringList): Cardinal;
var X: Integer;
    Size: Cardinal;
    AnsiAry: Array of AnsiChar;
    TmpStr: String;
begin
  // Evtl. StringList leeren
  SmartCardReaders.Clear;
  // Größe für Array einlesen
  Result:=SCardListReadersA(0, 0, nil, @Size);
  if (Result=0) and (Size>0) then begin
    // Speicher reservieren
    SetLength(AnsiAry, Size);
    // Reader-Liste als Multi-String (xxxxx+#0+xxxxx+#0+xxxxx+#0+#0) einlesen
    Result:=SCardListReadersA(0, 0, @AnsiAry[0], @Size);
    if Result=0 then begin
      // Multi-String -> StringList
      for X:=Low(AnsiAry) to High(AnsiAry) do begin
        if AnsiAry[X]<>#0 then TmpStr:=TmpStr+AnsiAry[X] else begin
          if TmpStr<>'' then SmartCardReaders.Add(TmpStr);
          TmpStr:='';
        end;
      end;
    end;
    // Speicher freigeben
    SetLength(AnsiAry, 0);
  end;
end;
:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz