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?
a source to share
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.
a source to share
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.
a source to share
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);
a source to share