unit RgReaderApi;
// {$Define UpdateFirmwareInc}

interface

uses
  RgReaderApiType, Winapi.Windows, System.SysUtils;

type
  ERgReaderError = class(Exception);

var
  FRgReaderApiLibrary: HMODULE;

  RG_GetVersion: TRG_GetVersion;
  RG_InitializeLib: TRG_InitializeLib;
  RG_Uninitialize: TRG_Uninitialize;
  RG_CloseResource: TRG_CloseResource;
  RG_FindEndPoints: TRG_FindEndPoints;
  RG_GetFoundEndPointInfo: TRG_GetFoundEndPointInfo;
  RG_FindDevices: TRG_FindDevices;
  RG_GetFoundDeviceInfo: TRG_GetFoundDeviceInfo;
  RG_InitDevice: TRG_InitDevice;
  RG_CloseDevice: TRG_CloseDevice;
  RG_GetInfo: TRG_GetInfo;
  RG_GetInfoExt: TRG_GetInfoExt;
  RG_SetCardsMask: TRG_SetCardsMask;
  RG_ClearProfiles: TRG_ClearProfiles;
  RG_WriteProfile: TRG_WriteProfile;
  RG_GetStatus: TRG_GetStatus;
  // RG_SetProfile: TRG_SetProfile;
  RG_ResetField: TRG_ResetField;
  RG_Iso_Ras: TRG_Iso_Ras;
  RG_MF_AuthorizeClassic: TRG_MF_AuthorizeClassic;
  RG_MF_ReadBlock: TRG_MF_ReadBlock;
  RG_MF_WriteBlock: TRG_MF_WriteBlock;
  RG_UpdateFirmware: TRG_UpdateFirmware;
  RG_Iso_Rats: TRG_Iso_Rats;
  RG_Iso_Exchange: TRG_Iso_Exchange;
  RG_Iso_Auth: TRG_Iso_Auth;
    RG_GetCard: TRG_GetCard;
  RG_UnlockSettigns: TRG_UnlockSettigns;
  RG_CommitSettings: TRG_CommitSettings;
  RG_ReadSettingsBlock: TRG_ReadSettingsBlock;
  RG_WriteSettingsBlock: TRG_WriteSettingsBlock;
const

  // {$IFDEF WIN32}
  // RG_DLL_Name = 'rglib_x86.dll';
  // {$ELSE}
  // RG_DLL_Name = 'rglib_x64.dll';
  // {$ENDIF}
  RG_DLL_Name = 'librgsec.dll';

function RgLoaded(): boolean;
function RgLoadLibrary(): boolean;
function RgUnloadLibrary(): boolean;

implementation

uses SHFolder;

function GetSpecialFolderPath(folder: integer): string;
const
  SHGFP_TYPE_CURRENT = 0;
var
  path: array [0 .. MAX_PATH] of char;
begin
  if SUCCEEDED(SHGetFolderPath(0, folder, 0, SHGFP_TYPE_CURRENT, @path[0])) then
    Result := path
  else
    Result := '';
end;

function RgLoaded(): boolean;
begin
  Result := FRgReaderApiLibrary <> 0;
end;

function RgUnloadLibrary(): boolean;
begin
  try
    FreeLibrary(FRgReaderApiLibrary);
  finally
    FRgReaderApiLibrary := 0;
  end;
end;

{ procedure CheckLoadLibrary(const Name: string);
  begin
  RgReaderApiLibrary := Windows.LoadLibrary(PChar(Name));
  if RgReaderApiLibrary = 0 then
  raise ERgReaderError.Create(SysErrorMessage(GetLastError) + ': ' + Name);
  end; }

function CheckGetProcAddress(const Name: string): Pointer;
begin
  Result := GetProcAddress(FRgReaderApiLibrary, PChar(Name));
  if Result = nil then
    RgUnloadLibrary;
end;

function RgLoadLibrary(): boolean;
var
  RG_DLL_Name_: string;
begin
  Result := false;
  if not RgLoaded then
  begin
    FRgReaderApiLibrary := LoadLibrary(PWideChar(RG_DLL_Name));
    if FRgReaderApiLibrary = 0 then
    begin
{$IFDEF WIN32}
      FRgReaderApiLibrary :=
        LoadLibrary(PWideChar('windows_x86_release\' + RG_DLL_Name));
{$ELSE}
      FRgReaderApiLibrary :=
        LoadLibrary(PWideChar('windows_x64_release\' + RG_DLL_Name));
{$ENDIF}
    end;
    if FRgReaderApiLibrary = 0 then
    begin
      RG_DLL_Name_ := GetSpecialFolderPath(CSIDL_WINDOWS) + '\System32\' +
        RG_DLL_Name;
      FRgReaderApiLibrary := LoadLibrary(PWideChar(RG_DLL_Name_));
    end;
    if FRgReaderApiLibrary = 0 then
    begin
      RG_DLL_Name_ := GetSpecialFolderPath(CSIDL_WINDOWS) + '\SysWOW64\' +
        RG_DLL_Name;
      FRgReaderApiLibrary := LoadLibrary(PWideChar(RG_DLL_Name_));
    end;
  end;
  try
    if FRgReaderApiLibrary <> 0 then
    begin
      RG_GetVersion := CheckGetProcAddress('RG_GetVersion');
      RG_InitializeLib := CheckGetProcAddress('RG_InitializeLib');
      RG_Uninitialize := CheckGetProcAddress('RG_Uninitialize');
      RG_CloseResource := CheckGetProcAddress('RG_CloseResource');
      RG_FindEndPoints := CheckGetProcAddress('RG_FindEndPoints');
      RG_GetFoundEndPointInfo := CheckGetProcAddress('RG_GetFoundEndPointInfo');
      RG_FindDevices := CheckGetProcAddress('RG_FindDevices');
      RG_GetFoundDeviceInfo := CheckGetProcAddress('RG_GetFoundDeviceInfo');
      RG_InitDevice := CheckGetProcAddress('RG_InitDevice');
      RG_CloseDevice := CheckGetProcAddress('RG_CloseDevice');
      RG_GetInfo := CheckGetProcAddress('RG_GetInfo');
      RG_GetInfoExt := CheckGetProcAddress('RG_GetInfoExt');
      RG_SetCardsMask := CheckGetProcAddress('RG_SetCardsMask');
      RG_ClearProfiles := CheckGetProcAddress('RG_ClearProfiles');
      RG_WriteProfile := CheckGetProcAddress('RG_WriteProfile');
      RG_GetStatus := CheckGetProcAddress('RG_GetStatus');
      // RG_SetProfile := CheckGetProcAddress('RG_SetProfile');
      RG_ResetField := CheckGetProcAddress('RG_ResetField');
      RG_Iso_Ras := CheckGetProcAddress('RG_Iso_Ras');
      RG_MF_AuthorizeClassic := CheckGetProcAddress('RG_MF_AuthorizeClassic');
      RG_MF_ReadBlock := CheckGetProcAddress('RG_MF_ReadBlock');
      RG_MF_WriteBlock := CheckGetProcAddress('RG_MF_WriteBlock');
      RG_Iso_Rats := CheckGetProcAddress('RG_Iso_Rats');
      RG_Iso_Exchange := CheckGetProcAddress('RG_Iso_Exchange');
      RG_Iso_Auth := CheckGetProcAddress('RG_Iso_Auth');
            RG_GetCard := CheckGetProcAddress('RG_GetCard');
      RG_UnlockSettigns := CheckGetProcAddress('RG_UnlockSettigns');
      RG_CommitSettings := CheckGetProcAddress('RG_CommitSettings');
      RG_ReadSettingsBlock := CheckGetProcAddress('RG_ReadSettingsBlock');
      RG_WriteSettingsBlock := CheckGetProcAddress('RG_WriteSettingsBlock');
{$IFDEF UpdateFirmwareInc}
      RG_UpdateFirmware := CheckGetProcAddress('RG_UpdateFirmware');
{$ENDIF}
      Result := true;
    end;
  except

  End;
end;

initialization

FRgReaderApiLibrary := 0;

end.
