How to Access I/O Ports in WindowsNT/2K/X
有点忙。。。还是贴篇旧文以免空白太多吧。
How to Access I/O Ports in WindowsNT/2K/XP
Mach, April 14, 2003
People can not use _inp() and _outp() in Windows NT Ring3 application. An exception will return from OS while these two functions were called in Ring3.
To access I/O ports on Windows NT and x86 platform (Alpha platform does not have I/O ports, forget that), some undocumented APIs will be utilized. They are:
// ke386... are functions in ntoskrnl.lib (ntoskrnl.exe)
// They are undocumented, thus list here
void Ke386SetIoAccessMap(int, IOPM *); // int: 1 Copy buffer, 0 fill with 0xff
void Ke386QueryIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int); // int: 1 enable I/O, 0 disable I/O
You can find these functions in ntoskrnl.exe with Dependency Walker (a utility in VC 6.0). To find the definition of these APIs, come to google or "Undocumented NT Secrets". I can give a short description here.
// IOPM is a 8192 bytes array, each bits represent one port,
// thus 8192*8 = 65536 = [All the I/O ports]
// If the bit is zero, the correspond I/O access is enabled
#define IOPM_SIZE 0x2000
typedef char IOPM[IOPM_SIZE];
IOPM *pIOPM = NULL;
In short, NT use a mask array of 8192 bytes to describe the 65535 I/O ports on x86 platform. Each bits of the array represent an I/O port. If the bit is 0, the correspond I/O access is enabled, otherwise the access is disabled. To enable I/O ports, we must set the privilege in Ring0, that is, of course, the usual way is writing a driver. Call the fowling sequence in driver:
pIOPM = MmAllocateNonCachedMemory(sizeof(IOPM));
if (pIOPM)
{
RtlZeroMemory(pIOPM, sizeof(IOPM));
Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); // 1 is enable
Ke386SetIoAccessMap(1, pIOPM);
}
The Ke386IoSetAccessProcess enabled I/O access of the current process, while Ke386SetIoAccessMap set the I/O access map to pIOPM.
To stop access to I/O ports:
if (pIOPM)
{
Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0);
Ke386SetIoAccessMap(1, pIOPM);
MmFreeNonCachedMemory(pIOPM, sizeof(IOPM));
pIOPM = NULL;
}
Yariv Kaplan has published WinIO source code on his website: www.internals.com
posted 2004.07.21 Wednesday
分类
Technology

发表评论