1、UNICODE_STRING
windows内核编码字符集采用unicode字符集,字符串处理使用UNICODE_STRING,是一个结构体,定义如下:
typedef struct _UNICODE_STRING
{
USHORT Length
;
USHORT MaximumLength
;
#ifdef MIDL_PASS
[size_is(MaximumLength
/ 2), length_is((Length
) / 2) ] USHORT
* Buffer
;
#else
_Field_size_bytes_part_opt_(MaximumLength
, Length
) PWCH Buffer
;
#endif
} UNICODE_STRING
;
Length 字符串长度,MaximumLength 字符串缓冲区长度,Buffer 字符串缓冲区指针变量。
2、字符串声明与初始化
第一种方式,以局部变量方式,让UNICODE_STRING的Buffer指向一个已声明的WCHAR数组。
UNICODE_STRING strDest
;
WCHAR dest_buf
[256];
RtlInitEmptyUnicodeString(&strDest
, dest_buf
, 256*sizeof(WCHAR
));
RtlInitEmptyUnicodeString去初始化strDest。
第二种方式,使用RtlInitUnicodeString函数去初始化一个UNICODE_STRING变量,给其复制,分配空间
UNICODE_STRING strSource
;
RtlInitUnicodeString(&strSource
, L
"测试字符串连接");
第三种方式,动态申请空间,类似应用程序的malloc函数。
UNICODE_STRING strDest
;
strDest
.Length
= 0;
strDest
.MaximumLength
= sizeof(WCHAR
) * 1024;
strDest
.Buffer
= (PWCH
)ExAllocatePoolWithTag(PagedPool
, sizeof(WCHAR
)*1024, MEMTAG
);
if (!strDest
.Buffer
)
{
return STATUS_INSUFFICIENT_RESOURCES
;
}
3、字符串拷贝
UNICODE_STRING strSource
;
RtlInitUnicodeString(&strSource
, L
"测试字符串连接");
KdPrint(("source is %wZ字节长度%d 最大长度%d.\n", &strSource
, strSource
.Length
, strSource
.MaximumLength
));
RtlCopyUnicodeString(&strDest
,&strSource
);
KdPrint(("dest is %wZ 字节长度%d 最大长度%d.\n", strDest
, strDest
.Length
, strDest
.MaximumLength
));
unicode格式化字符串输出使用%wZ,ansi格式化字符串输出使用%x
4、字符串连接
UNICODE_STRING strTmp
;
RtlInitUnicodeString(&strTmp
, L
"this is a new string");
ntres
= RtlAppendUnicodeStringToString(&strDest
, &strTmp
);
字符串连接使用,根据第二个参数类型而定,如果是unicode,选择RtlAppendUnicodeStringToString,如果是ansi,选择RtlAppendUnicodeToString。
5、字符串比较
UNICODE_STRING uCp1
, uCp2
;
RtlInitUnicodeString(&uCp1
, L
"hello a world.");
RtlInitUnicodeString(&uCp2
, L
"hello b world.");
LONG lRet
= RtlCompareUnicodeString(&uCp1
, &uCp2
, TRUE
);
if (lRet
> 0)
{
KdPrint(("%wZ 大于 %wZ .", &uCp1
, &uCp2
));
}
else if(lRet
< 0)
{
KdPrint(("%wZ 小于 %wZ .", &uCp1
, &uCp2
));
}
else
{
KdPrint(("%wZ 等于 %wZ .", &uCp1
, &uCp2
));
}
RtlCompareUnicodeString类似应用程序的strcmp函数,返回值为三种值,大于0,等于0,小于0,其第三个参数表示是否大小写敏感。
6、UNICODE_STRING与ANSI_STRING互转
UNICODE_STRING uniTrans
;
RtlInitUnicodeString(&uniTrans
, L
"test unicode to ansi");
ANSI_STRING ansiTrans
;
RtlUnicodeStringToAnsiString(&ansiTrans
, &uniTrans
, TRUE
);
KdPrint(("%wZ to ansi is %Z", &uniTrans
, &ansiTrans
));
RtlAnsiStringToUnicodeString(&uniTrans
, &ansiTrans
, TRUE
);
KdPrint(("%Z to ansi is %wZ", &ansiTrans
, &uniTrans
));
7、上述测试完整代码
#include <ntddk.h>
#define MEMTAG 'test'
VOID
DriverUnload(PDRIVER_OBJECT pDriverObject
)
{
KdPrint(("卸载驱动成功\n"));
}
NTSTATUS
DriverEntry(PDRIVER_OBJECT pDriverObject
, PUNICODE_STRING reg_path
)
{
NTSTATUS ntres
;
KdPrint(("驱动加载成功\n"));
HANDLE hPid
= PsGetCurrentProcessId();
KdPrint(("当前进程id:%d\n",(int)hPid
));
UNICODE_STRING strDest
;
strDest
.Length
= 0;
strDest
.MaximumLength
= sizeof(WCHAR
) * 1024;
strDest
.Buffer
= (PWCH
)ExAllocatePoolWithTag(PagedPool
, sizeof(WCHAR
)*1024, MEMTAG
);
if (!strDest
.Buffer
)
{
return STATUS_INSUFFICIENT_RESOURCES
;
}
UNICODE_STRING strSource
;
RtlInitUnicodeString(&strSource
, L
"测试字符串连接");
KdPrint(("source is %wZ字节长度%d 最大长度%d.\n", &strSource
, strSource
.Length
, strSource
.MaximumLength
));
RtlCopyUnicodeString(&strDest
,&strSource
);
KdPrint(("dest is %wZ 字节长度%d 最大长度%d.\n", strDest
, strDest
.Length
, strDest
.MaximumLength
));
UNICODE_STRING strTmp
;
RtlInitUnicodeString(&strTmp
, L
"this is a new string");
ntres
= RtlAppendUnicodeStringToString(&strDest
, &strTmp
);
if (NT_SUCCESS(ntres
))
{
}
else
{
KdPrint(("拼接失败"));
}
KdPrint(("打印 %wZ 字节长度%d 最大长度%d.\n", &strDest
, strDest
.Length
, strDest
.MaximumLength
));
UNICODE_STRING uCp1
, uCp2
;
RtlInitUnicodeString(&uCp1
, L
"hello a world.");
RtlInitUnicodeString(&uCp2
, L
"hello b world.");
LONG lRet
= RtlCompareUnicodeString(&uCp1
, &uCp2
, TRUE
);
if (lRet
> 0)
{
KdPrint(("%wZ 大于 %wZ .", &uCp1
, &uCp2
));
}
else if(lRet
< 0)
{
KdPrint(("%wZ 小于 %wZ .", &uCp1
, &uCp2
));
}
else
{
KdPrint(("%wZ 等于 %wZ .", &uCp1
, &uCp2
));
}
UNICODE_STRING uniTrans
;
RtlInitUnicodeString(&uniTrans
, L
"test unicode to ansi");
ANSI_STRING ansiTrans
;
RtlUnicodeStringToAnsiString(&ansiTrans
, &uniTrans
, TRUE
);
KdPrint(("%wZ to ansi is %Z", &uniTrans
, &ansiTrans
));
RtlAnsiStringToUnicodeString(&uniTrans
, &ansiTrans
, TRUE
);
KdPrint(("%Z to ansi is %wZ", &ansiTrans
, &uniTrans
));
if (strDest
.Buffer
!= NULL)
{
ExFreePool(strDest
.Buffer
);
strDest
.Length
= strDest
.MaximumLength
= 0;
}
pDriverObject
->DriverUnload
= DriverUnload
;
return STATUS_SUCCESS
;
}
8、测试结果