zhuge36
驱动牛犊
驱动牛犊
  • 注册日期2003-07-18
  • 最后登录2010-10-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望31点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:1163回复:0

为什么异步调用没有成功?

楼主#
更多 发布于:2004-02-19 16:36
CreateFile以异步方式建立。
有输入数据的话,就可以读出。但没有的话就停下来一直等,其它的通讯则无法完成。通过查看驱动输出的信息,在SubmitUrb()后的t << "Submit Overn";已经出现,说明已经执行了return STATUS_PENDING;但我的应用程序还在等待,不知为何。

应用程序:
BOOL CUDK_XP_DEVICE::Endpoint1ListenPipes(UINT Length, void *pBuffer)
{
ULONG nOutput; // Count written to bufOutput

// Call device IO Control interface (THERMOMETER_READ_DATA) in driver
if (!DeviceIoControl(hDevice,
D12_DRIVER_READ,
pBuffer,
Length,
pBuffer,
Length,
&nOutput,
NULL)
)
{
AfxMessageBox("ERROR: DeviceIoControl returns %d n", GetLastError());
return 0;
}

TRACE("The DRIVER_READ counter is %d .n", nOutput);

return 1;
}

驱动程序:
NTSTATUS D12_DriverDevice:D12_DRIVER_READ_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << "Entering D12_DriverDevice:12_DRIVER_READ_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER

// TODO: Handle the the D12_DRIVER_READ request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.

// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;

m_pUrb1In = m_Endpoint1In.BuildInterruptTransfer(
(unsigned char *)I.IoctlBuffer(), // transfer buffer
I.IoctlInputBufferSize(), // transfer buffer size
TRUE, // Short Ok
NULL, // link urb
m_pUrb1In // new urb
);

if ( m_pUrb1In == NULL )
{
return STATUS_INSUFFICIENT_RESOURCES;;
}

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() )
{
CurrentIrp() = NULL;
CancelSpinLock::Release();
return STATUS_CANCELLED;
}

I.SetCancelRoutine( LinkTo(Cancel) );
CancelSpinLock::Release();
I.MarkPending();

t << "Submit URBn";
// submit the URB to USBD
IncrementOutstandingRequestCount();
m_Endpoint1In.SubmitUrb(m_kIrp, m_pUrb1In, LinkTo(ReadCounterComplete),this);
t << "Submit Overn";
return STATUS_PENDING;

}

NTSTATUS D12_DriverDevice::ReadCounterComplete(KIrp I)
{
t << "Read Completion routinen";
KIrp Current( CurrentIrp() );
if ( Current == NULL )
{
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}
CancelSpinLock::Acquire();
if ( Current.WasCanceled() )
{
CancelSpinLock::Release();
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
Current.SetCancelRoutine(NULL);
CancelSpinLock::Release();
CurrentIrp() = NULL;
}
if ( I.Status() != STATUS_SUCCESS )
{
NTSTATUS status = I.Status();
Current.PnpComplete(this, status);
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}
// find the buffer pointer in the URB
PUCHAR buffer = (PUCHAR)m_pUrb1In->UrbBulkOrInterruptTransfer.TransferBuffer;

// Dump the buffer
t << "Urb data[0]: " << buffer[0] << "n";
// Data from the IRP read is stored in the ioctl buffer associated with this
// IRP:
PUCHAR(Current.IoctlBuffer());
// IrpBuffer[0] = buffer[0];
Current.Information() = 1;
Current.PnpComplete(this, STATUS_SUCCESS);
DecrementOutstandingRequestCount();
return STATUS_MORE_PROCESSING_REQUIRED;
}
游客

返回顶部