Our filter driver backs our special reparse point tag. When a user mode
application opens a reparse point file with our tag, the filter will do
something like redirecting or restoring etc. If a file is opened with
FILE_FLAG_OPEN_REPARSE_POINT, the filter does nothing for the file and just
lets it go.
But there is a problem when our application creates a reparse point file,
another CreateFile call without FILE_FLAG_OPEN_REPARSE_POINT is issued by
NTFS or something else after the reparse point file is created. For the
filter, it seems another regular user application wants to open the reparse
point. This problem causes the filter to immediately restore a file that is
just archived to tape by our application.
The user mode code to create a reparse point is attached in end of this
message.
Long time ago I asked a similar question and got response from Molly. But
neither way is applicable.
Here is Molly’s response:
I believe what you are seeing only occurs when setting a mount point
reparse point (reparse tag == IO_REPARSE_TAG_MOUNT_POINT). NTFS opens
the target of this mount point to verify that it is a valid path.You can distinguish this create from other creates you may see in two
ways:
- The RequestorMode in the IRP will be KernelMode, since Ntfs generated
the CREATE.- The return value of IoGetTopLevelIrp() will be non-NULL since this is
a recursive operation from the file system.
User mode code to create reparse point:
hFile = CreateFile((LPCSTR)szSrcFileName,
GENERIC_WRITE,
0,
NULL,
TRUNCATE_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if (hFile == INVALID_HANDLE_VALUE) // cannot open the drive
{
printf(“Failed to get the source file: %s handle!”, szSrcFileName);
return (-1);
}
// convert this file into a reparse point
ReparseData.ReparseTag = IO_REPARSE_TAG;
ReparseData.ReparseGuid = REPARSE_GUID;
// save the target name into reparse point
lstrcpyW((LPWSTR)ReparseData.DataBuffer, wszTgtUniName);
int len = (lstrlenW((LPWSTR)ReparseData.DataBuffer) + 1) * sizeof(WCHAR);
ReparseData.ReparseDataLength = len;
DWORD len2 = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + len;
bResult = DeviceIoControl(hFile,
FSCTL_SET_REPARSE_POINT,
&ReparseData, len2,
NULL, 0,
&temp,
(LPOVERLAPPED) NULL);
if (!bResult)
{
DWORD err = GetLastError();
printf(“Last Error: %u code\n”, err);
}
CloseHandle(hFile);