送你个函数吧
function TestPrinterStatus:byte;
begin
if getversion<$80000000 then
//NT、2000、XP、2003
begin
if not OpenPortTalk then
raise exception.Create('无法加载打印机驱动程序');
result := inportb($379);
ClosePortTalk;
end
else
//windows 95、98、ME
result := GetPrinterStatus;
end;
function GetPrinterStatus:byte;
asm
MOV DX,$379;
IN AL,DX;
end;
要将如下单元加入工程中,并在以上代码use下面的单元,并下载porttalk,把里面的porttalk.sys和porttalk.reg放在可执行文件的目录里,第一次运行时会自动安装到system32目录下,但好象windows 2003要手动安装,然后重启。
unit UnitPortTalk;
interface
uses
Windows, SysUtils, Dialogs,WinSvc;
const
PORTTALK_TYPE = 40000;
{ 32768-65535是保留给用户使用的}
METHOD_BUFFERED = 0;
FILE_ANY_ACCESS = 0;
IOCTL_IOPM_RESTRICT_ALL_ACCESS = PORTTALK_TYPE shl 16 +
$900 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS = PORTTALK_TYPE shl 16 +
$901 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_SET_IOPM = PORTTALK_TYPE shl 16 +
$902 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_ENABLE_IOPM_ON_PROCESSID = PORTTALK_TYPE shl 16 +
$903 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_READ_PORT_UCHAR = PORTTALK_TYPE shl 16 +
$904 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_WRITE_PORT_UCHAR = PORTTALK_TYPE shl 16 +
$905 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
function OpenPortTalk:boolean;
procedure ClosePortTalk;
procedure outportb(PortAddress:word;byte1:byte);
function inportb(PortAddress:word):byte;
function StartPortTalkDriver:boolean;
procedure InstallPortTalkDriver;
var
PortTalk_Handle:THANDLE;
{PortTalk句柄}
implementation
procedure outportb(PortAddress:word;byte1:byte);
var
error:boolean;
BytesReturned
WORD;
Buffer:array[0..2]of byte;
pBuffer
word;
begin
pBuffer := pword(@Buffer[0]);
pBuffer^ := PortAddress;
Buffer[2] := byte1;
error := DeviceIoControl(PortTalk_Handle,
Cardinal(IOCTL_WRITE_PORT_UCHAR),
@Buffer,
3,
nil,
0,
BytesReturned,
nil);
if (not error) then
showmessagefmt('从PortTalk输出端口数据时出错:%d',[GetLastError]);
end;
function inportb(PortAddress:word):byte;
var
error:boolean;
BytesReturned
WORD;
Buffer:array[0..2]of byte;
pBuffer
word;
begin
pBuffer := pword(@Buffer[0]);
pBuffer^ := PortAddress;
error := DeviceIoControl(PortTalk_Handle,
cardinal(IOCTL_READ_PORT_UCHAR),
@Buffer,
2,
@Buffer,
1,
BytesReturned,
nil);
if (not error) then
showmessagefmt('从PortTalk输入端口数据时出错:%d',[GetLastError]);
result:=Buffer[0];
end;
function OpenPortTalk:boolean;
begin
{打开PortTalk,如果不能打开,则安装它}
PortTalk_Handle := CreateFile('//./PortTalk',
GENERIC_READ,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(PortTalk_Handle = INVALID_HANDLE_VALUE) then
begin
{启动驱动程序}
StartPortTalkDriver;
{再次打开PortTalk}
PortTalk_Handle := CreateFile('//./PortTalk',
GENERIC_READ,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(PortTalk_Handle = INVALID_HANDLE_VALUE) then
begin
showmessage('PortTalk: 不能存取PortTalk,请确保驱动程序已安装。');
result:=false;
exit;
end;
end;
result:=true;
end;
procedure ClosePortTalk;
begin
CloseHandle(PortTalk_Handle);
end;
function StartPortTalkDriver:boolean;
type
TNewStartService=function (hService: SC_HANDLE;
dwNumServiceArgs: DWORD;
lpServiceArgVectors: PPChar): BOOL;
stdcall;
var
SchSCManager:SC_HANDLE;
schService:SC_HANDLE;
ret:BOOL;
err
WORD;
begin
{打开Service Control Manager}
SchSCManager := OpenSCManager (nil, { 机器 (nil = 本机) }
nil, { 数据库 (nil = 默认 }
SC_MANAGER_ALL_ACCESS);
{ 访问权 }
if (SchSCManager = 0) then
if (GetLastError = ERROR_ACCESS_DENIED) then
begin
{ 没有权限打开SCM管理,必须是poor用户}
showmessage('PortTalk: 没有权限访问Service Control Manager,'#$D#$A+
'不能安装和启动PortTalk,请使用超级用户来安装。');
result:=false;
exit;
end;
repeat begin
{打开PortTalk服务数据库}
schService := OpenService(SchSCManager, {服务数据库句柄}
'PortTalk', {要启动的服务名}
SERVICE_ALL_ACCESS);
{存取的权限}
if (schService = 0) then
case (GetLastError) of
ERROR_ACCESS_DENIED:
begin
showmessage('PortTalk: 没有权限访问PortTalk服务数据库');
result:=false;
exit;
end;
ERROR_INVALID_NAME:
begin
showmessage('PortTalk: 指定的服务名无效');
result:=false;
exit;
end;
ERROR_SERVICE_DOES_NOT_EXIST:
begin
showmessage('PortTalk: PortTalk驱动程序不存在');
InstallPortTalkDriver;
end;
end;
end until (schService <> 0);
{启动PortTalk驱动程序,如果发生错误,一般是由于PortTalk.SYS不存在。}
ret := TNewStartService(@StartService) (schService, {服务标识}
0, {参数个数}
nil);
{参数}
if (ret) then
//showmessage('PortTalk: PortTalk安装成功!')
else
begin
err := GetLastError;
if (err = ERROR_SERVICE_ALREADY_RUNNING) then
showmessage('PortTalk: PortTalk已经安装')
else
begin
showmessage('PortTalk: 启动PortTalk时发生未知错误。'+#$D#$A+
'PortTalk.SYS没有放入/System32/Drivers目录吗?');
result:=false;
exit;
end;
end;
{关闭Service Control Manager}
CloseServiceHandle (schService);
result:=TRUE;
end;
procedure InstallPortTalkDriver;
var
SchSCManager:SC_HANDLE;
schService:SC_HANDLE;
err
WORD;
DriverFileName:array[0..79]of CHAR;
begin
if (GetSystemDirectory(DriverFileName, 55)=0) then
begin
showmessage('PortTalk: 取System目录出错');
exit;
end;
{加入驱动程序文件名}
lstrcat(DriverFileName,'/Drivers/PortTalk.sys');
showmessagefmt('PortTalk: 拷贝驱动程序到%s',[DriverFileName]);
{拷贝驱动程序到System32/drivers目录,如果出错,一般是因为文件不存在。}
if (not CopyFile('PortTalk.sys', DriverFileName, FALSE)) then
begin
showmessagefmt('PortTalk: 拷贝驱动程序到以下位置出错:%s'+#$D#$A+
'请手工拷贝到system32/driver目录',
[DriverFileName]);
exit;
end;
{打开Service Control Manager}
SchSCManager := OpenSCManager (nil, { 机器 (nil = 本机) }
nil, { 数据库 (nil = 默认 }
SC_MANAGER_ALL_ACCESS);
{ 访问权 }
schService := CreateService (SchSCManager, { SCManager数据库 }
'PortTalk', { 服务个数 }
'PortTalk', { 显示名 }
SERVICE_ALL_ACCESS, { 权限 }
SERVICE_KERNEL_DRIVER, { 服务类别 }
SERVICE_DEMAND_START, { 启动类别 }
SERVICE_ERROR_NORMAL, { 出错控件类别 }
'System32/Drivers/PortTalk.sys', { 服务二进制文件 }
nil, { 加入的组 }
nil, { 标识 }
nil, { 隶属 }
nil, { 本地帐户 }
nil { 密码 }
);
if (schService = 0) then
begin
err := GetLastError;
if (err = ERROR_SERVICE_EXISTS) then
showmessage('PortTalk: 驱动程序不存在。')
else
showmessage('PortTalk:建立服务时发生未知的错误。');
end
else
showmessage('PortTalk: 成功安装!');
{ 关闭Service Control Manager }
CloseServiceHandle (schService);
end;
end.