• windows内核函数1


     

    1.ASCII字符串和宽字符串

    打印一个ASCII字符串:

    CHAR* string = “Hello”;

    KdPrint((“%s ”, string));        //s为小写

     

    打印一个宽字符字符串

    WCHAR* string = L”Hello”;

    KdPrint((“%S ”,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 ”,&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! "));

             UNICODE_STRING ustrTest1;

             WCHAR* wstring = L"Hello";

             //用DDK宏进行初始化

             RtlInitUnicodeString(&ustrTest1, wstring);

             KdPrint(("%wZ", &ustrTest1));

     

             KdPrint(("2.自己初始化UNICODE_STRING! "));

             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 ", &string1));

        KdPrint(("%wZ ", &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.相等 "));

        }

       

        if (RtlEqualUnicodeString(&string1, &string2, TRUE))

        {

            KdPrint(("相等! "));

        }

        else

        {

            KdPrint(("不相等 "));

        }

    }

     

     

    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 ",&string1));

     

        UNICODE_STRING string2;

        //RtlUpcaseUnicodeString最后一个参数为TRUE,表示为目标字符串分配内存,因此我们不需要手动分配了。

        RtlUpcaseUnicodeString(&string2, &string1, TRUE);

        KdPrint(("%wZ ", &string2));

     

        //目标字符串和源字符串可以是同一个字符串

        RtlUpcaseUnicodeString(&string1, &string1, FALSE);

        KdPrint(("%wZ ",&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(("转换失败! "));

        }

        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(("转换失败! "));

        }

        else

        {

            KdPrint(("%wZ ", &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! ");

     

        ANSI_STRING ansiString;

        NTSTATUS status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); //为ansiString分配内存

       

        if(NT_SUCCESS(status))

     {

            KdPrint(("%Z",&ansiString));

        }

    //销毁ansiString

     RtlFreeAnsiString(&ansiString);

    }

  • 相关阅读:
    CODEVS 3137 栈练习1
    CODEVS 3138 栈练习2
    线段树———模板
    深度优先搜索与广度优先搜索———模板
    犯罪团伙 codevs 3554
    嘟!数字三角形 W WW WWW集合!
    寻找子串位置 codevs 1204
    流输入练习——寻找Sb.VI codevs 3096
    C++之路进阶——codevs3287(货车运输)
    c++之路进阶——codevs4543(普通平衡树)
  • 原文地址:https://www.cnblogs.com/mayingkun/p/3860844.html
Copyright © 2020-2023  润新知