⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namesup.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 3 页
字号:
         DebugTrace(( 0, Dbg,
                     "UdfCheckLegalCS0Dstring, NameLength not odd, encoding 0x10!\n" )))) {

        if (ReturnOnError) {

            DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> FALSE\n" ));

            return FALSE;
        }

        DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> raised status\n" ));

        UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
    }

    DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> TRUE\n" ));

    return TRUE;
}


VOID
UdfRenderNameToLegalUnicode (
    IN PIRP_CONTEXT IrpContext,
    IN PUNICODE_STRING Name,
    IN PUNICODE_STRING RenderedName
    )

/*++

Routine Description:

    This routine will take a Unicode string containing illegal characters and
    run it through the UDF standard algorithim to render it into a "legal"
    name.
    
    The short form is to convert all runs of illegal characters to "_" and tack
    on a hex representation of the CRC of the original name.  The algorithm is
    nearly directly lifted from the UDF (2.01 proposed!) standard, so apologies
    for the style clash.
    
Arguments:

    Name - the actual name
    
    RenderedName - the name rendered into legal characters
    
Return Value:

    BOOLEAN - TRUE if the expressions match, FALSE otherwise.

--*/

{
    INT16 index;
    INT16 targetIndex;
    INT16 crcIndex;
    INT16 extLen;
    INT16 nameLen;
    INT16 charLen;
    INT16 overlayBytes;
    INT16 bytesLeft;
    UNICODE_CHAR current;
    BOOLEAN needsCRC;
    BOOLEAN foundDot;
    UNICODE_CHAR ext[EXT_LEN];

    //
    //  So as to lift as directly as possible from the standard, chunk things around.
    //
 
    PWCHAR newName = RenderedName->Buffer;
    PWCHAR udfName = Name->Buffer;
    LONG udfNameLen = Name->Length / sizeof(WCHAR);

    /* Remove trailing periods ('.') and spaces (' '), Windows     */
    /* does not like them.                                         */
    foundDot = FALSE;
    index = udfNameLen;
    while (index-- > 0) {
        if (udfName[index] == PERIOD)
            foundDot = TRUE;
        else if (udfName[index] != SPACE)
            break;
    }

    /* If any trailing periods or spaces were found, a CRC code    */
    /* needs to be added to the resulting file name.               */
    nameLen = index + 1;
    if (nameLen < udfNameLen)
        needsCRC = TRUE;

    needsCRC = FALSE;
    bytesLeft = MAX_LEN;
    extLen = 0;

    if (needsCRC == FALSE || foundDot == FALSE) {
        /* Look for an extension in the file name.  We do not      */
        /* need to look for one if there were any trailing periods */
        /* removed.                                                */
        INT16 endIndex;
        INT16 prevCharLen = 1;
        INT16 extBytes = 0;

        targetIndex = 0;
        index = nameLen;

        /* Determine how many bytes we need to scan to find the    */
        /* extension delimiter.  The extension has a maximum of    */
        /* five characters, but we do not want to scan past the    */
        /* beginning of the buffer.                                */
        endIndex = (udfNameLen > EXT_LEN + 1) ?
            udfNameLen - EXT_LEN - 1 : 1;

        /* Start at the end of the name and scan backward, looking */
        /* for the extension delimiter (".").                      */
        while (index-- > endIndex) {
            /* Get the character to test.                          */
            current = udfName[index];

            if (current == '.') {
                /* The extension delimiter was found, figure out   */
                /* how many characters the extension contains and  */
                /* the length of the resulting file name without   */
                /* the extension.                                  */
                extLen = nameLen - index - 1;
                nameLen = index;
                break;
            }

            /* Determine the byte length of the current character  */
            /* when converted to native format.                    */
            charLen = (IsFileNameCharLegal(current)) ?
                NativeCharLength(current) : 0;

            if (charLen == 0) {
                /* If the character byte length is zero, it is     */
                /* illegal or unprintable, place an underscore     */
                /* ("_") in the extension buffer if the previous   */
                /* character tested was legal.  Not that the       */
                /* characters placed in the extension buffer are   */
                /* in reverse order.                               */
                if (prevCharLen != 0) {
                    ext[targetIndex++] = ILLEGAL_CHAR_MARK;
                    extBytes++;
                }
            }
            else {
                /* The current character is legal and printable,   */
                /* put it in the extension buffer.  Note that the  */
                /* characters placed in the extension buffer are   */
                /* in reverse order.                               */
                ext[targetIndex++] = current;
                extBytes += charLen;
            }

            /* Save the byte length of the current character, so   */
            /* we can determine if it was a legal character during */
            /* the next test.                                      */
            prevCharLen = charLen;
        }

        /* If an extension was found, determine how many bytes     */
        /* remain in the file name buffer once we account for it.  */
        if (extLen > 0)
            bytesLeft -= extBytes + 1;
    }

    index = 0;
    targetIndex = 0;
    crcIndex = 0;
    overlayBytes = -1;
    while (index < nameLen && bytesLeft > 0) {
        /* Get the current character and convert it to upper case. */
        current = udfName[index];

        /* Determine if this is a valid file name char and         */
        /* calculate its corresponding native character byte       */
        /* length (zero if the char is not legal or undiplayable   */
        /* on this system).                                        */
        charLen = (IsFileNameCharLegal(current)) ?
            NativeCharLength(current) : 0;

        /* If the char is larger than the available space in the   */
        /* buffer, pretend it is undisplayable.                    */
        if (charLen > bytesLeft)
            charLen = 0;

        if (charLen == 0) {
            /* Undisplayable or illegal characters are substituted */
            /* with an underscore ("_"), and requires a CRC code   */
            /* appended to the mangled file name.                  */
            needsCRC = TRUE;
            charLen = 1;
            current = '_';

            /* Skip over any following undiplayable or illegal     */
            /* chars.                                              */
            while (index + 1 < udfNameLen &&
                (!IsFileNameCharLegal(udfName[index + 1]) ||
                NativeCharLength(udfName[index + 1]) == 0))
                index++;

            /* Terminate loop if at the end of the file name.      */
            if (index >= udfNameLen)
                break;
        }

        /* Assign the resulting char to the next index in the file */
        /* name buffer and determine how many native bytes are     */
        /* left.                                                   */
        newName[targetIndex++] = current;
        bytesLeft -= charLen;

        /* This figures out where the CRC code needs to start in   */
        /* the file name buffer.                                   */
        if (bytesLeft >= CRC_LEN) {
            /* If there is enough space left, just tack it onto    */
            /* the end.                                            */
            crcIndex = targetIndex;
        }
        else {
            /* If there is not enough space left, the CRC must     */
            /* overlay a character already in the file name        */
            /* buffer.  Once this condition has been met, the      */
            /* value will not change.                              */
            if (overlayBytes < 0) {
                /* Determine the index and save the length of the  */
                /* native character that is overlayed.  It is      */
                /* possible that the CRC might overlay half of a   */
                /* two-byte native character depending upon how    */
                /* the character boundaries line up.               */
                overlayBytes = (bytesLeft + charLen > CRC_LEN)
                    ? 1 : 0;
                crcIndex = targetIndex - 1;
            }
        }

        /* Advance to the next character.                          */
        index++;
    }

    /* If the scan did not reach the end of the file name, or the  */
    /* length of the file name is zero, a CRC code is needed.      */
    if (index < nameLen || index == 0)
        needsCRC = TRUE;

    /* If the name has illegal characters or and extension, it     */
    /* is not a DOS device name.                                   */
    if (needsCRC == FALSE && extLen == 0) {
        /* If this is the name of a DOS device, a CRC code should  */
        /* be appended to the file name.                           */
        if (IsDeviceName(udfName, udfNameLen))
            needsCRC = TRUE;
    }

    /* Append the CRC code to the file name, if needed.            */
    if (needsCRC) {
        /* Get the CRC value for the original Unicode string       */
        UINT16 udfCRCValue = UdfComputeCrc16Uni(udfName, udfNameLen);

        /* Determine the character index where the CRC should      */
        /* begin.                                                  */
        targetIndex = crcIndex;

        /* If the character being overlayed is a two-byte native   */
        /* character, replace the first byte with an underscore.   */
        if (overlayBytes > 0)
            newName[targetIndex++] = ILLEGAL_CHAR_MARK;

        /* Append the encoded CRC value with delimiter.            */
        newName[targetIndex++] = CRC_MARK;
        newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0xf000) >> 12];
        newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x0f00) >> 8];
        newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x00f0) >> 4];
        newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x000f)];
    }


    /* If an extension was found, append it here.                  */
    if (extLen > 0) {
        /* Add the period ('.') for the extension delimiter.       */
        newName[targetIndex++] = PERIOD;

        /* Append the characters in the extension buffer.  They    */
        /* were stored in reverse order, so we need to begin with  */
        /* the last character and work forward.                    */
        while (extLen-- > 0)
            newName[targetIndex++] = ext[extLen];
    }

    ASSERT( (targetIndex * sizeof(WCHAR)) <= RenderedName->MaximumLength );
 
    RenderedName->Length = (USHORT) (targetIndex * sizeof(WCHAR));
}


BOOLEAN
UdfIsNameInExpression (
    IN PIRP_CONTEXT IrpContext,
    IN PUNICODE_STRING CurrentName,
    IN PUNICODE_STRING SearchExpression,
    IN BOOLEAN Wild
    )

/*++

Routine Description:

    This routine will compare two Unicode strings.  We assume that if this
    is to be a case-insensitive search then they are already upcased.

Arguments:

    CurrentName - Filename from the disk.

    SearchExpression - Filename expression to use for match.
    
    Wild - True if wildcards are present in SearchExpression.

Return Value:

    BOOLEAN - TRUE if the expressions match, FALSE otherwise.

--*/

{
    BOOLEAN Match = TRUE;
    
    PAGED_CODE();

    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    //
    //  If there are wildcards in the expression then we call the
    //  appropriate FsRtlRoutine.
    //

    if (Wild) {

        Match = FsRtlIsNameInExpression( SearchExpression,
                                         CurrentName,
                                         FALSE,
                                         NULL );

    //
    //  Otherwise do a direct memory comparison for the name string.
    //

    } else {

        if ((CurrentName->Length != SearchExpression->Length) ||
            (!RtlEqualMemory( CurrentName->Buffer,
                              SearchExpression->Buffer,
                              CurrentName->Length ))) {

            Match = FALSE;
        }
    }

    return Match;
}


FSRTL_COMPARISON_RESULT
UdfFullCompareNames (
    IN PIRP_CONTEXT IrpContext,
    IN PUNICODE_STRING NameA,
    IN PUNICODE_STRING NameB
    )

/*++

Routine Description:

    This function compares two names as fast as possible.  Note that since
    this comparison is case sensitive we can do a direct memory comparison.

Arguments:

    NameA & NameB - The names to compare.

Return Value:

    COMPARISON - returns

        LessThan    if NameA < NameB lexicalgraphically,
        GreaterThan if NameA > NameB lexicalgraphically,
        EqualTo     if NameA is equal to NameB

--*/

{
    ULONG i;
    ULONG MinLength = NameA->Length;
    FSRTL_COMPARISON_RESULT Result = LessThan;

    PAGED_CODE();

    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    //
    //  Figure out the minimum of the two lengths
    //

    if (NameA->Length > NameB->Length) {

        MinLength = NameB->Length;
        Result = GreaterThan;

    } else if (NameA->Length == NameB->Length) {

        Result = EqualTo;
    }

    //
    //  Loop through looking at all of the characters in both strings
    //  testing for equalilty, less than, and greater than
    //

    i = (ULONG) RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength );

    if (i < MinLength) {

        //
        //  We know the offset of the first character which is different.
        //

        return ((NameA->Buffer[ i / 2 ] < NameB->Buffer[ i / 2 ]) ?
                 LessThan :
                 GreaterThan);
    }

    //
    //  The names match up to the length of the shorter string.
    //  The shorter string lexically appears first.
    //

    return Result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -