Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1209 lines
18 KiB

/*++
Copyright (c) 1990-2001 Microsoft Corporation
Module Name:
fatdent.hxx
Abstract:
This class models a FAT directory entry.
Author:
Norbert P. Kusters (norbertk) 4-Dec-90
--*/
#ifndef MAKEULONG
#define MAKEULONG(a, b) ((ULONG)(((USHORT)(a)) | ((ULONG)((USHORT)(b))) << 16))
#define LOUSHORT(l) ((USHORT)(l & 0xFFFF))
#define HIUSHORT(l) ((USHORT)(((l) >> 16) & 0xFFFF))
#endif // !MAKEULONG
#if !defined(FAT_DIRENT_DEFN)
#define FAT_DIRENT_DEFN
#if defined ( _AUTOCHECK_ )
#define UFAT_EXPORT
#elif defined ( _UFAT_MEMBER_ )
#define UFAT_EXPORT __declspec(dllexport)
#else
#define UFAT_EXPORT __declspec(dllimport)
#endif
DECLARE_CLASS( FAT_DIRENT );
DECLARE_CLASS( WSTRING );
DECLARE_CLASS( WSTRING );
DECLARE_CLASS( TIMEINFO );
typedef struct _SHORT_FAT_DIRENT {
UCHAR Name[11];
UCHAR Attributes[1];
UCHAR NtByte[1];
UCHAR CreationMSec[1]; // actually count of 10msec's
UCHAR CreationTime[2]; // two-second resolution
UCHAR CreationDate[2];
UCHAR LastAccessDate[2];
UCHAR EaHandle[2];
UCHAR LastWriteTime[2];
UCHAR LastWriteDate[2];
UCHAR FirstCluster[2];
UCHAR Size[4];
};
DEFINE_TYPE( _SHORT_FAT_DIRENT, SHORT_FAT_DIRENT );
typedef struct _LONG_FAT_DIRENT {
UCHAR Ordinal[1];
UCHAR Name1[10];
UCHAR Attribute[1];
UCHAR Type[1];
UCHAR Checksum[1];
UCHAR Name2[12];
UCHAR FirstCluster[2];
UCHAR Name3[4];
};
DEFINE_TYPE( _LONG_FAT_DIRENT, LONG_FAT_DIRENT );
#define LONG_DIRENT_TYPE_NAME 0
#define LONG_DIRENT_TYPE_CLASS 1
class FAT_DIRENT : public OBJECT {
public:
UFAT_EXPORT
DECLARE_CONSTRUCTOR( FAT_DIRENT );
VIRTUAL
UFAT_EXPORT
~FAT_DIRENT(
);
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
Initialize(
IN OUT PVOID Dirent
);
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
Initialize(
IN OUT PVOID Dirent,
IN UCHAR FatType
);
NONVIRTUAL
VOID
Clear(
);
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
QueryName(
OUT PWSTRING Name
) CONST;
NONVIRTUAL
BOOLEAN
SetName(
IN PCWSTRING Name
);
NONVIRTUAL
BOOLEAN
IsValidName(
) CONST;
NONVIRTUAL
BOOLEAN
IsDot(
) CONST;
NONVIRTUAL
BOOLEAN
IsDotDot(
) CONST;
NONVIRTUAL
BYTE
QueryAttributeByte(
) CONST;
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
IsValidLastWriteTime(
) CONST;
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
QueryLastWriteTime(
OUT LARGE_INTEGER *TimeStamp
) CONST;
NONVIRTUAL
BOOLEAN
SetLastWriteTime(
);
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
IsValidCreationTime(
) CONST;
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
QueryCreationTime(
OUT LARGE_INTEGER *TimeStamp
) CONST;
NONVIRTUAL
BOOLEAN
SetCreationTime(
);
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
IsValidLastAccessTime(
) CONST;
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
QueryLastAccessTime(
OUT LARGE_INTEGER *TimeStamp
) CONST;
NONVIRTUAL
BOOLEAN
SetLastAccessTime(
);
NONVIRTUAL
ULONG
QueryStartingCluster(
) CONST;
NONVIRTUAL
VOID
SetStartingCluster(
IN ULONG NewStartingCluster
);
NONVIRTUAL
ULONG
QueryFileSize(
) CONST;
NONVIRTUAL
VOID
SetFileSize(
IN ULONG NewFileSize
);
NONVIRTUAL
USHORT
QueryEaHandle(
) CONST;
NONVIRTUAL
VOID
SetEaHandle(
IN USHORT NewHandle
);
NONVIRTUAL
BOOLEAN
IsEndOfDirectory(
) CONST;
NONVIRTUAL
VOID
SetEndOfDirectory(
);
NONVIRTUAL
BOOLEAN
IsErased(
) CONST;
NONVIRTUAL
VOID
SetErased(
);
NONVIRTUAL
BOOLEAN
IsHidden(
) CONST;
NONVIRTUAL
VOID
SetHidden(
);
NONVIRTUAL
BOOLEAN
IsReadOnly(
) CONST;
NONVIRTUAL
VOID
SetReadOnly(
);
NONVIRTUAL
BOOLEAN
IsSystem(
) CONST;
NONVIRTUAL
VOID
SetSystem(
);
NONVIRTUAL
BOOLEAN
IsVolumeLabel(
) CONST;
NONVIRTUAL
VOID
SetVolumeLabel(
);
NONVIRTUAL
BOOLEAN
IsDirectory(
) CONST;
NONVIRTUAL
VOID
SetDirectory(
);
NONVIRTUAL
VOID
ResetDirectory(
);
NONVIRTUAL
UCHAR
QueryChecksum(
) CONST;
NONVIRTUAL
BOOLEAN
Is8LowerCase(
) CONST;
NONVIRTUAL
BOOLEAN
Is3LowerCase(
) CONST;
NONVIRTUAL
BOOLEAN
IsLongEntry(
) CONST;
NONVIRTUAL
BOOLEAN
IsLongNameEntry(
) CONST;
NONVIRTUAL
BOOLEAN
QueryLongOrdinal(
) CONST;
NONVIRTUAL
BOOLEAN
IsLastLongEntry(
) CONST;
NONVIRTUAL
BOOLEAN
IsWellTerminatedLongNameEntry(
) CONST;
NONVIRTUAL
BOOLEAN
QueryLongNameComponent(
OUT PWSTRING NameComponent
) CONST;
NONVIRTUAL
BOOLEAN
NameHasTilde(
) CONST;
NONVIRTUAL
BOOLEAN
NameHasExtendedChars(
) CONST;
STATIC
BOOLEAN
IsValidLongName(
IN PWSTRING LongName
);
private:
NONVIRTUAL
BOOLEAN
TimeStampsAreValid(
USHORT t,
USHORT d
) CONST;
NONVIRTUAL
VOID
Construct(
);
NONVIRTUAL
VOID
Destroy(
);
PUCHAR _dirent;
UCHAR _FatType;
};
INLINE
VOID
FAT_DIRENT::Clear(
)
/*++
Routine Description:
This routine zeros out the directory entry.
Arguments:
None.
Return Value:
None.
--*/
{
memset(_dirent, 0, 32);
}
INLINE
BOOLEAN
FAT_DIRENT::IsDot(
) CONST
/*++
Routine Description:
This routine computes whether or not the directory entry is the "."
entry.
Arguments:
None.
Return Value:
FALSE - The entry is not the "." entry.
TRUE - The entry is the "." entry.
--*/
{
return !memcmp(_dirent, ". ", 11);
}
INLINE
BOOLEAN
FAT_DIRENT::IsDotDot(
) CONST
/*++
Routine Description:
This routine computes whether or not the directory entry is the ".."
entry.
Arguments:
None.
Return Value:
FALSE - The entry is not the ".." entry.
TRUE - The entry is the ".." entry.
--*/
{
return !memcmp(_dirent, ".. ", 11);
}
INLINE
ULONG
FAT_DIRENT::QueryStartingCluster(
) CONST
/*++
Routine Description:
This routine computes the starting cluster number of the directory entry.
Arguments:
None.
Return Value:
The starting cluster number of the directory entry.
--*/
{
DebugAssert(_dirent);
ULONG dwSCN;
if ( FAT_TYPE_FAT32 == _FatType )
dwSCN = MAKEULONG( (*((PUSHORT) &_dirent[26])), (*((PUSHORT) &_dirent[20])));
else
dwSCN = *((PUSHORT) &_dirent[26]);
return dwSCN;
}
INLINE
VOID
FAT_DIRENT::SetStartingCluster(
IN ULONG NewStartingCluster
)
/*++
Routine Description:
This routine sets the starting cluster number for the directory entry.
Arguments:
NewStartingCluster - Supplies the starting cluster number for the
directory entry.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
if ( FAT_TYPE_FAT32 == _FatType )
*((PUSHORT) &_dirent[20]) = HIUSHORT( NewStartingCluster );
*((PUSHORT) &_dirent[26]) = LOUSHORT( NewStartingCluster );
}
INLINE
ULONG
FAT_DIRENT::QueryFileSize(
) CONST
/*++
Routine Description:
This routine returns the number of bytes in the file.
Arguments:
None.
Return Value:
The number of bytes in the file.
--*/
{
DebugAssert(_dirent);
return *((PULONG) &_dirent[28]);
}
INLINE
VOID
FAT_DIRENT::SetFileSize(
IN ULONG NewFileSize
)
/*++
Routine Description:
This routine sets the file size in the directory entry.
Arguments:
NewFileSize - Supplies the new file size.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
*((PULONG) &_dirent[28]) = NewFileSize;
}
INLINE
USHORT
FAT_DIRENT::QueryEaHandle(
) CONST
/*++
Routine Description:
This routine returns the EA handle for the file.
Arguments:
None.
Return Value:
The EA handle for the file.
--*/
{
DebugAssert(_dirent);
if ( FAT_TYPE_FAT32 == _FatType )
return ( 0 );
else
return *((PUSHORT) &_dirent[20]);
}
INLINE
VOID
FAT_DIRENT::SetEaHandle(
IN USHORT NewHandle
)
/*++
Routine Description:
This routine sets the EA handle for the file.
Arguments:
NewHandle - Supplies the EA handle for the file.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
*((PUSHORT) &_dirent[20]) = NewHandle;
}
INLINE
BOOLEAN
FAT_DIRENT::IsEndOfDirectory(
) CONST
/*++
Routine Description:
This routine computes whether or not this directory entry marks
the end of the directory.
Arguments:
None.
Return Value:
FALSE - This entry does not mark the end of the directory.
TRUE - This entry marks the end of the directory.
--*/
{
DebugAssert(_dirent);
return _dirent[0] ? FALSE : TRUE;
}
INLINE
VOID
FAT_DIRENT::SetEndOfDirectory(
)
/*++
Routine Description:
This routine sets this directory entry marks to the end of the
directory.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[0] = 0;
}
INLINE
BOOLEAN
FAT_DIRENT::IsErased(
) CONST
/*++
Routine Description:
This routine computes whether or not the directory entry is erased or not.
Arguments:
None.
Return Value:
FALSE - The directory entry is not erased.
TRUE - The directory entry is erased.
--*/
{
DebugAssert(_dirent);
return _dirent[0] == 0xE5 ? TRUE : FALSE;
}
INLINE
VOID
FAT_DIRENT::SetErased(
)
/*++
Routine Description:
This routine marks the directory entry as erased.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[0] = 0xE5;
}
INLINE
BOOLEAN
FAT_DIRENT::IsHidden(
) CONST
/*++
Routine Description:
This routine computes whether or not the file is hidden.
Arguments:
None.
Return Value:
FALSE - The file is not hidden.
TRUE - The file is hidden.
--*/
{
DebugAssert(_dirent);
return _dirent[11]&0x02 ? TRUE : FALSE; // FILE_ATTRIBUTE_HIDDEN
}
INLINE
VOID
FAT_DIRENT::SetHidden(
)
/*++
Routine Description:
This routine marks the directory entry as hidden.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] |= 0x02; // FILE_ATTRIBUTE_HIDDEN
}
INLINE
BOOLEAN
FAT_DIRENT::IsReadOnly(
) CONST
/*++
Routine Description:
This routine computes whether or not the file is read only.
Arguments:
None.
Return Value:
FALSE - The file is not read only.
TRUE - The file is read only.
--*/
{
DebugAssert(_dirent);
return _dirent[11]&0x01 ? TRUE : FALSE; // FILE_ATTRIBUTE_READONLY
}
INLINE
VOID
FAT_DIRENT::SetReadOnly(
)
/*++
Routine Description:
This routine marks the directory entry as read only.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] |= 0x01; // FILE_ATTRIBUTE_READONLY
}
INLINE
BOOLEAN
FAT_DIRENT::IsSystem(
) CONST
/*++
Routine Description:
This routine computes whether or not the file is a system file.
Arguments:
None.
Return Value:
FALSE - The file is not a system file.
TRUE - The file is a system file.
--*/
{
DebugAssert(_dirent);
return _dirent[11]&0x04 ? TRUE : FALSE;
}
INLINE
VOID
FAT_DIRENT::SetSystem(
)
/*++
Routine Description:
This routine marks the directory entry as system.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] |= 0x04; // FILE_ATTRIBUTE_SYSTEM
}
INLINE
BOOLEAN
FAT_DIRENT::IsVolumeLabel(
) CONST
/*++
Routine Description:
This routine computes whether or not the first 11 characters of the
directory entry are the volume label or not.
Arguments:
None.
Return Value:
FALSE - The directory entry is not a volume label.
TRUE - The directory entry is a volume label.
--*/
{
DebugAssert(_dirent);
return ((_dirent[11]&0x08) && !IsLongEntry());
}
INLINE
BOOLEAN
FAT_DIRENT::IsLongEntry(
) CONST
/*++
Routine Description;
This routine determines whether this entry is a
Long Directory Entry.
The entry is a Long Directory Entry if the attribute
field has all four low-order bits (read-only, hidden,
system, and volume-label) set. The four high-order
bits are ignored.
Arguments:
None.
Return Value:
TRUE if the entry is a Long Name Directory Entry.
--*/
{
return( (_dirent[11] & 0xF) == 0xF );
}
INLINE
BOOLEAN
FAT_DIRENT::IsLongNameEntry(
) CONST
/*++
Routine Description;
This routine determines whether this entry is a
Long Name Directory Entry.
A Long Name directory entry is a Long Directory Entry
with a type field of LONG_DIRENT_TYPE_LONG_NAME.
Arguments:
None.
Return Value:
TRUE if the entry is a Long Name Directory Entry.
--*/
{
return( IsLongEntry() && (_dirent[12] == LONG_DIRENT_TYPE_NAME) );
}
INLINE
BOOLEAN
FAT_DIRENT::QueryLongOrdinal(
) CONST
/*++
Routine Description;
This method returns the ordinal of a long directory entry.
If the directory entry is not a long entry, it returns
0xFF. Note that this method strips off the Last Long Entry
flag before returning the ordinal. To determine if an entry
is the last of a set of long entries, call IsLastLongEntry.
Arguments:
None.
Return Value:
The ordinal of this entry.
--*/
{
return( IsLongEntry() ? _dirent[0] & 0x3F: 0xFF );
}
INLINE
BOOLEAN
FAT_DIRENT::IsLastLongEntry(
) CONST
/*++
Routine Description:
This method determines whether this entry is the last
of a set of long directory entries.
Arguments:
None.
Return Value:
TRUE if this is the last of a set of long directory entries.
--*/
{
return( IsLongEntry() ? _dirent[0] & 0x40 : FALSE );
}
INLINE
VOID
FAT_DIRENT::SetVolumeLabel(
)
/*++
Routine Description:
This routine sets the directory entry to be a volume label.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] |= 0x08;
}
INLINE
BOOLEAN
FAT_DIRENT::IsDirectory(
) CONST
/*++
Routine Description:
This routine computes whether or not the directory entry is a directory.
Arguments:
None.
Return Value:
FALSE - The directory entry is not a directory.
TRUE - The directory entry is a directory.
--*/
{
DebugAssert(_dirent);
return ((_dirent[11]&0x10) && !IsLongEntry());
}
INLINE
VOID
FAT_DIRENT::SetDirectory(
)
/*++
Routine Description:
This routine sets the directory entry to be a directory.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] |= 0x10;
}
INLINE
VOID
FAT_DIRENT::ResetDirectory(
)
/*++
Routine Description:
This routine sets the directory entry to not be a directory.
Arguments:
None.
Return Value:
None.
--*/
{
DebugAssert(_dirent);
_dirent[11] &= ~0x10;
}
INLINE
BYTE
FAT_DIRENT::QueryAttributeByte(
) CONST
/*++
Routine Description:
This routine returns the attribute byte of the directory entry
Arguments:
None.
Return Value:
Attribute byte
--*/
{
DebugAssert(_dirent);
return _dirent[11];
}
INLINE
BOOLEAN
FAT_DIRENT::Is8LowerCase(
) CONST
/*++
Routine Description:
This routine tells whether the first 8 bytes of the short name
should be downcased after being read from the disk.
Arguments:
None.
Return Value:
TRUE or FALSE
--*/
{
DebugAssert(_dirent);
return (_dirent[12] & 0x08) != 0;
}
INLINE
BOOLEAN
FAT_DIRENT::Is3LowerCase(
) CONST
/*++
Routine Description:
This routine tells whether the last 8 bytes of the short name
should be downcased after being read from the disk.
Arguments:
None.
Return Value:
TRUE or FALSE
--*/
{
DebugAssert(_dirent);
return (_dirent[12] & 0x10) != 0;
}
#endif // FAT_DIRENT_DEFN