bihaizhou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-10
  • 最后登录2004-09-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1037回复:6

救命,一定给分

楼主#
更多 发布于:2004-03-03 15:52
小弟是一绝对菜鸟,各位老大一定要帮忙。
小弟最近在做一USB驱动,win2000,DS生成。在进行读操作时,象实现异步读,当没有数据返回应用程序。读一次时,没有问题,应程序可以正常结束。当再执行一边应用程序时,退出应用程序死机,显示locked page。。。。,记不准了,

NTSTATUS IPCDevice::Read(KIrp I)
{
t << "Entering IPCDevice::Read, " << I << EOL;
// TODO: Check the incoming request.  Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.

    if (FALSE) // If (Request is invalid)
{
// Invalid parameter in the Read request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}

// Always ok to read 0 elements.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}

// Declare a memory object
KMemory Mem(I.Mdl());

     ULONG dwTotalSize = I.ReadSize(CURRENT);
ULONG dwMaxSize = m_IPC_In.MaximumTransferSize();

// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
t << "dwTotalSize=" << dwTotalSize << EOL;

// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}

// TODO: Select the correct pipe to read from

// Create an URB to do actual Bulk read from the pipe
PURB pUrb = m_IPC_In.BuildBulkTransfer(
    Mem,       // Where is data coming from?
dwTotalSize,   // How much data to read?
TRUE,         // direction (TRUE = IN)
NULL, // Link to next URB
TRUE // Allow a short transfer
);    
t << "Already Build the URB." << EOL;

if (pUrb == NULL)
{
t << "Already Build the URB but insufficient resources" << EOL;
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);

}

// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;

// Set Cancel routine
t << "Begin to set the cancel routine." << EOL;

PVOID CI = InterlockedCompareExchangePointer( (PVOID*)&CurrentIrp(), PVOID( PIRP(I)), NULL);

// Allow only one request at a time
if ( CI != NULL ) return STATUS_DEVICE_BUSY;


CancelSpinLock::Acquire();
if(I.WasCanceled())
{
CancelSpinLock::Release();
delete pUrb;
delete pCompInfo;
return STATUS_CANCELLED;
}
I.SetCancelRoutine(LinkTo(Cancel));
CancelSpinLock::Release();
I.MarkPending();

    // Submit the URB to our USB device

m_IPC_In.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
return STATUS_PENDING;
}

NTSTATUS IPCDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag
t << "Enter in ReadComplete routine" << EOL;

/* Just handle the cases of ReadComplete routine in asyn way */
KIrp Current = CurrentIrp();
if (Current == NULL)
{
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}
CancelSpinLock::Acquire();
if (Current.WasCanceled())
{
CancelSpinLock::Release();
// Deallocate Urb and context structure
PURB pUrb = pContext->m_pUrb;
delete pUrb;
delete pContext;
I.Information() = 0;
DecrementOutstandingRequestCount();
return STATUS_CANCELLED;
//return STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
Current.SetCancelRoutine(NULL);
CancelSpinLock::Release();
CurrentIrp() = NULL;
}
if (I.Status() != STATUS_SUCCESS)
{
NTSTATUS status = I.Status();
// Deallocate Urb and context structure
PURB pUrb = pContext->m_pUrb;
delete pUrb;
delete pContext;
Current.PnpComplete(this, status);
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesRead = 0;

if ( NT_SUCCESS(status) )
{
nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesRead > 0)
t << "Read() got " << nBytesRead<< " bytes from USB\n";
     }

// Deallocate Urb and context structure
delete pUrb;
delete pContext;

// set returned count
I.Information() = nBytesRead;

// Plug and Play accounting
DecrementOutstandingRequestCount();

// allow IRP completion processing
return STATUS_SUCCESS;
}

应用程序
OVERLAPPED overlp;
::memset(&overlp,0,sizeof(OVERLAPPED));
HANDLE hWait;
hWait= ::CreateEvent(NULL,true,false,NULL);
overlp.hEvent = hWait;


buf = (char *) malloc(n);
if (buf == NULL)
{
printf("Failed to allocate buffer for read");
Exit(1);
}

// Read data from driver
printf("Reading from device - ");


if(ReadFile(hDevice,buf,n,&nRead,&overlp) == false)
{
if(WaitForSingleObject(hWait,100) == WAIT_TIMEOUT)
{
CancelIo(hDevice);
//AfxMessageBox("Wrong when reading data");
printf("Wrong when reading data\n");
}
else
{
if(GetOverlappedResult(hDevice,&overlp,&nRead,FALSE))
{
//handlling
//ReadFile(hDevice, buf, n, &nRead, &overlp);
printf("%d bytes read from device (%d requested).\n", nRead, n);

// Print what was read
i = 0;
while(i < n)
{
j = min((i+26),n);
for(; i < j; i++)
{
printf("%c, ", buf);
}
printf("\n");
}

}
}
}

各位老大一定要帮忙,一定给分
zmwk
驱动中牛
驱动中牛
  • 注册日期2001-05-15
  • 最后登录2009-04-05
  • 粉丝0
  • 关注0
  • 积分59分
  • 威望51点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-03-04 13:58
try KIrp::SetCancelRoutine & KIrp::QueryIrp

如果你不清楚固件的协议,driver是无法写好的。
A strong man can save himself. A great man can save another.
bihaizhou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-10
  • 最后登录2004-09-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-03-04 10:36
zmwk老兄,
我是希望在没有数据时,驱动会返回应用程序,进行其他的工作,并在超时后可以Cancel掉IRP或用其它的方法Complete掉IRP。固件应该没有问题,我手里有驱动可以完成对他的驱动,但只有.sys和.inf而没有源代码,而这个驱动的配置与我现在用的配置不一致,如果我想测试还需每次改变固件上的代码,很麻烦,因此想再写一个driver。
zmwk
驱动中牛
驱动中牛
  • 注册日期2001-05-15
  • 最后登录2009-04-05
  • 粉丝0
  • 关注0
  • 积分59分
  • 威望51点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-03-04 10:13
看起来,不象是driver的问题。应该看看固件是否上发数据。否则会Pending的。看你写的application,应该说软件水平不错,但100ms的超时是否小了点?

另外,按一般习惯,读URB之前,应该发送一个Vendor Request什么的,通知设备上传数据。否则,下边怎么知道什么时候上传呢?

希望能帮到你。
A strong man can save himself. A great man can save another.
bihaizhou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-10
  • 最后登录2004-09-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-03-03 16:41
认错人了,我刚开始做,且只是临时任务,所以没办法花太多精力。简直是没有功底,共同学习吧
alps123
驱动牛犊
驱动牛犊
  • 注册日期2004-01-07
  • 最后登录2004-03-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-03-03 16:33
bihaizhou大哥,我毕业设计(本科)的题目是“USB驱动程序设计”,我看你功底深厚,不知你能否帮我指条路,我该怎么学,我万分感激啊!
谢谢!谢谢!
bihaizhou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-10
  • 最后登录2004-09-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-03-03 16:14
又试了一遍,是process has locked pages的错误
游客

返回顶部