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

📄 namesup.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* and no extension was found.                             */
        extLen = 0;
        nameLen = udfNameLen;
    }
    else {
        /* A DOS extension was found, process it first.            */
        extLen = udfNameLen - index - 1;
        nameLen = index;
        targetIndex = 0;
        bytesLeft = DOS_EXT_LEN;

        while (++index < udfNameLen && bytesLeft > 0) {
            /* Get the current character and convert it to upper   */
            /* case.                                               */
            current = UnicodeToUpper(udfName[index]);
            if (current == SPACE) {
                /* If a space is found, a CRC must be appended to  */
                /* the mangled file name.                          */
                needsCRC = TRUE;
            }
            else {
                /* Determine if this is a valid file name char and */
                /* calculate its corresponding BCS character byte  */
                /* length (zero if the char is not legal or        */
                /* undisplayable on this system).                  */
                charLen = (IsFileNameCharLegal(current)) ?
                    NativeDosCharLength(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   */
                    /* required a CRC code appended to the mangled */
                    /* file name.                                  */
                    needsCRC = TRUE;
                    charLen = 1;
                    current = ILLEGAL_CHAR_MARK;

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

                /* Assign the resulting char to the next index in  */
                /* the extension buffer and determine how many BCS */
                /* bytes are left.                                 */
                ext[targetIndex++] = current;
                bytesLeft -= charLen;
            }
        }

        /* Save the number of Unicode characters in the extension  */
        extLen = targetIndex;

        /* If the extension was too large, or it was zero length   */
        /* (i.e. the name ended in a period), a CRC code must be   */
        /* appended to the mangled name.                           */
        if (index < udfNameLen || extLen == 0)
            needsCRC = TRUE;
    }

    /* Now process the actual file name.                           */
    index = 0;
    targetIndex = 0;
    crcIndex = 0;
    overlayBytes = -1;
    bytesLeft = DOS_NAME_LEN;
    while (index < nameLen && bytesLeft > 0) {
        /* Get the current character and convert it to upper case. */
        current = UnicodeToUpper(udfName[index]);
        if (current == SPACE || current == PERIOD) {
            /* Spaces and periods are just skipped, a CRC code     */
            /* must be added to the mangled file name.             */
            needsCRC = TRUE;
        }
        else {
            /* Determine if this is a valid file name char and     */
            /* calculate its corresponding BCS character byte      */
            /* length (zero if the char is not legal or            */
            /* undisplayable on this system).                      */
            charLen = (IsFileNameCharLegal(current)) ?
                NativeDosCharLength(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       */
                /* required a CRC code appended to the mangled     */
                /* file name.                                      */
                needsCRC = TRUE;
                charLen = 1;
                current = ILLEGAL_CHAR_MARK;

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

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

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

            /* This figures out where the CRC code needs to start  */
            /* in the file name buffer.                            */
            if (bytesLeft >= DOS_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 BCS character that is overlayed.  It    */
                    /* is possible that the CRC might overlay      */
                    /* half of a two-byte BCS character depending  */
                    /* upon how the character boundaries line up.  */
                    overlayBytes = (bytesLeft + charLen > DOS_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;
        UINT16 modulus;

        //
        //  In UDF 2.00, the sample code changed to take the CRC
        //  from the UNICODE expansion of the CS0 as opposed to
        //  the CS0 itself.  In UDF 2.01, the wording of the spec
        //  will actually match this.
        //
        //  Additionally, the checksum changes to be byte-order
        //  independent.
        //
        
        udfCRCValue = UdfComputeCrc16Uni(udfName, udfNameLen);

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

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

        //
        //  UDF 2.01 changes to a base 41 encoding.  UDF 1.50 and
        //  UDF 2.00 exchanged the # delimeter with the high 4bits
        //  of the CRC.
        //

        dosName[targetIndex++] = CRC_MARK;
        
        dosName[targetIndex++] =
            UdfCrcChar[udfCRCValue / (41 * 41)];
        udfCRCValue %= (41 * 41);
        
        dosName[targetIndex++] =
            UdfCrcChar[udfCRCValue / 41];
        udfCRCValue %= 41;
        
        dosName[targetIndex++] =
            UdfCrcChar[udfCRCValue];
    }

    /* Append the extension, if any.                               */
    if (extLen > 0) {
        /* Tack on a period and each successive byte in the        */
        /* extension buffer.                                       */
        dosName[targetIndex++] = PERIOD;
        for (index = 0; index < extLen; index++)
            dosName[targetIndex++] = ext[index];
    }

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

    //
    //  Now we upcase the whole name at once.
    //

    UdfUpcaseName( IrpContext,
                   ShortFileName,
                   ShortFileName );
}


VOID
UdfConvertCS0DstringToUnicode (
    IN PIRP_CONTEXT IrpContext,
    IN PUCHAR Dstring,
    IN UCHAR Length OPTIONAL,
    IN UCHAR FieldLength OPTIONAL,
    IN OUT PUNICODE_STRING Name
    )

/*++

Routine Description:

    This routine will convert the CS0 input dstring (1/7.2.12) to Unicode.  We assume that
    the length is sane.
    
    This "compression" in CS0 is really just a special case hack for ASCII.

Arguments:

    Dstring - the input dstring field
    
    Length - length of the dstring.  If unspecified, we assume that the characters come
        from a proper 1/7.2.12 dstring that specifies length in the last character of the
        field.
    
    FieldLength - length of the dstring field.  If unspecified, we assume that the characters
        come from an uncounted length of CS0 characters and that the Length parameter is
        specified.
    
    Name - the output Unicode string

Return Value:

    None.

--*/

{
    ULONG CompressID;
    ULONG UnicodeIndex, ByteIndex;
    PWCHAR Unicode = Name->Buffer;

    UCHAR NameLength;
    ULONG CopyNameLength;

    PAGED_CODE();
   
    //
    //  Check input.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    CompressID = *Dstring;

    //
    //  If the length is unspecified, this is a real 1/7.2.12 dstring and the length is in
    //  the last character of the field.
    //
    
    ASSERT( Length || FieldLength );

    if (Length) {

        NameLength = FieldLength = Length;
    
    } else {

        NameLength = *(Dstring + FieldLength - 1);
    }
    
    //
    //  If the caller specified a size, they should have made sure the buffer is big enough.
    //  Otherwise, we will trim to fit.
    //
    
    ASSERT( Length == 0 || Name->MaximumLength >= UdfCS0DstringUnicodeSize( IrpContext, Dstring, NameLength ) );
 
    //
    //  Decide how many UNICODE bytes to "copy".
    //
    
    CopyNameLength = Min( Name->MaximumLength, UdfCS0DstringUnicodeSize( IrpContext, Dstring, NameLength ));
    
    //
    //  Reset the name length and advance over the compression ID in the dstring.
    //
    
    Name->Length = 0;
    Dstring++;
 
    //
    //  Loop through all the bytes.
    //

    while (CopyNameLength > Name->Length) {
      
        if (CompressID == 16) {
       
            //
            //  We're little endian, and this is the single place in the entire UDF/ISO standard
            //  where they use big endian.
            //
            //  Thank you.  Thank you very much.
            //
            //  Do an unaligned swapcopy of this 16bit value.
            //

            SwapCopyUchar2( Unicode, Dstring );
            Dstring += sizeof(WCHAR);
       
        } else {

            //
            //  Drop the byte into the low bits.
            //
                
            *Unicode = *Dstring;
            Dstring += sizeof(CHAR);
        }

        Name->Length += sizeof(WCHAR);
        Unicode++;
    }

    return;
}


BOOLEAN
UdfCheckLegalCS0Dstring (
    PIRP_CONTEXT IrpContext,
    PUCHAR Dstring,
    UCHAR Length OPTIONAL,
    UCHAR FieldLength OPTIONAL,
    BOOLEAN ReturnOnError
    )

/*++

Routine Description:

    This routine inspects a CS0 Dstring for conformance.
    
Arguments:

    Dstring - a dstring to check
    
    Length - length of the dstring.  If unspecified, we assume that the characters come
        from a proper 1/7.2.12 dstring that specifies length in the last character of the
        field.
    
    FieldLength - length of the dstring field.  If unspecified, we assume that the characters
        come from an uncounted length of CS0 characters and that the Length parameter is
        specified.
    
    ReturnOnError - whether to return or raise on a discovered error
    
Return Value:

    None. Raised status if corruption is found.
    
--*/

{
    UCHAR NameLength;

    //
    //  Check input.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    //
    //  If the length is unspecified, this is a real 1/7.2.12 dstring and the length is in
    //  the last character of the field.
    //
    
    ASSERT( Length || FieldLength );

    if (Length) {

        NameLength = FieldLength = Length;
    
    } else {

        NameLength = *(Dstring + FieldLength - 1);
    }

    DebugTrace(( +1, Dbg,
                 "UdfCheckLegalCS0Dstring, Dstring %08x Length %02x FieldLength %02x (NameLength %02x)\n",
                 Dstring,
                 Length,
                 FieldLength,
                 NameLength ));

    //
    //  The string must be "compressed" in 8bit or 16bit chunks.  If it
    //  is in 16bit chunks, we better have an integral number of them -
    //  remember we have the compression ID, so the length will be odd.
    //
    
    if ((NameLength <= 1 &&
         DebugTrace(( 0, Dbg,
                      "UdfCheckLegalCS0Dstring, NameLength is too small!\n" ))) ||

        (NameLength > FieldLength &&
         DebugTrace(( 0, Dbg,
                      "UdfCheckLegalCS0Dstring, NameLength is bigger than the field itself!\n" ))) ||

        ((*Dstring != 8 && *Dstring != 16) &&
         DebugTrace(( 0, Dbg,
                      "UdfCheckLegalCS0Dstring, claims encoding %02x, unknown! (not 0x8 or 0x10)\n",
                      *Dstring ))) ||

        ((*Dstring == 16 && !FlagOn( NameLength, 1)) &&

⌨️ 快捷键说明

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