UNICODE_STRING 总结

UNICODE_STRING:

typedef struct _UNICODE_STRING {
  USHORT  Length;     //UNICODE占用的内存字节数,个数*2;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING ,*PUNICODE_STRING;

 

ANSI_STRING:

typedef struct _STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PCHAR  Buffer;
} STRING, *PANSI_STRING;

 

 

实例:

WCAHR temp[] = L"Hello World!";   //定义宽字符串

UNICODE_STRING str ;

str.Buffer = temp;

str.Length  = wcslen(temp)*sizeof(WCHAR)   //这个长度为UNICODE字符串所占用的字节数,即字符的个数乘以每个字符所占的字节数。通常为: 字符个数*2 ; 


    当使用UNICODE_STRING 时,一定要手动设置UNICODE_STRING 的Length和MaximumLength 成员,不要想当然的认为设置了Buffer后,Length和MaximumLength 成员就会根据Buffer被自动设置。由其是当自己写的函数用UNICODE_STRING作为参数返回时,一定要设置Length和MaximumLength 成员,不然很可能得到非预期结果。


 当应用程序与驱动通信时,一般应用程序传入的字符串为ANSI,所以在驱动中应先定义ANSI_STRING,然后再使用RtlAnsiStringToUnicodeString 将其转换成UNICODE_STRING,作为后用。例:

 

ANSI_STRING  str_a;

 

UNICODE_STRING  str_u;

WCHAR buf_u[1024] = L"";

 

str_a.Buffer = InputBuffer ;  //InputBuffer 为输入缓冲区地址

str_a.Length = str_a.MaximumLength = strlen(InputBuffer);

 

//开辟UNICODE内存空间

str_u.Buffer = buf_u;

str_u.Length = str_u.MaximumLength = strlen(InputBuffer) * sizeof(WCHAR);

 

RtlAnsiStringToUnicodeString(&str_u, &str_a , TRUE);

........

........

//当RtlAnsiStringToUnicodeString第三个参数为TRUE时,要用RtlFreeUnicodeString释放临时的UNICODE_STRING

RtlFreeUnicodeString(&str_u);


拼接UNICODE_STRING

  当拼接UNICODE_STRING 时,注意目标UNICODE的Length为当前UNICODE中存储字符的字节数。如:

WCHAR str1[] = L"12345";

UNICODE_STRING str2;

str2.Buffer = ExAllocatePool(NonPagedPool, wcslen(str1)*sizeof(WCHAR))

str2.Length = 0;

str2.MaximumLength = wcslen(str1)*sizeof(WCHAR);

 RtlAppendUnicodeToString(&str2, str1);

 


 UNICODE 和 ExAllocatePool

   内核在UNICODE拼接或其他临时操作时,经常使用ExAllocatePool动态分配UNICODE的Buffer,简单情况:

UNICODE_STRING str;

str.Buffer = ExAllocatePool(NonPagedPool, 50*sizeof(WCHAR));

str.Length = 0;

str.MaximumLength = 50*sizeof(WCHAR);

但若是定义一个UNICODE的指针,则如何初始化UNICODE ? 

PUNICODE_STRING pStr;

因为定义了一个指针,但指针目前并没有指向可用的内存地址,故先分配一块内存(NonPagedPool),让pStr指向这块内存。

pStr = ExAllocatePool(NonPagedPool, 50*sizeof(WCHAR));

接着初始化成员:

pStr.Length = 0;

pStr.MaximumLength = ???;

如何初始化Buffer ?

    因为UNICODE_STRING 是一个数据结构,我们申请一块内存来存储这个数据结构,所以这块内存不仅存储了Buffer这个我们最关心的字符串,而且还储存这个数据结构,即Length 、 MaximumLength 和 Buffer (指针)成员。因为pStr是这块内存的起始地址,所以:

&pStr.Length = (USHORT*)pStr

&pStr.MaximumLength = (USHORT*)pStr + 1

&pStr.Buffer = (USHORT*)pStr + 2

所以得:

pStr.Buffer = (WCHAR*)((USHORT*)pStr + 2 + 2 )  因为一个USHORT占2个字节,一个指针占4个字节。这时得出,pStr.MaximumLength =  50*sizeof(WCHAR) - (2+2+4);

注意,以上是为了方便观察特意写成赋值形式,但在编译器中并不适用,因为=左边得为左值。)

 整体:

PUNICODE_STRING pStr;

pStr = ExAllocatePool(NonPagedPool, 50*sizeof(WCHAR));

pStr.Length = 0;

pStr.Buffer = (WCHAR*)( (USHORT*)pStr + 2 + 2 ) ; 

 

总结:

    定义UNICODE_STRING 时,编译器在栈上自动分配了存储UNICODE_STRING这个数据结构的空间,我们唯一要做的就是给Buffer这个指针成员(指向)分配内存。

    而定义PUNICODE_STRING时,在堆上分配了一块内存,这块内存不仅存储了Buffer,而且还存储了UNICODE_STRING这个数据结构。所以定义为PUNICODE_STRING时,要比预期的字符串至少多8个字节,就因为此。

pStr.MaximumLength = 50*sizeof(WCHAR) - (2+2+4);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值