⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 USB1.1控制器pdusbd12 ddk 驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PIRP Irp,
    IN  BOOLEAN  bWrite
    )
/*++
Routine Description:
    This function is called for IOCTLs to Read or Write.
    For WRITEs, the data is retrieved from the SystemBuffer and sent to the device.
    
Arguments:
    DeviceObject - pointer to the device object for this instance of the D12 device.
    Irp          - pointer to IRP
    Read         - if TRUE this is a Device-to-Host (Read from device) transfer
                   if FALSE this is a Host-to-Device (Write to device) transfer

Return Value:
    NT status code
        STATUS_SUCCESS:                 Read was done successfully
        STATUS_INVALID_PARAMETER_3:     The Endpoint Index does not specify an IN pipe 
        STATUS_NO_MEMORY:               Insufficient data memory was supplied to perform the READ

    This routine fills the status code into the Irp
    
--*/
{
    USBD_INTERFACE_INFORMATION *    pInterfaceInfo;
    PIO_STACK_LOCATION              irpStack;
    PDEVICE_EXTENSION               deviceExtension;     
    NTSTATUS                        ntStatus;
    PVOID                           ioBuffer;
    ULONG                           length;
    ULONG                           inputBufferLength;
    ULONG                           outputBufferLength;
    ULONG                           siz;
    PURB                            urb;
    USHORT							wValue, wIndex;
	PIO_BLOCK						ioBlock;
	
	D12_KdPrint(("D12TEST.SYS: enter D12_ReadWriteRegister\n"));

    irpStack = IoGetCurrentIrpStackLocation (Irp);
    ASSERT (irpStack != NULL);
    
    deviceExtension = DeviceObject->DeviceExtension;
    ASSERT (deviceExtension != NULL);

    ioBuffer			= Irp->AssociatedIrp.SystemBuffer;
	ioBlock				= (PIO_BLOCK) ioBuffer;
    inputBufferLength	= irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength	= irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    //DEBUG ONLY
    if ((ioBuffer == NULL) || (inputBufferLength == 0) ){
        D12_KdPrint (("D12TEST.SYS: ERROR! ioBuffer %X | inBufLen: %d | outBufLen %d\n",
                          ioBuffer, inputBufferLength, outputBufferLength));
        
        Irp->IoStatus.Information = 0;
        return (STATUS_NO_MEMORY);
        
    } //DEBUG ONLY
        
                          
    siz = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);

	// allocate urb
	urb = ExAllocatePool(NonPagedPool, siz);

    // By convention, the first byte of the buffer is reserved for the ReportID, so
    // skip over the first Byte when specifying the transferbuffer
	
	length = ioBlock->uLength;
	wValue = (USHORT)ioBlock->uOffset;
	wIndex = (USHORT)ioBlock->uIndex;

    D12_KdPrint (("D12TEST.SYS: ReadWriteRegister: ioBuffer = %p, wIndex = %x, wLength = %lx, wValue = %x.\n",
		ioBlock->pbyData, wIndex, length, wValue));

    if (bWrite) {
        // A WRITE operation implies that the data is gotten from the User's Input Data Buffer
   		UsbBuildVendorRequest(urb,				//ptr to urb
						URB_FUNCTION_VENDOR_DEVICE,
						(USHORT) siz,			//siz of urb
						0,					
						0x0,					//reservedbits=bmRequestType
						0x0C,					//request = USBSCAN IOCTL_WRITE_REGISTER
						wValue,					
						wIndex,				
						ioBlock->pbyData,			//TransferBuffer
						NULL,					//mdl (unused)
						length,					//bufferlength
					    NULL);					//link
    } else {
   		// A READ operation implies that the data is placed in the User's Output Data Buffer
		UsbBuildVendorRequest(urb,				//ptr to urb
						URB_FUNCTION_VENDOR_DEVICE,
						(USHORT) siz,			//siz of urb
						USBD_TRANSFER_DIRECTION_IN,
						0x0,					//reservedbits=bmRequestType
						0x0C,					//request = USBSCAN IOCTL_READ_REGISTER
						wValue,					
						wIndex,				
						ioBuffer,				//TransferBuffer
						NULL,					//mdl (unused)
						length,					//bufferlength
					    NULL);					//link
 }/* else */
	/*
    /*
	// Call the USB Stack. This call blocks until the device returns data.  Note that if the
	// device NAKs forever, this call will not return and this thread will hang.  To correct 
	// this, a timeout value can be specified and a Kernel-Mode timer used to wake 
	// up the driver and then cancel this transfer.  Future versions of this sample 
	// driver will demonstrate that capability, or consult the Windows NT DDK for 
	// further details on the Kernel Timer functionality as well as the 
	// IoCancelIrp functionality.
	*/
	ntStatus = D12_CallUSBD(DeviceObject, urb);

	// The Information field tells IOM how much to copy back into the
    // usermode buffer in the BUFFERED method
    if (NT_SUCCESS(ntStatus) && bWrite) {
        Irp->IoStatus.Information =length;	//sizeof (ULONG);
   
    }else if (NT_SUCCESS(ntStatus)) {

        D12_KdPrint (("D12TEST.SYS: Sucessfully Transferred %d Bytes\n", urb->UrbControlVendorClassRequest.TransferBufferLength));

        Irp->IoStatus.Information = (urb->UrbControlVendorClassRequest.TransferBufferLength);	// + sizeof(UCHAR));
   
    }
    
	Irp->IoStatus.Status = ntStatus;

	// free allocated urb
	ExFreePool(urb);

	D12_KdPrint(("D12TEST.SYS: exit D12_ReadWriteRegister\n"));

    return (ntStatus);
}


NTSTATUS
D12_ProcessIOCTL(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

Arguments:

    DeviceObject - pointer to the device object for this instance of the 82930
                    devcice.


Return Value:

    NT status code

--*/
{
    PIO_STACK_LOCATION irpStack;
    PVOID ioBuffer;
    ULONG inputBufferLength;
    ULONG outputBufferLength;
    PDEVICE_EXTENSION deviceExtension;
    ULONG ioControlCode;
    NTSTATUS ntStatus;
    ULONG length;
    PUCHAR pch;
    PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor;

    D12_KdPrint (("D12TEST.SYS: IRP_MJ_DEVICE_CONTROL\n"));

    D12_IncrementIoCount(DeviceObject);

    //
    // Get a pointer to the current location in the Irp. This is where
    //     the function codes and parameters are located.
    //

    deviceExtension = DeviceObject->DeviceExtension;
    
    if (deviceExtension->AcceptingRequests == FALSE) {
        ntStatus = STATUS_DEVICE_DATA_ERROR;
        Irp->IoStatus.Status = ntStatus;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest (Irp,
                           IO_NO_INCREMENT
                          );

        D12_DecrementIoCount(DeviceObject);                          
        return ntStatus;
    }

    irpStack = IoGetCurrentIrpStackLocation (Irp);

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

    ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

    //
    // Handle Ioctls from User mode
    //

    switch (ioControlCode) {

    case IOCTL_D12_RESET_PIPE:
        {
        PD12_PIPE pipe;
	    PFILE_OBJECT fileObject;

		// get our context and see if it is a pipe
	    fileObject = irpStack->FileObject;

		pipe = (PD12_PIPE) fileObject->FsContext;    

		if(pipe == NULL) {
			// error, this is not a pipe
	        ntStatus =
		        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
		} else {            
            D12_ResetPipe(DeviceObject, pipe, TRUE);
            
            ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
        }
        }
        break;


     case IOCTL_D12_GET_CONFIG_DESCRIPTOR:

        //
        // This api returns a copy of the configuration descriptor
        // and all endpoint/interface descriptors.
        //

        //
        // inputs  - none
        // outputs - configuration descriptor plus interface
        //          and endpoint descriptors
        //

        pch = (PUCHAR) ioBuffer;

        configurationDescriptor =
            D12_GetConfigDescriptor(DeviceObject);

        if (configurationDescriptor) {
            
            length = configurationDescriptor->wTotalLength;

            RtlCopyMemory(pch,
                          (PUCHAR) configurationDescriptor,
                          length);

            ExFreePool(configurationDescriptor);

            Irp->IoStatus.Information = length;

            ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
        }
        else {

            Irp->IoStatus.Information = 0;

            ntStatus = Irp->IoStatus.Status = STATUS_DEVICE_DATA_ERROR;
        }

        break;


     case IOCTL_D12_RESET_DEVICE:
        
        {
        NTSTATUS ntStatus;
        ULONG portStatus;

        D12_KdPrint (("D12TEST.SYS: Reset Device Test\n"));
        
        TRAP(); // test this
        //
        // Check the port state, if it is disabled we will need 
        // to re-enable it
        //
        ntStatus = D12_GetPortStatus(DeviceObject, &portStatus);

        if (NT_SUCCESS(ntStatus) && !(portStatus & USBD_PORT_ENABLED) &&
            portStatus & USBD_PORT_CONNECTED) {
            //
            // port is disabled, attempt reset
            //
            //D12_EnableParentPort(DeviceObject);
            D12_ResetParentPort(DeviceObject);
        }

        }
        break;               

     case IOCTL_D12_GET_DEVICE_DESCRIPTOR:


        pch = (PUCHAR) ioBuffer;

        deviceDescriptor =
            deviceExtension->DeviceDescriptor;

        if (deviceDescriptor) {
            
            length = deviceDescriptor->bLength;

            RtlCopyMemory(pch,
                          (PUCHAR) deviceDescriptor,
                          length);

            Irp->IoStatus.Information = length;

            ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
        }
        else {

            Irp->IoStatus.Information = 0;

            ntStatus = Irp->IoStatus.Status = STATUS_DEVICE_DATA_ERROR;
        }

        break;
	
	case IOCTL_READ_REGISTERS:
		D12_ReadWriteRegister(DeviceObject, Irp, FALSE);
		ntStatus = Irp->IoStatus.Status;

		break;

	case IOCTL_WRITE_REGISTERS:
		D12_ReadWriteRegister(DeviceObject, Irp, TRUE);
		ntStatus = Irp->IoStatus.Status;

		break;

	default:

        ntStatus =
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    }

    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT
                       );

    D12_DecrementIoCount(DeviceObject);                       

    return ntStatus;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -