How do I call the API with PUCHAR?

I am trying to use the API under Delphi. Here's the API documentation

OKERR ENTRY SCardCLMifareStdAuthent 
    (IN SCARDHANDLE ulHandleCard,IN ULONG ulMifareBlockNr,
    IN UCHAR ucMifareAuthMode,IN UCHAR ucMifareAccessType,IN UCHAR ucMifareKeyNr,
    IN PUCHAR pucMifareKey,IN ULONG ulMifareKeyLen);

      

While pucMifareKey: A pointer to the six byte Mifare key

. The code I have tried so far is

function Auth():Integer;
type
  TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal; ulMifareBlockNr: ULONG;
   ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; pucMifareKey: puchar;
   ulMifareKeyLen: cardinal):LONG;
var
  SCardCLMifareStdAuthent: TSCardCLMifareStdAuthent;
  hDLL: Integer;
  CardHandle: cardinal;
  i: integer;
  Key: array of UCHAR;
begin
  Result:=1;
  //CardHandle is defined here
  SetLength(Key, 6);
  for i := low(key) to high(key) do
    Key[i] := $FF;
  hDLL := LoadLibrary('scardsyn.dll');
  @SCardCLMifareStdAuthent := GetProcAddress(hDLL, 'SCardCLMifareStdAuthent');
  if @SCardCLMifareStdAuthent <> nil then
    Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, ^Key, 6);
  FreeLibrary(hDLL);
end;

      

The error I am getting is Incompatible types: 'Byte' and 'Char'

on line Result:=SCardCL....

due ^ Key pointer. Any ideas?

0


a source to share


5 answers


I don't know this DLL, but for Delphi pre 2009 I would do the following:

function Auth: integer;
type
  TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal;
    ulMifareBlockNr: ULONG; ucMifareAuthMode, ucMifareAccessType,
    ucMifareKeyNr: byte; pucMifareKey: PAnsiChar;
    ulMifareKeyLen: Cardinal): longint;
var
  SCardCLMifareStdAuthent: TSCardCLMifareStdAuthent;
  hDLL: Integer;
  CardHandle: Cardinal;
  Key: string;
begin
  Result := 1;
  //CardHandle is defined here...
  Key := StringOfChar(Chr($FF), 6);
  hDLL := LoadLibrary('scardsyn.dll');
  if hDLL <> 0 then begin
    @SCardCLMifareStdAuthent := GetProcAddress(hDLL, 'SCardCLMifareStdAuthent');
    if @SCardCLMifareStdAuthent <> nil then begin
      Result := SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0,
        PChar(Key), Length(Key));
    end;
    FreeLibrary(hDLL);
  end;
end;

      



The access violation you are getting probably comes from a C string not terminated with a 0. Using a string and casting it in a PChar will make things easier.

+1


a source


type
  TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal; ulMifareBlockNr: ULONG;
    ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; pucMifareKey: puchar;
    ulMifareKeyLen: cardinal):LONG;

      

I think you should replace 'byte' with 'UCHAR':



ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte;

      

It is bad practice to treat a byte like a char.

+2


a source


Wouldn't you be in Delphi 2009? If so, "char" is defined as 2 bytes. Try "AnsiChar" instead.

+1


a source


Try the following:

  • Introduce a new type for the UCHAR array.
  • Introduce a new local variable of pointer type.
  • Set this variable as a pointer to your array of keys
  • Use this pointer when calling the function

    type 
      TArrayOfUchar = array of UCHAR;
    
    var 
      ...
      Key  : TArrayOfUchar;
      PKey : ^TArrayOfUchar; 
    begin
      ...
      PKey = @Key;
      if @SCardCLMifareStdAuthent <> nil then
        Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, PKey, 6);
    
          

+1


a source


You specified that the key is a 6 byte array (uchar). You are declaring a dynamic array to pass, why not just declare an array?

var
  {...}
  MyKey: array[0..5] of UCHAR;
begin
  {...}
  Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, @MyKey, 6);

      

+1


a source







All Articles