Unit Driver;

{
  V tomto souboru jsou implementovany rutiny pro
  praci s ovladacem, ktery slouzi jako prodlouzena
  ruka aplikace a sbira pro ni data.
}

Interface

Uses
  Windows;

Function DriverIOCTL(AIndex:Integer; AInBuffer:Pointer; aInBufferLength:DWORD; AOutBuffer:Pointer; AOutBufferLength:DWORD; AReturnLength:PDWORD = Nil):Boolean;
Function DriverConnect(AAccess:DWORD = GENERIC_ALL; AShare:DWORD = 0):Boolean;
Function DriverDisconnect:Boolean;
Function DriverConnected:Boolean;
Function DriverLoad:Boolean;
Function DriverUnload:Boolean;
Function DriverInit(ADriverServiceName:WideString; ADriverFileName:WideString; ADriverDeviceName:WideString; AIOCTLs:Array Of DWORD):Boolean;
Procedure DriverFinit;

Implementation

Uses
  Utils, scmDrivers, SysUtils;

Var
  // Handle zarizeni ovladace
  hDevice : THandle;
  // Nazev zarizeni
  DriverDeviceName : WideString;
  // Interni nazev sluzby ovladace
  DriverServiceName : WideString;
  // Jmeno souboru ovladace vcetne absolutni cesty
  DriverFileName : WideString;
  // Seznam kodu IOCTL, se kterymi ovladac umi
  // pracovat
  IOCTLs : Array Of DWORD;

Function DriverInit(ADriverServiceName:WideString; ADriverFileName:WideString; ADriverDeviceName:WideString; AIOCTLs:Array Of DWORD):Boolean;
{
  Inicializuje promenne tohoto modulu podle parametru
  tak, aby mohly byt volany dalsi funkce pro
  praci s ovladacem. Dale nainstaluje dany ovladac
  do databaze sluzeb.
}
Var
  I : Integer;
begin
hDevice := INVALID_HANDLE_VALUE;
DriverDeviceName := '\\.\' + ADriverDeviceName;
DriverServiceName := ADriverServiceName;
DriverFileName := ADriverFileName;
SetLength(IOCTLs, Length(AIOCTLs));
For I := Low(AIOCTLs) To High(AIOCTLs) Do
  IOCTLs[I] := AIOCTLs[I];

SCMDriverInstall(DriverServiceName, DriverFileName);
Result := True;
end;

Procedure DriverFinit;
{
  Odinstaluje ovladac.
}
begin
SCMDriverUninstall(DriverServiceName);
SetLength(IOCTLs, 0);
end;

Function DriverLoad:Boolean;
{
  Pokusi se nacist ovladac do pameti jadra.
}
begin
Result := SCMDriverLoad(DriverServiceName);
end;

Function DriverUnload:Boolean;
{
  Pokusi se uvolnit ovladac z pameti jadra.
}
begin
Result := SCMDriverUnload(DriverServiceName);
end;

Function DriverConnect(AAccess:DWORD = GENERIC_ALL; AShare:DWORD = 0):Boolean;
{
  Pokusi se pripojit k zarizeni, ktere ovladac
  vytvoril pro komunikaci s aplikaci.
}
begin
hDevice := CreateFileW(PWideChar(DriverDeviceName), AAccess, AShare, Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := hDevice <> INVALID_HANDLE_VALUE;
end;

Function DriverDisconnect:Boolean;
{
  Odpoji se od komunikacniho zarizeni ovladace.
}
begin
Result := CloseHandle(hDevice);
If Result Then
  hDevice := INVALID_HANDLE_VALUE;
end;

Function DriverConnected:Boolean;
{
  Zjisti, zda je ovladac k zarizeni pripojen.
  Jedna se pouze o testovani platnosti hodnoty
  handle zarizeni, nedochazi k zadnemu volani
  jadra.
}
begin
Result := hDevice <> INVALID_HANDLE_VALUE;
end;

Function DriverIOCTL(AIndex:Integer; AInBuffer:Pointer; aInBufferLength:DWORD; AOutBuffer:Pointer; AOutBufferLength:DWORD; AReturnLength:PDWORD = Nil):Boolean;
{
  Posle pozadavek IOCTL na komunikacni zarizeni
  ovladace. Volajici pozadavek vybira pomoci
  indexu do pole, ktere vyplnoval pri inicializaci
  modulu (rutina DriverInit).
}
Var
  Dummy : DWORD;
begin
Dummy := 0;
Result := DeviceIoControl(hDevice, IOCTLs[AIndex], AInBuffer, AInBufferLength, AOutBuffer, AOutBufferLength, Dummy, Nil);
If Assigned(AReturnLength) Then
  AReturnLength^ := Dummy;
end;

End.

