第6章 windows内核函数(字符串操作)

6.1 字符串操作

6.1.1. ASCII字符串和宽字符串

char(ASCII字符串)一个字节

wchar_t(宽字符串)两个字节

在构造字符串时使用关键字"L",编译器会自动生成所需的宽字符

wchar_t *str = L"abc";

在驱动程序开发中,DDK替换成CHAR和WCHAR

CHAR *str ="hello"';

KdPrint("%s\n",str);            //注意是小写的s

WCHAR *str =L"hello"';

KdPrint("%S\n",str);            //注意是大写的S

6.1.2 ANSI_STRING字符串与UNICODE_STRING字符串

DDK不鼓励使用C语言的字符串,鼓励使用DDK自定义的字符串

typedef struct _STRING{

USHORT Length;

USHORT MaximunLength;

PCHAR Buffer;

}STRING;                        //另一个类似

这两种字符串不是以0标志字符的结束,字符串长度依靠Length字段,最大长度是MaximunLength,而不是MaximunLength-1

6.1.3 字符初始化与销毁

ANSI_STRING字符串与UNICODE_STRING字符串使用前需要初始化。有两种办法构造这个数据结构

RtlInitAnsiString(IN OUT PANSI_STRING DestinationString, IN PCSZ SourceString );

RtlInitUnicodeString( );

初始化示例1

ANSI_STRING AnsiString1;

CHAR * string1="hello";

RtlInitAnsiString(&AnsiString1,string1);

但带来另外一个问题,如果修改string1,同时会导致AnsiString1字符发生变化。

初始化示例2

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

ExFreePool(UnicodeString1.Buffer);

UnicodeString1.Buffer =NULL;

UnicodeString1.Length =UnicodeString1.MaximumLength =0;

 

6.1.4 字符串复制

(1)ANSI_STRING字符串复制函数

VOID

 RtlCopyString(

  IN OUT PSTRING DestinationString,

  IN PSTRING SourceString OPTIONAL

);

DestinationString:目的字符串。
SourceString:源字符串。
(2)UNICODE_STRING字符串复制函数

VOID

 RtlCopyUnicodeString(

  IN OUT PUNICODE_STRING DestinationString,

  IN PUNICODE_STRING SourceString

);

DestinationString:目的字符串。
SourceString:源字符串。

 

6.1.5 字符串比较

LONG

 RtlCompareString(

  IN PSTRING String1,

  IN PSTRING String2,

  BOOLEAN CaseInSensitive

);

String1:要比较的第一个字符串。
String2:要比较的第二个字符串。
CaseInSensitive:是否对大小写敏感。
返回值:比较结果。
LONG

 RtlCompareUnicodeString(

  IN PUNICODE_STRING String1,

  IN PUNICODE_STRING String2,

  IN BOOLEAN CaseInSensitive

  );

如果函数返回值为0,表示两个字符串相等。如果小于零,则表示第一个字符串小于第二个字符串。反之,如果大于零,则代表第一个字符串大于第二个字符串。

 

6.1.6 字符串转化成大写

(1)ANSI_STRING字符串转化成大写。

VOID

 RtlUpperString(

  IN OUT PSTRING DestinationString,

  IN PSTRING SourceString

);

DestinationString:目的字符串。
SourceString:源字符串。
(2)UNICODE_STRING字符串转化成大写。

NTSTATUS

 RtlUpcaseUnicodeString(

  IN OUT PUNICODE_STRING DestinationString OPTIONAL,

  IN PCUNICODE_STRING SourceString,

  IN BOOLEAN AllocateDestinationString

);

 

6.1.7 字符串与整型数字相互转换

DDK提供了UNICODE_STRING字符串与整数相互转换的内核函数。

(1)将UNICODE_STRING字符串转换成整数。

这个函数是RtlUnicodeStringToInteger,其声明是:

NTSTATUS

 RtlUnicodeStringToInteger(

  IN PUNICODE_STRING String,

  IN ULONG Base OPTIONAL,

  OUT PULONG Value

  );

String:需要转换的字符串。
Base:转换的数的进制(如2、8、10、16)。
Value:需要转换的数字。
返回值:指明是否转换成功。

2)将整数转换成UNICODE_STRING字符串。

这个函数RtlIntegerToUnicodeString,其声明是:

NTSTATUS

 RtlIntegerToUnicodeString(

  IN ULONG Value,

  IN ULONG Base OPTIONAL,

  IN OUT PUNICODE_STRING String

  );

Value:需要转换的数字。
Base:转换的数的进制(如2、8、10、16)。
String:需要转换的字符串。
返回值:指明是否转换成功。

 

6.1.8 ANSI_STRING字符串与UNICODE_STRING字符串相互转换

DDK提供了ANSI_STRING字符串与UNICODE_STRING字符串相互转换的相关函数。

(1)将UNICODE_STRING字符串转换成ANSI_STRING字符串。

DDK对于这种转换提供的函数是RtlUnicodeStringToAnsiString,其声明是:

NTSTATUS

 RtlUnicodeStringToAnsiString(

  IN OUT PANSI_STRING DestinationString,

  IN PUNICODE_STRING SourceString,

  IN BOOLEAN AllocateDestinationString

  );

DestinationString:需要被转换的字符串。
SourceString:需要转换的源字符串。
AllocateDestinationString:是否需要对被转换的字符串分配内存。
返回值:指明是否转换成功。
(2)将ANSI_STRING字符串转换成UNICODE_STRING字符串。

DDK对于这种转换提供的函数是RtlAnsiStringToUnicodeString,其声明是:

NTSTATUS

 RtlAnsiStringToUnicodeString(

  IN OUT PUNICODE_STRING DestinationString,

  IN PANSI_STRING SourceString,

  IN BOOLEAN AllocateDestinationString

  );

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值