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

📄 mmc.c

📁 The CD ROM driver is used with Classpnp.sys to provide access to CD ROMs and DVD ROMs. It supports P
💻 C
📖 第 1 页 / 共 4 页
字号:
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "defect management"
                   ));
    }
    
    header = CdRomFindFeaturePage(Buffer, Usable, FeatureWriteOnce);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Write Once Media"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureRestrictedOverwrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Restricted Overwrites"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureCdrwCAVWrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "CD-RW CAV recording"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureMrw);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Mount Rainier media"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDvdPlusRW);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DVD+RW media"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureRigidRestrictedOverwrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Rigid Restricted Overwrite"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureCdTrackAtOnce);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "CD Recording (Track At Once)"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureCdMastering);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "CD Recording (Mastering)"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDvdRecordableWrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DVD Recording (Mastering)"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDDCDRead);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DD CD Reading"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDDCDRWrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DD CD-R Writing"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDDCDRWWrite);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DD CD-RW Writing"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureSMART);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "S.M.A.R.T."
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureCDAudioAnalogPlay);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Analogue CD Audio Operations"
                   ));
    }
    
    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDvdCSS);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DVD CSS"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureRealTimeStreaming);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "Real-time Streaming Reads"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDiscControlBlocks);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DVD Disc Control Blocks"
                   ));
    }

    header = CdRomFindFeaturePage(Buffer, Usable, FeatureDvdCPRM);
    if (header) {
        KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                   "CdromGetConfiguration: %s %s\n",
                   (header->Current ?
                    "Currently supports" : "Is able to support"),
                   "DVD CPRM"
                   ));
    }
    return;
}

NTSTATUS
CdRomUpdateMmcDriveCapabilitiesCompletion(
    IN PDEVICE_OBJECT Unused,
    IN PIRP Irp,
    IN PDEVICE_OBJECT Fdo
    )
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
    PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
    PCDROM_DATA cdData = fdoExtension->CommonExtension.DriverData;
    PCDROM_MMC_EXTENSION mmcData = &(cdData->Mmc);
    PSCSI_REQUEST_BLOCK srb = &(mmcData->CapabilitiesSrb);
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PIRP delayedIrp;
    
    // completion routine should retry as neccessary.
    // when success, clear the flag to allow startio to proceed.
    // else fail original request when retries are exhausted.

    ASSERT(mmcData->CapabilitiesIrp == Irp);

    // for now, if succeeded, just print the new pages.

    if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
        
        //
        // ISSUE-2000/4/20-henrygab - should we try to reallocate if size
        //                            available became larger than what we
        //                            originally allocated?  otherwise, it
        //                            is possible (not probable) that we
        //                            would miss the feature.  can check
        //                            that by looking at the header size
        //                            and comparing it to requested data
        //                            size.
        //

        BOOLEAN retry;
        ULONG retryInterval;
        
        //
        // Release the queue if it is frozen.
        //

        if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
            ClassReleaseQueue(Fdo);
        }

        retry = ClassInterpretSenseInfo(
                    Fdo,
                    srb,
                    irpStack->MajorFunction,
                    0,
                    MAXIMUM_RETRIES - ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4),
                    &status,
                    &retryInterval);

        //
        // DATA_OVERRUN is not an error in this case....
        //

        if (status == STATUS_DATA_OVERRUN) {
            status = STATUS_SUCCESS;
        }

        //
        // override verify_volume based on original irp's settings
        //

        if (TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME) &&
            status == STATUS_VERIFY_REQUIRED) {
            status = STATUS_IO_DEVICE_ERROR;
            retry = TRUE;
        }

        if (retry && ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4)--) {

            LARGE_INTEGER delay;
            delay.QuadPart = retryInterval;
            delay.QuadPart *= (LONGLONG)1000 * 1000 * 10;
            
            //
            // retry the request
            //

            KdPrintEx((DPFLTR_CDROM_ID, CdromDebugError,
                       "Not using ClassRetryRequest Yet\n"));
            KdPrintEx((DPFLTR_CDROM_ID, CdromDebugFeatures,
                       "Retry update capabilities %p\n", Irp));
            CdRomPrepareUpdateCapabilitiesIrp(Fdo);
            
            CdRomRetryRequest(fdoExtension, Irp, retryInterval, TRUE);

            //
            // ClassRetryRequest(Fdo, Irp, delay);
            //
            
            return STATUS_MORE_PROCESSING_REQUIRED;
        
        }

    } else {
        
        status = STATUS_SUCCESS;

    }

    Irp->IoStatus.Status = status;

    KeSetEvent(&mmcData->CapabilitiesEvent, IO_CD_ROM_INCREMENT, FALSE);


    return STATUS_MORE_PROCESSING_REQUIRED;
}


VOID
CdRomPrepareUpdateCapabilitiesIrp(
    PDEVICE_OBJECT Fdo
    )
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
    PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
    PCDROM_DATA cdData = fdoExtension->CommonExtension.DriverData;
    PCDROM_MMC_EXTENSION mmcData = &(cdData->Mmc);
    PIO_STACK_LOCATION nextStack;
    PSCSI_REQUEST_BLOCK srb;
    PCDB cdb;
    ULONG bufferSize;
    PIRP irp;
    
    ASSERT(mmcData->UpdateState);
    ASSERT(mmcData->NumDelayedIrps != 0);
    ASSERT(mmcData->CapabilitiesIrp != NULL);
    ASSERT(mmcData->CapabilitiesMdl != NULL);
    ASSERT(mmcData->CapabilitiesBuffer);
    ASSERT(mmcData->CapabilitiesBufferSize != 0);
    ASSERT(fdoExtension->SenseData);
    
    //
    // do *NOT* call IoReuseIrp(), since it would zero out our
    // current irp stack location, which we really don't want
    // to happen.  it would also set the current irp stack location
    // to one greater than currently exists (to give max irp usage),
    // but we don't want that either, since we use the top irp stack.
    //
    // IoReuseIrp(mmcData->CapabilitiesIrp, STATUS_UNSUCCESSFUL);
    //

    irp = mmcData->CapabilitiesIrp;
    srb = &(mmcData->CapabilitiesSrb);
    cdb = (PCDB)(srb->Cdb);
    bufferSize = mmcData->CapabilitiesBufferSize;

    //
    // zero stuff out
    //

    RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
    RtlZeroMemory(fdoExtension->SenseData, sizeof(SENSE_DATA));
    RtlZeroMemory(mmcData->CapabilitiesBuffer, bufferSize);
    
    //
    // setup the srb
    //
    
    srb->TimeOutValue = CDROM_GET_CONFIGURATION_TIMEOUT;
    srb->Length = SCSI_REQUEST_BLOCK_SIZE;
    srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
    srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
    srb->SenseInfoBuffer = fdoExtension->SenseData;
    srb->DataBuffer = mmcData->CapabilitiesBuffer;
    srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
    srb->DataTransferLength = mmcData->CapabilitiesBufferSize;
    srb->ScsiStatus = 0;
    srb->SrbStatus = 0;
    srb->NextSrb = NULL;
    srb->OriginalRequest = irp;
    srb->SrbFlags = fdoExtension->SrbFlags;
    srb->CdbLength = 10;
    SET_FLAG(srb->SrbFlags, SRB_FLAGS_DATA_IN);
    SET_FLAG(srb->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);

    //
    // setup the cdb
    //

    cdb->GET_CONFIGURATION.OperationCode = SCSIOP_GET_CONFIGURATION;
    cdb->GET_CONFIGURATION.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT;
    cdb->GET_CONFIGURATION.StartingFeature[0] = 0;
    cdb->GET_CONFIGURATION.StartingFeature[1] = 0;
    cdb->GET_CONFIGURATION.AllocationLength[0] = (UCHAR)(bufferSize >> 8);
    cdb->GET_CONFIGURATION.AllocationLength[1] = (UCHAR)(bufferSize & 0xff);

    //
    // setup the irp

⌨️ 快捷键说明

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