UNICEODE_STRING
1、数据结构
两数一针:无符号短整数 + 宽字符串指针
Length和MaximumLength 成员需手动设置!!!
UNICEODE_STRING变量定义后,Length、MaximumLength、Buffer成员均为随机值,最好立即初始化为0:RtlZeroMemory();
2、UNICEODE_STRING初始化
(1)RTL_CONSTANT_STRING宏
#include <ntdef.h>
UNICODE_STRING str = RTL_CONSTANT_STRING(L“my first string!”);
(2)RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
dst的buffer将指向src,dst的length和max length成员将初始化为src的length;
若src是NULL,length为0.
UNICODE_STRING dst;
RtlInitUnicodeString(&dst, L”my first string!”);
(3)RtlInitEmptyUnicodeString
Length = 0,MaximumLength = BufferSize,Buffer = SourceString
UNICODE_STRING dst; // 目标字符串
WCHAR dst_buf[256]; // 定义缓冲区
RtlInitEmptyUnicodeString(&dst, dst_buf, 256 * sizeof(WCHAR));
UNICODE_STRING src = RTL_CONSTANT_STRING(L”My source string!”);
RtlCopyUnicodeString(&dst,&src); // 字符串拷贝!
(4)动态分配内存 ExAllocatePoolWithTag
UNICODE_STRING ustr;
ustr.Length= 0;
ustr.MaximumLength = 256;
ustr.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,256,MEM_TAG); //MEM_TAG为自定义
RtlZeroMemory(ustr.Buffer, 256);
......
if (ustr.Buffer)
{
ExFreePoolWithTag(ustr.Buffer, MEM_TAG);
}
typedef WCHAR *PWCHAR;
typedef _Null_terminated_ WCHAR *PWSTR;
3、UNICEODE_STRING指针初始化
PUNICODE_STRING pStr;
pStr = ExAllocatePoolWithTag(NonPagedPool, 50, MEM_TAG); //MEM_TAG为自定义
RtlZeroMemory(pStr, 50);
pStr.Length = 0;
pStr.MaximumLength = 50 - sizeof(UNICEODE_STRIN) ; // 减去:(两个USHORT + 一个指针 = 8字节)
pStr.Buffer = (WCHAR*)( (UCHAR*)pStr + sizeof(UNICEODE_STRIN)) ;
4、字符串连接
(1)连接两个UNICODE_STRING
NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination, IN PUNICODE_STRING Source);
(2)将WCHAR字符串串接到UNICODE_STRING之后
NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination, IN PCWSTR Source);
5、字符串编码转换
NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString );
NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
IN PANSI_STRING SourceString,
IN BOOLEAN AllocateDestinationString );
UNICODE_STRING src;
ANSI_STRING dst;
RtlInitUnicodeString(&src,L”打印汉字”);
RtlUnicodeStringToAnsiString(&dst,&src,TRUE);
DbgPrint(“%Z”,&dst);
RtlFreeAnsiString(&dst);
6、字符串大小写转换
VOID RtlUpperString( IN OUT PSTRING DestinationString,
IN PSTRING SourceString ); // ANSI_STRING
NTSTATUS RtlDowncaseUnicodeString( OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString ); // UNICODE_STRING
NTSTATUS RtlUpcaseUnicodeString( IN OUT PUNICODE_STRING DestinationString,
IN PCUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString ); // UNICODE_STRING
7、字符串比较
LONG RtlCompareString( IN PSTRING String1,
IN PSTRING String2,
BOOLEAN CaseInSensitive ); // ANSI_STRING
LONG RtlCompareUnicodeString( IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive ); // UNICODE_STRING
BOOLEAN RtlEqualString( IN PSTRING String1,
IN PSTRING String2,
IN BOOLEAN CaseInSensitive ); // ANSI_STRING
BOOLEAN RtlEqualUnicodeString( IN CONST UNICODE_STRING *String1,
IN CONST UNICODE_STRING *String2,
IN BOOLEAN CaseInSensitive ); // UNICODE_STRING
BOOLEAN RtlPrefixUnicodeString( IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive );
SIZE_T RtlCompareMemory( IN CONST VOID *Source1,
IN CONST VOID *Source2,
IN SIZE_T Length );
8、字符串拷贝
VOID RtlCopyString( IN OUT PSTRING DestinationString,
IN PSTRING SourceString OPTIONAL ); // ANSI_STRING
VOID RtlCopyUnicodeString( IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString ); // UNICODE_STRING
9、字符串的内存释放
VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString);
releases storage that was allocated by RtlUnicodeStringToAnsiString。
VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString);
releases storage that was allocated by RtlAnsiStringToUnicodeString or RtlUpcaseUnicodeString or RtlDowncaseUnicodeString.
10、字符串与整数
NTSTATUS RtlUnicodeStringToInteger( IN PUNICODE_STRING String,
IN ULONG Base OPTIONAL,
OUT PULONG Value );
NTSTATUS RtlIntegerToUnicodeString( IN ULONG Value,
IN ULONG Base OPTIONAL,
IN OUT PUNICODE_STRING String );
11、字符串大小写转换
WCHAR RtlUpcaseUnicodeChar(
IN WCHAR SourceCharacter
);
IRQL: <=APC_LEVEL
NTSTATUS RtlUpcaseUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PCUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
IRQL: <=APC_LEVEL
WCHAR RtlDowncaseUnicodeChar(
IN WCHAR SourceCharacter
);
IRQL: PASSIVE_LEVEL
NTSTATUS RtlDowncaseUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
IRQL: <DISPATCH_LEVEL
自定义实现的安全性???
WCHAR fcDowncaseUnicodeChar(WCHAR srcChar)
{
if (srcChar >= 65 && srcChar <= 90)
{
return (srcChar + 32);
}
return srcChar;
}
WCHAR fcUppercaseUnicodeChar(WCHAR srcChar)
{
if (srcChar >= 97 && srcChar <= 122)
{
return (srcChar - 32);
}
return srcChar;
}
PUNICODE_STRING fcDowncaseUnicodeString(PUNICODE_STRING src_str)
{
size_t i = 0;
size_t wcharNum = 0;
if (NULL != src_str && NULL != src_str->Buffer)
{
wcharNum = src_str->Length / 2;
for (; i < wcharNum; i++)
{
src_str->Buffer[i] = fcDowncaseUnicodeChar(src_str->Buffer[i]);
}
}
return src_str;
}
PUNICODE_STRING fcUppercaseUnicodeString(PUNICODE_STRING src_str)
{
size_t i = 0;
size_t wcharNum = 0;
if (NULL != src_str && NULL != src_str->Buffer)
{
wcharNum = src_str->Length / 2;
for (; i < wcharNum; i++)
{
src_str->Buffer[i] = fcUppercaseUnicodeChar(src_str->Buffer[i]);
}
}
return src_str;
}