800 lines
14 KiB
C++
800 lines
14 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
attrrec.hxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the declarations for NTFS_ATTRIBUTE_RECORD,
|
|||
|
which models NTFS attribute records.
|
|||
|
|
|||
|
An Attribute Record may be a template laid over a chunk of
|
|||
|
memory; in that case, it does not own the memory. It may
|
|||
|
also be told, upon initialization, to allocate its own memory
|
|||
|
and copy the supplied data. In that case, it is also responsible
|
|||
|
for freeing that memory.
|
|||
|
|
|||
|
Attribute Records are passed between Attributes and File
|
|||
|
Record Segments. A File Record Segment can initialize
|
|||
|
an Attribute with a list of Attribute Records; when an
|
|||
|
Attribute is Set into a File Record Segment, it packages
|
|||
|
itself up into Attribute Records and inserts them into
|
|||
|
the File Record Segment.
|
|||
|
|
|||
|
File Record Segments also use Attribute Records to scan
|
|||
|
through their list of attribute records, and to shuffle
|
|||
|
them around.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Bill McJohn (billmc) 14-June-91
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
ULIB, User Mode
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#if !defined( _NTFS_ATTRIBUTE_RECORD_DEFN_ )
|
|||
|
|
|||
|
#define _NTFS_ATTRIBUTE_RECORD_DEFN_
|
|||
|
|
|||
|
DECLARE_CLASS( WSTRING );
|
|||
|
DECLARE_CLASS( NTFS_EXTENT_LIST );
|
|||
|
DECLARE_CLASS( NTFS_ATTRIBUTE_RECORD );
|
|||
|
DECLARE_CLASS( NTFS_ATTRIBUTE_COLUMNS );
|
|||
|
DECLARE_CLASS( NTFS_UPCASE_TABLE );
|
|||
|
|
|||
|
// This function is used to compare attribute records, in order
|
|||
|
// to determine their ordering in the base FRS. Its definition
|
|||
|
// appears in attrrec.cxx.
|
|||
|
//
|
|||
|
LONG
|
|||
|
CompareAttributeRecords(
|
|||
|
IN PCNTFS_ATTRIBUTE_RECORD Left,
|
|||
|
IN PCNTFS_ATTRIBUTE_RECORD Right,
|
|||
|
IN PCNTFS_UPCASE_TABLE UpcaseTable
|
|||
|
);
|
|||
|
|
|||
|
class NTFS_ATTRIBUTE_RECORD : public OBJECT {
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
UNTFS_EXPORT
|
|||
|
DECLARE_CONSTRUCTOR( NTFS_ATTRIBUTE_RECORD );
|
|||
|
|
|||
|
VIRTUAL
|
|||
|
UNTFS_EXPORT
|
|||
|
~NTFS_ATTRIBUTE_RECORD(
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
Initialize(
|
|||
|
IN PIO_DP_DRIVE Drive,
|
|||
|
IN OUT PVOID Data,
|
|||
|
IN ULONG MaximumLength,
|
|||
|
IN BOOLEAN MakeCopy DEFAULT FALSE
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
UNTFS_EXPORT
|
|||
|
BOOLEAN
|
|||
|
Initialize(
|
|||
|
IN PIO_DP_DRIVE Drive,
|
|||
|
IN OUT PVOID Data
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
CreateResidentRecord(
|
|||
|
IN PCVOID Value,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN ATTRIBUTE_TYPE_CODE TypeCode,
|
|||
|
IN PCWSTRING Name DEFAULT NULL,
|
|||
|
IN USHORT Flags DEFAULT 0,
|
|||
|
IN UCHAR ResidentFlags DEFAULT 0
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
CreateNonresidentRecord(
|
|||
|
IN PCNTFS_EXTENT_LIST Extents,
|
|||
|
IN BIG_INT AllocatedLength,
|
|||
|
IN BIG_INT ActualLength,
|
|||
|
IN BIG_INT ValidDataLength,
|
|||
|
IN ATTRIBUTE_TYPE_CODE TypeCode,
|
|||
|
IN PCWSTRING Name DEFAULT NULL,
|
|||
|
IN USHORT Flags DEFAULT 0,
|
|||
|
IN USHORT CompressionUnit DEFAULT 0,
|
|||
|
IN ULONG ClusterSize DEFAULT 0
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
Verify(
|
|||
|
IN PCNTFS_ATTRIBUTE_COLUMNS AttributeDefTable OPTIONAL,
|
|||
|
IN BOOLEAN BeLenient
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
UseClusters(
|
|||
|
IN OUT PNTFS_BITMAP VolumeBitmap,
|
|||
|
OUT PBIG_INT ClusterCount
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
UseClusters(
|
|||
|
IN OUT PNTFS_BITMAP VolumeBitmap,
|
|||
|
OUT PBIG_INT ClusterCount,
|
|||
|
IN ULONG AllowCrossLinkStart,
|
|||
|
IN ULONG AllowCrossLinkLength,
|
|||
|
OUT PBOOLEAN DidCrossLinkOccur
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
UnUseClusters(
|
|||
|
IN OUT PNTFS_BITMAP VolumeBitmap,
|
|||
|
IN ULONG LeaveInUseStart,
|
|||
|
IN ULONG LeaveInUseLength
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
ULONG
|
|||
|
QueryRecordLength(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
ATTRIBUTE_TYPE_CODE
|
|||
|
QueryTypeCode(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
USHORT
|
|||
|
QueryFlags(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
UCHAR
|
|||
|
QueryResidentFlags(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
ULONG
|
|||
|
QueryCompressionUnit(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
IsResident(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
IsIndexed(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VCN
|
|||
|
QueryLowestVcn(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
PWSTR
|
|||
|
GetName(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VCN
|
|||
|
QueryNextVcn(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
UNTFS_EXPORT
|
|||
|
BOOLEAN
|
|||
|
QueryName(
|
|||
|
OUT PWSTRING Name
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
ULONG
|
|||
|
QueryNameLength(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
QueryValueLength(
|
|||
|
OUT PBIG_INT ValueLength,
|
|||
|
OUT PBIG_INT AllocatedLength DEFAULT NULL,
|
|||
|
OUT PBIG_INT ValidLength DEFAULT NULL,
|
|||
|
OUT PBIG_INT TotalAllocated DEFAULT NULL
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
SetTotalAllocated(
|
|||
|
IN BIG_INT TotalAllocated
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
USHORT
|
|||
|
QueryInstanceTag(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
SetInstanceTag(
|
|||
|
USHORT NewTag
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
PCVOID
|
|||
|
GetData(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
UNTFS_EXPORT
|
|||
|
BOOLEAN
|
|||
|
QueryExtentList(
|
|||
|
OUT PNTFS_EXTENT_LIST ExtentList
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
PCVOID
|
|||
|
GetResidentValue(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
USHORT
|
|||
|
QueryResidentValueOffset(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
ULONG
|
|||
|
QueryResidentValueLength(
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
IsMatch(
|
|||
|
IN ATTRIBUTE_TYPE_CODE Type,
|
|||
|
IN PCWSTRING Name DEFAULT NULL,
|
|||
|
IN PCVOID Value DEFAULT NULL,
|
|||
|
IN ULONG ValueLength DEFAULT 0
|
|||
|
) CONST;
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
DisableUnUse(
|
|||
|
IN BOOLEAN NewState DEFAULT TRUE
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
BOOLEAN
|
|||
|
IsUnUseDisabled(
|
|||
|
);
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
Construct (
|
|||
|
);
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
Destroy(
|
|||
|
);
|
|||
|
|
|||
|
PATTRIBUTE_RECORD_HEADER _Data;
|
|||
|
ULONG _MaximumLength;
|
|||
|
BOOLEAN _IsOwnBuffer;
|
|||
|
|
|||
|
//
|
|||
|
// DisableUnUse will turn the UnUseClusters operation into a
|
|||
|
// no-op.
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN _DisableUnUse;
|
|||
|
|
|||
|
PIO_DP_DRIVE _Drive; // in order to obtain message outlet
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
ULONG
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryRecordLength(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the length of the attribute record. (Note
|
|||
|
that this is the length of the record itself, not the length
|
|||
|
of the buffer allotted to it).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The length of the attribute record.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return _Data->RecordLength;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
ATTRIBUTE_TYPE_CODE
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryTypeCode(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the attribute type code.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The attribute type code for this attribute record.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return _Data->TypeCode;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
USHORT
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryFlags(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the attribute's flags.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The flags from the attribute record.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DebugPtrAssert( _Data );
|
|||
|
|
|||
|
return( _Data->Flags );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
ULONG
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryCompressionUnit(
|
|||
|
) CONST
|
|||
|
{
|
|||
|
return( (_Data->FormCode == NONRESIDENT_FORM) ?
|
|||
|
_Data->Form.Nonresident.CompressionUnit :
|
|||
|
0 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
UCHAR
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryResidentFlags(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the attribute's resident-form flags.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The resident-form flags from the attribute record. If
|
|||
|
if the attribute is nonresident, this method returns zero.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DebugPtrAssert( _Data );
|
|||
|
|
|||
|
return( (_Data->FormCode == NONRESIDENT_FORM) ?
|
|||
|
0 :
|
|||
|
_Data->Form.Resident.ResidentFlags );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
BOOLEAN
|
|||
|
NTFS_ATTRIBUTE_RECORD::IsResident(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns whether the attribute is resident.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if the attribute is resident.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return (_Data->FormCode == RESIDENT_FORM);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
BOOLEAN
|
|||
|
NTFS_ATTRIBUTE_RECORD::IsIndexed(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns whether the attribute is indexed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if the attribute is indexed.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return IsResident() &&
|
|||
|
(_Data->Form.Resident.ResidentFlags & RESIDENT_FORM_INDEXED);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
VCN
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryLowestVcn(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the lowest VCN covered by this attribute
|
|||
|
record. If this attribute record is resident, the the lowest
|
|||
|
VCN is zero; if it is nonresident, the lowest VCN is given by
|
|||
|
the
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The lowest VCN covered by this attribute record.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if( IsResident() ) {
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return _Data->Form.Nonresident.LowestVcn;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
VCN
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryNextVcn(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the highest VCN covered by this attribute
|
|||
|
record. If this attribute record is resident, then the highest
|
|||
|
VCN is zero; if it is nonresident, the highest VCN is given by
|
|||
|
the
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The highest VCN covered by this attribute record.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if( IsResident() ) {
|
|||
|
|
|||
|
return 1;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return _Data->Form.Nonresident.HighestVcn + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
ULONG
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryNameLength(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the length of the name, in characters.
|
|||
|
Zero indicates that the attribute record has no name.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Length of the name, in characters.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return _Data->NameLength;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
USHORT
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryInstanceTag(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method queries the attribute record's unique-within-this-file
|
|||
|
attribute instance tag.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The attribute record's instance tag.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return _Data->Instance;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
VOID
|
|||
|
NTFS_ATTRIBUTE_RECORD::SetInstanceTag(
|
|||
|
USHORT NewTag
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method sets the attribute record's unique-within-this-file
|
|||
|
attribute instance tag.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NewTag -- Supplies the new value for the instance tag.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
_Data->Instance = NewTag;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
PWSTR
|
|||
|
NTFS_ATTRIBUTE_RECORD::GetName(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns a pointer to the wide-character attribute
|
|||
|
name.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
A pointer to the wide-character name in this attribute record;
|
|||
|
NULL if there is no name.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
This method is provided to permit optimization of the common
|
|||
|
attribute look-op operation in File Record Segments.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
if( QueryNameLength() == 0 ) {
|
|||
|
|
|||
|
return NULL;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return( (PWSTR)( (PBYTE)_Data + _Data->NameOffset ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
PCVOID
|
|||
|
NTFS_ATTRIBUTE_RECORD::GetData(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns a pointer to the attribute record's data.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
A pointer to the attribute record's data.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return _Data;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
PCVOID
|
|||
|
NTFS_ATTRIBUTE_RECORD::GetResidentValue(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns a pointer to the attribute record's
|
|||
|
resident value. If the attribute record is non-resident,
|
|||
|
it returns NULL.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The attribute record's resident value; NULL if the attribute
|
|||
|
record is non-resident.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if( _Data->FormCode == NONRESIDENT_FORM ) {
|
|||
|
|
|||
|
return NULL;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return ((PBYTE)_Data + _Data->Form.Resident.ValueOffset);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
USHORT
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryResidentValueOffset(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the attribute record's resident value offset.
|
|||
|
If the attribute record is non-resident, it returns 0.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The attribute record's resident value offset; 0 if the attribute
|
|||
|
record is non-resident.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if( _Data->FormCode == NONRESIDENT_FORM ) {
|
|||
|
|
|||
|
return NULL;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return _Data->Form.Resident.ValueOffset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INLINE
|
|||
|
ULONG
|
|||
|
NTFS_ATTRIBUTE_RECORD::QueryResidentValueLength(
|
|||
|
) CONST
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method returns the attribute record's resident value
|
|||
|
length (zero if the attribute is nonresident).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Who Cares.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return( (_Data->FormCode == NONRESIDENT_FORM) ?
|
|||
|
0 :
|
|||
|
_Data->Form.Resident.ValueLength );
|
|||
|
}
|
|||
|
|
|||
|
INLINE
|
|||
|
VOID
|
|||
|
NTFS_ATTRIBUTE_RECORD::DisableUnUse(
|
|||
|
IN BOOLEAN NewState
|
|||
|
)
|
|||
|
{
|
|||
|
_DisableUnUse = NewState;
|
|||
|
}
|
|||
|
|
|||
|
INLINE
|
|||
|
BOOLEAN
|
|||
|
NTFS_ATTRIBUTE_RECORD::IsUnUseDisabled(
|
|||
|
)
|
|||
|
{
|
|||
|
return _DisableUnUse;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#endif
|