驱动开发网上关于重启的网摘(3)

q:为什么在驱动中一运行READ_REGISTER_ULONG操作机器就重启

想对一块虚拟内存进行读取,写了一个小驱动,但是一调用WRITE_REGISTER_ULONG读取指定的内核内存空间,机器就重启,急死了,在这个地方耽搁了一个星期了,有人能帮帮我吗?

代码如下:
NTSTATUS PortTalkCreateDispatch(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp
  )
{
  Irp->IoStatus.Information = 0;
  Irp->IoStatus.Status = STATUS_SUCCESS;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(
  IN PDRIVER_OBJECT DriverObject,
  IN PUNICODE_STRING RegistryPath
  )
{
  PDEVICE_OBJECT deviceObject;
  NTSTATUS status;
  WCHAR NameBuffer[] = L"//Device//PortTalk";
  WCHAR DOSNameBuffer[] = L"//DosDevices//PortTalk";
  UNICODE_STRING uniNameString, uniDOSString;

  KdPrint( ("CARDTALK: CARDTALK V2.0 12/01/2005 has Loaded") );

  RtlInitUnicodeString(&uniNameString, NameBuffer);
  RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);

  status = IoCreateDevice(DriverObject,
                  0,
                  &uniNameString,
                  FILE_DEVICE_UNKNOWN,
                  0,
                  FALSE,
                  &deviceObject);
  if(!NT_SUCCESS(status))
    return status;

  status = IoCreateSymbolicLink (&uniDOSString, &uniNameString);

  if (!NT_SUCCESS(status))
    return status;

  DriverObject->MajorFunction[IRP_MJ_CREATE] = PortTalkCreateDispatch;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PortTalkDeviceControl;
  DriverObject->DriverUnload = PortTalkUnload;

  return STATUS_SUCCESS;
}

NTSTATUS
PortTalkDeviceControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP pIrp
  )

{
  PIO_STACK_LOCATION irpSp;
  NTSTATUS         ntStatus = STATUS_SUCCESS; 

  ULONG           inBufLength;   /* Input buffer length */
  ULONG           outBufLength; /* Output buffer length */
  ULONG           inBuf;       /* Pointer to Input and output buffer */

  PUCHAR         CharBuffer;
  PUSHORT         ShortBuffer;
  PULONG         LongBuffer;
  PVOID           ioBuffer;

  USHORT Offset;
  UCHAR Value;
     USHORT DValue;
     ULONG DDValue;

     volatile ULONG *m_commandReg;

  ULONG ProcessID; 
  struct _EPROCESS *Process;

  irpSp = IoGetCurrentIrpStackLocation( pIrp );
  inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;

  ioBuffer   = pIrp->AssociatedIrp.SystemBuffer;

  CharBuffer = (PUCHAR) ioBuffer;
  ShortBuffer = (PUSHORT) ioBuffer;
  LongBuffer = (PULONG) ioBuffer;

  switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
  {
      //case IOCTL_SETRegisters:
     //            break;

    case IOCTL_WRITE_REGISTER_ULONG:
            if (inBufLength>=4){
           m_commandReg = (PULONG)(0xDF922028);
           WRITE_REGISTER_ULONG((PULONG)m_commandReg,(PULONG)ShortBuffer[0],1);

            }
              pIrp->IoStatus.Information = 0; /* Output Buffer Size */
        ntStatus = STATUS_SUCCESS;
                 break;

    default:
        KdPrint( ("PORTTALK: Unsupported IOCTL Call/n") );
        ntStatus = STATUS_UNSUCCESSFUL;
        pIrp->IoStatus.Information = 0;
        break;

  }
  pIrp->IoStatus.Status = ntStatus;
  IoCompleteRequest( pIrp, IO_NO_INCREMENT );
  return ntStatus;
}

到底是什么地方出了问题,才会出现重启的现象呢??


a:你要先map然后在操作


q:m_commandReg = (PULONG)(0xDF922028);
WRITE_REGISTER_ULONG((PULONG)m_commandReg,(PULONG)ShortBuffer[0],1);

其中0xDF922028已经是卡驱动提供好的虚拟地址了,那还需要进行MAP再操作吗?
我的想法是,这是内存虚拟地址,所以已经可以直接用WRITE_REGISTER_ULONG直接对这块区域进行写操作了,不知道我的理解对不对,希望DX指教

a:你的是IO端口还是内存,无论怎样都需要将物理地址空间影射
你可以调试一下,看下错误时的代码是IRQL问题还是其他什么原因

q:现在发现重启问题没有了,但是读取出来的数据为什么和实际的不一样呢?
m_commandReg = (PULONG)(0xDF922028);
READ_REGISTER_ULONG((PULONG)m_commandReg);
其中0xDF922028是某一卡的驱动安装以后得到的资源中的内存范围中的开始地址,我想读取这个地址代表的寄存器,可是发现使用READ_REGISTER_ULONG((PULONG)m_commandReg);
读取出来的数据不对,和使用WINDRIVER读取出来的完全不一样,是什么原因呢?

q:还发现一个问题:在驱动模式下直接读取虚拟内存空间
*(PULONG)(&CharBuffer[0]) = *(PULONG)m_commandReg;和采用
READ_REGISTER_ULONG((PULONG)m_commandReg);
读取出来的数据完全一样,那READ_REGISTER_ULONG的作用又是什么呢???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值