Setting a Reparse Point / Driver GUID

Hi,

I am developing a File System Filter Driver. I want to use a reparse point that I ill set on files to indicate that certain processing should take place for these files. I plan to use the data buffer in the Reparse point to indicate a number of different options for the processing - but I can’t set the reparse point.

I have been struggling for a long time to understand the process. From what I can make out I need to register a GUID for my driver, and specify the same GUID in the ReparsePoint when I assign the tag. I don’t know how to do this. I had thought I had cracked it wtih a call to IoRegisterDeviceInterface but I don’t appear to have the Interface registered (I had expected to see it in the registry and it’s not there so I guess I’ve not done this correctly).

The code that (attempts to) register the interface is in the DriverEntry routine (derived from sfilter) as follows:

//
// Create the Control Device Object (CDO). This object represents this
// driver. Note that it does not have a device extension.
//

RtlInitUnicodeString( &nameString, L"\FileSystem\Filters\AHFSFilter" );
status = IoCreateDevice( DriverObject, 0, &nameString, FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN, FALSE, &gSFilterControlDeviceObject );
if (status == STATUS_OBJECT_PATH_NOT_FOUND)
{
//
// This must be a version of the OS that doesn’t have the Filters
// path in its namespace. This was added in Windows XP.
//
// We will try just putting our control device object in the \FileSystem
// portion of the object name space.
//
RtlInitUnicodeString( &nameString, L"\FileSystem\AHFSFilterCDO" );
status = IoCreateDevice( DriverObject, 0, &nameString, FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN, FALSE, &gSFilterControlDeviceObject );
if (!NT_SUCCESS( status ))
{
KdPrint(( “AHFSFilter!DriverEntry: Error creating control device object "%wZ", status=%08x\n”, &nameString, status ));
return status;
}

} else if (!NT_SUCCESS( status )) {

KdPrint(( “AHFSFilter!DriverEntry: Error creating control device object "%wZ", status=%08x\n”, &nameString, status ));
return status;
}
// !NB! RJL - Register the Interface Class for our Reparse Points …
//
if(NT_SUCCESS(IoRegisterDeviceInterface( DriverObject->DeviceObject,
&GUID_AHFS_REPARSE_POINT, NULL, &uszSymbolicLinkName)))
{
RtlFreeUnicodeString(&uszSymbolicLinkName);
}
else
{
KdPrint(( “AHFSFilter!DriverEntry: Error Registering Drevice Interface Class for GUID_AHFS_REPARSE_POINT, status=%08x\n”, status ));
}

I have not created a new device object, I was hoping to have the calls come through the same driver object. Is this possible? Sensible?

When I try setting the Reparse Point on a file I get error 4392 - which indicates that I have a problem with the structure. I call the function as follows:

hFile=CreateFile(pFile, GENERIC_READ | GENERIC_WRITE ,
0,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
buffer.ReparseTag=0x00000080;
buffer.ReparseDataLength=0;
buffer.Reserved=0;

buffer.ReparseGuid.Data1=0x23faa677;
buffer.ReparseGuid.Data2=0x3010;
buffer.ReparseGuid.Data3=0x4487;
buffer.ReparseGuid.Data4[0]=0x9f;
buffer.ReparseGuid.Data4[1]=0x82;
buffer.ReparseGuid.Data4[2]=0x5a;
buffer.ReparseGuid.Data4[3]=0xc0;
buffer.ReparseGuid.Data4[4]=0x3c;
buffer.ReparseGuid.Data4[5]=0xfe;
buffer.ReparseGuid.Data4[6]=0x5f;
buffer.ReparseGuid.Data4[7]=0x0b;

bResult = DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, &buffer, sizeof(REPARSE_GUID_DATA_BUFFER),
NULL, 0, &dwRetBytes, NULL);
if(!bResult)
{
dwRetBytes=GetLastError();
printf (“Could not set Reparse Point for file %s - error is %d\n”, pFile, dwRetBytes);
}
CloseHandle(hFile);

Do I need to include a data buffer, or is it failing because the GUID is not registered?

Note that we have not applied for a Reparse Tag from MS yet - this is (obviously) very early days for the project and it may get canned. We are using a value of 0x00000080 for our tag as you can see above.

So: I want to intercept a reparse point set on files -

  1. how do I set the point and register the driver to receive the tag?
    (I can look at every CREATE that comes down, which is what my code is expecting to do at the moment, but if I can’t set the point it won’t help me.)
  2. How does the Filter get called for a reparse point - is it on an interface that solely deals with the RP files, and if so, how do I set this up ?

Thanks in anticipation of your response.

Rob Lambden

PS: Sorry if the convention for this list is plain text only - let me know and I’ll ensure I stick to it!

The buffer length you are sending down is off by 1.
Specify the input buffer length as:
buffer.ReparseDataLength+REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
(since your reparse data length is 0, this reduces to
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE)

Ravi


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rob Lambden
Sent: Tuesday, October 26, 2004 3:10 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] Setting a Reparse Point / Driver GUID

Hi,

I am developing a File System Filter Driver. I want to use a reparse
point that I ill set on files to indicate that certain processing should
take place for these files. I plan to use the data buffer in the
Reparse point to indicate a number of different options for the
processing - but I can’t set the reparse point.

I have been struggling for a long time to understand the process. From
what I can make out I need to register a GUID for my driver, and specify
the same GUID in the ReparsePoint when I assign the tag. I don’t know
how to do this. I had thought I had cracked it wtih a call to
IoRegisterDeviceInterface but I don’t appear to have the Interface
registered (I had expected to see it in the registry and it’s not there
so I guess I’ve not done this correctly).

The code that (attempts to) register the interface is in the DriverEntry
routine (derived from sfilter) as follows:

//
// Create the Control Device Object (CDO). This object represents
this
// driver. Note that it does not have a device extension.
//

RtlInitUnicodeString( &nameString,
L"\FileSystem\Filters\AHFSFilter" );
status = IoCreateDevice( DriverObject, 0, &nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN, FALSE,
&gSFilterControlDeviceObject );
if (status == STATUS_OBJECT_PATH_NOT_FOUND)
{
//
// This must be a version of the OS that doesn’t have the
Filters
// path in its namespace. This was added in Windows XP.
//
// We will try just putting our control device object in the
\FileSystem
// portion of the object name space.
//
RtlInitUnicodeString( &nameString,
L"\FileSystem\AHFSFilterCDO" );
status = IoCreateDevice( DriverObject, 0, &nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN, FALSE,
&gSFilterControlDeviceObject );
if (!NT_SUCCESS( status ))
{
KdPrint(( “AHFSFilter!DriverEntry: Error creating control
device object "%wZ", status=%08x\n”, &nameString, status ));
return status;
}

} else if (!NT_SUCCESS( status )) {

KdPrint(( “AHFSFilter!DriverEntry: Error creating control device
object "%wZ", status=%08x\n”, &nameString, status ));
return status;
}
// !NB! RJL - Register the Interface Class for our Reparse Points

//
if(NT_SUCCESS(IoRegisterDeviceInterface( DriverObject->DeviceObject,
&GUID_AHFS_REPARSE_POINT, NULL,
&uszSymbolicLinkName)))
{
RtlFreeUnicodeString(&uszSymbolicLinkName);
}
else
{
KdPrint(( “AHFSFilter!DriverEntry: Error Registering Drevice
Interface Class for GUID_AHFS_REPARSE_POINT, status=%08x\n”, status ));
}

I have not created a new device object, I was hoping to have the calls
come through the same driver object. Is this possible? Sensible?

When I try setting the Reparse Point on a file I get error 4392 - which
indicates that I have a problem with the structure. I call the function
as follows:

hFile=CreateFile(pFile, GENERIC_READ | GENERIC_WRITE ,
0,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
buffer.ReparseTag=0x00000080;
buffer.ReparseDataLength=0;
buffer.Reserved=0;

buffer.ReparseGuid.Data1=0x23faa677;
buffer.ReparseGuid.Data2=0x3010;
buffer.ReparseGuid.Data3=0x4487;
buffer.ReparseGuid.Data4[0]=0x9f;
buffer.ReparseGuid.Data4[1]=0x82;
buffer.ReparseGuid.Data4[2]=0x5a;
buffer.ReparseGuid.Data4[3]=0xc0;
buffer.ReparseGuid.Data4[4]=0x3c;
buffer.ReparseGuid.Data4[5]=0xfe;
buffer.ReparseGuid.Data4[6]=0x5f;
buffer.ReparseGuid.Data4[7]=0x0b;

bResult = DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, &buffer,
sizeof(REPARSE_GUID_DATA_BUFFER),
NULL, 0, &dwRetBytes, NULL);
if(!bResult)
{
dwRetBytes=GetLastError();
printf (“Could not set Reparse Point for file %s - error is
%d\n”, pFile, dwRetBytes);
}
CloseHandle(hFile);

Do I need to include a data buffer, or is it failing because the GUID is
not registered?

Note that we have not applied for a Reparse Tag from MS yet - this is
(obviously) very early days for the project and it may get canned. We
are using a value of 0x00000080 for our tag as you can see above.

So: I want to intercept a reparse point set on files -

  1. how do I set the point and register the driver to receive the tag?
    (I can look at every CREATE that comes down, which is what my code is
    expecting to do at the moment, but if I can’t set the point it won’t
    help me.)
  2. How does the Filter get called for a reparse point - is it on an
    interface that solely deals with the RP files, and if so, how do I set
    this up ?

Thanks in anticipation of your response.

Rob Lambden

PS: Sorry if the convention for this list is plain text only - let me
know and I’ll ensure I stick to it!

Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks very much for this response. I have modified the code and I can now set the reparse point.

However, my driver is not working as expected, and I think I have a ‘design flaw’ in that I am trying to do something impossible in the current system.

My plan is to access data held in the actual file (not in the Reparse Buffer) using streams. To this end when I find the Reparse point on the file in the CREATE I change the request to identify which stream should be accessed, but ON THE SAME FILE. The O/S is reporting it can’t be accessed, presumably because the lower level drivers see an unknown reparse point.

Please can someone confirm how I should process the Reparse point - in particular:

1/ Can I modify the Create and pass down details of a new file to be accessed (on the same device)?
2/ Do I have to pick up the Reparse in the Completion buffer and give redirection information?
3/ Can I fulfill requests directly (perhaps by talking to a user mode app)?

Regards

Rob Lambden
“Ravisankar Pudipeddi” wrote in message news:xxxxx@ntfsd…
The buffer length you are sending down is off by 1.
Specify the input buffer length as:
buffer.ReparseDataLength+REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
(since your reparse data length is 0, this reduces to REPARSE_GUID_DATA_BUFFER_HEADER_SIZE)

Ravi

Are you setting the FILE_OPEN_REPARSE_POINT option in your IRP_MJ_CREATE
options?

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com

Looking forward to seeing you at the Next OSR File Systems Class October
18, 2004 in Silicon Valley!


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rob Lambden
Sent: Wednesday, October 27, 2004 8:32 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Setting a Reparse Point / Driver GUID

Thanks very much for this response. I have modified the code and I can
now set the reparse point.

However, my driver is not working as expected, and I think I have a
‘design flaw’ in that I am trying to do something impossible in the
current system.

My plan is to access data held in the actual file (not in the Reparse
Buffer) using streams. To this end when I find the Reparse point on the
file in the CREATE I change the request to identify which stream should
be accessed, but ON THE SAME FILE. The O/S is reporting it can’t be
accessed, presumably because the lower level drivers see an unknown
reparse point.

Please can someone confirm how I should process the Reparse point - in
particular:

1/ Can I modify the Create and pass down details of a new file to be
accessed (on the same device)?

2/ Do I have to pick up the Reparse in the Completion buffer and give
redirection information?

3/ Can I fulfill requests directly (perhaps by talking to a user mode
app)?

Regards

Rob Lambden

“Ravisankar Pudipeddi” wrote in
message news:xxxxx@ntfsd…

The buffer length you are sending down is off by 1.

Specify the input buffer length as:

buffer.ReparseDataLength+REPARSE_GUID_DATA_BUFFER_HEADER_SIZE

(since your reparse data length is 0, this reduces to
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE)

Ravi


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi Tony,

Thanks for your reply. I am now setting the Reparse point successfully in User Mode. The code that checks for the Reparse point in the driver is:

int
blCheckForFilterOperation(
IN PFILE_OBJECT pFileObject
)
{
HANDLE hFileHandle;
OBJECT_ATTRIBUTES oaObjAttrs;
IO_STATUS_BLOCK ioBlock;
FILE_ATTRIBUTE_TAG_INFORMATION fatiInfo;
int nRc=0;

InitializeObjectAttributes(&oaObjAttrs, &(pFileObject->FileName),
OBJ_KERNEL_HANDLE|OBJ_OPENIF, NULL, NULL);
if(ZwOpenFile(&hFileHandle, FILE_READ_ATTRIBUTES, &oaObjAttrs, &ioBlock,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE) == STATUS_SUCCESS)
{
if(ZwQueryInformationFile(hFileHandle, &ioBlock, &fatiInfo,
sizeof(FILE_ATTRIBUTE_TAG_INFORMATION), FileAttributeTagInformation) == STATUS_SUCCESS)
{
if( (fatiInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
(fatiInfo.ReparseTag == AHFS_REPARSE_TAG) )
{ // we should read the info for any additional functionality
nRc=1;
}
}
ZwClose(hFileHandle);
}
return(nRc);
}

My understanding is that this should work, although I am new to the documentation …

Currently the logical flow of operations within the driver for IRP_MJ_CREATE is:
Refuse Access to my control object
Is this a reparse file (switch on return value from above function)
If so amend the Filename to include stream information obtained from user mode service
Pass the IRP_MJ_CREATE down the stack.

That’s it. No completion processing required (as far as I know).

I am now guessing that this can’t work as the system will still see the Reparse point on the file and not actually read it. My fault for not having a clear understanding of how they work.

So my Questions remain:
1/ Can I modify the Create and pass down details of a new file to be accessed (on the same device)?

or

2/ Do I have to pick up the Reparse in the Completion buffer and give redirection information? (seems less efficient to me)

3/ Can I fulfill requests directly (perhaps by talking to a user mode app)? – not keen on this as it seems like a lot of work to me ;o)

Thanks again,

Rob

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Are you setting the FILE_OPEN_REPARSE_POINT option in your IRP_MJ_CREATE options?

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com

Looking forward to seeing you at the Next OSR File Systems Class October 18, 2004 in Silicon Valley!

------------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Rob Lambden
Sent: Wednesday, October 27, 2004 8:32 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Setting a Reparse Point / Driver GUID

Thanks very much for this response. I have modified the code and I can now set the reparse point.

However, my driver is not working as expected, and I think I have a ‘design flaw’ in that I am trying to do something impossible in the current system.

My plan is to access data held in the actual file (not in the Reparse Buffer) using streams. To this end when I find the Reparse point on the file in the CREATE I change the request to identify which stream should be accessed, but ON THE SAME FILE. The O/S is reporting it can’t be accessed, presumably because the lower level drivers see an unknown reparse point.

Please can someone confirm how I should process the Reparse point - in particular:

1/ Can I modify the Create and pass down details of a new file to be accessed (on the same device)?

2/ Do I have to pick up the Reparse in the Completion buffer and give redirection information?

3/ Can I fulfill requests directly (perhaps by talking to a user mode app)?

Regards

Rob Lambden

“Ravisankar Pudipeddi” wrote in message news:xxxxx@ntfsd…

The buffer length you are sending down is off by 1.

Specify the input buffer length as:

buffer.ReparseDataLength+REPARSE_GUID_DATA_BUFFER_HEADER_SIZE

(since your reparse data length is 0, this reduces to REPARSE_GUID_DATA_BUFFER_HEADER_SIZE)

Ravi


Questions? First check the IFS FAQ at https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Of course you can change the parameter information! If you want, you
can change to a different file object, direct the I/O operation to a
different driver, etc. There’s no reason to require that this be done in
completion.

As for (3) my only comment is that interacting with a UM service is
really pretty straight-forward - certainly in comparison to the work
involved in building a file system filter driver in any case.

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rob Lambden
Sent: Wednesday, October 27, 2004 11:43 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Setting a Reparse Point / Driver GUID

Hi Tony,

Thanks for your reply. I am now setting the Reparse point successfully
in User Mode. The code that checks for the Reparse point in the driver
is:

int
blCheckForFilterOperation(
IN PFILE_OBJECT pFileObject
)
{
HANDLE hFileHandle;
OBJECT_ATTRIBUTES oaObjAttrs;
IO_STATUS_BLOCK ioBlock;
FILE_ATTRIBUTE_TAG_INFORMATION fatiInfo;
int nRc=0;

InitializeObjectAttributes(&oaObjAttrs, &(pFileObject->FileName),
OBJ_KERNEL_HANDLE|OBJ_OPENIF, NULL, NULL);
if(ZwOpenFile(&hFileHandle, FILE_READ_ATTRIBUTES, &oaObjAttrs,
&ioBlock,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE) == STATUS_SUCCESS)
{
if(ZwQueryInformationFile(hFileHandle, &ioBlock, &fatiInfo,
sizeof(FILE_ATTRIBUTE_TAG_INFORMATION),
FileAttributeTagInformation) == STATUS_SUCCESS)
{
if( (fatiInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
(fatiInfo.ReparseTag == AHFS_REPARSE_TAG) )
{ // we should read the info for any additional functionality
nRc=1;
}
}
ZwClose(hFileHandle);
}
return(nRc);
}

My understanding is that this should work, although I am new to the
documentation …

Currently the logical flow of operations within the driver for
IRP_MJ_CREATE is:

Refuse Access to my control object

Is this a reparse file (switch on return value from above function)

If so amend the Filename to include stream information obtained from
user mode service

Pass the IRP_MJ_CREATE down the stack.

That’s it. No completion processing required (as far as I know).

I am now guessing that this can’t work as the system will still see the
Reparse point on the file and not actually read it. My fault for not
having a clear understanding of how they work.

So my Questions remain:

1/ Can I modify the Create and pass down details of a new file to be
accessed (on the same device)?

or

2/ Do I have to pick up the Reparse in the Completion buffer and give
redirection information? (seems less efficient to me)

3/ Can I fulfill requests directly (perhaps by talking to a user mode
app)? – not keen on this as it seems like a lot of work to me ;o)

Thanks again,

Rob

“Tony Mason” wrote in message
news:xxxxx@ntfsd…

Are you setting the FILE_OPEN_REPARSE_POINT option in your
IRP_MJ_CREATE options?

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com

Looking forward to seeing you at the Next OSR File Systems Class
October 18, 2004 in Silicon Valley!

________________________________

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rob Lambden
Sent: Wednesday, October 27, 2004 8:32 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Setting a Reparse Point / Driver GUID

Thanks very much for this response. I have modified the code
and I can now set the reparse point.

However, my driver is not working as expected, and I think I
have a ‘design flaw’ in that I am trying to do something impossible in
the current system.

My plan is to access data held in the actual file (not in the
Reparse Buffer) using streams. To this end when I find the Reparse
point on the file in the CREATE I change the request to identify which
stream should be accessed, but ON THE SAME FILE. The O/S is reporting
it can’t be accessed, presumably because the lower level drivers see an
unknown reparse point.

Please can someone confirm how I should process the Reparse
point - in particular:

1/ Can I modify the Create and pass down details of a new file
to be accessed (on the same device)?

2/ Do I have to pick up the Reparse in the Completion buffer and
give redirection information?

3/ Can I fulfill requests directly (perhaps by talking to a user
mode app)?

Regards

Rob Lambden

“Ravisankar Pudipeddi”
wrote in message news:xxxxx@ntfsd…

The buffer length you are sending down is off by 1.

Specify the input buffer length as:

buffer.ReparseDataLength+REPARSE_GUID_DATA_BUFFER_HEADER_SIZE

(since your reparse data length is 0, this reduces to
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE)

Ravi


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: unknown lmsubst tag
argument: ‘’
To unsubscribe send a blank email to
xxxxx@lists.osr.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Dear Tony,

Thanks for the reply. I am pressing on with the project, but I am still callenged by the documentation though. As I understand it I can store data actually in the file, and applications should be able to read it. But I can’t see a way to enable this because the lower level drivers all fail when I pas down the modified request for an alternate strream. If you could point me at some good documentaion I would much appreciate it.

In the meantime, for development and testing purposes I am going to use a parallel ile to redirect to.

Thanks again,

Regards

Rob Lambden