FltReadFile STATUS_INVALID_PARAMETER

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.

Are you checking to ensure the status of the open is STATUS_SUCCESS and
you are not just checking for NT_SUCCESS()?

Pete

On 7/23/2013 9:36 AM, xxxxx@dsl.pipex.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.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

On Tue, 23 Jul 2013 12:54:39 -0600, Peter Scott
wrote:

>
>Are you checking to ensure the status of the open is STATUS_SUCCESS and
>you are not just checking for NT_SUCCESS()?
>
>Pete

I think my preamble is adequate.

PAGED_CODE();

if (FlagOn(Flags, FLTFL_POST_OPERATION_DRAINING)
|| !NT_SUCCESS(Data->IoStatus.Status)
|| Data->IoStatus.Status == STATUS_REPARSE)
{
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);

-----

A little more information. the failing read is actually the second read. The
first read succeeds. That is from byte zero of the file. That is perfect
alignment. AFAIK network sources do not demand any alignment requirement. In
the instance attach routine I call FltGetVolumeProperties for the network
instance this gives me a SectorSize and AlignmentRequirement of zero.

The read that is failing is for the last 18 bytes of the file.

Do I need to call FltGetVolumeProperties for every file open over the network?

Just to make the problem perplexing. The application opens the file many times
before and after this failure and this read succeeds. If the read was disallowed
by options surely the first read should fail also.

> 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”

Finally, when it does fail, show us the values of all the variables used
in the call.
joe


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

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

> 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.

Why would a native Windows app make POSIX calls?

Note that the kernel can’t tell a Win32 open call from a POSIX open call,
since both have lost their identity by the time the I/O Manager sees the
open request, which ultimately arrives in the form of a Native API open
request.

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.

When you say “it fails”, what fails? Is there any place where you blindly
trust some DDI call is going to work, and don’t test the return result?
Do you have debug print output or some kind of logging output that reports
meaningful information along all failure paths? Note that

NTSTATUS status;

status = SomeDDICall(…);
if(!NT_SUCCESS(status))
return status;

is exactly what you must NOT be doing, anywhere, for any reason, in your
debug build. Instead, it would be

if(!NT_SUCCESS(status))
{
…report useful information here. Typically FILE, LINE, some
text indicating some human-readable explanation of the failure, and
the exact status code, expressed in decimall and hexadecimal
return status;
}

You may, if you need to, put that reporting under an #ifdef DBG/#endif
conditional, but if you have code that looks like the first case, you need
to fix that problem. Guessing, or relying on etheric vibrations from the
crash dump, is not a particularly effective technique for debugging such
problems. Unless you can pin down an exact set of details about the
failure, there’s little hope of identifying it and fixing it.

Note that in the case of a DDI failure, it is often EXTREMELY valuable to
format and display in your debug output/logging/whatever mechanism, EACH
of the parameter values that may be relevant, such as the file name or
other things like that.

Nothing, not even having a live debugger, substitutes for a
well-instrumented piece of code capable of displaying useful information
of each failure.
joe

>
>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


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On Fri, 26 Jul 2013 04:21:01 -0400 (EDT), xxxxx@flounder.com wrote:

Why would a native Windows app make POSIX calls?

Note that the kernel can’t tell a Win32 open call from a POSIX open call,
since both have lost their identity by the time the I/O Manager sees the
open request, which ultimately arrives in the form of a Native API open
request.

I appreciate that. All I was saying was I was not certain that Quicktime used CreateFile or not. It is not an unreasonable given that its primary version is written in the Objective C Cocoa
environment which calls functions in one of Apple’s corefoundation libraries that end up at XNU in, I think, open_nocancel.

>
When you say “it fails”, what fails? Is there any place where you blindly
trust some DDI call is going to work, and don’t test the return result?
Do you have debug print output or some kind of logging output that reports
meaningful information along all failure paths? Note that

NTSTATUS status;

status = SomeDDICall(…);
if(!NT_SUCCESS(status))
return status;

is exactly what you must NOT be doing, anywhere, for any reason, in your
debug build. Instead, it would be

if(!NT_SUCCESS(status))
{
…report useful information here. Typically FILE, LINE, some
text indicating some human-readable explanation of the failure, and
the exact status code, expressed in decimall and hexadecimal
return status;
}

Like here. Ok its not perfect I do not differentiate between error code and not enough data. The DbgBreakPoint was a later addition once I saw this problem.

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;
}

Two lines from the debug trace.

EVSDecrypt:11: EVSPostOperationOpen: FileObject = 0xFFFFFA8009D39F20 \win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov
EVSDecrypt:10: EVSPostOperationOpen: FltReadFile(2):‘\win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov’: Status C000000D

From my debug message “dprintf” I can see that the error occured in the function EVSPostOperationOpen at the second use of FltReadFile and the status code was 0xC000000D. I looked
this up in NTStatus.h and saw it was STATUS_INVALID_PARAMETER.

My first assumption on seeing this message is something screwy is going on and a parameterIS invalid. So I added the DbgBreakPoint and looked at the values in WinDdg. I confirmed to my satisfaction
the the instance looks like an instance, the fileobject looks like a FileObject, the offset is within the file. The ReadSize is sensible, smaller than the buffer and offset+ReadSize is within the
file. The buffer (pTS) points to valid memory. BytesRead is declared as ULONG.

You may, if you need to, put that reporting under an #ifdef DBG/#endif
conditional, but if you have code that looks like the first case, you need

my dprintf function can be turned on and off at will.

to fix that problem. Guessing, or relying on etheric vibrations from the
crash dump, is not a particularly effective technique for debugging such
problems. Unless you can pin down an exact set of details about the
failure, there’s little hope of identifying it and fixing it.

Note that in the case of a DDI failure, it is often EXTREMELY valuable to
format and display in your debug output/logging/whatever mechanism, EACH
of the parameter values that may be relevant, such as the file name or
other things like that.

Nothing, not even having a live debugger, substitutes for a
well-instrumented piece of code capable of displaying useful information
of each failure.

I agree, I agree.
You seem to think I am a neophyte. I assure you I have been at this game for some time.
Having just grumbled at you I should say I appreciate your input now and consider other postings from you informed and worth reading.

STATUS_INVALID_PARAMETER is not the most useful error code. One of the problems I have is I am confident the parameters I supply are correct. This failure is the second read in the function. The
first was successful.

This is the end of the trace a little under 600 lines of well over 100 successful opens precede it. No preceding open has the same create options. It is amazing how often multimedia programs open and
close a file. I guess different codecs doing the same thing over and over again.

EVSDecrypt:8: EVSPreOperationOpen: FileObject = \win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov
EVSDecrypt:10: EVSFPreOperationOpen : Options = 01200000, Share Access = 0007, File Attributes = 0000, DesiredAccess = 00000080
EVSDecrypt:11: EVSPostOperationOpen: FileObject = 0xFFFFFA8009E386A0 \win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov
EVSDecrypt:10: Sector Size = 0, Alignment Requirement = 0
EVSDecrypt:11: EVSPostOperationOpen: FileID 32 F3 F4 3C 41 CF 48 CF 9F 44 56 6C 68 D5 AD D6
EVSDecrypt:11: EVSPreOperationCleanup: 0xFFFFFA8009E386A0 ‘\win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov’ Awaiting First Read
EVSDecrypt:18: Removing File Context open id=-1
EVSDecrypt:8: EVSPreOperationOpen: FileObject = \win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov
EVSDecrypt:10: EVSFPreOperationOpen : Options = 01000068, Share Access = 0003, File Attributes = 0000, DesiredAccess = 00120089
EVSDecrypt:11: EVSPostOperationOpen: FileObject = 0xFFFFFA8009E386A0 \win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov
EVSDecrypt:10: Sector Size = 0, Alignment Requirement = 0
EVSDecrypt:10: EVSPostOperationOpen: FltReadFile(2):‘\win-4gpe1lsdo1u\sHARE\Enc-Outsourced.mov’: Status C000000D

To contrast here is the trace when Quicktime opens the file stored on my local disc. Again around 600 lines above. Same request. Same Program. Same driver. Same machine. Same File. Successful result.

EVSDecrypt:8: EVSPreOperationOpen: FileObject = \Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov
EVSDecrypt:10: EVSFPreOperationOpen : Options = 01200000, Share Access = 0007, File Attributes = 0000, DesiredAccess = 00000080
EVSDecrypt:11: EVSPostOperationOpen: FileObject = 0xFFFFFA80080DE090 \Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov
EVSDecrypt:10: Sector Size = 512, Alignment Requirement = 1
EVSDecrypt:11: EVSPostOperationOpen: FileID 32 F3 F4 3C 41 CF 48 CF 9F 44 56 6C 68 D5 AD D6
EVSDecrypt:11: EVSPreOperationCleanup: 0xFFFFFA80080DE090 ‘\Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov’ Awaiting First Read
EVSDecrypt:18: Removing File Context open id=-1
EVSDecrypt:8: EVSPreOperationOpen: FileObject = \Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov
EVSDecrypt:10: EVSFPreOperationOpen : Options = 01000068, Share Access = 0003, File Attributes = 0000, DesiredAccess = 00120089
EVSDecrypt:11: EVSPostOperationOpen: FileObject = 0xFFFFFA80080DE090 \Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov
EVSDecrypt:10: Sector Size = 512, Alignment Requirement = 1
EVSDecrypt:11: EVSPostOperationOpen: FileID 32 F3 F4 3C 41 CF 48 CF 9F 44 56 6C 68 D5 AD D6
EVSDecrypt:11: EVSPreOperationCleanup: 0xFFFFFA80080DE090 ‘\Users\Ian.Blake.FORTIUM\Videos\From_Ceri\Media_9_8_2011_NO_PASSWORD\Enc-Outsourced.mov’ Awaiting First Read
EVSDecrypt:18: Removing File Context open id=-1

On Fri, 26 Jul 2013 13:48:41 +0100, Ian Blake wrote:

>On Fri, 26 Jul 2013 04:21:01 -0400 (EDT), xxxxx@flounder.com wrote:
>
>>Note that in the case of a DDI failure, it is often EXTREMELY valuable to
>>format and display in your debug output/logging/whatever mechanism, EACH
>>of the parameter values that may be relevant, such as the file name or
>>other things like that.

Spot on. I seem to have a slightly incorrect file length. So the problem is not with the read.
I compared the ReadLength the local disc version ReadLength from the Win 2008 share and they are slightly different.

I will investigate before I comment again. Thankyou for your time.

I spoke too soon

Failing version from Win2008 share

EVSDecrypt:10: EVSPostOperationOpen: Inst = FFFFFA8008E19010, FO = FFFFFA80087A58C0, Offset = 913029328, ReadSize = 18, Buffer FFFFF980014B8FB0

Working version from local disc

EVSDecrypt:10: EVSPostOperationOpen: Inst = FFFFFA8008D81190, FO = FFFFFA8008E8A530, Offset = 913029120, ReadSize = 226, Buffer FFFFF98001518BF0

Just the different alignment 512 on disc but I only align to 16 on the network becuase it did not demand any alignment

I set the alignment requirement to 512. The read now works.

So it seems if you are reading from a Win 2008 share some reads some of the time need 512 byte alignment.
This is just an assumption but it fixed my problem. Shame about my slightly higher memory use.

> Just the different alignment 512 on disc but I only align to 16 on the network becuase it did not

demand any alignment

Bad assumption, SMB sometimes demands an alignment, it depends on lots of factors (practically: today’s weather or such).


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

On Sun, 28 Jul 2013 23:32:59 +0400, “Maxim S. Shatskih” wrote:

>> Just the different alignment 512 on disc but I only align to 16 on the network becuase it did not
>>demand any alignment
>
>Bad assumption, SMB sometimes demands an alignment, it depends on lots of factors (practically: today’s weather or such).

Clearly.

Is there a better way to get the alignment? I am using FltGetVolumeProperties and looking at SectorSize and AlignmentRequirement both are zero for the network.

> Is there a better way to get the alignment?

I’m aware of none.

My personal code, though user mode, just does read probing and write probing for this.

It is simpler with the local disk FSs, where SetFilePointer is enough.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com