文件访问

Accessing Files

 

文件访问

 

It’s sometimes useful to be able to read and write regular disk files from inside a WDM driver. Perhaps you need to download a large amount of microcode to your hardware, or perhaps you need to create your own extensive log of information for some purpose. There’s a set of ZwXxx routines to help you do these things.

 

有时候从一个WDM驱动中可以读和写规范的磁盘文件是很重要的。可能你要为你的硬件下载大量的微码,或者可能你要为一些目的创建你自己的信息的扩展日志。那里有一个ZwXxx设置程序来帮助你完成这些事情。

 

File access via the ZwXxx routines require you be running at PAS­SIVE_LEVEL (see the next chapter) in a thread that can safely be suspended. In practice, the latter requirement means that you must not have disabled Asynchronous Procedure Calls (APCs) by calling KeEnterCriticalRegion. You’ll read in the next chapter that some synchronization primitives require you to raise the IRQL above PASSIVE_LEVEL or to disable APCs. Just bear in mind that those synchronization primitives and file access are incompatible.

 

文件访问通过ZwXxx程序请求你运行在一个可以安全挂起的进程中的PASSIVE_LEVEL(查看下一个章节)上。实际上,后面的请求意味着:你不用通过调用KeEnterCriticalRegion来使得异步程序调用(APCs)无效。在下一章中,你将读到:一些同步概念要求你提高IRQL高于PASSIVE_LEVEL或者使得APCs无效。只要记住:那些同步概念和文件访问不相容的。

 

The first step in accessing a disk file is to open a handle by calling ZwCreateFile. The full description of this function in the DDK is relatively complex because of all the ways in which it can be used. I’m going to show you two simple scenarios, however, that are useful if you just want to read or write a file whose name you already know.

 

访问一个磁盘文件的第一步是通过调用ZwCreateFile打开一个操作。在DDK中这个函数的完整描述是彼此相关的音位所有它可以使用的途径都在里面。我要给你展示连个实例脚本,但是,如果你只想读或写已知名称的文件的话,它将很有用。

 

Sample Code

 

实例代码

 

The FILEIO sample driver in the companion content illustrates calls to some of the ZwXxx functions discussed in this section. This particular sample is valuable because it provides workarounds for the platform incompatibilities mentioned at the end of this chapter.

 

在附录中的FILEIO实例驱动说明了调用在本节中讨论的ZwXxx的一些函数。这个细节实力是有价值的音位他为本章节为部分的不相容方法平台提供工作区。

 

Opening an Existing File for Reading

 

为读操作打开一个存在的文件

 

To open an existing file so that you can read it, follow this example:

 

要打开一个存在的文件以便你可以读它,按照下面的例子:

 

NTSTATUS status;

 

OBJECT_ATTRIBUTES oa;

 

IO_STATUS_BLOCK iostatus;

 

HANDLE hfile;              // the output from this process

 

PUNICODE_STRING pathname;  // you've been given this

 

 

 

InitializeObjectAttributes(&oa, pathname, 

 

  OBJ_CASE_INSENSITIVE │ OBJ_KERNEL_HANDLE, NULL, NULL);

 

status = ZwCreateFile(&hfile, GENERIC_READ, &oa, &iostatus,

 

  NULL, 0, FILE_SHARE_READ, FILE_OPEN,

 

  FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

 

Creating or Rewriting a File

 

创建或者重写一个文件

 

To create a new file, or to open and truncate to zero length an existing file, replace the call to ZwCreateFile in the preceding fragment with this one:

 

在之前的片断中,要创建一个新的文件,或者要打开并且截去0长度的存在的文件,重置ZwCreateFile的调用,使用这个:

 

status = ZwCreateFile(&hfile, GENERIC_WRITE, &oa, &iostatus,

 

  NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 

 

  FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

 

In these fragments, we set up an OBJECT_ATTRIBUTES structure whose main purpose is to point to the full pathname of the file we’re about to open. We specify the OBJ_CASE_INSENSITIVE attribute because the Win32 file system model doesn’t treat case as significant in a pathname. We specify OBJ_KERNEL_HANDLE for the same reason we did so in the registry example shown earlier in this chapter. Then we call ZwCreateFile to open the handle.

 

在这些片断中,我们设立一个OBJECT_ATTRIBUTES结构,其主要目的是指向我们要打开的文件的完整路径。我们指定OBJ_CASW_INSENSITIVE的属性,因为在一个路径名中,Win32文件系统模式不把这种情况视为有意义的。我们指定OBJ_KERNEL_HANDLE因为同样的原因我们在本章早先展示的注册表例子中也是这么做的。然后我们调用ZwCreateFile来打开这个操作。

 

The first argument to ZwCreateFile(&hfile) is the address of the HANDLE variable where ZwCreateFile will return the handle it creates. The second argument (GENERIC_READ or GENERIC_WRITE) specifies the access we need to the handle to perform either reading or writing. The third argument (&oa) is the address of the OBJECT_ATTRIBUTES structure containing the name of the file. The fourth argument points to an IO_STATUS_BLOCK that will receive a disposition code indicating how ZwCreateFile actually implemented the operation we asked it to perform. When we open a read-only handle to an existing file, we expect the Status field of this structure to end up equal to FILE_OPENED. When we open a write-only handle, we expect it to end up equal to FILE_OVERWRITTEN or FILE_CREATED, depending on whether the file did or didn’t already exist. The fifth argument (NULL) can be a pointer to a 64-bit integer that specifies the initial allocation size for the file. This argument matters only when you create or overwrite a file, and omitting it as I did here means that the file grows from zero length as you write data. The sixth argument (0 or FILE_ATTRIBUTE_NORMAL) specifies file attribute flags for any new file that you happen to create. The seventh argument (FILE_SHARE_READ or 0) specifies how the file can be shared by other threads. If you’re opening for input, you can probably tolerate having other threads read the file simultaneously. If you’re opening for sequential output, you probably don’t want other threads trying to access the file at all.

 

对于ZwCreateFile(&hfile)的第一个内容是:变量HANDLE的地址,ZwCreateFile将在那里返回它创建的操作。第二个内容(GENERIC_READ或者GENERIC_WRITE)指的是我们需要的操作执行的或者是读或者是些的访问。第三个内容(&oa)是包含有文件名称的OBJECT_ATTRIBUTES结构的地址。第四个内容指的是一个IO_STATUS_BLOCK,它将得到一个指示ZwCreateFile实际上是如何实现我们要它执行的操作的控制码。当我们对一个存在的文件打开只读操作的时候,我们期望这个结构的状态文件最终等于FILE_OPENED。当我们打开一个只读操作的时候,我们期望它最终等于FILE_OVERWRITTEN或者FILE_CREATED,取决于这个文件是存在还是不存在。第五个内容可以是一个指向64位整数的指针,它指示对于这个文件最初分配的大小。只有当你创建或者重写一个文件的时候,这个内容发生,并且如同我在这里完成的一样忽略它,说明这个文件在你书写数据的时候从0长度开始增长。第六个内容(0或者FILE_ATTRIBUTE_NORMAL)为任何你偶然创建的新文件指定文件属性。第七个内容(FILE_SHARE_READ或者0)指示文件如何通过其他线程共享。如果你正在输入,你应该可以容忍其他的线程同时读取这个文件。如果你正在连续的输入,你可能不相其他的线程尝试访问这个文件。

 

The eighth argument (FILE_OPEN or FILE_OVERWRITE_IF) indicates how to proceed if the file either already exists or doesn’t. In the read-only case, I specified FILE_OPEN because I expected to open an existing file and wanted a failure if the file didn’t exist. In the write-only case, I specified FILE_OVERWRITE_IF because I wanted to overwrite any existing file by the same name or create a brand-new file as necessary. The ninth argument (FILE_SYNCHRONOUS_IO_NONALERT) specifies additional flag bits to govern the open operation and the subsequent use of the handle. In this case, I indicated that I’m going to be doing synchronous I/O operations (wherein I expect the read or write function not to return until the I/O is complete). The tenth and eleventh arguments (NULL and 0) are, respectively, an optional pointer to a buffer for extended attributes and the length of that buffer.

 

第八个内容(FILE_OPEN或者FILE_OVERWRITE_IF)说明如果文件已经存在或者没有存在,如何进行。在只读的情况下,我指定FILE_OPEN因为我希望打开一个存在的文件,并且如果这个文件不存在(我)想要的到一个失败(信号)。在只写情况下,我指定FILE_OVERWRITE_IF因为我想要使用相同的名称重写存在的文件或者在必要的情况下创建一个崭新的文件。第九个内容(FILE_SYNCHRONOUS_IO_NONALERT)指定额外的标志位来管理开放操作和操作的子请求作用。在这种情况下,我希望:我们要完成同步I/O操作(在里面我希望读或者写函数直到I/O完成才返回)。第十和第十一个内容(NULL和0)分别是:对于扩展属性缓冲区的一个可选指针和缓冲区的长度。

 

You expect ZwCreateFile to return STATUS_SUCCESS and to set the handle variable. You can then carry out whatever read or write operations you please by calling ZwReadFile or ZwWriteFile, and then you close the handle by calling ZwClose:

 

你期望ZwCreateFile来返回STATUS_SUCCESS并且设置操作变量。然后你可以通过调用ZwReadFile或者ZwWriteFile来执行你想要的任何读或写操作,然后你通过调用ZwClose关闭这个操作。

 

ZwClose(hfile);

 

You can perform synchronous or asynchronous reads and writes, depending on the flags you specified to ZwCreateFile. In the simple scenarios I’ve outlined, you would do synchronous operations that don’t return until they’ve completed. For example:

 

你可以执行同步或者异步读和写,取决于你对ZwCreateFile指定的标志。在我描绘的想定的例子中,你要完成同步操作:直到它们完成才返回。比如:

 

PVOID buffer;

 

ULONG bufsize;

 

status = ZwReadFile(hfile, NULL, NULL, NULL, &iostatus, buffer,

 

  bufsize, NULL, NULL);

 

 

 

            -or-

 

status = ZwWriteFile(hfile, NULL, NULL, NULL, &iostatus, buffer,

 

  bufsize, NULL, NULL);

 

These calls are analogous to a nonoverlapped ReadFile or WriteFile call from user mode. When the function returns, you might be interested in iostatus.Information, which will hold the number of bytes transferred by the operation.

 

这些调用对于用户模式的不可交叠读文件或者写文件调用是类似的。当函数返回的时候,你可能关心iostatus。信息,它将通过这个操作保存转移的字节数量。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 【2】项目主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 【3】项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 【4】如果基础还行,或热爱钻研,可基于此项目进行二次开发,DIY其他不同功能,欢迎交流学习。 【注意】 项目下载解压后,项目名字和项目路径不要用中文,否则可能会出现解析不了的错误,建议解压重命名为英文名字后再运行!有问题私信沟通,祝顺利! 基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值