windows 驱动开发- 内核中字符串数据结构

目录

windows中字符串的操作。

一丶UNICODE_STRING 字符串

1.1 使用UNICODE_STRING 以及注意的事项

无论是内核还是应用层变成,字符串都是最基本的数据结构。 而在内核中字符串给封装了。

封装成了UNICODE_STRING 和 ASCII_STRING。

看下这两个结构

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
	PWCH   Buffer;
} UNICODE_STRING;

本质是一个结构体, 这里请注意Buffer指向的字符串。而这个字符串可能并不是以 ‘\0’ 结尾的。

因为前两个字段已经在控制他的字符串长度了。

第二点需要注意的是 Buffer是一个指针。它可以指向一个缓冲区 这个缓冲区可以是你在栈上定义的缓冲区, 也可以是一个常量字符串缓冲区。 也可以是你申请内存后给定的一个堆内存的缓冲区。

默认他只是一个指针,请不要直接对他进行内存拷贝。

例如如下会出现bug的例子

UNICODE_STRING uabc;
memcpy(uabc.buffer,xxx,10);  //uabc.buffer 未初始化,不知道是指向哪里。有可能是0 给0拷贝就崩溃

例子2
wchat a[10] = L"xxx....";
RtlInitUnicodeString(&uabc,a); //这里实际上uabc.buffer = a 所以buffer的缓冲只有10越界也会崩溃

ASCII_STRING 同理 不在赘述

1.2 字符串常见的API操作函数

字符串初始化函数

函数 作用 IRQL级别
VOID RtlInitUnicodeString(PUNICODE_STRING Dest,PCWSTR Src) 将Src指向的字符串赋值给dest 如果Dst指向的内存是非分页内存,那么此函数可以工作在IRQL <= DISPATCH_LEVEL下,否则只能工作在<= APC_LEVEL

例子:

UNICODE_STRING uTest;
RtlInitUnicodeString(&uTest,L"HelloWorld");
DbgPrint("初始化的UTest = : %wZ \r\n", uTest);

本质上就是操作 utest.Buffer = L"HelloWorld"

其他常用的UnicodeString的方法如下:

RtlInitEmptyUnicodeString();  //初始化空的UNICODE_STRING
RtlCompareUnicodeString();    //比较UNICODE_STRING
RtlAppendUnicodeStringToString();//拼接UNICODE_STRING
RtlCopyUnicodeString();       //拷贝
RtlEqualUnicodeString();    
RtlInt64ToUnicodeString();

关于UNICODE_String 有更加安全的函数,那就是头文件 <ntstrsafe.h> 里面。

其中

RtlUnicodeStringxxxxx 前缀开始的是对UNICODE_STRING操作的

RtlStringxxx 前缀开始的是对 宽字符操作的。 比如 拷贝UNICODE_STRING的值到宽字符指针指向的内存中

其它还有就是字符串拼接等函数。 具体看下MSDN

MSDN_Kern API详解

这里额外提一下 对于UNICODE_STRING的格式化函数。 相当于 sprintf 或者wprintf

RtlUnicodeStringPrintf()

最重要的一点是 拷贝的函数 只能在 PASSIVE_LEVEL下使用

RtlUnicodeStringCopyString()
上一篇:Java数据类型扩展


下一篇:编码