20、Windows内核函数(1)-Windows驱动开发详解笔记,字符串

时间:2021-02-08 04:52:27

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);

//分别显示UnicodeString1UnicodeString2

KdPrint(("UnicodeString1:%wZ\n",&UnicodeString1));

KdPrint(("UnicodeString2:%wZ\n",&UnicodeString2));

//销毁UnicodeString2

//注意!!UnicodeString1不用销毁

RtlFreeUnicodeString(&UnicodeString2);

3)比较

RtlCompareString 

RtlCompareUnicodeString 

RtlEqualString 

RtlEqualUnicodeString 

4)字符串转换成大字

RtlUpperString 

注意,没有提供转化成小写的函数。

5)字符串与整形数字相互转换

RtlUnicodeStringToInteger 

RtlIntegerToUnicodeString 

6ANSI_STRINGUNICODE_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"));

}

参考:

1Windows驱动开发详解

2MSDN