Wired behavior of Windows offline files(CSC) and LanManager Redirector.

This is some thing which I encounter while testing, my mini-filter with windows offline files.
In post query directory information callback, when the FSD return STATUS_NO_MORE_FILES or STATUS_NO_SUCH_FILE. I add some extra entries to buffer and return STATUS_SUCCESS. When I am done with adding entries, I return STATUS_NO_MORE_FILES. It works fine, for local file system (NTFS) and Lanmanager redirector.
But when I select few file to work offline (i.e. windows offline File), and disconnect from network. I can still access selected file using same UNC path, although I am disconnected from N/W (an expected behavior of Offline files).
In this case of disconnected operations onces the redirector return STATUS_NO_MORE_FILES. If a query directory request is send to redirector using the same FO, after STATUS_NO_MORE_FILES was return in the previous call, redirector return STATUS_SUCCESS and buffer fill with lists of files. Expected here in this case, it should return STATUS_NO_MORE_FILES. I also verified that SL_RESTART_SCAN flag was not set and there is no any other filter below me.
Though I can workaround this case in my filter, But like to know if this is a some kind of bug or Is this a expected behavior of redirector? Or I am wrong on my understanding?
Following is a user more sample from MSDN, which is modified to repro the issue. I had test this sample on w2k3 SP2 with NO filters loaded. And second time I loop through FindNextFile(), using the same file handle it does not return any error.
// listdir.cpp : Defines the entry point for the console application.
//

#include “stdafx.h”
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <tchar.h>
#include <wchar.h>
#include <strsafe.h>

#define BUFSIZE MAX_PATH

int _tmain(int argc, _TCHAR* argv)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError;
LPTSTR DirSpec;
size_t length_of_arg;
INT retval;

DirSpec = (LPTSTR) malloc (BUFSIZE);

if( DirSpec == NULL )
{
printf( “Insufficient memory available\n” );
retval = 1;
goto Cleanup;
}

// Check for the directory to query, specified as
// a command-line parameter; otherwise, print usage.
if(argc != 2)
{
_tprintf(TEXT(“Usage: Test \n”));
retval = 2;
goto Cleanup;
}

// Check that the input is not larger than allowed.
StringCbLength(argv[1], BUFSIZE, &length_of_arg);

if (length_of_arg > (BUFSIZE - 2))
{
_tprintf(TEXT(“Input directory is too large.\n”));
retval = 3;
goto Cleanup;
}

_tprintf (TEXT(“Target directory is %s.\n”), argv[1]);

// Prepare string for use with FindFile functions. First,
// copy the string to a buffer, then append ‘*’ to the
// directory name.
StringCbCopyN (DirSpec, BUFSIZE, argv[1], length_of_arg+1);
StringCbCatN (DirSpec, BUFSIZE, TEXT("\"), 2sizeof(TCHAR));

// Find the first file in the directory.
hFind = FindFirstFile(DirSpec, &FindFileData);

if (hFind == INVALID_HANDLE_VALUE)
{
_tprintf (TEXT(“Invalid file handle. Error is %u.\n”),
GetLastError());
retval = (-1);
}
else
{
_tprintf (TEXT(“First file name is: %s\n”),
FindFileData.cFileName);

// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
{
_tprintf (TEXT(“Next file name is: %s\n”),
FindFileData.cFileName);
}

dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
_tprintf (TEXT(“FindNextFile error. Error is %u.\n”),
dwError);
FindClose(hFind);
retval = (-1);
goto Cleanup;
}

// second time list all the other files in the directory, using the same handle.
// FindNextFile return sucess, in case of disconnected Operations for LANManager
while (FindNextFile(hFind, &FindFileData) != 0)
{
_tprintf (TEXT(“Next file name is: %s\n”),
FindFileData.cFileName);
}

dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
_tprintf (TEXT(“FindNextFile error. Error is %u.\n”),
dwError);
FindClose(hFind);
retval = (-1);
goto Cleanup;
}

}
retval = 0;

Cleanup:
free(DirSpec);
return retval;

}

I had three directory’s (F1, F2, and F3) in the share \10.217.113.159\MYSHARE

output on running the sample when connected to N/W

C:&gt;LISTDIR.exe \10.217.113.159\MYSHARE
Target directory is \10.217.113.159\MYSHARE.
First file name is: .
Next file name is: …
Next file name is: F1
Next file name is: F2
Next file name is: F3

I select F1 & F2 directory to work offline using windows offline files and disconnect from N/W, following is the output of the sample

C:&gt;LISTDIR.exe \10.217.113.159\MYSHARE
Target directory is \10.217.113.159\MYSHARE.
First file name is: .
Next file name is: …
Next file name is: F1
Next file name is: F2
Next file name is: .
Next file name is: …
Next file name is: F1
Next file name is: F2

Thanks,
-Kishor.</strsafe.h></wchar.h></tchar.h></malloc.h></stdio.h></windows.h>

So, if I understand is properly, your sample code continues
enumeration after previous call to FindNextFile already
returned FALSE. My guess is that any call past that point
has random behavior.

Try to invoke that situation using FileTest’s NtQueryDirectoryFile,
that will give you results that show behavior of NT calls more
precisely.

Also, from my (very far ago) experiences with offline files,
any call made to them goes first to redirector, and when found out
that they are locally available, the redirector then issues
a new NT call, using one of Zw* functions. You wrote that your filter
is attached both to redirector and local file system, cold the issue
come from the fact that you are filtering the same request twice ?

L.

Version 1.7.0.152 of FileTest, which I am using, the call to NtQueryDirectoryFile() last parameter RestartScan is always set to TRUE.

When disconnect from N/W If I use FileTest, after get STATUS_NO_MORE_FILES, if I again query Redirector does not return any error.

My filter are not loaded. So no changes of returning are entry twice, by my filter.

Ladislav, seems like in case of offline file, redirector even does not handle RestartScan==TRUE case. As I use FileTest to query directory, when I am connected to N/W, FileTest return same entry (as this tool set RestartScan to True on each call). But when disconnected from N/W I get all entries followed by STATUS_NO_MORE_FILES and again Query the directory, redirector start returning the entries from start.