前言:为什么字符串在驱动里是“危险操作”
在用户态,操作字符串随便乱写基本不会让程序直接崩溃;
但在内核态:写错直接蓝屏!
字符串初始化
typedefstruct_UNICODE_STRING{USHORT Length;// 当前使用的字节数(注意是字节,不是字符)USHORT MaximumLength;// Buffer 最大可使用的字节数PWSTR Buffer;// 指向 wchar_t 字符数组(UTF-16)}UNICODE_STRING,*PUNICODE_STRING;typedefstruct_ANSI_STRING{USHORT Length;USHORT MaximumLength;PCHAR Buffer;}ANSI_STRING,*PANSI_STRING;// ===========================// UNICODE_STRING 示例// ===========================// RtlInitUnicodeString 只是初始化结构,不会分配内存或拷贝字符串UNICODE_STRING uStr1;RtlInitUnicodeString(&uStr1,L"unicode_string!");// 注意:Length 单位是“字节”,不是字符个数DbgPrint("(mydriver) Unicode.Length = %d, Buffer = %wZ\n",uStr1.Length,&uStr1);// ===========================// ANSI_STRING 示例// ===========================// 同理,RtlInitAnsiString 也不会分配内存ANSI_STRING aStr1;RtlInitAnsiString(&aStr1,"ansi_string!");// %Z 打印 ANSI_STRING,%wZ 打印 UNICODE_STRINGDbgPrint("(mydriver) Ansi.Length = %d, Buffer = %Z\n",aStr1.Length,&aStr1);拷贝字符串
// =============================================// 示例:Unicode 与 ANSI 字符串拷贝// =============================================// 1. 定义源字符串UNICODE_STRING uStrSrc;ANSI_STRING aStrSrc;RtlInitUnicodeString(&uStrSrc,L"unicode_string_test");RtlInitAnsiString(&aStrSrc,"ansi_string_test");// 2. 定义目标字符串缓冲区(必须自己提供内存)WCHAR uniBuffer[64];// 64 WCHAR = 128 字节CHAR ansiBuffer[64];// 64 CHARUNICODE_STRING uStrDst;ANSI_STRING aStrDst;// 3. 初始化“空字符串结构体”// 这一步会:// - Length = 0// - MaximumLength = sizeof(buffer)// - Buffer = buffer 指针RtlInitEmptyUnicodeString(&uStrDst,uniBuffer,sizeof(uniBuffer));RtlInitEmptyAnsiString(&aStrDst,ansiBuffer,sizeof(ansiBuffer));// 4. 执行字符串拷贝// 注意:这两个函数不做边界检查,如果源字符串比目标大 → 蓝屏RtlCopyUnicodeString(&uStrDst,&uStrSrc);RtlCopyString(&aStrDst,&aStrSrc);// 输出结果DbgPrint("(mydriver) ------- 字符串拷贝示例 -------\n");DbgPrint("(mydriver) Unicode Length = %d, MaximumLength = %d, Buffer = %wZ\n",uStrDst.Length,uStrDst.MaximumLength,&uStrDst);DbgPrint("(mydriver) ANSI Length = %d, MaximumLength = %d, Buffer = %Z\n",aStrDst.Length,aStrDst.MaximumLength,&aStrDst);字符串比较
// =============================================// 示例:Unicode 与 ANSI 字符串比较// =============================================// 1. 初始化 Unicode 字符串UNICODE_STRING uStr1;UNICODE_STRING uStr2;// RtlInitUnicodeString 仅初始化结构体,不分配内存RtlInitUnicodeString(&uStr1,L"Unicode_Test");RtlInitUnicodeString(&uStr2,L"unicode_test");// 2. 初始化 ANSI 字符串ANSI_STRING aStr1;ANSI_STRING aStr2;RtlInitAnsiString(&aStr1,"Ansi_Test");RtlInitAnsiString(&aStr2,"ansi_test");// ---------------------------------------------// Unicode 字符串比较// ---------------------------------------------if(RtlCompareUnicodeString(&uStr1,&uStr2,TRUE// 第三个参数:// TRUE = 大小写不敏感比较(忽略大小写)// FALSE = 大小写敏感比较)==0// 返回值 == 0 表示两个字符串完全相等){DbgPrint("(mydriver) uStr1 == uStr2 (Unicode比较)\n");}else{DbgPrint("(mydriver) uStr1 != uStr2 (Unicode比较)\n");}// ---------------------------------------------// ANSI 字符串比较// ---------------------------------------------if(RtlCompareString(&aStr1,&aStr2,TRUE// 第三个参数:// TRUE = 大小写不敏感比较// FALSE = 大小写敏感比较)==0// 返回值 == 0 表示两个字符串完全相等){DbgPrint("(mydriver) aStr1 == aStr2 (ANSI比较)\n");}else{DbgPrint("(mydriver) aStr1 != aStr2 (ANSI比较)\n");}Unicode ↔ ANSI,相互转换
// =============================================// 示例:UNICODE_STRING 与 ANSI_STRING 相互转换// =============================================// 1. 准备源字符串UNICODE_STRING uStrSrc;ANSI_STRING aStrSrc;RtlInitUnicodeString(&uStrSrc,L"Unicode_String_Test");RtlInitAnsiString(&aStrSrc,"Ansi_String_Test");// 2. 定义目标字符串(注意:此时不需要自己分配 Buffer)UNICODE_STRING uStrDst;ANSI_STRING aStrDst;// ---------------------------------------------// Unicode → ANSI// ---------------------------------------------//// 第三个参数说明:// TRUE :由系统分配目标字符串的 Buffer// 转换成功后,必须调用 RtlFreeAnsiString 释放// FALSE :调用者自己提供 Buffer(必须提前初始化 ANSI_STRING)//RtlUnicodeStringToAnsiString(&aStrDst,&uStrSrc,TRUE// 由系统分配内存);// ---------------------------------------------// ANSI → Unicode// ---------------------------------------------RtlAnsiStringToUnicodeString(&uStrDst,&aStrSrc,TRUE// 由系统分配内存);// 输出转换结果DbgPrint("(mydriver) -------- 字符串转换 --------\n");DbgPrint("(mydriver) Unicode Length = %hu, Buffer = %wZ\n",uStrDst.Length,&uStrDst);DbgPrint("(mydriver) ANSI Length = %hu, Buffer = %Z\n",aStrDst.Length,&aStrDst);// 3. 释放由系统分配的字符串 BufferRtlFreeUnicodeString(&uStrDst);RtlFreeAnsiString(&aStrDst);