unicode_stirng用法

前记:最近驱动也差不多弄完了,在过一段时间差不多该上了,回头看看,这半年来也就折腾了这个象样点,自然也要留点啥的,供后面回忆回忆。

言归正传,首先看UNICODE_STRING的结构定义:

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING *PUNICODE_STRING;

包括三个域,其中:

Length:表示Buffer的长度;

MaximumLength:表示Buffer的最大长度,一般不常用,和系统有关系;

Buffer:表示字符串指针地址;

UNICODE_STRING在驱动应用比较多,其操作大致有如下几个:

(1)初始化,常见的初始化有两种方式:

1.调用RtlInitUnicodeString,该函数原型如下:

VOID RtlInitUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);

该方法的实际原理是:将SourceString的宽字符串指针赋值给UNICODE_STRING的Buffer值,同时SourceString的长度值填入结构的Length域,默认的MaximumLength = Length + 2;

如:RtlInitUnicodeString(&ustrRegString,L"Hello");

2.采用动态分配内存的方式初始化,其调用方式如下:

UNICODE_STRING ustr;

ustr.Length= 0;

ustr.MaximumLength = 256;

ustr.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,256,MEM_TAG); //MEM_TAG为自定义

这样就动态分配了一个存储空间给ustr。

(2)字符串连接

连接常见的就是将两个UNICODE_STRING或者将WCHAR_T的字符串连接起来

首先,将两个UNICODE_STRING连接起来,调用RtlAppendUnicodeStringToString函数实现,其原型如下:

NTSTATUS RtlAppendUnicodeStringToString(
IN OUT PUNICODE_STRING Destination,
IN PUNICODE_STRING Source
);

调用该函数的原理是将两者的字符串Buffer拼接起来,同时,更新对应的Length和MaxLength域。在调用的

过程中要注意Destination的MaxLength域,若MaxLength小于Destination和Source的Length域的和的时候,该函数调用不成功,返回0xC0000023,即缓冲区溢出错误。所以在调用该函数的时候,一定要确定Destination的MaxLength域。

若将WCHAR_T字符串串接到UNICODE_STRING之后,则需要调用RtlAppendUnicodeToString,函数原型如下:

NTSTATUS RtlAppendUnicodeToString(
IN OUT PUNICODE_STRING Destination,
IN PCWSTR Source
);

该函数和上面函数并没有特别多的不一致,但该函数较上一个函数不同的地方就是不会出现缓冲区溢出的错误,也就是即使Destination的MaxLength域为0,也可以执行RtlAppendUnicodeToString的操作。

还有另外一个需要注明的地方,如果UNICODE_STRING是通过RtlInitUnicodeString初始化,那么不管调用什么函数,修改UNICODE_STRING值的时候,初始化使用的PCWSTR数组的值也会发生改变,因为他们指向的是同一个Buffer。

注上一例,备后用:

UNICODE_STRING ustrStr,ustrName;

ustrStr.Length = wcslen(strKey) * 2;
RtlAppendUnicodeToString(&ustrStr,strKey);
ustrStr.MaximumLength = 256;
RtlAppendUnicodeToString(&ustrStr,L"");
RtlAppendUnicodeStringToString(&ustrStr,&ustrName);

(3)字符串转换

转换目的可能涉及到中文显示的问题,如果简单的UNICODE_STRING转换为wchar_t或者char的形式,采用RtlCopyMemory的方式,因为UNICODE_STRING字符串并不一定以\0作为结束符,所以需要使用RtlCopyMemory,拷贝定长的字符串。

对于中文显示的问题,采用ANSI_STRING的方式进行输出。从UNICODE_STRING到ANSI_STRING转换,可以通过RtlUnicodeStringToAnsiString实现,其原型如下:

NTSTATUS RtlUnicodeStringToAnsiString(
IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);

典型例子如下:

UNICODE_STRING src;

ANSI_STRING dst;

RtlInitUnicodeString(&src,L”打印汉字”);

RtlUnicodeStringToAnsiString(&dst,&src,TRUE);

DbgPrint(“%Z”,&dst);

RtlFreeAnsiString(&dst);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值