Esempio n. 1
0
NTSTATUS
NTAPI
BeepDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                  IN PIRP Irp)
{
    PIO_STACK_LOCATION Stack;
    PBEEP_SET_PARAMETERS BeepParam;
    NTSTATUS Status;

    /* Get the stack location and parameters */
    Stack = IoGetCurrentIrpStackLocation(Irp);
    BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;

    /* We only support one IOCTL */
    if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
    {
        /* Unsupported command */
        Status = STATUS_NOT_IMPLEMENTED;
    }
    else
    {
        /* Validate the input buffer length */
        if (Stack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(BEEP_SET_PARAMETERS))
        {
            /* Invalid buffer */
            Status = STATUS_INVALID_PARAMETER;
        }
        else if ((BeepParam->Frequency != 0) && !(BeepParam->Duration))
        {
            /* No duration, return imemdiately */
            Status = STATUS_SUCCESS;
        }
        else
        {
            /* We'll queue this request */
            Status = STATUS_PENDING;
        }
    }

    /* Set packet information */
    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = 0;

    /* Check if we're completing or queuing a packet */
    if (Status == STATUS_PENDING)
    {
        /* Start the queue */
        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, BeepCancel);
    }
    else
    {
        /* Complete the request */
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    /* Return */
    return Status;
}
Esempio n. 2
0
NTSTATUS
USBSTOR_HandleInternalDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    PSCSI_REQUEST_BLOCK Request;
    PPDO_DEVICE_EXTENSION PDODeviceExtension;
    NTSTATUS Status;

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

    //
    // get request block
    //
    Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;

    //
    // sanity check
    //
    ASSERT(Request);

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

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

    switch(Request->Function)
    {
        case SRB_FUNCTION_EXECUTE_SCSI:
        {
            DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");

            //
            // check if request is valid
            //
            if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
            {
                //
                // data is transferred with this irp
                //
                if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) ||
                    Request->DataTransferLength == 0 ||
                    Irp->MdlAddress == NULL)
                {
                    //
                    // invalid parameter
                    //
                    Status = STATUS_INVALID_PARAMETER;
                    break;
                }
            }
            else
            {
                //
                // sense buffer request
                //
                if (Request->DataTransferLength ||
                    Request->DataBuffer ||
                    Irp->MdlAddress)
                {
                    //
                    // invalid parameter
                    //
                    Status = STATUS_INVALID_PARAMETER;
                    break;
                }
            }

            //
            // add the request
            //
            if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
            {
                //
                // irp was not added to the queue
                //
                IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
            }

            //
            // irp pending
            //
            return STATUS_PENDING;
        }
        case SRB_FUNCTION_RELEASE_DEVICE:
        {
            DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
            //
            // sanity check
            //
            ASSERT(PDODeviceExtension->Claimed == TRUE);

            //
            // release claim
            //
            PDODeviceExtension->Claimed = FALSE;
            Status = STATUS_SUCCESS;
            break;
        }
        case SRB_FUNCTION_CLAIM_DEVICE:
        {
            DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
            //
            // check if the device has been claimed
            //
            if (PDODeviceExtension->Claimed)
            {
                //
                // device has already been claimed
                //
                Status = STATUS_DEVICE_BUSY;
                Request->SrbStatus = SRB_STATUS_BUSY;
                break;
            }

            //
            // claim device
            //
            PDODeviceExtension->Claimed = TRUE;

            //
            // output device object
            //
            Request->DataBuffer = DeviceObject;

            //
            // completed successfully
            //
            Status = STATUS_SUCCESS;
            break;
        }
        case SRB_FUNCTION_RELEASE_QUEUE:
        {
            DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");

            //
            // release queue
            //
            USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);

            //
            // set status success
            //
            Request->SrbStatus = SRB_STATUS_SUCCESS;
            Status = STATUS_SUCCESS;
            break;
        }

        case SRB_FUNCTION_SHUTDOWN:
        case SRB_FUNCTION_FLUSH:
        case SRB_FUNCTION_FLUSH_QUEUE:
        {
            DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n");

            // HACK: don't flush pending requests
#if 0       // we really need a proper storage stack
            //
            // wait for pending requests to finish
            //
            USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
#endif
            //
            // set status success
            //
            Request->SrbStatus = SRB_STATUS_SUCCESS;
            Status = STATUS_SUCCESS;
            break;
        }
        default:
        {
            //
            // not supported
            //
            Status = STATUS_NOT_SUPPORTED;
            Request->SrbStatus = SRB_STATUS_ERROR;
        }
    }

    //
    // complete request
    //
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Esempio n. 3
0
VOID
USBSTOR_QueueRelease(
    IN PDEVICE_OBJECT DeviceObject)
{
    PFDO_DEVICE_EXTENSION FDODeviceExtension;
    PIRP Irp;
    KIRQL OldLevel;
    PIO_STACK_LOCATION IoStack;
    PSCSI_REQUEST_BLOCK Request;

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

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

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

    //
    // clear freezed status
    //
    FDODeviceExtension->IrpListFreeze = FALSE;

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

    //
    // grab newest irp
    //
    Irp = USBSTOR_RemoveIrp(DeviceObject);

    //
    // is there an irp
    //
    if (!Irp)
    {
        //
        // no irp
        //
        return;
    }

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

    //
    // get srb
    //
    Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;

    //
    // start new packet
    //
    IoStartPacket(DeviceObject,
                  Irp,
                  &Request->QueueSortKey, 
                  USBSTOR_CancelIo);
}
Esempio n. 4
0
VOID
USBSTOR_QueueNextRequest(
    IN PDEVICE_OBJECT DeviceObject)
{
    PFDO_DEVICE_EXTENSION FDODeviceExtension;
    PIRP Irp;
    PIO_STACK_LOCATION IoStack;
    PSCSI_REQUEST_BLOCK Request;

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

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

    //
    // check first if there's already a request pending or the queue is frozen
    //
    if (FDODeviceExtension->ActiveSrb != NULL ||
        FDODeviceExtension->IrpListFreeze)
    {
        //
        // no work to do yet
        //
        return;
    }

    //
    // remove first irp from list
    //
    Irp = USBSTOR_RemoveIrp(DeviceObject);

    //
    // is there an irp pending
    //
    if (!Irp)
    {
        //
        // no work to do
        //
        IoStartNextPacket(DeviceObject, TRUE);
        return;
    }

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

    //
    // get srb
    //
    Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;

    //
    // sanity check
    //
    ASSERT(Request);

    //
    // set the active SRB
    //
    FDODeviceExtension->ActiveSrb = Request;

    //
    // start next packet
    //
    IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);

    //
    // start next request
    //
    IoStartNextPacket(DeviceObject, TRUE);
}
Esempio n. 5
0
NTSTATUS
DBusInternalDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is the dispatch routine for internal device control requests.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/

{

    PIO_STACK_LOCATION irpSp;
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS status;

    BusPrint((2,"DBusInternalDeviceControl: enter\n"));

    //
    // Get a pointer to the device extension.
    //

    deviceExtension = DeviceObject->DeviceExtension;

    //
    // Initialize the returned Information field.
    //

    Irp->IoStatus.Information = 0;

    //
    // Get a pointer to the current parameters for this request.  The
    // information is contained in the current stack location.
    //

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    //
    // Case on the device control subfunction that is being performed by the
    // requestor.
    //

    switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {

        //
        // Connect a mouse class device driver to the port driver.
        //

        case IOCTL_INTERNAL_MOUSE_CONNECT:

            BusPrint((
                2,
                "DBusInternalDeviceControl: mouse connect\n"
                ));

            //
            // Only allow one connection.
            //
            // FUTURE:  Consider allowing multiple connections, just for
            // the sake of generality?
            //

            if (deviceExtension->ConnectData.ClassService
                != NULL) {

                BusPrint((
                    2,
                    "DBusInternalDeviceControl: error - already connected\n"
                    ));

                status = STATUS_SHARING_VIOLATION;
                break;

            } else 
            if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
                    sizeof(CONNECT_DATA)) {

                BusPrint((
                    2,
                    "DBusInternalDeviceControl: error - invalid buffer length\n"
                    ));

                status = STATUS_INVALID_PARAMETER;
                break;
            }

            //
            // Copy the connection parameters to the device extension.
            //

            deviceExtension->ConnectData =
                *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));

            //
            // Reinitialize the port input data queue synchronously.
            //

            KeSynchronizeExecution(
                deviceExtension->InterruptObject,
                (PKSYNCHRONIZE_ROUTINE) BusInitializeDataQueue,
                (PVOID) deviceExtension
                );

            //
            // Set the completion status.
            //

            status = STATUS_SUCCESS;
            break;

        //
        // Disconnect a mouse class device driver from the port driver.
        //
        // NOTE: Not implemented.
        //

        case IOCTL_INTERNAL_MOUSE_DISCONNECT:

            BusPrint((
                2,
                "DBusInternalDeviceControl: mouse disconnect\n"
                ));

            //
            // Perform a mouse interrupt disable call.
            //

            //
            // Clear the connection parameters in the device extension.
            // NOTE:  Must synchronize this with the mouse ISR.
            //
            //
            //deviceExtension->ConnectData.ClassDeviceObject =
            //    Null;
            //deviceExtension->ConnectData.ClassService =
            //    Null;

            //
            // Set the completion status.
            //

            status = STATUS_NOT_IMPLEMENTED;
            break;

        //
        // Enable mouse interrupts (mark the request pending and handle
        // it in StartIo).
        //

        case IOCTL_INTERNAL_MOUSE_ENABLE:

            BusPrint((
                2,
                "DBusInternalDeviceControl: mouse enable\n"
                ));

            status = STATUS_PENDING;
            break;

        //
        // Disable mouse interrupts (mark the request pending and handle
        // it in StartIo).
        //

        case IOCTL_INTERNAL_MOUSE_DISABLE:

            BusPrint((
                2,
                "DBusInternalDeviceControl: mouse disable\n"
                ));

            status = STATUS_PENDING;
            break;

        //
        // Query the mouse attributes.  First check for adequate buffer 
        // length.  Then, copy the mouse attributes from the device 
        // extension to the output buffer. 
        //

        case IOCTL_MOUSE_QUERY_ATTRIBUTES:

            BusPrint((
                2,
                "DBusInternalDeviceControl: mouse query attributes\n"
                ));

            if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(MOUSE_ATTRIBUTES)) {
                status = STATUS_BUFFER_TOO_SMALL;
            } else {

                //
                // Copy the attributes from the DeviceExtension to the
                // buffer.
                //

                *(PMOUSE_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer =
                    deviceExtension->Configuration.MouseAttributes;

                Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
                status = STATUS_SUCCESS;
            }

            break;

        default:

            BusPrint((
                2,
                "DBusInternalDeviceControl: INVALID REQUEST\n"
                ));

            status = STATUS_INVALID_DEVICE_REQUEST;
            break;
    }

    Irp->IoStatus.Status = status;
    if (status == STATUS_PENDING) {
        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, (PULONG)NULL, NULL);
    } else {
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    BusPrint((2,"DBusInternalDeviceControl: exit\n"));

    return(status);

}
Esempio n. 6
0
/*
 * Runs the keyboard IOCTL_INTERNAL dispatch.
 */
NTSTATUS NTAPI
i8042KbdInternalDeviceControl(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp)
{
	PIO_STACK_LOCATION Stack;
	PI8042_KEYBOARD_EXTENSION DeviceExtension;
	NTSTATUS Status;

	Stack = IoGetCurrentIrpStackLocation(Irp);
	Irp->IoStatus.Information = 0;
	DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension;

	switch (Stack->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_INTERNAL_KEYBOARD_CONNECT:
		{
			SIZE_T Size;
			PIO_WORKITEM WorkItem = NULL;
			PI8042_HOOK_WORKITEM WorkItemData = NULL;

			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
			if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA))
			{
				Status = STATUS_INVALID_PARAMETER;
				goto cleanup;
			}

			DeviceExtension->KeyboardData =
				*((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);

			/* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */
			WorkItem = IoAllocateWorkItem(DeviceObject);
			if (!WorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			WorkItemData = ExAllocatePoolWithTag(
				NonPagedPool,
				sizeof(I8042_HOOK_WORKITEM),
				I8042PRT_TAG);
			if (!WorkItemData)
			{
				WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
				Status = STATUS_NO_MEMORY;
				goto cleanup;
			}
			WorkItemData->WorkItem = WorkItem;
			WorkItemData->Irp = Irp;

			/* Initialize extension */
			DeviceExtension->Common.Type = Keyboard;
			Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA);
			DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag(
				NonPagedPool,
				Size,
				I8042PRT_TAG);
			if (!DeviceExtension->KeyboardBuffer)
			{
				WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
				Status = STATUS_NO_MEMORY;
				goto cleanup;
			}
			RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size);
			KeInitializeDpc(
				&DeviceExtension->DpcKeyboard,
				i8042KbdDpcRoutine,
				DeviceExtension);
			DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject);
			if (!DeviceExtension->PowerWorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject);
			if (!DeviceExtension->DebugWorkItem)
			{
				WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
				Status = STATUS_INSUFFICIENT_RESOURCES;
				goto cleanup;
			}
			DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension;
			DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED;

            i8042InitializeKeyboardAttributes(DeviceExtension);

			IoMarkIrpPending(Irp);
			/* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */
			DeviceExtension->KeyboardHook.QueueKeyboardPacket = i8042KbdQueuePacket;
			DeviceExtension->KeyboardHook.CallContext = DeviceExtension;
			IoQueueWorkItem(WorkItem,
				i8042SendHookWorkItem,
				DelayedWorkQueue,
				WorkItemData);
			Status = STATUS_PENDING;
			break;

cleanup:
			if (DeviceExtension->KeyboardBuffer)
				ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG);
			if (DeviceExtension->PowerWorkItem)
				IoFreeWorkItem(DeviceExtension->PowerWorkItem);
			if (DeviceExtension->DebugWorkItem)
				IoFreeWorkItem(DeviceExtension->DebugWorkItem);
			if (WorkItem)
				IoFreeWorkItem(WorkItem);
			if (WorkItemData)
				ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
			break;
		}
		case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n");
			/* MSDN says that operation is to implemented.
			 * To implement it, we just have to do:
			 * DeviceExtension->KeyboardData.ClassService = NULL;
			 */
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n");
			/* Nothing to do here */
			Status = STATUS_SUCCESS;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
		{
		    PKEYBOARD_ATTRIBUTES KeyboardAttributes;

            /* FIXME: KeyboardAttributes are not initialized anywhere */
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
			if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

            KeyboardAttributes = Irp->AssociatedIrp.SystemBuffer;
            *KeyboardAttributes = DeviceExtension->KeyboardAttributes;

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

			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
		{
			DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n");
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_SET_TYPEMATIC:
		{
			DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n");
			Status = STATUS_NOT_IMPLEMENTED;
			break;
		}
		case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n");

			/* We should check the UnitID, but it's kind of pointless as
			 * all keyboards are supposed to have the same one
			 */
			if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					Irp->AssociatedIrp.SystemBuffer,
					&IndicatorTranslation,
					sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));
				Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
				Status = STATUS_SUCCESS;
			}
			break;
		}
		case IOCTL_KEYBOARD_QUERY_INDICATORS:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n");

			if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					Irp->AssociatedIrp.SystemBuffer,
					&DeviceExtension->KeyboardIndicators,
					sizeof(KEYBOARD_INDICATOR_PARAMETERS));
				Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
				Status = STATUS_SUCCESS;
			}
			break;
		}
		case IOCTL_KEYBOARD_SET_INDICATORS:
		{
			TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n");

			if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
			{
				Status = STATUS_BUFFER_TOO_SMALL;
			}
			else
			{
				RtlCopyMemory(
					&DeviceExtension->KeyboardIndicators,
					Irp->AssociatedIrp.SystemBuffer,
					sizeof(KEYBOARD_INDICATOR_PARAMETERS));
				Status = STATUS_PENDING;
				IoMarkIrpPending(Irp);
				IoStartPacket(DeviceObject, Irp, NULL, NULL);
			}
			break;
		}
		default:
		{
			ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
				Stack->Parameters.DeviceIoControl.IoControlCode);
			ASSERT(FALSE);
			return ForwardIrpAndForget(DeviceObject, Irp);
		}
	}

	Irp->IoStatus.Status = Status;
	if (Status != STATUS_PENDING)
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return Status;
}
Esempio n. 7
0
NTSTATUS
LspDispatchRead(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
 )
 /*++
     Routine Description:
  
           Read disptach routine
           
     Arguments:
  
         DeviceObject - pointer to a device object.
                 Irp             - pointer to current Irp
  
     Return Value:
  
         NT status code.
  
--*/
{
    NTSTATUS            status;
    PDEVICE_EXTENSION   deviceExtension;
    PIO_STACK_LOCATION  irpStack;
    LARGE_INTEGER       currentTime;

    PAGED_CODE();

	LSP_KDPRINT(("LspRead Enter: Irp=%p\n", Irp));

    //
    // Get a pointer to the device extension.
    //

    deviceExtension = DeviceObject->DeviceExtension;
   
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    
    //
    // First make sure there is enough room.
    //

	//
	// read should be aligned to a sector size (512 bytes)
	//
	if (0 != (irpStack->Parameters.Read.Length % 512))
	{
		Irp->IoStatus.Status = status = STATUS_INVALID_PARAMETER;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest (Irp, IO_NO_INCREMENT);
		return status;
	}

    if (irpStack->Parameters.Read.Length < sizeof(INPUT_DATA))
    {
        Irp->IoStatus.Status = status = STATUS_BUFFER_TOO_SMALL;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }

	IoMarkIrpPending(Irp);
	IoStartPacket(DeviceObject, Irp, NULL, NULL);
	return STATUS_PENDING;

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

 //   KeQuerySystemTime(&currentTime);

 //   // *(ULONG *)Irp->AssociatedIrp.SystemBuffer =((currentTime.LowPart/13)%2);
	//// Irp->DriverContext[4] = ((currentTime.LowPart/13)%2);

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

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

 //   KeReleaseSemaphore(
	//	&deviceExtension->IrpQueueSemaphore,
 //       0,// No priority boost
 //       1,// Increment semaphore by 1
 //       FALSE );// No WaitForXxx after this call

 //   return STATUS_PENDING;
}
Esempio n. 8
0
NTSTATUS
LspDispatchClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

   Process the close IRPs sent to this device.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT Status code

--*/
{
    PIO_STACK_LOCATION   irpStack;
    NTSTATUS             status = STATUS_SUCCESS, cleanupStatus;

    PAGED_CODE ();

    LSP_KDPRINT(("LspDispatchClose Enter\n"));

    //
    // Get a pointer to the current location in the Irp.
    //

    irpStack = IoGetCurrentIrpStackLocation(Irp);

	ASSERT(IRP_MJ_CLOSE == irpStack->MajorFunction);

	LSP_KDPRINT(("IRP_MJ_CLOSE\n"));

	//
    // The IRP_MJ_CLOSE dispatch routine is called when a file object
    // opened on the driver is being removed from the system; that is,
    // all file object handles have been closed and the reference count
    // of the file object is down to 0. 
    //

	Irp->IoStatus.Information = 0;
	IoMarkIrpPending(Irp);
	IoStartPacket(DeviceObject, Irp, NULL, NULL);
	return STATUS_PENDING;


	////
 //   // Save Status for return and complete Irp
 //   //
 //   
 //   Irp->IoStatus.Status = status;
 //   IoCompleteRequest(Irp, IO_NO_INCREMENT);

 //   LSP_KDPRINT((" LspCreateClose Exit = %x\n", status));

    return status;
}
Esempio n. 9
0
NTSTATUS
LspDispatchCreate(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

   Process the Create and close IRPs sent to this device.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT Status code

--*/
{
    PIO_STACK_LOCATION   irpStack;
    NTSTATUS             status = STATUS_SUCCESS;
	PDEVICE_EXTENSION deviceExtension;
	KIRQL oldIrql;

    PAGED_CODE ();

    LSP_KDPRINT(("LspDispatchCreate Enter\n"));

    //
    // Get a pointer to the current location in the Irp.
    //

    irpStack = IoGetCurrentIrpStackLocation(Irp);
	ASSERT(IRP_MJ_CREATE == irpStack->MajorFunction);

	// 
    // The dispatch routine for IRP_MJ_CREATE is called when a 
    // file object associated with the device is created. 
    // This is typically because of a call to CreateFile() in 
    // a user-mode program or because a another driver is 
    // layering itself over a this driver. A driver is 
    // required to supply a dispatch routine for IRP_MJ_CREATE.
    //

	Irp->IoStatus.Information = 0;
	IoMarkIrpPending(Irp);
	IoStartPacket(DeviceObject, Irp, NULL, NULL);
	return STATUS_PENDING;

	//deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
	//
	//status = LspInitializeConnection(DeviceObject);
	//if (STATUS_PENDING == status)
	//{
	//	IoMarkIrpPending(Irp);
	//	status = STATUS_PENDING;
	//}
	//else
	//{
	//	Irp->IoStatus.Information = 0;
	//	Irp->IoStatus.Status = status;
	//	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	//}

 //   LSP_KDPRINT((" LspCreate Exit = %x\n", status));

    return status;
}
Esempio n. 10
0
NTSTATUS
ScsiPortStopAdapter(
    IN PDEVICE_OBJECT Adapter,
    IN PIRP StopRequest
    )

/*++

Routine Description:

    This routine will stop an adapter and release it's io and interrupt
    resources.  Pool allocations will not be freed, nor will the various
    miniport extensions.

Arguments:

    Adapter - the device object for the adapter.

Return Value:

    status

--*/

{
    PADAPTER_EXTENSION adapterExtension = Adapter->DeviceExtension;
    PCOMMON_EXTENSION commonExtension = Adapter->DeviceExtension;

    KEVENT event;

    ULONG bin;

    PAGED_CODE();

    ASSERT(adapterExtension->IsPnp);

    //
    // If we're not started and we weren't started then there's no reason
    // to do any work when stopping.
    //

    if((commonExtension->CurrentPnpState != IRP_MN_START_DEVICE) &&
       (commonExtension->PreviousPnpState != IRP_MN_START_DEVICE)) {

        return STATUS_SUCCESS;
    }

    //
    // Since all the children are stopped no requests can get through to the
    // adapter.
    //

    //
    // Send a request through the start-io routine to shut it down so that we
    // can start it back up later.
    //

    KeInitializeEvent(&event, SynchronizationEvent, FALSE);

    StopRequest->IoStatus.Information = (ULONG_PTR) &event;

    IoStartPacket(Adapter, StopRequest, 0, NULL);

    KeWaitForSingleObject(&event,
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL);

    //
    // Call the miniport and get it to shut the adapter down.
    //

    SpEnableDisableAdapter(adapterExtension, FALSE);

    SpReleaseAdapterResources(adapterExtension, TRUE);

    //
    // Zero out all the logical unit extensions.
    //

    for(bin = 0; bin < NUMBER_LOGICAL_UNIT_BINS; bin++) {

        PLOGICAL_UNIT_EXTENSION lun;

        for(lun = adapterExtension->LogicalUnitList[bin].List;
            lun != NULL;
            lun = lun->NextLogicalUnit) {

            RtlZeroMemory(lun->HwLogicalUnitExtension,
                          adapterExtension->HwLogicalUnitExtensionSize);
        }
    }

    return STATUS_SUCCESS;
}
Esempio n. 11
0
VOID
NTAPI
CdRompFlushDelayedList(
    IN PDEVICE_OBJECT Fdo,
    IN PCDROM_MMC_EXTENSION MmcData,
    IN NTSTATUS Status,
    IN BOOLEAN CalledFromWorkItem
    )
{
    PSINGLE_LIST_ENTRY list;
    PIRP irp;

    // NOTE - REF #0002
    //
    // need to set the new state first to prevent deadlocks.
    // this is only done from the workitem, to prevent any
    // edge cases where we'd "lose" the UpdateRequired
    //
    // then, must ignore the state, since it's not guaranteed to
    // be the same any longer.  the only thing left is to handle
    // all the delayed irps by flushing the queue and sending them
    // back onto the StartIo queue for the device.
    //

    if (CalledFromWorkItem) {
        
        LONG oldState;
        LONG newState;

        if (NT_SUCCESS(Status)) {
            newState = CdromMmcUpdateComplete;
        } else {
            newState = CdromMmcUpdateRequired;
        }

        oldState = InterlockedCompareExchange(&MmcData->UpdateState,
                                              newState,
                                              CdromMmcUpdateStarted);
        ASSERT(oldState == CdromMmcUpdateStarted);

    } else {

        //
        // just flushing the queue if not called from the workitem,
        // and we don't want to ever fail the queue in those cases.
        //

        ASSERT(NT_SUCCESS(Status));

    }

    list = ExInterlockedFlushSList(&MmcData->DelayedIrps);
    
    // if this assert fires, it means that we have started
    // a workitem when the previous workitem took the delayed
    // irp.  if this happens, then the logic in HACKHACK #0002
    // is either flawed or the rules set within are not being
    // followed.  this would require investigation.
    
    ASSERT(list != NULL);

    //
    // now either succeed or fail all the delayed irps, according
    // to the update status.
    //

    while (list != NULL) {

        irp = (PIRP)( ((PUCHAR)list) -
                      FIELD_OFFSET(IRP, Tail.Overlay.DriverContext[0])
                      );
        list = list->Next;
        irp->Tail.Overlay.DriverContext[0] = 0;
        irp->Tail.Overlay.DriverContext[1] = 0;
        irp->Tail.Overlay.DriverContext[2] = 0;
        irp->Tail.Overlay.DriverContext[3] = 0;

        if (NT_SUCCESS(Status)) {
            
            KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                       "CdRomUpdateMmc => Re-sending delayed irp %p\n",
                       irp));
            IoStartPacket(Fdo, irp, NULL, NULL);

        } else {
            
            KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                       "CdRomUpdateMmc => Failing delayed irp %p with "
                       " status %x\n", irp, Status));
            irp->IoStatus.Information = 0;
            irp->IoStatus.Status = Status;
            ClassReleaseRemoveLock(Fdo, irp);
            IoCompleteRequest(irp, IO_CD_ROM_INCREMENT);

        }

    } // while (list)

    return;

}