BSOD при записи/чтении
От: Ivan_83  
Дата: 04.12.11 19:34
Оценка:
Здравствуйте.

Пишу драйвер батареи: для APC smart на ком порту.
Драйвер легаси, но с пнп кодом: через devcon добавляю устройство, а дальше обычный пнп.
В AddDevice атачусь к тому что приходит, дальше открываю компорт через IoGetDeviceObjectPointer — но в стёк к нему не добавляюсь.
Порт открывается, IRP_MJ_DEVICE_CONTROL с IOCTL_SERIAL_* проходят вроде нормально — без ошибок.
А на IRP_MJ_WRITE ухожу в BSOD.

Пожалуйста помогите, уже неделю не могу осилить!



RtlInitUnicodeString(&ObjectName, L"\\DosDevices\\COM1");
Status = IoGetDeviceObjectPointer(&ObjectName, STANDARD_RIGHTS_ALL, &FileObject, &ComPdo);
...
pDeviceData->WriteBuffSize = OEM_SERIAL_BUFFSIZE;
pDeviceData->WriteBuff = ExAllocatePoolWithTag(NonPagedPool, pDeviceData->WriteBuffSize, DRIVER_TAG);
...
RtlCopyMemory(pDeviceData->WriteBuff, "Y", 1);//(*WriteBuff) = 'Y';
Status = SmBatt_SerialPortWrite(pDeviceData->ComPdo, pDeviceData->ComFileObject, pDeviceData->WriteBuff, 1);

...

NTSTATUS
IOSyncRequestCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
    UNREFERENCED_PARAMETER(Irp);
    UNREFERENCED_PARAMETER(DeviceObject);

    // If the lower driver didn't return STATUS_PENDING, we don't need to
    // set the event because we won't be waiting on it.
    // This optimization avoids grabbing the dispatcher lock and improves perf.
    if (Irp->PendingReturned == TRUE)
        KeSetEvent((PKEVENT)Context, 0, FALSE);
//  We don't want IO to get our IRP and free it.
return(STATUS_MORE_PROCESSING_REQUIRED);
}


NTSTATUS
IOSyncRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS Status;
    KEVENT Event;

    DebugPrint("IOSyncRequest...");

    KeInitializeEvent(&Event, NotificationEvent, FALSE);
    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
    Irp->IoStatus.Information = 0;
    IoSetCompletionRoutine(Irp, IOSyncRequestCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE); 

    // Call the device to do the read and wait for it to finish.
    Status = IoCallDriver(DeviceObject, Irp);
    if (Status == STATUS_PENDING) { // Wait for the IRP
        Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        if (Status == STATUS_SUCCESS)
            Status = Irp->IoStatus.Status;
    }
    KeClearEvent(&Event);
    DebugPrint("IOSyncRequest - DONE!!!");

return(Status);
}


NTSTATUS
SendDevIoControlReq(ULONG IoControlCode, BOOLEAN Internal, PDEVICE_OBJECT DeviceObject, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, ULONG_PTR *pnBytesReturned)
{
    NTSTATUS Status;
    PIRP Irp;
    PIO_STACK_LOCATION IrpSp;

    PAGED_CODE();
    
    DebugPrint("SendDevIoControlReq...");

    Irp = IoAllocateIrp((DeviceObject->StackSize + 1), FALSE);
     if (Irp == NULL) {
        DebugPrint("SendDevIoControlReq: Failed to allocate IRP");
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = ((TRUE == Internal) ? IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL);
    IrpSp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
    IrpSp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
    IrpSp->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
    Irp->UserBuffer = OutputBuffer;
    Irp->AssociatedIrp.SystemBuffer = InputBuffer;

    // Call the device to do the read and wait for it to finish.
    Status = IOSyncRequest(DeviceObject, Irp);
    IoFreeIrp(Irp);
    DebugPrint("SendDevIoControlReq - DONE!!!");

    if (pnBytesReturned)
        *pnBytesReturned = Irp->IoStatus.Information;

return(Status);
}


NTSTATUS
SmBatt_SerialPortWrite(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PVOID Buffer, ULONG NumberOfBytesToWrite)
{
    NTSTATUS Status;
    PIRP Irp;
    PIO_STACK_LOCATION IrpSp;

    PAGED_CODE();
    
    DebugPrint("SmBatt_SerialPortWrite...");

    Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, Buffer  OPTIONAL, NumberOfBytesToWrite, NULL, NULL);
    //Irp = IoAllocateIrp((DeviceObject->StackSize + 1), FALSE);
     if (Irp == NULL) {
        DebugPrint("SerialPortWrite: Failed to allocate IRP");
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    /*IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_WRITE;
    IrpSp->Parameters.Write.Length = NumberOfBytesToWrite;
    IrpSp->FileObject = FileObject;
    Irp->AssociatedIrp.SystemBuffer = Buffer;*/

    // Call the device to do the read and wait for it to finish.
    Status = IOSyncRequest(DeviceObject, Irp);
    IoFreeIrp(Irp);
    DebugPrint("SmBatt_SerialPortWrite - DONE!!!");

return(Status);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.