⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 The CD ROM driver is used with Classpnp.sys to provide access to CD ROMs and DVD ROMs. It supports P
💻 C
📖 第 1 页 / 共 5 页
字号:
                      "XA Read (Buffer %p not aligned with mask %x\n",
                      irpStack->Parameters.DeviceIoControl.Type3InputBuffer,
                      fdoExtension->AdapterDescriptor->AlignmentMask));
            status = STATUS_INVALID_PARAMETER;
            break;
        }



        //
        // HACKHACK - REF #0001
        // The retry count will be in this irp's IRP_MN function,
        // as the new irp was freed, and we therefore cannot use
        // this irp's next stack location for this function.
        // This may be a good location to store this info for
        // when we remove RAW_READ (mode switching), as we will
        // no longer have the nextIrpStackLocation to play with
        // when that occurs
        //
        // once XA_READ is removed, then this hack can also be
        // removed.
        //
        irpStack->MinorFunction = MAXIMUM_RETRIES; // HACKHACK - REF #0001

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
    case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX: {
        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Get drive geometryEx\n"));
        if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
             FIELD_OFFSET(DISK_GEOMETRY_EX, Data)) {
            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);
        return STATUS_PENDING;
    }

    case IOCTL_DISK_GET_DRIVE_GEOMETRY:
    case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Get drive geometry\n"));

        if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof( DISK_GEOMETRY ) ) {

            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_READ_TOC_EX: {

        PCDROM_READ_TOC_EX inputBuffer;

        if (CdRomIsPlayActive(DeviceObject)) {
            status = STATUS_DEVICE_BUSY;
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(CDROM_READ_TOC_EX)) {
            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            MINIMUM_CDROM_READ_TOC_EX_SIZE) {
            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = MINIMUM_CDROM_READ_TOC_EX_SIZE;
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >
            ((USHORT)-1)) {
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength &
            fdoExtension->AdapterDescriptor->AlignmentMask) {
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        inputBuffer = Irp->AssociatedIrp.SystemBuffer;

        if ((inputBuffer->Reserved1 != 0) ||
            (inputBuffer->Reserved2 != 0) ||
            (inputBuffer->Reserved3 != 0)) {
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // NOTE: when adding new formats, ensure that first two bytes
        //       specify the amount of additional data available.
        //

        if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_TOC     ) ||
            (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_FULL_TOC) ||
            (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_CDTEXT  )) {

            // SessionTrack field is used

        } else
        if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
            (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_PMA)     ||
            (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_ATIP)) {

            // SessionTrack field is reserved

            if (inputBuffer->SessionTrack != 0) {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

        } else {
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);
        return STATUS_PENDING;
    }

    case IOCTL_CDROM_GET_LAST_SESSION: {

        //
        // If the cd is playing music then reject this request.
        //

        if (CdRomIsPlayActive(DeviceObject)) {
            status = STATUS_DEVICE_BUSY;
            break;
        }

        //
        // Make sure the caller is requesting enough data to make this worth
        // our while.
        //

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(CDROM_TOC_SESSION_DATA)) {

            //
            // they didn't request the entire TOC -- use _EX version
            // for partial transfers and such.
            //

            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(CDROM_TOC_SESSION_DATA);
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength &
            fdoExtension->AdapterDescriptor->AlignmentMask) {
            status = STATUS_INVALID_PARAMETER;
            break;
        }


        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_READ_TOC:  {

        //
        // If the cd is playing music then reject this request.
        //

        if (CdRomIsPlayActive(DeviceObject)) {
            status = STATUS_DEVICE_BUSY;
            break;
        }

        //
        // Make sure the caller is requesting enough data to make this worth
        // our while.
        //

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(CDROM_TOC)) {

            //
            // they didn't request the entire TOC -- use _EX version
            // for partial transfers and such.
            //

            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(CDROM_TOC);
            break;
        }
        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength &
            fdoExtension->AdapterDescriptor->AlignmentMask) {
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_PLAY_AUDIO_MSF: {

        //
        // Play Audio MSF
        //

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Play audio MSF\n"));

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(CDROM_PLAY_AUDIO_MSF)) {

            //
            // Indicate unsuccessful status.
            //

            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_SEEK_AUDIO_MSF: {


        //
        // Seek Audio MSF
        //

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Seek audio MSF\n"));

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(CDROM_SEEK_AUDIO_MSF)) {

            //
            // Indicate unsuccessful status.
            //

            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);
        return STATUS_PENDING;

    }

    case IOCTL_CDROM_PAUSE_AUDIO: {

        //
        // Pause audio
        //

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Pause audio\n"));

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;

        break;
    }

    case IOCTL_CDROM_RESUME_AUDIO: {

        //
        // Resume audio
        //

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Resume audio\n"));

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_READ_Q_CHANNEL: {

        PCDROM_SUB_Q_DATA_FORMAT inputBuffer =
                         Irp->AssociatedIrp.SystemBuffer;
        ULONG transferByteCount;

        if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(CDROM_SUB_Q_DATA_FORMAT)) {

            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        //
        // check for all valid types of request
        //
        if (inputBuffer->Format == IOCTL_CDROM_CURRENT_POSITION) {
            transferByteCount = sizeof(SUB_Q_CURRENT_POSITION);
        } else if (inputBuffer->Format == IOCTL_CDROM_MEDIA_CATALOG) {
            transferByteCount = sizeof(SUB_Q_MEDIA_CATALOG_NUMBER);
        } else if (inputBuffer->Format == IOCTL_CDROM_TRACK_ISRC) {
            transferByteCount = sizeof(SUB_Q_TRACK_ISRC);
        } else {
            status = STATUS_INVALID_PARAMETER;
            Irp->IoStatus.Information = 0;
            break;
        }

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            transferByteCount) {
            Irp->IoStatus.Information = transferByteCount;
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_GET_VOLUME: {

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Get volume control\n"));

        //
        // Verify user buffer is large enough for data.
        //

        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(VOLUME_CONTROL)) {

            //
            // Indicate unsuccessful status and no data transferred.
            //

            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(VOLUME_CONTROL);
            break;

        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;
    }

    case IOCTL_CDROM_SET_VOLUME: {

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: Set volume control\n"));

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(VOLUME_CONTROL)) {

            //
            // Indicate unsuccessful status.
            //

            status = STATUS_INFO_LENGTH_MISMATCH;
            break;

        }

        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject, Irp, NULL, NULL);

        return STATUS_PENDING;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -