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