On Wed, 24 Jul 2013 05:25:46 -0400 (EDT), xxxxx@flounder.com wrote:
> I have a problem that I hope one of you may know the answer to. I am
> using FltReadFile in the post operation open call back to see if the file
> interests my decryption filter.
>
> Status = FltReadFile(FltObjects->Instance,
> Data->Iopb->TargetFileObject,
> &offset,
> ReadSize,
> pTS,
> FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET
> | FLTFL_IO_OPERATION_NON_CACHED,
> &BytesRead,
> NULL,
> NULL);
>
> ReadSize and offset are aligned. This call is used many times in different
> opens of the same file that do not fail.
>
> If the file I am using is on my local disc, or on most network shares the
> call succeeds. If the application triggers the same call when the file is
> on a share from Win 2008 server the call fails with
> STATUS_INVALID_PARAMETER (0xC000000D).
>
> Any suggestions are welcome.
>
>
First suggestion: show declarations and, when appropriate,
initializations, of all variables used in your example.
Then, I have no idea what you mean by the phrase “if the application
triggers the same call”
Sorry if I was not clear. The troublesome application is QuickTime.
The troublesome file is one of many encrypted .MOV video files.
Perhaps I should have said after several succesful opens (and closes) quicktime makes a particular CreateFile call that
results in the failure.
Quicktime and the driver is always on my win7 64 bit development machine
If the .MOV file is on a local disc this failure does NOT happen.
If the .MOV file is on my WinXP box this failure does NOT happen.
If the .MOV file is on my companies server Win2003 this failure does NOT happen.
If the .MOV file is on one of my Apple Macs this failure does NOT happen.
If the .MOV file is on a Win2008 server this failure DOES happen.
Quicktime makes many CreateFile (I assume, possibly posix open) calls before and after the failure without any problem.
I do not fail this open but the file was not reecognised and will not be decrypted. Quicktime continues but displays a
blank screen.
I admit I am not certain that Quicktime is treating the file the same way from all the file’s locations but I do not see
why it would not.
This driver has been out with customers for over a year and has been stable apart from this problem. It took a while to
track it down. The customers assertion doesn’t work on the network was a little broad because mostly it does. Once it
was narrowed to QuickTime Player and Win2008 server I could finally reproduce the problem everytime.
Finally, when it does fail, show us the values of all the variables used
in the call.
joe
Data->Iopb->TargetFileObject,
same as the first succesful read in this function
offset
Although the network does not impose alignment restrictions this driver defaults to 16 bytes. The end of file is
xxxxxxxE2. The object I want to read is the last 10 bytes of the file. offset is set to xxxxxxxD0. Verified in WinDbg
ReadSize
Orignally this was set to to 32 but when I was looking at this I added code to not read beyond the end so it is 18 now.
pTS
The same buffer supplied to first read.
Ok here is a more complete listing
FLT_POSTOP_CALLBACK_STATUS FLTAPI EVSFPostOperationOpen(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags)
{
NTSTATUS Status;
LARGE_INTEGER offset;
ULONG BytesRead = 0;
int once;
PVOID pHFPAlloc = NULL;
PHEADERFIXEDPART pHFP;
PVOID pFSIAlloc = NULL;
PFILE_STANDARD_INFORMATION pFSI;
PTAILSIGNATURE pTS = NULL;
PEVSFINSTANCECONTEXT pIContext;
ULONG ReadSize;
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
if (FlagOn(Flags, FLTFL_POST_OPERATION_DRAINING)
|| !NT_SUCCESS(Data->IoStatus.Status)
|| Data->IoStatus.Status == STATUS_REPARSE)
{
// if we are being unloaded or the open failed
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (Data->IoStatus.Status != STATUS_SUCCESS)
{
dprintf(DPF_FILTER, "EVSPostOperationOpen: called with non zero status %08X ‘%wZ’ ",
Data->IoStatus.Status,
&Data->Iopb->TargetFileObject->FileName);
}
dprintf(DPF_FILTER_NOISY, “EVSPostOperationOpen: FileObject = 0x%p %wZ”,
Data->Iopb->TargetFileObject,
&Data->Iopb->TargetFileObject->FileName);
FltGetInstanceContext(FltObjects->Instance, &pIContext);
for (once = TRUE; once; once = FALSE)
{
// We need to know if this is a directory and suitably large
pFSIAlloc = ExAllocateFromNPagedLookasideList(&Global.FSILookasideList);
if (pFSIAlloc == NULL) break;
// FltQueryInformationFile buffers must be 8 byte aligned
pFSI = Align8v(pFSIAlloc);
Status = FltQueryInformationFile(
FltObjects->Instance,
Data->Iopb->TargetFileObject,
pFSI,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation,
&BytesRead);
if (!NT_SUCCESS(Status) || BytesRead != sizeof(FILE_STANDARD_INFORMATION))
{
dprintf(DPF_FILTER, “EVSPostOperationOpen: FltQueryInformationFile (FSI):’ %wZ’: Status %08X”,
&Data->Iopb->TargetFileObject->FileName,
Status);
break;
}
if (pFSI->Directory) break;
if (pFSI->EndOfFile.QuadPart < EVSMinimumFileSize) break;
// We need to read some data to decide if this file is encrypted
// The header has a fixed part that contains the data we need to
// identify the need to decrypt this target.
// The header is sometimes located at the front of the file but can
// alternatively be located at the back.
// sizeof(&pHFPAlloc) is much greater than sizeof(HEADERFIXEDPART)
// it is sufficient to hold the sector alignment requiremenrs typically 2*512.
pHFPAlloc = ExAllocateFromPagedLookasideList(&pIContext->HFPLookasideList);
if (pHFPAlloc == NULL) break;
pHFP = (PHEADERFIXEDPART)(((ULONG_PTR)pHFPAlloc + pIContext->AlignmentRequirement) &
~pIContext->AlignmentRequirement);
// Read the fixed part of the header plus sector alignment
offset.QuadPart = 0;
Status = FltReadFile(FltObjects->Instance,
Data->Iopb->TargetFileObject,
&offset,
EVSFReadSize(pIContext, sizeof(HEADERFIXEDPART), offset.QuadPart),
pHFP,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET
| FLTFL_IO_OPERATION_NON_CACHED,
&BytesRead,
NULL,
NULL);
if (!NT_SUCCESS(Status) || BytesRead < sizeof(HEADERFIXEDPART))
{
dprintf(DPF_FILTER, “EVSPostOperationOpen: FltReadFile(1):‘%wZ’: Status %08X”,
&Data->Iopb->TargetFileObject->FileName,
Status);
break;
}
if (pHFP->Signature == kFileSignature)
{
// CODE REMOVED
break;
}
// sizeof(TAILSIGNATURE) is always less than sizeof(HEADERFIXEDPART)
// so the same buffer can be reused for the TAILSIGNATURE
pTS = (PTAILSIGNATURE)pHFP;
offset.QuadPart = pFSI->EndOfFile.QuadPart - sizeof(TAILSIGNATURE);
ReadSize = EVSFReadSize(pIContext, sizeof(TAILSIGNATURE), offset.QuadPart);
offset.QuadPart &=~(ULONGLONG)(pIContext->SectorSize - 1);
if (offset.QuadPart + ReadSize > pFSI->EndOfFile.QuadPart)
{
ReadSize = (ULONG)(pFSI->EndOfFile.QuadPart - offset.QuadPart);
}
Status = FltReadFile(FltObjects->Instance,
Data->Iopb->TargetFileObject,
&offset,
ReadSize,
pTS,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET
| FLTFL_IO_OPERATION_NON_CACHED,
&BytesRead,
NULL,
NULL);
if (!NT_SUCCESS(Status) || BytesRead < sizeof(TAILSIGNATURE))
{
dprintf(DPF_FILTER, “EVSPostOperationOpen: FltReadFile(2):‘%wZ’: Status %08X”,
&Data->Iopb->TargetFileObject->FileName,
Status);
DbgBreakPoint();
break;
}
pTS = Add2Ptr(pTS, (pFSI->EndOfFile.QuadPart - sizeof(TAILSIGNATURE)) & (pIContext->SectorSize - 1));
if (pTS->Signature != kFileSignature) break;
// Continues I
}
if (pHFPAlloc) ExFreeToPagedLookasideList(&pIContext->HFPLookasideList, pHFPAlloc);
if (pFSIAlloc) ExFreeToNPagedLookasideList(&Global.FSILookasideList, pFSIAlloc);
FltReleaseContext(pIContext);
return FLT_POSTOP_FINISHED_PROCESSING;
}
Ian Blake
Fortium Technologies