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

📄 index.htm

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

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>I/O Port Programming with Delphi and NT</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>Hardware I/O Port Programming with Delphi and NT</strong></big></big><br>
    <em><small><small>Article created: 98-06-01<br>
    Minor edits: 98-06-18</small></small></em></td>
  </tr>
</table>

<h3>Orientation</h3>

<p>Engineers and others interested in using their PCs to manipulate external hardware have
long been drawn to TurboPascal/Delphi, because of the combination of power, predictability
and speedy compilation that it offers while avoiding some of the complexity of C++.&nbsp;
You can afford to be a specialist at something other than the programming language.&nbsp;
This was great under DOS, and even under W3.1 and W95 with Delphi 1.&nbsp; But with Delphi
2 and 3, and Win NT, the direct hardware manipulation features are not so directly
accessible.</p>

<p>This article covers these general topics: 

<ul>
  <li><big><strong>This Page</strong></big><ul>
      <li>The port I/O instructions themselves</li>
      <li>Getting NT to give you permission to use them.&nbsp; A driver that does the job.</li>
      <li>Having your program install the driver transparently with minimum fuss.</li>
      <li>A Delphi unit to handle it all.</li>
      <li>Alternate Approaches</li>
      <li>Resources and References</li>
      <li>Copyright status</li>
    </ul>
  </li>
</ul>

<ul>
  <li><big><strong>Other Pages</strong></big><ul>
      <li>Documentation for<a href="gwiopm_code.htm"> gwiopm.sys driver and gwiopm.pas</a>
        interface unit for Delphi</li>
      <li>Documentation for <a href="PortTest.htm">PortTest</a> test program</li>
      <li>If you are reading this page off my web site, then download all source code, executables
        and these pages here: <a href="gwiopm.zip">gwiopm.zip</a> (if reading from CD or
        hard-drive, you already got this zip and expanded it, so the link is disabled.)</li>
    </ul>
  </li>
</ul>

<p>Version applicability: This article applies to (and the software has been tested with)
Windows NT 4 (SP3). It uses techniques that have applied certainly since 1996 (hence
should work with NT 3.5x).&nbsp; It has not been tried with NT 5. </p>

<h3>The Port I/O Instructions</h3>

<p>This is actually the easy part.&nbsp; In Turbo/Borland Pascal and Delphi 1 there are
Port arrays which you can read and write (like any other array). These are absent from
Delphi 2 and 3, presumably because of the additional wrinkles added by Win32 and NT
programming.&nbsp; No matter, we can easily add PortIn and PortOut functions/procedures to
call the CPU's I/O instructions.&nbsp; These are in unit <strong>gwportio.pas</strong>,
and are similar to other such functions floating around the web.&nbsp;&nbsp; (Onno
Kortmann authored a unit called <strong>simport.pas</strong> with a slightly cooler
object-based implementation that looks like the old Port arrays. I decided to go for
simplest implementation, so mine are just functions and procedures.)</p>

<h3>Getting Permission From NT</h3>

<p>Under NT, &quot;user-mode&quot; code (ie: applications written by mere mortals) is not
allowed to access hardware directly, hence when your application attempts to execute an
I/O instruction you get an exception.&nbsp; The idea is, of course, that hardware
resources are things that no application should just take over at will, instead it should
be up to the operating system (and its drivers) to arbitrate between different apps
requests to use those resources.</p>

<p>That's the theory.&nbsp; Turns out that the NT kernel maintains a map of I/O port
addresses that each process is allowed to access, and for your apps that's normally set to
&quot;none&quot;. But we can tell NT to use a different I/O Permissions Map (IOPM) for our
process and thereby gain access to the ports.&nbsp; This approach is of course very
naughty from a disciplined OS standpoint, so not recommended for widely distributed
commercial apps.&nbsp; But for those times when you just need to hack on some hardware,
who has time to write a proper NT device driver?</p>

<p>The only problem is that user-mode code is not allowed to execute the kernel functions
to change the permissions map. The workaround for that problem is to create an NT driver
(drivers have sufficient privileges) to twiddle the IOPM at the request of your app. Just
such a driver, <strong>giveio.sys</strong>, has been floating around the net since '96,
authored by Dale Roberts in conjunction with a May 96 Dr Dobbs article. </p>

<h3>Improved Driver and Delphi Interface Unit</h3>

<p>Giveio.sys demonstrates the concept and most importantly clues us in to the
undocumented kernel functions, but it throws open access to all I/O ports.&nbsp; So I
decided to take a crack at an improved driver that would allow giving access only to
selected ports, and would provide a few diagnostic functions in to the bargain. The result
is <strong>gwiopm.sys</strong> (source code included if you want to browse). &nbsp; A
Delphi interface to gwiopm.sys is provided in <strong>gwiopm.pas</strong>.</p>

<p>If you too want to have a go at device driver development, be forewarned that the only
known way to compile one is with the MS NT Device Driver Development Kit (NT DDK), which
in turn needs the Win32 SDK, and relies on some pretty specific feature of the MS C
environment (Visual Studio). (Oh, and supposedly you can't compile on a W95 machine
either...) &nbsp;&nbsp;&nbsp; This leads to the somewhat incongruous necessity to install
about about 500 Meg of cra... er, I mean, &quot;supporting code&quot; in order to compile
a couple of hundred lines of source code into a 4K executable.&nbsp; Recommended: Art
Baker's &quot;The Windows NT Device Driver Book&quot; (Prentice Hall '97) helps to smooth
out the bumps.</p>

<h3>Installing a Driver Without Hassle for Users</h3>

<p>So now we have a driver that can give our application permission to use I/O
instructions. To install this driver you could create an installation program, or you
could manually edit the registry to have NT load up the driver on boot up.&nbsp; But
though you're not <em>really</em> going to distribute your hardware hack, there are just a
<em>couple</em> of other people who'll need to install it, right? And making them hassle
with installing a driver is tedious.</p>

<p>For this reason, <strong>gwiopm.pas</strong> includes functions that your Delphi app
can call to transparently install the gwiopm driver on the fly, start it up and then later
stop and uninstall it after you are done. (I first learned about the functions to do this
from example loaddrv.c code written by Paula Tomlinson, associated with a Windows Dev
Journal article.) </p>

<h3>Alternative Approaches</h3>

<p><strong>I/O Port Driver:</strong>&nbsp; The port I/O approach shown here takes the
point of view that if you're wanting to manipulate ports directly, you probably want as
few extraneous mechanisms involved as possible.&nbsp;And if you have dedicated hardware
attached to your PC, in many instances you probably have a single piece of dedicated
software to control it.&nbsp; So there's no need to worry about arbitration. For these
reasons, the approach described in this article provides actual cpu I/O instructions right
in your Delphi/assembler code.&nbsp;</p>

<p>However, in other situations you may genuinely need a more civilized approach: even
though you are manipulating the hardware in a custom manner, you might still like your
port usage to be arbitrated by a &quot;good citizen&quot; driver.&nbsp; An example of this
scenario would be where you are twiddling some peripheral that's attached to a PC parallel
printer&nbsp; port... but you don't want to clobber NT's use of that same port.</p>

<p>This, of course, requires a more sophisticated driver that request and gains control of
the port in the polite and proper manner, and intermediates your app's
&quot;requests&quot; for I/O, translating them into actual I/O actions. Such an approach
is taken by Victor I. Ishikeev in his TVicPort driver and accompanying examples for Win95
and NT.&nbsp;Find it at the main Delphi freeware/shareware sites (look for recent versions
as early ones didn't cover NT.)&nbsp;&nbsp;&nbsp; Or one could look at the samples in the
NT DDK if you are considering writing your own.</p>

<p><strong>Writing Drivers in Delphi:</strong>&nbsp; On the surface, it would appear that
you can't use Delphi to write drivers. (The advance word on D4 indicates some features for
writing services... it remains to be seen whether this includes device drivers, and in any
case this is a feature of the expensive version.)&nbsp; The primary reason is that Delphi
lacks the compile/link functions to produce a .sys file, not to mention missing the
Delphi-ized DDK header files. &nbsp; </p>

<p>However, you <em>can</em> get generic &quot;adapter&quot; drivers which will callback
your Delphi code.&nbsp; There is some overhead involved, but for some situations it could
be just the ticket. Other related products offer &quot;Wizard&quot;-style driver
development, which again avoids the necessity to understand device drivers in depth (one
hopes)&nbsp; See: 

<ul>
  <li><a href="http://www.bluewatersystems.com/frames/index.html">BlueWater System (WinRT)</a></li>
  <li><a href="http://www.tetradyne.com/">Tetradyne (DriverX)</a></li>
  <li><a href="http://www.vireo.com/">Vireo (Driver::Agent)</a></li>
</ul>

<h3>Resources</h3>

<p>Start at <a href="http://www.albany.net/~danorton/">Cherry Hill</a>: </p>

<h4>Copyright Status</h4>

<p><em>Please feel free to distribute or publish this article and associated code,
provided some note of credit for me remains attached. Permission is also granted to
include this article on CDROM collections, again provided credit remains attached. Thanks!</em></p>

<hr>

<p><em>Go to:&nbsp;</em> <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 + -