一个端口访问器的编写_第1页
一个端口访问器的编写_第2页
一个端口访问器的编写_第3页
一个端口访问器的编写_第4页
一个端口访问器的编写_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一个端口访问器的编写, Windows XP驱动程序举例,东南大学计算机科学与工程学院 杨全胜,VS.NET+WIN XP DDK+DriverStudio3.2开发环境版,本讲义假设阅读者已经熟悉VC+.NET和VS.NET(2002)的使用。如果对Window XP驱动程序的编写尚不熟悉,请参阅本人所编写的Windows XP驱动程序编写方法Step by Step电子讲义。,注意:程序中暗红色显示的部分是我们添加或修改过的语句,其他是DriverWorks自动生成的。蓝色显示的部分是要删除的语句。省略号的部分是不变的。语句中T.Trace(TraceInfo, _FUNCTION_“xx

2、xx”)这样的语句是向调试软件输出信息,该信息可在DriverMonitor或其他调试监视器中看到。,2次,由于一个可能是DriverStudio 3.2中的BUG,所以及时生成的一个空工程项目也无法编译通过,需要对生成的工程文件做以下手工修改: 把MyIOPort项目中的sources文件中的:TARGETLIBS=$ (DDK_LIB_PATH)ntstrsafe.lib $ (DDK_LIB_PATH)csq.lib 这一行去掉就可以编译通过了,protected: / Member data KIoRangem_ParPortIos;,在“MyIOPortDevice.h”文件的 cl

3、ass MyIOPortDevice : public KPnpDevice定义中添加下面的变量定义。,注意:程序中暗红色显示的部分是我们添加或修改过的语句,其他是DriverWorks自动生成的。蓝色显示的部分是要删除的语句。省略号的部分是不变的。语句中T.Trace(TraceInfo, _FUNCTION_“xxxx”)这样的语句是向调试软件输出信息,该信息可在DriverMonitor或其他调试监视器中看到。,修改下面函数代码:,NTSTATUS MyIOPortDevice:OnStartDevice(KIrp I) T.Trace(TraceInfo, _FUNCTION_+. I

4、RP %pn, I); NTSTATUS status = STATUS_SUCCESS; I.Information() = 0; / Get the list of raw resources from the IRP PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources(); / Get the list of translated resources from the IRP PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources(); / TODO: Add devi

5、ce-specific code to initialize/start your hardware device. / The base class will handle completion of the IRP status = m_ParPortIos.Initialize( 0 x00, / PC机I/O地址空间的首地址是00H TRUE, / 在CPU I/O空间内 8, / 设备读写数据的字节宽度 TRUE / 映射到系统空间 ); T.Trace(TraceInfo, _FUNCTION_-. IRP %p, STATUS %xn, I, status); return st

6、atus; ,NTSTATUS MyIOPortDevice:MYIOPORT_IOCTL_Read_Handler(KIrp I) T.Trace(TraceInfo, _FUNCTION_+. IRP %pn, I); NTSTATUS status = STATUS_SUCCESS; ULONG outputSize = I.IoctlOutputBufferSize(); char buff150,buff250; struct ioport int port; UCHAR data; *iopt; ULONG fwLength=0; iopt=(ioport *)I.IoctlBuf

7、fer(); / 指针直接指向IRP的BUFF区域这里进 /来的时候有用户程序的信息,出去的时候放返回信息 /显示从应用程序得到的要读的端口号。 T.Trace(TraceInfo, _FUNCTION_Read port is 0 x%dn, iopt-port );,下面的函数保留和添加下述语句,其他全部删除,/ 从端口读一个字节的数据 iopt-data= (UCHAR)m_ParPortIos.inb(iopt-port); fwLength = 8; if (outputSize = fwLength) / 如果读入缓冲够长 I.Information() = fwLength; /

8、 返回信息长度 T.Trace(TraceInfo, _FUNCTION_Read Data is 0 x%dn, iopt-data); / 显示从应用程序得到的命令串。 else I.Information() = 0;/ 否则信息长度为0 T.Trace(TraceInfo, _FUNCTION_buff size too smalln); T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, _FUNCTION_-. IRP %p, STATUS %xn, I, status); return status; ,NTSTATUS MyIO

9、PortDevice:MYIOPORT_IOCTL_Write_Handler(KIrp I) T.Trace(TraceInfo, _FUNCTION_+. IRP %pn, I); NTSTATUS status = STATUS_SUCCESS; char buff150,buff250; struct ioport int port; UCHAR data; *iopt; ULONG fwLength=0; iopt=(ioport *)I.IoctlBuffer(); / 指针直接指向IRP的BUFF区域这里进来的时候有用户程序的信息,出去的时候放返回信息 T.Trace(Trace

10、Info, _FUNCTION_Write port is 0 x%d, Write data is 0 x%dn, iopt-port , iopt-data ); / 显示从应用程序得到的命令串。 m_ParPortIos.outb(iopt-port,iopt-data); / 向端口写一个字节的数据 I.Information() = 0; T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, _FUNCTION_-. IRP %p, STATUS %xn, I, status); return status; ,下面我们来修改应用程序,

11、该程序访问硬件端口来获得CMOS中的数据以及让主板小喇叭发声。首先要修改一下应用程序项目的属性中的字符集。缺省的字符集是“使用 Unicode 字符集”,把它改成“未设置”。,右键点击,接下来我们修改资源文件。下图是系统自动生成的应用程序界面,这并不适合我们的需要。删除这些控件,换上下页显示的控件。,全部删除,Static Text,List Control,Button,在对话框中分别建立如图的三个按钮,一个列表控件(List Control)和一个静态文本框。其中,列表控件和按钮的属性如下页的图设置。,UCHAR ReadOneByte(int port); / 从port读一个字节 vo

12、id WriteOneByte(int port, UCHAR value); / 向端口port写一个字节 BOOL OpenMyDevice(); / 打开设备 void Silence( void ); / 静音 void Sound(DWORD freq ); / 发频率为freq的声音 void OnReadcmos(HWND hDlg); / 读CMOS,在“MyIOPortApp.h”文件中增加下列函数声明,在“MyIOPortApp.cpp”文件中增加下列函数:,UCHAR ReadOneByte(int port) charbuff200; ULONGnOutput; / C

13、ount written to bufOutput struct ioport int port; UCHAR data; iopt,iopt2; iopt.port=port; if (!DeviceIoControl(g_hDevice, MYIOPORT_IOCTL_Read, :MessageBox(NULL,buff,错误, MB_OK|MB_ICONSTOP); return 0; else return iopt2.data; ,void WriteOneByte(int port, UCHAR value) charbuff200; ULONGnOutput;struct io

14、port int port; UCHAR data; iopt,iopt2; iopt.port=port; iopt.data=value; if (!DeviceIoControl(g_hDevice, MYIOPORT_IOCTL_Write, :MessageBox(NULL,buff,错误, MB_OK|MB_ICONSTOP); return ; ,BOOL OpenMyDevice() DWORD lastError; HDEVINFO hDeviceInfo; DWORD bufferSize; SP_DEVICE_INTERFACE_DATA interfaceData; P

15、SP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail; / Find devices that have our interface hDeviceInfo = SetupDiGetClassDevs( (LPGUID),if (hDeviceInfo = INVALID_HANDLE_VALUE) lastError = GetLastError(); MyIOPortOutputText(_T(SetupDiGetClassDevs failed, GetLastError() = %d), lastError); return FALSE; / Set

16、up the interface data struct interfaceData.cbSize = sizeof(interfaceData); if(SetupDiEnumDeviceInterfaces(hDeviceInfo,NULL, (LPGUID) return FALSE; / Allocate a big enough buffer to get detail data deviceDetail= (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(bufferSize); if (deviceDetail = NULL) MyIOPortOu

17、tputText(_T(Error: Buffer allocation failed); return FALSE; / Setup the device interface struct deviceDetail-cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);,/ Try again to get the device interface detail info if (!SetupDiGetDeviceInterfaceDetail( hDeviceInfo, ,g_hDevice = CreateFile( (LPCTSTR)devi

18、ceDetail-DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,0); if (g_hDevice = INVALID_HANDLE_VALUE) MyIOPortOutputText(_T(Error: CreateFile failed for device %s (%d)n), deviceDetail-DevicePath, GetLastError(); return FALSE; MyIOP

19、ortOutputText(_T(Opened device %s), deviceDetail-DevicePath); return TRUE; MyIOPortOutputText(_T(No devices found); return FALSE; ,void Sound(DWORD freq ) UCHAR data; if(freq=20 ,void Silence( void ) UCHAR data; data = ReadOneByte(0 x61); WriteOneByte(0 x61, data ,void OnReadcmos(HWND hDlg) / TODO:

20、Add your control notification handler code here int i,it; char buff23; char cmosram128200= / CMOS每个字节的含义 目前系统时间的秒, 报警时间秒值, 目前系统时间的分, 报警时间分值, 目前系统时间的小时, 报警时间小时值, 目前星期几, 目前系统日期, 目前系统月份, 目前系统年的后两位,状态寄存器A, 状态寄存器B, 状态寄存器C, 状态寄存器D, 诊断状态记录值, 当机复位指示字节, 磁盘驱动器类型:xxxx. 软驱0类型 0001=360K 0010=1.2M .xxxx 软驱1类型 001

21、1=720K 0100=1.44M 0110=2.88M, (海洋板).x. 硬盘0Translate 1=Yes 0=No .x. 硬盘1Translate 1=Yes 0=No .x. 1=Step rate fast 0=Step rate slow .xx 软驱个数00=1个 01=2个 10=三个 11=四个 , 硬盘类型:xxxx. 硬盘驱动器0的类型 1111=使用19h单元 .xxxx 硬盘驱动器1的类型 1111=使用1Ah单元, 字节 x. 1=Anti-Virus 硬盘Boot区写保护 0=disable .xxx. 软驱2类型 .xxxx 软驱3类型,所安装设备的类型:

22、xx. 00=1个软驱,01=2个软驱,.xx. 00=单显 01=CGA 10=CGA 11=VGA/EGA,后四位高到低是显示、键盘、协处理器与软件机使能(=1), 基本内存容量低字节,单位KB, 基本内存容量高字节,单位KB, 扩充内存容量低字节,单位KB, 扩充内存容量高字节,单位KB, (海洋板)硬盘驱动器0的类型, (海洋板)硬盘驱动器1的类型, (海洋板)显示卡类型 VGA/monochrome, (海洋板).xxxx 启动顺序0=A:C: 1=C:A: 2=Screen prompt 3=Auto search 4=Network .x. 486-CPU Cache 0=dis

23、able 1= enable , (海洋板)x. 1=键盘使用缺省参数 0=使用本单元值 .xx. 键盘延时00=0.25秒01=0.5秒10=0.75秒11=1秒 .xxxxx 键盘重发速率,单位cps,(海洋板)硬盘1的柱面数, (海洋板)硬盘1的柱面数, (海洋板)硬盘1的磁头数, (海洋板)硬盘1的扇区数, (海洋板)硬盘0的柱面数, (海洋板)硬盘0的柱面数, (海洋板)硬盘0的磁头数, (海洋板)硬盘0的扇区数, (海洋板)AT-Bus clock 0=16.7Mhz 1=13.3Mhz 2=11.1Mhz 3=8.3Mhz 4=6.7Mhz 5=5.6Mhz 6=4.2Mhz,

24、(海洋板)memory type 00h=60nS 20h=70nS, 串口配置, 并口配置, 未使用, 未使用, 未使用, 未使用,标准CMOS校验和, 标准CMOS校验和, 扩充内存容量低字节,单位KB, 扩充内存容量低字节,单位KB, BCD码的世纪值(年的高2位,如19,20等), 信息标志, xxxx. Shadow of D000 0=Vacant .xxxx Shadow of C000 0=ROM , xxxx. Shadow of F000 0=ROM .xxxx Shadow of E000 0=Vacant , xxxx. Shadow of D000 1=WP 0=Re

25、ad/Write .xxxx Shadow of C000 1=WP 0=Read/Write , xxxx. Shadow of F000 1=WP 0=Read/Write .xxxx Shadow of E000 1=WP 0=Read/Write , 内存大小,单位兆, (内存大小有关=160/前一单元 ), 口令代码Security Code, 口令代码Security Code,xx. 口令检测方式 0=Disable 1=Setup only 2=Powerup LVITEM lvitem; HWND hWnd; hWnd = GetDlgItem(hDlg, IDC_CMOSL

26、IST); BOOL qu; UCHAR index,value,tmp; for(i=0;i128;i+) lvitem.mask = LVIF_TEXT|LVIF_STATE; lvitem.iItem = i; lvitem.iSubItem = 0; sprintf(buff,%02XH,i); lvitem.pszText = buff;,SendMessage(hWnd,LVM_INSERTITEM,0,(LPARAM) ,下面增加关键的消息处理:,LRESULT CALLBACK MyIOPortMainDlgProc( HWND hDlg, UINT uMsg, WPARAM

27、wParam, LPARAM lParam ) switch (uMsg) case WM_INITDIALOG: g_hDevice = INVALID_HANDLE_VALUE; / 初始化List Control hWnd = GetDlgItem(hDlg, IDC_CMOSLIST); RECT rect; GetWindowRect(hWnd,strcpy(lvm.pszText,偏移); lvm.cx = (rect.right - rect.left)/10; lvm.iSubItem = 0; lvm.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBI

28、TEM; lvm.fmt = LVCFMT_CENTER; SendMessage(hWnd,LVM_INSERTCOLUMN,0,(LPARAM),if(OpenMyDevice() EnableWindow(GetDlgItem(hDlg, IDC_READCMOS), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_SPEAKER), TRUE); else EnableWindow(GetDlgItem(hDlg, IDC_READCMOS), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SPEAKER), FALSE); / 此处还有DS自动生成的程序段,需全部删除 return 1; case WM_COMMA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论