串口编程 IRP_MJ_READ问题

没原来那个名字长了 2009-10-17 08:13:35
这两天学写驱动以下是我的com.sys的代码...可以捕捉到IRP_MJ_READ的数据并在dbg中显示出来...但还不会修改.....请问大大们应该怎么修改捕捉到的数据呢....给点能用的代码马上结贴给分...

if(irpsp->MajorFunction == IRP_MJ_READ)
{
// 如果是写,先获得长度
ULONG len1 = irpsp->Parameters.Read.Length;
// 然后获得缓冲区
PUCHAR buf1 = NULL;
if(irp->MdlAddress != NULL)
buf1 =
(PUCHAR)
MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
else
buf1 = (PUCHAR)irp->UserBuffer;
if(buf1 == NULL)
buf1 = (PUCHAR)irp->AssociatedIrp.SystemBuffer;

// 打印内容
for(j=0;j<len1;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf1[j]);
}
}

// 这些请求直接下发执行即可。我们并不禁止或者改变它。
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(s_nextobj[i],irp);


...全文
780 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
回楼上的:确实没有错...而且把memset(buf1,0x31,len1);放在打印前面的话dgb里面显示的是改变过的字符。。。。可是我想改变是是irp->AssociatedIrp.SystemBuffer里的内容然后让读取该串口的程序读到我修改过的数据而不是原先从COM1口设备上发过来的数据.....(好象有点做坏事的感觉....大家不要误会哦...我只想模拟个设备....)
MoXiaoRab 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 free365 的回复:]
貌似我连memset都没有成功哪里错了吗?

C/C++ codeif(irpsp->MajorFunction== IRP_MJ_READ)
{// 如果是写,先获得长度 ULONG len1= irpsp->Parameters.Read.Length;// 然后获得缓冲区 UCHAR* buf1= NULL;if(irp->MdlAddress!= NULL)
buf1=(UCHAR*)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);else
buf1= (UCHAR*)irp->UserBuffer;if(buf1== NULL)
buf1= (UCHAR*)irp->AssociatedIrp.SystemBuffer;// 打印内容for(j=0;j<len1;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf1[j]);
}
memset(buf1,0x31,len1);
}// 这些请求直接下发执行即可。我们并不禁止或者改变它。 IoSkipCurrentIrpStackLocation(irp);return IoCallDriver(s_nextobj[i],irp);


[/Quote]
仔细对照下,绝对没错。我以前用过的
MoXiaoRab 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 free365 的回复:]
//操作输出缓冲区
            UCHAR* OutputBuffer = (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;
            memset(OutputBuffer,0xAA,cbout);
这个好象就是把OutputBuffer全都设置成0xAA....可是我想设置我配置文件上的数据呢
只会用CString跟GetPrivateProfileString.....貌似内核模式下这些都不能用...郁闷
[/Quote]
写ini?
  • 打赏
  • 举报
回复
貌似我连memset都没有成功哪里错了吗?


if(irpsp->MajorFunction == IRP_MJ_READ)
{
// 如果是写,先获得长度
ULONG len1 = irpsp->Parameters.Read.Length;
// 然后获得缓冲区
UCHAR* buf1 = NULL;
if(irp->MdlAddress != NULL)
buf1 =(UCHAR*)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
else
buf1 = (UCHAR*)irp->UserBuffer;
if(buf1 == NULL)
buf1 = (UCHAR*)irp->AssociatedIrp.SystemBuffer;

// 打印内容
for(j=0;j<len1;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf1[j]);
}
memset(buf1,0x31,len1);
}

// 这些请求直接下发执行即可。我们并不禁止或者改变它。
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(s_nextobj[i],irp);


  • 打赏
  • 举报
回复
//操作输出缓冲区
UCHAR* OutputBuffer = (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;
memset(OutputBuffer,0xAA,cbout);
这个好象就是把OutputBuffer全都设置成0xAA....可是我想设置我配置文件上的数据呢
只会用CString跟GetPrivateProfileString.....貌似内核模式下这些都不能用...郁闷
MoXiaoRab 2009-10-17
  • 打赏
  • 举报
回复
修改数据很简单的啊。给你看个我从我项目中抠出来的代码

NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Enter HelloDDKDeviceIOControl\n"));

//得到当前堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//得到输入缓冲区大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到输出缓冲区大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL码
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

ULONG info = 0;

switch (code)
{ // process request
case IOCTL_TEST1:
{
KdPrint(("IOCTL_TEST1\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据
UCHAR* InputBuffer = (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;
for (ULONG i=0;i<cbin;i++)
{
KdPrint(("%X\n",InputBuffer[i]));
}

//操作输出缓冲区
UCHAR* OutputBuffer = (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;
memset(OutputBuffer,0xAA,cbout);
//设置实际操作输出缓冲区长度
info = cbout;
break;
}
case IOCTL_TEST2:
{
KdPrint(("IOCTL_TEST2\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据

//缓冲区方式IOCTL
//显示输入缓冲区数据
UCHAR* InputBuffer = (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;
for (ULONG i=0;i<cbin;i++)
{
KdPrint(("%X\n",InputBuffer[i]));
}

//pIrp->MdlAddress为DeviceIoControl输出缓冲区地址相同
KdPrint(("User Address:0X%08X\n",MmGetMdlVirtualAddress(pIrp->MdlAddress)));

UCHAR* OutputBuffer = (UCHAR*)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority);
//InputBuffer被映射到内核模式下的内存地址,必定在0X80000000-0XFFFFFFFF之间
memset(OutputBuffer,0xAA,cbout);
//设置实际操作输出缓冲区长度
info = cbout;
break;
}
case IOCTL_TEST3:
{
KdPrint(("IOCTL_TEST3\n"));
//缓冲区方式IOCTL

//缓冲区方式IOCTL
//显示输入缓冲区数据
UCHAR* UserInputBuffer = (UCHAR*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
KdPrint(("UserInputBuffer:0X%0X\n",UserInputBuffer));

//得到用户模式地址
PVOID UserOutputBuffer = pIrp->UserBuffer;

KdPrint(("UserOutputBuffer:0X%0X\n",UserOutputBuffer));

__try
{
KdPrint(("Enter __try block\n"));

//判断指针是否可读
ProbeForRead(UserInputBuffer,cbin,4);
//显示输入缓冲区内容
for (ULONG i=0;i<cbin;i++)
{
KdPrint(("%X\n",UserInputBuffer[i]));
}

//判断指针是否可写
ProbeForWrite(UserOutputBuffer,cbout,4);

//操作输出缓冲区
memset(UserOutputBuffer,0xAA,cbout);

//由于在上面引发异常,所以以后语句不会被执行!
info = cbout;

KdPrint(("Leave __try block\n"));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("Catch the exception\n"));
KdPrint(("The program will keep going\n"));
status = STATUS_UNSUCCESSFUL;
}

info = cbout;
break;
}

default:
status = STATUS_INVALID_VARIANT;
}

// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = info; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );

KdPrint(("Leave HelloDDKDeviceIOControl\n"));

return status;
}

我不仅仅给出了缓冲内存模式的IOCTL,还给出了直接内存模式IOCTL,其他内存模式IOCTL的操作方式
MoXiaoRab 2009-10-17
  • 打赏
  • 举报
回复
在dbg中显示,你的意思是?DbgPrint吗?
  • 打赏
  • 举报
回复
忘了发IRP_MJ_READ代码了...补发下

if(irpsp->MajorFunction == IRP_MJ_READ)
{
// 如果是写,先获得长度
ULONG len1 = irpsp->Parameters.Read.Length;
// 然后获得缓冲区
UCHAR* buf1 = NULL;


if(irp->MdlAddress != NULL)
{
buf1 =(UCHAR*)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
DbgPrint("1111111111111");
}
else
{
memset((UCHAR*)irp->UserBuffer,0x32,len1);
buf1 = (UCHAR*)irp->UserBuffer;
DbgPrint("222222222");
}
if(buf1 == NULL)
{
memset((UCHAR*)irp->AssociatedIrp.SystemBuffer,0x32,len1);
buf1 = (UCHAR*)irp->AssociatedIrp.SystemBuffer;
DbgPrint("33333333");
}

// 打印内容
for(j=0;j<len1;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf1[j]);
}
}
  • 打赏
  • 举报
回复

if(irpsp->MajorFunction == IRP_MJ_WRITE)
{
// 如果是写,先获得长度
ULONG len = irpsp->Parameters.Write.Length;
// 然后获得缓冲区
PUCHAR buf = NULL;


if(irp->MdlAddress != NULL)
{
buf = (PUCHAR)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
DbgPrint("aaaaaaaaaa");
}
else
{
//memset((PUCHAR)irp->UserBuffer,0x31,len);
buf = (PUCHAR)irp->UserBuffer;
DbgPrint("bbbbbbbbbbb");
}
if(buf == NULL)
{
memset((PUCHAR)irp->AssociatedIrp.SystemBuffer,0x31,len);
buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
DbgPrint("cccccccccc");
}

// 打印内容
for(j=0;j<len;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf[j]);
}
}

这样子做之后无论往该COM口写入什么数据都会就成1
但为什么对IRP_MJ_READ却不行...我同样也是改了缓冲区啊....请大大们帮忙看看到低应该在哪里才可以改变从串口设备发回来的数据.....发出去的数据测试过可以改变了....

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧