diff options
| author | katiezb <[email protected]> | 2023-03-01 10:34:21 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-03-01 10:34:21 -0800 |
| commit | e4fec231def3b751b0f717855737317a4a2edbac (patch) | |
| tree | c6ef0679f8e29d39dc659c8864da3a4239a5c717 /storage/class/cdrom/src/aacs.c | |
| parent | 800278d3a66158b2f0f7eb6e9ce880bedb54def3 (diff) | |
Archiving storage\class\cdrom sample (#904)
The following sample is being archived but can still be accessed using:
git checkout win11-22h2
or by accessing this link:
https://github.com/microsoft/Windows-driver-samples/tree/win11-22h2
Diffstat (limited to 'storage/class/cdrom/src/aacs.c')
| -rw-r--r-- | storage/class/cdrom/src/aacs.c | 1481 |
1 files changed, 0 insertions, 1481 deletions
diff --git a/storage/class/cdrom/src/aacs.c b/storage/class/cdrom/src/aacs.c deleted file mode 100644 index 191ba6b0..00000000 --- a/storage/class/cdrom/src/aacs.c +++ /dev/null @@ -1,1481 +0,0 @@ -/*-- - -Copyright (C) Microsoft Corporation. All rights reserved. - -Module Name: - - aacs.c - -Abstract: - - The CDROM class driver implementation of handling AACS IOCTLs. - -Environment: - - kernel mode only - -Notes: - - -Revision History: - ---*/ - -#include "stddef.h" -#include "string.h" - -#include "ntddk.h" -#include "ntddstor.h" -#include "cdrom.h" -#include "ioctl.h" -#include "scratch.h" - -#ifdef DEBUG_USE_WPP -#include "aacs.tmh" -#endif - -#ifdef ALLOC_PRAGMA - -#pragma alloc_text(PAGE, DeviceHandleAacsReadMediaKeyBlock) -#pragma alloc_text(PAGE, DeviceHandleAacsStartSession) -#pragma alloc_text(PAGE, DeviceHandleAacsEndSession) -#pragma alloc_text(PAGE, DeviceHandleAacsSendCertificate) -#pragma alloc_text(PAGE, DeviceHandleAacsGetCertificate) -#pragma alloc_text(PAGE, DeviceHandleAacsGetChallengeKey) -#pragma alloc_text(PAGE, DeviceHandleAacsReadSerialNumber) -#pragma alloc_text(PAGE, DeviceHandleAacsReadMediaId) -#pragma alloc_text(PAGE, DeviceHandleAacsReadBindingNonce) -#pragma alloc_text(PAGE, DeviceHandleAacsGenerateBindingNonce) -#pragma alloc_text(PAGE, DeviceHandleReadVolumeId) -#pragma alloc_text(PAGE, DeviceHandleSendChallengeKey) - -#endif - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsReadMediaKeyBlock( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTLs: - IOCTL_AACS_READ_MEDIA_KEY_BLOCK_SIZE - IOCTL_AACS_READ_MEDIA_KEY_BLOCK -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - NTSTATUS status = STATUS_SUCCESS; - PAACS_LAYER_NUMBER layerNumber = NULL; - PVOID outputBuffer = NULL; - ULONG transferSize = sizeof(READ_DVD_STRUCTURES_HEADER); - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&layerNumber, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - if (RequestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_AACS_READ_MEDIA_KEY_BLOCK) - { - // maximum size for this transfer is one pack + header - transferSize += AACS_MKB_PACK_SIZE; - } - - if (transferSize > DeviceExtension->ScratchContext.ScratchBufferSize) - { - // rare case. normally the size of scratch buffer is 64k. - status = STATUS_INTERNAL_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - UCHAR rmdBlockNumber = 0; - BOOLEAN sendChangedCommand = TRUE; - BOOLEAN shouldRetry = TRUE; - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.READ_DVD_STRUCTURE.OperationCode = SCSIOP_READ_DVD_STRUCTURE; - // cdb->AsByte[1] = 0x01; // AACS sub-command not required for this - - cdb.READ_DVD_STRUCTURE.LayerNumber = (UCHAR)(*layerNumber); - cdb.READ_DVD_STRUCTURE.Format = 0x83; // MKB - cdb.READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(transferSize >> (8*1)); - cdb.READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(transferSize >> (8*0)); - - while (sendChangedCommand) - { - // RMDBlockNumber is set to zero.... - // RMDBlockNumber[3] maybe changed for other blocks. - cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3] = rmdBlockNumber; - - if (shouldRetry) - { - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, transferSize, TRUE, &cdb, 12); - } - - #ifdef ENABLE_AACS_TESTING - if (RequestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_AACS_READ_MEDIA_KEY_BLOCK_SIZE) - { - static const UCHAR results[] = { 0x80, 0x02, 0x00, 0x02 }; - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; - } - else if (RequestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_AACS_READ_MEDIA_KEY_BLOCK) - { - static const UCHAR results[] = { 0x80, 0x02, 0x00, 0x02 }; - static const UCHAR defaultFill = 0x30; // '0' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x8004, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; - } - #endif //ENABLE_AACS_TESTING - - if (NT_SUCCESS(status)) - { - // command succeeded, process data... - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - UCHAR thisPackNumber = cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3]; - UCHAR otherPacks = header->Reserved[1]; - - // validate and zero-base the otherPacks - if (otherPacks == 0) - { - TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT, - "AACS: Device is reporting zero total packs (invalid)\n")); - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - else - { - otherPacks--; - - if (RequestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_AACS_READ_MEDIA_KEY_BLOCK_SIZE) - { - // if not already requested last pack, do so now - if (otherPacks != thisPackNumber) - { - // re-send the command for the other pack number. - // this is safe here because NT_SUCCESS() is TRUE, - // and all the rest of this routine does is SetHardError() - // and release of resources we're still about to use. - - // re-zero the output buffer - RtlZeroMemory(DeviceExtension->ScratchContext.ScratchBuffer, sizeof(READ_DVD_STRUCTURES_HEADER)); - - // modify the CDB to get the very last pack of the MKB - rmdBlockNumber = otherPacks; - - transferSize = sizeof(READ_DVD_STRUCTURES_HEADER); - - // keep items clean - ScratchBuffer_ResetItems(DeviceExtension, TRUE); - - // make sure the loop will be executed for modified command. - sendChangedCommand = TRUE; - shouldRetry = TRUE; - } - else - { - // this request already got the last pack - // so just interpret the data - REVERSE_SHORT(&header->Length); - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - else - { - ULONG totalSize = header->Length; - // subtract out any remaining bytes in the header - // to get the number of usable bytes in this pack - totalSize -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - totalSize += otherPacks * AACS_MKB_PACK_SIZE; - - // save the result and complete the request - *((PULONG)outputBuffer) = totalSize; - *DataLength = sizeof(ULONG); - status = STATUS_SUCCESS; - } - // This will exit the loop of sendChangedCommand - sendChangedCommand = FALSE; - shouldRetry = FALSE; - } - } - else if (RequestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_AACS_READ_MEDIA_KEY_BLOCK) - { - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - else - { - // success, how many bytes to copy for this pack? - ULONG totalSize = header->Length; - size_t originalBufferSize; - - // subtract out any remaining bytes in the header - // to get the number of usable bytes in this pack - totalSize -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // if not the final pack, this should be a full transfer per spec - NT_ASSERT( (totalSize == AACS_MKB_PACK_SIZE) || (thisPackNumber == otherPacks) ); - - // validate the user's buffer is large enough to accept the full data - originalBufferSize = RequestParameters.Parameters.DeviceIoControl.OutputBufferLength; - - if (originalBufferSize < (totalSize + (AACS_MKB_PACK_SIZE*thisPackNumber))) - { - // just return a slightly bigger-than-normal size - *DataLength = (otherPacks + 1)*AACS_MKB_PACK_SIZE; - status = STATUS_BUFFER_TOO_SMALL; - } - else - { - PUCHAR whereToCopy; - // determine where to copy to the user's memory - whereToCopy = outputBuffer; - whereToCopy += AACS_MKB_PACK_SIZE * thisPackNumber; - - RtlCopyMemory(whereToCopy, header->Data, totalSize); - - // update the Information field here because we already - // have calculated the size of the block - *DataLength = totalSize + (AACS_MKB_PACK_SIZE * thisPackNumber); - status = STATUS_SUCCESS; - - // if there are more packs to get from the device, send it again.... - if (thisPackNumber != otherPacks) - { - // re-send the command for the next pack number. - // this is safe here because NT_SUCCESS() is TRUE, - // and all the rest of this routine does is SetHardError() - // and release of resources we're still about to use. - - // re-zero the output buffer - RtlZeroMemory(DeviceExtension->ScratchContext.ScratchBuffer, sizeof(READ_DVD_STRUCTURES_HEADER)); - - // modify the CDB to get the next pack of the MKB - rmdBlockNumber = cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3]++; - - // modify the SRB to be resent - // - transferSize = AACS_MKB_PACK_SIZE + sizeof(READ_DVD_STRUCTURES_HEADER); - - // keep items clean - ScratchBuffer_ResetItems(DeviceExtension, FALSE); - - // make sure the loop will be executed for modified command. - sendChangedCommand = TRUE; - shouldRetry = TRUE; - } - else - { - // else, that was the end of the transfer, so just complete the request - sendChangedCommand = FALSE; - } - } - } - - } // end of IOCTL_AACS_READ_MEDIA_KEY_BLOCK - } - } // end of NT_SUCCESS(status) - - if (!NT_SUCCESS(status)) - { - // command failed. - sendChangedCommand = FALSE; - } - } //end of while (sendChangedCommand) - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsStartSession( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_START_SESSION -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsGetAgid - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID sessionId = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&sessionId, - NULL); - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(CDVD_REPORT_AGID_DATA); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.REPORT_KEY.OperationCode = SCSIOP_REPORT_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.REPORT_KEY.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.REPORT_KEY.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.REPORT_KEY.KeyFormat = 0x00; // DVD_REPORT_AGID? - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }; - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PCDVD_KEY_HEADER keyHeader = DeviceExtension->ScratchContext.ScratchBuffer; - PCDVD_REPORT_AGID_DATA keyData = (PCDVD_REPORT_AGID_DATA)keyHeader->Data; - - *sessionId = (DVD_SESSION_ID)(keyData->AGID); - *DataLength = sizeof(DVD_SESSION_ID); - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsEndSession( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_END_SESSION -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsReleaseAgid - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID sessionId = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&sessionId, - NULL); - - if (NT_SUCCESS(status)) - { - ULONG transferSize = 0; - CDB cdb; - DVD_SESSION_ID currentSession = 0; - DVD_SESSION_ID limitSession = 0; - - if(*sessionId == DVD_END_ALL_SESSIONS) - { - currentSession = 0; - limitSession = MAX_COPY_PROTECT_AGID - 1; - } - else - { - currentSession = *sessionId; - limitSession = *sessionId; - } - - ScratchBuffer_BeginUse(DeviceExtension); - - do - { - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.SEND_KEY.OperationCode = SCSIOP_SEND_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.SEND_KEY.AGID = (UCHAR)(currentSession); - cdb.SEND_KEY.KeyFormat = DVD_INVALIDATE_AGID; - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, transferSize, FALSE, &cdb, 12); - - currentSession++; - } while ((currentSession <= limitSession) && NT_SUCCESS(status)); - -#ifdef ENABLE_AACS_TESTING - status = STATUS_SUCCESS; -#endif - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsSendCertificate( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_SEND_CERTIFICATE -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsSendHostCertificate - - NTSTATUS status = STATUS_SUCCESS; - PAACS_SEND_CERTIFICATE input = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_CERTIFICATE); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - // copy the input buffer to the data buffer for the transfer - { - PCDVD_KEY_HEADER header = (PCDVD_KEY_HEADER)DeviceExtension->ScratchContext.ScratchBuffer; - ULONG tmp = dataTransferLength; - - tmp -= RTL_SIZEOF_THROUGH_FIELD(CDVD_KEY_HEADER, DataLength); - - header->DataLength[0] = (UCHAR)(tmp >> (8*1)); - header->DataLength[1] = (UCHAR)(tmp >> (8*0)); - RtlCopyMemory(header->Data, &(input->Certificate), sizeof(AACS_CERTIFICATE)); - } - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.SEND_KEY.OperationCode = SCSIOP_SEND_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.SEND_KEY.ParameterListLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.SEND_KEY.ParameterListLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.SEND_KEY.AGID = (UCHAR)( input->SessionId ); - cdb.SEND_KEY.KeyFormat = 0x01; // Send Host Challenge Certificate - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, FALSE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - *DataLength = 0; - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsGetCertificate( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_GET_CERTIFICATE -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsGetDriveCertificate - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_CERTIFICATE); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.REPORT_KEY.OperationCode = SCSIOP_REPORT_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.REPORT_KEY.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.REPORT_KEY.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.REPORT_KEY.AGID = (UCHAR)(*input); - cdb.REPORT_KEY.KeyFormat = 0x01; // Return a drive certificate challenge - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x72, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x31; // '1' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0074, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_CERTIFICATE); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < (sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length))) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsGetChallengeKey( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_GET_CHALLENGE_KEY -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsGetChallengeKey - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_CHALLENGE_KEY); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.REPORT_KEY.OperationCode = SCSIOP_REPORT_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.REPORT_KEY.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.REPORT_KEY.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.REPORT_KEY.AGID = (UCHAR)(*input); - cdb.REPORT_KEY.KeyFormat = 0x02; // Return a drive certificate challenge - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x52, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x32; // '2' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0054, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_CHALLENGE_KEY); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleSendChallengeKey( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_SEND_CHALLENGE_KEY -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsSendChallengeKey - - NTSTATUS status = STATUS_SUCCESS; - PAACS_SEND_CHALLENGE_KEY input = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_CHALLENGE_KEY); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - // copy the input buffer to the data buffer for the transfer - { - PCDVD_KEY_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG tmp = dataTransferLength; - tmp -= RTL_SIZEOF_THROUGH_FIELD(CDVD_KEY_HEADER, DataLength); - - header->DataLength[0] = (UCHAR)(tmp >> (8*1)); - header->DataLength[1] = (UCHAR)(tmp >> (8*0)); - RtlCopyMemory(header->Data, &(input->ChallengeKey), sizeof(AACS_CHALLENGE_KEY)); - } - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.SEND_KEY.OperationCode = SCSIOP_SEND_KEY; - cdb.AsByte[7] = 0x02; // AACS key class - cdb.SEND_KEY.ParameterListLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.SEND_KEY.ParameterListLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.SEND_KEY.AGID = (UCHAR)( input->SessionId ); - cdb.SEND_KEY.KeyFormat = 0x02; // Send Host Challenge Certificate - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, FALSE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - *DataLength = 0; - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleReadVolumeId( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_READ_VOLUME_ID -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsReadVolumeID - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_VOLUME_ID); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.READ_DVD_STRUCTURE.OperationCode = SCSIOP_READ_DVD_STRUCTURE; - cdb.READ_DVD_STRUCTURE.Format = 0x80; // Return the AACS volumeID - cdb.READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.READ_DVD_STRUCTURE.AGID = (UCHAR)(*input); - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x22, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x33; // '3' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0024, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_VOLUME_ID); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsReadSerialNumber( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_READ_SERIAL_NUMBER -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsReadSerialNumber - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_SERIAL_NUMBER); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.READ_DVD_STRUCTURE.OperationCode = SCSIOP_READ_DVD_STRUCTURE; - cdb.READ_DVD_STRUCTURE.Format = 0x81; // Return the AACS volumeID - cdb.READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.READ_DVD_STRUCTURE.AGID = (UCHAR)(*input); - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x22, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x34; // '4' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0024, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_SERIAL_NUMBER); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsReadMediaId( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_READ_MEDIA_ID -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsReadMediaID - - NTSTATUS status = STATUS_SUCCESS; - PDVD_SESSION_ID input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_MEDIA_ID); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.READ_DVD_STRUCTURE.OperationCode = SCSIOP_READ_DVD_STRUCTURE; - cdb.READ_DVD_STRUCTURE.Format = 0x82; // Return the AACS volumeID - cdb.READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.READ_DVD_STRUCTURE.AGID = (UCHAR)(*input); - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x22, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x35; // '5' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0024, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_MEDIA_ID); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsReadBindingNonce( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_READ_BINDING_NONCE -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsReadBindingNonce - - NTSTATUS status = STATUS_SUCCESS; - PAACS_READ_BINDING_NONCE input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_BINDING_NONCE); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - cdb.REPORT_KEY.OperationCode = SCSIOP_REPORT_KEY; - cdb.REPORT_KEY.LogicalBlockAddress[0] = (UCHAR)( input->StartLba >> (3*8) ); - cdb.REPORT_KEY.LogicalBlockAddress[1] = (UCHAR)( input->StartLba >> (2*8) ); - cdb.REPORT_KEY.LogicalBlockAddress[2] = (UCHAR)( input->StartLba >> (1*8) ); - cdb.REPORT_KEY.LogicalBlockAddress[3] = (UCHAR)( input->StartLba >> (0*8) ); - cdb.AsByte[6] = (UCHAR)( input->NumberOfSectors ); - cdb.AsByte[7] = 0x02; // AACS key class - cdb.REPORT_KEY.AllocationLength[0] = (UCHAR)(dataTransferLength >> (8*1)); - cdb.REPORT_KEY.AllocationLength[1] = (UCHAR)(dataTransferLength >> (8*0)); - cdb.REPORT_KEY.AGID = (UCHAR)( input->SessionId ); - cdb.REPORT_KEY.KeyFormat = 0x21; // Return an existing binding nonce - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x22, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x36; // '6' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0024, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_BINDING_NONCE); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - -_IRQL_requires_max_(APC_LEVEL) -NTSTATUS -DeviceHandleAacsGenerateBindingNonce( - _In_ PCDROM_DEVICE_EXTENSION DeviceExtension, - _In_ WDFREQUEST Request, - _In_ WDF_REQUEST_PARAMETERS RequestParameters, - _Out_ size_t * DataLength - ) -/*++ - -Routine Description: - This routine is used to process IOCTL: - IOCTL_AACS_GENERATE_BINDING_NONCE -Arguments: - DeviceExtension - device context - - Request - the request that will be formatted - - RequestParameters - request parameter structur - - DataLength - data transferred length - -Return Value: - NTSTATUS - - --*/ -{ - //AacsGenerateBindingNonce - - NTSTATUS status = STATUS_SUCCESS; - PAACS_READ_BINDING_NONCE input = NULL; - PVOID outputBuffer = NULL; - - PAGED_CODE(); - - *DataLength = 0; - - status = WdfRequestRetrieveInputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.InputBufferLength, - (PVOID*)&input, - NULL); - - if (NT_SUCCESS(status)) - { - status = WdfRequestRetrieveOutputBuffer(Request, - RequestParameters.Parameters.DeviceIoControl.OutputBufferLength, - (PVOID*)&outputBuffer, - NULL); - } - - if (NT_SUCCESS(status)) - { - ULONG dataTransferLength = sizeof(CDVD_KEY_HEADER) + sizeof(AACS_BINDING_NONCE); - CDB cdb; - - ScratchBuffer_BeginUse(DeviceExtension); - - RtlZeroMemory(&cdb, sizeof(CDB)); - // Set up the CDB - - status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, dataTransferLength, TRUE, &cdb, 12); - -#ifdef ENABLE_AACS_TESTING - static const UCHAR results[] = { 0x00, 0x22, 0x00, 0x00 }; - static const UCHAR defaultFill = 0x37; // '7' - RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x0024, defaultFill); - RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results)); - status = STATUS_SUCCESS; -#endif - if (NT_SUCCESS(status)) - { - PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer; - ULONG dataLengthToCopy = sizeof(AACS_BINDING_NONCE); - - // make length field native byte ordering - REVERSE_SHORT(&header->Length); - - // exit if getting invalid data from the drive - if (header->Length < sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length)) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - - if (NT_SUCCESS(status)) - { - // adjust data length to reflect only the addition data - header->Length -= sizeof(DVD_DESCRIPTOR_HEADER) - RTL_SIZEOF_THROUGH_FIELD(DVD_DESCRIPTOR_HEADER, Length); - - // exit if the drive is returning an unexpected data size - if (header->Length != dataLengthToCopy) - { - *DataLength = 0; - status = STATUS_IO_DEVICE_ERROR; - } - } - - if (NT_SUCCESS(status)) - { - // else copy the data to the user's buffer - RtlCopyMemory(outputBuffer, header->Data, dataLengthToCopy); - *DataLength = dataLengthToCopy; - } - } - - ScratchBuffer_EndUse(DeviceExtension); - } - - return status; -} - |
