Ochkarik
|
|
« Ответ #2 : 01-02-2006 10:17 » |
|
и второй вариант из первых попыток, практически нумеговский код. извините, в вашем коде на первый взгляд ничего плохого не нашел а разбираться увы - со временем напряженка... возможно STATUS_DEVICE_DATA_ERROR (0xC000009C) может выдаваться если устройство не подтверждает запись в этот регион... адреса правильно указаны? к сожалению более точно уже не помю... забыл уже) попробуйте по ДДК посмотреть что где может возвращатся... на "асинк-врайт".
/////////////////////////////////////////////////////////////////////////////////////////////////// // Test1394PC1SubmitIrb // method to asynchronously submit an IRB to the bus driver. //!Функция отправляет текущий IRP, нижнему драйверу через его IRP_MJ_INTERNAL_DEVICE_CONTROL. //!по окончании обработки IRP вызывается: //! CompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) NTSTATUS Test1394PC1SubmitIrb( IN PDEVICE_OBJECT DeviceObject, //!>device object IN PIRB Irb, //!>IRB для запроса IN PIRP Irp, //!>текущий IRP IN PIO_COMPLETION_ROUTINE CompletionRoutine, //!>функция завершения запроса IRP (completion routine) IN PVOID Context) //!>конеткст вызова функции завершения (completion routine) { NTSTATUS status; IO_STATUS_BLOCK ioStatus; KEVENT event; PIO_STACK_LOCATION irpStack;
Test1394PC1DebugPrint(DBG_IO, DBG_INFO, __FUNCTION__"++");
// Get the next IRP stack location irpStack = IoGetNextIrpStackLocation(Irp);
// Use internal device control even though // some DDK documentation may state otherwise irpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
// Set the control code irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
// Set up the parameters for the IRP irpStack->Parameters.Others.Argument1 = Irb;
// Set our completion routine in the IRP IoSetCompletionRoutine(Irp,CompletionRoutine,Context,TRUE,TRUE,TRUE);
// Send it down status = IoCallDriver(DeviceObject, Irp);
Test1394PC1DebugPrint(DBG_IO, DBG_INFO, __FUNCTION__"--. STATUS %x", status);
return status; } /////////////////////////////////////////////////////////////////////////////////////////////////// // Test1394PC1_DeviceAccess // Sends or receives data on the 1394 bus using asynchronous read or // write transfers, using a completion routine // Arguments: // IN DeviceExtension // Our device extension // IN OriginalRequest // IRP to send to completion routine // IN OffsetHigh // Destination address high part // IN OffsetLow // Destination address low part // IN Mdl // Transfer data buffer // IN NumberOfBytes // Number of data bytes to transfer // IN bWrite // Flag to indicate transfer direction // IN bRawMode // Flag to indicate whether to send the request to the bus driver or the port driver. // IN Node // Node number to read/write from/to, set to MAX_LOCAL_NODES to let the bus route the transfer. // Return Value: // If a failure status is returned, then the completion routine // will not be called. STATUS_PENDING is a successful return. // //! Функция четния/записи адресного пространства устройства 1394. //! Функция размещает IRP для драйвера шины 1394, размещает ioContext, //! и посылает запрос с CompletionRoutine, которая будет вызвана по завершению операции. //! возвращает STATUS_PENDING при успешном вызове (или STATUS_INSUFFICIENT_RESOURCES) //! Если возвращен не STATUS_PENDING - функция завершения не будет вызвана. //! текущий запрос помечается IoMarkIrpPending(OriginalRequest) NTSTATUS Test1394PC1_DeviceAccess( IN PTEST1394PC1_DEVICE_EXTENSION DeviceExtension, //!< device extension IN PIRP OriginalRequest, //!< инициирующий IRP IN ULONG NumberOfBytes, //!< длинна запроса чтения/записи IN USHORT OffsetHigh, //!< адрес (старшая часть) IN ULONG OffsetLow, //!< адрес (младшая часть) IN PMDL Mdl, //!< MDL куда писать при чтении(откуда читать при записи) IN BOOLEAN bWrite, //!< Запись(чтение) IN BOOLEAN bRawMode, //!< запись в порт (минуя драйвер шины 1394) IN USHORT Node //!< номер устройства 1394 на локальной шине, если запись в порт или MAX_LOCAL_NODES - если запсись в драйвер шины ) { PTEST1394PC1_IO_CONTEXT ioContext; ULONG length; PIRP irp; PIRB irb; NTSTATUS status;
do{ ASSERT(Mdl != NULL);
// allocate io context to pass to completion routine ioContext = (PTEST1394PC1_IO_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(TEST1394PC1_IO_CONTEXT));
if (ioContext == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; }
irp = IoAllocateIrp(DeviceExtension->LowerDeviceObject->StackSize,FALSE);
if (irp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; }
// Allocate an IRB irb = (PIRB)ExAllocateFromNPagedLookasideList(&DeviceExtension->IrbList); if (irb == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; }
// Mark the original IRP pending IoMarkIrpPending(OriginalRequest);
// Setup the IRB RtlZeroMemory(irb, sizeof(IRB));
if (bWrite) { irb->FunctionNumber = REQUEST_ASYNC_WRITE;
irb->u.AsyncWrite.DestinationAddress.IA_Destination_Offset.Off_High = OffsetHigh; irb->u.AsyncWrite.DestinationAddress.IA_Destination_Offset.Off_Low = OffsetLow; irb->u.AsyncWrite.nNumberOfBytesToWrite = NumberOfBytes; irb->u.AsyncWrite.Mdl = Mdl; irb->u.AsyncWrite.ulGeneration = DeviceExtension->GenerationCount; if (Node < MAX_LOCAL_NODES) { irb->u.AsyncWrite.DestinationAddress.IA_Destination_ID.NA_Bus_Number = LOCAL_BUS; irb->u.AsyncWrite.DestinationAddress.IA_Destination_ID.NA_Node_Number = Node; } } else { irb->FunctionNumber = REQUEST_ASYNC_READ;
irb->u.AsyncRead.DestinationAddress.IA_Destination_Offset.Off_High = OffsetHigh; irb->u.AsyncRead.DestinationAddress.IA_Destination_Offset.Off_Low = OffsetLow; irb->u.AsyncRead.nNumberOfBytesToRead = NumberOfBytes; irb->u.AsyncRead.Mdl = Mdl; irb->u.AsyncRead.ulGeneration = DeviceExtension->GenerationCount; if (Node < MAX_LOCAL_NODES) { irb->u.AsyncRead.DestinationAddress.IA_Destination_ID.NA_Bus_Number = LOCAL_BUS; irb->u.AsyncRead.DestinationAddress.IA_Destination_ID.NA_Node_Number = Node; } }
// Setup the context ioContext->DeviceExtension = DeviceExtension; ioContext->Irp = irp; ioContext->Irb = irb; ioContext->Mdl = Mdl; ioContext->NumberOfBytes = NumberOfBytes; ioContext->OriginalRequest = OriginalRequest;
// Send it down if (bRawMode) Test1394PC1SubmitIrb( DeviceExtension->PortDeviceObject, ioContext->Irb, ioContext->Irp, Test1394PC1_AccessCompletionRoutine, ioContext); else Test1394PC1SubmitIrb( DeviceExtension->LowerDeviceObject, ioContext->Irb, ioContext->Irp, Test1394PC1_AccessCompletionRoutine, ioContext);
status = STATUS_PENDING; } while (FALSE);
if (!NT_SUCCESS(status)) { //в случае ошибок освобождаем все что нахватали из ресурсов: // Free our allocated IRP if (irp != NULL) IoFreeIrp(irp);
// Free our allocated IRB memory if (irb != NULL) ExFreeToNPagedLookasideList(&DeviceExtension->IrbList,irb);
// Free our allocated context if (ioContext != NULL) ExFreePool(ioContext); }
return status; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // Test1394PC1_AccessCompletionRoutine // Completion routine for asynchronous transfer. //! Функция вызывается по завершению запроса Test1394PC1Access0RDeviceAccess //! Устанавливает статус выполнения операции запроса IRP, //! указывает число скопированных данных, освобождает ресурсы запроса и завершает исходный IRP. NTSTATUS Test1394PC1_AccessCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PTEST1394PC1_IO_CONTEXT ioContext; NTSTATUS status; PIRP originalIrp; PTEST1394PC1_DEVICE_EXTENSION deviceExtension;
// Get our completion context ioContext = (PTEST1394PC1_IO_CONTEXT)Context;
// Get the status of the async request status = Irp->IoStatus.Status;
Test1394PC1DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p STATUS %x", Irp, status);
// Get the IRP from the async request originalIrp = ioContext->OriginalRequest;
// Get our device extension deviceExtension = ioContext->DeviceExtension;
if (originalIrp) { originalIrp->IoStatus.Status = Irp->IoStatus.Status; if (NT_SUCCESS(Irp->IoStatus.Status)) { originalIrp->IoStatus.Information = ioContext->NumberOfBytes; } }
// Free our allocated IRB memory ExFreeToNPagedLookasideList(&deviceExtension->IrbList,ioContext->Irb);
// Free our allocate IRP IoFreeIrp(ioContext->Irp);
// Free our allocated context ExFreePool(ioContext);
if (originalIrp) { // Complete the original request IoCompleteRequest(originalIrp, IO_NO_INCREMENT); Test1394PC1DecrementIoCount(&deviceExtension->IoLock); }
Test1394PC1DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");
return STATUS_MORE_PROCESSING_REQUIRED; }
|