Windows內核下操做字符串!

 
 
 

*
  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;
} 
相關文章
相關標籤/搜索