阅读:2442回复:8
斑竹,高手,大虾们,都来看看阿~~~~~偶弄了几天了~~~~
小弟偶第一次做驱动,重启蓝屏无数次了,装系统也有N次了。要不是实在没办法(身边的参考资料几乎只从网上下,我们学校的图书馆放假了,书店也放假了),偶是不会随便来bbs哭的:)。
各位高手,你们先不要骂我,等调通了偶竖着耳朵让你们骂,OK?? 是这样的,偶在一个NDIS中间层驱动下面想要访问磁盘文件,这里就是想从磁盘文件里面读数据,该文件名是c:\\passthru.txt,里面的数据是一些字符,偶随便写了些,比如,gggggghhhhh。 我是这样来编码的: 在DriverEntry里面: ... MyDriverCreateFile(NULL,&m_ghFileHandle,m_gFileName); ... 这是个自定义函数,用于打开一个文件,参数m_ghFileHandle是个全局变量,m_gFileName是"\\\\??\\\\c:\\\\passthru.txt",这个函数返回的文件句柄是176,偶把它输出来看了的。 在PtReiceive里面:(这个函数工作在IRQL=DISPATCH_LEVEL) ... char readbuffer[50];//这个是用来存放读出数据的缓冲区 char * piChar; ... MyDriverReadFile(readbuffer,20,m_ghFileHandle);//自定义函数 //这个函数就是读取数据的函数,其中m_ghFileHandle的值,经察看是176, //readbuffer即用于存放数据的缓冲区,20表示读取20字节。 piChar=readbuffer; //指向缓冲区的头部 for(i=0;i<=19;i++) //用于输出缓冲区的数据,显示为乱码,不是文件中的数据gggggghhhhh. { DbgPrint("%c",*piChar);//输出到DbgView piChar++; } ... 下面是偶的自定义函数,主要是3个函数:一个用于打开文件,两个用于读取文件数据。 1.MyDriverCreateFile();//打开文件 这个函数用于打开文件,当然,也是在workitem里面打开了。其中对IRQL进行判断,若在IRQL=DISPATCH则用workitem来创建一个系统进程,再在workitem里面打开文件,这个函数返回值正确,就不列出细节,只给出最主要的ZwCreateFile部分。而且偶用它返回的文件句柄来写文件是正确的,就是说可以用这个文件句柄来写,就是读不出来,缓冲区始终为原来的值,不是读出的文件数据。 ... ntStatus=NT::ZwCreateFile( &FileHandle, SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); ... 2.MyDriverReadFile(); 这个是用来读文件数据的函数: VOID MyDriverReadFile( IN PVOID Buffer, //存放数据的缓冲区 IN ULONG Length, //读出的字节数 IN OUT HANDLE FileHandle) //文件句柄 { NTSTATUS ntStatus; NT::OBJECT_ATTRIBUTES ObjectAttributes;//NT是个namespace,里面包含了ntddk.h,ntdef.h,及自定义的struct_FILE_WORK_ITEM结构 NT::IO_STATUS_BLOCK IoStatusBlock; NT::UNICODE_STRING UniFileName; NT::PFILE_WORK_ITEM workitem; //FILE_WORK_ITEM结构是在NT这个namespace里面定义的 NT::LARGE_INTEGER ByteOffset; if(NT::KeGetCurrentIrql() < DISPATCH_LEVEL) //若IRQL==PASSIVE_LEVEL { ntStatus=NT::ZwReadFile(FileHandle, 0, 0, 0, &IoStatusBlock, Buffer, Length, NULL, NULL); if(NT_SUCCESS(ntStatus) && FileHandle != NULL) { } } else //经输出调试,发现IRQL不在 //PASSIVE_LEVEL,因此,执行的是这个分支 { ntStatus = STATUS_PENDING; workitem = (NT::PFILE_WORK_ITEM)NT::ExAllocatePool(NT::NonPagedPool,sizeof(NT::FILE_WORK_ITEM)); if (workitem) { ExInitializeWorkItem(&workitem->WorkItem, MyDriverReadFileWorkItem,//自定义的系统线程,用于读文件 workitem); workitem->FileContext = Buffer; workitem->FileHandle = FileHandle; workitem->Length = Length; NT::ExQueueWorkItem(&workitem->WorkItem,NT::DelayedWorkQueue); } else { ntStatus = STATUS_INSUFFICIENT_RESOURCES; } } return; } 3.MyDriverReadFileWorkItem(); 这个是自定义的读数据的系统进程函数,把其中的"Read"换成"Write"就是写文件的函数,而且经使用,写是可以正确写的(这时ZwCreateFile函数的参数要相应改为GENERIC_WRITE)。 VOID MyDriverReadFileWorkItem( PVOID Context) { HANDLE FileHandle; NTSTATUS ntStatus; NT::IO_STATUS_BLOCK IoStatusBlock; NT::LARGE_INTEGER ByteOffset; PVOID Buffer; ULONG Length; NT::PFILE_WORK_ITEM workitem = (NT::PFILE_WORK_ITEM) Context; FileHandle = workitem->FileHandle; Buffer = workitem->FileContext; Length = workitem->Length; ntStatus=NT::ZwReadFile(FileHandle, 0, 0, 0, &IoStatusBlock, Buffer, Length, NULL, NULL); if(NT_SUCCESS(ntStatus) && FileHandle != NULL) { } NT::ExFreePool(workitem); return; } 就是这3个函数了,打开文件,然后读文件数据到缓冲区。 再强调一下几个数据: 文件句柄:m_ghFileandle是个全局变量 缓冲区:char readbuffer[50]是在PtReceive里面定义的 用这个句柄和缓冲区是可以正确的写文件到数据的,已经实现过了,可就是不能正确的读文件数据。 偶第一次做驱动,重启蓝屏无数次了,装系统也有N次了。要不是实在没办法(身边的参考资料几乎只从 网上下,我们学校的图书馆放假了,书店也放假了),偶也不会来这哭了:)。 各位高手,就这些了,你们先不要骂我,等调通了偶竖着耳朵让你们骂,OK?? Thank you for all your help~~~! |
|
最新喜欢:![]() |
沙发#
发布于:2004-08-19 22:49
1. Are you sure you can write to the file correctly? Have you verified it?
2. From your description you said that your read operation happened at IRQL higher than PASSIVE_LEVEL. So you created a work item to delay the operation and you used the file handle as context. But the work item routine will be called in the context of a system thread. Your file handle is still effective in this system thread context? You know handle is thread context specific. Why not also open the file in the work item routine, then read the file? 3. Why you still used the ExInitializeWorkItem()? According to the DDK document it is obsolete. Why not using IoAllocateWorkItem(), then IoQueueWorkItem()? There is a drawback once you use ExQueueWorkItem(). Hope this can help you. |
|
板凳#
发布于:2004-08-19 23:12
恩
char readbuffer[50];是一个局部变量 恩你知道什么是局部变量么 知道局部变量的生存期间么 她只是在函数执行的时候存在..... 这是第一个问题 第二个问题是 你的读取文件的操作是异步执行的 并不能保证你在访问你的readbuffer的时候 读取文件已经完成了....... 以上..... |
|
地板#
发布于:2004-08-20 02:44
恩 同意第一个观点,但是他的代码中读文件操作应该是同步的, |
|
|
地下室#
发布于:2004-08-20 03:08
1. Are you sure you can write to the file correctly? Have you verified it? 我不太同意你的第二个观点,为什么说workitem会无效?都在系统地址空间,即便是进程切换,也不会失效的吧,除非workitem是在你的函数堆栈上创建的,不过楼主还是请你要检查一下这个参数是否有效 |
|
|
5楼#
发布于:2004-08-20 09:16
我感觉你内存释放的位置不对,
|
|
|
6楼#
发布于:2004-08-20 09:26
//这3行是不应该在ExInitializeWorkItem的上面?
workitem->FileContext = Buffer; workitem->FileHandle = FileHandle; workitem->Length = Length; |
|
|
7楼#
发布于:2004-08-20 09:59
非常感谢各位的帮助,问题太多,我先一个个改试试
|
|
8楼#
发布于:2004-08-21 17:30
终于调通啦,谢谢各位大虾,另开一贴子送分
|
|