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

📄 genport.c

📁 win2000下ISA接口的串口板卡的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
--*/
    
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)Extension;
	UCHAR ch;
//	ch = READ_INTERRUPT_STATE_REG((ULONG_PTR)pLDI->PortBase);
//	if( ch & ISR_INTERRUPT_MASK)
	{
//		DebugPrint (("ch = %X\n",ch));
		pLDI->TestIsr++;
		IoRequestDpc(pLDI->DeviceObject,0,NULL);
	}
    return(TRUE);
}
//

NTSTATUS
GpdIoctlReadPort(
    IN PLOCAL_DEVICE_INFO pLDI,
    IN PIRP pIrp,
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode  )


/*++

Routine Description:
    This routine processes the IOCTLs which read from the ports.

Arguments:
    
    pLDI        - our local device data
    pIrp        - IO request packet
    IrpStack    - The current stack location
    IoctlCode   - The ioctl code from the IRP

Return Value:
    STATUS_SUCCESS           -- OK

    STATUS_INVALID_PARAMETER -- The buffer sent to the driver
                                was too small to contain the
                                port, or the buffer which
                                would be sent back to the driver
                                was not a multiple of the data size.

    STATUS_ACCESS_VIOLATION  -- An illegal port number was given.

--*/

{
                                // NOTE:  Use METHOD_BUFFERED ioctls.
    PULONG pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as an array of longs).
    ULONG InBufferSize;         // Amount of data avail. from caller.
    ULONG OutBufferSize;        // Max data that caller can accept.
    ULONG nPort;                // Port number to read
    ULONG DataBufferSize;

    PAGED_CODE();

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

    // Size of buffer for data to be sent to application
    OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
    pIOBuffer     = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

    // Check to ensure input buffer is big enough to hold a port number and
    // the output buffer is at least as big as the port data width.
    //
    switch (IoctlCode)
    {
    case IOCTL_GPD_READ_PORT_UCHAR:
        DataBufferSize = sizeof(UCHAR);
        break;
    case IOCTL_GPD_READ_PORT_USHORT:
        DataBufferSize = sizeof(USHORT);
        break;
    case IOCTL_GPD_READ_PORT_ULONG:
        DataBufferSize = sizeof(ULONG);
        break;
    default:      
        return STATUS_INVALID_PARAMETER;

    }

    if ( InBufferSize != sizeof(ULONG) || OutBufferSize < DataBufferSize )
    {
        return STATUS_INVALID_PARAMETER;
    }

    // Buffers are big enough.

    nPort = *pIOBuffer;             // Get the I/O port number from the buffer.

    if (nPort >= pLDI->PortCount ||
        (nPort + DataBufferSize) > pLDI->PortCount ||
        (((ULONG_PTR)pLDI->PortBase + nPort) & (DataBufferSize - 1)) != 0)
    {
        return STATUS_ACCESS_VIOLATION;   // It was not legal.
    }
    
    if (pLDI->PortMemoryType == 1)
    {
        // Address is in I/O space
        
        switch (IoctlCode)
        {
        case IOCTL_GPD_READ_PORT_UCHAR:
//            *(PUCHAR)pIOBuffer = READ_PORT_UCHAR(//我屏蔽的
 //                           (PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort) );
			if(pIOBuffer == NULL)
			{
				DebugPrint (("pIOBuffer == NULL"));
			}
			else
			{
				DebugPrint (("%X ",pIOBuffer));
			}
			  if(pLDI->Buf[REC_INDEX][0].Number > 0)
				  BufPopByte(&pLDI->Buf[REC_INDEX][0] ,(PUCHAR)pIOBuffer);
			  else
					return STATUS_UNSUCCESSFUL;
            break;
        case IOCTL_GPD_READ_PORT_USHORT:
            *(PUSHORT)pIOBuffer = READ_PORT_USHORT(
                            (PUSHORT)((ULONG_PTR)pLDI->PortBase + nPort) );
            break;
        case IOCTL_GPD_READ_PORT_ULONG:
            *(PULONG)pIOBuffer = READ_PORT_ULONG(
                            (PULONG)((ULONG_PTR)pLDI->PortBase + nPort) );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;


        }
    } 
    else if (pLDI->PortMemoryType == 0)
    {
        // Address is in Memory space
        
        switch (IoctlCode)
        {
        case IOCTL_GPD_READ_PORT_UCHAR:
            *(PUCHAR)pIOBuffer = READ_REGISTER_UCHAR(
                            (PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort) );
            break;
        case IOCTL_GPD_READ_PORT_USHORT:
            *(PUSHORT)pIOBuffer = READ_REGISTER_USHORT(
                            (PUSHORT)((ULONG_PTR)pLDI->PortBase + nPort) );
            break;
        case IOCTL_GPD_READ_PORT_ULONG:
            *(PULONG)pIOBuffer = READ_REGISTER_ULONG(
                            (PULONG)((ULONG_PTR)pLDI->PortBase + nPort) );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;

        }
    } 
    else
    {
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Indicate # of bytes read
    //
    
    pIrp->IoStatus.Information = DataBufferSize;

    return STATUS_SUCCESS;
}


NTSTATUS
GpdIoctlWritePort(
    IN PLOCAL_DEVICE_INFO pLDI, 
    IN PIRP pIrp, 
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode
    )

/*++

Routine Description:
    This routine processes the IOCTLs which write to the ports.

Arguments:
    
    pLDI        - our local device data
    pIrp        - IO request packet
    IrpStack    - The current stack location
    IoctlCode   - The ioctl code from the IRP

Return Value:
    STATUS_SUCCESS           -- OK

    STATUS_INVALID_PARAMETER -- The buffer sent to the driver
                                was too small to contain the
                                port, or the buffer which
                                would be sent back to the driver
                                was not a multiple of the data size.

    STATUS_ACCESS_VIOLATION  -- An illegal port number was given.

--*/

{
                                // NOTE:  Use METHOD_BUFFERED ioctls.
    PULONG pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as array of longs).
    ULONG InBufferSize ;        // Amount of data avail. from caller.
    ULONG nPort;                // Port number to read or write.
    ULONG DataBufferSize;
    ULONG OutBufferSize;        // Max data that caller can accept.
	UCHAR OldACR,AL;
	int i,RealWriteSize,Count;
    PAGED_CODE();

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
	OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after return,
    // for METHOD_BUFFERED IOCTL's.
    pIOBuffer     = (PULONG) pIrp->AssociatedIrp.SystemBuffer;

    pIrp->IoStatus.Information = 0;
    
    // Check to ensure input buffer is big enough to hold a port number as well
    // as the data to write.
    //
    // The relative port # is a ULONG, and the data is the type appropriate to
    // the IOCTL.
    //

    switch (IoctlCode)
    {
    case IOCTL_GPD_WRITE_PORT_UCHAR:
      DataBufferSize = sizeof(UCHAR);
        break;
    case IOCTL_GPD_WRITE_PORT_USHORT:
        DataBufferSize = sizeof(USHORT);
        break;
    case IOCTL_GPD_WRITE_PORT_ULONG:
        DataBufferSize = sizeof(ULONG);
        break;
    default:      
        return STATUS_INVALID_PARAMETER;
    }

    if ( InBufferSize < (sizeof(ULONG) + DataBufferSize) )
    {
        return STATUS_INVALID_PARAMETER;
    }

    nPort = *pIOBuffer++;

    if (nPort >= pLDI->PortCount ||
        (nPort + DataBufferSize) > pLDI->PortCount ||
        (((ULONG_PTR)pLDI->PortBase + nPort) & (DataBufferSize - 1)) != 0)
    {
        return STATUS_ACCESS_VIOLATION;   // Illegal port number
    }

    if (pLDI->PortMemoryType == 1)
    {
        // Address is in I/O space
        
        switch (IoctlCode)
        {
        case IOCTL_GPD_WRITE_PORT_UCHAR:
            WRITE_PORT_UCHAR(
                (PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort),
                *(PUCHAR)pIOBuffer );
            break;
        case IOCTL_GPD_WRITE_PORT_USHORT:
            WRITE_PORT_USHORT(
                (PUSHORT)((ULONG_PTR)pLDI->PortBase + nPort),
                *(PUSHORT)pIOBuffer );
            break;
        case IOCTL_GPD_WRITE_PORT_ULONG:
            WRITE_PORT_ULONG(
                (PULONG)((ULONG_PTR)pLDI->PortBase + nPort),
                *(PULONG)pIOBuffer );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;
        }
    } 
    else if (pLDI->PortMemoryType == 0) 
    {
        // Address is in Memory space
        
        switch (IoctlCode)
        {
        case IOCTL_GPD_WRITE_PORT_UCHAR:
            WRITE_REGISTER_UCHAR( 
                    (PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort),
                    *(PUCHAR)pIOBuffer );
            break;
        case IOCTL_GPD_WRITE_PORT_USHORT:
            WRITE_REGISTER_USHORT(
                    (PUSHORT)((ULONG_PTR)pLDI->PortBase + nPort),
                    *(PUSHORT)pIOBuffer );
            break;
        case IOCTL_GPD_WRITE_PORT_ULONG:
            WRITE_REGISTER_ULONG(
                    (PULONG)((ULONG_PTR)pLDI->PortBase + nPort),
                    *(PULONG)pIOBuffer );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;
        }
    }
    else
    {
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Indicate # of bytes written
    //
    
    pIrp->IoStatus.Information = DataBufferSize;

    return STATUS_SUCCESS;
}

NTSTATUS
SerialSetBaud(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
	IN PIO_STACK_LOCATION IrpStack
    )
/*++

Routine Description:

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    If the io is zero length then it will return STATUS_SUCCESS,
    otherwise this routine will return the status returned by
    the actual start read routine.

--*/
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)DeviceObject->DeviceExtension;
	// NOTE:  Use METHOD_BUFFERED ioctls.
	PCOM_SET_MODE pComSetMode;	//指向InBuffer中的COM_SET_MODE结构体
    PULONG pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as an array of longs).
    ULONG InBufferSize;         // Amount of data avail. from caller.
    ULONG OutBufferSize;        // Max data that caller can accept.
    ULONG nPort;                // Port number to read
	ULONG i;
	USHORT divisor,ComIndex;
	UCHAR parameter,*p1,*p2,OldACR;
    UCHAR LineControl;                                            
    PAGED_CODE();
	DebugPrint ((">>>  entered SerialSetBaud!\n"));

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
	if(InBufferSize != sizeof(COM_SET_MODE))
		return STATUS_INVALID_PARAMETER;//如果应用程传递进来的数据长度小于COM_SET_MODE结构体的长度,数据无效

    // Size of buffer for data to be sent to application
    OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
//    pIOBuffer     = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

    // Check to ensure input buffer is big enough to hold a port number and
    // the output buffer is at least as big as the port data width.
    //
 
    //
    // Indicate # of bytes read
    //设置波特率,数据位,停止位,校验位
	pComSetMode = (PCOM_SET_MODE)pIrp->AssociatedIrp.SystemBuffer;//得到传入的参数

⌨️ 快捷键说明

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