Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4823459
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类: WINDOWS

2010-04-19 17:40:48

UNICODE_STRING:

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

ANSI_STRING:

typedef struct _STRING {
  USHORT  ;
  USHORT  ;
  PCHAR  ;
} 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);

阅读(2238) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-06-01 06:30:06

MBT is based on Africa's indigenous people to create innovative walking barefoot, and wear this shoe can stimulate the body to relax the muscles so that the muscles of heat to be released, consumed calories, thus to achieve weight loss results. MBT's pursuit of beauty in order to satisfy customers, design a variety of styles, such as Mbt Chapa shoe, MBT Lami Shoe