Windows驱动开发技术详解 第六章的(Windows内核函数)自我理解
- 格式:pdf
- 大小:115.11 KB
- 文档页数:9
深入研究计算机操作系统内核Windows内核原理解析计算机操作系统是指支持计算机软硬件运行的基本软件系统,其中内核是操作系统的核心部分。
作为广泛应用的操作系统之一,Windows 内核在计算机领域中具有重要地位。
本文将深入研究Windows内核的原理解析,以帮助读者更好地理解计算机操作系统内核的工作原理。
一、Windows操作系统的发展历程Windows操作系统的发展经历了多个版本和起伏。
自20世纪80年代中期开始推出的Windows 1.0版本以图形用户界面为特点,为个人计算机用户带来了更加友好的操作界面。
随着版本的不断升级,Windows 操作系统逐渐成熟,并在个人计算机市场上占据主导地位。
二、Windows内核的概述Windows内核是Windows操作系统的核心组成部分,负责管理计算机硬件资源和提供系统服务。
Windows内核采用了微内核的设计思想,将核心的功能模块化,以实现更高的灵活性和可扩展性。
Windows内核包括以下几个主要组件:1. 进程管理:负责管理计算机上的进程,调度和分配资源,实现进程的并发执行。
2. 内存管理:负责管理计算机内存的分配和回收,以及虚拟内存的管理,提供内存保护机制。
3. 文件系统:负责管理磁盘上的文件和目录,提供文件读写和文件共享的功能。
4. 设备驱动程序:提供与硬件设备的通信接口,实现对硬件设备的操作和控制。
5. 网络通信:提供网络通信功能,实现计算机之间的数据传输和通信。
三、Windows内核的工作原理分析1. 进程管理Windows内核通过进程管理来实现系统的多任务处理。
每个进程都有自己的地址空间和调度优先级。
内核根据调度算法来选择需要执行的进程,并为其分配CPU时间片。
当一个进程处于等待状态时,内核将其挂起,切换到其他可执行的进程,保证系统的整体性能。
2. 内存管理Windows内核通过内存管理来管理计算机的物理内存和虚拟内存。
物理内存管理负责将物理内存划分成多个页框,提供页面分配和回收的功能。
《Windows驱动开发技术详解》之Windows内核函数内核模式下字符串操作ANSI_STRING和UNICODE_STRING分别定义如下:以UnicodeString类型对象进⾏初始化为例,代码如下:输出:进⾏复制字符串操作,代码如下:输出:但是如果这⾥改为:加载驱动运⾏就会蓝屏。
Why?其实,RltFreeUnicodeString是⽤来释放利⽤申请的堆空间初始化的UnicodeString类型对象的,⽽RtlInitUnicodeString对UniStr1进⾏初始化时,只是让Buffer指向了⼀个常量区。
进⾏ANSI_STRING字符串与UNICODE_STRING字符串相互转换操作,代码如下:注意这⾥要利⽤RtlFreeUnicodeString释放通过RtlAnsiStringToUnicodeString得到的UniStr2。
为什么这个需要释放?我们利⽤Windbg跟踪下代码。
⾸先,跟踪时要逐⼀,这⾥的勾如果不去掉,就是在源码下单步跟踪,⽽不是在汇编指令⾥单步跟踪:在RtlUnicodeStringToAnsiString函数中,有这么⼀个系统API此时的参数是正好是传⼊的字节数的⼤⼩。
⽽这个API最终调⽤了:所以,我们要利⽤RtlFreeUnicodeString进⾏释放。
内核模式下的⽂件操作:创建⽂件:代码⼊下:1 VOID FILEOPERATION(){2 OBJECT_ATTRIBUTES ObjAttributes;3 IO_STATUS_BLOCK iostatus;4 HANDLE hfile;5 UNICODE_STRING logFileUnicodeString;67 RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");8 InitializeObjectAttributes(&ObjAttributes,9 &logFileUnicodeString,10 OBJ_CASE_INSENSITIVE,11 NULL,12 NULL);13//创建⽂件14 NTSTATUS status = ZwCreateFile(&hfile, GENERIC_WRITE,15 &ObjAttributes,16 &iostatus,17 NULL,18 FILE_ATTRIBUTE_NORMAL,19 FILE_SHARE_READ,20 FILE_OPEN_IF,//这⾥是FILE_OPEN_IF则不论⽂件是否存在都可以Create成功,⽽如果改为FILE_OPEN,则只当⽂件存在时create成功。
《Windows驱动开发技术详解》之读写操作缓冲区⽅式读写操作设置缓冲区读写⽅式:读写操作⼀般是由ReadFile和WriteFile函数引起的,这⾥先以WriteFile函数为例进⾏介绍。
WriteFile要求⽤户提供⼀段缓冲区,并且说明缓冲区的⼤⼩,然后WriteFile将这段内存的数据传⼊到驱动程序中。
这种⽅法,操作系统将应⽤程序提供缓冲区数据直接复制到内核模式的地址中。
这样做,⽐较简单的解决了将⽤户地址传⼊驱动的问题,⽽缺点是需要在⽤户模式和内核模式之间复制数据,影响了效率。
在少量内存操作时,可以采⽤这种⽅法。
拷贝到内核模式下的地址由WriteFile创建的IRP的AssociatedIrp.SystemBuffer⼦域记录。
下⾯的代码演⽰了如何利⽤缓冲区⽅式读取设备,这个例⼦中,驱动程序负责向缓冲区中填⼊了数据:应⽤层调⽤ReadFile,想驱动传送⼀个读IRP请求:1int main(){2 HANDLE hDevice =3 CreateFile("\\\\.\\HelloDDK",4 GENERIC_READ | GENERIC_WRITE,50, NULL,6 OPEN_EXISTING,7 FILE_ATTRIBUTE_NORMAL,8 NULL);9if (hDevice == INVALID_HANDLE_VALUE){10 printf("Open device failed!\n");11 }12else{13 printf("Open device succeed!\n");14 }15 UCHAR buffer[10];16 ULONG ulRead;17 BOOL bRet = ReadFile(hDevice, buffer, 10, &ulRead, NULL);18if (bRet){19 printf("Read %d bytes!", ulRead);20for (int i = 0; i < (int)ulRead; i++){21 printf("%02X", buffer[i]);22 }23 printf("\n");24 }25 CloseHandle(hDevice);26 system("pause");27return0;28 }运⾏之后的结果如下:创建⼀个虚拟设备模拟⽂件读写:读、写派遣函数如下:1 NTSTATUS HelloDDKDispatchRead(PDEVICE_OBJECT pDevObj, PIRP pIrp){2 UNREFERENCED_PARAMETER(pDevObj);3 DbgPrint("Enter dispach read!\n");4 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;5 NTSTATUS status = STATUS_SUCCESS;6 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);7//得到要读取的数据的长度8 ULONG ulReadLength = stack->Parameters.Read.Length;9 ULONG ulReadOffset = (ULONG)stack->Parameters.Read.ByteOffset.QuadPart;10if (ulReadOffset + ulReadLength > MAX_FILE_LENGTH){11 status = STATUS_FILE_INVALID;12 ulReadLength = 0;13 }14else{15 memcpy(pIrp->AssociatedIrp.SystemBuffer, pDevExt->buffer + ulReadOffset, ulReadLength);16 status = STATUS_SUCCESS;17 }18 pIrp->IoStatus.Status = status;19 pIrp->rmation = ulReadLength;20//memset(pIrp->AssociatedIrp.SystemBuffer, 0x68, ulReadLength);21 IoCompleteRequest(pIrp, IO_NO_INCREMENT);22return status;23 }2425 NTSTATUS HelloDDKDispatchWrite(PDEVICE_OBJECT pDevObj, PIRP pIrp){26 UNREFERENCED_PARAMETER(pDevObj);27 NTSTATUS status = STATUS_SUCCESS;28 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;29 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);30 ULONG ulWriteLength = stack->Parameters.Write.Length;31 ULONG ulWriteOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;32if (ulWriteOffset + ulWriteLength > MAX_FILE_LENGTH){33 status = STATUS_FILE_INVALID;34 ulWriteLength = 0;35 }36else{37 memcpy(pDevExt->buffer + ulWriteOffset, pIrp->AssociatedIrp.SystemBuffer, ulWriteLength);38 status = STATUS_SUCCESS;39if (ulWriteLength + ulWriteOffset > pDevExt->file_length){40 pDevExt->file_length = ulWriteLength + ulWriteOffset;41 }42 }43 pIrp->IoStatus.Status = status;44 pIrp->rmation = ulWriteLength;45 IoCompleteRequest(pIrp, IO_NO_INCREMENT);4647return status;48 }再在R3添加⼊代码:1 UCHAR buffer[10];2 memset(buffer, 0x66, 10);3 ULONG ulRead;4 ULONG ulWrite;5 BOOL bRet = WriteFile(hDevice, buffer, 10, &ulWrite, NULL);6if (bRet){7 printf("Write %d bytes!\n", ulWrite);8 }910 bRet = ReadFile(hDevice, buffer, 10, &ulRead, NULL);11if (bRet){12 printf("Read %d bytes!", ulRead);13for (int i = 0; i < (int)ulRead; i++){14 printf("%02X", buffer[i]);15 }16 }17 printf("\n");运⾏,得到结果:如果我们要查询⽂件信息,没有注册IRP_MY_QUERY_INFORMATION的派遣函数时,GetFileSize会正常返回读到的⽂件的⼤⼩:但是,因为GetFileSize读取的是⽂件的⼤⼩,⽽这⾥传递的是设备对象的句柄,本来是读不到⼤⼩的,但是如果利⽤驱动对IRP进⾏修改,再返回给R3层,就可以得到了:其派遣函数代码如下:R3层添加代码:1 bRet = GetFileSizeEx(hDevice, &dwFileSize);2 printf("File size is %u\n", dwFileSize);直接⽅式读写操作与缓冲区⽅式读写设备不同,直接⽅式读写设备,操作系统会将⽤户模式下的缓冲区锁住。
目录一、驱动开发环境的搭建 (1)1.1 关于DDK (1)1.2 关于驱动程序的编译 (1)1.3关于驱动程序的运行 (2)二、驱动程序的结构 (3)2.1 驱动程序的头文件 (3)2.2 驱动程序的入口点 (3)2.3 创建设备例程 (4)2.4 卸载驱动例程 (5)2.5 派遣例程 (6)三、编写驱动程序的基础知识 (6)3.1 内核模式下的字符串操作 (6)3.2 内核模式下各种开头函数的区别 (8)3.3 一个示例程序 (10)3.4 补充说明 (10)四、在驱动中使用链表 (10)4.1 内存的分配与释放 (10)4.2 使用LIST_ENTRY (12)4.3 使用自旋锁 (12)五、在驱动中读写文件 (15)5.1 使用OBJECT_ATTRIBUTES (15)5.2 创建、打开文件 (16)5.3 读写文件操作 (16)5.4 文件的其它相关操作 (18)六、在驱动中操作注册表 (18)6.1 创建、打开注册表 (19)6.2 读写注册表 (20)6.3 枚举注册表 (21)七、在驱动中获取系统时间 (21)7.1 获取启动毫秒数 (21)7.2 获取系统时间 (22)八、在驱动中创建内核线程 (23)8.1 创建内核线程 (23)8.2 关于线程同步 (24)九、初探IRP (25)9.1 IRP的概念 (25)9.2 IRP的处理 (26)9.3 IRP派遣例程示例 (27)十、驱动程序与应用层的通信 (29)10.1 使用WriteFile通信 (29)10.2 使用DeviceIoControl进行通信 (32)十二、驱动程序开发实例 (33)12.1 NT驱动程序 (33)12.2 WDM驱动程序 (35)十三、参考资料 (41)一、驱动开发环境的搭建1.1 关于DDK开发驱动程序必备的一个东西就是DDK(Device Development Kit,设备驱动开发包),它跟我们在ring3常听到的SDK差不多,只不过它们分别支持开发不同的程序而已。
Windows内核及操作系统原理培训心得体会3月2日——11日,本人有幸参加了《Windows内核及操作系统原理》和.Net编程培训班,通过这次学习,本人感觉收获颇大,对Windows系统有了更加深入的了解,尤其是从系统原理、核心架构等方面有了更深层次的认识。
主要收获如下:1、通过对Windows进程的学习,使我认识到,Windows的进程是一个容器,其中包含了当执行一个程序的特定实例时用到的各种资源。
Windows的进程包含以下元素:一个私有的虚拟地址空间一个可执行的程序一个已打开句柄的列表一个被称为访问令牌的安全环境一个进程ID至少一个执行线程进程由一个执行体进程(EPROCESS)块来表示。
Windows线程是进程内部某段代码执行的实体。
线程由一个执行体线程(ETHREAD)块来表示。
2、通过对Windows执行体组件的学习,使我知道了主要有哪些执行体,以及这些执行体的作用。
配置管理器:注册表的实现和管理。
进程和线程管理器:创建或终止进程和线程。
I/O管理器:实现了与设备无关的I/O操作,负责将这些操作分派到恰当的设备驱动程序以供进一步处理。
即插即用管理器:针对特定设备确定必需的驱动程序,并加载它们。
内存管理器:实现虚拟内存。
对象管理器:创建、管理和删除Windows执行体对象和抽象数据类型。
电源管理器:负责协调电源事件,并向设备驱动程序产生电源管理I/O通知。
3、通过学习还使我了解了应用程序代码中调用Windows API CreateProcess的过程。
在CreateProcess的内部调用Ntdll.dll中的NtCreateProcess,此函数首先检查参数的正确性,再将处理器模式从用户模式切换到内核模式,调用相关的执行体服务,创建执行体进程对象和初始线程,接下来通知Windows子系统的进程csrss,在它的协助下创建出用户进程。
通过参加这次培训班的学习,必将对我今后的工作产生较大作用,我将用更加努力的工作回报单位。
接触windows驱动开发有一个月了,感觉Windows驱动编程并不像传说中的那么神秘。
为了更好地为以后的学习打下基础,记录下来这些学习心得,也为像跟我一样致力于驱动开发却苦于没有门路的菜鸟朋友们抛个砖,引个玉。
我的开发环境:Windows xp 主机+ VMW ARE虚拟机(windows 2003 server系统)。
编译环境:WinDDK6001.18002。
代码编辑工具:SourceInsight。
IDE:VS2005/VC6.0。
调试工具:WinDBG,DbgView.exe, SRVINSTW.EXE上面所有工具均来自互联网。
对于初学者,DbgView.exe和SRVINSTW.EXE是非常简单有用的两个工具,一定要装上。
前者用于查看日志信息,后者用于加载驱动。
下面从最简单的helloworld说起吧。
Follow me。
驱动程序的入口函数叫做DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegisgryString)。
两个参数,一个是驱动对象,代表该驱动程序;另一个跟注册表相关,是驱动程序在注册表中的服务名,暂时不用管它。
DriverEntry 类似于C语言中的main函数。
它跟main的差别就是,main完全按照顺序调用的方法执行,所有东西都按照程序员预先设定的顺序依次发生;而DriverEntry则有它自己的规则,程序员只需要填写各个子例程,至于何时调用,谁先调,由操作系统决定。
我想这主要是因为驱动偏底层,而底层与硬件打交道,硬件很多都是通过中断来与操作系统通信,中断的话就比较随机了。
但到了上层应用程序,我们是看不到中断的影子的。
说到中断,驱动程序中可以人为添加软中断,__asm int 3或者Int_3();前者是32位操作系统用的,后者是64位用的。
64位驱动不允许内嵌汇编。
下面是我的一个helloworld的源码:注意第16行的宏。
windows编程原理Windows编程是指在Windows操作系统上进行软件开发的过程。
Windows操作系统是面向图形用户界面的操作系统,因此Windows编程主要涉及图形用户界面的设计和交互逻辑的实现。
Windows编程的原理包括以下几个核心概念:1. 窗口:Windows编程的核心是窗口的管理。
窗口是用户界面的基本单元,可以包含控件和其他组件。
窗口有不同的类型,如主窗口、对话框、工具栏等,每个窗口都有唯一的标识符。
2. 消息:在Windows编程中,窗口之间通过消息进行通信。
消息是Windows系统传递给应用程序的事件,如键盘输入、鼠标点击等。
每个窗口都有一个消息处理函数,用于处理接收到的消息。
3. 控件:控件是窗口中的可视化元素,用于实现用户界面的各种功能。
常见的控件包括按钮、文本框、列表框等。
控件可以通过事件处理函数来响应用户操作。
4. 资源:Windows编程中使用资源文件来存储应用程序的资源,如图像、音频、字符串等。
资源文件可以在程序运行时被加载和使用。
5. API函数:Windows编程使用Windows API函数来实现与操作系统的交互。
API函数提供了大量的功能,如创建窗口、处理消息、绘制图形等。
可以使用编程语言(如C++、C#等)来调用这些API函数。
在Windows编程中,开发者可以选择使用不同的编程语言和框架来进行开发。
最常用的编程语言包括C++、C#、 等,常用的框架包括MFC、WinForms、WPF等。
开发者可以根据自己的需求和熟悉程度选择合适的编程语言和框架。
总之,Windows编程是一种基于Windows操作系统的软件开发过程,涉及窗口管理、消息传递、控件操作等核心概念。
开发者需要熟悉Windows API函数和相应的编程语言来进行开发工作。
windows内核驱动开发的英文书籍Windows内核驱动开发是一个相对专业和复杂的主题,涉及底层系统设计和编程。
英文书籍通常具有更全面的知识和更快的更新速度,所以我会推荐一些英文书籍。
以下是一些与Windows内核驱动开发相关的英文书籍:
1. "Windows Kernel Programming" by Alex Ionescu
- 这本书是Windows内核驱动开发领域非常经典的书籍,涵盖了从基础知识到高级技术的全面内容。
2. "The Windows Internals Book" by Mark Russinovich and David A. Solomon
- 这本书深入探讨了Windows操作系统的内部工作原理,适合对底层系统有深入了解的读者。
3. "Microsoft Windows Driver Kit (WDK)"
- 这是一个由微软官方提供的开发套件,其中包含大量的文档、示例和工具,用于帮助开发者编写Windows内核驱动。
4. "Driver Development Kit (DDK)"
- 这是另一个由微软提供的开发套件,用于编写Windows内核驱动和设备驱动。
请注意,这些书籍可能需要一些高级的编程和系统知识才能完全理解。
如果你对这些主题还不熟悉,可能需要先从更基础的书籍或在线教程开始学习。
同时,由于操作系统和开发技术不断发展和更新,这些书籍的内容也可能已经有所变化或更新,所以建议查看最新的版本。
Windows开发工程师岗位面试题及答案1.请介绍一下您在Windows开发方面的经验。
答:我在Windows开发领域有X年的经验。
我曾参与开发过基于Windows的桌面应用程序,涉及UI设计、后端逻辑和与操作系统交互的模块。
2.请详细描述您在Windows应用程序界面设计方面的经验。
答:在应用程序界面设计方面,我使用过WPF和WinForms等工具,设计用户友好的界面。
举例来说,我曾开发一个音乐播放器,通过WPF实现了现代化的界面,包括动画效果和自定义控件。
3.您在多线程编程方面有何经验?答:我熟悉在Windows环境下使用多线程进行并发编程。
在一个视频编辑软件项目中,我实现了多线程视频渲染,提升了性能和用户体验。
4.请解释一下Windows消息循环机制。
答:Windows消息循环是应用程序与操作系统交互的基础。
应用程序通过循环不断地接收、分发和处理消息,包括用户输入和系统事件。
例如,WM_PAINT消息触发界面的重绘。
5.如何处理Windows应用程序中的异常?答:异常处理对于稳定的应用程序至关重要。
我会使用trycatch 块捕获可能的异常,并在适当的地方记录日志。
在一个文件管理器项目中,我实现了针对文件操作的异常处理,确保应用程序不会因为意外情况崩溃。
6.请谈谈您在Windows注册表操作方面的经验。
答:注册表是Windows配置和设置的关键部分。
我曾经开发过一个系统优化工具,使用C编写了操作注册表的模块,允许用户自定义系统设置以提升性能。
7.如何优化Windows应用程序的启动时间?答:优化启动时间需要减少不必要的资源加载和初始化。
我会延迟加载非必要模块,使用异步加载,以及优化资源的预加载。
在一个文本编辑器项目中,我成功减少了启动时间,提升了用户体验。
8.请谈谈您对COM(ComponentObjectModel)的理解。
答:COM是一种Windows平台上的组件技术,用于实现不同组件之间的通信和交互。
windows驱动开发教程Windows驱动开发是指在Windows操作系统下编写、调试和部署驱动程序的过程。
驱动程序是操作系统的核心组成部分,它负责与硬件设备通信,使得操作系统能够正确地识别、管理和控制硬件设备。
在本教程中,我们将介绍Windows驱动开发的基本概念、工具和流程。
首先,为了进行Windows驱动开发,我们需要准备好相应的开发工具。
其中最重要的工具是Windows Driver Kit(WDK),它包含了用于驱动开发的各种工具和库文件。
我们可以从微软官方网站上下载并安装最新版本的WDK。
接下来,我们需要熟悉驱动程序的基本概念。
在Windows中,驱动程序可以分为内核驱动和用户模式驱动。
内核驱动运行在操作系统的内核空间,具有更高的权限和更广泛的硬件访问能力;而用户模式驱动则运行在用户空间,通过系统调用与内核驱动进行通信。
我们需要了解如何编写和编译这两种类型的驱动程序,并了解它们的工作原理和特点。
在编写驱动程序之前,我们还需要了解一些基本的Windows内核编程概念,例如驱动对象模型(Driver Object Model)、设备对象模型(Device Object Model)和驱动程序接口(Driver Interface)。
这些概念是驱动程序的基础,对于理解和设计驱动程序非常重要。
接下来,我们将介绍如何使用WDK的工具和库文件来编写驱动程序。
我们可以使用Visual Studio编写驱动程序的源代码,并使用WDK的编译工具将源代码编译成驱动程序二进制文件。
在编译过程中,我们需要配置驱动程序的环境和依赖项,并确保编译成功。
在编写和编译驱动程序之后,我们需要进行驱动程序的调试和部署。
对于驱动程序的调试,我们可以使用WDK提供的调试工具和技术,例如Kernel-Mode Debugging和WinDbg。
对于驱动程序的部署,我们需要将驱动程序二进制文件和相关的配置文件复制到操作系统的指定目录,并注册驱动程序的信息到操作系统的驱动程序数据库。
Windows驱动开发技术详解第六章的(Windows内核函数)自我理解学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。
其实这章主要就是讲函数DDK有自己的函数跟SDK一样编写DDK使用DDK提供的函数就OK了///////////////////////////////////////////////////////////////////////////////ASCII字符串和宽字符串ASCII字符构造char*str1="abc";打印ASCII字符串char*string="hello";KdPrint("%s\n",string);\\注意是小写%s/////UNICODE字符构造wchar_t*str2=L"abc";打印宽字符串WCHAR*string=L"hello";KdPrint("%S\n",string);\\注意是大写%S///////////////////////////////////////////////////////////////////////////////ANSI_STRING字符串和UNICODE_STRING字符串ASCII字符串进行了封装typedef struct_STRING{USHORT Length;//字符的长度。
USHORT MaximumLength;//整个字符串缓冲区的最大长度。
PCHAR Buffer;//缓冲区的指针。
}STRING;输出字符串ANSI_STRING ansiString;KdPrint("%Z\n",&ansiString);//注意是%ZUNICODE_STRING宽字符串封装typedef struct_UNICODE_STRING{USHORT Length;//字符的长度,单位是字节。
如果是N个字符,那么Length等于N的2倍。
USHORT MaximumLength;//整个字符串缓冲区的最大长度,单位也是字节。
PWSTR Buffer;//缓冲区的指针。
}UNICODE_STRING*PUNICODE_STRING;输出字符串UNICODE_STRING ansiString;KdPrint("%wZ\n",&ansiString);//注意是%wZ///////////////////////////////////////////////////////////////////////////////字符初始化与销毁初始化ANSI_STRING字符串VOIDRtlInitAnsiString(IN OUT PANSI_STRING DestinationString,//要初始化的ANSI_STRING字符串IN PCSZ SourceString//字符串的内容);初始化UNICODE_STRING字符串VOIDRtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,//要初始化的UNICODE_STRING字符串IN PCWSTR SourceString//字符串的内容);///////////////////////////////////////////////////////////////////////////////字符串复制ANSI_STRING字符串复制VOIDRtlCopyString(IN OUT PSTRING DestinationString,//目的字符串。
IN PSTRING SourceString OPTIONAL//源字符串。
);UNICODE_STRING字符串复制VOIDRtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,//目的字符串。
IN PUNICODE_STRING SourceString//源字符串。
);///////////////////////////////////////////////////////////////////////////////字符串比较ANSI_STRING字符串LONGRtlCompareString(IN PSTRING String1,//要比较的第一个字符串。
IN PSTRING String2,//要比较的第二个字符串。
BOOLEAN CaseInSensitive//是否对大小写敏感。
);UNICODE_STRING字符串LONGRtlCompareUnicodeString(IN PUNICODE_STRING String1,//要比较的第一个字符串。
IN PUNICODE_STRING String2,//要比较的第二个字符串。
IN BOOLEAN CaseInSensitive//是否对大小写敏感。
);///////////////////////////////////////////////////////////////////////////////字符串转化成大写ANSI_STRING字符串转化成大写VOIDRtlUpperString(IN OUT PSTRING DestinationString,//目的字符串。
IN PSTRING SourceString//源字符串。
);UNICODE_STRING字符串转化成大写NTSTA TUSRtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString OPTIONAL,//目的字符串。
IN PCUNICODE_STRING SourceString,//源字符串。
IN BOOLEAN AllocateDestinationString//是否为目的字符串分配内存。
);///////////////////////////////////////////////////////////////////////////////字符串与整型数字相互转换UNICODE_STRING字符串转化成整数NTSTA TUSRtlUnicodeStringToInteger(IN PUNICODE_STRING String,//需要转换的字符串。
IN ULONG Base OPTIONAL,//转换的数的进制(如2,8,10,16)。
OUT PULONG Value//需要转换的数字。
);将整数转化成UNICODE_STRING字符串NTSTA TUSRtlIntegerToUnicodeString(IN ULONG Value,//需要转换的数字。
IN ULONG Base OPTIONAL,//转换的数的进制(如2,8,10,16)。
IN OUT PUNICODE_STRING String//需要转换的字符串。
);///////////////////////////////////////////////////////////////////////////////内核模式下的文件操作文件创建NTSTA TUSZwCreateFile(OUT PHANDLE FileHandle,//返回打开文件的句柄IN ACCESS_MASK DesiredAccess,//对打开文件操作的描述,读,写或者其他。
一般指定GENERIC_READ或者GENERIC_WRITE。
IN POBJECT_ATTRIBUTES ObjectAttributes,//是OBJECT_ATTRIBUTES结构地址,该结构包含要打开的文件名。
OUT PIO_STA TUS_BLOCK IoStatusBlock,//指向一个IO_STA TUS_BLOCK结构,该结构接收ZwCreateFile操作的结果状态。
IN PLARGE_INTEGER AllocationSize OPTIONAL,//是一个指针,指向一个64位整数,该数指定文件初始分配时的大小。
该参数仅关系到创建或重写文件操作,如果忽略它(如笔者在这里所做的),那么文件长度将从0开始,并随着写入而增长。
IN ULONG FileAttributes,//0或FILE_ATTRIBUTE_NORML,指定新创建文件的属性。
IN ULONG ShareAccess,//FILE_SHARE_READ或0,指定文件的共享方式。
如果仅为读数据而打开文件,则可以与其他线程同时读取该文件。
如果为写数据而打开文件,可能不希望其他线程访问该文件。
IN ULONG CreateDisposition,//FILE_OPEN或FILE_OVERWRITE_IF,表明当指定文件存在或不存在时应如何处理。
IN ULONG CreateOptions,//FILE_SYNCHRONOUS_IO_NONALERT,指定控制打开操作和句柄使用的附加标志位。
IN PVOID EaBuffer OPTIONAL,//一个指针,指向可选的扩展属性区。
IN ULONG EaLength//扩展属性区的长度。
);DDK提供了对OBJECT_ATTRIBUTES结构初始化的宏InitializeObjectAttributesVOIDInitializeObjectAttributes(OUT POBJECT_ATTRIBUTES InitializedAttributes,//返回的OBJECT_ATTRIBUTES结构IN PUNICODE_STRING ObjectName,//对象名称,用UNICODE_STRING描述,这里设置的是文件名。
IN ULONG Attributes,//一般设为OBJ_CASE_INSENSITIVE,对大小敏感。
IN HANDLE RootDirectory,//一般为NULL空IN PSECURITY_DESCRIPTOR SecurityDescriptor//一般为NULL空);打开文件NTSTA TUSZwOpenFile(OUT PHANDLE FileHandle,//返回打开的文件句柄。
IN ACCESS_MASK DesiredAccess,//打开的权限,一般设为GENERIC_ALL。
IN POBJECT_ATTRIBUTES ObjectAttributes,//ObjectAttributes结构指针。