【例子介绍】
【相关图片】
【源码结构】
unit WinIo;
interface
uses
Windows, kol, WinSvc;
const
DRIVER_NAME_NT='OSCI_DRVNT';
type
tMSR = packed record
HiPart,
LowPart: DWord;
end;
function CreateDrive: Boolean;
function UnLoadDeviceDriver:boolean;
function ReadMSRNT(ulECX:DWord; var MSRreg:tmsr):boolean;
function WriteMSRNT(ulECX:DWord;MSRreg:tmsr):boolean;
function PortDWordInNT(Port : DWord) : DWord;
function PortWordInNT(Port : DWord) : Word;
function PortInNT(Port : DWord) : Byte;
procedure PortDWordOutNT(Port : DWord; Data : DWord);
procedure PortWordOutNT(Port : DWord; Data : Word);
procedure PortOutNT(Port : DWord; Data : Byte);
Procedure GetPCIRDWord( dwBus, dwDev, dwFunc, offs : byte; var pdata:DWord);
implementation
const
METHOD_BUFFERED = 0;
METHOD_IN_DIRECT = 1;
METHOD_OUT_DIRECT = 2;
METHOD_NEITHER = 3;
MSR_TYPE = 40000;
PCI_TYPE=40000;
FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
FILE_WRITE_ACCESS = 2;
PCRAddress = $0cf8;
PCRData = $0cfc;
FILE_NAME_NT='OSCI_DRVNT.sys';
var
DriverHandle: THandle;
function ExtractRes(FileName: KolString): boolean;
var
HResInfo:HRSRC;
HGlobal :THandle;
ASize :integer;
S: pStream;
begin
Result := False;
HResInfo := FindResource(hInstance, 'Setup', 'sysfile');
if HResInfo <> 0 then
begin
HGlobal := LoadResource(hInstance, HResInfo);
if HGlobal <> 0 then
begin
ASize := SizeOfResource(hInstance, HResInfo);
S := NewExMemoryStream(LockResource(HGlobal), ASize );
S.SaveToFile(FileName,0, ASize);
S.Free;
Result := True;
end;
end;
end;
function LoadDeviceDriver:boolean;
var
FileW: PChar;
lpBuffer: array[0..255] of Char;
DestDir: string;
Code: Integer;
schSCManager, schService: SC_HANDLE;
b: PChar;
begin
Result := False; b := nil;
GetWindowsDirectory(lpBuffer, 255);
DestDir := lpBuffer '\System32\Drivers\';
FileW := PChar(DestDir FILE_NAME_NT);
Code := GetFileAttributes(FileW);
if (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0) then DeleteFile(FileW);
//if Windows.CopyFile(FILE_NAME_NT, FileW, False) then
if ExtractRes(FileW) then
begin
schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if schSCManager <> 0 then
begin
schService := CreateService(SchSCManager, // SCManager database
DRIVER_NAME_NT, // name of service
DRIVER_NAME_NT, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
FileW, // service's binary
nil, // no load ordering group
nil, // no tag identifier
nil, // no dependencies
nil, // LocalSystem account
nil // no password
);
if SchService <> 0 then
begin
StartService(schService, 0, b);
DriverHandle := CreateFile(PChar('\\.\' DRIVER_NAME_NT), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (DriverHandle <> INVALID_HANDLE_VALUE) and (DriverHandle <> 0);
CloseServiceHandle(schService);
end;
CloseServiceHandle(schSCManager);
end;
end;
end;
function UnLoadDeviceDriver:boolean;
var
schSCManager, schService: SC_HANDLE;
ServiceStatus: TServiceStatus;
begin
schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if schSCManager <> 0 then
begin
schService := OpenService(SchSCManager, DRIVER_NAME_NT, SERVICE_ALL_ACCESS);
if schService <> 0 then
begin
ControlService(schService, SERVICE_CONTROL_STOP, ServiceStatus);
DeleteService(schService);
CloseServiceHandle(schService);
end;
CloseServiceHandle(schSCManager);
end;
end;
function CreateDrive: Boolean;
begin
UnLoadDeviceDriver;
Result := LoadDeviceDriver;
end;
function CTL_CODE(Device,Funct,Method,Access:word):DWord;
begin
result:=(Device SHL 16) or (access SHL 14) or (funct SHL 2) or method;
end;
function ReadMSRNT(ulECX:DWord; var MSRreg:tmsr):boolean;
var
IOCTL_READ_MSR: longint;
ReturnedLength: DWord;
IoctlResult: boolean;
buf:array[1..2] of DWord;
begin
IOCTL_READ_MSR := CTL_CODE(MSR_TYPE, $981, METHOD_BUFFERED, FILE_ANY_ACCESS);
IoctlResult := DeviceIoControl(
DriverHandle, // Handle to device
IOCTL_READ_MSR, // RDMSR code
@ulECX, // Buffer to driver
sizeof(ulECX), // Length of buffer in bytes.
@buf, // Buffer from driver.
sizeof(buf), // Length of buffer in bytes.
ReturnedLength, // Bytes placed in outbuf.
nil //
);
MSRreg.LowPart:=buf[1];
MSRreg.HiPart:=buf[2];
result := IoctlResult;
end;
function WriteMSRNT(ulECX:DWord;MSRreg:tmsr):boolean;
var
IOCTL_WRITE_MSR:longint;
ReturnedLength:DWord;
IoctlResult:boolean;
buf:array[1..3] of DWord;
begin
buf[1]:=ulECX;
buf[2]:=MSRreg.LowPart;
buf[3]:=MSRreg.HiPart;
IOCTL_WRITE_MSR:=CTL_CODE(MSR_TYPE, $982, METHOD_BUFFERED, FILE_ANY_ACCESS);
IoctlResult:=DeviceIoControl(
DriverHandle, // Handle to device
IOCTL_WRITE_MSR, // WRMSR code
@buf, // Buffer to driver
sizeof(buf), // Length of buffer in bytes.
@result, // Buffer from driver.
sizeof(result), // Length of buffer in bytes.
ReturnedLength, // Bytes placed in outbuf.
nil // nil
);
result:=IoctlResult;
end;
function PortDWordInNT(Port : DWord) : DWord;
var
IOCTL_PCI_READ_PORT_ULONG:longint;
data:DWord;
IoctlResult:boolean;
ReturnedLength:DWord;
begin
data:=0;
IOCTL_PCI_READ_PORT_ULONG:=CTL_CODE( PCI_TYPE, $902, METHOD_BUFFERED, FILE_READ_ACCESS );
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_READ_PORT_ULONG,
@port,
sizeof(DWord),
@data,
sizeof(data),
ReturnedLength,
nil
);
assert(IoctlResult);
assert(ReturnedLength=sizeof(data));
result:=data;
end;
function PortWordInNT(Port : DWord) : Word;
var
IOCTL_PCI_READ_PORT_USHORT:longint;
data:Word;
IoctlResult:boolean;
ReturnedLength:DWord;
begin
data:=0;
IOCTL_PCI_READ_PORT_USHORT:=CTL_CODE( PCI_TYPE, $901, METHOD_BUFFERED, FILE_READ_ACCESS );
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_READ_PORT_USHORT,
@port,
sizeof(DWord),
@data,
sizeof(data),
ReturnedLength,
nil
);
assert(IoctlResult);
assert(ReturnedLength=sizeof(data));
result:=data;
end;
function PortInNT(Port : DWord) : Byte;
var
IOCTL_PCI_READ_PORT_UCHAR:longint;
data:byte;
IoctlResult:boolean;
ReturnedLength:DWord;
begin
data:=0;
IOCTL_PCI_READ_PORT_UCHAR:=CTL_CODE( PCI_TYPE, $900, METHOD_BUFFERED, FILE_READ_ACCESS );
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_READ_PORT_UCHAR,
@Port,
sizeof(DWord),
@data,
sizeof(data),
ReturnedLength,
nil
);
assert(IoctlResult);
assert(ReturnedLength=sizeof(data));
result:=data;
end;
procedure PortDWordOutNT(Port : DWord; Data : DWord);
type
TPCIInputBuffer=packed record
PortNumber:DWord;
DWordData:DWord;
end;
var
IOCTL_PCI_WRITE_PORT_ULONG:longint;
IoctlResult:boolean;
ReturnedLength:DWord;
DataLength:DWord;
PCIInputBuffer:TPCIInputBuffer;
begin
IOCTL_PCI_WRITE_PORT_ULONG:=CTL_CODE(PCI_TYPE, $912, METHOD_BUFFERED, FILE_WRITE_ACCESS);
PCIInputBuffer.DWordData:=data;
PCIInputBuffer.PortNumber:=port;
DataLength:=32 sizeof(PCIInputBuffer.DWordData);
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_WRITE_PORT_ULONG,
@PCIInputBuffer,
DataLength,
nil,
0,
ReturnedLength,
nil
);
assert(IoctlResult);
end;
procedure PortWordOutNT(Port : DWord; Data : Word);
type
TPCIInputBuffer=packed record
PortNumber:DWord;
WordData:Word;
end;
var
IOCTL_PCI_WRITE_PORT_USHORT:longint;
IoctlResult:boolean;
ReturnedLength:DWord;
DataLength:DWord;
PCIInputBuffer:TPCIInputBuffer;
begin
IOCTL_PCI_WRITE_PORT_USHORT:=CTL_CODE(PCI_TYPE, $911, METHOD_BUFFERED, FILE_WRITE_ACCESS);
PCIInputBuffer.WordData:=data;
PCIInputBuffer.PortNumber:=port;
DataLength:=32 sizeof(PCIInputBuffer.WordData);
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_WRITE_PORT_USHORT,
@PCIInputBuffer,
DataLength,
nil,
0,
ReturnedLength,
nil
);
assert(IoctlResult);
end;
procedure PortOutNT(Port : DWord; Data : Byte);
type
TPCIInputBuffer=packed record
PortNumber:DWord;
CharData:byte;
end;
var
IOCTL_PCI_WRITE_PORT_UCHAR:longint;
IoctlResult:boolean;
ReturnedLength:DWord;
DataLength:DWord;
PCIInputBuffer:TPCIInputBuffer;
begin
IOCTL_PCI_WRITE_PORT_UCHAR:=CTL_CODE(PCI_TYPE, $910, METHOD_BUFFERED, FILE_WRITE_ACCESS);
PCIInputBuffer.CharData:=data;
PCIInputBuffer.PortNumber:=port;
DataLength:=32 sizeof(PCIInputBuffer.CharData);
IoctlResult:=DeviceIoControl(
DriverHandle,
IOCTL_PCI_WRITE_PORT_UCHAR,
@PCIInputBuffer,
DataLength,
nil,
0,
ReturnedLength,
nil
);
assert(IoctlResult);
end;
Procedure GetPCIRDWord( dwBus, dwDev, dwFunc, offs : byte; var pdata:DWord);
var
Data: Cardinal;
begin
Data := $80000000 or (longint(dwBus) shl 16) or ((longint(dwDev) and $1f) shl 11) or
((longint(dwFunc) and $07 ) shl 8) or (offs and $fc);
PortDWordOutNT(PCRAddress, Data);
pData := PortDWOrdInNT(PCRData);
end;
end.


评论