2014年7月11日星期五

内核中的通配符和字符匹配

#include <ntifs.h>
#include <windef.h>


/*
FsRtlIsNameInExpression的用法规则:
1.If IgnoreCase is TRUE, Expression must be uppercase.
  如果忽略大小写(第三个参数),第一个参数必须是大写的。
2.If this value is not supplied, the default system uppercase character table is used.
  如果第四个参数为0,那(第一个参数)必须是大写的。
3.If only one of the string parameters has a length of zero, FsRtlIsNameInExpression returns FALSE. 
  This means that "*" does not match a null string. 
  如果有一个参数是0,返回失败。
4.If both parameters are null strings, FsRtlIsNameInExpression returns TRUE.
  如果都是0,返回匹配。

Wildcard character Meaning 
* (asterisk)       Matches zero or more characters. 
? (question mark)  Matches a single character. 
DOS_DOT            Matches either a period or zero characters beyond the name string. 
DOS_QM             Matches any single character or, upon encountering a period or end of name string, advances the expression to the end of the set of contiguous DOS_QMs. 
DOS_STAR           Matches zero or more characters until encountering and matching the final . in the name. 

DOS_QM和DOS_STAR是啥东西呢?

#define DOS_STAR        (L'<')
#define DOS_QM          (L'>')
#define DOS_DOT         (L'"') //dot也就是L".",为何定义这呢?不过看源码,它也处理了L"."
摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntioapi.h

但是另一个文档的说明如下:
~* is DOS_STAR, ~? is DOS_QM, and ~. is DOS_DOT
摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\base\ntos\fsrtl\name.c

前后不符。

综上所述:DOS_QM和DOS_STAR,DOS_DOT是处理DOS路径的(个人理解)。

参考资料:MSDN和WRK。

多字符的FsRtlIsDbcsInExpression与此类似。

不说了,能用则已,简单的几个,不够用的时候在仔细看。
  
made by correy
made at 2014.07.11
homepage:http://correy.webs.com
*/


BOOLEAN RtlIsNameInExpression(IN UNICODE_STRING * Expression, IN UNICODE_STRING * Name)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    UNICODE_STRING  DestinationString;
    BOOLEAN B;

    if (Expression == 0 || Name == 0)
    {
        return FALSE ;
    }

    status = RtlUpcaseUnicodeString(&DestinationString, Expression, TRUE);
    if (!NT_SUCCESS( status )) 
    {
        return FALSE ;
    }

    B = FsRtlIsNameInExpression(&DestinationString, Name, TRUE, 0);

    RtlFreeUnicodeString(&DestinationString);

    return B;
}


DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL; 
    UNICODE_STRING Expression1 = RTL_CONSTANT_STRING(L"co*ey");
    UNICODE_STRING Expression2 = RTL_CONSTANT_STRING(L"cor?ey");
    UNICODE_STRING Name  = RTL_CONSTANT_STRING(L"correy");
    UNICODE_STRING Name2  = RTL_CONSTANT_STRING(L"coeyrr");
    
    KdBreakPoint();

    if (RtlIsNameInExpression(&Expression1, &Name))
    {
        KdPrint(("匹配\n"));
    }
    else
    {
        KdPrint(("不匹配\n"));
    }

    if (RtlIsNameInExpression(&Expression2, &Name))
    {
        KdPrint(("匹配\n"));
    }
    else
    {
        KdPrint(("不匹配\n"));
    }    

    //以上都因该匹配。
    /////////////////////////////////////////////////////
    //以下都应该不匹配。

    if (RtlIsNameInExpression(&Expression1, &Name2))
    {
        KdPrint(("匹配\n"));
    }
    else
    {
        KdPrint(("不匹配\n"));
    }

    if (RtlIsNameInExpression(&Expression2, &Name2))
    {
        KdPrint(("匹配\n"));
    }
    else
    {
        KdPrint(("不匹配\n"));
    }    

    return status;//STATUS_SUCCESS
} 

----------------------------------------------------------------------------------------------

/*
通配符的测试。

The following are wildcard characters: *, ?, ANSI_DOS_STAR, ANSI_DOS_DOT, and ANSI_DOS_QM.

FsRtlDoesNameContainWildCards 是个函数,调用FsRtlIsUnicodeCharacterWild实现的。
FsRtlIsUnicodeCharacterWild 是个宏
FsRtlIsAnsiCharacterWild 是个宏

made by correy
made at 2015.03.04

#define DOS_STAR        (L'<')
#define DOS_QM          (L'>')
#define DOS_DOT         (L'"') //dot也就是L".",为何定义这呢?不过看源码,它也处理了L"."
摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntioapi.h

但是另一个文档的说明如下:
~* is DOS_STAR, ~? is DOS_QM, and ~. is DOS_DOT
摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\base\ntos\fsrtl\name.c
经测试:这个是不正确的,不可信的。

其实:
#define ANSI_DOS_STAR   ('<') 但是这代表啥意思的呢?还没有测试。
#define ANSI_DOS_QM     ('>')
#define ANSI_DOS_DOT    ('"')

#define DOS_STAR        (L'<')
#define DOS_QM          (L'>')
#define DOS_DOT         (L'"')
这些都定义在ntifs.h中的。
*/

#include <ntifs.h>
//#include <ntddk.h> //这两个次序不能乱,有上面的,这个可以注释掉。

#pragma INITCODE
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    BOOLEAN B = FALSE;

    UNICODE_STRING test1 = RTL_CONSTANT_STRING(L"*");
    UNICODE_STRING test2 = RTL_CONSTANT_STRING(L"a*");
    UNICODE_STRING test3 = RTL_CONSTANT_STRING(L"*a");
    UNICODE_STRING test4 = RTL_CONSTANT_STRING(L"*a*");

    UNICODE_STRING test5 = RTL_CONSTANT_STRING(L"?");
    UNICODE_STRING test6 = RTL_CONSTANT_STRING(L"a?");
    UNICODE_STRING test7 = RTL_CONSTANT_STRING(L"?a");
    UNICODE_STRING test8 = RTL_CONSTANT_STRING(L"?a?");

    UNICODE_STRING test9 = RTL_CONSTANT_STRING(L"test");

    UNICODE_STRING test10 = RTL_CONSTANT_STRING(L"<");
    UNICODE_STRING test11 = RTL_CONSTANT_STRING(L">");
    UNICODE_STRING test12 = RTL_CONSTANT_STRING(L"\"");
    UNICODE_STRING test13 = RTL_CONSTANT_STRING(L".");

    //混合的就不测试了,因为单个的测试了,混合的必定可以的。

    KdBreakPoint();
      
    B = FsRtlDoesNameContainWildCards(&test1);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test1));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test1));
    }

    B = FsRtlDoesNameContainWildCards(&test2);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test2));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test2));
    }

    B = FsRtlDoesNameContainWildCards(&test3);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test3));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test3));
    }

    B = FsRtlDoesNameContainWildCards(&test4);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test4));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test4));
    }

    B = FsRtlDoesNameContainWildCards(&test5);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test5));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test5));
    }

    B = FsRtlDoesNameContainWildCards(&test6);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test6));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test6));
    }

    B = FsRtlDoesNameContainWildCards(&test7);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test7));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test7));
    }

    B = FsRtlDoesNameContainWildCards(&test8);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test8));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test8));
    }

    B = FsRtlDoesNameContainWildCards(&test9);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test9));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test9));
    }

    B = FsRtlDoesNameContainWildCards(&test10);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test10));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test10));
    }

    B = FsRtlDoesNameContainWildCards(&test11);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test11));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test11));
    }

    B = FsRtlDoesNameContainWildCards(&test12);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test12));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test12));
    }

    B = FsRtlDoesNameContainWildCards(&test13);
    if (B) {
        KdPrint(("%wZ contains wildcard characters!\n", &test13));
    } else {
        KdPrint(("%wZ not contains wildcard characters!\n", &test13));
    }
      
    return status;//STATUS_SUCCESS
}


/*
测试结果如下:
1: kd> g
* contains wildcard characters!
a* contains wildcard characters!
*a contains wildcard characters!
*a* contains wildcard characters!
? contains wildcard characters!
a? contains wildcard characters!
?a contains wildcard characters!
?a? contains wildcard characters!
test not contains wildcard characters!
< contains wildcard characters!
> contains wildcard characters!
" contains wildcard characters!
. not contains wildcard characters!
*/

没有评论:

发表评论