Windows内核函数(1) - 字符串处理函数

  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是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。
  示例代码:
  #pragmaINITCODE
  VOIDTestUnicodeString()
  {
  KdPrint(("1.利用DDK函数进行初始化UNICODE_STRING!\n"));
  UNICODE_STRINGustrTest1;
  WCHAR* wstring = L"Hello";
  //用DDK宏进行初始化
  RtlInitUnicodeString(&ustrTest1, wstring);
  KdPrint(("%wZ", &ustrTest1));
  KdPrint(("2.自己初始化UNICODE_STRING!\n"));
  UNICODE_STRINGustring2 = {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/3559978620 101112115510592/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值