1.ASCII字符串和宽字符串
打印一个ASCII字符串:
CHAR* string = “Hello”;
KdPrint((“%s/n”, string)); //s为小写
打印一个宽字符字符串
WCHAR* string = L”Hello”;
KdPrint((“%S/n”,string)); //s为大写
2.ANSI_STRING字符串与UNICODE_STRING字符串
ANSI_STRING:
typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer;} ANSI_STRING *PANSI_STRING;
UNICODE_STRING:
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING *PUNICODE_STRING;
打印ANSI_STRING
ANSI_STRING ansiString;
//省略对ansiString的初始化
KdPrint((“%Z/n”,&ansiString)); //注意是大写的Z
打印UNICODE_STRING
UNICODE_STRING unicodeString;
//省略对unicodeString的初始化
KdPrint((“%wZ”,&unicodeString)); //注意是小写的w和大写的Z
3.字符串的初始化与销毁
(1)方法一是使用DDK提供的相应的函数。
初始化ANSI_STRING字符串:
VOID RtlInitAnsiString( IN OUT PANSI_STRING DestinationString, IN PCSZ SourceString );
初始化UNICODE_STRING字符串
VOID RtlInitUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
使用方法(以ANSI_STRING为例):
ANSI_STRING ansiString;
CHAR* string = “Hello”;
RtlInitAnsiString(&ansiString, string);
注意:
这种方法是将ANSI_STRING结构体中的Buffer指针等于string指针。
这种初始化的优点是操作简单,用完后不用清理内存。但是带来另外一个问题,如果修改string,同时会导致ansiString字符串发生变化。
(2)方法2是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。
示例代码:
#pragma INITCODE
VOID TestUnicodeString()
{
KdPrint(("1.利用DDK函数进行初始化UNICODE_STRING!/n"));
UNICODE_STRING ustrTest1;
WCHAR* wstring = L"Hello";
//用DDK宏进行初始化
RtlInitUnicodeString(&ustrTest1, wstring);
KdPrint(("%wZ", &ustrTest1));
KdPrint(("2.自己初始化UNICODE_STRING!/n"));
UNICODE_STRING ustring2 = {0};
//设置缓冲区大小
ustring2.MaximumLength = BUFFER_SIZE;
//申请内存
ustring2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
WCHAR* string2 = L"hello";
//两倍字符的长度
ustring2.Length = 2*wcslen(string2);
RtlCopyMemory(ustring2.Buffer, string2, ustring2.Length);
KdPrint(("%wZ", &ustring2));
//清理内存
ExFreePool(ustring2.Buffer);
ustring2.Buffer = NULL;
ustring2.Length = ustring2.MaximumLength = 0;
//RtlFreeUnicodeString(&ustring2);
}
对于最后一步清理内存,DDK给出了简化函数,分别是RtlFreeAnsiString和RtlFreeUnicodeString,这两个函数内部调用了ExFreePool去回收内存。
所以最后的三行代码也可替换成最后的一行注释代码。
4.字符串复制
ANSI_STRING字符串复制函数
VOID RtlCopyString( IN OUT PSTRING DestinationString, IN PSTRING SourceString OPTIONAL );
UNICODE_STRING字符串复制函数
VOID RtlCopyUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString );
示例代码:
#pragma INITCODE
void TestCopy()
{
//初始化string1
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"fuckzq");
//初始化string2
UNICODE_STRING string2;
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
string2.Length = string1.Length;
//开始复制
RtlCopyUnicodeString(&string2, &string1);
KdPrint(("%wZ/n", &string1));
KdPrint(("%wZ/n", &string2));
//销毁string2。
//注意:string1不用销毁
RtlFreeUnicodeString(&string2);
}
5.字符串比较
ANSI_STRING比较函数
LONG RtlCompareString( IN PSTRING String1, IN PSTRING String2, BOOLEAN CaseInSensitive //是否对大小写敏感 );
BOOLEAN RtlEqualString( IN PSTRING String1, IN PSTRING String2, IN BOOLEAN CaseInSensitive );
UNICODE_STRING比较函数
LONG RtlCompareUnicodeString( IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive );
BOOLEAN RtlEqualUnicodeString( IN CONST UNICODE_STRING *String1, IN CONST UNICODE_STRING *String2, IN BOOLEAN CaseInSensitive );
示例代码:
#pragma INITCODE
VOID TestCmpSting()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"fuckyouzq");
UNICODE_STRING string2;
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
RtlCopyUnicodeString(&string2, &string1);
if (RtlCompareUnicodeString(&string1, &string2, TRUE) == 0)
{
KdPrint(("1.相等/n"));
}
if (RtlEqualUnicodeString(&string1, &string2, TRUE))
{
KdPrint(("相等!/n"));
}
else
{
KdPrint(("不相等/n"));
}
}
6.字符串转化成大写
ANSI_STRING:
VOID RtlUpperString( IN OUT PSTRING DestinationString, IN PSTRING SourceString );
UNICODE_STRING:
NTSTATUS RtlUpcaseUnicodeString( IN OUT PUNICODE_STRING DestinationString OPTIONAL, IN PCUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString //是否为目的字符串分配内存 );
注意:DDK虽然提供了转化成大写的函数,但是却没有提供转化为小写的函数。
示例代码:
#pragma INITCODE
VOID TestUpperString()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"Hello World");
KdPrint(("%wZ/n",&string1));
UNICODE_STRING string2;
//RtlUpcaseUnicodeString最后一个参数为TRUE,表示为目标字符串分配内存,因此我们不需要手动分配了。
RtlUpcaseUnicodeString(&string2, &string1, TRUE);
KdPrint(("%wZ/n", &string2));
//目标字符串和源字符串可以是同一个字符串
RtlUpcaseUnicodeString(&string1, &string1, FALSE);
KdPrint(("%wZ/n",&string1));
RtlFreeUnicodeString(string2);
}
7.字符串与整形数字相互转换
将UNICODE_STRING字符串转换成整数
NTSTATUS RtlUnicodeStringToInteger( IN PUNICODE_STRING String, //字符串 IN ULONG Base OPTIONAL, //转换的数的进制 OUT PULONG Value //转换后的数字 );
将整数转换成UNICODE_STRING
NTSTATUS RtlIntegerToUnicodeString( IN ULONG Value, IN ULONG Base OPTIONAL, IN OUT PUNICODE_STRING String );
示例代码:
VOID TestStringToInt()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"-100");
ULONG i;
NTSTATUS status = RtlUnicodeStringToInteger(&string1, 10, &i);
if (!NT_SUCCESS(status))
{
KdPrint(("转换失败!/n"));
}
else
{
KdPrint(("%d", i));
}
UNICODE_STRING string2 = {0};
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
status = RtlIntegerToUnicodeString(200, 10, &string2);
if (!NT_SUCCESS(status))
{
KdPrint(("转换失败!/n"));
}
else
{
KdPrint(("%wZ/n", &string2));
}
RtlFreeUnicodeString(&string2);
}
8.ANSI_STRING 和 UNICODE_STRING字符串相互转换
UNICODE_STRING转换为ANSI_STRING字符串
NTSTATUS RtlUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString );
ANSI_STRING 转为 UNICODE_STRING 字符串
NTSTATUS RtlAnsiStringToUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString );
示例代码:
#pragma INITCODE
VOID TestStringToString()
{
UNICODE_STRING unicodeString;
RtlInitUnicodeString(&unicodeString, L"fuckyou!/n");
ANSI_STRING ansiString;
NTSTATUS status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); //为ansiString分配内存
if(NT_SUCCESS(status))
{
KdPrint(("%Z",&ansiString));
}
//销毁ansiString
RtlFreeAnsiString(&ansiString);
}
更多驱动编程文章 http://mzf2008.blog.163.com/blog/static/3559978620101112115510592/