anton
Tue Aug 08 19:28:55 CDT 2006
Hi Jay
I have to repeat again - output buffer is the place where drivers
output data. Once you are on top of the stack and output buffer gets
filled by the lower-level driver, output buffer does not yet hold any
data at the time when you try to examine it. If you want to check data
in output buffer, you have to set IO completion routine before passing
IRP to the lower-level driver. By the time your completion routine gets
called, buffer will be already filled with data, so that you are able
to check it in IO completion routine.
In general, I would advise you to stop posting questions, and, instead,
read DDK documentation. This is an ABSOLUTE MUST - otherwise, you will
never learn anything . Everything you have asked us about in so far is
just fundamental DDK stuff, and DDK documentation provides not-so-bad
introduction to driver basics
Anton Bassov
patelj27b@gmail.com wrote:
> Mr. Bassov,
> Thanks for the comments. The thing is, it was freezing before I
> put in the ProbeForRead, and before I had the try-except block in
> there. Also, I have this attached to the tcp stack through:
>
> RtlInitUnicodeString(&usDeviceToFilter, L"\\Device\\Tcp");
> currStatus = IoGetDeviceObjectPointer(
> &usDeviceToFilter,FILE_READ_DATA,&pFileObject,&pNewDeviceObj);
>
> So, when a web browser is used, the data is passed down, and the
> OutputLength is large, while InputLength is 0. So, I would assume that
> the data being sent down the stack is being specified by OutputLength.
> Originally, the block looked like:
>
> if(OutputLength > 100)
> {
> for(i = 0;i < OutputLength;i++)
> {
> DbgPrint("IoBuffer[%d]=%02x\n",i,pIoBuffer[i]);
> }
> }
>
>
> and it would still freeze. Any ideas?
>
> Thanks for all the help!
> Jay
>
>
>
>
>
> anton bassov wrote:
> > Hi Jay
> >
> > The answer is plain obvious - ProbeForRead() checks whether user-mode
> > buffer actually resides in the user portion of the address space, and,
> > if its does not, it raises STATUS_ACCESS_VIOLATION exception.
> > Irp->AssociatedIrp.SystemBuffer resides in the kernel address space.
> > Have you got any more questions why you get
> > STATUS_ACCESS_VIOLATION?????
> >
> >
> > However, the system gets frozen for totally different reason - you
> > complete IRP if status STATUS_ACCESS_VIOLATION got raised, so that
> > lower-level driver does not receive it. This is the reason for the
> > ACTUAL(!!!) freeze - if you forwarded IRP to the lower-level driver
> > even if STATUS_ACCESS_VIOLATION gets raised (after all, this exception
> > has nothing to do with lower-level drivers, don't you think????), you
> > would not freeze.
> >
> >
> > Furthermore, as Don have already pointed out, in order to check
> > whether buffer has any data to be read, you should check
> > Parameters.DeviceIoControl.InputBufferLength, rather than
> > Parameters.DeviceIoControl.OutputBufferLength
> >
> >
> >
> > These are the bugs that I have noticed at the very first glance -
> > probably, there are few more left
> >
> > Anton Bassov
> >
> > Jay wrote:
> > > Hey There,
> > > The offending code segments look like this:
> > >
> > >
> > > NTSTATUS TDIIoControlInternal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
> > > {
> > > NTSTATUS NtStatus = STATUS_SUCCESS;
> > > PEXAMPLE_FILTER_EXTENSION pFilterDevContext =
> > > (PEXAMPLE_FILTER_EXTENSION)DeviceObject->DeviceExtension;
> > > PIO_STACK_LOCATION pIoStackIrp = NULL;
> > > PVOID IoBuffer = NULL;
> > > UCHAR tempVal;
> > > PUCHAR pIoBuffer;
> > > ULONG InputLength;
> > > ULONG OutputLength;
> > > unsigned int i;
> > >
> > > UNREFERENCED_PARAMETER(i);
> > > IoBuffer = Irp->AssociatedIrp.SystemBuffer;
> > > pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
> > > if(pIoStackIrp)
> > > {
> > > pIoBuffer = (PUCHAR)IoBuffer;
> > > tempVal = *pIoBuffer;
> > > InputLength =
> > > pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
> > > OutputLength =
> > > pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
> > >
> > > if((OutputLength > 0) && (OutputLength < 1000))
> > > {
> > > DbgPrint("OutputLength = %d\n",OutputLength);
> > >
> > > if(OutputLength > 100)
> > > {
> > > __try
> > > {
> > > ProbeForRead( IoBuffer, OutputLength, sizeof( UCHAR ) );
> > > }
> > > __except(EXCEPTION_EXECUTE_HANDLER)
> > > {
> > > NtStatus = GetExceptionCode();
> > > Irp->IoStatus.Status = NtStatus;
> > > IoCompleteRequest( Irp, IO_NO_INCREMENT );
> > > return NtStatus;
> > > }
> > > DbgPrint(("In If\n"));
> > > for(i = 0;i < OutputLength;i++)
> > > {
> > > __try
> > > {
> > > DbgPrint("IoBuffer[%d]=%02x\n",i,pIoBuffer[i]);
> > > }
> > > __except(EXCEPTION_EXECUTE_HANDLER)
> > > {
> > > NtStatus = GetExceptionCode();
> > > DbgPrint("****OutputLength= %d ****\n",OutputLength);
> > > DbgPrint("****InputLength= %d ****\n",InputLength);
> > > DbgPrint("*****Error = 0X%08X*****\n",NtStatus);
> > > break;
> > > }
> > > }
> > > }
> > > }
> > > }
> > >
> > > IoSkipCurrentIrpStackLocation(Irp);
> > > ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
> > > NtStatus = IoCallDriver(pFilterDevContext->pNextDeviceInChain, Irp);
> > > return NtStatus;
> > > }
> > >
> > > Inside DriverEntry:
> > >
> > > pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = TDICleanUp;
> > > pDriverObject->MajorFunction[IRP_MJ_CLOSE] = TDIClose;
> > > pDriverObject->MajorFunction[IRP_MJ_CREATE] = TDICreate;
> > > pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TDIIoControl;
> > > pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
> > > TDIIoControlInternal;
> > > pDriverObject->MajorFunction[IRP_MJ_READ] = TDIRead;
> > > pDriverObject->MajorFunction[IRP_MJ_WRITE] = TDIWrite;
> > >
> > > pDriverObject->DriverUnload = TDIUnload;
> > >
> > > pFilterDeviceContext =
> > > (PEXAMPLE_FILTER_EXTENSION)pDeviceObject->DeviceExtension;
> > >
> > > ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
> > > currStatus = IoGetDeviceObjectPointer(
> > > &usDeviceToFilter,FILE_READ_DATA,&pFileObject,&pNewDeviceObj);
> > >
> > > if(currStatus != STATUS_SUCCESS)
> > > {
> > > DbgPrint("IoGetDeviceObjectPointer was not successful\n");
> > > return currStatus;
> > > }
> > >
> > > ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
> > > pFilterDeviceContext->pNextDeviceInChain =
> > > IoAttachDeviceToDeviceStack(pDeviceObject, pNewDeviceObj);
> > > if(&pFilterDeviceContext->pNextDeviceInChain == NULL)
> > > {
> > > IoDeleteDevice(pDeviceObject);
> > > }
> > > else
> > > {
> > > pFilteredDevice = pFilterDeviceContext->pNextDeviceInChain;
> > > pDeviceObject->Flags |= pFilteredDevice->Flags & (DO_BUFFERED_IO |
> > > DO_DIRECT_IO);
> > > pDeviceObject->DeviceType = pFilteredDevice->DeviceType;
> > > pDeviceObject->Characteristics = pFilteredDevice->Characteristics;
> > > //pDeviceObject->Flags |= DO_BUFFERED_IO;
> > > pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
> > >
> > > DbgPrint("Flag = 0x%08X\n",pDeviceObject->Flags);
> > >
> > > }
> > > IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
> > >
> > >
> > >
> > > Any help would be greatly appreciated!
> > >
> > > Thanks,
> > > Jay
> > >
> > > anton bassov wrote:
> > > > Hi Don
> > > >
> > > > > There is no data in the buffer until you put it there since your
> > > > > InputBufferLength equals 0. You should be writing to the buffer, not
> > > > > reading it.
> > > >
> > > > It does not really matter - no matter what you do, you must be able to
> > > > access a system buffer without raising access violation. Therefore, we
> > > > need to see the what he does and how he does it - apparently, he has
> > > > made quite a few errors....
> > > >
> > > > Anton Bassov
> > > >
> > > >
> > > > Don Burn wrote:
> > > > > There is no data in the buffer until you put it there since your
> > > > > InputBufferLength equals 0. You should be writing to the buffer, not
> > > > > reading it.
> > > > >
> > > > >
> > > > > --
> > > > > Don Burn (MVP, Windows DDK)
> > > > > Windows 2k/XP/2k3 Filesystem and Driver Consulting
> > > > >
http://www.windrvr.com
> > > > > Remove StopSpam from the email to reply
> > > > >
> > > > >
> > > > >
> > > > > <patelj27b@gmail.com> wrote in message
> > > > > news:1154987157.944330.274450@b28g2000cwb.googlegroups.com...
> > > > > > Hey There,
> > > > > > If buffered I/O is being used and the
> > > > > > Parameters.DeviceIoControl.OutputBufferLength is > 0 while
> > > > > > Parameters.DeviceIoControl.InputBufferLength equals 0, the data should
> > > > > > be in AssociatedIrp.SystemBuffer. I create a variable IoBuffer that
> > > > > > equals AssociatedIrp.SystemBuffer and try to read the data in IoBuffer.
> > > > > > When this is executed, it generates a 0XC0000005 error, which is an
> > > > > > Access Violation Error. If the data should be there, what would cause
> > > > > > it to create that error?
> > > > > >
> > > > > > Thanks,
> > > > > > Jay
> > > > > >