20、Windows内核函数(1)-Windows驱动开发详解笔记,字符串
1、字符串
1)两种字符串,一种是char型,记录ansi字符集。每个字符一个字节。以0标志结束。在KdPrint中用%s输出。
宽字符型,wchar_t,描述unicode字符集的字符串,每个字符两个字节,以0标志结束。通过L来体现。在KdPrint中用%S输出。
如CHAR *string = "Hello";
WCHAR *string2 = L"hello";
KdPrint("%s\n", string);
KdPrint("%S\n", string2);
2)ANSI_STRING字符串和UNICODE_STRING字符串
DDK不鼓励用1)中所示的C语言字符串,因为C的字符串处理函数易导致缓冲区溢出等错误(如忘记对长度进行检查)。而鼓励用DDK自己定义的字符串。
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING *PANSI_STRING;
注意STRING不是以0结束的。
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING *PUNICODE_STRING;
用%Z输出 ANSI_STRING字符串,用%wZ输出 UNICODE_STRING
UNICODE_STRING uniString;
KdPrint("%wZ", &uniString);
3)字符串常见操作
(1)初始化
方法一:使用DDK提供的函数
RtlInitUnicodeString
RtlInitAnsiString
如
UNICODE_STRING uniString;
CHAR *string1 = "Hello";
RtlInitAnsiString(&uniString, string1);
不过有一个问题,修改string1,uniString也会变化。
方法二:自己申请内存,使用完后回收内存
#define BUFFER_SIZE 1024
UNICODE_STRING UnicodeString1 = {0};
//设置缓冲区大小
UnicodeString1.MaximumLength = BUFFER_SIZE;
//分配内存
UnicodeString1.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
WCHAR* wideString = L"hello";
//设置字符长度,因为是宽字符,所以是字符长度的2倍
UnicodeString1.Length = 2*wcslen(wideString);
//保证缓冲区足够大,否则程序终止
ASSERT(UnicodeString1.MaximumLength>=UnicodeString1.Length);
//内存拷贝,
RtlCopyMemory(UnicodeString1.Buffer,wideString,UnicodeString1.Length);
//设置字符长度
UnicodeString1.Length = 2*wcslen(wideString);
KdPrint(("UnicodeString:%wZ\n",&UnicodeString1));
//清理内存
ExFreePool(UnicodeString1.Buffer);
UnicodeString1.Buffer = NULL;
UnicodeString1.Length = UnicodeString1.MaximumLength = 0;
最后一步清理内存,可以使用DDK函数简化:
RtlFreeAnsiString
RtlFreeUnicodeString
(2)复制
RtlCopyString
RtlCopyUnicodeString
//初始化UnicodeString1
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1,L"Hello World");
//初始化UnicodeString2
UNICODE_STRING UnicodeString2={0};
UnicodeString2.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
UnicodeString2.MaximumLength = BUFFER_SIZE;
//将初始化UnicodeString2拷贝到UnicodeString1
RtlCopyUnicodeString(&UnicodeString2,&UnicodeString1);
//分别显示UnicodeString1和UnicodeString2
KdPrint(("UnicodeString1:%wZ\n",&UnicodeString1));
KdPrint(("UnicodeString2:%wZ\n",&UnicodeString2));
//销毁UnicodeString2
//注意!!UnicodeString1不用销毁
RtlFreeUnicodeString(&UnicodeString2);
(3)比较
RtlCompareString
RtlCompareUnicodeString
RtlEqualString
RtlEqualUnicodeString
(4)字符串转换成大字
RtlUpperString
注意,没有提供转化成小写的函数。
(5)字符串与整形数字相互转换
RtlUnicodeStringToInteger
RtlIntegerToUnicodeString
(6)ANSI_STRING与UNICODE_STRING相互转换
RtlUnicodeStringToAnsiString
RtlAnsiStringToUnicodeString
另外注意返回值的处理方法:
if ( NT_SUCCESS(nStatus))
{
KdPrint(("Conver to integer succussfully!\n"));
KdPrint(("Result:%d\n",lNumber));
}else
{
KdPrint(("Conver to integer unsuccessfully!\n"));
}
参考:
[1] Windows驱动开发详解
[2] MSDN