Example #1
0
NTSTATUS
NTAPI
BeepCleanup(IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{
    KIRQL OldIrql, CancelIrql;
    PKDEVICE_QUEUE_ENTRY Packet;
    PIRP CurrentIrp;

    /* Raise IRQL and acquire the cancel lock */
    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
    IoAcquireCancelSpinLock(&CancelIrql);

    /* Get the current IRP */
    CurrentIrp = DeviceObject->CurrentIrp;
    DeviceObject->CurrentIrp = NULL;
    while (CurrentIrp)
    {
        /* Clear its cancel routine */
        (VOID)IoSetCancelRoutine(CurrentIrp, NULL);

        /* Cancel the IRP */
        CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
        CurrentIrp->IoStatus.Information = 0;

        /* Release the cancel lock and complete it */
        IoReleaseCancelSpinLock(CancelIrql);
        IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);

        /* Reacquire the lock and get the next queue packet */
        IoAcquireCancelSpinLock(&CancelIrql);
        Packet = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
        if (Packet)
        {
            /* Get the IRP */
            CurrentIrp = CONTAINING_RECORD(Packet,
                                           IRP,
                                           Tail.Overlay.DeviceQueueEntry);
        }
        else
        {
            /* No more IRPs */
            CurrentIrp = NULL;
        }
    }

    /* Release lock and go back to low IRQL */
    IoReleaseCancelSpinLock(CancelIrql);
    KeLowerIrql(OldIrql);

    /* Complete the IRP */
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    /* Stop and beep and return */
    HalMakeBeep(0);
    return STATUS_SUCCESS;
}
Example #2
0
static PNPFS_CCB
NpfsFindListeningServerInstance(PNPFS_FCB Fcb)
{
    PLIST_ENTRY CurrentEntry;
    PNPFS_WAITER_ENTRY Waiter;
    KIRQL oldIrql;
    PIRP Irp;

    CurrentEntry = Fcb->WaiterListHead.Flink;
    while (CurrentEntry != &Fcb->WaiterListHead)
    {
        Waiter = CONTAINING_RECORD(CurrentEntry, NPFS_WAITER_ENTRY, Entry);
        Irp = CONTAINING_RECORD(Waiter, IRP, Tail.Overlay.DriverContext);
        if (Waiter->Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
        {
            DPRINT("Server found! CCB %p\n", Waiter->Ccb);

            IoAcquireCancelSpinLock(&oldIrql);
            if (!Irp->Cancel)
            {
                if (IoSetCancelRoutine(Irp, NULL) != NULL)
                {
                    IoReleaseCancelSpinLock(oldIrql);
                    return Waiter->Ccb;
                }
            }
            IoReleaseCancelSpinLock(oldIrql);
        }

        CurrentEntry = CurrentEntry->Flink;
    }

    return NULL;
}
Example #3
0
/*
 * @implemented
 */
VOID
MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
{
    PIRP Irp;
    KIRQL OldIrql;
    LIST_ENTRY CopyList;
    PLIST_ENTRY NextEntry;

    /* Increase the epic number */
    DeviceExtension->EpicNumber++;

    InitializeListHead(&CopyList);

    /* Copy all the pending IRPs for notification */
    IoAcquireCancelSpinLock(&OldIrql);
    while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
    {
        NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
        Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
        InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
    }
    IoReleaseCancelSpinLock(OldIrql);

    /* Then, notifiy them one by one */
    while (!IsListEmpty(&CopyList))
    {
        NextEntry = RemoveHeadList(&CopyList);
        Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);

        *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
        Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
}
Example #4
0
PIRP
SoundRemoveFromCancellableQ(
    PLIST_ENTRY QueueHead
)
/*++

Routine Description:


    Remove the Irp to the queue and remove the cancel routine under the
    protection of the cancel spin lock.

Arguments:

    QueueHead - the queue to remove it from

Return Value:

    The Irp at the head of the queue or NULL if the queue is empty.

--*/
{
    KIRQL OldIrql;
    PIRP Irp;
    LIST_ENTRY ListNode;

    //
    // Get the cancel spin lock so we can mess with the cancel stuff
    //

    IoAcquireCancelSpinLock(&OldIrql);


    if (IsListEmpty(QueueHead)) {
        Irp = NULL;
    } else {

        PLIST_ENTRY ListNode;
        ListNode = RemoveHeadList(QueueHead);
        Irp = CONTAINING_RECORD(ListNode, IRP, Tail.Overlay.ListEntry);

        //
        // Remove the cancel routine
        //

        IoSetCancelRoutine(Irp, NULL);
    }

    //
    // Free the spin lock
    //

    IoReleaseCancelSpinLock(OldIrql);

    //
    // Return IRP (if any)
    //

    return Irp;
}
Example #5
0
NTSTATUS Notification_Recieve(NOTIFICATION_QUEUE *queue, PIRP irp) {
	PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
	KIRQL irq;

	if(irpstack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PGNOTIFICATION)) {
		irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
		irp->IoStatus.Information = 0;
		IoCompleteRequest(irp, IO_NO_INCREMENT);

		return STATUS_BUFFER_TOO_SMALL;
	}
	
	KeAcquireSpinLock(&queue->lock, &irq);

	if(IsListEmpty(&queue->notification_list)) {
		PGIRPNODE *irpnode;
		KIRQL crirq;

		irpnode = ExAllocateFromNPagedLookasideList(&queue->lookaside);

		InitializeListHead(&irpnode->entry);

		irpnode->irp = irp;
		//irp->Tail.Overlay.DriverContext[0] = irpnode;

		InsertTailList(&queue->irp_list, &irpnode->entry);

		IoMarkIrpPending(irp);

		IoAcquireCancelSpinLock(&crirq);

#pragma warning(push)
#pragma warning(disable:4311 4312)
		//IoSetCancelRoutine generates warnings in 32-bit due to silly macroisms.
		IoSetCancelRoutine(irp, Notification_OnCancel);
#pragma warning(pop)

		IoReleaseCancelSpinLock(crirq);
		
		KeReleaseSpinLock(&queue->lock, irq);

		return STATUS_PENDING;
	}
	else {
		PGNOTIFYNODE *notifynode = (PGNOTIFYNODE*)RemoveHeadList(&queue->notification_list);
		PGNOTIFICATION *notification = irp->AssociatedIrp.SystemBuffer;

		RtlCopyMemory(notification, &notifynode->notification, sizeof(PGNOTIFICATION));
		ExFreeToNPagedLookasideList(&queue->lookaside, notifynode);
		--queue->queued;
		
		KeReleaseSpinLock(&queue->lock, irq);

		irp->IoStatus.Status = STATUS_SUCCESS;
		irp->IoStatus.Information = sizeof(PGNOTIFICATION);
		IoCompleteRequest(irp, IO_NO_INCREMENT);

		return STATUS_SUCCESS;
	}
}
Example #6
0
//----------------------------------------------------------------------------
NTSTATUS
NTCheckSetCancelRoutine(
    IN  PIRP            pIrp,
    IN  PVOID           CancelRoutine,
    IN  PDEVICE  pDevice
    )

/*++
Routine Description;

    This Routine sets the cancel routine for an Irp.

Arguments;

    status - a completion status for the Irp

Return Value;

    NTSTATUS - status of the request

--*/

{
    NTSTATUS status;

    IpxPrint1("CheckSetCancelRoutine: Entered. Irp = (%lx)\n", pIrp);
    //
    // Check if the irp was cancelled yet and if not, then set the
    // irp cancel routine.
    //
    IoAcquireCancelSpinLock(&pIrp->CancelIrql);
    if (pIrp->Cancel)
    {
        pIrp->IoStatus.Status = STATUS_CANCELLED;
        status = STATUS_CANCELLED;

    }
    else
    {
        // setup the cancel routine
        IoMarkIrpPending(pIrp);
        IoSetCancelRoutine(pIrp,CancelRoutine);
        status = STATUS_SUCCESS;
    }

    IoReleaseCancelSpinLock(pIrp->CancelIrql);
    return(status);

}
Example #7
0
/*!
 * \brief Entry point for RDF_CARD_TRACKING.<br>
 * <br>
 * The RDF_CARD_TRACKING callback function installs an event handler to
	track every time a card is inserted in or removed from a card reader.
 * <br>
 * \param [in] pSmartcardExtension A pointer to the smart card extension,
		SMARTCARD_EXTENSION, of the device.
 *
 * \retval STATUS_PENDING Smart card tracking has started.
 */
NTSTATUS VR_RDF_CardTracking(IN PSMARTCARD_EXTENSION pSmartcardExtension)
{
	dbg_log("VR_RDF_CardTracking start");
	KIRQL cancelIrql;

	// The corresponding WDM driver library adds a pointer to the request
	// in SmartcardExtension->OsData->NotificationIrp.
	// http://msdn2.microsoft.com/en-us/library/ms801317.aspx
	IoAcquireCancelSpinLock(&cancelIrql);
	IoSetCancelRoutine(pSmartcardExtension->OsData->NotificationIrp, VR_RDF_Cancel);
	IoReleaseCancelSpinLock(cancelIrql);

	dbg_log("VR_RDF_CardTracking end - status: 0x%08X", STATUS_PENDING);
	return STATUS_PENDING;
}
Example #8
0
NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
    KIRQL OldIrql;

    Irp->IoStatus.Status = Status;

    if( Status == STATUS_PENDING )
	IoMarkIrpPending( Irp );
    else {
        IoAcquireCancelSpinLock(&OldIrql);
	(void)IoSetCancelRoutine( Irp, NULL );
        IoReleaseCancelSpinLock(OldIrql);

	IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
    }

    return Status;
}
Example #9
0
NTSTATUS DispPrepareIrpForCancel(
    PTRANSPORT_CONTEXT Context,
    PIRP Irp,
    PDRIVER_CANCEL CancelRoutine)
/*
 * FUNCTION: Prepare an IRP for cancellation
 * ARGUMENTS:
 *     Context       = Pointer to context information
 *     Irp           = Pointer to an I/O request packet
 *     CancelRoutine = Routine to be called when I/O request is cancelled
 * RETURNS:
 *     Status of operation
 */
{
    KIRQL OldIrql;
    PIO_STACK_LOCATION IrpSp;
    PTRANSPORT_CONTEXT TransContext;

    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

    IrpSp       = IoGetCurrentIrpStackLocation(Irp);
    TransContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;

    IoAcquireCancelSpinLock(&OldIrql);

    if (!Irp->Cancel && !TransContext->CancelIrps) {
        (void)IoSetCancelRoutine(Irp, CancelRoutine);
        IoReleaseCancelSpinLock(OldIrql);

        TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp));

        return STATUS_SUCCESS;
    }

    /* IRP has already been cancelled */

    IoReleaseCancelSpinLock(OldIrql);

    Irp->IoStatus.Status      = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;

    TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP was already cancelled).\n"));

    return Irp->IoStatus.Status;
}
Example #10
0
void co_os_manager_userspace_close(co_manager_open_desc_t opened)
{
	KIRQL irql;
	PIRP Irp;

	Irp = opened->os->irp;
	if (Irp) {
		IoAcquireCancelSpinLock(&irql);
		fixme_IoSetCancelRoutine(Irp, NULL);
		opened->os->irp = NULL;
		IoReleaseCancelSpinLock(irql);

		Irp->IoStatus.Status = STATUS_CANCELLED;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	}

	co_os_free(opened->os);
	opened->os = NULL;
}
Example #11
0
VOID
NTAPI
USBH_HubQueuePortWakeIrps(IN PUSBHUB_FDO_EXTENSION HubExtension,
                          IN PLIST_ENTRY ListIrps)
{
    PDEVICE_OBJECT PortDevice;
    PUSBHUB_PORT_PDO_EXTENSION PortExtension;
    USHORT NumPorts;
    USHORT Port;
    PIRP WakeIrp;
    KIRQL OldIrql;

    DPRINT("USBH_HubQueuePortWakeIrps ... \n");

    NumPorts = HubExtension->HubDescriptor->bNumberOfPorts;

    InitializeListHead(ListIrps);

    IoAcquireCancelSpinLock(&OldIrql);

    for (Port = 0; Port < NumPorts; ++Port)
    {
        PortDevice = HubExtension->PortData[Port].DeviceObject;

        if (PortDevice)
        {
            PortExtension = PortDevice->DeviceExtension;

            WakeIrp = PortExtension->PdoWaitWakeIrp;
            PortExtension->PdoWaitWakeIrp = NULL;

            if (WakeIrp)
            {
                DPRINT1("USBH_HubQueuePortWakeIrps: UNIMPLEMENTED. FIXME\n");
                DbgBreakPoint();
            }
        }
    }

    IoReleaseCancelSpinLock(OldIrql);
}
Example #12
0
co_rc_t co_os_manager_userspace_eof(co_manager_t *manager, co_manager_open_desc_t opened)
{
	PIRP Irp;

	Irp = opened->os->irp;
	if (Irp) {
		KIRQL irql;

		IoAcquireCancelSpinLock(&irql);
		fixme_IoSetCancelRoutine(Irp, NULL);
		opened->os->irp = NULL;
		IoReleaseCancelSpinLock(irql);

		co_manager_close(manager, opened);

		Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	}

	return CO_RC(OK);
}
Example #13
0
bool_t co_os_manager_userspace_try_send_direct(
	co_manager_t *manager,
	co_manager_open_desc_t opened,
	co_message_t *message)
{
	PIRP Irp;

	Irp = opened->os->irp;
	if (Irp) {
		KIRQL irql;
		unsigned char *io_buffer;
		uintptr_t size = message->size + sizeof(*message);
		uintptr_t buffer_size = Irp->IoStatus.Information;

		IoAcquireCancelSpinLock(&irql);
		fixme_IoSetCancelRoutine(Irp, NULL);
		opened->os->irp = NULL;
		IoReleaseCancelSpinLock(irql);

		co_manager_close(manager, opened);

		io_buffer = Irp->AssociatedIrp.SystemBuffer;

		if (size <= buffer_size) {
			co_memcpy(io_buffer, message, size);
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = size;
			IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
			return PTRUE;
		} else {
			Irp->IoStatus.Status = STATUS_CANCELLED;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}
	}

	return PFALSE;
}
Example #14
0
NTSTATUS
SerialIoControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine provides the initial processing for all of the
    Ioctrls for the serial device.

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call

--*/

{
    //
    // The status that gets returned to the caller and
    // set in the Irp.
    //
    NTSTATUS Status;

    //
    // The current stack location.  This contains all of the
    // information we need to process this particular request.
    //
    PIO_STACK_LOCATION IrpSp;

    //
    // Just what it says.  This is the serial specific device
    // extension of the device object create for the serial driver.
    //
    PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;

    //
    // A temporary to hold the old IRQL so that it can be
    // restored once we complete/validate this request.
    //
    KIRQL OldIrql;

    SerialDump(
        SERIRPPATH,
        ("SERIAL: Dispatch entry for: %x\n",Irp)
        );
    if (SerialCompleteIfError(
            DeviceObject,
            Irp
            ) != STATUS_SUCCESS) {

        return STATUS_CANCELLED;

    }
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    Irp->IoStatus.Information = 0L;
    Status = STATUS_SUCCESS;
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {

        case IOCTL_SERIAL_SET_BAUD_RATE : {

            ULONG BaudRate;
            //
            // Will hold the value of the appropriate divisor for
            // the requested baud rate.  If the baudrate is invalid
            // (because the device won't support that baud rate) then
            // this value is undefined.
            //
            // Note: in one sense the concept of a valid baud rate
            // is cloudy.  We could allow the user to request any
            // baud rate.  We could then calculate the divisor needed
            // for that baud rate.  As long as the divisor wasn't less
            // than one we would be "ok".  (The percentage difference
            // between the "true" divisor and the "rounded" value given
            // to the hardware might make it unusable, but... )  It would
            // really be up to the user to "Know" whether the baud rate
            // is suitable.  So much for theory, *We* only support a given
            // set of baud rates.
            //
            SHORT AppropriateDivisor;

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_BAUD_RATE)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            } else {

                BaudRate = ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;

            }

            //
            // Get the baud rate from the irp.  We pass it
            // to a routine which will set the correct divisor.
            //

            Status = SerialGetDivisorFromBaud(
                         Extension->ClockRate,
                         BaudRate,
                         &AppropriateDivisor
                         );

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            if (NT_SUCCESS(Status)) {

                SERIAL_IOCTL_SYNC S;

                Extension->CurrentBaud = BaudRate;

                S.Extension = Extension;
                S.Data = (PVOID)AppropriateDivisor;
                KeSynchronizeExecution(
                    Extension->Interrupt,
                    SerialSetBaud,
                    &S
                    );

            }

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_GET_BAUD_RATE: {

            PSERIAL_BAUD_RATE Br = (PSERIAL_BAUD_RATE)Irp->AssociatedIrp.SystemBuffer;
            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_BAUD_RATE)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            Br->BaudRate = Extension->CurrentBaud;

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            Irp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);

            break;

        }
        case IOCTL_SERIAL_SET_LINE_CONTROL: {

            //
            // Points to the line control record in the Irp.
            //
            PSERIAL_LINE_CONTROL Lc =
                ((PSERIAL_LINE_CONTROL)(Irp->AssociatedIrp.SystemBuffer));

            UCHAR LData;
            UCHAR LStop;
            UCHAR LParity;
            UCHAR Mask = 0xff;

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_LINE_CONTROL)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            switch (Lc->WordLength) {
                case 5: {

                    LData = SERIAL_5_DATA;
                    Mask = 0x1f;
                    break;

                }
                case 6: {

                    LData = SERIAL_6_DATA;
                    Mask = 0x3f;
                    break;

                }
                case 7: {

                    LData = SERIAL_7_DATA;
                    Mask = 0x7f;
                    break;

                }
                case 8: {

                    LData = SERIAL_8_DATA;
                    break;

                }
                default: {

                    Status = STATUS_INVALID_PARAMETER;
                    goto DoneWithIoctl;

                }

            }

            switch (Lc->Parity) {

                case NO_PARITY: {

                    LParity = SERIAL_NONE_PARITY;
                    break;

                }
                case EVEN_PARITY: {

                    LParity = SERIAL_EVEN_PARITY;
                    break;

                }
                case ODD_PARITY: {

                    LParity = SERIAL_ODD_PARITY;
                    break;

                }
                case SPACE_PARITY: {

                    LParity = SERIAL_SPACE_PARITY;
                    break;

                }
                case MARK_PARITY: {

                    LParity = SERIAL_MARK_PARITY;
                    break;

                }
                default: {

                    Status = STATUS_INVALID_PARAMETER;
                    goto DoneWithIoctl;
                    break;
                }

            }

            switch (Lc->StopBits) {

                case STOP_BIT_1: {

                    LStop = SERIAL_1_STOP;
                    break;
                }
                case STOP_BITS_1_5: {

                    if (LData != SERIAL_5_DATA) {

                        Status = STATUS_INVALID_PARAMETER;
                        goto DoneWithIoctl;
                    }
                    LStop = SERIAL_1_5_STOP;
                    break;

                }
                case STOP_BITS_2: {

                    if (LData == SERIAL_5_DATA) {

                        Status = STATUS_INVALID_PARAMETER;
                        goto DoneWithIoctl;
                    }
                    LStop = SERIAL_2_STOP;
                    break;

                }
                default: {

                    Status = STATUS_INVALID_PARAMETER;
                    goto DoneWithIoctl;
                }

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            Extension->LineControl =
                (UCHAR)((Extension->LineControl & SERIAL_LCR_BREAK) |
                        (LData | LParity | LStop));
            Extension->ValidDataMask = Mask;

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetLineControl,
                Extension
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_GET_LINE_CONTROL: {

            PSERIAL_LINE_CONTROL Lc = (PSERIAL_LINE_CONTROL)Irp->AssociatedIrp.SystemBuffer;

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_LINE_CONTROL)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            if ((Extension->LineControl & SERIAL_DATA_MASK) == SERIAL_5_DATA) {
                Lc->WordLength = 5;
            } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                        == SERIAL_6_DATA) {
                Lc->WordLength = 6;
            } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                        == SERIAL_7_DATA) {
                Lc->WordLength = 7;
            } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                        == SERIAL_8_DATA) {
                Lc->WordLength = 8;
            }

            if ((Extension->LineControl & SERIAL_PARITY_MASK)
                    == SERIAL_NONE_PARITY) {
                Lc->Parity = NO_PARITY;
            } else if ((Extension->LineControl & SERIAL_PARITY_MASK)
                    == SERIAL_ODD_PARITY) {
                Lc->Parity = ODD_PARITY;
            } else if ((Extension->LineControl & SERIAL_PARITY_MASK)
                    == SERIAL_EVEN_PARITY) {
                Lc->Parity = EVEN_PARITY;
            } else if ((Extension->LineControl & SERIAL_PARITY_MASK)
                    == SERIAL_MARK_PARITY) {
                Lc->Parity = MARK_PARITY;
            } else if ((Extension->LineControl & SERIAL_PARITY_MASK)
                    == SERIAL_SPACE_PARITY) {
                Lc->Parity = SPACE_PARITY;
            }

            if (Extension->LineControl & SERIAL_2_STOP) {
                if (Lc->WordLength == 5) {
                    Lc->StopBits = STOP_BITS_1_5;
                } else {
                    Lc->StopBits = STOP_BITS_2;
                }
            } else {
                Lc->StopBits = STOP_BIT_1;
            }

            Irp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_SET_TIMEOUTS: {

            PSERIAL_TIMEOUTS NewTimeouts =
                ((PSERIAL_TIMEOUTS)(Irp->AssociatedIrp.SystemBuffer));


            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_TIMEOUTS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            if ((NewTimeouts->ReadIntervalTimeout == MAXULONG) &&
                (NewTimeouts->ReadTotalTimeoutMultiplier == MAXULONG) &&
                (NewTimeouts->ReadTotalTimeoutConstant == MAXULONG)) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            Extension->Timeouts.ReadIntervalTimeout =
                NewTimeouts->ReadIntervalTimeout;

            Extension->Timeouts.ReadTotalTimeoutMultiplier =
                NewTimeouts->ReadTotalTimeoutMultiplier;

            Extension->Timeouts.ReadTotalTimeoutConstant =
                NewTimeouts->ReadTotalTimeoutConstant;

            Extension->Timeouts.WriteTotalTimeoutMultiplier =
                NewTimeouts->WriteTotalTimeoutMultiplier;

            Extension->Timeouts.WriteTotalTimeoutConstant =
                NewTimeouts->WriteTotalTimeoutConstant;

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_GET_TIMEOUTS: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_TIMEOUTS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            *((PSERIAL_TIMEOUTS)Irp->AssociatedIrp.SystemBuffer) = Extension->Timeouts;
            Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_SET_CHARS: {

            SERIAL_IOCTL_SYNC S;
            PSERIAL_CHARS NewChars =
                ((PSERIAL_CHARS)(Irp->AssociatedIrp.SystemBuffer));


            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_CHARS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // The only thing that can be wrong with the chars
            // is that the xon and xoff characters are the
            // same.
            //
#if 0
            if (NewChars->XonChar == NewChars->XoffChar) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }
#endif

            //
            // We acquire the control lock so that only
            // one request can GET or SET the characters
            // at a time.  The sets could be synchronized
            // by the interrupt spinlock, but that wouldn't
            // prevent multiple gets at the same time.
            //

            S.Extension = Extension;
            S.Data = NewChars;

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            //
            // Under the protection of the lock, make sure that
            // the xon and xoff characters aren't the same as
            // the escape character.
            //

            if (Extension->EscapeChar) {

                if ((Extension->EscapeChar == NewChars->XonChar) ||
                    (Extension->EscapeChar == NewChars->XoffChar)) {

                    Status = STATUS_INVALID_PARAMETER;
                    KeReleaseSpinLock(
                        &Extension->ControlLock,
                        OldIrql
                        );
                    break;

                }

            }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetChars,
                &S
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_GET_CHARS: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_CHARS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            *((PSERIAL_CHARS)Irp->AssociatedIrp.SystemBuffer) = Extension->SpecialChars;
            Irp->IoStatus.Information = sizeof(SERIAL_CHARS);

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_SET_DTR:
        case IOCTL_SERIAL_CLR_DTR: {

            //
            // We acquire the lock so that we can check whether
            // automatic dtr flow control is enabled.  If it is
            // then we return an error since the app is not allowed
            // to touch this if it is automatic.
            //

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            if ((Extension->HandFlow.ControlHandShake & SERIAL_DTR_MASK)
                == SERIAL_DTR_HANDSHAKE) {

                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

            } else {

                KeSynchronizeExecution(
                    Extension->Interrupt,
                    ((IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                     IOCTL_SERIAL_SET_DTR)?
                     (SerialSetDTR):(SerialClrDTR)),
                    Extension
                    );

            }

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_RESET_DEVICE: {

            break;
        }
        case IOCTL_SERIAL_SET_RTS:
        case IOCTL_SERIAL_CLR_RTS: {
            //
            // We acquire the lock so that we can check whether
            // automatic rts flow control or transmit toggleing
            // is enabled.  If it is then we return an error since
            // the app is not allowed to touch this if it is automatic
            // or toggling.
            //

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            if (((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK)
                 == SERIAL_RTS_HANDSHAKE) ||
                ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK)
                 == SERIAL_TRANSMIT_TOGGLE)) {

                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

            } else {

                KeSynchronizeExecution(
                    Extension->Interrupt,
                    ((IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                     IOCTL_SERIAL_SET_RTS)?
                     (SerialSetRTS):(SerialClrRTS)),
                    Extension
                    );

            }

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_SET_XOFF: {

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialPretendXoff,
                Extension
                );

            break;

        }
        case IOCTL_SERIAL_SET_XON: {

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialPretendXon,
                Extension
                );

            break;

        }
        case IOCTL_SERIAL_SET_BREAK_ON: {

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialTurnOnBreak,
                Extension
                );

            break;
        }
        case IOCTL_SERIAL_SET_BREAK_OFF: {

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialTurnOffBreak,
                Extension
                );

            break;
        }
        case IOCTL_SERIAL_SET_QUEUE_SIZE: {

            //
            // Type ahead buffer is fixed, so we just validate
            // the the users request is not bigger that our
            // own internal buffer size.
            //

            PSERIAL_QUEUE_SIZE Rs =
                ((PSERIAL_QUEUE_SIZE)(Irp->AssociatedIrp.SystemBuffer));

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_QUEUE_SIZE)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // We have to allocate the memory for the new
            // buffer while we're still in the context of the
            // caller.  We don't even try to protect this
            // with a lock because the value could be stale
            // as soon as we release the lock - The only time
            // we will know for sure is when we actually try
            // to do the resize.
            //

            if (Rs->InSize <= Extension->BufferSize) {

                Status = STATUS_SUCCESS;
                break;

            }

            try {

                IrpSp->Parameters.DeviceIoControl.Type3InputBuffer =
                    ExAllocatePoolWithQuota(
                        NonPagedPool,
                        Rs->InSize
                        );

            } except (EXCEPTION_EXECUTE_HANDLER) {

                IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
                Status = GetExceptionCode();

            }

            if (!IrpSp->Parameters.DeviceIoControl.Type3InputBuffer) {

                break;

            }

            //
            // Well the data passed was big enough.  Do the request.
            //
            // There are two reason we place it in the read queue:
            //
            // 1) We want to serialize these resize requests so that
            //    they don't contend with each other.
            //
            // 2) We want to serialize these requests with reads since
            //    we don't want reads and resizes contending over the
            //    read buffer.
            //

            return SerialStartOrQueue(
                       Extension,
                       Irp,
                       &Extension->ReadQueue,
                       &Extension->CurrentReadIrp,
                       SerialStartRead
                       );

            break;

        }
        case IOCTL_SERIAL_GET_WAIT_MASK: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Simple scalar read.  No reason to acquire a lock.
            //

            Irp->IoStatus.Information = sizeof(ULONG);

            *((ULONG *)Irp->AssociatedIrp.SystemBuffer) = Extension->IsrWaitMask;

            break;

        }
        case IOCTL_SERIAL_SET_WAIT_MASK: {

            ULONG NewMask;

            SerialDump(
                SERDIAG3 | SERIRPPATH,
                ("SERIAL: In Ioctl processing for set mask\n")
                );
            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(ULONG)) {

                SerialDump(
                    SERDIAG3,
                    ("SERIAL: Invalid size fo the buffer %d\n",
                     IrpSp->Parameters.DeviceIoControl.InputBufferLength)
                    );
                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            } else {

                NewMask = *((ULONG *)Irp->AssociatedIrp.SystemBuffer);

            }

            //
            // Make sure that the mask only contains valid
            // waitable events.
            //

            if (NewMask & ~(SERIAL_EV_RXCHAR   |
                            SERIAL_EV_RXFLAG   |
                            SERIAL_EV_TXEMPTY  |
                            SERIAL_EV_CTS      |
                            SERIAL_EV_DSR      |
                            SERIAL_EV_RLSD     |
                            SERIAL_EV_BREAK    |
                            SERIAL_EV_ERR      |
                            SERIAL_EV_RING     |
                            SERIAL_EV_PERR     |
                            SERIAL_EV_RX80FULL |
                            SERIAL_EV_EVENT1   |
                            SERIAL_EV_EVENT2)) {

                SerialDump(
                    SERDIAG3,
                    ("SERIAL: Unknown mask %x\n",NewMask)
                    );
                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Either start this irp or put it on the
            // queue.
            //

            SerialDump(
                SERDIAG3 | SERIRPPATH,
                ("SERIAL: Starting or queuing set mask irp %x\n",Irp)
                );
            return SerialStartOrQueue(
                       Extension,
                       Irp,
                       &Extension->MaskQueue,
                       &Extension->CurrentMaskIrp,
                       SerialStartMask
                       );

        }
        case IOCTL_SERIAL_WAIT_ON_MASK: {

            SerialDump(
                SERDIAG3 | SERIRPPATH,
                ("SERIAL: In Ioctl processing for wait mask\n")
                );
            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                SerialDump(
                    SERDIAG3,
                    ("SERIAL: Invalid size fo the buffer %d\n",
                     IrpSp->Parameters.DeviceIoControl.InputBufferLength)
                    );
                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Either start this irp or put it on the
            // queue.
            //

            SerialDump(
                SERDIAG3 | SERIRPPATH,
                ("SERIAL: Starting or queuing wait mask irp %x\n",Irp)
                );
            return SerialStartOrQueue(
                       Extension,
                       Irp,
                       &Extension->MaskQueue,
                       &Extension->CurrentMaskIrp,
                       SerialStartMask
                       );

        }
        case IOCTL_SERIAL_IMMEDIATE_CHAR: {

            KIRQL OldIrql;

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(UCHAR)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            IoAcquireCancelSpinLock(&OldIrql);
            if (Extension->CurrentImmediateIrp) {

                Status = STATUS_INVALID_PARAMETER;
                IoReleaseCancelSpinLock(OldIrql);

            } else {

                //
                // We can queue the char.  We need to set
                // a cancel routine because flow control could
                // keep the char from transmitting.  Make sure
                // that the irp hasn't already been canceled.
                //

                if (Irp->Cancel) {

                    IoReleaseCancelSpinLock(OldIrql);
                    Status = STATUS_CANCELLED;

                } else {

                    Extension->CurrentImmediateIrp = Irp;
                    Extension->TotalCharsQueued++;
                    IoReleaseCancelSpinLock(OldIrql);
                    SerialStartImmediate(Extension);

                    return STATUS_PENDING;

                }

            }

            break;

        }
        case IOCTL_SERIAL_PURGE: {

            ULONG Mask;

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(ULONG)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }
            //
            // Check to make sure that the mask only has
            // 0 or the other appropriate values.
            //

            Mask = *((ULONG *)(Irp->AssociatedIrp.SystemBuffer));

            if ((!Mask) || (Mask & (~(SERIAL_PURGE_TXABORT |
                                      SERIAL_PURGE_RXABORT |
                                      SERIAL_PURGE_TXCLEAR |
                                      SERIAL_PURGE_RXCLEAR
                                     )
                                   )
                           )) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Either start this irp or put it on the
            // queue.
            //

            return SerialStartOrQueue(
                       Extension,
                       Irp,
                       &Extension->PurgeQueue,
                       &Extension->CurrentPurgeIrp,
                       SerialStartPurge
                       );

        }
        case IOCTL_SERIAL_GET_HANDFLOW: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_HANDFLOW)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(SERIAL_HANDFLOW);

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            *((PSERIAL_HANDFLOW)Irp->AssociatedIrp.SystemBuffer) =
                Extension->HandFlow;

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_SET_HANDFLOW: {

            SERIAL_IOCTL_SYNC S;
            PSERIAL_HANDFLOW HandFlow = Irp->AssociatedIrp.SystemBuffer;

            //
            // Make sure that the hand shake and control is the
            // right size.
            //

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_HANDFLOW)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Make sure that there are no invalid bits set in
            // the control and handshake.
            //

            if (HandFlow->ControlHandShake & SERIAL_CONTROL_INVALID) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            if (HandFlow->FlowReplace & SERIAL_FLOW_INVALID) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Make sure that the app hasn't set an invlid DTR mode.
            //

            if ((HandFlow->ControlHandShake & SERIAL_DTR_MASK) ==
                SERIAL_DTR_MASK) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Make sure that haven't set totally invalid xon/xoff
            // limits.
            //

            if ((HandFlow->XonLimit < 0) ||
                ((ULONG)HandFlow->XonLimit > Extension->BufferSize)) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            if ((HandFlow->XoffLimit < 0) ||
                ((ULONG)HandFlow->XoffLimit > Extension->BufferSize)) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            S.Extension = Extension;
            S.Data = HandFlow;

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            //
            // Under the protection of the lock, make sure that
            // we aren't turning on error replacement when we
            // are doing line status/modem status insertion.
            //

            if (Extension->EscapeChar) {

                if (HandFlow->FlowReplace & SERIAL_ERROR_CHAR) {

                    Status = STATUS_INVALID_PARAMETER;
                    KeReleaseSpinLock(
                        &Extension->ControlLock,
                        OldIrql
                        );
                    break;

                }

            }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetHandFlow,
                &S
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_GET_MODEMSTATUS: {

            SERIAL_IOCTL_SYNC S;

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(ULONG);

            S.Extension = Extension;
            S.Data = Irp->AssociatedIrp.SystemBuffer;

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialGetModemUpdate,
                &S
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_GET_DTRRTS: {

            ULONG ModemControl;
            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(ULONG);
            Irp->IoStatus.Status = STATUS_SUCCESS;

            //
            // Reading this hardware has no effect on the device.
            //

            ModemControl = READ_MODEM_CONTROL(Extension->Controller);

            ModemControl &= SERIAL_DTR_STATE | SERIAL_RTS_STATE;

            *(PULONG)Irp->AssociatedIrp.SystemBuffer = ModemControl;

            break;

        }
        case IOCTL_SERIAL_GET_COMMSTATUS: {

            SERIAL_IOCTL_SYNC S;

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_STATUS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(SERIAL_STATUS);

            S.Extension = Extension;
            S.Data =  Irp->AssociatedIrp.SystemBuffer;

            //
            // Acquire the cancel spin lock so nothing much
            // changes while were getting the state.
            //

            IoAcquireCancelSpinLock(&OldIrql);

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialGetCommStatus,
                &S
                );

            IoReleaseCancelSpinLock(OldIrql);

            break;

        }
        case IOCTL_SERIAL_GET_PROPERTIES: {


            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_COMMPROP)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // No synchronization is required since this information
            // is "static".
            //

            SerialGetProperties(
                Extension,
                Irp->AssociatedIrp.SystemBuffer
                );

            Irp->IoStatus.Information = sizeof(SERIAL_COMMPROP);
            Irp->IoStatus.Status = STATUS_SUCCESS;

            break;
        }
        case IOCTL_SERIAL_XOFF_COUNTER: {

            PSERIAL_XOFF_COUNTER Xc = Irp->AssociatedIrp.SystemBuffer;

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_XOFF_COUNTER)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            if (Xc->Counter <= 0) {

                Status = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // So far so good.  Put the irp onto the write queue.
            //

            return SerialStartOrQueue(
                       Extension,
                       Irp,
                       &Extension->WriteQueue,
                       &Extension->CurrentWriteIrp,
                       SerialStartWrite
                       );

        }
        case IOCTL_SERIAL_LSRMST_INSERT: {

            PUCHAR escapeChar = Irp->AssociatedIrp.SystemBuffer;

            //
            // Make sure we get a byte.
            //

            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(UCHAR)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            if (*escapeChar) {

                //
                // We've got some escape work to do.  We will make sure that
                // the character is not the same as the Xon or Xoff character,
                // or that we are already doing error replacement.
                //

                if ((*escapeChar == Extension->SpecialChars.XoffChar) ||
                    (*escapeChar == Extension->SpecialChars.XonChar) ||
                    (Extension->HandFlow.FlowReplace & SERIAL_ERROR_CHAR)) {

                    Status = STATUS_INVALID_PARAMETER;

                    KeReleaseSpinLock(
                        &Extension->ControlLock,
                        OldIrql
                        );
                    break;

                }

            }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetEscapeChar,
                Irp
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_CONFIG_SIZE: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(ULONG);
            Irp->IoStatus.Status = STATUS_SUCCESS;

            *(PULONG)Irp->AssociatedIrp.SystemBuffer = 0;

            break;
        }
        case IOCTL_SERIAL_GET_STATS: {

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIALPERF_STATS)) {

                Status = STATUS_BUFFER_TOO_SMALL;
                break;

            }
            Irp->IoStatus.Information = sizeof(SERIALPERF_STATS);
            Irp->IoStatus.Status = STATUS_SUCCESS;

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialGetStats,
                Irp
                );

            break;
        }
        case IOCTL_SERIAL_CLEAR_STATS: {

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialClearStats,
                Extension
                );
            break;
        }
        default: {

            Status = STATUS_INVALID_PARAMETER;
            break;
        }
    }

DoneWithIoctl:;

    Irp->IoStatus.Status = Status;

    SerialDump(
        SERIRPPATH,
        ("SERIAL: Complete Irp: %x\n",Irp)
        );
    IoCompleteRequest(
        Irp,
        0
        );

    return Status;

}
Example #15
0
static NTSTATUS manager_read(co_manager_t *manager, co_manager_open_desc_t opened,
			     PIRP Irp)
{
	NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
	co_rc_t rc;
	co_queue_t *queue;

	DbgPrint("colinux: manager_read...\n");
	if (!opened->active) {
		ntStatus = STATUS_PIPE_BROKEN;
		Irp->IoStatus.Status = ntStatus;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return ntStatus;
	}

	co_os_mutex_acquire(opened->lock);

	queue = &opened->out_queue;
	if (co_queue_size(queue) != 0) {
		unsigned char *io_buffer_start = Irp->AssociatedIrp.SystemBuffer;
		unsigned char *io_buffer = io_buffer_start;
		unsigned char *io_buffer_end = io_buffer + Irp->IoStatus.Information;

		while (co_queue_size(queue) != 0)
		{
			co_message_queue_item_t *message_item;
			rc = co_queue_peek_tail(queue, (void **)&message_item);
			if (!CO_OK(rc))
				return rc;

			co_message_t *message = message_item->message;
			uintptr_t size = message->size + sizeof(*message);
			if (io_buffer + size > io_buffer_end) {
				break;
			}

			rc = co_queue_pop_tail(queue, (void **)&message_item);
			if (!CO_OK(rc))
				break;

			co_queue_free(queue, message_item);
			co_memcpy(io_buffer, message, size);
			io_buffer += size;
			co_os_free(message);
		}

		Irp->IoStatus.Information = io_buffer - io_buffer_start;
		if (Irp->IoStatus.Information == 0)
			Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
		else
			Irp->IoStatus.Status = ntStatus = STATUS_SUCCESS;

		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	} else {
		if (opened->os->irp) {
			ntStatus = STATUS_INVALID_PARAMETER; /* TODO */
			Irp->IoStatus.Status = ntStatus;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);

		} else {
			KIRQL irql;
			IoAcquireCancelSpinLock(&irql);

			opened->ref_count++;
			ntStatus = STATUS_PENDING;
			Irp->IoStatus.Status = ntStatus;
			Irp->Tail.Overlay.DriverContext[0] = opened;
			fixme_IoSetCancelRoutine(Irp, manager_irp_cancel);
			opened->os->irp = Irp;
			IoMarkIrpPending(Irp);

			IoReleaseCancelSpinLock(irql);
		}
	}

	co_os_mutex_release(opened->lock);

	return ntStatus;
}
Example #16
0
VOID
NbfActionDatagramIndication(
    IN PDEVICE_CONTEXT DeviceContext,
    IN PNBF_HDR_CONNECTIONLESS UiFrame,
    IN ULONG Length
)

/*++

Routine Description:

    This routine is called after a datagram frame has been
    received. It checks if there is a DATAGRAM.INDICATION IRP
    waiting to be completed, and if so completes it.

Arguments:

    DeviceContext - Pointer to our device context.

    UiFrame - Pointer to the incoming frame. The first byte of
        information is the first byte of the NetBIOS connectionless
        header.

    Length - The length of the frame starting at UiFrame.

Return Value:

    None

--*/

{
    KIRQL oldirql, cancelirql;
    PTP_REQUEST Request;
    PLIST_ENTRY p;
    PACTION_DATAGRAM_INDICATION ActionHeader;
    PDATAGRAM_INDICATION DatagramIndication;
    ULONG CopyLength;
    PMDL Mdl;
    NTSTATUS Status;


    IoAcquireCancelSpinLock (&cancelirql);
    ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql);

    if (!IsListEmpty (&DeviceContext->DatagramIndicationQueue)) {

        p = RemoveHeadList (&DeviceContext->DatagramIndicationQueue);
        RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);

        Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage);
        IoSetCancelRoutine(Request->IoRequestPacket, NULL);
        IoReleaseCancelSpinLock(cancelirql);

        Mdl = Request->Buffer2;
        ActionHeader = (PACTION_DATAGRAM_INDICATION)
                       (MmGetSystemAddressForMdl(Mdl));
        DatagramIndication = &ActionHeader->DatagramIndication;

        //
        // Copy over data from frame (note that dest and source
        // address are copied with one call).
        //

        RtlCopyMemory ((PUCHAR)(DatagramIndication->DestinationName),
                       (PUCHAR)(UiFrame->DestinationName),
                       2 * NETBIOS_NAME_LENGTH);

        if ((Length-sizeof(NBF_HDR_CONNECTIONLESS)) <=
                (ULONG)DatagramIndication->DatagramBufferLength) {

            CopyLength = Length - sizeof(NBF_HDR_CONNECTIONLESS);
            Status = STATUS_SUCCESS;

        } else {

            CopyLength = DatagramIndication->DatagramBufferLength;
            Status = STATUS_BUFFER_OVERFLOW;

        }


        RtlCopyMemory(
            (PUCHAR)DatagramIndication->DatagramBuffer,
            ((PUCHAR)UiFrame) + sizeof(NBF_HDR_CONNECTIONLESS),
            CopyLength);
        DatagramIndication->DatagramBufferLength = (USHORT)CopyLength;

        NbfCompleteRequest (Request, Status, CopyLength +
                            FIELD_OFFSET (ACTION_DATAGRAM_INDICATION, DatagramIndication.DatagramBuffer[0]));

    } else {

        RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);
        IoReleaseCancelSpinLock(cancelirql);

    }
}
Example #17
0
NTSTATUS
NbfTdiAction(
    IN PDEVICE_CONTEXT DeviceContext,
    IN PIRP Irp
)

/*++

Routine Description:

    This routine performs the TdiAction request for the transport
    provider.

Arguments:

    DeviceContext - The device context for the operation

    Irp - the Irp for the requested operation.

Return Value:

    NTSTATUS - status of operation.

--*/

{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PTDI_ACTION_HEADER ActionHeader;
    LARGE_INTEGER timeout = {0,0};
    PTP_REQUEST tpRequest;
    KIRQL oldirql, cancelirql;
    ULONG BytesRequired;

    //
    // what type of status do we want?
    //

    irpSp = IoGetCurrentIrpStackLocation (Irp);

    if ((!Irp->MdlAddress) ||
            (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(TDI_ACTION_HEADER))) {
        return STATUS_INVALID_PARAMETER;
    }

    ActionHeader = (PTDI_ACTION_HEADER)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

    if (!ActionHeader) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Make sure we have required number of bytes for this type of request
    //

    switch (ActionHeader->ActionCode) {

    case QUERY_INDICATION_CODE:
        BytesRequired = sizeof(ACTION_QUERY_INDICATION);
        break;

    case DATAGRAM_INDICATION_CODE:
        BytesRequired = sizeof(ACTION_DATAGRAM_INDICATION);
        break;

    default:
        return STATUS_NOT_IMPLEMENTED;
    }

    if (MmGetMdlByteCount(Irp->MdlAddress) < BytesRequired) {
        return STATUS_INVALID_PARAMETER;
    }

    //
    // Here the request is one of QUERY_INDICATION or DATAGRAM_INDICATION
    //

    //
    // These two requests are sent by RAS to "MABF"
    //

    if (!RtlEqualMemory ((PVOID)(&ActionHeader->TransportId), "MABF", 4)) {
        return STATUS_NOT_SUPPORTED;
    }

    //
    // They should be sent on the control channel
    //

    if (irpSp->FileObject->FsContext2 != (PVOID)NBF_FILE_TYPE_CONTROL) {
        return STATUS_NOT_SUPPORTED;
    }


    //
    // Create a request to describe this.
    //

    status = NbfCreateRequest (
                 Irp,                           // IRP for this request.
                 DeviceContext,                 // context.
                 REQUEST_FLAGS_DC,              // partial flags.
                 Irp->MdlAddress,
                 MmGetMdlByteCount(Irp->MdlAddress),
                 timeout,
                 &tpRequest);

    if (NT_SUCCESS (status)) {

        NbfReferenceDeviceContext ("Action", DeviceContext, DCREF_REQUEST);
        tpRequest->Owner = DeviceContextType;
        tpRequest->FrameContext = (USHORT)irpSp->FileObject->FsContext;

        IoAcquireCancelSpinLock(&cancelirql);
        ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock,&oldirql);

        //
        // Disallow these requests on a stopping device.
        //

        if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) {

            RELEASE_SPIN_LOCK (&DeviceContext->SpinLock,oldirql);
            IoReleaseCancelSpinLock(cancelirql);
            NbfCompleteRequest (tpRequest, STATUS_DEVICE_NOT_READY, 0);

        } else {

            if (ActionHeader->ActionCode == QUERY_INDICATION_CODE) {

                InsertTailList (
                    &DeviceContext->QueryIndicationQueue,
                    &tpRequest->Linkage);

            } else {

                InsertTailList (
                    &DeviceContext->DatagramIndicationQueue,
                    &tpRequest->Linkage);

            }

            DeviceContext->IndicationQueuesInUse = TRUE;


            //
            // If this IRP has been cancelled, then call the
            // cancel routine.
            //

            if (Irp->Cancel) {
                RELEASE_SPIN_LOCK (&DeviceContext->SpinLock,oldirql);
                Irp->CancelIrql = cancelirql;
                NbfCancelAction((PDEVICE_OBJECT)DeviceContext, Irp);
                return STATUS_PENDING;
            }

            IoSetCancelRoutine(Irp, NbfCancelAction);

            RELEASE_SPIN_LOCK (&DeviceContext->SpinLock,oldirql);
            IoReleaseCancelSpinLock(cancelirql);

        }

        status = STATUS_PENDING;

    }

    return status;

}
Example #18
0
VOID
NbfStopControlChannel(
    IN PDEVICE_CONTEXT DeviceContext,
    IN USHORT ChannelIdentifier
)

/*++

Routine Description:

    This routine is called when an MJ_CLEANUP IRP is received
    on a control channel. It walks the device context's list of
    pending action requests and cancels those associated with
    this channel (as identified by ChannelIdentifier.

Arguments:

    DeviceContext - Pointer to our device context.

    ChannelIdentifier - The identifier for this open of the control
        channel, which is stored in Request->FrameContext for requests
        made on this channel.

Return Value:

    None

--*/

{

    KIRQL oldirql, cancelirql;
    PTP_REQUEST Request;
    PLIST_ENTRY p;
    UINT i;
    BOOLEAN FoundRequest;
    PLIST_ENTRY QueueHead, QueueEnd;


    //
    // Scan both queues, looking for requests. Since the list
    // may change, we scan until we find one, then remove it
    // and complete it. We then start scanning at the beginning
    // again. We continue until we find none on the queue that
    // belong to this control channel.
    //
    // The outer loop only runs twice; the first time it
    // processes QueryIndicationQueue, the second time
    // DatagramIndicationQueue.
    //

    for (i = 0; i < 2; i++) {

        do {

            //
            // Loop until we do not find a request on this
            // pass through the queue.
            //

            FoundRequest = FALSE;

            IoAcquireCancelSpinLock(&cancelirql);
            ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql);

            if (i == 0) {
                QueueHead = DeviceContext->QueryIndicationQueue.Flink;
                QueueEnd = &DeviceContext->QueryIndicationQueue;
            } else {
                QueueHead = DeviceContext->DatagramIndicationQueue.Flink;
                QueueEnd = &DeviceContext->DatagramIndicationQueue;
            }


            //
            // Scan the appropriate queue for a request on this
            // channel.
            //

            for (p = QueueHead; p != QueueEnd; p = p->Flink) {

                Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage);
                if (Request->FrameContext == ChannelIdentifier) {

                    //
                    // Found it, remove it from the list here.
                    //

                    IoSetCancelRoutine(Request->IoRequestPacket, NULL);
                    RemoveEntryList (p);

                    FoundRequest = TRUE;
                    break;

                }

            }

            RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);
            IoReleaseCancelSpinLock(cancelirql);

            //
            // If we found a request, then complete it and loop
            // back to the top of the while loop to rescan the
            // list. If not, then we will exit the while loop
            // now.
            //

            if (FoundRequest) {

                NbfCompleteRequest (Request, STATUS_CANCELLED, 0);

            }

        } while (FoundRequest);

    }

}
Example #19
0
VOID
NbfActionQueryIndication(
    IN PDEVICE_CONTEXT DeviceContext,
    IN PNBF_HDR_CONNECTIONLESS UiFrame
)

/*++

Routine Description:

    This routine is called after a UI frame of type NAME_QUERY,
    ADD_NAME_QUERY, or ADD_GROUP_NAME_QUERY has been processed.
    It checks if there is a QUERY.INDICATION IRP waiting to
    be completed, and if so completes it.

Arguments:

    DeviceContext - Pointer to our device context.

    UiFrame - Pointer to the incoming frame. The first byte of
        information is the first byte of the NetBIOS connectionless
        header.

Return Value:

    None

--*/

{
    KIRQL oldirql, cancelirql;
    PTP_REQUEST Request;
    PLIST_ENTRY p;
    PMDL Mdl;
    PACTION_QUERY_INDICATION ActionHeader;
    PQUERY_INDICATION QueryIndication;


    IoAcquireCancelSpinLock (&cancelirql);
    ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql);

    if (!IsListEmpty (&DeviceContext->QueryIndicationQueue)) {

        p = RemoveHeadList (&DeviceContext->QueryIndicationQueue);
        RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);

        Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage);
        IoSetCancelRoutine(Request->IoRequestPacket,NULL);
        IoReleaseCancelSpinLock(cancelirql);

        Mdl = Request->Buffer2;
        ActionHeader = (PACTION_QUERY_INDICATION)
                       (MmGetSystemAddressForMdl(Mdl));
        QueryIndication = &ActionHeader->QueryIndication;

        //
        // Copy over data from frame (note that dest and source
        // address are copied with one call).
        //

        QueryIndication->Command = UiFrame->Command;
        RtlCopyMemory ((PUCHAR)(&QueryIndication->Data2), (PUCHAR)(&UiFrame->Data2Low), 2);
        RtlCopyMemory ((PUCHAR)(QueryIndication->DestinationName),
                       (PUCHAR)(UiFrame->DestinationName),
                       2 * NETBIOS_NAME_LENGTH);

        NbfCompleteRequest (Request, STATUS_SUCCESS, sizeof(ACTION_QUERY_INDICATION));

    } else {

        RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);
        IoReleaseCancelSpinLock(cancelirql);

    }
}
Example #20
0
BOOLEAN
USBSTOR_QueueAddIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PDRIVER_CANCEL OldDriverCancel;
    KIRQL OldLevel;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;
    BOOLEAN IrpListFreeze;
    BOOLEAN SrbProcessing;
    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
    PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;

    //
    // get FDO device extension
    //
    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    //
    // sanity check
    //
    ASSERT(FDODeviceExtension->Common.IsFDO);

    //
    // mark irp pending
    //
    IoMarkIrpPending(Irp);

    //
    // acquire lock
    //
    KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);

    //
    // check if there are irp pending
    //
    SrbProcessing = FDODeviceExtension->IrpPendingCount != 0;

    if (SrbProcessing)
    {
        //
        // add irp to queue
        //
        InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry);
    }

    //
    // increment pending count
    //
    FDODeviceExtension->IrpPendingCount++;


    //
    // clear the no requests pending event
    //
    KeClearEvent(&FDODeviceExtension->NoPendingRequests);

    //
    // check if queue is freezed
    //
    IrpListFreeze = FDODeviceExtension->IrpListFreeze;

    //
    // release list lock
    //
    KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);

    //
    // synchronize with cancellations by holding the cancel lock
    //
    IoAcquireCancelSpinLock(&Irp->CancelIrql);

    //
    // now set the driver cancel routine
    //
    if (SrbProcessing)
    {
        ASSERT(FDODeviceExtension->ActiveSrb != NULL);

        OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_Cancel);
    }
    else
    {
        ASSERT(FDODeviceExtension->ActiveSrb == NULL);

        FDODeviceExtension->ActiveSrb = Request;
        OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
    }

    //
    // check if the irp has already been cancelled
    //
    if (Irp->Cancel && OldDriverCancel == NULL)
    {
        //
        // cancel irp
        //
        Irp->CancelRoutine(DeviceObject, Irp);

        //
        // irp was cancelled
        //
        return FALSE;
    }

    //
    // release the cancel lock
    //
    IoReleaseCancelSpinLock(Irp->CancelIrql);

    //
    // if list is freezed, dont start this packet
    //
    DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);

    return (IrpListFreeze || SrbProcessing);
}
Example #21
0
NTSTATUS body()

{


   if (STATUS_SUCCESS != status)
   {
     while(1) { int ddd2; ddd2 = ddd2; }

   }


   if(1) {

      if(nondet()) {

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;
           }

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_SET_WAIT_MASK:*/ {

           CurrentWaitIrp=NULL;
           NewMask = nondet();

           if (nondet()) {

               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           } else {

               keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

               NewMask = nondet();




               keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

               if (CurrentWaitIrp != NULL) {






                   RemoveReferenceAndCompleteRequest(CurrentWaitIrp,
STATUS_SUCCESS);
               }


           }

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_WAIT_ON_MASK:*/ {

           CurrentWaitIrp=NULL;

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }


           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);




           CurrentWaitIrp=nondet();




           if (nondet()) {



               status=STATUS_UNSUCCESSFUL;

           } else {




               IoMarkIrpPending(Irp);
               status=STATUS_PENDING;
           }

           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           if (CurrentWaitIrp != NULL) {






               RemoveReferenceAndCompleteRequest(
                   CurrentWaitIrp, STATUS_SUCCESS);
           }


           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_PURGE:*/ {

	 CancelIrp = nondet();
	 Mask= nondet();

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }

           if (Mask & SERIAL_PURGE_RXABORT) {

               keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

               length = nondet();
               while (length>0) {

                   length--;
                   CancelIrp=nondet();

                   IoAcquireCancelSpinLock(&CancelIrql);

                   if (nondet()) {
                       IoReleaseCancelSpinLock(CancelIrql);
                       continue;
                   }

                   //IoSetCancelRoutine(CancelIrp, NULL);

                   IoReleaseCancelSpinLock(CancelIrql);

                   keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);


                   RemoveReferenceAndCompleteRequest(
                        CancelIrp, STATUS_CANCELLED);

                   keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);
               }

               CancelIrp=NULL;

               if (nondet())
               {
                   CancelIrp=nondet();

               }

               keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

               if (CancelIrp != NULL) {

                   RemoveReferenceAndCompleteRequest(
                       CancelIrp, STATUS_CANCELLED);

               }

           }


           /*break*/;
       }


       else if(nondet()) /* case IOCTL_SERIAL_GET_MODEMSTATUS:*/ {


           if (nondet()) {

               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }



           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_SET_TIMEOUTS:*/ {

           NewTimeouts = nondet();

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }

           if (nondet()) {
               status = STATUS_INVALID_PARAMETER;
               /*break*/;
           }

           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_GET_TIMEOUTS:*/ {

           if (nondet()) {

               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }

           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_GET_COMMSTATUS:*/ {

           SerialStatus=nondet();

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           }

           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           /*break*/;
       }

      //else if(nondet())  case IOCTL_SERIAL_SET_DTR:  {}
       else if(nondet()) /* case IOCTL_SERIAL_CLR_DTR:*/ {


           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

           if (nondet()) {
           } else {
               if (nondet()) {
               }
           }


           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           ProcessConnectionStateChange(DeviceObject);


           /*break*/;
       }


       else if(nondet()) /* case IOCTL_SERIAL_SET_QUEUE_SIZE:*/ {

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;
           }

           /*break*/;
       }


       else if(nondet()) /* case IOCTL_SERIAL_SET_BAUD_RATE:*/ {

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           } else {

               keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

               keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);
           }


           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_GET_BAUD_RATE:*/ {

           pBaudRate = nondet();

           if (nondet()) {

               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;

           } else {

               keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

               keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);


           }

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_SET_LINE_CONTROL:*/ {

           pLineControl = nondet();
           LData = 0;
           LStop = 0;
           LParity = 0;
           Mask = 0xff;

           if (nondet()) {
               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;
           }

           if(1) { // switch(nondet())

               if(nondet()) /* case 5:*/ {

                   LData = SERIAL_5_DATA;
                   Mask = 0x1f;
                   /*break*/;

               }
               else if(nondet()) /* case 6:*/ {

                   LData = SERIAL_6_DATA;
                   Mask = 0x3f;
                   /*break*/;

               }
               else if(nondet()) /* case 7:*/ {

                   LData = SERIAL_7_DATA;
                   Mask = 0x7f;
                   /*break*/;

               }
               else if(nondet()) /* case 8:*/ {

                   LData = SERIAL_8_DATA;
                   /*break*/;

               }
	       else /*default:*/ {

                   status = STATUS_INVALID_PARAMETER;

               }
           }

           if (status != STATUS_SUCCESS)
           {
               /*break*/;
           }

           if(1) { // switch (nondet()) {

               if(nondet()) /* case NO_PARITY:*/ {
                   LParity = SERIAL_NONE_PARITY;
                   /*break*/;

               }
               else if(nondet()) /* case EVEN_PARITY:*/ {
                   LParity = SERIAL_EVEN_PARITY;
                   /*break*/;

               }
               else if(nondet()) /* case ODD_PARITY:*/ {
                   LParity = SERIAL_ODD_PARITY;
                   /*break*/;

               }
               else if(nondet()) /* case SPACE_PARITY:*/ {
                   LParity = SERIAL_SPACE_PARITY;
                   /*break*/;

               }
               else if(nondet()) /* case MARK_PARITY:*/ {
                   LParity = SERIAL_MARK_PARITY;
                   /*break*/;

               }
               else /*default:*/ {

                   status = STATUS_INVALID_PARAMETER;
                   /*break*/;
               }

           }

           if (status != STATUS_SUCCESS)
           {
               /*break*/;
           }

           if (1) { /* switch */

               if(nondet()) /* case STOP_BIT_1:*/ {

                   LStop = SERIAL_1_STOP;
                   /*break*/;
               }

               else if(nondet()) /* case STOP_BITS_1_5:*/ {

                   if (LData != SERIAL_5_DATA) {

                       status = STATUS_INVALID_PARAMETER;
                       /*break*/;
                   }
                   LStop = SERIAL_1_5_STOP;
                   /*break*/;

               }
               else if(nondet()) /* case STOP_BITS_2:*/ {

                   if (LData == SERIAL_5_DATA) {

                       status = STATUS_INVALID_PARAMETER;
                       /*break*/;
                   }

                   LStop = SERIAL_2_STOP;
                   /*break*/;
               }

               else /*default:*/ {

                   status = STATUS_INVALID_PARAMETER;
               }

           }

           if (status != STATUS_SUCCESS)
           {
               /*break*/;
           }


           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);

           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_GET_LINE_CONTROL:*/ {

           if (nondet())  {

               status = STATUS_BUFFER_TOO_SMALL;
               /*break*/;
           }

           keA = 1; keA = 0; KeAcquireSpinLock(&lock, &OldIrql);


           keR = 1; keR = 0; KeReleaseSpinLock(&lock, OldIrql);

           /*break*/;
       }

       else if(nondet()) /* case IOCTL_SERIAL_SET_RTS:*/ {

           /*break*/;

       }

       else /*default: */

           status=STATUS_NOT_SUPPORTED;
   }

   if (status != STATUS_PENDING) {




       if (Irp != NULL)
       {
           RemoveReferenceAndCompleteRequest(Irp, status);
       }
   }


   RemoveReferenceForDispatch(DeviceObject);

   while (1) { int rrr; rrr = rrr; }


}
Example #22
0
NTSTATUS
Ik220FilterIrps(IN PIRP PIrp, IN PIK220_DEVICE_EXTENSION PDevExt)
/*++

Routine Description:

    This routine will be used to approve irps for processing.
    If an irp is approved, success will be returned.  If not,
    the irp will be queued or rejected outright.  The IoStatus struct
    and return value will appropriately reflect the actions taken.

Arguments:

    PIrp - Pointer to the Irp to cancel

    PDevExt - Pointer to the device extension

Return Value:

    None.

--*/
{
   PIO_STACK_LOCATION pIrpStack;
   KIRQL oldIrqlFlags;

   pIrpStack = IoGetCurrentIrpStackLocation(PIrp);

   KeAcquireSpinLock(&PDevExt->FlagsLock, &oldIrqlFlags);

   if ((PDevExt->DevicePNPAccept == IK220_PNPACCEPT_OK)
       && ((PDevExt->Flags & IK220_FLAGS_BROKENHW) == 0)) {
      KeReleaseSpinLock(&PDevExt->FlagsLock, oldIrqlFlags);
      return STATUS_SUCCESS;
   }

   if ((PDevExt->DevicePNPAccept & IK220_PNPACCEPT_REMOVING)
       || (PDevExt->Flags & IK220_FLAGS_BROKENHW)
       || (PDevExt->DevicePNPAccept & IK220_PNPACCEPT_SURPRISE_REMOVING)) {

      KeReleaseSpinLock(&PDevExt->FlagsLock, oldIrqlFlags);

      //
      // Accept all PNP IRP's -- we assume PNP can synchronize itself
      //

      if (pIrpStack->MajorFunction == IRP_MJ_PNP) {
         return STATUS_SUCCESS;
      }

      PIrp->IoStatus.Status = STATUS_DELETE_PENDING;
      return STATUS_DELETE_PENDING;
   }

   if (PDevExt->DevicePNPAccept & IK220_PNPACCEPT_STOPPING) {
       KIRQL oldIrql;

       KeReleaseSpinLock(&PDevExt->FlagsLock, oldIrqlFlags);


      //
      // Accept all PNP IRP's -- we assume PNP can synchronize itself
      //

      if (pIrpStack->MajorFunction == IRP_MJ_PNP) {
         return STATUS_SUCCESS;
      }

      IoAcquireCancelSpinLock(&oldIrql);

      if (PIrp->Cancel) {
         IoReleaseCancelSpinLock(oldIrql);
         PIrp->IoStatus.Status = STATUS_CANCELLED;
         return STATUS_CANCELLED;
      } else {
         //
         // Mark the Irp as pending
         //

         PIrp->IoStatus.Status = STATUS_PENDING;
         IoMarkIrpPending(PIrp);

         //
         // Queue up the IRP
         //

         InsertTailList(&PDevExt->StalledIrpQueue,
                        &PIrp->Tail.Overlay.ListEntry);

         IoSetCancelRoutine(PIrp, Ik220FilterCancelQueued);
         IoReleaseCancelSpinLock(oldIrql);
         return STATUS_PENDING;
      }
   }

   KeReleaseSpinLock(&PDevExt->FlagsLock, oldIrqlFlags);

   return STATUS_SUCCESS;
}
Example #23
0
NTSTATUS
NTAPI
USBH_FdoWWIrpIoCompletion(IN PDEVICE_OBJECT DeviceObject,
                          IN PIRP Irp,
                          IN PVOID Context)
{
    PUSBHUB_FDO_EXTENSION HubExtension;
    NTSTATUS Status;
    KIRQL OldIrql;
    POWER_STATE PowerState;
    PIRP WakeIrp;

    DPRINT("USBH_FdoWWIrpIoCompletion: DeviceObject - %p, Irp - %p\n",
            DeviceObject,
            Irp);

    HubExtension = Context;

    Status = Irp->IoStatus.Status;

    IoAcquireCancelSpinLock(&OldIrql);

    HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_PENDING_WAKE_IRP;

    WakeIrp = InterlockedExchangePointer((PVOID *)&HubExtension->PendingWakeIrp,
                                         NULL);

    if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
    {
        KeSetEvent(&HubExtension->PendingRequestEvent,
                   EVENT_INCREMENT,
                   FALSE);
    }

    IoReleaseCancelSpinLock(OldIrql);

    DPRINT("USBH_FdoWWIrpIoCompletion: Status - %lX\n", Status);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("USBH_FdoWWIrpIoCompletion: DbgBreakPoint() \n");
        DbgBreakPoint();
    }
    else
    {
        PowerState.DeviceState = PowerDeviceD0;

        HubExtension->HubFlags |= USBHUB_FDO_FLAG_WAKEUP_START;
        InterlockedIncrement(&HubExtension->PendingRequestCount);

        Status = STATUS_SUCCESS;

        PoRequestPowerIrp(HubExtension->LowerPDO,
                          IRP_MN_SET_POWER,
                          PowerState,
                          USBH_FdoPoRequestD0Completion,
                          (PVOID)HubExtension,
                          NULL);
    }

    if (!WakeIrp)
    {
        if (!InterlockedExchange(&HubExtension->FdoWaitWakeLock, 1))
        {
            Status = STATUS_MORE_PROCESSING_REQUIRED;
        }
    }

    DPRINT("USBH_FdoWWIrpIoCompletion: Status - %lX\n", Status);

    if (Status != STATUS_MORE_PROCESSING_REQUIRED)
    {
        PoStartNextPowerIrp(Irp);
    }

    return Status;
}
Example #24
0
GENERICAPI NTSTATUS GENERIC_EXPORT InitializeGenericExtension(PGENERIC_EXTENSION pdx, PGENERIC_INIT_STRUCT isp)
	{							// InitializeGenericExtension
	if (isp->Size < FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags)
		|| !isp->DeviceObject
		|| !isp->Ldo
		|| !isp->Pdo
		|| !isp->StartDevice
		|| !isp->StopDevice
		|| !isp->RemoveDevice
		|| isp->DeviceQueue && !isp->StartIo)

		return STATUS_INVALID_PARAMETER;

	RtlZeroMemory(pdx, sizeof(GENERIC_EXTENSION));

	pdx->DeviceObject = isp->DeviceObject;
	pdx->LowerDeviceObject = isp->Ldo;
	pdx->Pdo = isp->Pdo;
	pdx->StartDevice = isp->StartDevice;
	pdx->StopDevice = isp->StopDevice;
	pdx->RemoveDevice = isp->RemoveDevice;

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, OkayToRemove) + sizeof(PQUERYFUNCTION))
		{						// set OkayToStop & OkayToRemove pointers
		pdx->OkayToStop = isp->OkayToStop;
		pdx->OkayToRemove = isp->OkayToRemove;
		}						// set OkayToStop & OkayToRemove pointers

	if ((pdx->dqReadWrite = isp->DeviceQueue))
		{						// queue reads & writes
		if (!isp->StartIo)
			return STATUS_INVALID_PARAMETER;
		InitializeQueue(pdx->dqReadWrite, isp->StartIo);
		}						// queue reads & writes

	if ((pdx->RemoveLock = isp->RemoveLock))
		IoInitializeRemoveLock(pdx->RemoveLock, 0, 0, 0);

	pdx->state = STOPPED;
	
	pdx->devpower = PowerDeviceD0;
	pdx->syspower = PowerSystemWorking;
	POWER_STATE state;
	state.DeviceState = PowerDeviceD0;
	PoSetPowerState(pdx->DeviceObject, DevicePowerState, state);

	// Capture the mini-driver name for messages. This needs to be in ANSI because
	// unicode conversions at or above DISPATCH_LEVEL are not allowed

	if (!isp->DebugName.Length)
		strcpy(pdx->DebugName, "GENERIC");
	else
		{						// convert debug name
		ANSI_STRING asname = {0, sizeof(pdx->DebugName) - 1, pdx->DebugName};
		RtlUnicodeStringToAnsiString(&asname, &isp->DebugName, FALSE);
		pdx->DebugName[asname.Length] = 0;
		}						// convert debug name

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags) + sizeof(ULONG))
		pdx->Flags = isp->Flags & GENERIC_CLIENT_FLAGS;

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, RestoreDeviceContext) + sizeof(PCONTEXTFUNCTION))
		{						// get power helper functions
		pdx->QueryPower = isp->QueryPower;
		pdx->SaveDeviceContext = isp->SaveDeviceContext;
		pdx->RestoreDeviceContext = isp->RestoreDeviceContext;
		}						// get power helper functions

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, PerfBoundary) + sizeof(DEVICE_POWER_STATE))
		pdx->PerfBoundary = isp->PerfBoundary;
	else
		pdx->PerfBoundary = PowerDeviceUnspecified;

	if (pdx->PerfBoundary == PowerDeviceUnspecified)
		pdx->PerfBoundary = PowerDeviceMaximum; // inhibit POWER_SEQUENCE optimization

	// Initialize variables related to asynchrounous IOCTL management.

	if (pdx->Flags & GENERIC_PENDING_IOCTLS)
		{						// driver may cache asyncronous IOCTLs
		InitializeListHead(&pdx->PendingIoctlList);
		pdx->IoctlAbortStatus = 0;

		// We need to initialize our IOCTL spin lock sometime, but just once.
		// Acquiring the cancel spin lock to guard this operation is a bit of
		// a hack, I suppose, but note that a class driver like this one never
		// gets an actual chance to initialize, so it's not my fault...

		KIRQL oldirql;
		IoAcquireCancelSpinLock(&oldirql);	// any global spin lock would do
		if (!IoctlListLockInitialized)
			{					// initialize global lock
			IoctlListLockInitialized = TRUE;
			KeInitializeSpinLock(&IoctlListLock);
			}					// initialize global lock
		IoReleaseCancelSpinLock(oldirql);
		}						// driver may cache asynchronous IOCTLs

	// Initialize to manage registered device interfaces

	ExInitializeFastMutex(&pdx->iflock);
	InitializeListHead(&pdx->iflist);

	// Indicate we handle power IRPs at PASSIVE_LEVEL

	pdx->DeviceObject->Flags |= DO_POWER_PAGABLE;

	KdPrint(("GENERIC - Initializing for %s\n", pdx->DebugName));

	// If requested to do so, register an AutoLaunch interface

	if (pdx->Flags & GENERIC_AUTOLAUNCH)
		GenericRegisterInterface(pdx, &GUID_AUTOLAUNCH_NOTIFY);

	// Register a power management interface

	GenericRegisterInterface(pdx, &GUID_GENERIC_POWER);

#ifdef _X86_
	win98 = IsWin98();
#endif

	return STATUS_SUCCESS;
	}							// InitializeGenericExtension
Example #25
0
NTSTATUS
NbfTdiReceive(
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine performs the TdiReceive request for the transport provider.

Arguments:

    Irp - I/O Request Packet for this request.

Return Value:

    NTSTATUS - status of operation.

--*/

{
    NTSTATUS status;
    PTP_CONNECTION connection;
    KIRQL oldirql;
    PIO_STACK_LOCATION irpSp;

    //
    // verify that the operation is taking place on a connection. At the same
    // time we do this, we reference the connection. This ensures it does not
    // get removed out from under us. Note also that we do the connection
    // lookup within a try/except clause, thus protecting ourselves against
    // really bogus handles
    //

    irpSp = IoGetCurrentIrpStackLocation (Irp);
    connection = irpSp->FileObject->FsContext;

    //
    // Check that this is really a connection.
    //

    if ((connection->Size != sizeof (TP_CONNECTION)) ||
        (connection->Type != NBF_CONNECTION_SIGNATURE)) {
#if DBG
        NbfPrint2 ("TdiReceive: Invalid Connection %lx Irp %lx\n", connection, Irp);
#endif
        return STATUS_INVALID_CONNECTION;
    }

    //
    // Initialize bytes transferred here.
    //

    Irp->IoStatus.Information = 0;              // reset byte transfer count.

    // This reference is removed by NbfDestroyRequest.

    KeRaiseIrql (DISPATCH_LEVEL, &oldirql);

    ACQUIRE_DPC_C_SPIN_LOCK (&connection->SpinLock);

    if ((connection->Flags & CONNECTION_FLAGS_READY) == 0) {

        RELEASE_DPC_C_SPIN_LOCK (&connection->SpinLock);

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

        status = STATUS_PENDING;

    } else {
        KIRQL cancelIrql;

        //
        // Once the reference is in, LinkSpinLock will be valid.
        //

        NbfReferenceConnection("TdiReceive request", connection, CREF_RECEIVE_IRP);
        RELEASE_DPC_C_SPIN_LOCK (&connection->SpinLock);

        IoAcquireCancelSpinLock(&cancelIrql);
        ACQUIRE_DPC_SPIN_LOCK (connection->LinkSpinLock);

        IRP_RECEIVE_IRP(irpSp) = Irp;
        IRP_RECEIVE_REFCOUNT(irpSp) = 1;

#if DBG
        NbfReceives[NbfReceivesNext].Irp = Irp;
        NbfReceives[NbfReceivesNext].Request = NULL;
        NbfReceives[NbfReceivesNext].Connection = (PVOID)connection;
        NbfReceivesNext = (NbfReceivesNext++) % TRACK_TDI_LIMIT;
#endif

        //
        // If this IRP has been cancelled, complete it now.
        //

        if (Irp->Cancel) {

#if DBG
            NbfCompletedReceives[NbfCompletedReceivesNext].Irp = Irp;
            NbfCompletedReceives[NbfCompletedReceivesNext].Request = NULL;
            NbfCompletedReceives[NbfCompletedReceivesNext].Status = STATUS_CANCELLED;
            {
                ULONG i,j,k;
                PUCHAR va;
                PMDL mdl;

                mdl = Irp->MdlAddress;

                NbfCompletedReceives[NbfCompletedReceivesNext].Contents[0] = (UCHAR)0;

                i = 1;
                while (i<TRACK_TDI_CAPTURE) {
                    if (mdl == NULL) break;
                    va = MmGetSystemAddressForMdl (mdl);
                    j = MmGetMdlByteCount (mdl);

                    for (i=i,k=0;i<TRACK_TDI_CAPTURE&k<j;i++,k++) {
                        NbfCompletedReceives[NbfCompletedReceivesNext].Contents[i] = *va++;
                    }
                    mdl = mdl->Next;
                }
            }

            NbfCompletedReceivesNext = (NbfCompletedReceivesNext++) % TRACK_TDI_LIMIT;
#endif

            //
            // It is safe to do this with locks held.
            //
            NbfCompleteReceiveIrp (Irp, STATUS_CANCELLED, 0);

            RELEASE_DPC_SPIN_LOCK (connection->LinkSpinLock);
            IoReleaseCancelSpinLock(cancelIrql);

        } else {

            //
            // Insert onto the receive queue, and make the IRP
            // cancellable.
            //

            InsertTailList (&connection->ReceiveQueue,&Irp->Tail.Overlay.ListEntry);
            IoSetCancelRoutine(Irp, NbfCancelReceive);

            //
            // Release the cancel spinlock out of order. Since we were
            // already at dpc level when it was acquired, we don't
            // need to swap irqls.
            //
            ASSERT(cancelIrql == DISPATCH_LEVEL);
            IoReleaseCancelSpinLock(cancelIrql);

            //
            // This call releases the link spinlock, and references the
            // connection first if it needs to access it after
            // releasing the lock.
            //

            AwakenReceive (connection);             // awaken if sleeping.

        }

        status = STATUS_PENDING;

    }

    KeLowerIrql (oldirql);

    return status;
} /* TdiReceive */
Example #26
0
VOID
SoundAddIrpToCancellableQ(
    PLIST_ENTRY QueueHead,
    PIRP Irp,
    BOOLEAN Head
)
/*++

Routine Description:


    Add the Irp to the queue and set the cancel routine under the
    protection of the cancel spin lock.

Arguments:

    QueueHead - the queue to add it to
    Irp - the Irp
    Head - if TRUE insert at the head of the queue

Return Value:

    None.

--*/
{
    KIRQL OldIrql;

    //
    // Get the cancel spin lock so we can mess with the cancel stuff
    //

    IoAcquireCancelSpinLock(&OldIrql);

    //
    // Well, it may ALREADY be cancelled!
    //

    if (Irp->Cancel) {

        dprintf2(("Irp already cancelled"));

        //
        // Release the cancel spin lock
        //

        IoReleaseCancelSpinLock(OldIrql);

        //
        // Set status and complete
        //

        Irp->IoStatus.Status = STATUS_CANCELLED;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return;
    }

    //
    // Set the cancel routine
    //

    IoSetCancelRoutine(Irp, SoundRemoveAndComplete);

    //
    // Insert it in the queue
    //

    if (Head) {
        InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry);
    } else {
        InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry);
    }

    //
    // Free the spin lock
    //

    IoReleaseCancelSpinLock(OldIrql);
}
Example #27
0
VOID
otLwfEventProcessingStop(
    _In_ PMS_FILTER             pFilter
    )
{
    PLIST_ENTRY Link = NULL;

    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p", pFilter);

    // By this point, we have disabled the Data Path, so no more 
    // NBLs should be queued up.

    // Clean up worker thread
    if (pFilter->EventWorkerThread)
    {
        LogInfo(DRIVER_DEFAULT, "Stopping event processing worker thread and waiting for it to complete.");

        // Send event to shutdown worker thread
        KeSetEvent(&pFilter->EventWorkerThreadStopEvent, 0, FALSE);

        // Wait for worker thread to finish
        KeWaitForSingleObject(
            pFilter->EventWorkerThread,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        // Free worker thread
        ObDereferenceObject(pFilter->EventWorkerThread);
        pFilter->EventWorkerThread = NULL;

        LogInfo(DRIVER_DEFAULT, "Event processing worker thread cleaned up.");
    }

    // Clean up any left over events
    if (pFilter->AddressChangesHead.Flink)
    {
        Link = pFilter->AddressChangesHead.Flink;
        while (Link != &pFilter->AddressChangesHead)
        {
            POTLWF_ADDR_EVENT Event = CONTAINING_RECORD(Link, OTLWF_ADDR_EVENT, Link);
            Link = Link->Flink;

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Clean up any left over events
    if (pFilter->NBLsHead.Flink)
    {
        Link = pFilter->NBLsHead.Flink;
        while (Link != &pFilter->NBLsHead)
        {
            POTLWF_NBL_EVENT Event = CONTAINING_RECORD(Link, OTLWF_NBL_EVENT, Link);
            Link = Link->Flink;

            otLwfCompleteNBLs(pFilter, FALSE, Event->NetBufferLists, STATUS_CANCELLED);

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Clean up any left over events
    if (pFilter->MacFramesHead.Flink)
    {
        Link = pFilter->MacFramesHead.Flink;
        while (Link != &pFilter->MacFramesHead)
        {
            POTLWF_MAC_FRAME_EVENT Event = CONTAINING_RECORD(Link, OTLWF_MAC_FRAME_EVENT, Link);
            Link = Link->Flink;

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Reinitialize the list head
    InitializeListHead(&pFilter->AddressChangesHead);
    InitializeListHead(&pFilter->NBLsHead);
    InitializeListHead(&pFilter->MacFramesHead);
    
    if (pFilter->EventIrpListHead.Flink)
    {
        FILTER_ACQUIRE_LOCK(&pFilter->EventsLock, FALSE);

        // Clean up any left over IRPs
        Link = pFilter->EventIrpListHead.Flink;
        while (Link != &pFilter->EventIrpListHead)
        {
            PIRP Irp = CONTAINING_RECORD(Link, IRP, Tail.Overlay.ListEntry);
            Link = Link->Flink;
        
            // Before we are allowed to complete the pending IRP, we must remove the cancel routine
            KIRQL irql;
            IoAcquireCancelSpinLock(&irql);
            IoSetCancelRoutine(Irp, NULL);
            IoReleaseCancelSpinLock(irql);

            Irp->IoStatus.Status = STATUS_CANCELLED;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }
    
        // Reinitialize the list head
        InitializeListHead(&pFilter->EventIrpListHead);
    
        FILTER_RELEASE_LOCK(&pFilter->EventsLock, FALSE);
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Example #28
0
VOID
NTAPI
USBSTOR_StartIo(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;
    PPDO_DEVICE_EXTENSION PDODeviceExtension;
    KIRQL OldLevel;
    BOOLEAN ResetInProgress;

    DPRINT("USBSTOR_StartIo\n");

    //
    // get FDO device extension
    //
    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    //
    // sanity check
    //
    ASSERT(FDODeviceExtension->Common.IsFDO);

    //
    // acquire cancel spinlock
    //
    IoAcquireCancelSpinLock(&OldLevel);

    //
    // set cancel routine to zero
    //
    IoSetCancelRoutine(Irp, NULL);

    //
    // check if the irp has been cancelled
    //
    if (Irp->Cancel)
    {
        //
        // irp has been cancelled, release cancel spinlock
        //
        IoReleaseCancelSpinLock(OldLevel);

        //
        // irp is cancelled
        //
        Irp->IoStatus.Status = STATUS_CANCELLED;
        Irp->IoStatus.Information = 0;

        //
        // terminate request
        //
        USBSTOR_QueueTerminateRequest(DeviceObject, Irp);

        //
        // complete request
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        //
        // queue next request
        //
        USBSTOR_QueueNextRequest(DeviceObject);

        //
        // done
        //
        return;
    }

    //
    // release cancel spinlock
    //
    IoReleaseCancelSpinLock(OldLevel);

    //
    // acquire lock
    //
    KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);

    //
    // check reset is in progress
    //
    ResetInProgress = FDODeviceExtension->ResetInProgress;
    ASSERT(ResetInProgress == FALSE);

    //
    // release lock
    //
    KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);

    //
    // get current irp stack location
    //
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // get pdo device extension
    //
    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;

    //
    // sanity check
    //
    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);

    //
    // is a reset in progress
    //
    if (ResetInProgress)
    {
        //
        // hard reset is in progress
        //
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
        USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return;
    }

    //
    // execute scsi
    //
    USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0);

    //
    // FIXME: handle error
    //
}
Example #29
0
NTSTATUS
NbfTdiReceiveDatagram(
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine performs the TdiReceiveDatagram request for the transport
    provider. Receive datagrams just get queued up to an address, and are
    completed when a DATAGRAM or DATAGRAM_BROADCAST frame is received at
    the address.

Arguments:

    Irp - I/O Request Packet for this request.

Return Value:

    NTSTATUS - status of operation.

--*/

{
    NTSTATUS status;
    KIRQL oldirql;
    PTP_ADDRESS address;
    PTP_ADDRESS_FILE addressFile;
    PIO_STACK_LOCATION irpSp;
    KIRQL cancelIrql;

    //
    // verify that the operation is taking place on an address. At the same
    // time we do this, we reference the address. This ensures it does not
    // get removed out from under us. Note also that we do the address
    // lookup within a try/except clause, thus protecting ourselves against
    // really bogus handles
    //

    irpSp = IoGetCurrentIrpStackLocation (Irp);
    addressFile = irpSp->FileObject->FsContext;

    status = NbfVerifyAddressObject (addressFile);

    if (!NT_SUCCESS (status)) {
        return status;
    }

#if DBG
    if (((PTDI_REQUEST_KERNEL_RECEIVEDG)(&irpSp->Parameters))->ReceiveLength > 0) {
        ASSERT (Irp->MdlAddress != NULL);
    }
#endif

    address = addressFile->Address;

    IoAcquireCancelSpinLock(&cancelIrql);
    ACQUIRE_SPIN_LOCK (&address->SpinLock,&oldirql);

    if ((address->Flags & (ADDRESS_FLAGS_STOPPING | ADDRESS_FLAGS_CONFLICT)) != 0) {

        RELEASE_SPIN_LOCK (&address->SpinLock,oldirql);
        IoReleaseCancelSpinLock(cancelIrql);

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = (address->Flags & ADDRESS_FLAGS_STOPPING) ?
                    STATUS_NETWORK_NAME_DELETED : STATUS_DUPLICATE_NAME;
        IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);

    } else {

        //
        // If this IRP has been cancelled, then call the
        // cancel routine.
        //

        if (Irp->Cancel) {

            RELEASE_SPIN_LOCK (&address->SpinLock, oldirql);
            IoReleaseCancelSpinLock(cancelIrql);

            Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = STATUS_CANCELLED;
            IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);

        } else {

            IoSetCancelRoutine(Irp, NbfCancelReceiveDatagram);
            NbfReferenceAddress ("Receive datagram", address, AREF_REQUEST);
            InsertTailList (&addressFile->ReceiveDatagramQueue,&Irp->Tail.Overlay.ListEntry);
            RELEASE_SPIN_LOCK (&address->SpinLock,oldirql);
            IoReleaseCancelSpinLock(cancelIrql);
        }

    }

    NbfDereferenceAddress ("Temp rcv datagram", address, AREF_VERIFY);

    return STATUS_PENDING;

} /* TdiReceiveDatagram */
Example #30
0
VOID
SoundFreePendingIrps(
    PLIST_ENTRY QueueHead,
    PFILE_OBJECT FileObject
)
{
    KIRQL OldIrql;

    //
    // Free anyone waiting for the volume to change whose file object
    // is the one about to be closed.
    //

    PLIST_ENTRY ListEntry, Next;

    //
    // Our list is cancellable so do this under the cancel spin
    // lock
    //

    IoAcquireCancelSpinLock(&OldIrql);

    for (ListEntry = QueueHead->Flink;
         ListEntry != QueueHead;
         ListEntry = Next) {

        PIRP IrpList;
        IrpList = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);

        Next = ListEntry->Flink;

        ASSERT(IoGetCurrentIrpStackLocation(IrpList)->MajorFunction ==
                   IRP_MJ_DEVICE_CONTROL);

        if (FileObject ==
                IoGetCurrentIrpStackLocation(IrpList)->FileObject) {

            RemoveEntryList(ListEntry);

            //
            // Make sure our cancel routine doesn't get in!
            //

            IoSetCancelRoutine(IrpList, NULL);


            //
            // Free the spin lock in case IoCompleteRequest doesn't
            // like us to hold it
            //

            IoReleaseCancelSpinLock(OldIrql);

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

            IoAcquireCancelSpinLock(&OldIrql);

            //
            // The world may have changed so restart
            //

            Next = QueueHead->Flink;
        }
    }

    IoReleaseCancelSpinLock(OldIrql);
}