kernel file copy and MJ_READ problem

Hello,

My minifilter does a file copy in its pre-read routine. When a MJ_READ
request comes for fileA whose content is empty, the filter copies data from
fileB to fileA and let the request continues. The problem is that if I read
fileA by DOS command type “c:\>type fileA”, it only shows the beginning part
content of the file. If I open it by Notepad.exe, it shows the whole content
of the file. Below is my file copy code. Please advise me what I can do
else. - Thanks.

BOOLEAN
MfCopyFile(
IN PFLT_CALLBACK_DATA Data,
IN PWSTR SrcFilePath
)
{
OBJECT_ATTRIBUTES objectAttr;
IO_STATUS_BLOCK ioStatusZW;
HANDLE hSrcFile;
PFILE_OBJECT ObSrcFile;
NTSTATUS status;
UNICODE_STRING fileName;
PFILTER_INSTANCE_CONTEXT instContext;
USHORT SectorSize;

// Get the context.
status = FltGetInstanceContext( Data->Iopb->SrcInstance,
&instContext );
if (!NT_SUCCESS(status))
{
return FALSE;
}
SectorSize = instContext->SectorSize;

// Release our reference on the context
FltReleaseContext( instContext );

// open the source file for copying its content
RtlInitUnicodeString(&fileName, SrcFilePath);
InitializeObjectAttributes(&objectAttr,
&fileName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwOpenFile(&hSrcFile,
DELETE | SYNCHRONIZE | GENERIC_READ,
&objectAttr,
&ioStatusZW,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
if (STATUS_SUCCESS != status)
{
return FALSE;
}

// get file’s handle
status = ObReferenceObjectByHandle(hSrcFile,
FILE_READ_ACCESS,
*IoFileObjectType,
KernelMode,
&ObSrcFile, 0);
if (STATUS_SUCCESS == status)
{
// copy file data
status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
Data->Iopb->SrcFileObject, 10 * SectorSize);
ObDereferenceObject(ObSrcFile);

// delete the source file if copy successful
if (STATUS_SUCCESS == status)
{
FILE_DISPOSITION_INFORMATION delInfo;
delInfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hSrcFile,
&ioStatusZW, &delInfo, sizeof(delInfo),
FileDispositionInformation);
}
}

ZwClose(hSrcFile);

if (STATUS_SUCCESS != status)
return FALSE;

return TRUE;
}

NTSTATUS MfCopyData(
IN PFLT_INSTANCE Instance,
IN PFILE_OBJECT SrcFile,
IN PFILE_OBJECT DestFile,
IN USHORT BufferSize
)
{
PVOID buffer;
NTSTATUS status;
FILE_POSITION_INFORMATION posInfo;

// allocate copy buffer
buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
BufferSize, POOL_TAG );
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
}

while (TRUE)
{
ULONG bytesRead = 0;
ULONG bytesWritten = 0;

status = FltReadFile( Instance, SrcFile, NULL,
BufferSize, buffer,
FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
if (!NT_SUCCESS(status) || 0 == bytesRead)
break;

// write data to destination file
status = FltWriteFile( Instance, DestFile, NULL,
bytesRead, buffer,
FLTFL_IO_OPERATION_NON_CACHED,
&bytesWritten, NULL, NULL );
if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
break;
}

FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );

// reset file pointer of destination file
posInfo.CurrentByteOffset.QuadPart = 0;
status = FltSetInformationFile( Instance, DestFile, &posInfo,
sizeof(posInfo), FilePositionInformation);
return status;
}

Where to start…

  1. Why do you want to do it in pre-read? Pre- or post-create seem more
    appropriate. Sharing violations would seem to be a potential problem.
    Also, most of your operations must be done at PASSIVE_LEVEL, and I think
    pre-read can be called at IRQL = APC_LEVEL and in an arbitrary thread
    context.

  2. Use the Fltxxx versions of ZwOpenFile, ZwSetInformationFile, ZwClose
    (*especially* ZwOpenFile).

  3. You don’t know the results of your read and/or write operations because
    “status” gets overwritten by the FltSetInformationFile() call. Maybe the
    read operation is terminating prematurely and you don’t know it.

  4. You’re mixing Zwxxx and Fltxxx routines – I’m not sure what the results
    are, but it’s probably a Bad Idea.

With respect, it looks like you’re way off track here.

Ken

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shangwu
Sent: Wednesday, May 11, 2005 3:15 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] kernel file copy and MJ_READ problem

Hello,

My minifilter does a file copy in its pre-read routine. When a MJ_READ
request comes for fileA whose content is empty, the filter copies data from
fileB to fileA and let the request continues. The problem is that if I read
fileA by DOS command type “c:\>type fileA”, it only shows the beginning part

content of the file. If I open it by Notepad.exe, it shows the whole content

of the file. Below is my file copy code. Please advise me what I can do
else. - Thanks.

BOOLEAN
MfCopyFile(
IN PFLT_CALLBACK_DATA Data,
IN PWSTR SrcFilePath
)
{
OBJECT_ATTRIBUTES objectAttr;
IO_STATUS_BLOCK ioStatusZW;
HANDLE hSrcFile;
PFILE_OBJECT ObSrcFile;
NTSTATUS status;
UNICODE_STRING fileName;
PFILTER_INSTANCE_CONTEXT instContext;
USHORT SectorSize;

// Get the context.
status = FltGetInstanceContext( Data->Iopb->SrcInstance,
&instContext );
if (!NT_SUCCESS(status))
{
return FALSE;
}
SectorSize = instContext->SectorSize;

// Release our reference on the context
FltReleaseContext( instContext );

// open the source file for copying its content
RtlInitUnicodeString(&fileName, SrcFilePath);
InitializeObjectAttributes(&objectAttr,
&fileName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwOpenFile(&hSrcFile,
DELETE | SYNCHRONIZE | GENERIC_READ,
&objectAttr,
&ioStatusZW,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
if (STATUS_SUCCESS != status)
{
return FALSE;
}

// get file’s handle
status = ObReferenceObjectByHandle(hSrcFile,
FILE_READ_ACCESS,
*IoFileObjectType,
KernelMode,
&ObSrcFile, 0);
if (STATUS_SUCCESS == status)
{
// copy file data
status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
Data->Iopb->SrcFileObject, 10 * SectorSize);
ObDereferenceObject(ObSrcFile);

// delete the source file if copy successful
if (STATUS_SUCCESS == status)
{
FILE_DISPOSITION_INFORMATION delInfo;
delInfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hSrcFile,
&ioStatusZW, &delInfo, sizeof(delInfo),
FileDispositionInformation);
}
}

ZwClose(hSrcFile);

if (STATUS_SUCCESS != status)
return FALSE;

return TRUE;
}

NTSTATUS MfCopyData(
IN PFLT_INSTANCE Instance,
IN PFILE_OBJECT SrcFile,
IN PFILE_OBJECT DestFile,
IN USHORT BufferSize
)
{
PVOID buffer;
NTSTATUS status;
FILE_POSITION_INFORMATION posInfo;

// allocate copy buffer
buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
BufferSize, POOL_TAG );
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
}

while (TRUE)
{
ULONG bytesRead = 0;
ULONG bytesWritten = 0;

status = FltReadFile( Instance, SrcFile, NULL,
BufferSize, buffer,
FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
if (!NT_SUCCESS(status) || 0 == bytesRead)
break;

// write data to destination file
status = FltWriteFile( Instance, DestFile, NULL,
bytesRead, buffer,
FLTFL_IO_OPERATION_NON_CACHED,
&bytesWritten, NULL, NULL );
if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
break;
}

FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );

// reset file pointer of destination file
posInfo.CurrentByteOffset.QuadPart = 0;
status = FltSetInformationFile( Instance, DestFile, &posInfo,
sizeof(posInfo), FilePositionInformation);
return status;
}


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

You are currently subscribed to ntfsd as: xxxxx@comcast.net
To unsubscribe send a blank email to xxxxx@lists.osr.com

Ken,

Thanks for the input. Here are answers for your questions.

  1. Why do you want to do it in pre-read?
    I want to avoid copies when Explorer browses files. Pre-read should be at
    PASSIVE_LEVEL.
  1. Use the Fltxxx versions of ZwOpenFile, ZwSetInformationFile, ZwClose
    (*especially* ZwOpenFile).
    It seems that those functions are not related to the problem.
  1. You don’t know the results of your read and/or write operations
    because
    “status” gets overwritten by the FltSetInformationFile() call.
    I removed some error checks from the posting to make it shorter. I am sure
    read/write operations completed successfully.
  1. You’re mixing Zwxxx and Fltxxx routines – I’m not sure what the
    results
    are, but it’s probably a Bad Idea.
    Some ZwXX functions have fewer paramters. So I like an easy way if it
    doesn’t cause any problem.

Regards,

Shangwu

“Ken Cross” wrote in message news:xxxxx@ntfsd…
> Where to start…
>
> 1. Why do you want to do it in pre-read? Pre- or post-create seem more
> appropriate. Sharing violations would seem to be a potential problem.
> Also, most of your operations must be done at PASSIVE_LEVEL, and I think
> pre-read can be called at IRQL = APC_LEVEL and in an arbitrary thread
> context.
>
> 2. Use the Fltxxx versions of ZwOpenFile, ZwSetInformationFile, ZwClose
> (especially ZwOpenFile).
>
> 3. You don’t know the results of your read and/or write operations
> because
> “status” gets overwritten by the FltSetInformationFile() call. Maybe the
> read operation is terminating prematurely and you don’t know it.
>
> 4. You’re mixing Zwxxx and Fltxxx routines – I’m not sure what the
> results
> are, but it’s probably a Bad Idea.
>
> With respect, it looks like you’re way off track here.
>
> Ken
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Shangwu
> Sent: Wednesday, May 11, 2005 3:15 PM
> To: Windows File Systems Devs Interest List
> Subject: [ntfsd] kernel file copy and MJ_READ problem
>
> Hello,
>
> My minifilter does a file copy in its pre-read routine. When a MJ_READ
> request comes for fileA whose content is empty, the filter copies data
> from
> fileB to fileA and let the request continues. The problem is that if I
> read
> fileA by DOS command type “c:>type fileA”, it only shows the beginning
> part
>
> content of the file. If I open it by Notepad.exe, it shows the whole
> content
>
> of the file. Below is my file copy code. Please advise me what I can do
> else. - Thanks.
>
> BOOLEAN
> MfCopyFile(
> IN PFLT_CALLBACK_DATA Data,
> IN PWSTR SrcFilePath
> )
> {
> OBJECT_ATTRIBUTES objectAttr;
> IO_STATUS_BLOCK ioStatusZW;
> HANDLE hSrcFile;
> PFILE_OBJECT ObSrcFile;
> NTSTATUS status;
> UNICODE_STRING fileName;
> PFILTER_INSTANCE_CONTEXT instContext;
> USHORT SectorSize;
>
> // Get the context.
> status = FltGetInstanceContext( Data->Iopb->SrcInstance,
> &instContext );
> if (!NT_SUCCESS(status))
> {
> return FALSE;
> }
> SectorSize = instContext->SectorSize;
>
> // Release our reference on the context
> FltReleaseContext( instContext );
>
> // open the source file for copying its content
> RtlInitUnicodeString(&fileName, SrcFilePath);
> InitializeObjectAttributes(&objectAttr,
> &fileName,
> OBJ_KERNEL_HANDLE,
> NULL,
> NULL);
> status = ZwOpenFile(&hSrcFile,
> DELETE | SYNCHRONIZE | GENERIC_READ,
> &objectAttr,
> &ioStatusZW,
> FILE_SHARE_READ,
> FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
> if (STATUS_SUCCESS != status)
> {
> return FALSE;
> }
>
> // get file’s handle
> status = ObReferenceObjectByHandle(hSrcFile,
> FILE_READ_ACCESS,
> *IoFileObjectType,
> KernelMode,
> &ObSrcFile, 0);
> if (STATUS_SUCCESS == status)
> {
> // copy file data
> status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
> Data->Iopb->SrcFileObject, 10 * SectorSize);
> ObDereferenceObject(ObSrcFile);
>
> // delete the source file if copy successful
> if (STATUS_SUCCESS == status)
> {
> FILE_DISPOSITION_INFORMATION delInfo;
> delInfo.DeleteFile = TRUE;
> status = ZwSetInformationFile(hSrcFile,
> &ioStatusZW, &delInfo, sizeof(delInfo),
> FileDispositionInformation);
> }
> }
>
> ZwClose(hSrcFile);
>
> if (STATUS_SUCCESS != status)
> return FALSE;
>
> return TRUE;
> }
>
>
> NTSTATUS MfCopyData(
> IN PFLT_INSTANCE Instance,
> IN PFILE_OBJECT SrcFile,
> IN PFILE_OBJECT DestFile,
> IN USHORT BufferSize
> )
> {
> PVOID buffer;
> NTSTATUS status;
> FILE_POSITION_INFORMATION posInfo;
>
> // allocate copy buffer
> buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
> BufferSize, POOL_TAG );
> if (NULL == buffer)
> {
> return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
> }
>
> while (TRUE)
> {
> ULONG bytesRead = 0;
> ULONG bytesWritten = 0;
>
> status = FltReadFile( Instance, SrcFile, NULL,
> BufferSize, buffer,
> FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
> if (!NT_SUCCESS(status) || 0 == bytesRead)
> break;
>
> // write data to destination file
> status = FltWriteFile( Instance, DestFile, NULL,
> bytesRead, buffer,
> FLTFL_IO_OPERATION_NON_CACHED,
> &bytesWritten, NULL, NULL );
> if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
> break;
> }
>
> FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );
>
> // reset file pointer of destination file
> posInfo.CurrentByteOffset.QuadPart = 0;
> status = FltSetInformationFile( Instance, DestFile, &posInfo,
> sizeof(posInfo), FilePositionInformation);
> return status;
> }
>
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@comcast.net
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

>> 1. Why do you want to do it in pre-read?

I want to avoid copies when Explorer browses files. Pre-read should be at
PASSIVE_LEVEL.

Well, I really think Ken is right. There were many questions
here “how to create file inside IRP_MJ_READ”, but the answer was
always “Do it inside IRP_MJ_CREATE”. I’m afraid if you
don’t do it that way, you’ll sooner or later have problems
that you’ve never dreamt of - sharing violations, even access
denied statuses. And also remember - if it will work on local drives,
it must not work on network drives, there are additional
sharing tests on the other side of the cable.

Although I don’t know what should your filter do,
I think a filter driver will never work when opening
files inside read/write (If I am wrong, correct me someone)

L.

…based on the symptoms you are seeing, my guess would be that the data
in the copied file contains an end of file marker (0x1A). The type
command would not show any data after this end of file marker but
notepad would. Try a hexdump of the file to see whether or not this is
in there.

Regards

Mark

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shangwu
Sent: 11 May 2005 20:15
To: Windows File Systems Devs Interest List
Subject: [ntfsd] kernel file copy and MJ_READ problem

Hello,

My minifilter does a file copy in its pre-read routine. When a MJ_READ
request comes for fileA whose content is empty, the filter copies data
from
fileB to fileA and let the request continues. The problem is that if I
read
fileA by DOS command type “c:\>type fileA”, it only shows the beginning
part
content of the file. If I open it by Notepad.exe, it shows the whole
content
of the file. Below is my file copy code. Please advise me what I can do
else. - Thanks.

BOOLEAN
MfCopyFile(
IN PFLT_CALLBACK_DATA Data,
IN PWSTR SrcFilePath
)
{
OBJECT_ATTRIBUTES objectAttr;
IO_STATUS_BLOCK ioStatusZW;
HANDLE hSrcFile;
PFILE_OBJECT ObSrcFile;
NTSTATUS status;
UNICODE_STRING fileName;
PFILTER_INSTANCE_CONTEXT instContext;
USHORT SectorSize;

// Get the context.
status = FltGetInstanceContext( Data->Iopb->SrcInstance,
&instContext );
if (!NT_SUCCESS(status))
{
return FALSE;
}
SectorSize = instContext->SectorSize;

// Release our reference on the context
FltReleaseContext( instContext );

// open the source file for copying its content
RtlInitUnicodeString(&fileName, SrcFilePath);
InitializeObjectAttributes(&objectAttr,
&fileName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwOpenFile(&hSrcFile,
DELETE | SYNCHRONIZE | GENERIC_READ,
&objectAttr,
&ioStatusZW,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
if (STATUS_SUCCESS != status)
{
return FALSE;
}

// get file’s handle
status = ObReferenceObjectByHandle(hSrcFile,
FILE_READ_ACCESS,
*IoFileObjectType,
KernelMode,
&ObSrcFile, 0);
if (STATUS_SUCCESS == status)
{
// copy file data
status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
Data->Iopb->SrcFileObject, 10 * SectorSize);
ObDereferenceObject(ObSrcFile);

// delete the source file if copy successful
if (STATUS_SUCCESS == status)
{
FILE_DISPOSITION_INFORMATION delInfo;
delInfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hSrcFile,
&ioStatusZW, &delInfo, sizeof(delInfo),
FileDispositionInformation);
}
}

ZwClose(hSrcFile);

if (STATUS_SUCCESS != status)
return FALSE;

return TRUE;
}

NTSTATUS MfCopyData(
IN PFLT_INSTANCE Instance,
IN PFILE_OBJECT SrcFile,
IN PFILE_OBJECT DestFile,
IN USHORT BufferSize
)
{
PVOID buffer;
NTSTATUS status;
FILE_POSITION_INFORMATION posInfo;

// allocate copy buffer
buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
BufferSize, POOL_TAG );
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
}

while (TRUE)
{
ULONG bytesRead = 0;
ULONG bytesWritten = 0;

status = FltReadFile( Instance, SrcFile, NULL,
BufferSize, buffer,
FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
if (!NT_SUCCESS(status) || 0 == bytesRead)
break;

// write data to destination file
status = FltWriteFile( Instance, DestFile, NULL,
bytesRead, buffer,
FLTFL_IO_OPERATION_NON_CACHED,
&bytesWritten, NULL, NULL );
if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
break;
}

FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );

// reset file pointer of destination file
posInfo.CurrentByteOffset.QuadPart = 0;
status = FltSetInformationFile( Instance, DestFile, &posInfo,
sizeof(posInfo), FilePositionInformation);
return status;
}


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

You are currently subscribed to ntfsd as: mark.cook@ca.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Ladislav,

Thanks for the input. My legacy filter driver does the copy on MJ_CREATE. It
cannot solve the browser problem. So I decide to do it on MJ_READ. I know
that Microsoft RSS uses the same approach to copy a file when a file is
read. Hopefully MS staff can give me some hint how to do this correctly.

Regards,

Shangwu

“Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
>>> 1. Why do you want to do it in pre-read?
>
>> I want to avoid copies when Explorer browses files. Pre-read should be at
>> PASSIVE_LEVEL.
>
> Well, I really think Ken is right. There were many questions
> here “how to create file inside IRP_MJ_READ”, but the answer was
> always “Do it inside IRP_MJ_CREATE”. I’m afraid if you
> don’t do it that way, you’ll sooner or later have problems
> that you’ve never dreamt of - sharing violations, even access
> denied statuses. And also remember - if it will work on local drives,
> it must not work on network drives, there are additional
> sharing tests on the other side of the cable.
>
> Although I don’t know what should your filter do,
> I think a filter driver will never work when opening
> files inside read/write (If I am wrong, correct me someone)
>
> L.
>
>

The problem is not creating a new file when you see a read, but rather
blocking the read until the new file has been created and copied. If
you use the read as a trigger event and initiate the copy (e.g., in a
work thread) then you won’t introduce a deadlock issue.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shangwu
Sent: Thursday, May 12, 2005 9:39 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Re:kernel file copy and MJ_READ problem

Ladislav,

Thanks for the input. My legacy filter driver does the copy on
MJ_CREATE. It
cannot solve the browser problem. So I decide to do it on MJ_READ. I
know
that Microsoft RSS uses the same approach to copy a file when a file is
read. Hopefully MS staff can give me some hint how to do this correctly.

Regards,

Shangwu

“Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
>>> 1. Why do you want to do it in pre-read?
>
>> I want to avoid copies when Explorer browses files. Pre-read should
be at
>> PASSIVE_LEVEL.
>
> Well, I really think Ken is right. There were many questions
> here “how to create file inside IRP_MJ_READ”, but the answer was
> always “Do it inside IRP_MJ_CREATE”. I’m afraid if you
> don’t do it that way, you’ll sooner or later have problems
> that you’ve never dreamt of - sharing violations, even access
> denied statuses. And also remember - if it will work on local drives,
> it must not work on network drives, there are additional
> sharing tests on the other side of the cable.
>
> Although I don’t know what should your filter do,
> I think a filter driver will never work when opening
> files inside read/write (If I am wrong, correct me someone)
>
> L.
>
>


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

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> My legacy filter driver does the copy on

MJ_CREATE. It cannot solve the browser problem.

Basically, you cannot write a filter some way “because an
application uses some certain approach”. IIRC the browser
problem for you was file reads when browsing folders
with Windows Explorer (If not, sorry for the mystification).
If the Windows Explorer is your only (and performance only)
problem, the file opening can be disabled using Explorer
policies. But remember - there always can be an application
which could do things the same way.

I know that Microsoft RSS uses the same approach to copy
a file when a file is read.

What is Microsoft RSS ?

L.


Stihle nohy? Pekny zadek? S N-Dorfiny za par babek! Inline brusle
Nike za super cenu od 2499 Kc + L-Carnitin a Chrom 20 ml ZDARMA!
http://www.sportobchod.cz/index_uvod.php?kat1=10

> What is Microsoft RSS ?
Remote Storage Service. It is a HSM product built in Windows 2000 server.

Thanks,

Shangwu

“Ladislav Zezula” wrote in message news:xxxxx@ntfsd…
>> My legacy filter driver does the copy on
>> MJ_CREATE. It cannot solve the browser problem.
>
> Basically, you cannot write a filter some way “because an
> application uses some certain approach”. IIRC the browser
> problem for you was file reads when browsing folders
> with Windows Explorer (If not, sorry for the mystification).
> If the Windows Explorer is your only (and performance only)
> problem, the file opening can be disabled using Explorer
> policies. But remember - there always can be an application
> which could do things the same way.
>
>> I know that Microsoft RSS uses the same approach to copy
>> a file when a file is read.
>
> What is Microsoft RSS ?
>
> L.
>
>
>
> –
> Stihle nohy? Pekny zadek? S N-Dorfiny za par babek! Inline brusle
> Nike za super cenu od 2499 Kc + L-Carnitin a Chrom 20 ml ZDARMA!
> http://www.sportobchod.cz/index_uvod.php?kat1=10
>
>

Let me describe the situation again. I create a tag file that points to
another file probably located remotely.
If the tag file is opened by a user program, my filter lets the open
completed successfully and trace its operations. When a READ comes, the
filter copies the file content from the target file to the tag file and lets
the READ continue.
If the tag file is created as a sparse file with original file size, then
the TYPE command can show the file content correctly. But NOTEPAD (run from
command line) shows it as an empty file although the file’s content is
copied successfully. I set break points in the code and found that NOTEPAD
does not issue a READ if the first CREATE returns an empty file (FCB value
of ValidDataLength is zero).
I tried to update FCB values which is pointed by FsContext, into some
integer. The system gives me an error message saying the file system is
corrupted.
So how can I set FCB values without cause any problem?

Thank you for any input.

Shangwu

My minifilter does a file copy in its pre-read routine. When a MJ_READ
request comes for fileA whose content is empty, the filter copies data
from fileB to fileA and let the request continues. The problem is that if
I read fileA by DOS command type “c:\>type fileA”, it only shows the
beginning part content of the file. If I open it by Notepad.exe, it shows
the whole content of the file. Below is my file copy code. Please advise
me what I can do else. - Thanks.

BOOLEAN
MfCopyFile(
IN PFLT_CALLBACK_DATA Data,
IN PWSTR SrcFilePath
)
{
OBJECT_ATTRIBUTES objectAttr;
IO_STATUS_BLOCK ioStatusZW;
HANDLE hSrcFile;
PFILE_OBJECT ObSrcFile;
NTSTATUS status;
UNICODE_STRING fileName;
PFILTER_INSTANCE_CONTEXT instContext;
USHORT SectorSize;

// Get the context.
status = FltGetInstanceContext( Data->Iopb->SrcInstance,
&instContext );
if (!NT_SUCCESS(status))
{
return FALSE;
}
SectorSize = instContext->SectorSize;

// Release our reference on the context
FltReleaseContext( instContext );

// open the source file for copying its content
RtlInitUnicodeString(&fileName, SrcFilePath);
InitializeObjectAttributes(&objectAttr,
&fileName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwOpenFile(&hSrcFile,
DELETE | SYNCHRONIZE | GENERIC_READ,
&objectAttr,
&ioStatusZW,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
if (STATUS_SUCCESS != status)
{
return FALSE;
}

// get file’s handle
status = ObReferenceObjectByHandle(hSrcFile,
FILE_READ_ACCESS,
*IoFileObjectType,
KernelMode,
&ObSrcFile, 0);
if (STATUS_SUCCESS == status)
{
// copy file data
status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
Data->Iopb->SrcFileObject, 10 * SectorSize);
ObDereferenceObject(ObSrcFile);

// delete the source file if copy successful
if (STATUS_SUCCESS == status)
{
FILE_DISPOSITION_INFORMATION delInfo;
delInfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hSrcFile,
&ioStatusZW, &delInfo, sizeof(delInfo),
FileDispositionInformation);
}
}

ZwClose(hSrcFile);

if (STATUS_SUCCESS != status)
return FALSE;

return TRUE;
}

NTSTATUS MfCopyData(
IN PFLT_INSTANCE Instance,
IN PFILE_OBJECT SrcFile,
IN PFILE_OBJECT DestFile,
IN USHORT BufferSize
)
{
PVOID buffer;
NTSTATUS status;
FILE_POSITION_INFORMATION posInfo;

// allocate copy buffer
buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
BufferSize, POOL_TAG );
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
}

while (TRUE)
{
ULONG bytesRead = 0;
ULONG bytesWritten = 0;

status = FltReadFile( Instance, SrcFile, NULL,
BufferSize, buffer,
FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
if (!NT_SUCCESS(status) || 0 == bytesRead)
break;

// write data to destination file
status = FltWriteFile( Instance, DestFile, NULL,
bytesRead, buffer,
FLTFL_IO_OPERATION_NON_CACHED,
&bytesWritten, NULL, NULL );
if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
break;
}

FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );

// reset file pointer of destination file
posInfo.CurrentByteOffset.QuadPart = 0;
status = FltSetInformationFile( Instance, DestFile, &posInfo,
sizeof(posInfo), FilePositionInformation);
return status;
}

> If the tag file is opened by a user program, my filter lets the open

completed successfully and trace its operations.

Is the tag file the same size like the “real” file ?
If not, you’ll experience problems with mismatched
file sizes.

When someone opens the tag file, you must open the remote
file. Then you have to redirect all operations on that tag file
to the remote file. Maybe reparsing will work for you ?

You also have to ensure that directory operations
will work as well. An application can (and often will)
query the directory where the file is stored for getting file
size, date or full name.

FYI: The approach yu want to implement seems to be similar
to the offline folders. They are implemented by the mrxsmb
redirector. If you open a network file (marked as offline)
and the remote computer is not available at the moment,
redirector opens the local copy of the file (usually
stored in %windir%\CSC) and lets the application think
that it works with the network file.

I tried to update FCB values which is pointed by FsContext, into some
integer. The system gives me an error message saying the file system is
corrupted.
So how can I set FCB values without cause any problem?

You cannot just change the FCB. It is from underlying file system,
so it does not belong to you. Never do this, unless you write
a layered file system driver. The values within FCB ar copied
to many places (e.g. cache is being initialized using them).

L.