summaryrefslogtreecommitdiff
path: root/storage/class/cdrom/src/aacs.c
diff options
context:
space:
mode:
authorkatiezb <[email protected]>2023-03-01 10:34:21 -0800
committerGitHub <[email protected]>2023-03-01 10:34:21 -0800
commite4fec231def3b751b0f717855737317a4a2edbac (patch)
treec6ef0679f8e29d39dc659c8864da3a4239a5c717 /storage/class/cdrom/src/aacs.c
parent800278d3a66158b2f0f7eb6e9ce880bedb54def3 (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.c1481
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;
-}
-