chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1640回复:13

如何用驱动程序将一个文件读到内存里(30分送上)

楼主#
更多 发布于:2005-04-07 11:24

我自己的驱动是这样写的:

FileName 里是文件名及其所在的目录,比如\"\\\\SystemRoot\\\\abcd.txt\"
Buf = ExAllocatePool(NonPagedPool,64*1024)
ReadLen = 64*1024


int ReadFileToBuffer(char *FileName, char *Buf, int *ReadLen)
{
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
struct _UNICODE_STRING UnicodeString;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS ntStatus;
FILE_STANDARD_INFORMATION fi;
int Filelen;
WCHAR FileName1[256];
int i;

for(i=0;i<(int)strlen(FileName);i++)
   FileName1 = FileName;
FileName1 = 0;

RtlInitUnicodeString(&UnicodeString, FileName1);
 
InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL );

ntStatus = ZwCreateFile(&FileHandle,           // Handle GENERIC_READ|SYNCHRONIZE,//DiredAccess &ObjectAttributes,  //ObjectAttributes &IoStatusBlock, // IoStatusBlock 0, // AllocationSize FILE_ATTRIBUTE_NORMAL,// ileAttributes FILE_SHARE_READ,     // ShareAccess FILE_OPEN,      //CreateDisposition FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_ALERT,//CreateOptions NULL, // EaBuffer 0); // EaLength

ntStatus = ZwQueryInformationFile                                   (FileHandle, &IoStatusBlock,&fi,sizeof(fi),FileStandardInformation);
Filelen = (int)fi.EndOfFile.QuadPart;

ntStatus =  ZwReadFile(FileHandle,// FileHandle NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatusBlock, // IoStatusBlock Buf, // Buffer Filelen, // Length, NULL, // ByteOffset NULL); // Key
 
    if (!NT_SUCCESS(ntStatus))
{
ZwClose(FileHandle);
return 3;
}

ZwClose(FileHandle);
*ReadLen = Filelen;
return 0;
}

运行到ZwReadFile时,就出错
Error = A (IRQL_NOT_LESS_OR_EQUAL)
P1=XXXXXXX P2 = 2  P3 = 1 P4 = XXXXXXXX

看了两天了都不知道哪里错了,请大家指点指点,谢谢.

最新喜欢:

threebagsthreeb...
刚刚接触驱动开发,请多关照
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-04-07 11:27
程序看不清,重新贴一下程序

int ReadFileToBuffer(char *FileName, UINT8 *Buf, int *ReadLen)
{
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
struct _UNICODE_STRING UnicodeString;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS ntStatus;
FILE_STANDARD_INFORMATION fi;
int Filelen;
WCHAR FileName1[256];
int i;

for(i=0;i<(int)strlen(FileName);i++)
FileName1 = FileName;
FileName1 = 0;

PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Enter ReadFileToBuffer \'%s\', %d\",FileName, *ReadLen));

RtlInitUnicodeString(&UnicodeString, FileName1);
 
// PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Enter ReadFileToBuffer \'%s\', %d\",&UnicodeString.Buffer, *ReadLen));

InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL );

ntStatus = ZwCreateFile(&FileHandle, // Handle
GENERIC_READ|SYNCHRONIZE, // DesiredAccess
&ObjectAttributes, // ObjectAttributes
&IoStatusBlock, // IoStatusBlock
0, // AllocationSize
FILE_ATTRIBUTE_NORMAL, // FileAttributes
FILE_SHARE_READ, // ShareAccess
FILE_OPEN, // CreateDisposition
FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_ALERT, // CreateOptions
NULL, // EaBuffer
0); // EaLength
 
PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Open File : %s Handle %08x\",NtStatusToString(ntStatus),FileHandle));

    if (!NT_SUCCESS(ntStatus))
return 1;

PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"zwCreatFile Success\"));
PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Enter ReadFileToBuffer : zwQueryInformationFile\"));

ntStatus = ZwQueryInformationFile(FileHandle,&IoStatusBlock,&fi,sizeof(fi),FileStandardInformation);

PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"ReadFileToBuffer : zwQueryInformationFile Status : %s\",NtStatusToString(ntStatus)));

Filelen = (int)fi.EndOfFile.QuadPart;

if(Filelen > *ReadLen)
{
PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"ReadFileToBuffer : Buffer too small\"));
ZwClose(FileHandle);
return 2;
}

PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Enter ReadFileToBuffer : zwReadFile\"));

ntStatus =  ZwReadFile( FileHandle, // FileHandle
NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&IoStatusBlock, // IoStatusBlock
Buf, // Buffer
Filelen, // Length,
NULL, // ByteOffset
NULL); // Key
 
PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"ReadFileToBuffer : zwReadFile : Status : %s, Size : %d\",NtStatusToString(ntStatus), Filelen));

    if (!NT_SUCCESS(ntStatus))
{
ZwClose(FileHandle);
return 3;
}

ZwClose(FileHandle);
*ReadLen = Filelen;

PrintMsg(DEBUG_ALWAYS_DISPLAY, (\"Read File \'%s\' Success, Length : %d\", FileName, *ReadLen));

return 0;
}
刚刚接触驱动开发,请多关照
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-04-07 11:29
后半部分字怎么总是斜的
刚刚接触驱动开发,请多关照
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-04-07 14:41
文件名定义格式的不对,应为 L\"\\\\??\\\\C:\\\\windows\\\\file1.ext\"
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
Odyssey
驱动小牛
驱动小牛
  • 注册日期2004-12-15
  • 最后登录2008-03-29
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望115点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-04-07 14:49
ZwReadFile等等函数运行在IRQL=PASSIVE_LEVEL, 调用你的那个函数是在那个IRQL上?
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-04-07 14:54
文件名定义格式的不对,应为 L\"\\\\??\\\\C:\\\\windows\\\\file1.ext\"


我觉得可能格式是对的,要不然ZwCreatFile怎么能调用成功

回头我把文件名格式改改看看

谢谢
刚刚接触驱动开发,请多关照
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-04-07 15:00
ZwReadFile等等函数运行在IRQL=PASSIVE_LEVEL, 调用你的那个函数是在那个IRQL上?


我不知道,怎么看IRQL?
我是通过应用程序doWrite()传给驱动一个控制选择数字,比如:1 写一个寄存器,0: bootupchip,来作一些简单的工作.

在bootupchip里调用这个ReadFileToBuffer().
刚刚接触驱动开发,请多关照
Odyssey
驱动小牛
驱动小牛
  • 注册日期2004-12-15
  • 最后登录2008-03-29
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望115点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-04-07 15:22
那应该是在一个DispatchRoutine里面, 一般来说是在PASSIVE_LEVEL的。不过可以在调用你的函数之前加一个PAGED_CODE()宏来测试一下。

例如:
PAGED_CODE()
MYFunction();
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-04-07 16:08
那应该是在一个DispatchRoutine里面, 一般来说是在PASSIVE_LEVEL的。不过可以在调用你的函数之前加一个PAGED_CODE()宏来测试一下。

例如:
PAGED_CODE()
MYFunction();
 


我在程序里调用ReadFileToBuffer前加上PAGED_CODE()了

在softice里可以看到:
Pageable code called at IRQL 2
Assertion Failed : FALSE
Source File : F:\\.....\\ReadFileDevice.cpp  line xxx

是不是要把这些程序安排在DispatchRoutine里,就有可能解决这个问题了?现在我在类里声明,定义了bootupchip函数,ReadFileToBuffer定义在另一个文件include.cpp中,用文件包含的方式调用它.
刚刚接触驱动开发,请多关照
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-04-08 09:49
为啥没有给分的选项?
刚刚接触驱动开发,请多关照
Odyssey
驱动小牛
驱动小牛
  • 注册日期2004-12-15
  • 最后登录2008-03-29
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望115点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-04-08 23:32


我在程序里调用ReadFileToBuffer前加上PAGED_CODE()了

在softice里可以看到:
Pageable code called at IRQL 2
Assertion Failed : FALSE
Source File : F:\\.....\\ReadFileDevice.cpp  line xxx

是不是要把这些程序安排在DispatchRoutine里,就有可能解决这个问题了?现在我在类里声明,定义了bootupchip函数,ReadFileToBuffer定义在另一个文件include.cpp中,用文件包含的方式调用它.


这说明ReadFileToBuffer在irql>passive_level上调用了。可以将ReadFileToBuffer放到system worker thread里面去执行就可以了。
chinaxine
驱动牛犊
驱动牛犊
  • 注册日期2004-10-22
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-04-12 10:03
[quote]

我在程序里调用ReadFileToBuffer前加上PAGED_CODE()了

在softice里可以看到:
Pageable code called at IRQL 2
Assertion Failed : FALSE
Source File : F:\\.....\\ReadFileDevice.cpp  line xxx

是不是要把这些程序安排在DispatchRoutine里,就有可能解决这个问题了?现在我在类里声明,定义了bootupchip函数,ReadFileToBuffer定义在另一个文件include.cpp中,用文件包含的方式调用它.


这说明ReadFileToBuffer在irql>passive_level上调用了。可以将ReadFileToBuffer放到system worker thread里面去执行就可以了。 [/quote]

谢谢,经过你的指点,我又看了一下武安河的书(.我是用DS来开发驱动的),在武安河的书上也提到了要使用KFile类离不开系统线程KSystemThread.
我在驱动程序里添加了一个KSystemThread 类型的变量m_Thread.
使用MEMBER_THREAD(ReadFileDevice,ReadFiletoBuffer)将ReadFiletoBuffer()定义为ReadFileDevice类的一个成员函数.(这些都是参考武安河树上的例子),这里有个问题,使用MEMBER_THREAD()的时候ReadFiletoBuffer()是不是必须为VOID类型的,而且它的参数也必须为void类型的.因为我的ReadFiletoBuffer函数以前是int类型的,还带有3个参数,编译的时候老出错,后来改成VOID类型,把所有参数删除才通过.这是第一个问题.
做完上面那些步骤后,再在驱动中创建并启动系统线程
m_Thread.Start(LinkTo(ReadFiletoBuffer),this);然后在ReadFiletoBuffer()中声明一个KFile 类型的变量m_File.把以前用DDK函数的地方都改成m_File的成员函数.m_File.OpenCreat,m_File.Read.编译驱动,通过后,运行测试的应用程序会出现这样的错误:(在softice中显示为)
Bread due to Page Fault (oEh). Fault = 0000(也出现过0002)
还有这样的:
Error = 1E(KMODE_EXCEPTION_NOT_HANDLE) P1=XXXX,P2=XXXX,P3=XXXX,P4=XXXX
然后退出softice计算机就会重起.
刚刚接触驱动开发,请多关照
blueHacker
驱动牛犊
驱动牛犊
  • 注册日期2004-11-19
  • 最后登录2009-07-29
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-04-15 11:42
这个肯定是irql不对导致的
用一个system thread来做这件事情就可以了
system thread总是运行在passive level上的
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-04-16 10:09
这个肯定是irql不对导致的
用一个system thread来做这件事情就可以了
system thread总是运行在passive level上的
 
]
即创建一个WorkItem
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
游客

返回顶部