CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    May 2009
    Posts
    16

    Weird IRP_MJ_READ behavior

    Hello. I'm having some weird behavior when handling IRP_MJ_READ inside my dispatched function. First of all, I check if ioStack->Parameters.Read.Length is 0 and if it is, I exit immediatly. But then...

    Code:
    case IRP_MJ_READ:
    		{
    			DTRACE0("ReadWrite - READ");
    			mdlBuffer = (PCHAR) MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    			if (mdlBuffer == NULL)
    			{
    				Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
    				Irp->IoStatus.Information = 0;
    				break;
    			}
    			DTRACE2("Reading from %u (%d)", ioStack->Parameters.Read.ByteOffset.QuadPart, ioStack->Parameters.Read.Length);
    			ZwReadFile(deviceExtension->fileHandle, NULL, NULL, NULL, &Irp->IoStatus, mdlBuffer, ioStack->Parameters.Read.Length, &ioStack->Parameters.Read.ByteOffset, NULL);
    			DTRACE3("Read %s from %u (%d)", ioStack->Parameters.Read.ByteOffset.QuadPart, mdlBuffer, ioStack->Parameters.Read.Length);
    			DTRACE1("IOSTATUS = %08X", Irp->IoStatus);
    			break;
    		}
    You can tell I'm using DO_DIRECT_IO.

    Here's some DebugView output (everywhere the read happens, it's the same, just the negative number changes):
    00000020 58.16388321 [DRV] : ReadWrite - READ
    00000021 58.16408539 [DRV] : Reading from 0 (0)
    00000022 58.16419220 [DRV] : Read (null) from 0 (-121745408)
    00000023 58.16429138 [DRV] : IOSTATUS = 00000000
    00000024 58.16435242 [DRV]<- ReadWrite
    00000027 58.16460037 [DRV] : ReadWrite - READ
    00000028 58.16460800 [DRV] : Reading from 32768 (0)
    00000029 58.16466141 [DRV] : IOSTATUS = 00000000
    00000030 58.16468048 [DRV]<- ReadWrite

    Some debug messages do not show up, but that's not a problem, for now. Does anyone know why I'm getting these weird values for ioStack->Parameters.Read.Length? It shouldn't be 0, since I do the check before:
    Code:
    if (ioStack->Parameters.Read.Length == 0)
    	{
    		Irp->IoStatus.Status = STATUS_SUCCESS;
    		Irp->IoStatus.Information = 0;
    		IoCompleteRequest(Irp, IO_NO_INCREMENT);
    		return STATUS_SUCCESS;
    	}
    Thanks to anyone willing to help.

  2. #2

    Re: Weird IRP_MJ_READ behavior

    Hello,

    Is the ioStack pointer being set up correctly and not being overwritten by another value?
    Try sticking in several traces to view the pointer value of ioStack

    It might also be a good idea to print out the value of "ioStack->Parameters.Read.Length" directly before the check is done to eliminate 0 length - and then print it out again slightly further down to see if its the same value.

    Peter

  3. #3
    Join Date
    May 2009
    Posts
    16

    Re: Weird IRP_MJ_READ behavior

    Thank your for your response. That's what I suspected as well, but I can't figure out what's happening or where.
    Code:
    DTRACE2("ioStack = %08x, Length=%d", ioStack, ioStack->Parameters.Read.Length);
    DTRACE2("Reading from %u - %d", ioStack->Parameters.Read.ByteOffset.QuadPart, ioStack->Parameters.Read.Length);
    DTRACE2("ioStack = %08X, Length=%d", ioStack, ioStack->Parameters.Read.Length);
    ZwReadFile(deviceExtension->fileHandle, NULL, NULL, NULL, &Irp->IoStatus, mdlBuffer, ioStack->Parameters.Read.Length, &ioStack->Parameters.Read.ByteOffset, NULL);
    DTRACE2("ioStack = %08X, Length=%d", ioStack, ioStack->Parameters.Read.Length);
    DTRACE2("Read    from %u - %d", ioStack->Parameters.Read.ByteOffset.QuadPart, ioStack->Parameters.Read.Length);
    DTRACE2("ioStack = %08X, Length=%d", ioStack, ioStack->Parameters.Read.Length);
    DTRACE1("IOSTATUS = %08X", Irp->IoStatus);
    This is what I have now. I assume that the offset is being displayed correctly, because it changes its value at different times. But this is what happens with the following code:
    00000021 22.22846031 [DRV] : ReadWrite - READ
    00000022 22.22847557 [DRV] : ioStack = 81FAAC68, Length=512
    00000023 22.22852325 [DRV] : ioStack = 81FAAC68, Length=512
    00000024 22.22855759 [DRV] : ioStack = 81FAAC68, Length=512
    00000025 22.22860336 [DRV] : Reading from 0 - 0
    00000026 22.22862434 [DRV] : ioStack = 81FAAC68, Length=512
    00000027 22.22866821 [DRV] : ioStack = 81FAAC68, Length=512
    00000028 22.22868347 [DRV] : Read from 0 - 0
    00000029 22.22870064 [DRV] : ioStack = 81FAAC68, Length=512
    00000030 22.22873306 [DRV] : IOSTATUS = 00000000

    The 2 lines - "Reading from 0 - 0" and "Read from 0 - 0" are incorrect, but I can see that Length is the correct value when I print it before AND after. I can't understand why.

  4. #4

    Re: Weird IRP_MJ_READ behavior

    Hello

    What values does it display, if you change the "&#37;u" in the DTRACE format string for "reading" and "read" to "%d" or "%08x" ?

    like this:

    Code:
    DTRACE2("Reading from %d - %d", ioStack->Parameters.Read.ByteOffset.QuadPart, ioStack->Parameters.Read.Length);
    Peter

  5. #5
    Join Date
    May 2009
    Posts
    16

    Re: Weird IRP_MJ_READ behavior

    Both are 0 (or 0x00000000 for that matter), just as they are now. I can't explain it.

  6. #6

    Re: Weird IRP_MJ_READ behavior

    Hello,

    Using a kernel level debugger program can be very useful in this sort of situation to follow through step by step, watching what happens to those variables.

    Where does the DTRACE set of macros come from? Its just that its a bit strange that it appears to print things out multiple times - could it be that its going a bit wrong with the values as well?

    Peter

  7. #7
    Join Date
    May 2009
    Posts
    16

    Re: Weird IRP_MJ_READ behavior

    DTRACEs are nothing more than macro wrappers over KdPrint.

    So, I started using WinDbg to debug in kernel mode. The problem which I see now (let's completely ignore the previous) is that ZwReadFile sets Irp->IoStatus.Information to 0 (according to MSDN, this means it read 0 bytes). I can see that the first byte of the buffer it set to NULL, but ZwReadFile returns STATUS_SUCCESS. The file is already opened.

    What I'm doing is redirecting read requests and reading from a file instead of a disc. So the question is: why can't I read from the file? Any suggestion is appreciated.

  8. #8

    Re: Weird IRP_MJ_READ behavior

    Hello,

    Which function call is being used to open the file? - presumably there is something already in the file to begin with?

    Also, check that the byte offset and length parameters are multiples of the sector size


    Peter

  9. #9
    Join Date
    May 2009
    Posts
    16

    Re: Weird IRP_MJ_READ behavior

    ZwCreateFile, of course. I'm using the GENERIC_READ | GENERIC_WRITE flags, also FILE_RANDOM_ACCESS. The handle is valid, and I'm also using ZwQueryFileInformation to get the alignment, and then settting DeviceObject->AlignmentRequirement accordingly. And yes, the sector size is 512 bytes, and Length and Offset are multiples of it.

    EDIT. I found something. Previously, I was only checking IoStatus->Status for errors, but now I see that ZwReadFile returns 0x00000008 ("Not enough storage is available to process this command."). Odd enough, I'm allocating another buffer with the specified Read.Length and reading to it. Another return value I'm getting is 0x8050780D (?!?!?!?!?!).
    Last edited by TehPwner; May 31st, 2009 at 11:04 AM.

  10. #10

    Re: Weird IRP_MJ_READ behavior

    Hello

    ZwCreateFile will create an empty file if it cannot find the specified file(eg wrong path), whereas ZwOpenFile will return an error if the file doesnt already exist. Its not important other than a question of knowing that the correct file in the correct location has been found and opened.

    Peter

  11. #11
    Join Date
    May 2009
    Posts
    16

    Re: Weird IRP_MJ_READ behavior

    The file name should be correct, because on the open handle I then query both FILE_STANDARD_INFORMATION (to get the size in bytes - which is the correct value) and FILE_ALIGNMENT_INFORMATION. Specifying the FILE_OPEN flag to ZwCreateFile will open if (if it exists) or return an error (if it doesn't).

  12. #12

    Re: Weird IRP_MJ_READ behavior

    Hello,

    You're quite right about the FILE_OPEN with ZwCreateFile. I had missed seeing that bit.

    Just out of interest, how much data is trying to be read in, is it very big?

    As a test - what happens if the length is fixed to something small - like 512 - and the offset is set to zero, it might not read in the entire file, but would show whether it could at least read in something from the file.

    Peter

  13. #13
    Join Date
    May 2009
    Posts
    16

    Post Re: Weird IRP_MJ_READ behavior

    I finally figured it all out.

    I made a mistake displaying ZwReadFile's return error. Once fixed, I noticed it actually returns 0xC0000024. A quick Google led me to this thread - http://www.osronline.com/showThread.cfm?link=29913

    Adding the OBJ_KERNEL_HANDLE to InitializeObjectAttributes, as "Tony Mason" stated there, fixed all my errors. Both reading and writing work flawlessly.

    Thanks Peter, for bearing with me.
    Last edited by TehPwner; June 3rd, 2009 at 09:13 AM.

  14. #14

    Re: Weird IRP_MJ_READ behavior

    Hello,

    Great! Well done on getting it to work!

    Peter

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured