📄 genport.c
字号:
--*/
{
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 + -