Exemplo n.º 1
0
VOID 
NcSetFileName (
    _In_ PVOID Entry,
    _In_ PWSTR NewName,
    _In_ ULONG Length,
    _In_ CONST PDIRECTORY_CONTROL_OFFSETS Offsets,
    _In_ BOOLEAN ForceLast
    )
/*++

Routine Description:

    Sets a new file name into the entry.

Arguments:

    Entry - A pointer to the start of the entry.

    NewName - A pointer to the new file name.

    Length - The length of the new name (in bytes).

    Offsets - Offsets structure for the information class.

    ForceLast - If true, the entry's size will be set to zero
                so that it looks like a valid last entry.

Return Value

    None.

--*/
{
    PWSTR NamePtr;
    PULONG NameLength;

    PAGED_CODE();

    //
    //  Get a pointer to the name in the buffer.
    //

    NamePtr = NcGetFileName( Entry, Offsets);
    NameLength = Add2Ptr( Entry, Offsets->FileNameLengthDist );

    //
    //  Copy the new name into buffer.
    //
    
    RtlCopyMemory( NamePtr, NewName, Length );
    *NameLength = Length;

    //
    //  Now we have to update the size of this entry.
    //

    NcSetNextEntryOffset( Entry, Offsets, ForceLast );
}
Exemplo n.º 2
0
PNC_CACHE_ENTRY
NcDirEnumSelectNextEntry( 
    _Inout_ PNC_DIR_QRY_CONTEXT Context, 
    _In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
    _In_ BOOLEAN IgnoreCase
    )
/*++

Routine Description:

    This routine determines whether the cached entry (returned from the
    filesystem) should be returned now or whether the injected entry (as a
    result of our mapping) should be returned now.

Arguments:

    Context - The enumeration context of this handle.

    Offsets - Information describing the offsets for this enumeration class.

    IgnoreCase - TRUE if we are case insensitive, FALSE if case sensitive.

Return Value:

    A pointer to the entry we should return, or NULL if there is nothing
    remaining to return.

--*/
{
    PNC_CACHE_ENTRY NextEntry;
    UNICODE_STRING CacheString;
    UNICODE_STRING InsertString;
    PVOID CacheEntry;
    PVOID InjectEntry;

    PAGED_CODE();

    //
    //  Figure out which name comes first
    //

    if ((Context->Cache.Buffer == NULL) && 
        (Context->InjectionEntry.Buffer == NULL)) {

        //
        //  There are no names left, return STATUS_NO_MORE_FILES
        //

        NextEntry = NULL;

    } else if (Context->Cache.Buffer == NULL) {

        //
        //  The cache is empty, so inject.
        //

        NextEntry = &Context->InjectionEntry;

    } else if (Context->InjectionEntry.Buffer == NULL) {

        //
        //  The injection entry is empty, drain the cache.
        //

        NextEntry = &Context->Cache;

    } else {

        //
        //  We have to seek in the entry buffer to the current entry within the buffer.
        //

        CacheEntry = Add2Ptr( Context->Cache.Buffer, Context->Cache.CurrentOffset );
        InjectEntry = Add2Ptr( Context->InjectionEntry.Buffer, Context->InjectionEntry.CurrentOffset );

        //
        //  Find names within the entries.
        //

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

        InsertString.Buffer = NcGetFileName( InjectEntry, Offsets );
        InsertString.Length = (USHORT) NcGetFileNameLength( InjectEntry, Offsets );
        InsertString.MaximumLength = InsertString.Length;

        //
        //  Compare the names
        //

        if (RtlCompareUnicodeString( &CacheString,
                                     &InsertString,
                                     IgnoreCase ) < 0) {

            //
            //  Cache string comes first
            //

            NextEntry = &Context->Cache;

        } else {

            //
            //  insert string comes first
            //

            NextEntry = &Context->InjectionEntry;
        }
    }
    return NextEntry;
}
Exemplo n.º 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;
}