ReactOS 0.4.15-dev-8135-g1bc6c90
aacs.c File Reference
#include "stddef.h"
#include "string.h"
#include "ntddk.h"
#include "ntddstor.h"
#include "cdrom.h"
#include "ioctl.h"
#include "scratch.h"
Include dependency graph for aacs.c:

Go to the source code of this file.

Functions

 _IRQL_requires_max_ (APC_LEVEL)
 

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 54 of file aacs.c.

81{
83 PAACS_LAYER_NUMBER layerNumber = NULL;
84 PVOID outputBuffer = NULL;
85 ULONG transferSize = sizeof(READ_DVD_STRUCTURES_HEADER);
86
87 PAGED_CODE();
88
89 *DataLength = 0;
90
91 status = WdfRequestRetrieveInputBuffer(Request,
93 (PVOID*)&layerNumber,
94 NULL);
95
96 if (NT_SUCCESS(status))
97 {
98 status = WdfRequestRetrieveOutputBuffer(Request,
100 (PVOID*)&outputBuffer,
101 NULL);
102 }
103
104 if (NT_SUCCESS(status))
105 {
107 {
108 // maximum size for this transfer is one pack + header
109 transferSize += AACS_MKB_PACK_SIZE;
110 }
111
112 if (transferSize > DeviceExtension->ScratchContext.ScratchBufferSize)
113 {
114 // rare case. normally the size of scratch buffer is 64k.
116 }
117 }
118
119 if (NT_SUCCESS(status))
120 {
121 UCHAR rmdBlockNumber = 0;
122 BOOLEAN sendChangedCommand = TRUE;
123 BOOLEAN shouldRetry = TRUE;
124 CDB cdb;
125
126 ScratchBuffer_BeginUse(DeviceExtension);
127
128 RtlZeroMemory(&cdb, sizeof(CDB));
129 // Set up the CDB
131 // cdb->AsByte[1] = 0x01; // AACS sub-command not required for this
132
133 cdb.READ_DVD_STRUCTURE.LayerNumber = (UCHAR)(*layerNumber);
134 cdb.READ_DVD_STRUCTURE.Format = 0x83; // MKB
135 cdb.READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(transferSize >> (8*1));
136 cdb.READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(transferSize >> (8*0));
137
138 while (sendChangedCommand)
139 {
140 // RMDBlockNumber is set to zero....
141 // RMDBlockNumber[3] maybe changed for other blocks.
142 cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3] = rmdBlockNumber;
143
144 if (shouldRetry)
145 {
146 status = ScratchBuffer_ExecuteCdb(DeviceExtension, Request, transferSize, TRUE, &cdb, 12);
147 }
148
149 #ifdef ENABLE_AACS_TESTING
151 {
152 static const UCHAR results[] = { 0x80, 0x02, 0x00, 0x02 };
153 RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results));
155 }
157 {
158 static const UCHAR results[] = { 0x80, 0x02, 0x00, 0x02 };
159 static const UCHAR defaultFill = 0x30; // '0'
160 RtlFillMemory(DeviceExtension->ScratchContext.ScratchBuffer, 0x8004, defaultFill);
161 RtlCopyMemory(DeviceExtension->ScratchContext.ScratchBuffer, results, SIZEOF_ARRAY(results));
163 }
164 #endif //ENABLE_AACS_TESTING
165
166 if (NT_SUCCESS(status))
167 {
168 // command succeeded, process data...
169 PDVD_DESCRIPTOR_HEADER header = DeviceExtension->ScratchContext.ScratchBuffer;
170 UCHAR thisPackNumber = cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3];
171 UCHAR otherPacks = header->Reserved[1];
172
173 // validate and zero-base the otherPacks
174 if (otherPacks == 0)
175 {
176 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT,
177 "AACS: Device is reporting zero total packs (invalid)\n"));
178 *DataLength = 0;
180 }
181 else
182 {
183 otherPacks--;
184
186 {
187 // if not already requested last pack, do so now
188 if (otherPacks != thisPackNumber)
189 {
190 // re-send the command for the other pack number.
191 // this is safe here because NT_SUCCESS() is TRUE,
192 // and all the rest of this routine does is SetHardError()
193 // and release of resources we're still about to use.
194
195 // re-zero the output buffer
196 RtlZeroMemory(DeviceExtension->ScratchContext.ScratchBuffer, sizeof(READ_DVD_STRUCTURES_HEADER));
197
198 // modify the CDB to get the very last pack of the MKB
199 rmdBlockNumber = otherPacks;
200
201 transferSize = sizeof(READ_DVD_STRUCTURES_HEADER);
202
203 // keep items clean
204 ScratchBuffer_ResetItems(DeviceExtension, TRUE);
205
206 // make sure the loop will be executed for modified command.
207 sendChangedCommand = TRUE;
208 shouldRetry = TRUE;
209 }
210 else
211 {
212 // this request already got the last pack
213 // so just interpret the data
214 REVERSE_SHORT(&header->Length);
216 {
217 *DataLength = 0;
219 }
220 else
221 {
222 ULONG totalSize = header->Length;
223 // subtract out any remaining bytes in the header
224 // to get the number of usable bytes in this pack
226 totalSize += otherPacks * AACS_MKB_PACK_SIZE;
227
228 // save the result and complete the request
229 *((PULONG)outputBuffer) = totalSize;
230 *DataLength = sizeof(ULONG);
232 }
233 // This will exit the loop of sendChangedCommand
234 sendChangedCommand = FALSE;
235 shouldRetry = FALSE;
236 }
237 }
239 {
240 // make length field native byte ordering
241 REVERSE_SHORT(&header->Length);
242
243 // exit if getting invalid data from the drive
245 {
246 *DataLength = 0;
248 }
249 else
250 {
251 // success, how many bytes to copy for this pack?
252 ULONG totalSize = header->Length;
253 size_t originalBufferSize;
254
255 // subtract out any remaining bytes in the header
256 // to get the number of usable bytes in this pack
258
259 // if not the final pack, this should be a full transfer per spec
260 NT_ASSERT( (totalSize == AACS_MKB_PACK_SIZE) || (thisPackNumber == otherPacks) );
261
262 // validate the user's buffer is large enough to accept the full data
263 originalBufferSize = RequestParameters.Parameters.DeviceIoControl.OutputBufferLength;
264
265 if (originalBufferSize < (totalSize + (AACS_MKB_PACK_SIZE*thisPackNumber)))
266 {
267 // just return a slightly bigger-than-normal size
268 *DataLength = (otherPacks + 1)*AACS_MKB_PACK_SIZE;
270 }
271 else
272 {
273 PUCHAR whereToCopy;
274 // determine where to copy to the user's memory
275 whereToCopy = outputBuffer;
276 whereToCopy += AACS_MKB_PACK_SIZE * thisPackNumber;
277
278 RtlCopyMemory(whereToCopy, header->Data, totalSize);
279
280 // update the Information field here because we already
281 // have calculated the size of the block
282 *DataLength = totalSize + (AACS_MKB_PACK_SIZE * thisPackNumber);
284
285 // if there are more packs to get from the device, send it again....
286 if (thisPackNumber != otherPacks)
287 {
288 // re-send the command for the next pack number.
289 // this is safe here because NT_SUCCESS() is TRUE,
290 // and all the rest of this routine does is SetHardError()
291 // and release of resources we're still about to use.
292
293 // re-zero the output buffer
294 RtlZeroMemory(DeviceExtension->ScratchContext.ScratchBuffer, sizeof(READ_DVD_STRUCTURES_HEADER));
295
296 // modify the CDB to get the next pack of the MKB
297 rmdBlockNumber = cdb.READ_DVD_STRUCTURE.RMDBlockNumber[3]++;
298
299 // modify the SRB to be resent
300 //
301 transferSize = AACS_MKB_PACK_SIZE + sizeof(READ_DVD_STRUCTURES_HEADER);
302
303 // keep items clean
304 ScratchBuffer_ResetItems(DeviceExtension, FALSE);
305
306 // make sure the loop will be executed for modified command.
307 sendChangedCommand = TRUE;
308 shouldRetry = TRUE;
309 }
310 else
311 {
312 // else, that was the end of the transfer, so just complete the request
313 sendChangedCommand = FALSE;
314 }
315 }
316 }
317
318 } // end of IOCTL_AACS_READ_MEDIA_KEY_BLOCK
319 }
320 } // end of NT_SUCCESS(status)
321
322 if (!NT_SUCCESS(status))
323 {
324 // command failed.
325 sendChangedCommand = FALSE;
326 }
327 } //end of while (sendChangedCommand)
328
329 ScratchBuffer_EndUse(DeviceExtension);
330 }
331
332 return status;
333}
#define PAGED_CODE()
unsigned char BOOLEAN
static struct _test_info results[8]
Definition: SetCursorPos.c:31
LONG NTSTATUS
Definition: precomp.h:26
#define SIZEOF_ARRAY(ar)
Definition: cdrom.h:1482
#define AACS_MKB_PACK_SIZE
Definition: cdrom.h:764
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define SCSIOP_READ_DVD_STRUCTURE
Definition: cdrw_hw.h:960
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:138
struct _DVD_DESCRIPTOR_HEADER DVD_DESCRIPTOR_HEADER
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define IOCTL_AACS_READ_MEDIA_KEY_BLOCK
Definition: ntddcdvd.h:61
#define IOCTL_AACS_READ_MEDIA_KEY_BLOCK_SIZE
Definition: ntddcdvd.h:58
* PAACS_LAYER_NUMBER
Definition: ntddcdvd.h:255
VOID ScratchBuffer_ResetItems(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
Definition: scratch.c:343
FORCEINLINE VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: scratch.h:104
#define ScratchBuffer_BeginUse(context)
Definition: scratch.h:87
struct _READ_DVD_STRUCTURES_HEADER READ_DVD_STRUCTURES_HEADER
#define REVERSE_SHORT(Short)
Definition: scsi.h:3481
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
union _WDF_REQUEST_PARAMETERS::@3886 Parameters
struct _WDF_REQUEST_PARAMETERS::@3886::@3890 DeviceIoControl
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
Definition: cdrw_hw.h:28
struct _CDB::_READ_DVD_STRUCTURE READ_DVD_STRUCTURE
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define NT_ASSERT
Definition: rtlfuncs.h:3310
unsigned char UCHAR
Definition: xmlstorage.h:181