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