Delphi调用安装驱动sys的单元

时间:2023-03-09 16:25:56
Delphi调用安装驱动sys的单元
unit SysDriver;

interface

uses windows, winsvc; // jwawinsvc;

Type
TSysDriver = class(TObject)
private
HomeDir, DriverDir, DriverName, DEVICE_NAME_STRING,
DriverPath : string; // the whole thing
hSCMan : SC_HANDLE; // Service Control Manager
hDevice : SC_HANDLE; // Handle for device
public
HaveLoad : Boolean;
BaseControlCode : DWORD;
constructor Create(DeviceName: string); //---------------------------------------
// Interact with Service Control Manager
//---------------------------------------
function OpenSCM: DWORD;
function CloseSCM: DWORD; //---------------------------------------
// Install/Start/Stop/Remove driver
//---------------------------------------
function Install(newdriverpath: string): DWORD; { use '' for default }
function Start: DWORD;
function Stop: DWORD;
function Remove: DWORD; //--------------------------------
// Device Open/Close
//--------------------------------
function DeviceOpen: DWORD; // get a valid hDevice
function DeviceClose: DWORD; //--------------------------------
function IOControl(Cmd: DWORD; inBuf: Pointer; inSize: DWORD;
outbuf: Pointer; var outSize: DWORD): Boolean;
//--------------------------------
function ErrorLookup(ErrorNum: DWORD): string;
end; //-------------------------------------------
implementation
//-------------------------------------------
uses sysutils; Const // from ntddk
// Service Types (Bit Mask)
SERVICE_KERNEL_DRIVER = $;
SERVICE_FILE_SYSTEM_DRIVER = $;
SERVICE_ADAPTER = $;
SERVICE_RECOGNIZER_DRIVER = $; SERVICE_DRIVER = SERVICE_KERNEL_DRIVER or
SERVICE_FILE_SYSTEM_DRIVER or
SERVICE_RECOGNIZER_DRIVER; SERVICE_WIN32_OWN_PROCESS = $;
SERVICE_WIN32_SHARE_PROCESS = $;
SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS or
SERVICE_WIN32_SHARE_PROCESS; SERVICE_INTERACTIVE_PROCESS = $; SERVICE_TYPE_ALL = SERVICE_WIN32 or
SERVICE_ADAPTER or
SERVICE_DRIVER or
SERVICE_INTERACTIVE_PROCESS;
// Start Type
SERVICE_BOOT_START = $;
SERVICE_SYSTEM_START = $;
SERVICE_AUTO_START = $;
SERVICE_DEMAND_START = $;
SERVICE_DISABLED = $; // Error control type
SERVICE_ERROR_IGNORE = $;
SERVICE_ERROR_NORMAL = $;
SERVICE_ERROR_SEVERE = $;
SERVICE_ERROR_CRITICAL = $; Type
TErrorMsg = record
Num: DWORD;
Msg: string;
end; Const
ErrorMsgCt = ;
ERROR_SCM_CANT_CONNECT = ;
ERROR_NO_DEVICE_HANDLE = ;
ERROR_GW_BUFFER_TOO_SMALL = ;
ERROR_UNEXPECTED = ; ErrorMsgs: array[..ErrorMsgCt] of TErrorMsg = (
(Num: ERROR_SUCCESS ; Msg: 'Operation was successful'),
(Num: ERROR_INVALID_FUNCTION ; Msg: 'Invalid Function'),
(Num: ERROR_ACCESS_DENIED ; Msg: 'Access denied'),
(Num: ERROR_CIRCULAR_DEPENDENCY ; Msg: 'Circular dependency'),
(Num: ERROR_DATABASE_DOES_NOT_EXIST ; Msg: 'Database doesn''t exist'),
(Num: ERROR_DEPENDENT_SERVICES_RUNNING; Msg: 'Dependent services running'),
(Num: ERROR_DUP_NAME ; Msg: 'Display name already exists'),
(Num: ERROR_INVALID_HANDLE ; Msg: 'Invalid handle'),
(Num: ERROR_INVALID_NAME ; Msg: 'Invalid service name'),
(Num: ERROR_INVALID_PARAMETER ; Msg: 'Invalid Parameter'),
(Num: ERROR_INVALID_SERVICE_ACCOUNT ; Msg: 'User account doesn''t exist'),
(Num: ERROR_INVALID_SERVICE_CONTROL ; Msg: 'Invalid service control code'),
(Num: ERROR_PATH_NOT_FOUND ; Msg: 'Path not found'),
(Num: ERROR_SERVICE_ALREADY_RUNNING ; Msg: 'Service already running'),
(Num: ERROR_SERVICE_CANNOT_ACCEPT_CTRL; Msg: 'Service can''t accept control'),
(Num: ERROR_SERVICE_DATABASE_LOCKED ; Msg: 'The database is locked'),
(Num: ERROR_SERVICE_DEPENDENCY_DeleteD; Msg: 'Depends on nonexistant service'),
(Num: ERROR_SERVICE_DEPENDENCY_FAIL ; Msg: 'Depends on service that failed'),
(Num: ERROR_SERVICE_DISABLED ; Msg: 'Service has been disabled'),
(Num: ERROR_SERVICE_DOES_NOT_EXIST ; Msg: 'Service doesn''t exist'),
(Num: ERROR_SERVICE_EXISTS ; Msg: 'Service already exists'),
(Num: ERROR_SERVICE_LOGON_FAILED ; Msg: 'Service couldn''t be logged on'),
(Num: ERROR_SERVICE_MARKED_FOR_Delete ; Msg: 'Service marked for deletion'),
(Num: ERROR_SERVICE_NO_THREAD ; Msg: 'Couldn''t create thread'),
(Num: ERROR_SERVICE_NOT_ACTIVE ; Msg: 'Service hasn''t been started'),
(Num: ERROR_SERVICE_REQUEST_TIMEOUT ; Msg: 'Service timed out'),
(Num: ERROR_GW_BUFFER_TOO_SMALL ; Msg: 'Buffer too small'),
(Num: ERROR_NO_DEVICE_HANDLE ; Msg: 'No device handle'),
(Num: ERROR_SCM_CANT_CONNECT ; Msg: 'Can''t connect to Service Control Manager'),
(Num: ERROR_UNEXPECTED ; Msg: 'An unexpected error occured')
); //-----------------------------------------
function TSysDriver.ErrorLookup(ErrorNum: DWORD): string;
//-----------------------------------------
Var
N: integer;
Begin
If Error <> ERROR_SUCCESS then
begin
result := 'Error: ' + IntToStr(ErrorNum) + ': ';
exit;
end; For N := to ErrorMsgCt do
Begin
if ErrorNum = ErrorMsgs[N].Num then
Begin
break;
end;
end;
result:=ErrorMsgs[N].Msg; end; //----------------------------------------------------------
// IOCTL codes
//----------------------------------------------------------
function CTL_CODE(DeviceType: integer; func: integer; meth: integer; access: integer): DWORD;
Begin
result := (DeviceType shl ) or (Access shl ) or (func shl ) or (meth);
end; Const
// Buffering method for user-mode app talking to drive
METHOD_BUFFERED = ;
METHOD_IN_DIRECT = ;
METHOD_OUT_DIRECT = ;
METHOD_NEITHER = ; // Define the access allowed
FILE_ANY_ACCESS = ;
FILE_READ_ACCESS = ; // file & pipe
FILE_WRITE_ACCESS = ; // file & pipe //-----------------------------------------
constructor TSysDriver.Create(DeviceName: string);
//-----------------------------------------
Begin
hSCMan := ;
hDevice := INVALID_HANDLE_VALUE;
HomeDir := ExtractFilePath(GetModuleName(HInstance));
DEVICE_NAME_STRING := DeviceName;
DriverName := DEVICE_NAME_STRING;
HaveLoad :=False;
// default driver name needed by stop/remove if install wasn't executed
// this run (ie: driver already installed
end; //-------------------------------------------
function TSysDriver.OpenSCM: DWORD;
//-------------------------------------------
Begin
result := ERROR_SUCCESS;
hSCMan := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCMan = then result := ERROR_SCM_CANT_CONNECT;
end; //-------------------------------------------
function TSysDriver.CloseSCM: DWORD;
//-------------------------------------------
Begin
result := ERROR_SUCCESS;
CloseServiceHandle(hSCMan);
hSCMan := ;
end; //-----------------------------------------
function TSysDriver.Install(newdriverpath: string): DWORD; { use '' for default }
//-----------------------------------------
Var
hService: SC_HANDLE;
dwStatus: DWORD;
Begin
dwStatus := ; If newdriverpath = '' then
Begin
DriverDir := HomeDir;
DriverName := DEVICE_NAME_STRING;
end else
Begin
DriverDir := ExtractFilePath(newdriverpath);
// DriverName := ExtractFileName(driverpath);
end;
DriverPath := DriverDir + DriverName+'.sys'; // add to service control manager's database
hService := CreateService(hSCMan, PChar(DriverName),PChar(DriverName),
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, PChar(DriverPath),
nil, nil, nil, nil, nil);
if (hService = ) then
Begin
dwStatus := GetLastError();
end else
Begin
CloseServiceHandle(hService);
end; result := dwStatus;
end; //-------------------------------------------
function TSysDriver.Start: DWORD;
//-------------------------------------------
Var
hService: SC_HANDLE;
dwStatus: DWORD;
lpServiceArgVectors: PChar;
temp: LongBool;
Begin
dwStatus := ;
lpServiceArgVectors := nil; // get a handle to the service
hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
if hService <> then
Begin
// start the driver
temp := StartService(hService, , PChar(lpServiceArgVectors));
if not temp then dwStatus := GetLastError();
end else dwStatus := GetLastError(); if (hService <> ) then CloseServiceHandle(hService);
result := dwStatus;
end; //-------------------------------------------
function TSysDriver.Stop: DWORD;
//-------------------------------------------
Var
hService: SC_HANDLE;
dwStatus: DWORD;
serviceStatus: TServiceStatus;
temp: LongBool;
Begin
dwStatus := ; // get a handle to the service
hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
if hService <> then
Begin
// stop the driver
temp := ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
if not temp then dwStatus := GetLastError();
end else dwStatus := GetLastError(); if (hService <> ) then CloseServiceHandle(hService);
result := dwStatus;
end; //-------------------------------------------
function TSysDriver.Remove: DWORD;
//-------------------------------------------
Var
hService: SC_HANDLE;
dwStatus: DWORD;
temp: LongBool;
Begin
dwStatus := Stop; // ignore result // get a handle to the service
hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
if hService <> then
Begin
temp := DeleteService(hService);
if not temp then dwStatus := GetLastError();
end else dwStatus := GetLastError(); if (hService <> ) then CloseServiceHandle(hService);
result := dwStatus;
end; //=============================================================
// Device Open/Close functions
//============================================================= //-------------------------------------------
function TSysDriver.DeviceOpen: DWORD;
//-------------------------------------------
Var
dwStatus: DWORD;
Begin
dwStatus := ; if hDevice <> INVALID_HANDLE_VALUE then DeviceClose; // get a handle to the device
hDevice := CreateFile(
{ lpFileName: PChar } PChar('\\.\'+ DEVICE_NAME_STRING),
{ dwDesiredAccess: integer } GENERIC_READ or GENERIC_WRITE,
{ dwShareMode: Integer } ,
{ lpSecurityAttributes } nil,
{ dwCreationDisposition: DWORD } OPEN_EXISTING,
{ dwFlagsAndAttributes: DWORD } FILE_ATTRIBUTE_NORMAL,
{ hTemplateFile: THandle } ); if hDevice = INVALID_HANDLE_VALUE then
Begin
dwStatus := GetLastError();
end else
begin
HaveLoad:=True;
end; result := dwStatus;
end; //-------------------------------------------
function TSysDriver.DeviceClose: DWORD;
//-------------------------------------------
Var
dwStatus: DWORD;
Begin
dwStatus := ;
if (hDevice <> INVALID_HANDLE_VALUE) then CloseHandle(hDevice);
hDevice := INVALID_HANDLE_VALUE;
result := dwStatus; { assume that it went OK? }
end; //-------------------------------------------
function TSysDriver.IOControl(Cmd: DWORD; inBuf: Pointer; inSize: DWORD;
outbuf: Pointer; var outSize: DWORD): Boolean;
//-------------------------------------------
Var
BytesReturned: DWORD;
MyControlCode: DWORD; Begin
Result := False; if hDevice = INVALID_HANDLE_VALUE then Exit; MyControlCode := Cmd;//CTL_CODE(BaseControlCode, Cmd , METHOD_BUFFERED, FILE_ANY_ACCESS); BytesReturned := ;
Result := DeviceIoControl(hDevice, MyControlCode ,
{ in buffer (to driver) } InBuf, inSize,
{ out buffer (from driver) } OutBuf, outSize, BytesReturned, nil);
end; end.

http://www.lsworks.net/article/72.html