驅動開發網上關於重啓的網摘(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的作用又是什麼呢???

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章