Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTFSD
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


async FltReadFile

Eugenio_BarahonaEugenio_Barahona Member Posts: 13
Hi all,

I have a mini filter that uses some code to read files from a preCreate callback. I am reading the file in blocks of 512 bytes, but the Information field at my IO_STATUS_BLOCK structure always is set to 1. I have checked the contents of the buffer where data is stored and the system is storing 512 bytes.

The code is like this:

NTSTATUS TestReadFile(IN CONST PFLT_INSTANCE Instance, IN CONST UNICODE_STRING& File, IN OUT PUCHAR Result)
{
IO_STATUS_BLOCK IoStatus;
PFILE_OBJECT FileObject = NULL;
HANDLE hFile = NULL;

NTSTATUS Status = GetFileObject(Instance, File, hFile, IoStatus, &FileObject);
if (!NT_SUCCESS(Status)) return Status;

PUCHAR ReadBuffer = (PUCHAR)FltAllocatePoolAlignedWithTag(Instance, NonPagedPool, 512, 'TEST');
if (!ReadBuffer) Status = STATUS_UNSUCCESSFUL;

KEVENT ReadCompletionEvent;
KeInitializeEvent(&ReadCompletionEvent, SynchronizationEvent, FALSE);

LARGE_INTEGER ByteOffset = { 0 };

while (Status == STATUS_SUCCESS)
{
Status = FltReadFile(Instance, FileObject, &ByteOffset, 512, ReadBuffer,
FLTFL_IO_OPERATION_NON_CACHED, NULL, (PFLT_COMPLETED_ASYNC_IO_CALLBACK)ReadCompletionRoutine,
&ReadCompletionEvent);

if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}

if (Status == STATUS_SUCCESS)
{
ByteOffset.QuadPart += IoStatus.Information;
}
}

if (Status == STATUS_END_OF_FILE)
{
Status = STATUS_SUCCESS;
}

if (ReadBuffer) FltFreePoolAlignedWithTag(Instance, ReadBuffer, 'TEST');
if (FileObject) ObDereferenceObject(FileObject);
if (hFile) FltClose(hFile);

return Status;
}

VOID ReadCompletionRoutine(IN PFLT_CALLBACK_DATA CallbackData, IN PFLT_CONTEXT Context)
{
UNREFERENCED_PARAMETER(CallbackData);

if (Context) KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
}

NTSTATUS GetFileObject(IN CONST PFLT_INSTANCE Instance, IN CONST UNICODE_STRING& File,
IN OUT HANDLE& FileHandle, IN OUT IO_STATUS_BLOCK& IoStatus,
IN OUT PFILE_OBJECT* FileObjectResult)
{
if (!m_Flt) return STATUS_UNSUCCESSFUL;
if (!Instance) return STATUS_UNSUCCESSFUL;
if (!FileObjectResult) return STATUS_UNSUCCESSFUL;

OBJECT_ATTRIBUTES Attr;
InitializeObjectAttributes(&Attr, (PUNICODE_STRING)&File, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

NTSTATUS Status = FltCreateFile(m_Flt, Instance, &FileHandle, FILE_READ_DATA /*| SYNCHRONIZE*/, &Attr, &IoStatus,
NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS, FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY , NULL, 0, 0);

if (NT_SUCCESS(Status))
{
PFILE_OBJECT Result = NULL;

Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_DATA, *IoFileObjectType,
KernelMode, reinterpret_cast<PVOID*>(&Result), NULL);
if (NT_SUCCESS(Status)) *FileObjectResult = Result;
}
return Status;
}

Thanks in advance.

Eugenio

Comments

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,337
    How big is the file? If it's 1 byte long then all is working as
    designed/expected.

    -scott
    OSR
    @OSRDrivers

    -scott
    OSR

  • Eugenio_BarahonaEugenio_Barahona Member Posts: 13
    Hi Scott,

    The file is 120 MB long.

    Eugenio
  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,337
    Sorry, I can't spot the problem. Have you put ProcMon under your filter to
    see what's coming out the bottom? If yes, then try using FileTest on another
    system and reading a file with the same arguments. You can then compare
    ProcMon traces and try to figure out what's going on.

    My only comment is that I'm not sure why you would bother using the
    asynchronous callback if you're just going to force the operation to be
    synchronous anyway?

    -scott
    OSR
    @OSRDrivers

    -scott
    OSR

  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,151
    I'd be inclined to set and access breakpoint on Iosb.Information and see
    what happens
  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,151
    So reading your code more closely.

    - you setup the IOSB in GetFileObject only. So the Information field is
    something like FILE_OPENED.
    - you never set the IOSB again. If you want to know the length written you
    will need to add the parameter to FltRead

    /Rod
  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,364
    You are passing NULL for a callback routine so your operation is performed
    synchronously, not asynchronously. Also why not provide the out parameter
    for BytesRead? I'll just guess that if you do that for the synchronous
    option (NULL callback) you will get the correct result.

    Mark Roddy


    On Wed, Aug 1, 2018 at 3:58 AM Rod Widdowson <
    [email protected]> wrote:

    > So reading your code more closely.
    >
    > - you setup the IOSB in GetFileObject only. So the Information field is
    > something like FILE_OPENED.
    > - you never set the IOSB again. If you want to know the length written
    > you
    > will need to add the parameter to FltRead
    >
    > /Rod
    >
    >
    > ---
    > NTFSD is sponsored by OSR
    >
    >
    > MONTHLY seminars on crash dump analysis, WDF, Windows internals and
    > software drivers!
    > Details at
    >
    > To unsubscribe, visit the List Server section of OSR Online at <
    > http://www.osronline.com/page.cfm?name=ListServer&gt;
    >
  • Eugenio_BarahonaEugenio_Barahona Member Posts: 13
    Hi all,

    The length written to the buffer and the final status of the read operation are at the CallbackData parameter received by the callback function. CallbackData->IoStatus has the status of the operation and the amount readed into the buffer.

    Thanks to all of you for your comments.

    Eugenio
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA