实战DeviceIoControl 之六:访问物理端口[1]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 bhw98 的 blog

q 在nt/2000/xp中,如何读取cmos数据?

q 在nt/2000/xp中,如何控制speaker发声?

q 在nt/2000/xp中,如何直接访问物理端口?

a 看似小小问题,难倒多少好汉!

nt/2000/xp从安全性、可靠性、稳定性上考虑,应用程序和操作系统是分开的,操作系统代码运行在核心态,有权访问系统数据和硬件,能执行特权指令;应用程序运行在用户态,能够使用的接口和访问系统数据的权限都受到严格限制。当用户程序调用系统服务时,处理器捕获该调用,然后把调用的线程切换到核心态。当系统服务完成后,操作系统将线程描述表切换回用户态,调用者继续运行。

想在用户态应用程序中实现i/o读写,直接存取硬件,可以通过编写驱动程序,实现createfile、closehandle、 deviceiocontrol、readfile、writefile等功能。从windows 2000开始,引入wdm核心态驱动程序的概念。

下面是本人写的一个非常简单的驱动程序,可实现字节型端口i/o。

#include <ntddk.h>
#include "myport.h"
  
// 设备类型定义
// 0-32767被microsoft占用,用户自定义可用32768-65535
#define file_device_myport    0x0000f000
  
// i/o控制码定义
// 0-2047被microsoft占用,用户自定义可用2048-4095 
#define myport_ioctl_base 0xf00
  
#define ioctl_myport_read_byte   ctl_code(file_device_myport, myport_ioctl_base, method_buffered, file_any_access)
#define ioctl_myport_write_byte  ctl_code(file_device_myport, myport_ioctl_base+1, method_buffered, file_any_access)
  
// iopm是65536个端口的位屏蔽矩阵,包含8192字节(8192 x 8 = 65536)
// 0 bit: 允许应用程序访问对应端口
// 1 bit: 禁止应用程序访问对应端口
  
#define iopm_size    8192
  
typedef uchar iopm[iopm_size];
  
iopm *piopm = null;
  
// 设备名(要求以unicode表示)
const wchar namebuffer[] = l"\\device\\myport";
const wchar dosnamebuffer[] = l"\\dosdevices\\myport";
  
// 这是两个在ntoskrnl.exe中的未见文档的服务例程
// 没有现成的已经说明它们原型的头文件,我们自己声明
void ke386setioaccessmap(int, iopm *);
void ke386iosetaccessprocess(peprocess, int);
  
// 函数原型预先说明
ntstatus myportdispatch(in pdevice_object deviceobject, in pirp irp);
void myportunload(in pdriver_object driverobject);
  
// 驱动程序入口,由系统自动调用,就像win32应用程序的winmain
ntstatus driverentry(in pdriver_object driverobject, in punicode_string

本文关键:DeviceIoControl,物理端口,设备驱动程序,IOPM,CMOS,speaker
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top