阅读:4208回复:20
2000 下 读取端口信息 错误原因
昨天因为修改了两个函数成功build了一个sys而激动不已,
可在编写验证app时却读不出数据,读出的还是app中的初始值。 万分疑惑,再次向各位求助: driver原代码是我在csdn上看到的,“http://www.csdn.net/develop/author/netauthor/bhw98/ ” 写的非常不错。 重要代码如下 : ///////////////////////////////////////////////////////////////////////////// PULONG pvIOBuffer; pvIOBuffer = Irp->AssociatedIrp.SystemBuffer; switch (dwIoControlCode) { case IOCTL_MYPORT_READ_DWORD: ----> pvIOBuffer[1] = READ_PORT_ULONG(&pvIOBuffer[0]); Irp->IoStatus.Information = 32; break; case IOCTL_MYPORT_WRITE_DWORD: ----> WRITE_PORT_ULONG(&pvIOBuffer[0], pvIOBuffer[1]); break; default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } /////////////////////////////////////////////////////////////////////////////// ----> 处是我将 _inp() 和_outp() 换成 READ_PORT_ULONG()和 WRITE_PORT_ULONG() 后的部分。 原本我也想定义一个结构的 typedef struct _IOBUFFER { PULONG Port; <----此处的端口长度 可为UCHAR,USHORT,ULONG 什么时候用多长,我一直没弄明白。 ULONG Value; }IOBUFFER,pIOBUFFER; 可此时参数总会出错,所以没有定义了。 在app中read和write的代码应该没有问题,所以我觉得问题出在driver上了,应该是定义 PULONG pvIOBuffer; 这个指针和做为参数使用时的问题。但....... 就是解决不了555555 app 的访问代码 : DWORD ReadPortDWORD(DWORD port) { DWORD buf[2]; DWORD dwOutBytes; buf[0] = port; buf[1] = 0x111; ::DeviceIoControl(hMyPort, IOCTL_MYPORT_READ_DWORD, &buf[0], sizeof(DWORD), &buf[1], sizeof(DWORD), &dwOutBytes, (LPOVERLAPPED)NULL); return (DWORD)buf[1]; } void WritePortDWORD(DWORD port, DWORD data) { DWORD buf[2]; DWORD dwOutBytes; buf[0] = port; buf[1] = data; ::DeviceIoControl(hMyPort, IOCTL_MYPORT_WRITE_DWORD, &buf[0], 2*sizeof(DWORD), NULL, 0, &dwOutBytes, (LPOVERLAPPED)NULL); } 返回的值总是初始定义的buf[1],没有从driver里传回数据,不知哪位能给点指点! ////////////////////////////////////////////////////////////////////// 其实我仅想看到下面的功能而已,不知哪位大哥知道我想要干什么的给我点建议啊, 我太想解决这个问题了! CString str; DWORD io_cf8; DWORD io_cfc; io_cfc=0; io_cf8=0x80000000; WritePortDWORD(0x00000cf8, io_cf8); io_cfc = ReadPortDWORD(0xcfc); str.Format(\"0x%x\",io_cfc); SetDlgItemText(IDC_EDIT2,str); [编辑 - 3/20/05 by llllllllg] |
|
|
沙发#
发布于:2005-03-21 23:05
case IOCTL_MYPORT_READ_DWORD:
----> pvIOBuffer[1] = READ_PORT_ULONG(&pvIOBuffer[0]); Irp->IoStatus.Information = 32; break; 修改为 case IOCTL_MYPORT_READ_DWORD: ----> pvIOBuffer[0] = READ_PORT_ULONG(&pvIOBuffer[0]); Irp->IoStatus.Information = 4; break; |
|
|
板凳#
发布于:2005-03-22 09:47
UCHAR(字节),USHORT(16位短整数),ULONG(32位长整数)为一次写入端口的数据尺寸,inp和outp一般为字节,如果要改inp和outp,用UCHAR
|
|
|
地板#
发布于:2005-03-22 15:09
UCHAR(字节),USHORT(16位短整数),ULONG(32位长整数)为一次写入端口的数据尺寸,inp和outp一般为字节,如果要改inp和outp,用UCHAR 恩,我有个问题就是 我如何确认 要写入端口的数据长度呢, 也就是我如何确认端口中的数据的长度,不是32位的吗 ? 难道 有的端口数据长度 8 , 有的 16 ,有的 32 是这样吗 ? |
|
|
地下室#
发布于:2005-03-22 20:18
当然,你也写8位、16位和32位,需要使用不同函数(READ_PORT_ULONG、READ_PORT_UCHAR、READ_PORT_USHORT等) |
|
|
5楼#
发布于:2005-03-22 20:41
case IOCTL_MYPORT_READ_DWORD: 哈哈,我按照你的方法修改了, 不好意思,不行耶!!! 此时返回的值确实不是初始值了, 变成了app中调用read函数值的 port 值啊 ? ReadPortDWORD(0xcfc); 为 0xcfc !!! [编辑 - 3/22/05 by llllllllg] |
|
|
6楼#
发布于:2005-03-22 20:47
[quote] 当然,你也写8位、16位和32位,需要使用不同函数(READ_PORT_ULONG、READ_PORT_UCHAR、READ_PORT_USHORT等) [/quote] 我现在在想,如果端口数据为 32 位的, 但我用 READ_PORT_UCHAR 来读,也可以读出数据吗? 那剩下的 24 位怎么办呢 ? 剩下的端口号要怎样确定 呢 ? 难道要用到所谓的 移位操作吗 ? |
|
|
7楼#
发布于:2005-03-23 08:40
[quote][quote] 当然,你也写8位、16位和32位,需要使用不同函数(READ_PORT_ULONG、READ_PORT_UCHAR、READ_PORT_USHORT等) [/quote] 我现在在想,如果端口数据为 32 位的, 但我用 READ_PORT_UCHAR 来读,也可以读出数据吗? 那剩下的 24 位怎么办呢 ? 剩下的端口号要怎样确定 呢 ? 难道要用到所谓的 移位操作吗 ? [/quote] 32位必须按32位读,不能用READ_PORT_UCHAR 来读,这对应于外部设备上数据寄存器的长度 |
|
|
8楼#
发布于:2005-03-23 10:01
很好, 我决定给分你了 bmyyyud,终于解决了我一个困扰我很久的问题!!!
不晓得你对于我读 0xcfc 有什么看法,我还是读不出来, 今天调试了一下,根本就不是驱动的问题, 发现原来就没有打开驱动,无法动态启动服务! BOOL StartDriver(LPCTSTR lpszDriverPath, LPCTSTR lpszServiceName) { SC_HANDLE hSCManager; SC_HANDLE hService; BOOL bResult = FALSE; hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); if(hSCManager) { hService = CreateService(hSCManager, lpszServiceName, lpszServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpszDriverPath, NULL, NULL, NULL, NULL, NULL); if(hService == NULL) { if(::GetLastError() == ERROR_SERVICE_EXISTS) { hService = ::OpenServic (hSCManager, lpszServiceName, SERVICE_ALL_ACCESS); } } if(hService) { bResult = StartService(hService, 0, NULL); //此处的bresult返回为0 !! CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); } return bResult; } 怎么就打不开服务呢 ?我什么都没改啊 ,是不是要设置什么 ? |
|
|
9楼#
发布于:2005-03-23 11:31
将这个
hService = ::OpenServic (hSCManager, lpszServiceName, SERVICE_ALL_ACCESS); 改成 hService = ::OpenService (hSCManager, lpszServiceName, SERVICE_START); 如果不行在 bResult = StartService(hService, 0, NULL); //此处的bresult返回为0 !! 后用GetLastError看看什么错误 |
|
|
10楼#
发布于:2005-03-23 13:27
:)呵呵,不好意思啊,我在打开错误后,重启了一下计算机,
就可以打开了 。所以,我将 Irp->IoStatus.Information = 4; 分别变为 8,16,32,64 试了一下,重起了二十几次计算机 :D 发现 还是 在 8 的时候可以收到数据 , 但为 0xffffffff 我这样写了一段,什么都没收到:( :( :( void CReadPortDlg::OnButton2() { CString str; DWORD io_CF8; DWORD io_CFC; io_CFC=0; io_CF8=0x80000000; for(;;) { WritePortDWORD(0xcf8, io_CF8); io_CFC = ReadPortDWORD(0xcfc); if (io_CFC!=0xffffffff) { str.Format(\"0x%x\",io_CFC); SetDlgItemText(IDC_EDIT2,str); } io_CF8+=0x800; if (io_CF8>=0x80FFFF00) break; } } |
|
|
11楼#
发布于:2005-03-23 15:06
:)呵呵,不好意思啊,我在打开错误后,重启了一下计算机, 其实 case IOCTL_MYPORT_READ_DWORD: ----> pvIOBuffer[1] = READ_PORT_ULONG(&pvIOBuffer[0]); Irp->IoStatus.Information = 32; break; case IOCTL_MYPORT_WRITE_DWORD: ----> WRITE_PORT_ULONG(&pvIOBuffer[0], pvIOBuffer[1]); break; default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 中Irp->IoStatus.Information设置为多少并无多大关系,它一般用来指示这次读了多少个字节 关键是加 pIrp->IoStatus.Status = STATUS_SUCCESS; 在 Irp->IoStatus.Information = 32; 前面,表明这次IRP是成功的 |
|
|
12楼#
发布于:2005-03-23 21:14
有些时候我觉得我过的非常艰难,在我们办公室又没有人能够帮到我 什么东西都的靠自己,即使是非常非常简单的东西, 也会困饶我很久,感觉有点孤独! 我按你的方式改过了,确实可以读出一些端口的信息, 大部分的都是 0xffffffff。 但我读 0xcfc的仍然不成功,我实在是受不了了,把我的代码 全贴上来算了,让大家看看! |
|
|
13楼#
发布于:2005-03-26 17:32
对于 这个结构
#define IOPM_SIZE 0x2000 typedef UCHAR IOPM[IOPM_SIZE]; 对于读的端口有什么影响啊,在2000下,这个值是什么意思? 2000 下,端口的寄存器长度为32位的,读 cfc 这个值定为 8192 是否合理啊 ? 不知哪里有类似的可以运行的代码,这个可是非常经典的了。 |
|
|
14楼#
发布于:2005-03-27 14:39
对于 这个结构 你首先确定cfc端口对应什么设备,否则是乱读,结果就不好说了 我看了你的代码,IOPM为Ring3下的IO屏蔽位图,这个在win9x下用的很广泛,用于决定在ring 3下那些端口可以访问,在nt 2k xp中你用的这种方法失灵了,因为无法进入Ring0,进入ring0,最好写驱动,然后用DeviceIoControl来通讯读写端口。直到看了你的全部代码,我才发现。可见上下文是多么关键呀! |
|
|
15楼#
发布于:2005-03-28 19:29
hi , 其实我想读出pci configspace,和 一些 这样的信息 :
================================ Vendor ID: 168C Device ID: 0013 SubSystem ID: 1051168C Reversion : 01 Description: Atheros AR5002 Anwi Diagnostic Kernel Driver Driver Provider: Atheros ================================ Vendor ID: 168C Device ID: 0013 SubSystem ID: 1130168C Reversion : 01 Description: Atheros AR5002 Anwi Diagnostic Kernel Driver Driver Provider: Atheros ================================ Vendor ID: 168C Device ID: 0013 SubSystem ID: 1131168C Reversion : 01 Description: Atheros AR5002 Anwi Diagnostic Kernel Driver Driver Provider: Atheros ================================ Vendor ID: 168C Device ID: 0013 SubSystem ID: 3A131186 Reversion : 01 Description: D-Link AirPlus DWL-G520 Wireless PCI Adapter(rev.B) Driver Ver: 3.0.0.44 Driver Date: 10-22-2003 Driver Provider: D-Link 像这样的,我知要用驱动读 pci 配置空间, 这这这 太难了对我来说555555555555555555555555555555555555 不晓得你是做什么的啊 , 我是做产品测试的,在东莞! |
|
|
16楼#
发布于:2005-03-28 22:45
既然你的问题已经解决了,我来说点感想吧。
1、我也是初学驱动程序不久,你的问题我并不能全部回答,所以看了整个解决过程感到对自己挺有帮助的,对认真提问和认真回答的两位网友表示感谢。但是糊里糊涂看到最后你才写清楚这是一个关于PCI接口的驱动程序(狂汗~~~),不知道程序里是不是有什么代码是PCI驱动专用语句或者是驱动通用语句,让人一看就明白这是一个针对PCI接口的驱动程序?如果不是这样,真是要很佩服为你一步步解疑的高手了,简直熟练到通吃各种接口驱动的地步(敬仰如黄河之水啊……) 2、想顺带问个小问题。我入手PCI驱动是从调试别人已经完成大部分的程序开始,因为一直有编写用户端通信程序的人员配合,可以直接看到PCI接口的通信效果,所以不知道原来还可以编写app测试程序独立测试驱动程序的通信情况。如果不是难以回答的话,能不能简约告诉我app程序用什么工具编写,在什么环境下运行,能观察到PCI接口芯片的那些信号之类的情况,或者推荐一些app的资料书籍给我借鉴?我会非常感激。 |
|
17楼#
发布于:2005-03-30 10:46
既然你的问题已经解决了,我来说点感想吧。 其实我连初学者都不算,只能算是个业余初学者,只是出于爱好。我这么问问题是因为对pci规范 了解一点就知道 cf8和cfc端口的意思,他们一看就知道我想干什么,也只有他们才可以解决我的 问题了。 我之所以写app 来验证驱动,难为情,是因为我不会调试驱动。 你会调试驱动,不会连app用什么工具都不知道吧,我用的是2000的简体系统,vc6.0和c++builder。 多多交流!! ------------------------------------------------------- 我现在用winio.sys 作为驱动,向端口cf8写双字,从端口cfc读,读出了一些数据。 627081350 627212422 616726662 609124486 616595590 74781056 822481158 1250956 2168000748ao 然而,我要读出的项是 DriverDesc , Driver Ver ,Driver Provider和Description: 之类的信息,可我又不知道该怎么办了, 我知道要看pci规范,可我这里又没有资料, 小弟不才, 所以希望各位大哥多多指教啊 我从 pciconfigaddress 如何得到 driverdesc 的地址呢 ? 是 pciconfigaddress 的后面 256 个字节吗 ? 还是要重新得到 呢 ?还有就是从 pciconfigaddress 可以得到eeprom的地址吗 ? [编辑 - 3/31/05 by llllllllg] |
|
|
18楼#
发布于:2005-03-31 11:59
读I/0端口有现成的工具软件的。
我没看你的代码。。 2000下我读过不少端口。。 BIOS的大部分。并口,都没问题。 或者你直接用SOFTICE 有命令可以直接读的。 |
|
19楼#
发布于:2005-03-31 19:50
为什么我的 softice 不能用啊 ,是不是要注册 ?
|
|
|
上一页
下一页