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

📄 genport.c

📁 win2000下
💻 C
📖 第 1 页 / 共 5 页
字号:

Return Value:

    STATUS_SUCCESS if the IRP was processed successfully, otherwise an error
    indicating the reason for failure.

--*/

{
    PLOCAL_DEVICE_INFO pLDI;
    PIO_STACK_LOCATION pIrpStack;
    NTSTATUS Status;

    PAGED_CODE();

    pIrp->IoStatus.Information = 0;
    pLDI = (PLOCAL_DEVICE_INFO)pDO->DeviceExtension;    // Get local info struct

//    DebugPrint (("Entered GpdDispatch\n"));

    Status = IoAcquireRemoveLock (&pLDI->RemoveLock, pIrp);//在处理IRP请求之前,先上锁,以免被其他程序将该请求删除,引起冲突
															//与其对应的解锁操作是IoReleaseRemoveLock(&pLDI->RemoveLock, pIrp);
    if (!NT_SUCCESS (Status)) {
		DebugPrint ((">>>  IoAcquireRemoveLock Failed! %X\n",Status));
        pIrp->IoStatus.Information = 0;
        pIrp->IoStatus.Status = Status;
        IoCompleteRequest (pIrp, IO_NO_INCREMENT);
        return Status;
    }

    if (!pLDI->Started) {//如果所指定的设备还没有被“start”,将报“STATUS_DEVICE_NOT_READY”状态错误
        //
        // We fail all the IRPs that arrive before the device is started.
        //
        pIrp->IoStatus.Status = Status = STATUS_DEVICE_NOT_READY;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT );
        IoReleaseRemoveLock(&pLDI->RemoveLock, pIrp);       
		DebugPrint ((">>>  !pLDI->Started ! STATUS_DEVICE_NOT_READY\n"));
        return Status;
    }
    
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);//从IRP栈内取一个包,准备处理

    // Dispatch based on major fcn code.

    switch (pIrpStack->MajorFunction)
    {
        case IRP_MJ_CREATE:
			DebugPrint ((">>>  IRP_MJ_CREATE\n"));
            Status = STATUS_SUCCESS;
            break;
        case IRP_MJ_CLOSE:
            // We don't need any special processing on open/close so we'll
            // just return success.
			DebugPrint ((">>>  IRP_MJ_CLOSE\n"));
            Status = STATUS_SUCCESS;
            break;

        case IRP_MJ_DEVICE_CONTROL:
            //  Dispatch on IOCTL
            switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)//pIrpStack->MajorFunction 如果是 IRP_MJ_DEVICE_CONTROL
				//则需要查看 pIrpStack->Parameters.DeviceIoControl.IoControlCode 的代码的值,再分别进行处理
            {
            case IOCTL_GPD_READ_PORT_UCHAR:
            case IOCTL_GPD_READ_PORT_USHORT:
            case IOCTL_GPD_READ_PORT_ULONG:
//				DebugPrint ((">>>  IOCTL_GPD_READ_PORT_UCHAR\n"));
                Status = GpdIoctlReadPort(
                            pLDI,
                            pIrp,
                            pIrpStack,
                            pIrpStack->Parameters.DeviceIoControl.IoControlCode
                            );
                break;

            case IOCTL_GPD_WRITE_PORT_UCHAR:
            case IOCTL_GPD_WRITE_PORT_USHORT:
            case IOCTL_GPD_WRITE_PORT_ULONG:
//				DebugPrint ((">>>  IOCTL_GPD_WRITE_PORT_UCHAR TestIsr = %d\n",pLDI->TestIsr));
                Status = GpdIoctlWritePort(
                            pLDI, 
                            pIrp,
                            pIrpStack,
                            pIrpStack->Parameters.DeviceIoControl.IoControlCode
                            );
                break;
			case IOCTL_RESET://设置串口波特率,和工作方式
//				DebugPrint ((">>>  IOCTL_RESET \n"));
				Status = SerialReset(pDO,pIrp,pIrpStack);
				break;
			case IOCTL_SET_BAUD_MODE://设置串口波特率,和工作方式
//				DebugPrint ((">>>  IOCTL_SET_BAUD_MODE \n"));
				Status = SerialSetBaud(pDO,pIrp,pIrpStack);
				break;
			case IOCTL_READ_DATA_0://读串口0的数据
//				DebugPrint ((">>>  IOCTL_READ_DATA \n"));
				Status = SerialReadData(pDO,pIrp,pIrpStack,0);
				break;
			case IOCTL_WRITE_DATA_0://写串口0的数据
//				DebugPrint ((">>>  IOCTL_WRITE_DATA \n"));
				Status = SerialWriteData(pDO,pIrp,pIrpStack,0);
				break;
			case IOCTL_READ_DATA_1://读串口1的数据
//				DebugPrint ((">>>  IOCTL_READ_DATA_1 \n"));
				Status = SerialReadData(pDO,pIrp,pIrpStack,1);
				break;
			case IOCTL_WRITE_DATA_1://写串口1的数据
//				DebugPrint ((">>>  IOCTL_WRITE_DATA_1 \n"));
				Status = SerialWriteData(pDO,pIrp,pIrpStack,1);
				break;
			////////////////////////////////
			case IOCTL_READ_DATA_2://读串口2的数据
//				DebugPrint ((">>>  IOCTL_READ_DATA_2 \n"));
				Status = SerialReadData(pDO,pIrp,pIrpStack,2);
				break;
			case IOCTL_WRITE_DATA_2://写串口2的数据
//				DebugPrint ((">>>  IOCTL_WRITE_DATA_2 \n"));
				Status = SerialWriteData(pDO,pIrp,pIrpStack,2);
				break;
			case IOCTL_READ_DATA_3://读串口3的数据
//				DebugPrint ((">>>  IOCTL_READ_DATA_3 \n"));
				Status = SerialReadData(pDO,pIrp,pIrpStack,3);
				break;
			case IOCTL_WRITE_DATA_3://写串口3的数据
//				DebugPrint ((">>>  IOCTL_WRITE_DATA_3 \n"));
				Status = SerialWriteData(pDO,pIrp,pIrpStack,3);
			//njh20080118
			case IOCTL_WRITE_SWITCH://开关量输出
				 DebugPrint ((">>>  enter IOCTL_WRITE_SWITCH branch \n"));
				 Status = WriteSwitch(pDO,pIrp,pIrpStack);
				break;
            default:      
                Status = STATUS_INVALID_PARAMETER;

            }
            break;
        default: 
            Status = STATUS_NOT_IMPLEMENTED;
            break;
    }

    // We're done with I/O request.  Record the status of the I/O action.
    pIrp->IoStatus.Status = Status;

    // Don't boost priority when returning since this took little time.
    IoCompleteRequest(pIrp, IO_NO_INCREMENT );
    IoReleaseRemoveLock(&pLDI->RemoveLock, pIrp);       
    return Status;
}
//
BOOLEAN
GpdInterruptService(
    IN  PKINTERRUPT Interrupt,
    IN  PVOID       Extension
    )

/*++
      
Routine Description:
      
    This routine services the interrupt for the parallel port.
      This routine will call out to all of the interrupt routines
      that connected with this device via
      IOCTL_INTERNAL_PARALLEL_CONNECT_INTERRUPT in order until
      one of them returns TRUE.
      
Arguments:
      
    Interrupt   - Supplies the interrupt object.
      
    Extension   - Supplies the device extension.
      
Return Value:
      
    FALSE   - The interrupt was not handled.
    TRUE    - The interrupt was handled.
      
--*/
    
{
    ((PLOCAL_DEVICE_INFO)Extension)->TestIsr++;
    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.
    //
//	DebugPrint ((">>>  GpdIoctlReadPort 1\n"));
    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;

    }
//	DebugPrint ((">>>  GpdIoctlReadPort 2\n"));

    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.
    }*/
//	DebugPrint ((">>>  GpdIoctlReadPort 3\n"));
    
    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) );
			DebugPrint ((">>>  ReadPort Port=0x%X Value=0x%X\n",
				(PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort),
				*(PUCHAR)pIOBuffer));
            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) );
			DebugPrint ((">>>  ReadMem Mem=0x%X Value=0x%X\n",
				(PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort),
				*(PUCHAR)pIOBuffer));
            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 Dat

⌨️ 快捷键说明

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