示例#1
0
PVOID
NcGetNextEntry (
    _In_ CONST PVOID Buffer,
    _In_ CONST PDIRECTORY_CONTROL_OFFSETS Offsets
    )
/*++

Routine Description:

    Returns a pointer to the next entry in the buffer.

Arguments:

    Buffer - Pointer to the start of the current entry.

    Offsets - Offsets structure for this information class.

Return Value:

    Returns a pointer to the beginning of the next entry.

--*/
{
    ULONG Offset = NcGetNextEntryOffset( Buffer, Offsets );
    PVOID NextEntry = Add2Ptr( Buffer, Offset );
    PAGED_CODE();
    return NextEntry;
}
示例#2
0
ULONG
NcGetEntrySize (
    _In_ CONST PVOID Buffer,
    _In_ CONST PDIRECTORY_CONTROL_OFFSETS Offsets
    )
/*++

Routine Description:

    Returns the size of this entry in bytes.

Arguments:

    Buffer - Pointer to the start of the entry.

    Offsets - Offsets structure for the information class.

Return Value:

    Returns the size of this entry in bytes.

--*/
{
    ULONG EntrySize = NcGetNextEntryOffset(Buffer, Offsets);
    PAGED_CODE();

    if (EntrySize == 0) {

        //
        //  We are at last entry, so we need to calculate this ourselves.
        //

        EntrySize = NcGetFileNameLength( Buffer, Offsets );
        EntrySize += Offsets->FileNameDist;
    }

    return EntrySize;
}
示例#3
0
BOOLEAN
NcSkipName (
    _In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
    _In_ PNC_DIR_QRY_CONTEXT Context, 
    _In_ NC_PATH_OVERLAP RealOverlap,
    _In_ PNC_MAPPING Mapping,
    _In_ BOOLEAN IgnoreCase
    )
/*++

Routine Description:

    Determines if the next entry is for the real mapping.  If it is, we want
    to "skip" returning this entry and proceed to the next.

Arguments:

    Offsets - Offset information for this enumeration class.

    Context - Pointer to directory query context (on the stream handle.)
        This is used to obtain the entry we are contemplating returning.

    RealOverlap - Relationship of the object that enumeration is being
        requested on to the real mapping.  This routine will only skip
        entries if we are enumerating the parent of the real mapping.

Return Value:

    TRUE if this entry should be skipped/suppressed; FALSE if it should be
    returned to the user.

--*/
{
    BOOLEAN Result = FALSE;
    PVOID CacheEntry;
    UNICODE_STRING CacheString;
    PUNICODE_STRING IgnoreString = &Mapping->RealMapping.LongNamePath.FinalComponentName;
    ULONG ElementSize;
    BOOLEAN LastElement;

    PAGED_CODE();

    if (RealOverlap.Parent) {

        //
        //  We have to check for a match.
        //

        CacheEntry = Add2Ptr( Context->Cache.Buffer, Context->Cache.CurrentOffset);
        ElementSize = NcGetEntrySize( CacheEntry, Offsets );
        LastElement = (BOOLEAN)(NcGetNextEntryOffset( CacheEntry, Offsets ) == 0);

        CacheString.Buffer = NcGetFileName( CacheEntry, Offsets );
        CacheString.Length = (USHORT) NcGetFileNameLength( CacheEntry, Offsets );
        CacheString.MaximumLength = CacheString.Length;


        if (RtlCompareUnicodeString( &CacheString, 
                                     IgnoreString,
                                     IgnoreCase ) == 0) {

            //
            //  We need to ignore this name.
            //

            Result = TRUE;

            //
            //  skip
            //

            if (LastElement) {

                //
                //  This was the last element in the entry, so we should clean the entry.
                //

                ExFreePoolWithTag(Context->Cache.Buffer, NC_DIR_QRY_CACHE_TAG);
                Context->Cache.Buffer = NULL;
                Context->Cache.CurrentOffset = 0;

            } else {

                //
                //  Entry has more elements, update offset counter.
                //

                Context->Cache.CurrentOffset += ElementSize;
            }
        } 
    }

    return Result;
}
示例#4
0
ULONG
NcCopyDirEnumEntry (
    _Out_ PVOID UserBuffer,
    _In_ ULONG UserOffset,
    _In_ ULONG UserSize,
    _Inout_ PNC_CACHE_ENTRY Entry,
    _In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
    _Out_ PBOOLEAN Copied 
    )
/*++

Routine Description:

    This routine copies a single enumeration result into the caller's
    buffer.

Arguments:

    UserBuffer - Pointer to the caller's buffer.

    UserOffset - Offset within the caller's buffer that we intend to write new
        results.

    UserSize - Size of the caller's buffer, in bytes.

    Entry - Pointer to the directory entry that we intend to return.

    Offsets - Information describing the offsets for this enumeration class.

    Copied - Pointer to a boolean value indicating whether this routine copied
        a new entry or not.

Return Value:

    The new offset in the user buffer that any future copies should use.

--*/
{
    PVOID Element =        Add2Ptr( Entry->Buffer, Entry->CurrentOffset );
    PVOID Dest =           Add2Ptr( UserBuffer, UserOffset );
    ULONG ElementSize =    NcGetEntrySize( Element, Offsets );
    BOOLEAN LastElement =  (BOOLEAN)(NcGetNextEntryOffset( Element, Offsets ) == 0);

    PAGED_CODE();

    if (UserSize - UserOffset >= ElementSize) {

        //
        //  There is enough room for this element, so copy it.
        //

        RtlCopyMemory( Dest, Element, ElementSize );
        UserOffset += ElementSize;
        *Copied = TRUE;

        //
        //  Update Entry's Offset
        //

        if (LastElement) {

            //
            //  This was the last element in the entry, so we should clean the
            //  entry.
            //

            ExFreePoolWithTag( Entry->Buffer, NC_TAG );
            Entry->Buffer = NULL;
            Entry->CurrentOffset = 0;

            //
            //  The last element in cached entries have a NextEntryOffset of 0,
            //  make sure that we report the actual next entry offset.
            //

            NcSetNextEntryOffset( Dest, Offsets, FALSE );

        } else {

            //
            //  Entry has more elements, update offset counter.
            //

            Entry->CurrentOffset += ElementSize;
        }

    } else {

        //
        //  User buffer does not have enough space.
        //

        *Copied = FALSE;
    }

    return UserOffset;
}