* Windows內核下操做字符串! */ #include <ntddk.h> #include <ntstrsafe.h> #define BUFFER_SIZE 1024 VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) { KdPrint(("DriverUnload Load...\n")); } //=========================================================================== // ANSI_STRING結構和UNICODE_STRING結構的使用 #pragma code_seg("INIT") NTSTATUS StringTest(VOID) { ANSI_STRING AStString = { 0 }; UNICODE_STRING UStString2 = { 0 }; UNICODE_STRING UStString3 = RTL_CONSTANT_STRING(L"Initialization string directly!"); CHAR *SzHello = "hello"; WCHAR *WSzHello = L"hello"; // 初始化ANSI_STRING字符串的作法 RtlInitAnsiString(&AStString, SzHello); // %Z打印ANSI的結構字符串 KdPrint(("StringTest->ANSI_STRING: %Z\n", &AStString)); SzHello[0] = 'H'; SzHello[1] = 'E'; SzHello[2] = 'L'; SzHello[3] = 'L'; SzHello[4] = 'O'; SzHello[5] = '\0'; // 改變SzHello, 結構也會發生改變, ANSI_STRING裏面擁有的只是指針 KdPrint(("ANSI_STRING: %Z\n", &AStString)); // 手工初始化字符串 UStString2.MaximumLength = BUFFER_SIZE; // 最大緩衝區 // 分配內存, 在分頁內存中 UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE); // 設置字符長度,由於是寬字符,因此是字符長度的2倍 UStString2.Length = 2 * wcslen(WSzHello); // 保證緩衝區足夠大, 不然程序終止 ASSERT(UStString2.MaximumLength >= UStString2.Length); // 內存COPY, Copy的長度就是Unicode字符串的長度 RtlCopyMemory(UStString2.Buffer, WSzHello, UStString2.Length); // 打印UnicodeString的方法%wZ KdPrint(("StringTest->UStString2:%wZ\n", &UStString2)); KdPrint(("StringTest->UStString3:%wZ\n", &UStString3)); // 清理內存 ExFreePool(UStString2.Buffer); UStString2.Buffer = NULL; UStString2.Length = UStString2.MaximumLength = 0; return STATUS_SUCCESS; } //=========================================================================== // 字符串測試2, 字符串之間的Copy #pragma code_seg("INIT") NTSTATUS StringCopyTest(VOID) { UNICODE_STRING UStString1 = { 0 }; UNICODE_STRING UStString2 = { 0 }; // RtlInitUnicodeString不用釋放 RtlInitUnicodeString(&UStString1, L"Hello World"); // 這樣也是能夠初始化的, 不過要記得釋放 UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE); // Copy字符串以前必須先填寫最大長度 UStString2.MaximumLength = BUFFER_SIZE; // 將初始化UStString2拷貝到UStString1 RtlCopyUnicodeString(&UStString2, &UStString1); // 分別顯示UnicodeString1和UnicodeString2 KdPrint(("StringCopyTest->UnicodeString1:%wZ!\n", &UStString1)); KdPrint(("StringCopyTest->UnicodeString2:%wZ!\n", &UStString2)); // 字符串的鏈接 RtlUnicodeStringCatUnicodeString(&UStString2, &UStString1); KdPrint(("StringCopyTest->UnicodeString2:%wZ!\n", &UStString2)); // 銷燬UnicodeString2 注意!!UnicodeString1不用銷燬 RtlFreeUnicodeString(&UStString2); return STATUS_SUCCESS; } //=========================================================================== // 字符串的比較試驗 #pragma code_seg("INIT") VOID StringCompareTest(VOID) { LONG dwFlags; UNICODE_STRING UStString1; UNICODE_STRING UStString2; RtlInitUnicodeString(&UStString1, L"Hello World"); RtlInitUnicodeString(&UStString2, L"Hello WorlD"); // 比較字符串, 區分大小寫(FALSE), 相等返回True if (RtlEqualUnicodeString(&UStString1, &UStString2, FALSE)) { KdPrint(("StringCompareTest->UStString1 and UStString2 are equal\n")); } else { KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal\n")); } // 比較字符串, 不區分大小寫(TRUE), 相等返回TRUE RtlInitUnicodeString(&UStString2, L"Hello World"); if (RtlEqualUnicodeString(&UStString1, &UStString2, FALSE)) { KdPrint(("StringCompareTest->UStString1 and UStString2 are equal\n")); } else { KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal\n")); } // 比較字符串, 不區分大小寫(TRUE), 相等返回TRUE RtlInitUnicodeString(&UStString2, L"Hello"); if (RtlEqualUnicodeString(&UStString1, &UStString2, TRUE)) { KdPrint(("StringCompareTest->UStString1 and UStString2 are equal\n")); } else { KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal\n")); } // 比較字符串大小, 不區分大小寫(TRUE) dwFlags = RtlCompareUnicodeString(&UStString1, &UStString2, TRUE); if (dwFlags == 0) { KdPrint(("StringCompareTest->UStString1 == UStString2\n")); } else if(dwFlags > 0) { KdPrint(("StringCompareTest->UStString1 > UStString2\n")); } else { KdPrint(("StringCompareTest->UStString1 < UStString2\n")); } } //=========================================================================== // 字符串轉整數型試驗 #pragma code_seg("INIT") VOID StringToIntegerTest(VOID) { ULONG uValue; NTSTATUS nStatus; UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"-100"); UNICODE_STRING UStString2={ 0 }; // 轉換正常的十進制數字 nStatus = RtlUnicodeStringToInteger(&UStString1, 10, &uValue); if (NT_SUCCESS(nStatus)) { KdPrint(("StringToIntegerTest->Conver to integer succussfully!\n")); KdPrint(("Result:%d\n", uValue)); } else { KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!\n")); } // 轉換16進制數據 RtlInitUnicodeString(&UStString1, L"100"); nStatus = RtlUnicodeStringToInteger(&UStString1, 16, &uValue); if (NT_SUCCESS(nStatus)) { KdPrint(("StringToIntegerTest->Conver to integer succussfully!")); KdPrint(("Result:%u 0x%X \n", uValue,uValue)); } else { KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!\n")); } // 數字轉換成字符串, 初始化UnicodeString2 UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE); UStString2.MaximumLength = BUFFER_SIZE; nStatus = RtlIntegerToUnicodeString(200, 10, &UStString2); if (NT_SUCCESS(nStatus)) { KdPrint(("StringToIntegerTest->Conver to string succussfully!")); KdPrint(("Result:%wZ\n", &UStString2)); } else { KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!\n")); } // 16進制數字轉字符串 nStatus = RtlIntegerToUnicodeString(300, 16, &UStString2); if (NT_SUCCESS(nStatus)) { KdPrint(("StringToIntegerTest->Conver to string succussfully!")); KdPrint(("Result:%wZ\n", &UStString2)); } else { KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!\n")); } // UStString2, 注意!!UStString1不用銷燬 RtlFreeUnicodeString(&UStString2); } //=========================================================================== // 字符串變大寫實驗 #pragma code_seg("INIT") VOID StringToUpperTest(VOID) { UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"Hello World"); // 變化前 KdPrint(("StringToUpperTest->UnicodeString1:%wZ\n", &UStString1)); // 變大寫 RtlUpcaseUnicodeString(&UStString1, &UStString1, FALSE); // 變化後 KdPrint(("StringToUpperTest->UnicodeString1:%wZ\n", &UStString1)); } //=========================================================================== // ANSI_STRING字符串和UNICODE_STRING之間的轉換 #pragma code_seg("INIT") VOID StringConverTest(VOID) { ANSI_STRING StString1 = { 0 }; UNICODE_STRING UStString2 = { 0 }; ANSI_STRING StString2 = RTL_CONSTANT_STRING("Hello World"); UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"Hello World"); // (1)將UNICODE_STRING字符串轉換成ANSI_STRING字符串 NTSTATUS nStatus = RtlUnicodeStringToAnsiString(&StString1, &UStString1, TRUE); if (NT_SUCCESS(nStatus)) { KdPrint(("Conver succussfully!")); KdPrint(("Result:%Z\n",&StString1)); } else { KdPrint(("Conver unsuccessfully!\n")); } // 銷燬AnsiString1 RtlFreeAnsiString(&StString1); // (2)將ANSI_STRING字符串轉換成UNICODE_STRING字符串初始化AnsiString2 nStatus = RtlAnsiStringToUnicodeString(&UStString2, &StString2, TRUE); if (NT_SUCCESS(nStatus)) { KdPrint(("Conver succussfully!\n")); KdPrint(("Result:%wZ\n",&UStString2)); } else { KdPrint(("Conver unsuccessfully!\n")); } // 銷燬UnicodeString2 RtlFreeUnicodeString(&UStString2); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg) { pDriverObj->DriverUnload = DriverUnload; StringTest(); // 字符串初始化試驗 StringCopyTest(); // 字符串Copy試驗 StringCompareTest(); // 字符串的比較試驗 StringToIntegerTest(); // 字符串轉整數型試驗 StringToUpperTest(); // 字符串變大寫實驗 StringConverTest(); // ANSI和UNICODE之間的轉換 return STATUS_SUCCESS; }