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

📄 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 页
字号:
    }

    case IOCTL_CDROM_STOP_AUDIO: {

        //
        // Stop play.
        //

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

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

        return STATUS_PENDING;
    }

    case IOCTL_STORAGE_CHECK_VERIFY:
    case IOCTL_DISK_CHECK_VERIFY:
    case IOCTL_CDROM_CHECK_VERIFY: {

        TraceLog((CdromDebugTrace,
                    "CdRomDeviceControl: [%p] Check Verify\n", Irp));

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

           TraceLog((CdromDebugWarning,
                       "CdRomDeviceControl: Check Verify: media count "
                       "buffer too small\n"));

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

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

        return STATUS_PENDING;
    }

    case IOCTL_DVD_READ_STRUCTURE: {

        TraceLog((CdromDebugTrace,
                    "DvdDeviceControl: [%p] IOCTL_DVD_READ_STRUCTURE\n", Irp));

        if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: License Failure\n"));
            status = STATUS_COPY_PROTECTION_FAILURE;
            break;
        }

        if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
            //
            // if currently in-progress, this will just return.
            // prevents looping by doing that interlockedExchange()
            //
            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: PickRegion() from "
                        "READ_STRUCTURE\n"));
            CdRomPickDvdRegion(DeviceObject);
        }


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

            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl - READ_STRUCTURE: input buffer "
                        "length too small (was %d should be %d)\n",
                        irpStack->Parameters.DeviceIoControl.InputBufferLength,
                        sizeof(DVD_READ_STRUCTURE)));
            status = STATUS_INVALID_PARAMETER;
            break;
        }

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

            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl - READ_STRUCTURE: output buffer "
                        "cannot hold header information\n"));
            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(READ_DVD_STRUCTURES_HEADER);
            break;
        }

        if(irpStack->Parameters.DeviceIoControl.OutputBufferLength >
           MAXUSHORT) {

            //
            // key length must fit in two bytes
            //
            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl - READ_STRUCTURE: output buffer "
                        "too large\n"));
            status = STATUS_INVALID_PARAMETER;
            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_DVD_START_SESSION: {

        TraceLog((CdromDebugTrace,
                    "DvdDeviceControl: [%p] IOCTL_DVD_START_SESSION\n", Irp));

        if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: License Failure\n"));
            status = STATUS_COPY_PROTECTION_FAILURE;
            break;
        }

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

            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: DVD_START_SESSION - output "
                        "buffer too small\n"));
            status = STATUS_BUFFER_TOO_SMALL;
            Irp->IoStatus.Information = sizeof(DVD_SESSION_ID);
            break;
        }

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

        return STATUS_PENDING;
    }

    case IOCTL_DVD_SEND_KEY:
    case IOCTL_DVD_SEND_KEY2: {

        PDVD_COPY_PROTECT_KEY key = Irp->AssociatedIrp.SystemBuffer;
        ULONG keyLength;

        TraceLog((CdromDebugTrace,
                    "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY\n", Irp));

        if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: License Failure\n"));
            status = STATUS_COPY_PROTECTION_FAILURE;
            break;
        }

        if((irpStack->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(DVD_COPY_PROTECT_KEY)) ||
           (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
            key->KeyLength)) {

            //
            // Key is too small to have a header or the key length doesn't
            // match the input buffer length.  Key must be invalid
            //

            TraceLog((CdromDebugWarning,
                        "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY - "
                        "key is too small or does not match KeyLength\n",
                        Irp));
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // allow only certain key type (non-destructive) to go through
        // IOCTL_DVD_SEND_KEY (which only requires READ access to the device)
        //
        if (ioctlCode == IOCTL_DVD_SEND_KEY) {

            if ((key->KeyType != DvdChallengeKey) &&
                (key->KeyType != DvdBusKey2) &&
                (key->KeyType != DvdInvalidateAGID)) {

                status = STATUS_INVALID_PARAMETER;
                break;
            }
        } else {

            if ((key->KeyType != DvdChallengeKey) &&
                (key->KeyType != DvdBusKey1) &&
                (key->KeyType != DvdBusKey2) &&
                (key->KeyType != DvdTitleKey) &&
                (key->KeyType != DvdAsf) &&
                (key->KeyType != DvdSetRpcKey) &&
                (key->KeyType != DvdGetRpcKey) &&
                (key->KeyType != DvdDiskKey) &&
                (key->KeyType != DvdInvalidateAGID)) {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

        }

        if (cdData->DvdRpc0Device) {

            if (key->KeyType == DvdSetRpcKey) {

                PDVD_SET_RPC_KEY rpcKey = (PDVD_SET_RPC_KEY) key->KeyData;

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

                    status = STATUS_INVALID_PARAMETER;
                    break;
                }

                //
                // we have a request to set region code
                // on a RPC0 device which doesn't support
                // region coding.
                //
                // we have to fake it.
                //

                KeWaitForMutexObject(
                    &cdData->Rpc0RegionMutex,
                    UserRequest,
                    KernelMode,
                    FALSE,
                    NULL
                    );

                if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
                    //
                    // if currently in-progress, this will just return.
                    // prevents looping by doing that interlockedExchange()
                    //
                    TraceLog((CdromDebugWarning,
                                "DvdDeviceControl: PickRegion() from "
                                "SEND_KEY\n"));
                    CdRomPickDvdRegion(DeviceObject);
                }

                if (cdData->Rpc0SystemRegion == rpcKey->PreferredDriveRegionCode) {

                    //
                    // nothing to change
                    //
                    TraceLog((CdromDebugWarning,
                                "DvdDeviceControl (%p) => not changing "
                                "regions -- requesting current region\n",
                                DeviceObject));
                    status = STATUS_SUCCESS;

                } else if (cdData->Rpc0SystemRegionResetCount == 0) {

                    //
                    // not allowed to change it again
                    //

                    TraceLog((CdromDebugWarning,
                                "DvdDeviceControl (%p) => no more region "
                                "changes are allowed for this device\n",
                                DeviceObject));
                    status = STATUS_CSS_RESETS_EXHAUSTED;

                } else {

                    ULONG i;
                    UCHAR mask;
                    ULONG bufferLen;
                    PDVD_READ_STRUCTURE dvdReadStructure;
                    PDVD_COPYRIGHT_DESCRIPTOR dvdCopyRight;
                    IO_STATUS_BLOCK ioStatus = {0};
                    UCHAR mediaRegionData;

                    mask = ~rpcKey->PreferredDriveRegionCode;

                    if (CountOfSetBitsUChar(mask) != 1) {

                        status = STATUS_INVALID_DEVICE_REQUEST;
                        break;
                    }

                    //
                    // this test will always be TRUE except during initial
                    // automatic selection of the first region.
                    //

                    if (cdData->Rpc0SystemRegion != 0xff) {

                        //
                        // make sure we have a media in the drive with the same
                        // region code if the drive is already has a region set
                        //

                        TraceLog((CdromDebugTrace,
                                    "DvdDeviceControl (%p) => Checking "
                                    "media region\n",
                                    DeviceObject));

                        bufferLen = max(sizeof(DVD_DESCRIPTOR_HEADER) +
                                            sizeof(DVD_COPYRIGHT_DESCRIPTOR),
                                        sizeof(DVD_READ_STRUCTURE)
                                        );

                        dvdReadStructure = (PDVD_READ_STRUCTURE)
                            ExAllocatePoolWithTag(PagedPool,
                                                  bufferLen,
                                                  DVD_TAG_RPC2_CHECK);

                        if (dvdReadStructure == NULL) {
                            status = STATUS_INSUFFICIENT_RESOURCES;
                            KeReleaseMutex(&cdData->Rpc0RegionMutex,FALSE);
                            break;
                        }

                        dvdCopyRight = (PDVD_COPYRIGHT_DESCRIPTOR)
                            ((PDVD_DESCRIPTOR_HEADER) dvdReadStructure)->Data;

                        //
                        // check to see if we have a DVD device
                        //

                        RtlZeroMemory (dvdReadStructure, bufferLen);
                        dvdReadStructure->Format = DvdCopyrightDescriptor;

                        //
                        // Build a request for READ_KEY
                        //
                        ClassSendDeviceIoControlSynchronous(
                            IOCTL_DVD_READ_STRUCTURE,
                            DeviceObject,
                            dvdReadStructure,
                            sizeof(DVD_READ_STRUCTURE),
                            sizeof(DVD_DESCRIPTOR_HEADER) +
                                sizeof(DVD_COPYRIGHT_DESCRIPTOR),
                            FALSE,
                            &ioStatus);

                        //
                        // this is just to prevent bugs from creeping in
                        // if status is not set later in development
                        //

                        status = ioStatus.Status;

                        //
                        // handle errors
                        //

                        if (!NT_SUCCESS(status)) {
                            KeReleaseMutex(&cdData->Rpc0RegionMutex,FALSE);
                            ExFreePool(dvdReadStructure);
                            status = STATUS_INVALID_DEVICE_REQUEST;
                            break;
                        }

                        //
                        // save the mediaRegionData before freeing the
                        // allocated memory
                        //

                        mediaRegionData =
                            dvdCopyRight->RegionManagementInformation;
                        ExFreePool(dvdReadStructure);

                        TraceLog((CdromDebugWarning,
                                    "DvdDeviceControl (%p) => new mask is %x"
                                    " MediaRegionData is %x\n", DeviceObject,
                                    rpcKey->PreferredDriveRegionCode,
                                    mediaRegionData));

                        //
                        // the media region must match the requested region
                        // for RPC0 drives for initial region selection
                        //

                        if (((UCHAR)~(mediaRegionData | rpcKey->PreferredDriveRegionCode)) == 0) {
                            KeReleaseMutex(&cdData->Rpc0RegionMutex,FALSE);
                            status = STATUS_CSS_REGION_MISMATCH;
                            break;
                        }

                    }

                    //
                    // now try to set the region
                    //

                    TraceLog((CdromDebugTrace,
                                "DvdDeviceControl (%p) => Soft-Setting "
                                "region of RPC1 device to %x\n",
                                DeviceObject,
                                rpcKey->PreferredDriveRegionCode
                                ));

⌨️ 快捷键说明

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