39#pragma alloc_text(PAGE, DeviceDeallocateMmcResources)
40#pragma alloc_text(PAGE, DeviceAllocateMmcResources)
41#pragma alloc_text(PAGE, DeviceUpdateMmcCapabilities)
42#pragma alloc_text(PAGE, DeviceGetConfigurationWithAlloc)
43#pragma alloc_text(PAGE, DeviceGetConfiguration)
44#pragma alloc_text(PAGE, DeviceUpdateMmcWriteCapability)
45#pragma alloc_text(PAGE, MmcDataFindFeaturePage)
46#pragma alloc_text(PAGE, MmcDataFindProfileInProfiles)
47#pragma alloc_text(PAGE, DeviceRetryTimeGuessBasedOnProfile)
48#pragma alloc_text(PAGE, DeviceRetryTimeDetectionBasedOnModePage2A)
49#pragma alloc_text(PAGE, DeviceRetryTimeDetectionBasedOnGetPerformance)
54#pragma warning(disable:4214)
58DeviceDeallocateMmcResources(
93 if (mmcData->CapabilitiesBuffer)
96 mmcData->CapabilitiesBuffer =
NULL;
113DeviceAllocateMmcResources(
146 &mmcData->CapabilitiesBuffer,
167 mmcData->CapabilitiesBuffer =
NULL;
179 mmcData->CapabilitiesBuffer =
NULL;
187 status = WdfRequestCreateFromIrp(&attributes,
201DeviceUpdateMmcCapabilities(
224 ULONG returnedBytes = 0;
249 mmcData->CapabilitiesBuffer,
263 ULONG blockingFactor = 1;
265 DeviceUpdateMmcWriteCapability(mmcData->CapabilitiesBuffer,
281 ULONG minAdditionalLength;
286 header = MmcDataFindFeaturePage(mmcData->CapabilitiesBuffer,
292 (
header->AdditionalLength >= minAdditionalLength))
308 header = DeviceFindFeaturePage(mmcData->CapabilitiesBuffer,
334 mmcData->CapabilitiesBuffer->CurrentProfile[0] << (8*1) |
335 mmcData->CapabilitiesBuffer->CurrentProfile[1] << (8*0) ;
351 final =
min(
final, t4);
355 final =
min(
final, t3);
359 final =
min(
final, t2);
363 final =
min(
final, t1);
394DeviceGetConfigurationWithAlloc(
450 header.DataLength[1] << 16 |
451 header.DataLength[2] << 8 |
452 header.DataLength[3] << 0 ;
464 "DeviceGetConfigurationWithAlloc: drive reports only %x bytes?\n",
496 else if (returned >
size)
506 returned =
buffer->DataLength[0] << 24 |
507 buffer->DataLength[1] << 16 |
508 buffer->DataLength[2] << 8 |
509 buffer->DataLength[3] << 0 ;
510 returned += 4*
sizeof(
UCHAR);
512 if (returned <=
size)
535 "DeviceGetConfigurationWithAlloc: Failed %d attempts to get all feature "
536 "information\n",
i));
544DeviceGetConfiguration(
604#pragma warning(disable: 6386)
612 return DeviceGetConfiguration(
Device,
640 "DeviceGetConfiguration: Status was %x\n",
status));
649 (
header->DataLength[1] << (8*2)) |
650 (
header->DataLength[2] << (8*1)) |
651 (
header->DataLength[3] << (8*0)) ;
676 "DeviceGetConfiguration: failed %x\n",
status));
685DeviceUpdateMmcWriteCapability(
742 defectHeader = MmcDataFindFeaturePage(
Buffer,
745 writableHeader = MmcDataFindFeaturePage(
Buffer,
749 if (defectHeader ==
NULL || writableHeader ==
NULL)
756 "DeviceUpdateMmcWriteCapability => Writes supported (defect management)\n"));
763 "DeviceUpdateMmcWriteCapability => Writes *allowed* (defect management)\n"));
803 } FEATURE_TO_WRITE_SCHEMA_MAP;
805 static FEATURE_TO_WRITE_SCHEMA_MAP
const FeaturesToAllowWritesWith[] = {
817 FeaturesToAllowWritesWith[
count].FeatureToFind);
825 "DeviceUpdateMmcWriteCapability => Writes supported (feature %04x)\n",
826 FeaturesToAllowWritesWith[
count].FeatureToFind
834 "DeviceUpdateMmcWriteCapability => Writes *allowed* (feature %04x)\n",
835 FeaturesToAllowWritesWith[
count].FeatureToFind
861 "DeviceUpdateMmcWriteCapability => Writes supported (feature %04x)\n",
867 else if (
header->Header.Current)
870 "DeviceUpdateMmcWriteCapability => Writes *allowed* (feature %04x)\n",
896 "DeviceUpdateMmcWriteCapability => Writes supported (feature %04x)\n",
902 else if (
header->Header.Current)
905 "DeviceUpdateMmcWriteCapability => Writes *allowed* (feature %04x)\n",
935 if (bufferEnd >= headerEnd)
943 } PROFILE_TO_WRITE_SCHEMA_MAP;
945 static PROFILE_TO_WRITE_SCHEMA_MAP
const ProfilesToAllowWritesWith[] = {
963 "DeviceUpdateMmcWriteCapability => Writes %s (profile %04x)\n",
984MmcDataFindFeaturePage(
1029 buffer = FeatureBuffer->Data;
1039 thisFeature = (
header->FeatureCode[0] << 8) |
1040 (
header->FeatureCode[1]);
1060 "Feature %x exists, but not safe to access all its "
1061 "data. returning NULL\n",
Feature));
1070 if ((
header->AdditionalLength % 4) &&
1085MmcDataFindProfileInProfiles(
1110 ULONG numberOfProfiles;
1119 if (ProfileHeader->Header.AdditionalLength % 2 != 0)
1122 "Profile total length %x is not integral multiple of 4\n",
1123 ProfileHeader->Header.AdditionalLength));
1129 numberOfProfiles = ProfileHeader->Header.AdditionalLength / 4;
1130 profile = ProfileHeader->Profiles;
1133 for (
i = 0;
i < numberOfProfiles;
i++)
1137 currentProfile = (
profile->ProfileNumber[0] << 8) |
1138 (
profile->ProfileNumber[1] & 0xff);
1298 ULONG transferSize =
min(0xFFF0, DeviceExtension->ScratchContext.ScratchBufferSize);
1314 status = ScratchBuffer_ExecuteCdb(DeviceExtension,
NULL, transferSize,
TRUE, &cdb, 10);
1322 (
header->ModeDataLength[1] << (8*0)) ;
1337 else if (
dataLength > DeviceExtension->ScratchContext.ScratchBufferSize)
1341 else if ((
header->BlockDescriptorLength[1] == 0) &&
1342 (
header->BlockDescriptorLength[0] == 0))
1347 else if ((
header->BlockDescriptorLength[1] == 0) &&
1374 "ModePage 2Ah was requested, but drive reported "
1375 "only %x bytes (%x needed). Ignoring.\n",
1386 "ModePage 2Ah was requested, but drive reported "
1397 (
page->WriteSpeedMaximum[0] << (8*1)) |
1398 (
page->WriteSpeedMaximum[1] << (8*0)) ;
1409 result = ConvertSectorsPerSecondTo100nsUnitsFor64kWrite(
temp);
1444 typedef struct _GET_PERFORMANCE_HEADER {
1445 UCHAR TotalDataLength[4];
1448 UCHAR Reserved0 : 6;
1450 } GET_PERFORMANCE_HEADER, *PGET_PERFORMANCE_HEADER;
1451 C_ASSERT(
sizeof(GET_PERFORMANCE_HEADER) == 8);
1453 typedef struct _GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR {
1455 UCHAR StartPerformance[4];
1457 UCHAR EndPerformance[4];
1458 } GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR, *PGET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR;
1459 C_ASSERT(
sizeof(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR) == 16);
1462 typedef struct _GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR {
1463 UCHAR MixedReadWrite : 1;
1464 UCHAR GuaranteedForWholeMedia : 1;
1465 UCHAR Reserved0_RDD : 1;
1466 UCHAR WriteRotationControl : 2;
1470 UCHAR MediaCapacity[4];
1471 UCHAR ReadSpeedKilobytesPerSecond[4];
1472 UCHAR WriteSpeedKilobytesPerSecond[4];
1473 } GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR, *PGET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR;
1474 C_ASSERT(
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) == 16);
1483 C_ASSERT(
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) ==
sizeof(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR));
1485 ULONG const maxDescriptors =
min(200, (DeviceExtension->ScratchContext.ScratchBufferSize-
sizeof(GET_PERFORMANCE_HEADER))/
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR));
1486 ULONG validDescriptors = 0;
1487 ULONG transferSize =
sizeof(GET_PERFORMANCE_HEADER) + (maxDescriptors*
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR));
1496 if (UseLegacyNominalPerformance)
1517 GET_PERFORMANCE_HEADER
const*
header = (GET_PERFORMANCE_HEADER
const*)DeviceExtension->ScratchContext.ScratchBuffer;
1518 ULONG temp1 = (
header->TotalDataLength[0] << (8*3)) |
1519 (
header->TotalDataLength[1] << (8*2)) |
1520 (
header->TotalDataLength[2] << (8*1)) |
1521 (
header->TotalDataLength[3] << (8*0)) ;
1528 else if (temp1 != 0)
1537 else if (temp1 <=
sizeof(GET_PERFORMANCE_HEADER))
1541 else if (UseLegacyNominalPerformance &&
1547 else if (!UseLegacyNominalPerformance &&
1553 else if ( (temp1 -
sizeof(GET_PERFORMANCE_HEADER)) %
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) != 0)
1556 C_ASSERT(
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) ==
sizeof(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR));
1563 C_ASSERT(
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) ==
sizeof(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR));
1566 temp1 =
min(temp1, DeviceExtension->ScratchContext.ScratchSrb->DataTransferLength);
1568 validDescriptors = (temp1 -
sizeof(GET_PERFORMANCE_HEADER)) /
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR);
1577 GET_PERFORMANCE_HEADER
const*
header = (GET_PERFORMANCE_HEADER
const*)DeviceExtension->ScratchContext.ScratchBuffer;
1578 GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR
const*
descriptor = (GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR
const*)(
header+1);
1587 C_ASSERT(
sizeof(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR) ==
sizeof(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR));
1588 C_ASSERT(
FIELD_OFFSET(GET_PERFORMANCE_WRITE_SPEED_DESCRIPTOR, WriteSpeedKilobytesPerSecond) ==
1589 FIELD_OFFSET(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR, EndPerformance)
1592 RTL_FIELD_SIZE(GET_PERFORMANCE_NOMINAL_PERFORMANCE_DESCRIPTOR, EndPerformance)
1598 ULONG const writeKBps =
1599 (
descriptor->WriteSpeedKilobytesPerSecond[0] << (8*3)) |
1600 (
descriptor->WriteSpeedKilobytesPerSecond[1] << (8*2)) |
1601 (
descriptor->WriteSpeedKilobytesPerSecond[2] << (8*1)) |
1602 (
descriptor->WriteSpeedKilobytesPerSecond[3] << (8*0)) ;
1606 ULONG const sectorsPerSecond =
1607 (writeKBps > 0x00418937) ?
1608 ((writeKBps / 2048) * 1000) :
1609 ((writeKBps * 1000) / 2048) ;
1611 if (sectorsPerSecond <= 0)
1620 result =
min(
result, ConvertSectorsPerSecondTo100nsUnitsFor64kWrite(sectorsPerSecond));
#define WRITE_RETRY_DELAY_CD_4x
#define WRITE_RETRY_DELAY_DVD_1x
#define CDROM_GET_CONFIGURATION_TIMEOUT
#define CdromMmcUpdateRequired
#define CDROM_HACK_BAD_GET_CONFIG_SUPPORT
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
_In_ ULONG const _In_ FEATURE_NUMBER const Feature
#define TEST_FLAG(Flags, Bit)
#define CdromMmcUpdateStarted
#define CDROM_GET_PERFORMANCE_TIMEOUT
#define CDROM_TAG_FEATURE
#define CdromMmcUpdateComplete
#define WRITE_RETRY_DELAY_HDDVD_1x
#define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS
#define SCSIOP_MODE_SENSE10
#define SCSIOP_GET_CONFIGURATION
#define SCSIOP_GET_PERFORMANCE
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_BLOCK MODE_PARAMETER_BLOCK
#define MODE_PAGE_CAPABILITIES
#define NT_SUCCESS(StatCode)
static WCHAR available[MAX_STRING_RESOURCE_LEN]
#define _IRQL_requires_max_(irql)
#define ExAllocatePoolWithTag(hernya, size, tag)
GLuint GLuint GLsizei count
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define InterlockedCompareExchange
#define RTL_FIELD_SIZE(type, field)
ULONG const BOOLEAN const _Out_ PBOOLEAN Writable
_Outptr_result_bytebuffer_all_ BytesReturned PGET_CONFIGURATION_HEADER _Out_ PULONG FEATURE_NUMBER const ULONG const RequestedType
ULONG const BOOLEAN const _Out_ PBOOLEAN _Out_ PFEATURE_NUMBER ValidationSchema
MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS LONGLONG DeviceRetryTimeGuessBasedOnProfile(FEATURE_PROFILE_TYPE const Profile)
ULONG const BOOLEAN const CurrentOnly
MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS LONGLONG DeviceRetryTimeDetectionBasedOnGetPerformance(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN UseLegacyNominalPerformance)
_Outptr_result_bytebuffer_all_ BytesReturned PGET_CONFIGURATION_HEADER _Out_ PULONG FEATURE_NUMBER const StartingFeature
_In_ ULONG const _Out_ PULONG ValidBytes
ULONG const BOOLEAN const _Out_ PBOOLEAN _Out_ PFEATURE_NUMBER _Out_ PULONG BlockingFactor
MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS LONGLONG DeviceRetryTimeDetectionBasedOnModePage2A(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension)
_In_ FEATURE_PROFILE_TYPE const ProfileToFind
INTERNETFEATURELIST feature
#define _Outptr_result_bytebuffer_all_(size)
#define _In_reads_bytes_(s)
#define _Ret_range_(l, h)
#define _Out_writes_bytes_to_(s, c)
#define _Analysis_assume_
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
enum _FEATURE_NUMBER * PFEATURE_NUMBER
struct _FEATURE_DATA_RANDOM_READABLE * PFEATURE_DATA_RANDOM_READABLE
struct _FEATURE_HEADER * PFEATURE_HEADER
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT
enum _FEATURE_NUMBER FEATURE_NUMBER
@ ProfileBDRSequentialWritable
@ ProfileBDRRandomWritable
@ ProfileDvdPlusRWDualLayer
@ ProfileNonRemovableDisk
@ ProfileDvdDashRLayerJump
@ ProfileDvdPlusRDualLayer
@ ProfileDvdDashRDualLayer
enum _FEATURE_PROFILE_TYPE FEATURE_PROFILE_TYPE
struct _FEATURE_DATA_REAL_TIME_STREAMING * PFEATURE_DATA_REAL_TIME_STREAMING
struct _GET_CONFIGURATION_HEADER * PGET_CONFIGURATION_HEADER
@ FeatureDvdPlusRDualLayer
@ FeatureRestrictedOverwrite
@ FeatureIncrementalStreamingWritable
@ FeatureDefectManagement
@ FeatureRealTimeStreaming
@ FeatureRigidRestrictedOverwrite
struct _FEATURE_HEADER FEATURE_HEADER
_In_ ULONG _In_ ULONG _In_ ULONG Length
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID NTAPI IoFreeIrp(IN PIRP Irp)
#define STATUS_INTERNAL_ERROR
FORCEINLINE VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
#define ScratchBuffer_BeginUse(context)
#define REVERSE_BYTES(Destination, Source)
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_OVERFLOW
#define TRACE_LEVEL_WARNING
#define TRACE_LEVEL_ERROR
#define TRACE_LEVEL_INFORMATION
LONGLONG ReadWriteRetryDelay100nsUnits
PDEVICE_OBJECT DeviceObject
CDROM_DATA DeviceAdditionalData
FEATURE_NUMBER ValidationSchema
BOOLEAN StreamingReadSupported
ULONG CapabilitiesBufferSize
WDFREQUEST CapabilitiesRequest
BOOLEAN StreamingWriteSupported
#define FIELD_OFFSET(t, f)
#define RtlZeroMemory(Destination, Length)
#define STATUS_INVALID_DEVICE_REQUEST
#define STATUS_DATA_OVERRUN
#define STATUS_UNSUCCESSFUL
#define STATUS_INSUFFICIENT_RESOURCES
struct _CDB::_MODE_SENSE10 MODE_SENSE10
struct _CDB::_GET_CONFIGURATION GET_CONFIGURATION
struct _CDB::_GET_PERFORMANCE GET_PERFORMANCE
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
_Must_inspect_result_ _In_ WDFDEVICE Device
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)