引用 12 楼 huntercao 的回复:
引用 9 楼 wdy0725 的回复:
引用 7 楼 huntercao 的回复:
如果同时烧写多个设备,如果突然拔出其中一个,有时会造成另一个烧写失败, 有时正常。不解, 请赐教。
每开始一个任务,上层应用都会起一个线程, 可以使多个任务同时工作。
->一个程序同时烧写多个设备?烧写失败的时候,烧写程序得到的错误信息是什么?
根上面的一样,31,连接系统上的设备没有发……
谢谢!
1. 释放一些资源。将IoRegisterDeviceInterface 得到的 SymbolicLinkName 释放,释放 USBD_INTERFACE_LIST_ENTRY。
我试过了,即使我不释放任何资源,问题还在,所以说可能不是这里的问题。
2. 31(连接系统上的设备没有发挥作用) 是 ReadFile/WriteFile 返回的错误码。
对应驱动层的错误是 c0000001(STATUS_UNSUCCESSFUL). 是这样得到的:依次调用IoSetCompletionRoutine,IoCallDriver, KeWaitForSingleObject后,下层驱动回调我的函数(也就是IoSetCompletionRoutine 的第二个参数),其中第二个参数(PIRP)中的IoStatus.Status 就是 c0000001.这些代码是DriverStudio 写的, 我节选一些:
I.SetCompletionRoutine(SyncCompleteSubmitUrb, &Ctx);//做IoSetCompletionRoutine。 SyncCompleteSubmitUrb 函数在下面
// Pass the IRP/URB to USBD
BOUNDS_CHECKER(SUBMIT_URB, (this, pUrb, PIRP(I)));
status = Call(I); //做IoCallDriver
if ( status == STATUS_PENDING )
{
// calculate the time out interval
ULONGLONG TimeOut100nSec;
PLARGE_INTEGER pTimeOut;
if ( mSecTimeOut != 0 )
{
// the input value may be negative or positive. Make sure
// it's positive, and then convert to negative afterwards.
LONG mSecTimeOutSigned = LONG(mSecTimeOut);
if (mSecTimeOutSigned < 0)
mSecTimeOutSigned = -mSecTimeOutSigned;
mSecTimeOut = ULONG(mSecTimeOutSigned);
// Calculate wait as 100ns intervals. Negative is relative
TimeOut100nSec = mSecTimeOut;
TimeOut100nSec *= -10000; // convert units
pTimeOut = PLARGE_INTEGER(&TimeOut100nSec);
}
else
pTimeOut = NULL;
// Wait for the event to be signaled, or timeout if specified
status = Synch.Wait(KernelMode, FALSE, pTimeOut);
if (status != STATUS_SUCCESS) //这里返回成功,不会走进去
{
BOUNDS_CHECKER(URB_TIMEOUT, (this, pUrb));
IoCancelIrp(I);
// Cancelling the IRP should result in a speedy completion. We have
// to wait because we don't want the completion routine to run
// after the event (Synch) has gone out of scope.
Synch.Wait(KernelMode, FALSE, NULL);
}
else
status = Ctx.Status; // Ctx.Status == c0000001. 我的理解它是从下面的函数中获得的
////////////////////////////////////////////////////////////////////
// KUsbLowerDevice::SyncCompleteSubmitUrb
//
// This completion routine signals an event to allow execution to
// resume in the case of a synchronous SubmitUrb.
//
// Parameters
// DeviceObject pointer to device object
// pIrp Irp that just completed
// Context Context structure for Irp to be completed
//
NTSTATUS KUsbLowerDevice::SyncCompleteSubmitUrb(
PDEVICE_OBJECT DeviceObject,
PIRP pIrp,
PVOID Context
)
{
SyncCompleteSubmitUrbContext_t* pCtx =
(SyncCompleteSubmitUrbContext_t*)Context;
BOUNDS_CHECKER(COMPLETED_URB, (pCtx->pLD, pCtx->pUrb, pIrp, pIrp->IoStatus.Status));
// load up the context structure
pCtx->Status = pIrp->IoStatus.Status;
// signal the event to release waiting thread
(pCtx->pEvent)->Set();
return STATUS_MORE_PROCESSING_REQUIRED;
UNREFERENCED_PARAMETER(DeviceObject);
}
谢谢啦。