// =========================================================================
NTSTATUS
QueueIRPToThread(
    IN  PDEVICE_OBJECT DeviceObject,    
    IN  PIRP           Irp
)
{
    PDEVICE_EXTENSION devExt;
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("QueueIrpToThread\n"));
    
    devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    
    status = STATUS_PENDING;                
      
    // Note: IoCsqInsertIrp marks the IRP pending.
    IoCsqInsertIrp(&devExt->CancelSafeQueue, Irp, NULL);

    // A semaphore remains signaled as long as its count is greater than 
    // zero, and non-signaled when the count is zero. Following function 
    // increments the semaphore count by 1.
    KeReleaseSemaphore(
                        &devExt->IRPQueueSemaphore,
                        0,  // No priority boost
                        1,  // Increment semaphore by 1
                        FALSE  // No WaitForXxx after this call
                        );

            
    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("QueueIrpToThread\n"));
    
    return status;
}    
Example #2
0
NTSTATUS NTAPI DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	/* According to the cancel sample in the DDK, IoCsqInsertIrp() marks the irp pending */
	/* However, I think it's wrong. */
	IoMarkIrpPending(Irp);
	IoCsqInsertIrp(&Csq, Irp, 0);

	return STATUS_PENDING;
}
Example #3
0
NTSTATUS FileRead(__in BASE_FILE * File, __in PIRP Irp,
		  __in PIO_STACK_LOCATION IrpStack)
{
	CSFBR_FILE_DATA *FileData =
	    (CSFBR_FILE_DATA *) BaseFileGetPrivate(File);

	UNREFERENCED_PARAMETER(IrpStack);

	ASSERT(Irp->MdlAddress);
	TRACE_MSG(TRACE_LEVEL_INFO, TRACE_FLAG_DEFAULT, "Read %u bytes\n",
		  IrpStack->Parameters.Write.Length);

	IoCsqInsertIrp(&FileData->csq, Irp, NULL);

	NotifyReceivedPacket(File);

	return STATUS_PENDING;
}
Example #4
0
NTSTATUS NTAPI
ReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
 * FUNCTION: Dispatch routine called for read or write IRPs
 * ARGUMENTS:
 * RETURNS:
 *     STATUS_PENDING if the IRP is queued
 *     STATUS_INVALID_PARAMETER if IRP is set up wrong
 * NOTES:
 *     - This function validates arguments to the IRP and then queues it
 *     - Note that this function is implicitly serialized by the queue logic.  Only
 *       one of these at a time is active in the system, no matter how many processors
 *       and threads we have.
 *     - This function stores the DeviceObject in the IRP's context area before dropping
 *       it onto the irp queue
 */
{
    TRACE_(FLOPPY, "ReadWrite called\n");

    ASSERT(DeviceObject);
    ASSERT(Irp);

    if(!Irp->MdlAddress)
    {
        WARN_(FLOPPY, "ReadWrite(): MDL not found in IRP - Completing with STATUS_INVALID_PARAMETER\n");
        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INVALID_PARAMETER;
    }

    /*
     * Queue the irp to the thread.
     * The de-queue thread will look in DriverContext[0] for the Device Object.
     */
    Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
    IoCsqInsertIrp(&Csq, Irp, NULL);

    return STATUS_PENDING;
}
Example #5
0
NTSTATUS INTERNAL
ReadReport(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpsp = NULL;

    irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevExt=%p,Irp=%p,IrpSp=%p)\n", DevExt, Irp, irpsp));
    TAssert(Irp->UserBuffer != NULL);

    if (irpsp->Parameters.DeviceIoControl.OutputBufferLength !=
        sizeof(HID_INPUT_REPORT))
    {
        status = STATUS_INVALID_BUFFER_SIZE;
        LogError(ERRLOG_INVALID_BUFFER_SIZE,
                 status,
                 UNIQUE_ERRID(0x60),
                 NULL,
                 NULL);
        TWarn(("invalid input report size (len=%d).\n",
                   irpsp->Parameters.DeviceIoControl.OutputBufferLength));
    }
    else
    {
        IoCsqInsertIrp(&DevExt->IrpQueue,
                    Irp,
                    NULL);
        status = STATUS_PENDING;
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //ReadReport
Example #6
0
NTSTATUS USBPcapBufferHandleReadIrp(PIRP pIrp,
                                    PDEVICE_EXTENSION pDevExt,
                                    PUINT32 pBytesRead)
{
    PDEVICE_EXTENSION      pRootExt;
    PUSBPCAP_ROOTHUB_DATA  pRootData;
    PVOID                  buffer;
    UINT32                 bufferLength;
    UINT32                 bytesRead;
    NTSTATUS               status;
    KIRQL                  irql;
    PIO_STACK_LOCATION     pStack = NULL;

    pStack = IoGetCurrentIrpStackLocation(pIrp);

    *pBytesRead = 0;

    if (pStack->Parameters.Read.Length == 0)
    {
        return STATUS_SUCCESS;
    }

    pRootExt = (PDEVICE_EXTENSION)pDevExt->context.control.pRootHubObject->DeviceExtension;
    pRootData = pRootExt->context.usb.pDeviceData->pRootData;

    if (pRootData->buffer == NULL)
    {
        return STATUS_UNSUCCESSFUL;
    }

    /*
     * Since control device has DO_DIRECT_IO bit set the MDL is already
     * probed and locked
     */
    buffer = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
                                          NormalPagePriority);

    if (buffer == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        bufferLength = MmGetMdlByteCount(pIrp->MdlAddress);
    }

    /* Get data from data queue, if there is no data we put
     * this IRP to Cancel-Safe queue and return status pending
     * otherwise complete this IRP then return SUCCESS
     */
    KeAcquireSpinLock(&pRootData->bufferLock, &irql);
    bytesRead = USBPcapBufferRead(pRootData,
                                  buffer, bufferLength);
    KeReleaseSpinLock(&pRootData->bufferLock, irql);

    *pBytesRead = bytesRead;
    if (bytesRead == 0)
    {
        IoCsqInsertIrp(&pDevExt->context.control.ioCsq,
                       pIrp, NULL);
        return STATUS_PENDING;
    }

    return STATUS_SUCCESS;
}
Example #7
0
NTSTATUS
CsampRead(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
 )
 /*++
     Routine Description:

           Read disptach routine

     Arguments:

         DeviceObject - pointer to a device object.
                 Irp             - pointer to current Irp

     Return Value:

         NT status code.

--*/
{
    NTSTATUS            status;
    PDEVICE_EXTENSION   devExtension;
    PIO_STACK_LOCATION  irpStack;
    LARGE_INTEGER       currentTime;
    PFILE_CONTEXT       fileContext;
    PVOID               readBuffer;
    BOOLEAN             inCriticalRegion;

    PAGED_CODE();

    CSAMP_KDPRINT(("CsampRead Enter:0x%p\n", Irp));

    devExtension = DeviceObject->DeviceExtension;
    inCriticalRegion = FALSE;

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    ASSERT(irpStack->FileObject != NULL);

    fileContext = irpStack->FileObject->FsContext;    

    status = IoAcquireRemoveLock(&fileContext->FileRundownLock, Irp);
    if (!NT_SUCCESS(status)) {
        //
        // Lock is in a removed state. That means we have already received 
        // cleaned up request for this handle. 
        //
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    //
    // First make sure there is enough room.
    //
    if (irpStack->Parameters.Read.Length < sizeof(INPUT_DATA))
    {
        Irp->IoStatus.Status = status = STATUS_BUFFER_TOO_SMALL;
        Irp->IoStatus.Information  = 0;
        IoReleaseRemoveLock(&fileContext->FileRundownLock, Irp);
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }

    //
    // FOR TESTING:
    // Initialize the data to mod 2 of some random number.
    // With this value you can control the number of times the
    // Irp will be queued before completion. Check
    // CsampPollDevice routine to know how this works.
    //

    KeQuerySystemTime(&currentTime);

    readBuffer = Irp->AssociatedIrp.SystemBuffer;
    
    *((PULONG)readBuffer) = ((currentTime.LowPart/13)%2);

    //
    // To avoid the thread from being suspended after it has queued the IRP and
    // before it signalled the semaphore, we will enter critical region.
    //
    ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
    KeEnterCriticalRegion();
    inCriticalRegion = TRUE;

    //
    // Queue the IRP and return STATUS_PENDING after signalling the
    // polling thread.
    // Note: IoCsqInsertIrp marks the IRP pending.
    //
    IoCsqInsertIrp(&devExtension->CancelSafeQueue, Irp, NULL);

    //
    // Do not touch the IRP once it has been queued because another thread
    // could remove the IRP and complete it before this one gets to run.
    //

    //
    // A semaphore remains signaled as long as its count is greater than
    // zero, and non-signaled when the count is zero. Following function
    // increments the semaphore count by 1.
    //

    KeReleaseSemaphore(&devExtension->IrpQueueSemaphore,
                        0,// No priority boost
                        1,// Increment semaphore by 1
                        FALSE );// No WaitForXxx after this call
    if (inCriticalRegion == TRUE) {
        KeLeaveCriticalRegion();
    }
    //
    // We don't hold the lock for IRP that's pending in the list because this
    // lock is meant to rundown currently dispatching threads when the cleanup
    // is handled.
    //
    IoReleaseRemoveLock(&fileContext->FileRundownLock, Irp);
    
    return STATUS_PENDING;
}
Example #8
0
NTSTATUS
NTAPI
USBPORT_HandleSubmitURB(IN PDEVICE_OBJECT PdoDevice,
                        IN PIRP Irp,
                        IN PURB Urb)
{
    PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
    PDEVICE_OBJECT FdoDevice;
    PUSBPORT_DEVICE_EXTENSION FdoExtension;
    USHORT Function;
    PUSBPORT_DEVICE_HANDLE DeviceHandle;
    NTSTATUS Status = STATUS_NOT_IMPLEMENTED;

    ASSERT(Urb);

    PdoExtension = PdoDevice->DeviceExtension;
    FdoDevice = PdoExtension->FdoDevice;
    FdoExtension = FdoDevice->DeviceExtension;

    Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
    Urb->UrbHeader.UsbdFlags = 0;

    Function = Urb->UrbHeader.Function;

    if (Function > URB_FUNCTION_MAX)
    {
        Status = USBPORT_USBDStatusToNtStatus(Urb,
                                              USBD_STATUS_INVALID_URB_FUNCTION);

        DPRINT1("USBPORT_HandleSubmitURB: Unknown URB function - %x !!!\n",
               Function);

        return Status;
    }

    if (FdoExtension->TimerFlags & USBPORT_TMFLAG_RH_SUSPENDED)
    {
        DPRINT1("USBPORT_HandleSubmitURB: Bad Request\n");

        USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_DEVICE_GONE);

        Irp->IoStatus.Status = STATUS_PENDING;
        IoMarkIrpPending(Irp);
        IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL);

        return STATUS_PENDING;
    }

    DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;

    if (!DeviceHandle)
    {
        DeviceHandle = &PdoExtension->DeviceHandle;
        Urb->UrbHeader.UsbdDeviceHandle = DeviceHandle;
    }

    if (!USBPORT_ValidateDeviceHandle(PdoExtension->FdoDevice,
                                      DeviceHandle))
    {
        DPRINT1("USBPORT_HandleSubmitURB: Not valid device handle\n");

        Irp->IoStatus.Status = STATUS_PENDING;
        IoMarkIrpPending(Irp);
        IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL);

        return STATUS_PENDING;
    }

    InterlockedIncrement(&DeviceHandle->DeviceHandleLock);

    DPRINT_URB("USBPORT_HandleSubmitURB: Function - 0x%02X, DeviceHandle - %p\n",
               Function,
               Urb->UrbHeader.UsbdDeviceHandle);

    switch (Function)
    {
        case URB_FUNCTION_ISOCH_TRANSFER:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_ISOCH_TRANSFER UNIMPLEMENTED. FIXME. \n");
            break;

        case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
        case URB_FUNCTION_CONTROL_TRANSFER:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, FALSE, FALSE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleDataTransfers(Urb);
            break;

        case URB_FUNCTION_VENDOR_DEVICE:
        case URB_FUNCTION_VENDOR_INTERFACE:
        case URB_FUNCTION_VENDOR_ENDPOINT:
        case URB_FUNCTION_CLASS_DEVICE:
        case URB_FUNCTION_CLASS_INTERFACE:
        case URB_FUNCTION_CLASS_ENDPOINT:
        case URB_FUNCTION_CLASS_OTHER:
        case URB_FUNCTION_VENDOR_OTHER:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleVendorOrClass(Irp, Urb);
            break;

        case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
        case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
        case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
        case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
        case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
        case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleGetSetDescriptor(Irp, Urb);
            break;

        case URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR (0x2A) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb,
                                                USBD_STATUS_INVALID_URB_FUNCTION);

        case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
        case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
        case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
        case URB_FUNCTION_GET_STATUS_FROM_OTHER:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleGetStatus(Irp, Urb);
            break;

        case URB_FUNCTION_SELECT_CONFIGURATION:
            Status = USBPORT_HandleSelectConfiguration(PdoExtension->FdoDevice,
                                                       Irp,
                                                       Urb);
            break;

        case URB_FUNCTION_SELECT_INTERFACE:
            Status = USBPORT_HandleSelectInterface(PdoExtension->FdoDevice,
                                                   Irp,
                                                   Urb);
            break;

        case URB_FUNCTION_GET_CONFIGURATION:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleGetConfiguration(Urb);
            break;

        case URB_FUNCTION_GET_INTERFACE:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_INTERFACE (0x27) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb,
                                                USBD_STATUS_INVALID_URB_FUNCTION);

        case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
            Status = USBPORT_SyncResetPipeAndClearStall(PdoExtension->FdoDevice,
                                                        Irp,
                                                        Urb);
            break;

        case URB_FUNCTION_SYNC_RESET_PIPE:
            Status = USBPORT_ResetPipe(PdoExtension->FdoDevice,
                                       Irp,
                                       Urb);
            break;

        case URB_FUNCTION_SYNC_CLEAR_STALL:
            Status = USBPORT_ClearStall(PdoExtension->FdoDevice,
                                        Irp,
                                        Urb);
            break;

        case URB_FUNCTION_ABORT_PIPE:
            Status = USBPORT_AbortPipe(PdoExtension->FdoDevice,
                                       Irp,
                                       Urb);
            break;

        case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
        case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
        case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
        case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
        case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
        case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER:
        case URB_FUNCTION_SET_FEATURE_TO_OTHER:
            Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, TRUE);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
                break;
            }

            Status = USBPORT_HandleSetOrClearFeature(Urb);
            break;

        case URB_FUNCTION_GET_CURRENT_FRAME_NUMBER:
            Status = USBPORT_HandleGetCurrentFrame(PdoExtension->FdoDevice,
                                                   Irp,
                                                   Urb);
            break;

        case URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL (0x03) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);

        case URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL (0x04) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);

        case URB_FUNCTION_GET_FRAME_LENGTH:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_FRAME_LENGTH (0x05) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);

        case URB_FUNCTION_SET_FRAME_LENGTH:
            DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_SET_FRAME_LENGTH (0x06) NOT_SUPPORTED\n");
            return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);

        default:
            DPRINT1("USBPORT_HandleSubmitURB: Unknown URB Function - %x\n",
                    Function);
            //URB_FUNCTION_RESERVED_0X0016
            //URB_FUNCTION_RESERVE_0X001D
            //URB_FUNCTION_RESERVE_0X002B
            //URB_FUNCTION_RESERVE_0X002C
            //URB_FUNCTION_RESERVE_0X002D
            //URB_FUNCTION_RESERVE_0X002E
            //URB_FUNCTION_RESERVE_0X002F
            break;
    }

    if (Status == STATUS_PENDING)
    {
        return Status;
    }

    if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_ALLOCATED_TRANSFER)
    {
        PUSBPORT_TRANSFER Transfer;

        Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
        Urb->UrbControlTransfer.hca.Reserved8[0] = NULL;
        Urb->UrbHeader.UsbdFlags |= ~USBD_FLAG_ALLOCATED_TRANSFER;
        ExFreePoolWithTag(Transfer, USB_PORT_TAG);
    }

    InterlockedDecrement(&DeviceHandle->DeviceHandleLock);

    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}