Ejemplo n.º 1
0
VOID
NonPnpEvtDeviceIoInCallerContext(
    IN WDFDEVICE  Device,
    IN WDFREQUEST Request
    )
/*++
Routine Description:

    This I/O in-process callback is called in the calling threads context/address
    space before the request is subjected to any framework locking or queueing
    scheme based on the device pnp/power or locking attributes set by the
    driver. The process context of the calling app is guaranteed as long as
    this driver is a top-level driver and no other filter driver is attached
    to it.

    This callback is only required if you are handling method-neither IOCTLs,
    or want to process requests in the context of the calling process.

    Driver developers should avoid defining neither IOCTLs and access user
    buffers, and use much safer I/O tranfer methods such as buffered I/O
    or direct I/O.

Arguments:

    Device - Handle to a framework device object.

    Request - Handle to a framework request object. Framework calls
              PreProcess callback only for Read/Write/ioctls and internal
              ioctl requests.

Return Value:

    VOID

--*/
{
    NTSTATUS                   status = STATUS_SUCCESS;
    PREQUEST_CONTEXT            reqContext = NULL;
    WDF_OBJECT_ATTRIBUTES           attributes;
    WDF_REQUEST_PARAMETERS  params;
    size_t              inBufLen, outBufLen;
    PVOID              inBuf, outBuf;

    PAGED_CODE();

    WDF_REQUEST_PARAMETERS_INIT(&params);

    WdfRequestGetParameters(Request,  &params );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "Entered NonPnpEvtDeviceIoInCallerContext %p \n",
                            Request);

    //
    // Check to see whether we have recevied a METHOD_NEITHER IOCTL. if not
    // just send the request back to framework because we aren't doing
    // any pre-processing in the context of the calling thread process.
    //
    if(!(params.Type == WdfRequestTypeDeviceControl &&
            params.Parameters.DeviceIoControl.IoControlCode ==
                                    IOCTL_NONPNP_METHOD_NEITHER)) {
        //
        // Forward it for processing by the I/O package
        //
        status = WdfDeviceEnqueueRequest(Device, Request);
        if( !NT_SUCCESS(status) ) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                        "Error forwarding Request 0x%x",  status);
            goto End;
        }

        return;
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "EvtIoPreProcess: received METHOD_NEITHER ioctl \n");

    //
    // In this type of transfer, the I/O manager assigns the user input
    // to Type3InputBuffer and the output buffer to UserBuffer of the Irp.
    // The I/O manager doesn't copy or map the buffers to the kernel
    // buffers.
    //
    status = WdfRequestRetrieveUnsafeUserInputBuffer(Request, 0, &inBuf, &inBufLen);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfRequestRetrieveUnsafeUserInputBuffer failed 0x%x",  status);
        goto End;
    }

    status = WdfRequestRetrieveUnsafeUserOutputBuffer(Request, 0, &outBuf, &outBufLen);
    if(!NT_SUCCESS(status)) {
       TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfRequestRetrieveUnsafeUserOutputBuffer failed 0x%x",  status);
       goto End;
    }

    //
    // Allocate a context for this request so that we can store the memory
    // objects created for input and output buffer.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, REQUEST_CONTEXT);

    status = WdfObjectAllocateContext(Request, &attributes, &reqContext);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfObjectAllocateContext failed 0x%x",  status);
        goto End;
    }

    //
    // WdfRequestProbleAndLockForRead/Write function checks to see
    // whether the caller in the right thread context, creates an MDL,
    // probe and locks the pages, and map the MDL to system address
    // space and finally creates a WDFMEMORY object representing this
    // system buffer address. This memory object is associated with the
    // request. So it will be freed when the request is completed. If we
    // are accessing this memory buffer else where, we should store these
    // pointers in the request context.
    //

    #pragma prefast(suppress:6387, "If inBuf==NULL at this point, then inBufLen==0")    
    status = WdfRequestProbeAndLockUserBufferForRead(Request,
                            inBuf,
                            inBufLen,
                            &reqContext->InputMemoryBuffer);

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfRequestProbeAndLockUserBufferForRead failed 0x%x",  status);
        goto End;
    }

    #pragma prefast(suppress:6387, "If outBuf==NULL at this point, then outBufLen==0") 
    status = WdfRequestProbeAndLockUserBufferForWrite(Request,
                            outBuf,
                            outBufLen,
                            &reqContext->OutputMemoryBuffer);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfRequestProbeAndLockUserBufferForWrite failed 0x%x",  status);
        goto End;
    }

    //
    // Finally forward it for processing by the I/O package
    //
    status = WdfDeviceEnqueueRequest(Device, Request);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                                    "Error WdfDeviceEnqueueRequest failed 0x%x",  status);
        goto End;
    }

    return;

End:

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "EvtIoPreProcess failed %x \n", status);
    WdfRequestComplete(Request, status);
    return;
}
Ejemplo n.º 2
0
			break;
		case WdfRequestTypeWrite:
			DEBUG("Intercepted Write IRP");
			status = WdfRequestRetrieveInputBuffer(	Request,	//!todo This should work for BUFFERED and DIRECT, but I think it will break for Neither !!
													1,
													(PVOID)&buf,
													&bufLength);
			CHECKSTATUS(status, ERROR("Failed to retrieve intercepted write buffer. 0x%0.4", status); break;);
			DEBUG("Intercepted Write of %d bytes: %#0.2x ...", bufLength, (unsigned char)buf[0]);			
			//!todo place the buf into the RAW PDO context
			break;
		// All else can just be passed on...
	}

	// Try to pass this down the stack
	status = WdfDeviceEnqueueRequest(	Device, 
					 					Request);
	if (!NT_SUCCESS(status))		
	{
		// If we failed then complete it with an error
		ERROR("Error passing Intercepted IO request on, completing it ourself.");
		WdfRequestComplete(Request,
						   status);
	}
}
#else
// Filter read
VOID GFilterRead(	IN 	WDFQUEUE		Queue,
					IN	WDFREQUEST		Request,
					IN	size_t			Length)
{
	NTSTATUS					status = STATUS_ABANDONED;