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

📄 gwiopm_code.htm

📁 在Windows NT使用I/O端口,包括装载,开始,卸载驱动程序的函数.
💻 HTM
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>gwiopm.pas documentation</title>
</head>

<body bgcolor="#FFFFFF">

<table border="0" cellpadding="4" width="100%">
  <tr>
    <td width="50%">&nbsp;<a href="http://www.wideman-one.com/"><img src="logo_small.gif" alt="wideman-one" border="0" align="top" WIDTH="164" HEIGHT="22"></a><em><small><small>&nbsp; </small></small><br>
    <small><small>Last edit: <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%y-%m-%d" startspan -->98-06-18<!--webbot bot="Timestamp" endspan i-checksum="13341" --> Graham Wideman</small></small></em></td>
    <td width="50%" valign="top" align="right"><h3 align="right">Delphi</h3>
    </td>
  </tr>
</table>

<table border="1" cellpadding="2" width="100%">
  <tr>
    <td><big><big><strong>gwiopm.pas and gwiopm.sys documentation</strong></big></big><br>
    <em><small><small>Article created: 98-06-01</small></small><br>
    <small><small>Minor edits: 98-06-18</small></small></em></td>
  </tr>
</table>

<h3>Overview</h3>

<p>The basic model is shown below:</p>

<p><img src="iopm_tech.gif" alt="iopm_tech.gif (9789 bytes)" WIDTH="553" HEIGHT="396"></p>

<p>The keys to the whole picture are the kernel functions highlighted in yellow. &nbsp;
These are what our driver uses to command the NT kernel to install our desired I/O
permissions map.&nbsp; (Some comments on this below.)</p>

<p>The unit gwiopm.pas contains an object GWIOPM_Driver with a number of methods to
install the driver, prepare an I/O permissions map, hand that map to the driver, and then
from driver to kernel. &nbsp; </p>

<p>An I/O permissions map is 8K bytes in size, with each bit controlling access to one
port in the x86's 64K I/O port address space. Bit 0 of Byte 0 controls I/O address 0, and
so on. A &quot;1&quot; bit value disables access, a &quot;0&quot; value enables access.</p>

<p>There are other auxiliary functions to provide some diagnostics and general hacking
satisfaction.</p>

<table border="1" cellpadding="3" width="100%">
  <tr>
    <td width="263" valign="top"><strong>Task and </strong>GWIOPM_Driver<strong> function</strong></td>
    <td width="590" valign="top"><strong>Description</strong></td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Connect to Service Control Manager</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>OpenSCM: DWORD;
CloseSCM: DWORD;</small></pre>
    </td>
    <td width="590" valign="top">Open and close connection to Service Control Manager. Basic
    function of OpenSCM is to get a handle to the SCM, which is retained by the GWIOPM_Driver
    object for later use in the driver management functions.... </td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Manage Driver</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>Install(newdriverpath: string): DWORD;
Start: DWORD;
Stop: DWORD;
Remove: DWORD;</small></pre>
    </td>
    <td width="590" valign="top">Functions to install, start, stop and remove driver. &nbsp;
    Install() takes either a driver path or '' for default (gwiopm.sys in the application's
    home directory.)</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Device functions</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>DeviceOpen: DWORD;
DeviceClose: DWORD;</pre>
    </small></td>
    <td width="590" valign="top">First you must open a device. This fetches a device handle
    for the future use of GWIOPM_Driver's other driver functions. (Note that the device handle
    is different from the SCM handle).&nbsp; Later, you must close the device if you want to
    remove the driver. Note that closing the device or removing the driver does <em>not</em>
    remove the IOPM that you may have provided to the NT kernel (though presumably the kernel
    knows to forget about it after the application using it quits?)</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Test functions</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>IOCTL_IOPMD_READ_TEST
    (var RetVal: DWORD): DWORD;
IOCTL_IOPMD_READ_VERSION
    (var RetVal: DWORD): DWORD;</pre>
    </small></td>
    <td width="590" valign="top">Diagnostics to check that driver is installed and
    functioning. READ_TEST returns a RetVal of $123 while READ_VERSION returns a decimal
    number somewhere over 100 for version 1.x</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Manipulate driver's local IOPM (LIOPM)</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><small><pre>IOCTL_IOPMD_CLEAR_LIOPM: DWORD;
IOCTL_IOPMD_SET_LIOPM
  (Addr: Word; B: byte): DWORD;</pre>
    </small></td>
    <td width="590" valign="top">Clear the driver's preparatory map array, or set specific
    bytes to particular values. </td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>IOCTL_IOPMD_GET_LIOPMB
  (Addr: Word; var B: byte): DWORD;
IOCTL_IOPMD_GET_LIOPMA(var A: TIOPM): DWORD;</pre>
    </small></td>
    <td width="590" valign="top">Fetch either a particular byte, or the whole map from the
    driver. Note that this is the driver's map-in-preparation, not the one that the kernel is
    actually using.</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong><pre></strong><small>LIOPM_Set_Ports</small>
<small>  (BeginPort: word; EndPort: word; </small>
<small>   Enable: Boolean): DWORD;</small><strong></pre>
    </strong></td>
    <td width="590" valign="top">Enable/disable bits for specific ports. (Preferable to
    calling <small>IOCTL_IOPMD_SET_LIOPM</small> if you only need to set or change a few
    bits.)</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Interact with kernel IOPM (KIOPM)</strong></td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>IOCTL_IOPMD_ACTIVATE_KIOPM: DWORD;</small></pre>
    </td>
    <td width="590" valign="top">Give the driver's &quot;local&quot; (preparatory) map to the
    kernel and make it the active one for our process.</td>
  </tr>
  <tr>
    <td width="263" valign="top"><small><pre>IOCTL_IOPMD_DEACTIVATE_KIOPM: DWORD;</pre>
    </small></td>
    <td width="590" valign="top">Tell kernel to forget about our process-specific map.</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>IOCTL_IOPMD_QUERY_KIOPM: DWORD;</small></pre>
    </td>
    <td width="590" valign="top">Readback the kernel's map to the driver. (If you then use
    GET_LIOPMB your app can see the map the kernel is currently using.)</td>
  </tr>
  <tr>
    <td width="263" valign="top">&nbsp;</td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
  <tr>
    <td width="263" valign="top"><strong>Return values:</strong></td>
    <td width="590" valign="top">Functions generally return ERROR_SUCCESS or other error code
    that can be examined with the ErrorLookup function</td>
  </tr>
  <tr>
    <td width="263" valign="top"><pre><small>ErrorLookup(ErrorNum: DWORD): string;</small></pre>
    </td>
    <td width="590" valign="top">&nbsp;</td>
  </tr>
</table>

<h3>Kernel Functions</h3>

<p>The NT kernel functions that are used by the gwiopm driver are poorly documented, so
their exact function is a matter of some speculation. They were partly sleuthed by Dale
Roberts, and I have experimented with them a little more. So here's what I think they do:</p>

<table border="1" cellpadding="4" width="100%">
  <tr>
    <td width="322" valign="top"><strong>Kernel function</strong></td>
    <td width="448" valign="top"><strong>Description or speculation</strong></td>
  </tr>
  <tr>
    <td width="322" valign="top"><pre><small>void </small>
<small>Ke386IoSetAccessProcess(PEPROCESS, int);</small></pre>
    </td>
    <td width="448" valign="top">This provides the identity of the current process (ie: your
    application) to the kernel, and apparently lets the kernel know that we want to use a
    special I/O permissions map for this process (presumably the kernel needs to reserve us
    some space.)&nbsp; The int argument apparently enables (1) or disables (0) the special map
    (or blanket enables/disables I/O for this process, I'm not sure which.)</td>
  </tr>
  <tr>
    <td width="322" valign="top"><pre><small>void </small>
<small>Ke386SetIoAccessMap(int, IOPM *); </small></pre>
    </td>
    <td width="448" valign="top">This is the function that the driver uses to provide a new
    map (8K bytes) to the kernel.&nbsp; The int argument chooses between:<br>
    &quot;1&quot;:&nbsp; copy our map... or... <br>
    &quot;0&quot;: fill kernel's map with 0xFF&quot;<br>
    Note that a 1 bit <em>in the map</em> disables access to a particular port, so the int=0
    option effectively clears the kernel's map to all-disabled. </td>
  </tr>
  <tr>
    <td width="322" valign="top"><pre><small>void </small>
<small>Ke386QueryIoAccessMap(int, IOPM *);</small></pre>
    </td>
    <td width="448" valign="top">This function copies the kernel's map back to the driver's
    local map buffer.&nbsp; I have no idea what the int argument does, but when set to 1 it
    works. Perhaps set to 0 it clears the driver's map to 0xFF's.</td>
  </tr>
</table>

<p>In each case you can look at the gwiopm.c source to see how I used them.&nbsp; This
follows how Dale Roberts used them, with a little bit of extra experimentation on the
Query function.</p>

<h3>Further Adventures...</h3>

<p><strong>Client-specific IOPM: </strong>The gwiopm.sys driver was written with only a
single client application in mind.&nbsp; In fact the whole idea of bypassing NT's resource
arbitration/allocation philosophy and&nbsp; programming directly to the I/O ports
presupposes that only one application (or applications that are very friendly) will be
using the driver.&nbsp;&nbsp; However, it might make some sense to modestly redesign
gwiopm so that the local IOPM table is client-app specific, rather than global for all
clients of the driver. This could be done by defining a so-called &quot;device
extension&quot; to hold the client-by-client port-enable info. See the Art Baker reference
or the NT DDK samples.</p>

<hr>

<p><em>Go to:</em>&nbsp; <a href="http://www.wideman-one.com/"><img src="logo_small.gif" alt="wideman-one" border="0" align="top" WIDTH="164" HEIGHT="22"></a></p>
</body>
</html>

⌨️ 快捷键说明

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