⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitporttalk.pas

📁 游戏变速齿轮源码 游戏变速齿轮源码 游戏变速齿轮源码
💻 PAS
字号:
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:DWORD;
    Buffer:array[0..2]of byte;
    pBuffer:pword;
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:DWORD;
    Buffer:array[0..2]of byte;
    pBuffer:pword;
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:DWORD;
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:DWORD;
    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.

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -