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的作用又是什麼呢???