wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
阅读:762回复:0

重起?

楼主#
更多 发布于:2004-05-09 11:30
在驱动程序中,我写了一个模拟Dma传输的程序,并没有涉及任何的硬件操作,只是在
启动例程StartDMA(),中设置了一个1秒的定时器,1秒后程序调用定时器回调函数,回调函数然后
调用m_CurrentTransfer->Continue(UseTransferSize)函数,触发OnDmaReady()函数调用,
但是在程序运行时,在 sofitice中出现如下的错误:
Break Due to KeBufCheckEx(unhandle kernel mode exception)
Error = A (IROQL_NOT_Less_or_EQAOL)
P1=60 D2=2  P3=0 P4=F47A0EC0
然后机器自动重新启动了。当屏蔽掉OnDmaReady()中的(ULONG) pXfer->BytesRemaining() == I.ReadSize()这段代码时
程序就不会出现任何的错误。我实在是弄不清这是什么的原因,请大家帮我检查一下我的程序错在那里?我的主要代码如下:

NTSTATUS C6416Device::OnStartDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

I.Information() = 0;


PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();

PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

#define MAX_DMA_LENGTH 0x100000 // 0x100000 is 1 MB


DEVICE_DESCRIPTION dd;
RtlZeroMemory(&dd, sizeof(dd));
dd.Version = DEVICE_DESCRIPTION_VERSION;
dd.Master = TRUE;
dd.ScatterGather = FALSE;
dd.DemandMode = TRUE;
dd.AutoInitialize = FALSE;
dd.Dma32BitAddresses = TRUE;
dd.IgnoreCount = FALSE;
dd.DmaChannel = 0;
dd.InterfaceType = PCIBus;
dd.DmaWidth = Width32Bits; // PCI default width
dd.DmaSpeed = Compatible;
dd.MaximumLength = MAX_DMA_LENGTH;

m_Dma.Initialize(&dd, m_Lower.PDO());

m_Buffer.Initialize(&m_Dma,1024);

return status;
}

NTSTATUS C6416Device::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

Invalidate();

return status;

}



NTSTATUS C6416Device::OnRemoveDevice(KIrp I)
{
Device removed, release the system resources.
Invalidate();

return STATUS_SUCCESS;

}



NTSTATUS C6416Device::Create(KIrp I)
{
NTSTATUS status;

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

return status;
}



NTSTATUS C6416Device::Close(KIrp I)
{
NTSTATUS status;

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

    return status;
}


NTSTATUS C6416Device::CleanUp(KIrp I)
{
m_DriverManagedQueue.PnpCleanUp(this, I.FileObject());
return I.PnpComplete(this, STATUS_SUCCESS);
}

void C6416Device::SerialRead(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

m_CurrentTransfer = new(NonPagedPool) KDmaTransfer(this, &m_Dma);

if ( m_CurrentTransfer == NULL )
{
status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint(\"unable to allocate transfer object: %x\\n\", status);

I.Information() = 0;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}

status = m_CurrentTransfer->Initiate(
this,
&m_Dma,
I.Mdl(),
(I.MajorFunction() == IRP_MJ_READ) ? FromDeviceToMemory : FromMemoryToDevice,
LinkTo(OnDmaReady),
&m_Buffer
);


if ( ! NT_SUCCESS(status) )
{
DbgPrint(\"unable to initiate transfer: %x\\n\", status);

delete m_CurrentTransfer;
m_CurrentTransfer = NULL;

I.Information() = 0;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}

}


NTSTATUS C6416Device::Read(KIrp I)
{
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
return m_DriverManagedQueue.QueueIrp(I);
}


void C6416Device::SerialWrite(KIrp I)
{


NTSTATUS status = STATUS_SUCCESS;

KMemory Mem(I.Mdl());

PVOID pSBuffer = Mem.MapToSystemSpace();

PVOID pDBuffer = m_Buffer.VirtualAddress();
ULONG   dwTotalSize = I.WriteSize(CURRENT);
ULONG   dwBytesSent = 0;

if (dwTotalSize > 1024) dwBytesSent = 1024;
else dwBytesSent = dwTotalSize;

RtlCopyMemory(pDBuffer, pSBuffer, dwBytesSent);

I.Information() = dwBytesSent;
I.Status() = status;

m_DriverManagedQueue.PnpNextIrp(I);

}


NTSTATUS C6416Device::Write(KIrp I)
{
    

if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}

return m_DriverManagedQueue.QueueIrp(I);
}


NTSTATUS C6416Device::DeviceControl(KIrp I)
{
NTSTATUS status;

switch (I.IoctlCode())
{
default:
status = STATUS_INVALID_PARAMETER;
break;
}

if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}


VOID C6416Device_DriverManagedQueue::StartIo(KIrp I)
{
C6416Device *pDev = (C6416Device *) KDevicePTR(I.DeviceObject());

switch (I.MajorFunction())
{
case IRP_MJ_READ:
pDev->SerialRead(I);
break;

case IRP_MJ_WRITE:
pDev->SerialWrite(I);
break;

case IRP_MJ_DEVICE_CONTROL:
switch (I.IoctlCode())
{
default:
ASSERT(FALSE);
break;
}
break;

default:
ASSERT(FALSE);
I.Status() = STATUS_INVALID_PARAMETER;
PnpNextIrp(I);
break;
}
}


VOID C6416Device::IsrProxyTimer(PVOID Arg1, PVOID Arg2)
{
m_CurrentTransfer->Continue(UseTransferSize);
}


VOID C6416Device::StartDMA(ULONG PAddress,ULONG NBytes)
{

LONGLONG DueTime = -10000000; // 100ns units (1sec)
m_IsrProxyTimer.Set(
DueTime,
LinkTo(IsrProxyTimer),
this
);
}

VOID C6416Device::OnDmaReady(KDmaTransfer* pXfer, KIrp I)
{

if (pXfer->BytesRemaining() == 0)
{
pXfer->Terminate();

I.Information() = I.ReadSize(CURRENT);
I.Status() = STATUS_SUCCESS;

PnpNextIrp(I);


m_CurrentTransfer = NULL;
delete pXfer;
return;
}


PTRANSFER_DESCRIPTOR ptd;

while (pXfer->SequenceTransferDescriptors(&ptd)) {
t << \"Physical address 0x\" << ptd->td_PhysAddr.LowPart << \". Length is 0x\"
<< ptd->td_Length << \".\" << EOL;
}
if ((ULONG) pXfer->BytesRemaining() == I.ReadSize())
StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length);

}
附件名称/大小 下载次数 最后更新
2004-05-09_程序源代码.rar (39KB)  7
游客

返回顶部