ReactOS  0.4.13-dev-73-gcfe54aa
ioctl.c
Go to the documentation of this file.
1 /*--
2 
3 Copyright (C) Microsoft Corporation, 1999 - 1999
4 
5 Module Name:
6 
7  ioctl.c
8 
9 Abstract:
10 
11  The CDROM class driver tranlates IRPs to SRBs with embedded CDBs
12  and sends them to its devices through the port driver.
13 
14 Environment:
15 
16  kernel mode only
17 
18 Notes:
19 
20  SCSI Tape, CDRom and Disk class drivers share common routines
21  that can be found in the CLASS directory (..\ntos\dd\class).
22 
23 Revision History:
24 
25 --*/
26 
27 #include "cdrom.h"
28 
29 #if DBG
30  PUCHAR READ_DVD_STRUCTURE_FORMAT_STRINGS[DvdMaxDescriptor+1] = {
31  "Physical",
32  "Copyright",
33  "DiskKey",
34  "BCA",
35  "Manufacturer",
36  "Unknown"
37  };
38 #endif // DBG
39 
40 #define DEFAULT_CDROM_SECTORS_PER_TRACK 32
41 #define DEFAULT_TRACKS_PER_CYLINDER 64
42 
44 NTAPI
47  IN PIRP Irp
48  )
49 /*++
50 
51 Routine Description:
52 
53  This is the NT device control handler for CDROMs.
54 
55 Arguments:
56 
57  DeviceObject - for this CDROM
58 
59  Irp - IO Request packet
60 
61 Return Value:
62 
63  NTSTATUS
64 
65 --*/
66 {
69 
71  PIO_STACK_LOCATION nextStack;
72  PCDROM_DATA cdData = (PCDROM_DATA)(commonExtension->DriverData);
73 
74  //BOOLEAN use6Byte = TEST_FLAG(cdData->XAFlags, XA_USE_6_BYTE);
76  PCDB cdb = (PCDB)srb.Cdb;
77  //PVOID outputBuffer;
78  //ULONG bytesTransferred = 0;
80  //NTSTATUS status2;
81  KIRQL irql;
82 
83  ULONG ioctlCode;
84  ULONG baseCode;
85  ULONG functionCode;
86 
87 RetryControl:
88 
89  //
90  // Zero the SRB on stack.
91  //
92 
93  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
94 
95  Irp->IoStatus.Information = 0;
96 
97  //
98  // if this is a class driver ioctl then we need to change the base code
99  // to IOCTL_CDROM_BASE so that the switch statement can handle it.
100  //
101  // WARNING - currently the scsi class ioctl function codes are between
102  // 0x200 & 0x300. this routine depends on that fact
103  //
104 
105  ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
106  baseCode = ioctlCode >> 16;
107  functionCode = (ioctlCode & (~0xffffc003)) >> 2;
108 
110  "CdRomDeviceControl: Ioctl Code = %lx, Base Code = %lx,"
111  " Function Code = %lx\n",
112  ioctlCode,
113  baseCode,
114  functionCode
115  ));
116 
117  if((functionCode >= 0x200) && (functionCode <= 0x300)) {
118 
119  ioctlCode = (ioctlCode & 0x0000ffff) | CTL_CODE(IOCTL_CDROM_BASE, 0, 0, 0);
120 
122  "CdRomDeviceControl: Class Code - new ioctl code is %lx\n",
123  ioctlCode));
124 
125  irpStack->Parameters.DeviceIoControl.IoControlCode = ioctlCode;
126 
127  }
128 
129  switch (ioctlCode) {
130 
132 
133  PGET_MEDIA_TYPES mediaTypes = Irp->AssociatedIrp.SystemBuffer;
134  PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
135  ULONG sizeNeeded;
136 
137  sizeNeeded = sizeof(GET_MEDIA_TYPES);
138 
139  //
140  // IsMmc is static...
141  //
142 
143  if (cdData->Mmc.IsMmc) {
144  sizeNeeded += sizeof(DEVICE_MEDIA_INFO) * 1; // return two media types
145  }
146 
147  //
148  // Ensure that buffer is large enough.
149  //
150 
151  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
152  sizeNeeded) {
153 
154  //
155  // Buffer too small.
156  //
157 
158  Irp->IoStatus.Information = sizeNeeded;
160  break;
161  }
162 
163  RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, sizeNeeded);
164 
165  //
166  // ISSUE-2000/5/11-henrygab - need to update GET_MEDIA_TYPES_EX
167  //
168 
170 
171  mediaTypes->MediaInfoCount = 1;
172  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = CD_ROM;
173  mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
174  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_ONLY;
175  mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
176  mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
177  mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
178  mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
179 
180  if (cdData->Mmc.IsMmc) {
181 
182  //
183  // also report a removable disk
184  //
185  mediaTypes->MediaInfoCount += 1;
186 
187  mediaInfo++;
188  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = RemovableMedia;
189  mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
190  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
191  mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
192  mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
193  mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
194  mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
195  mediaInfo--;
196 
197  }
198 
199  //
200  // Status will either be success, if media is present, or no media.
201  // It would be optimal to base from density code and medium type, but not all devices
202  // have values for these fields.
203  //
204 
205  //
206  // Send a TUR to determine if media is present.
207  //
208 
209  srb.CdbLength = 6;
210  cdb = (PCDB)srb.Cdb;
211  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
212 
213  //
214  // Set timeout value.
215  //
216 
217  srb.TimeOutValue = fdoExtension->TimeOutValue;
218 
220  &srb,
221  NULL,
222  0,
223  FALSE);
224 
225 
227  "CdRomDeviceControl: GET_MEDIA_TYPES status of TUR - %lx\n",
228  status));
229 
230  if (NT_SUCCESS(status)) {
231 
232  //
233  // set the disk's media as current if we can write to it.
234  //
235 
236  if (cdData->Mmc.IsMmc && cdData->Mmc.WriteAllowed) {
237 
238  mediaInfo++;
239  SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
241  mediaInfo--;
242 
243 
244  } else {
245 
246  SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
248 
249  }
250 
251  }
252 
253  Irp->IoStatus.Information = sizeNeeded;
255  break;
256  }
257 
258 
259  case IOCTL_CDROM_RAW_READ: {
260 
261  LARGE_INTEGER startingOffset;
262  ULONGLONG transferBytes;
263  ULONGLONG endOffset;
264  ULONGLONG mdlBytes;
265  //ULONG startingSector;
266  PRAW_READ_INFO rawReadInfo = (PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
267 
268  //
269  // Ensure that XA reads are supported.
270  //
271 
272  if (TEST_FLAG(cdData->XAFlags, XA_NOT_SUPPORTED)) {
274  "CdRomDeviceControl: XA Reads not supported. Flags (%x)\n",
275  cdData->XAFlags));
277  break;
278  }
279 
280  //
281  // Check that ending sector is on disc and buffers are there and of
282  // correct size.
283  //
284 
285  if (rawReadInfo == NULL) {
286 
287  //
288  // Called from user space. Save the userbuffer in the
289  // Type3InputBuffer so we can reduce the number of code paths.
290  //
291 
292  irpStack->Parameters.DeviceIoControl.Type3InputBuffer =
293  Irp->AssociatedIrp.SystemBuffer;
294 
295  //
296  // Called from user space. Validate the buffers.
297  //
298 
299  rawReadInfo = (PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
300 
301  if (rawReadInfo == NULL) {
302 
304  "CdRomDeviceControl: Invalid I/O parameters for "
305  "XA Read (No extent info\n"));
307  break;
308 
309  }
310 
311  if (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
312  sizeof(RAW_READ_INFO)) {
313 
315  "CdRomDeviceControl: Invalid I/O parameters for "
316  "XA Read (Invalid info buffer\n"));
318  break;
319 
320  }
321  }
322 
323  //
324  // if they don't request any data, just fail the request
325  //
326 
327  if (rawReadInfo->SectorCount == 0) {
328 
330  break;
331 
332  }
333 
334  startingOffset.QuadPart = rawReadInfo->DiskOffset.QuadPart;
335  /* startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >>
336  fdoExtension->SectorShift); */
337  transferBytes = (ULONGLONG)rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
338 
339  endOffset = (ULONGLONG)rawReadInfo->SectorCount * COOKED_SECTOR_SIZE;
340  endOffset += startingOffset.QuadPart;
341 
342  //
343  // check for overflows....
344  //
345 
346  if (transferBytes < (ULONGLONG)(rawReadInfo->SectorCount)) {
348  "CdRomDeviceControl: Invalid I/O parameters for XA "
349  "Read (TransferBytes Overflow)\n"));
351  break;
352  }
353  if (endOffset < (ULONGLONG)startingOffset.QuadPart) {
355  "CdRomDeviceControl: Invalid I/O parameters for XA "
356  "Read (EndingOffset Overflow)\n"));
358  break;
359  }
360  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
361  transferBytes) {
363  "CdRomDeviceControl: Invalid I/O parameters for XA "
364  "Read (Bad buffer size)\n"));
366  break;
367  }
368  if (endOffset > (ULONGLONG)commonExtension->PartitionLength.QuadPart) {
370  "CdRomDeviceControl: Invalid I/O parameters for XA "
371  "Read (Request Out of Bounds)\n"));
373  break;
374  }
375 
376  //
377  // cannot validate the MdlAddress, since it is not included in any
378  // other location per the DDK and file system calls.
379  //
380 
381  //
382  // validate the mdl describes at least the number of bytes
383  // requested from us.
384  //
385 
386  mdlBytes = (ULONGLONG)MmGetMdlByteCount(Irp->MdlAddress);
387  if (mdlBytes < transferBytes) {
389  "CdRomDeviceControl: Invalid MDL %s, Irp %p\n",
390  "size (5)", Irp));
392  break;
393  }
394 
395  //
396  // HACKHACK - REF #0001
397  // The retry count will be in this irp's IRP_MN function,
398  // as the new irp was freed, and we therefore cannot use
399  // this irp's next stack location for this function.
400  // This may be a good location to store this info for
401  // when we remove RAW_READ (mode switching), as we will
402  // no longer have the nextIrpStackLocation to play with
403  // when that occurs
404  //
405  // once XA_READ is removed, then this hack can also be
406  // removed.
407  //
408  irpStack->MinorFunction = MAXIMUM_RETRIES; // HACKHACK - REF #0001
409 
412 
413  return STATUS_PENDING;
414  }
415 
419  "CdRomDeviceControl: Get drive geometryEx\n"));
420  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
423  Irp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
424  break;
425  }
428  return STATUS_PENDING;
429  }
430 
433 
435  "CdRomDeviceControl: Get drive geometry\n"));
436 
437  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
438  sizeof( DISK_GEOMETRY ) ) {
439 
441  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
442  break;
443  }
444 
447 
448  return STATUS_PENDING;
449  }
450 
452 
453  PCDROM_READ_TOC_EX inputBuffer;
454 
457  break;
458  }
459 
460  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
461  sizeof(CDROM_READ_TOC_EX)) {
463  break;
464  }
465 
466  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
469  Irp->IoStatus.Information = MINIMUM_CDROM_READ_TOC_EX_SIZE;
470  break;
471  }
472 
473  if (irpStack->Parameters.Read.Length > ((USHORT)-1)) {
475  break;
476  }
477 
478  inputBuffer = Irp->AssociatedIrp.SystemBuffer;
479 
480  if ((inputBuffer->Reserved1 != 0) ||
481  (inputBuffer->Reserved2 != 0) ||
482  (inputBuffer->Reserved3 != 0)) {
484  break;
485  }
486 
487  //
488  // NOTE: when adding new formats, ensure that first two bytes
489  // specify the amount of additional data available.
490  //
491 
492  if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_TOC ) ||
493  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_FULL_TOC) ||
494  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_CDTEXT )) {
495 
496  // SessionTrack field is used
497 
498  } else
499  if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
500  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_PMA) ||
501  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_ATIP)) {
502 
503  // SessionTrack field is reserved
504 
505  if (inputBuffer->SessionTrack != 0) {
507  break;
508  }
509 
510  } else {
512  break;
513  }
514 
517  return STATUS_PENDING;
518  }
519 
521 
522  //
523  // If the cd is playing music then reject this request.
524  //
525 
528  break;
529  }
530 
531  //
532  // Make sure the caller is requesting enough data to make this worth
533  // our while.
534  //
535 
536  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
537  sizeof(CDROM_TOC_SESSION_DATA)) {
538 
539  //
540  // they didn't request the entire TOC -- use _EX version
541  // for partial transfers and such.
542  //
543 
545  Irp->IoStatus.Information = sizeof(CDROM_TOC_SESSION_DATA);
546  break;
547  }
548 
551 
552  return STATUS_PENDING;
553  }
554 
555  case IOCTL_CDROM_READ_TOC: {
556 
557  //
558  // If the cd is playing music then reject this request.
559  //
560 
563  break;
564  }
565 
566  //
567  // Make sure the caller is requesting enough data to make this worth
568  // our while.
569  //
570 
571  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
572  sizeof(CDROM_TOC)) {
573 
574  //
575  // they didn't request the entire TOC -- use _EX version
576  // for partial transfers and such.
577  //
578 
580  Irp->IoStatus.Information = sizeof(CDROM_TOC);
581  break;
582  }
583 
586 
587  return STATUS_PENDING;
588  }
589 
591 
592  //
593  // Play Audio MSF
594  //
595 
597  "CdRomDeviceControl: Play audio MSF\n"));
598 
599  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
600  sizeof(CDROM_PLAY_AUDIO_MSF)) {
601 
602  //
603  // Indicate unsuccessful status.
604  //
605 
607  break;
608  }
609 
612 
613  return STATUS_PENDING;
614  }
615 
617 
618 
619  //
620  // Seek Audio MSF
621  //
622 
624  "CdRomDeviceControl: Seek audio MSF\n"));
625 
626  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
627  sizeof(CDROM_SEEK_AUDIO_MSF)) {
628 
629  //
630  // Indicate unsuccessful status.
631  //
632 
634  break;
635  }
636 
639  return STATUS_PENDING;
640 
641  }
642 
644 
645  //
646  // Pause audio
647  //
648 
650  "CdRomDeviceControl: Pause audio\n"));
651 
654 
655  return STATUS_PENDING;
656 
657  break;
658  }
659 
661 
662  //
663  // Resume audio
664  //
665 
667  "CdRomDeviceControl: Resume audio\n"));
668 
671 
672  return STATUS_PENDING;
673  }
674 
676 
677  PCDROM_SUB_Q_DATA_FORMAT inputBuffer =
678  Irp->AssociatedIrp.SystemBuffer;
679 
680  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
681  sizeof(CDROM_SUB_Q_DATA_FORMAT)) {
682 
684  break;
685  }
686 
687  //
688  // check for all valid types of request
689  //
690 
691  if (inputBuffer->Format != IOCTL_CDROM_CURRENT_POSITION &&
692  inputBuffer->Format != IOCTL_CDROM_MEDIA_CATALOG &&
693  inputBuffer->Format != IOCTL_CDROM_TRACK_ISRC ) {
695  Irp->IoStatus.Information = 0;
696  break;
697  }
698 
701 
702  return STATUS_PENDING;
703  }
704 
706 
708  "CdRomDeviceControl: Get audio control\n"));
709 
710  //
711  // Verify user buffer is large enough for the data.
712  //
713 
714  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
715  sizeof(CDROM_AUDIO_CONTROL)) {
716 
717  //
718  // Indicate unsuccessful status and no data transferred.
719  //
720 
722  Irp->IoStatus.Information = sizeof(CDROM_AUDIO_CONTROL);
723  break;
724 
725  }
726 
729 
730  return STATUS_PENDING;
731  }
732 
733  case IOCTL_CDROM_GET_VOLUME: {
734 
736  "CdRomDeviceControl: Get volume control\n"));
737 
738  //
739  // Verify user buffer is large enough for data.
740  //
741 
742  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
743  sizeof(VOLUME_CONTROL)) {
744 
745  //
746  // Indicate unsuccessful status and no data transferred.
747  //
748 
750  Irp->IoStatus.Information = sizeof(VOLUME_CONTROL);
751  break;
752 
753  }
754 
757 
758  return STATUS_PENDING;
759  }
760 
761  case IOCTL_CDROM_SET_VOLUME: {
762 
764  "CdRomDeviceControl: Set volume control\n"));
765 
766  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
767  sizeof(VOLUME_CONTROL)) {
768 
769  //
770  // Indicate unsuccessful status.
771  //
772 
774  break;
775 
776  }
777 
780 
781  return STATUS_PENDING;
782  }
783 
784  case IOCTL_CDROM_STOP_AUDIO: {
785 
786  //
787  // Stop play.
788  //
789 
791  "CdRomDeviceControl: Stop audio\n"));
792 
795 
796  return STATUS_PENDING;
797  }
798 
802 
804  "CdRomDeviceControl: [%p] Check Verify\n", Irp));
805 
806  if((irpStack->Parameters.DeviceIoControl.OutputBufferLength) &&
807  (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))) {
808 
810  "CdRomDeviceControl: Check Verify: media count "
811  "buffer too small\n"));
812 
814  Irp->IoStatus.Information = sizeof(ULONG);
815  break;
816  }
817 
820 
821  return STATUS_PENDING;
822  }
823 
825 
827  "DvdDeviceControl: [%p] IOCTL_DVD_READ_STRUCTURE\n", Irp));
828 
829  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
831  "DvdDeviceControl: License Failure\n"));
833  break;
834  }
835 
836  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
837  //
838  // if currently in-progress, this will just return.
839  // prevents looping by doing that interlockedExchange()
840  //
842  "DvdDeviceControl: PickRegion() from "
843  "READ_STRUCTURE\n"));
845  }
846 
847 
848  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
849  sizeof(DVD_READ_STRUCTURE)) {
850 
852  "DvdDeviceControl - READ_STRUCTURE: input buffer "
853  "length too small (was %d should be %d)\n",
854  irpStack->Parameters.DeviceIoControl.InputBufferLength,
855  sizeof(DVD_READ_STRUCTURE)));
857  break;
858  }
859 
860  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
861  sizeof(READ_DVD_STRUCTURES_HEADER)) {
862 
864  "DvdDeviceControl - READ_STRUCTURE: output buffer "
865  "cannot hold header information\n"));
867  Irp->IoStatus.Information = sizeof(READ_DVD_STRUCTURES_HEADER);
868  break;
869  }
870 
871  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength >
872  MAXUSHORT) {
873 
874  //
875  // key length must fit in two bytes
876  //
878  "DvdDeviceControl - READ_STRUCTURE: output buffer "
879  "too large\n"));
881  break;
882  }
883 
886 
887  return STATUS_PENDING;
888  }
889 
891 
893  "DvdDeviceControl: [%p] IOCTL_DVD_START_SESSION\n", Irp));
894 
895  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
897  "DvdDeviceControl: License Failure\n"));
899  break;
900  }
901 
902  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
903  sizeof(DVD_SESSION_ID)) {
904 
906  "DvdDeviceControl: DVD_START_SESSION - output "
907  "buffer too small\n"));
909  Irp->IoStatus.Information = sizeof(DVD_SESSION_ID);
910  break;
911  }
912 
915 
916  return STATUS_PENDING;
917  }
918 
919  case IOCTL_DVD_SEND_KEY:
920  case IOCTL_DVD_SEND_KEY2: {
921 
922  PDVD_COPY_PROTECT_KEY key = Irp->AssociatedIrp.SystemBuffer;
923  //ULONG keyLength;
924 
926  "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY\n", Irp));
927 
928  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
930  "DvdDeviceControl: License Failure\n"));
932  break;
933  }
934 
935  if((irpStack->Parameters.DeviceIoControl.InputBufferLength <
936  sizeof(DVD_COPY_PROTECT_KEY)) ||
937  (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
938  key->KeyLength)) {
939 
940  //
941  // Key is too small to have a header or the key length doesn't
942  // match the input buffer length. Key must be invalid
943  //
944 
946  "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY - "
947  "key is too small or does not match KeyLength\n",
948  Irp));
950  break;
951  }
952 
953  //
954  // allow only certain key type (non-destructive) to go through
955  // IOCTL_DVD_SEND_KEY (which only requires READ access to the device
956  //
957  if (ioctlCode == IOCTL_DVD_SEND_KEY) {
958 
959  if ((key->KeyType != DvdChallengeKey) &&
960  (key->KeyType != DvdBusKey2) &&
961  (key->KeyType != DvdInvalidateAGID)) {
962 
964  break;
965  }
966  }
967 
968  if (cdData->DvdRpc0Device) {
969 
970  if (key->KeyType == DvdSetRpcKey) {
971 
972  PDVD_SET_RPC_KEY rpcKey = (PDVD_SET_RPC_KEY) key->KeyData;
973 
974  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
976 
978  break;
979  }
980 
981  //
982  // we have a request to set region code
983  // on a RPC0 device which doesn't support
984  // region coding.
985  //
986  // we have to fake it.
987  //
988 
990  &cdData->Rpc0RegionMutex,
991  UserRequest,
992  KernelMode,
993  FALSE,
994  NULL
995  );
996 
997  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
998  //
999  // if currently in-progress, this will just return.
1000  // prevents looping by doing that interlockedExchange()
1001  //
1003  "DvdDeviceControl: PickRegion() from "
1004  "SEND_KEY\n"));
1006  }
1007 
1008  if (cdData->Rpc0SystemRegion == rpcKey->PreferredDriveRegionCode) {
1009 
1010  //
1011  // nothing to change
1012  //
1014  "DvdDeviceControl (%p) => not changing "
1015  "regions -- requesting current region\n",
1016  DeviceObject));
1018 
1019  } else if (cdData->Rpc0SystemRegionResetCount == 0) {
1020 
1021  //
1022  // not allowed to change it again
1023  //
1024 
1026  "DvdDeviceControl (%p) => no more region "
1027  "changes are allowed for this device\n",
1028  DeviceObject));
1030 
1031  } else {
1032 
1033  //ULONG i;
1034  UCHAR mask;
1035  ULONG bufferLen;
1036  PDVD_READ_STRUCTURE dvdReadStructure;
1037  PDVD_COPYRIGHT_DESCRIPTOR dvdCopyRight;
1038  IO_STATUS_BLOCK ioStatus;
1039  UCHAR mediaRegionData;
1040 
1041  mask = ~rpcKey->PreferredDriveRegionCode;
1042 
1043  if (CountOfSetBitsUChar(mask) != 1) {
1044 
1046  break;
1047  }
1048 
1049  //
1050  // this test will always be TRUE except during initial
1051  // automatic selection of the first region.
1052  //
1053 
1054  if (cdData->Rpc0SystemRegion != 0xff) {
1055 
1056  //
1057  // make sure we have a media in the drive with the same
1058  // region code if the drive is already has a region set
1059  //
1060 
1062  "DvdDeviceControl (%p) => Checking "
1063  "media region\n",
1064  DeviceObject));
1065 
1066  bufferLen = max(sizeof(DVD_DESCRIPTOR_HEADER) +
1067  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1068  sizeof(DVD_READ_STRUCTURE)
1069  );
1070 
1071  dvdReadStructure = (PDVD_READ_STRUCTURE)
1073  bufferLen,
1075 
1076  if (dvdReadStructure == NULL) {
1079  break;
1080  }
1081 
1082  dvdCopyRight = (PDVD_COPYRIGHT_DESCRIPTOR)
1083  ((PDVD_DESCRIPTOR_HEADER) dvdReadStructure)->Data;
1084 
1085  //
1086  // check to see if we have a DVD device
1087  //
1088 
1089  RtlZeroMemory (dvdReadStructure, bufferLen);
1090  dvdReadStructure->Format = DvdCopyrightDescriptor;
1091 
1092  //
1093  // Build a request for READ_KEY
1094  //
1097  DeviceObject,
1098  dvdReadStructure,
1099  sizeof(DVD_READ_STRUCTURE),
1100  sizeof(DVD_DESCRIPTOR_HEADER) +
1101  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1102  FALSE,
1103  &ioStatus);
1104 
1105  //
1106  // this is just to prevent bugs from creeping in
1107  // if status is not set later in development
1108  //
1109 
1110  status = ioStatus.Status;
1111 
1112  //
1113  // handle errors
1114  //
1115 
1116  if (!NT_SUCCESS(status)) {
1118  ExFreePool(dvdReadStructure);
1120  break;
1121  }
1122 
1123  //
1124  // save the mediaRegionData before freeing the
1125  // allocated memory
1126  //
1127 
1128  mediaRegionData =
1129  dvdCopyRight->RegionManagementInformation;
1130  ExFreePool(dvdReadStructure);
1131 
1133  "DvdDeviceControl (%p) => new mask is %x"
1134  " MediaRegionData is %x\n", DeviceObject,
1135  rpcKey->PreferredDriveRegionCode,
1136  mediaRegionData));
1137 
1138  //
1139  // the media region must match the requested region
1140  // for RPC0 drives for initial region selection
1141  //
1142 
1143  if (((UCHAR)~(mediaRegionData | rpcKey->PreferredDriveRegionCode)) == 0) {
1146  break;
1147  }
1148 
1149  }
1150 
1151  //
1152  // now try to set the region
1153  //
1154 
1156  "DvdDeviceControl (%p) => Soft-Setting "
1157  "region of RPC1 device to %x\n",
1158  DeviceObject,
1159  rpcKey->PreferredDriveRegionCode
1160  ));
1161 
1163  rpcKey->PreferredDriveRegionCode);
1164 
1165  if (!NT_SUCCESS(status)) {
1167  "DvdDeviceControl (%p) => Could not "
1168  "set region code (%x)\n",
1170  ));
1171  } else {
1172 
1174  "DvdDeviceControl (%p) => New region set "
1175  " for RPC1 drive\n", DeviceObject));
1176 
1177  //
1178  // if it worked, our extension is already updated.
1179  // release the mutex
1180  //
1181 
1182  DebugPrint ((4, "DvdDeviceControl (%p) => DVD current "
1183  "region bitmap 0x%x\n", DeviceObject,
1184  cdData->Rpc0SystemRegion));
1185  DebugPrint ((4, "DvdDeviceControl (%p) => DVD region "
1186  " reset Count 0x%x\n", DeviceObject,
1187  cdData->Rpc0SystemRegionResetCount));
1188  }
1189 
1190  }
1191 
1193  break;
1194  } // end of key->KeyType == DvdSetRpcKey
1195  } // end of Rpc0Device hacks
1196 
1199  return STATUS_PENDING;
1200  }
1201 
1202  case IOCTL_DVD_READ_KEY: {
1203 
1204  PDVD_COPY_PROTECT_KEY keyParameters = Irp->AssociatedIrp.SystemBuffer;
1205  ULONG keyLength;
1206 
1208  "DvdDeviceControl: [%p] IOCTL_DVD_READ_KEY\n", Irp));
1209 
1210  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1212  "DvdDeviceControl: License Failure\n"));
1214  break;
1215  }
1216 
1217  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
1219  "DvdDeviceControl: PickRegion() from READ_KEY\n"));
1221  }
1222 
1223 
1224  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1225  sizeof(DVD_COPY_PROTECT_KEY)) {
1226 
1228  "DvdDeviceControl: EstablishDriveKey - challenge "
1229  "key buffer too small\n"));
1230 
1232  break;
1233 
1234  }
1235 
1236 
1237  switch(keyParameters->KeyType) {
1238 
1239  case DvdChallengeKey:
1240  keyLength = DVD_CHALLENGE_KEY_LENGTH;
1241  break;
1242 
1243  case DvdBusKey1:
1244  case DvdBusKey2:
1245 
1246  keyLength = DVD_BUS_KEY_LENGTH;
1247  break;
1248 
1249  case DvdTitleKey:
1250  keyLength = DVD_TITLE_KEY_LENGTH;
1251  break;
1252 
1253  case DvdAsf:
1254  keyLength = DVD_ASF_LENGTH;
1255  break;
1256 
1257  case DvdDiskKey:
1258  keyLength = DVD_DISK_KEY_LENGTH;
1259  break;
1260 
1261  case DvdGetRpcKey:
1262  keyLength = DVD_RPC_KEY_LENGTH;
1263  break;
1264 
1265  default:
1266  keyLength = sizeof(DVD_COPY_PROTECT_KEY);
1267  break;
1268  }
1269 
1270  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1271  keyLength) {
1272 
1274  "DvdDeviceControl: EstablishDriveKey - output "
1275  "buffer too small\n"));
1277  Irp->IoStatus.Information = keyLength;
1278  break;
1279  }
1280 
1281  if (keyParameters->KeyType == DvdGetRpcKey) {
1282 
1284  }
1285 
1286  if ((keyParameters->KeyType == DvdGetRpcKey) &&
1287  (cdData->DvdRpc0Device)) {
1288 
1289  PDVD_RPC_KEY rpcKey;
1290  rpcKey = (PDVD_RPC_KEY)keyParameters->KeyData;
1291  RtlZeroMemory (rpcKey, sizeof (*rpcKey));
1292 
1294  &cdData->Rpc0RegionMutex,
1295  UserRequest,
1296  KernelMode,
1297  FALSE,
1298  NULL
1299  );
1300 
1301  //
1302  // make up the data
1303  //
1305  rpcKey->ManufacturerResetsAvailable = 0;
1306  if (cdData->Rpc0SystemRegion == 0xff) {
1307  rpcKey->TypeCode = 0;
1308  } else {
1309  rpcKey->TypeCode = 1;
1310  }
1311  rpcKey->RegionMask = (UCHAR) cdData->Rpc0SystemRegion;
1312  rpcKey->RpcScheme = 1;
1313 
1315  &cdData->Rpc0RegionMutex,
1316  FALSE
1317  );
1318 
1319  Irp->IoStatus.Information = DVD_RPC_KEY_LENGTH;
1321  break;
1322 
1323  } else if (keyParameters->KeyType == DvdDiskKey) {
1324 
1325  PDVD_COPY_PROTECT_KEY keyHeader;
1326  PDVD_READ_STRUCTURE readStructureRequest;
1327 
1328  //
1329  // Special case - build a request to get the dvd structure
1330  // so we can get the disk key.
1331  //
1332 
1333  //
1334  // save the key header so we can restore the interesting
1335  // parts later
1336  //
1337 
1338  keyHeader = ExAllocatePoolWithTag(NonPagedPool,
1339  sizeof(DVD_COPY_PROTECT_KEY),
1341 
1342  if(keyHeader == NULL) {
1343 
1344  //
1345  // Can't save the context so return an error
1346  //
1347 
1349  "DvdDeviceControl - READ_KEY: unable to "
1350  "allocate context\n"));
1352  break;
1353  }
1354 
1355  RtlCopyMemory(keyHeader,
1356  Irp->AssociatedIrp.SystemBuffer,
1357  sizeof(DVD_COPY_PROTECT_KEY));
1358 
1360 
1361  nextStack = IoGetNextIrpStackLocation(Irp);
1362 
1363  nextStack->Parameters.DeviceIoControl.IoControlCode =
1365 
1366  readStructureRequest = Irp->AssociatedIrp.SystemBuffer;
1367  readStructureRequest->Format = DvdDiskKeyDescriptor;
1368  readStructureRequest->BlockByteOffset.QuadPart = 0;
1369  readStructureRequest->LayerNumber = 0;
1370  readStructureRequest->SessionId = keyHeader->SessionId;
1371 
1372  nextStack->Parameters.DeviceIoControl.InputBufferLength =
1373  sizeof(DVD_READ_STRUCTURE);
1374 
1375  nextStack->Parameters.DeviceIoControl.OutputBufferLength =
1377 
1380  (PVOID) keyHeader,
1381  TRUE,
1382  TRUE,
1383  TRUE);
1384 
1385  {
1386  UCHAR uniqueAddress;
1387  ClassAcquireRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1389 
1391  IoCallDriver(commonExtension->DeviceObject, Irp);
1393 
1394  ClassReleaseRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1395  }
1396 
1397  return STATUS_PENDING;
1398 
1399  } else {
1400 
1403 
1404  }
1405  return STATUS_PENDING;
1406  }
1407 
1408  case IOCTL_DVD_END_SESSION: {
1409 
1410  PDVD_SESSION_ID sessionId = Irp->AssociatedIrp.SystemBuffer;
1411 
1413  "DvdDeviceControl: [%p] END_SESSION\n", Irp));
1414 
1415  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1417  "DvdDeviceControl: License Failure\n"));
1419  break;
1420  }
1421 
1422  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1423  sizeof(DVD_SESSION_ID)) {
1424 
1426  "DvdDeviceControl: EndSession - input buffer too "
1427  "small\n"));
1429  break;
1430  }
1431 
1433 
1434  if(*sessionId == DVD_END_ALL_SESSIONS) {
1435 
1437 
1438  if(status == STATUS_SUCCESS) {
1439 
1440  //
1441  // Just complete the request - it was never issued to the
1442  // lower device
1443  //
1444 
1445  break;
1446 
1447  } else {
1448 
1449  return STATUS_PENDING;
1450 
1451  }
1452  }
1453 
1455 
1456  return STATUS_PENDING;
1457  }
1458 
1459  case IOCTL_DVD_GET_REGION: {
1460 
1461  PDVD_COPY_PROTECT_KEY copyProtectKey;
1462  ULONG keyLength;
1463  IO_STATUS_BLOCK ioStatus;
1464  PDVD_DESCRIPTOR_HEADER dvdHeader;
1465  PDVD_COPYRIGHT_DESCRIPTOR copyRightDescriptor;
1466  PDVD_REGION dvdRegion;
1467  PDVD_READ_STRUCTURE readStructure;
1468  PDVD_RPC_KEY rpcKey;
1469 
1471  "DvdDeviceControl: [%p] IOCTL_DVD_GET_REGION\n", Irp));
1472 
1473  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1475  "DvdDeviceControl: License Failure\n"));
1477  break;
1478  }
1479 
1480  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1481  sizeof(DVD_REGION)) {
1482 
1484  "DvdDeviceControl: output buffer DVD_REGION too small\n"));
1486  break;
1487  }
1488 
1489  //
1490  // figure out how much data buffer we need
1491  //
1492 
1493  keyLength = max(sizeof(DVD_DESCRIPTOR_HEADER) +
1494  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1495  sizeof(DVD_READ_STRUCTURE)
1496  );
1497  keyLength = max(keyLength,
1499  );
1500 
1501  //
1502  // round the size to nearest ULONGLONG -- why?
1503  //
1504 
1505  keyLength += sizeof(ULONGLONG) - (keyLength & (sizeof(ULONGLONG) - 1));
1506 
1507  readStructure = ExAllocatePoolWithTag(NonPagedPool,
1508  keyLength,
1510  if (readStructure == NULL) {
1512  break;
1513  }
1514 
1515  RtlZeroMemory (readStructure, keyLength);
1516  readStructure->Format = DvdCopyrightDescriptor;
1517 
1518  //
1519  // Build a request for READ_STRUCTURE
1520  //
1521 
1524  DeviceObject,
1525  readStructure,
1526  keyLength,
1527  sizeof(DVD_DESCRIPTOR_HEADER) +
1528  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1529  FALSE,
1530  &ioStatus);
1531 
1532  status = ioStatus.Status;
1533 
1534  if (!NT_SUCCESS(status)) {
1536  "CdRomDvdGetRegion => read structure failed %x\n",
1537  status));
1538  ExFreePool(readStructure);
1539  break;
1540  }
1541 
1542  //
1543  // we got the copyright descriptor, so now get the region if possible
1544  //
1545 
1546  dvdHeader = (PDVD_DESCRIPTOR_HEADER) readStructure;
1547  copyRightDescriptor = (PDVD_COPYRIGHT_DESCRIPTOR) dvdHeader->Data;
1548 
1549  //
1550  // the original irp's systembuffer has a copy of the info that
1551  // should be passed down in the request
1552  //
1553 
1554  dvdRegion = Irp->AssociatedIrp.SystemBuffer;
1555 
1556  dvdRegion->CopySystem = copyRightDescriptor->CopyrightProtectionType;
1557  dvdRegion->RegionData = copyRightDescriptor->RegionManagementInformation;
1558 
1559  //
1560  // now reuse the buffer to request the copy protection info
1561  //
1562 
1563  copyProtectKey = (PDVD_COPY_PROTECT_KEY) readStructure;
1564  RtlZeroMemory (copyProtectKey, DVD_RPC_KEY_LENGTH);
1565  copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
1566  copyProtectKey->KeyType = DvdGetRpcKey;
1567 
1568  //
1569  // send a request for READ_KEY
1570  //
1571 
1574  DeviceObject,
1575  copyProtectKey,
1578  FALSE,
1579  &ioStatus);
1580  status = ioStatus.Status;
1581 
1582  if (!NT_SUCCESS(status)) {
1584  "CdRomDvdGetRegion => read key failed %x\n",
1585  status));
1586  ExFreePool(readStructure);
1587  break;
1588  }
1589 
1590  //
1591  // the request succeeded. if a supported scheme is returned,
1592  // then return the information to the caller
1593  //
1594 
1595  rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
1596 
1597  if (rpcKey->RpcScheme == 1) {
1598 
1599  if (rpcKey->TypeCode) {
1600 
1601  dvdRegion->SystemRegion = ~rpcKey->RegionMask;
1602  dvdRegion->ResetCount = rpcKey->UserResetsAvailable;
1603 
1604  } else {
1605 
1606  //
1607  // the drive has not been set for any region
1608  //
1609 
1610  dvdRegion->SystemRegion = 0;
1611  dvdRegion->ResetCount = rpcKey->UserResetsAvailable;
1612  }
1613  Irp->IoStatus.Information = sizeof(DVD_REGION);
1614 
1615  } else {
1616 
1618  "CdRomDvdGetRegion => rpcKey->RpcScheme != 1\n"));
1620  }
1621 
1622  ExFreePool(readStructure);
1623  break;
1624  }
1625 
1626 
1628 
1629  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1630  sizeof(STORAGE_SET_READ_AHEAD)) {
1631 
1633  "DvdDeviceControl: SetReadAhead buffer too small\n"));
1635  break;
1636  }
1637 
1640 
1641  return STATUS_PENDING;
1642  }
1643 
1644  case IOCTL_DISK_IS_WRITABLE: {
1645 
1648 
1649  return STATUS_PENDING;
1650 
1651  }
1652 
1654 
1655  ULONG size;
1656 
1657  //
1658  // we always fake zero or one partitions, and one partition
1659  // structure is included in DRIVE_LAYOUT_INFORMATION
1660  //
1661 
1662  size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[1]);
1663 
1664 
1666  "CdRomDeviceControl: Get drive layout\n"));
1667  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < size) {
1669  Irp->IoStatus.Information = size;
1670  break;
1671  }
1672 
1675  return STATUS_PENDING;
1676 
1677 
1678  }
1680 
1681  ULONG size;
1682 
1683  //
1684  // we always fake zero or one partitions, and one partition
1685  // structure is included in DRIVE_LAYOUT_INFORMATION_EX
1686  //
1687 
1688  size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[1]);
1689 
1691  "CdRomDeviceControl: Get drive layout ex\n"));
1692  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < size) {
1694  Irp->IoStatus.Information = size;
1695  break;
1696  }
1697 
1700  return STATUS_PENDING;
1701 
1702  }
1703 
1704 
1706 
1707  //
1708  // Check that the buffer is large enough.
1709  //
1710 
1711  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1712  sizeof(PARTITION_INFORMATION)) {
1713 
1715  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
1716  break;
1717  }
1718 
1721  return STATUS_PENDING;
1722 
1723  }
1725 
1726  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1727  sizeof(PARTITION_INFORMATION_EX)) {
1728 
1730  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
1731  break;
1732  }
1733 
1736  return STATUS_PENDING;
1737  }
1738 
1739  case IOCTL_DISK_VERIFY: {
1740 
1742  "IOCTL_DISK_VERIFY to device %p through irp %p\n",
1743  DeviceObject, Irp));
1744 
1745  //
1746  // Validate buffer length.
1747  //
1748 
1749  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1750  sizeof(VERIFY_INFORMATION)) {
1751 
1753  break;
1754  }
1757  return STATUS_PENDING;
1758  }
1759 
1761 
1762  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1763  sizeof(GET_LENGTH_INFORMATION)) {
1765  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
1766  break;
1767  }
1770  return STATUS_PENDING;
1771  }
1772 
1774 
1775  PGET_CONFIGURATION_IOCTL_INPUT inputBuffer;
1776 
1778  "IOCTL_CDROM_GET_CONFIGURATION to via irp %p\n", Irp));
1779 
1780  //
1781  // Validate buffer length.
1782  //
1783 
1784  if (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
1787  break;
1788  }
1789  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1790  sizeof(GET_CONFIGURATION_HEADER)) {
1792  Irp->IoStatus.Information = sizeof(GET_CONFIGURATION_HEADER);
1793  break;
1794  }
1795  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength > 0xffff) {
1796  // output buffer is too large
1798  break;
1799  }
1800 
1801  //
1802  // also verify the arguments are reasonable.
1803  //
1804 
1805  inputBuffer = Irp->AssociatedIrp.SystemBuffer;
1806  if (inputBuffer->Feature > 0xffff) {
1808  break;
1809  }
1810  if ((inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE) &&
1814  break;
1815  }
1816  if (inputBuffer->Reserved[0] || inputBuffer->Reserved[1]) {
1818  break;
1819  }
1820 
1823  return STATUS_PENDING;
1824 
1825  }
1826 
1827  default: {
1828 
1829  BOOLEAN synchronize = (KeGetCurrentIrql() == PASSIVE_LEVEL);
1830  PKEVENT deviceControlEvent;
1831 
1832  //
1833  // If the ioctl has come in at passive level then we will synchronize
1834  // with our start-io routine when sending the ioctl. If the ioctl
1835  // has come in at a higher interrupt level and it was not handled
1836  // above then it's unlikely to be a request for the class DLL - however
1837  // we'll still use it's common code to forward the request through.
1838  //
1839 
1840  if (synchronize) {
1841 
1842  deviceControlEvent = ExAllocatePoolWithTag(NonPagedPool,
1843  sizeof(KEVENT),
1845 
1846  if (deviceControlEvent == NULL) {
1847 
1848  //
1849  // must complete this irp unsuccessful here
1850  //
1852  break;
1853 
1854  } else {
1855 
1856  //PIO_STACK_LOCATION currentStack;
1857 
1858  KeInitializeEvent(deviceControlEvent, NotificationEvent, FALSE);
1859 
1860  //currentStack = IoGetCurrentIrpStackLocation(Irp);
1861  nextStack = IoGetNextIrpStackLocation(Irp);
1862 
1863  //
1864  // Copy the stack down a notch
1865  //
1866 
1868 
1870  Irp,
1872  deviceControlEvent,
1873  TRUE,
1874  TRUE,
1875  TRUE
1876  );
1877 
1879 
1880  Irp->IoStatus.Status = STATUS_SUCCESS;
1881  Irp->IoStatus.Information = 0;
1882 
1883  //
1884  // Override volume verifies on this stack location so that we
1885  // will be forced through the synchronization. Once this
1886  // location goes away we get the old value back
1887  //
1888 
1890 
1892 
1893  //
1894  // Wait for CdRomClassIoctlCompletion to set the event. This
1895  // ensures serialization remains intact for these unhandled device
1896  // controls.
1897  //
1898 
1900  deviceControlEvent,
1901  Executive,
1902  KernelMode,
1903  FALSE,
1904  NULL);
1905 
1906  ExFreePool(deviceControlEvent);
1907 
1909  "CdRomDeviceControl: irp %p synchronized\n", Irp));
1910 
1911  status = Irp->IoStatus.Status;
1912  }
1913 
1914  } else {
1916  }
1917 
1918  //
1919  // If an error occured then propagate that back up - we are no longer
1920  // guaranteed synchronization and the upper layers will have to
1921  // retry.
1922  //
1923  // If no error occured, call down to the class driver directly
1924  // then start up the next request.
1925  //
1926 
1927  if (NT_SUCCESS(status)) {
1928 
1929  UCHAR uniqueAddress;
1930 
1931  //
1932  // The class device control routine will release the remove
1933  // lock for this Irp. We need to make sure we have one
1934  // available so that it's safe to call IoStartNextPacket
1935  //
1936 
1937  if(synchronize) {
1938 
1939  ClassAcquireRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1940 
1941  }
1942 
1944 
1945  if(synchronize) {
1948  KeLowerIrql(irql);
1949  ClassReleaseRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1950  }
1951  return status;
1952 
1953  }
1954 
1955  //
1956  // an error occurred (either STATUS_INSUFFICIENT_RESOURCES from
1957  // attempting to synchronize or StartIo() error'd this one
1958  // out), so we need to finish the irp, which is
1959  // done at the end of this routine.
1960  //
1961  break;
1962 
1963  } // end default case
1964 
1965  } // end switch()
1966 
1967  if (status == STATUS_VERIFY_REQUIRED) {
1968 
1969  //
1970  // If the status is verified required and this request
1971  // should bypass verify required then retry the request.
1972  //
1973 
1974  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME) {
1975 
1977  goto RetryControl;
1978 
1979  }
1980  }
1981 
1983 
1984  if (Irp->Tail.Overlay.Thread) {
1986  }
1987 
1988  }
1989 
1990  //
1991  // Update IRP with completion status.
1992  //
1993 
1994  Irp->IoStatus.Status = status;
1995 
1996  //
1997  // Complete the request.
1998  //
1999 
2003  "CdRomDeviceControl: Status is %lx\n", status));
2004  return status;
2005 
2006 } // end CdRomDeviceControl()
2007 
2008 NTSTATUS
2009 NTAPI
2012  IN PIRP Irp,
2013  IN PVOID Context
2014  )
2015 /*++
2016 
2017 Routine Description:
2018 
2019  This routine signals the event used by CdRomDeviceControl to synchronize
2020  class driver (and lower level driver) ioctls with cdrom's startio routine.
2021  The irp completion is short-circuited so that CdRomDeviceControlDispatch
2022  can reissue it once it wakes up.
2023 
2024 Arguments:
2025 
2026  DeviceObject - the device object
2027  Irp - the request we are synchronizing
2028  Context - a PKEVENT that we need to signal
2029 
2030 Return Value:
2031 
2032  NTSTATUS
2033 
2034 --*/
2035 {
2036  PKEVENT syncEvent = (PKEVENT) Context;
2037 
2039  "CdRomClassIoctlCompletion: setting event for irp %p\n", Irp));
2040 
2041  //
2042  // We released the lock when we completed this request. Reacquire it.
2043  //
2044 
2046 
2047  KeSetEvent(syncEvent, IO_DISK_INCREMENT, FALSE);
2048 
2050 }
2051 
2052 NTSTATUS
2053 NTAPI
2056  IN PIRP Irp,
2057  IN PVOID Context
2058  )
2059 {
2062 
2063  PCDROM_DATA cdData = (PCDROM_DATA)(commonExtension->DriverData);
2064  BOOLEAN use6Byte = TEST_FLAG(cdData->XAFlags, XA_USE_6_BYTE);
2065 
2067  PIO_STACK_LOCATION realIrpStack;
2068  PIO_STACK_LOCATION realIrpNextStack;
2069 
2071 
2072  PIRP realIrp = NULL;
2073 
2074  NTSTATUS status;
2075  BOOLEAN retry;
2076  ULONG retryCount;
2077 
2078  //
2079  // Extract the 'real' irp from the irpstack.
2080  //
2081 
2082  realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
2083  realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
2084  realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
2085 
2086  //
2087  // check that we've really got the correct irp
2088  //
2089 
2090  ASSERT(realIrpNextStack->Parameters.Others.Argument3 == Irp);
2091 
2092  //
2093  // Check SRB status for success of completing request.
2094  //
2095 
2096  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2097 
2098  ULONG retryInterval;
2099 
2101  "CdRomDeviceControlCompletion: Irp %p, Srb %p Real Irp %p Status %lx\n",
2102  Irp,
2103  srb,
2104  realIrp,
2105  srb->SrbStatus));
2106 
2107  //
2108  // Release the queue if it is frozen.
2109  //
2110 
2111  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2113  "CdRomDeviceControlCompletion: Releasing Queue\n"));
2115  }
2116 
2117 
2119  srb,
2120  irpStack->MajorFunction,
2121  irpStack->Parameters.DeviceIoControl.IoControlCode,
2122  MAXIMUM_RETRIES - ((ULONG)(ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
2123  &status,
2124  &retryInterval);
2125 
2127  "CdRomDeviceControlCompletion: IRP will %sbe retried\n",
2128  (retry ? "" : "not ")));
2129 
2130  //
2131  // Some of the Device Controls need special cases on non-Success status's.
2132  //
2133 
2134  if (realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
2135  if ((realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_LAST_SESSION) ||
2136  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_TOC) ||
2137  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_TOC_EX) ||
2138  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_CONTROL) ||
2139  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_VOLUME)) {
2140 
2141  if (status == STATUS_DATA_OVERRUN) {
2143  retry = FALSE;
2144  }
2145  }
2146 
2147  if (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_Q_CHANNEL) {
2148  PLAY_ACTIVE(fdoExtension) = FALSE;
2149  }
2150  }
2151 
2152  //
2153  // If the status is verified required and the this request
2154  // should bypass verify required then retry the request.
2155  //
2156 
2157  if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
2159 
2160  // note: status gets overwritten here
2162  retry = TRUE;
2163 
2164  if (((realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) ||
2166  ) &&
2167  ((realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
2169  (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
2171  (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
2173  (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
2175  )
2176  ) {
2177 
2178  //
2179  // Update the geometry information, as the media could have
2180  // changed. The completion routine for this will complete
2181  // the real irp and start the next packet.
2182  //
2183 
2184  if (srb) {
2185  if (srb->SenseInfoBuffer) {
2187  }
2188  if (srb->DataBuffer) {
2189  ExFreePool(srb->DataBuffer);
2190  }
2191  ExFreePool(srb);
2192  srb = NULL;
2193  }
2194 
2195  if (Irp->MdlAddress) {
2196  IoFreeMdl(Irp->MdlAddress);
2197  Irp->MdlAddress = NULL;
2198  }
2199 
2200  IoFreeIrp(Irp);
2201  Irp = NULL;
2202 
2203  status = CdRomUpdateCapacity(fdoExtension, realIrp, NULL);
2205  "CdRomDeviceControlCompletion: [%p] "
2206  "CdRomUpdateCapacity completed with status %lx\n",
2207  realIrp, status));
2208 
2209  //
2210  // needed to update the capacity.
2211  // the irp's already handed off to CdRomUpdateCapacity().
2212  // we've already free'd the current irp.
2213  // nothing left to do in this code path.
2214  //
2215 
2217 
2218  } // end of ioctls to update capacity
2219 
2220  }
2221 
2222  //
2223  // get current retry count
2224  //
2225  retryCount = PtrToUlong(realIrpNextStack->Parameters.Others.Argument1);
2226 
2227  if (retry && retryCount) {
2228 
2229  //
2230  // update retry count
2231  //
2232  realIrpNextStack->Parameters.Others.Argument1 = UlongToPtr(retryCount-1);
2233 
2234  if (((ULONG)(ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
2235 
2236  //
2237  // Retry request.
2238  //
2239 
2241  "Retry request %p - Calling StartIo\n", Irp));
2242 
2243 
2245  if (srb->DataBuffer) {
2246  ExFreePool(srb->DataBuffer);
2247  }
2248  ExFreePool(srb);
2249  if (Irp->MdlAddress) {
2250  IoFreeMdl(Irp->MdlAddress);
2251  }
2252 
2253  realIrpNextStack->Parameters.Others.Argument3 = (PVOID)-1;
2254  IoFreeIrp(Irp);
2255 
2256  CdRomRetryRequest(fdoExtension, realIrp, retryInterval, FALSE);
2258  }
2259 
2260  //
2261  // Exhausted retries. Fall through and complete the request with
2262  // the appropriate status.
2263  //
2264 
2265  }
2266  } else {
2267 
2268  //
2269  // Set status for successful request.
2270  //
2271 
2273 
2274  }
2275 
2276 
2277  if (NT_SUCCESS(status)) {
2278 
2279  //BOOLEAN b = FALSE;
2280 
2281 
2282  switch (realIrpStack->Parameters.DeviceIoControl.IoControlCode) {
2283 
2285  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
2286  srb->DataBuffer,
2287  srb->DataTransferLength);
2288  realIrp->IoStatus.Information = srb->DataTransferLength;
2289  break;
2290  }
2291 
2293 
2294  PGET_LENGTH_INFORMATION lengthInfo;
2295 
2298 
2299  lengthInfo = (PGET_LENGTH_INFORMATION)realIrp->AssociatedIrp.SystemBuffer;
2300  lengthInfo->Length = commonExtension->PartitionLength;
2301  realIrp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
2303  break;
2304  }
2305 
2308 
2309  PDISK_GEOMETRY_EX geometryEx;
2310 
2313 
2314  geometryEx = (PDISK_GEOMETRY_EX)(realIrp->AssociatedIrp.SystemBuffer);
2315  geometryEx->DiskSize = commonExtension->PartitionLength;
2316  geometryEx->Geometry = fdoExtension->DiskGeometry;
2317  realIrp->IoStatus.Information =
2319  break;
2320  }
2321 
2324 
2325  PDISK_GEOMETRY geometry;
2326 
2329 
2330  geometry = (PDISK_GEOMETRY)(realIrp->AssociatedIrp.SystemBuffer);
2331  *geometry = fdoExtension->DiskGeometry;
2332  realIrp->IoStatus.Information = sizeof(DISK_GEOMETRY);
2333  break;
2334  }
2335 
2336  case IOCTL_DISK_VERIFY: {
2337  //
2338  // nothing to do but return the status...
2339  //
2340  break;
2341  }
2342 
2345  case IOCTL_CDROM_CHECK_VERIFY: {
2346 
2347  if((realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_CHECK_VERIFY) &&
2348  (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength)) {
2349 
2350  *((PULONG)realIrp->AssociatedIrp.SystemBuffer) =
2351  commonExtension->PartitionZeroExtension->MediaChangeCount;
2352 
2353  realIrp->IoStatus.Information = sizeof(ULONG);
2354  } else {
2355  realIrp->IoStatus.Information = 0;
2356  }
2357 
2359  "CdRomDeviceControlCompletion: [%p] completing "
2360  "CHECK_VERIFY buddy irp %p\n", realIrp, Irp));
2361  break;
2362  }
2363 
2364  case IOCTL_CDROM_READ_TOC_EX: {
2365 
2368  break;
2369  }
2370 
2371  //
2372  // Copy the returned info into the user buffer.
2373  //
2374 
2375  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
2376  srb->DataBuffer,
2377  srb->DataTransferLength);
2378 
2379  //
2380  // update information field.
2381  //
2382 
2383  realIrp->IoStatus.Information = srb->DataTransferLength;
2384  break;
2385  }
2386 
2387 
2389  case IOCTL_CDROM_READ_TOC: {
2390 
2391  //
2392  // Copy the returned info into the user buffer.
2393  //
2394 
2395  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
2396  srb->DataBuffer,
2397  srb->DataTransferLength);
2398 
2399  //
2400  // update information field.
2401  //
2402 
2403  realIrp->IoStatus.Information = srb->DataTransferLength;
2404  break;
2405  }
2406 
2407  case IOCTL_DVD_READ_STRUCTURE: {
2408 
2409  DVD_STRUCTURE_FORMAT format = ((PDVD_READ_STRUCTURE) realIrp->AssociatedIrp.SystemBuffer)->Format;
2410 
2411  PDVD_DESCRIPTOR_HEADER header = realIrp->AssociatedIrp.SystemBuffer;
2412 
2413  //FOUR_BYTE fourByte;
2414  //PTWO_BYTE twoByte;
2415  //UCHAR tmp;
2416 
2418  "DvdDeviceControlCompletion - IOCTL_DVD_READ_STRUCTURE: completing irp %p (buddy %p)\n",
2419  Irp,
2420  realIrp));
2421 
2423  "DvdDCCompletion - READ_STRUCTURE: descriptor format of %d\n", format));
2424 
2426  srb->DataBuffer,
2427  srb->DataTransferLength);
2428 
2429  //
2430  // Cook the data. There are a number of fields that really
2431  // should be byte-swapped for the caller.
2432  //
2433 
2435  "DvdDCCompletion - READ_STRUCTURE:\n"
2436  "\tHeader at %p\n"
2437  "\tDvdDCCompletion - READ_STRUCTURE: data at %p\n"
2438  "\tDataBuffer was at %p\n"
2439  "\tDataTransferLength was %lx\n",
2440  header,
2441  header->Data,
2442  srb->DataBuffer,
2443  srb->DataTransferLength));
2444 
2445  //
2446  // First the fields in the header
2447  //
2448 
2449  TraceLog((CdromDebugInfo, "READ_STRUCTURE: header->Length %lx -> ",
2450  header->Length));
2451  REVERSE_SHORT(&header->Length);
2452  TraceLog((CdromDebugInfo, "%lx\n", header->Length));
2453 
2454  //
2455  // Now the fields in the descriptor
2456  //
2457 
2458  if(format == DvdPhysicalDescriptor) {
2459 
2461 
2462  TraceLog((CdromDebugInfo, "READ_STRUCTURE: StartingDataSector %lx -> ",
2463  layer->StartingDataSector));
2464  REVERSE_LONG(&(layer->StartingDataSector));
2465  TraceLog((CdromDebugInfo, "%lx\n", layer->StartingDataSector));
2466 
2467  TraceLog((CdromDebugInfo, "READ_STRUCTURE: EndDataSector %lx -> ",
2468  layer->EndDataSector));
2469  REVERSE_LONG(&(layer->EndDataSector));
2470  TraceLog((CdromDebugInfo, "%lx\n", layer->EndDataSector));
2471 
2472  TraceLog((CdromDebugInfo, "READ_STRUCTURE: EndLayerZeroSector %lx -> ",
2473  layer->EndLayerZeroSector));
2474  REVERSE_LONG(&(layer->EndLayerZeroSector));
2475  TraceLog((CdromDebugInfo, "%lx\n", layer->EndLayerZeroSector));
2476  }
2477 
2478  TraceLog((CdromDebugTrace, "Status is %lx\n", Irp->IoStatus.Status));
2479  TraceLog((CdromDebugTrace, "DvdDeviceControlCompletion - "
2480  "IOCTL_DVD_READ_STRUCTURE: data transfer length of %d\n",
2481  srb->DataTransferLength));
2482 
2483  realIrp->IoStatus.Information = srb->DataTransferLength;
2484  break;
2485  }
2486 
2487  case IOCTL_DVD_READ_KEY: {
2488 
2489  PDVD_COPY_PROTECT_KEY copyProtectKey = realIrp->AssociatedIrp.SystemBuffer;
2490 
2491  PCDVD_KEY_HEADER keyHeader = srb->DataBuffer;
2492  ULONG dataLength;
2493 
2494  ULONG transferLength =
2495  srb->DataTransferLength -
2497 
2498  //
2499  // Adjust the data length to ignore the two reserved bytes in the
2500  // header.
2501  //
2502 
2503  dataLength = (keyHeader->DataLength[0] << 8) +
2504  keyHeader->DataLength[1];
2505  dataLength -= 2;
2506 
2507  //
2508  // take the minimum of the transferred length and the
2509  // length as specified in the header.
2510  //
2511 
2512  if(dataLength < transferLength) {
2513  transferLength = dataLength;
2514  }
2515 
2517  "DvdDeviceControlCompletion: [%p] - READ_KEY with "
2518  "transfer length of (%d or %d) bytes\n",
2519  Irp,
2520  dataLength,
2521  srb->DataTransferLength - 2));
2522 
2523  //
2524  // Copy the key data into the return buffer
2525  //
2526  if(copyProtectKey->KeyType == DvdTitleKey) {
2527 
2528  RtlMoveMemory(copyProtectKey->KeyData,
2529  keyHeader->Data + 1,
2530  transferLength - 1);
2531  copyProtectKey->KeyData[transferLength - 1] = 0;
2532 
2533  //
2534  // If this is a title key then we need to copy the CGMS flags
2535  // as well.
2536  //
2537  copyProtectKey->KeyFlags = *(keyHeader->Data);
2538 
2539  } else {
2540 
2541  RtlMoveMemory(copyProtectKey->KeyData,
2542  keyHeader->Data,
2543  transferLength);
2544  }
2545 
2546  copyProtectKey->KeyLength = sizeof(DVD_COPY_PROTECT_KEY);
2547  copyProtectKey->KeyLength += transferLength;
2548 
2549  realIrp->IoStatus.Information = copyProtectKey->KeyLength;
2550  break;
2551  }
2552 
2553  case IOCTL_DVD_START_SESSION: {
2554 
2555  PDVD_SESSION_ID sessionId = realIrp->AssociatedIrp.SystemBuffer;
2556 
2557  PCDVD_KEY_HEADER keyHeader = srb->DataBuffer;
2558  PCDVD_REPORT_AGID_DATA keyData = (PCDVD_REPORT_AGID_DATA) keyHeader->Data;
2559 
2560  *sessionId = keyData->AGID;
2561 
2562  realIrp->IoStatus.Information = sizeof(DVD_SESSION_ID);
2563 
2564  break;
2565  }
2566 
2567  case IOCTL_DVD_END_SESSION:
2568  case IOCTL_DVD_SEND_KEY:
2569  case IOCTL_DVD_SEND_KEY2:
2570 
2571  //
2572  // nothing to return
2573  //
2574  realIrp->IoStatus.Information = 0;
2575  break;
2576 
2578 
2579  PLAY_ACTIVE(fdoExtension) = TRUE;
2580 
2581  break;
2582 
2584 
2585  PSUB_Q_CHANNEL_DATA userChannelData = realIrp->AssociatedIrp.SystemBuffer;
2586  PCDROM_SUB_Q_DATA_FORMAT inputBuffer = realIrp->AssociatedIrp.SystemBuffer;
2587  PSUB_Q_CHANNEL_DATA subQPtr = srb->DataBuffer;
2588 
2589 #if DBG
2590  switch( inputBuffer->Format ) {
2591 
2593  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->CurrentPosition.Header.AudioStatus ));
2594  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: ADR = 0x%x\n", subQPtr->CurrentPosition.ADR ));
2595  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Control = 0x%x\n", subQPtr->CurrentPosition.Control ));
2596  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Track = %u\n", subQPtr->CurrentPosition.TrackNumber ));
2597  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Index = %u\n", subQPtr->CurrentPosition.IndexNumber ));
2598  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Absolute Address = %x\n", *((PULONG)subQPtr->CurrentPosition.AbsoluteAddress) ));
2599  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Relative Address = %x\n", *((PULONG)subQPtr->CurrentPosition.TrackRelativeAddress) ));
2600  break;
2601 
2603  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->MediaCatalog.Header.AudioStatus ));
2604  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Mcval is %u\n", subQPtr->MediaCatalog.Mcval ));
2605  break;
2606 
2608  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->TrackIsrc.Header.AudioStatus ));
2609  TraceLog((CdromDebugTrace,"CdRomDeviceControlCompletion: Tcval is %u\n", subQPtr->TrackIsrc.Tcval ));
2610  break;
2611 
2612  }
2613 #endif
2614 
2615  //
2616  // Update the play active status.
2617  //
2618 
2620 
2621  PLAY_ACTIVE(fdoExtension) = TRUE;
2622 
2623  } else {
2624 
2625  PLAY_ACTIVE(fdoExtension) = FALSE;
2626 
2627  }
2628 
2629  //
2630  // Check if output buffer is large enough to contain
2631  // the data.
2632  //
2633 
2634  if (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
2635  srb->DataTransferLength) {
2636 
2637  srb->DataTransferLength =
2638  realIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
2639  }
2640 
2641  //
2642  // Copy our buffer into users.
2643  //
2644 
2645  RtlMoveMemory(userChannelData,
2646  subQPtr,
2647  srb->DataTransferLength);
2648 
2649  realIrp->IoStatus.Information = srb->DataTransferLength;
2650  break;
2651  }
2652 
2654 
2655  PLAY_ACTIVE(fdoExtension) = FALSE;
2656  realIrp->IoStatus.Information = 0;
2657  break;
2658 
2660 
2661  realIrp->IoStatus.Information = 0;
2662  break;
2663 
2665 
2666  realIrp->IoStatus.Information = 0;
2667  break;
2668 
2670 
2671  PLAY_ACTIVE(fdoExtension) = FALSE;
2672  realIrp->IoStatus.Information = 0;
2673  break;
2674 
2675  case IOCTL_CDROM_GET_CONTROL: {
2676 
2677  PCDROM_AUDIO_CONTROL audioControl = srb->DataBuffer;
2678  PAUDIO_OUTPUT audioOutput;
2679  ULONG bytesTransferred;
2680 
2681  audioOutput = ClassFindModePage((PCHAR)audioControl,
2682  srb->DataTransferLength,
2684  use6Byte);
2685  //
2686  // Verify the page is as big as expected.
2687  //
2688 
2689  bytesTransferred = (ULONG)((PCHAR) audioOutput - (PCHAR) audioControl) +
2690  sizeof(AUDIO_OUTPUT);
2691 
2692  if (audioOutput != NULL &&
2693  srb->DataTransferLength >= bytesTransferred) {
2694 
2695  audioControl->LbaFormat = audioOutput->LbaFormat;
2696 
2697  audioControl->LogicalBlocksPerSecond =
2698  (audioOutput->LogicalBlocksPerSecond[0] << (UCHAR)8) |
2699  audioOutput->LogicalBlocksPerSecond[1];
2700 
2701  realIrp->IoStatus.Information = sizeof(CDROM_AUDIO_CONTROL);
2702 
2703  } else {
2704  realIrp->IoStatus.Information = 0;
2706  }
2707  break;
2708  }
2709 
2710  case IOCTL_CDROM_GET_VOLUME: {
2711 
2712  PAUDIO_OUTPUT audioOutput;
2713  PVOLUME_CONTROL volumeControl = srb->DataBuffer;
2714  ULONG i;
2715  ULONG bytesTransferred;
2716 
2717  audioOutput = ClassFindModePage((PCHAR)volumeControl,
2718  srb->DataTransferLength,
2720  use6Byte);
2721 
2722  //
2723  // Verify the page is as big as expected.
2724  //
2725 
2726  bytesTransferred = (ULONG)((PCHAR) audioOutput - (PCHAR) volumeControl) +
2727  sizeof(AUDIO_OUTPUT);
2728 
2729  if (audioOutput != NULL &&
2730  srb->DataTransferLength >= bytesTransferred) {
2731 
2732  for (i=0; i<4; i++) {
2733  volumeControl->PortVolume[i] =
2734  audioOutput->PortOutput[i].Volume;
2735  }
2736 
2737  //
2738  // Set bytes transferred in IRP.
2739  //
2740 
2741  realIrp->IoStatus.Information = sizeof(VOLUME_CONTROL);
2742 
2743  } else {
2744  realIrp->IoStatus.Information = 0;
2746  }
2747 
2748  break;
2749  }
2750 
2752 
2753  realIrp->IoStatus.Information = 0;
2754  break;
2755 
2756  default:
2757 
2758  ASSERT(FALSE);
2759  realIrp->IoStatus.Information = 0;
2761 
2762  } // end switch()
2763  }
2764 
2765  //
2766  // Deallocate srb and sense buffer.
2767  //
2768 
2769  if (srb) {
2770  if (srb->DataBuffer) {
2771  ExFreePool(srb->DataBuffer);
2772  }
2773  if (srb->SenseInfoBuffer) {
2775  }
2776  ExFreePool(srb);
2777  }
2778 
2779  if (realIrp->PendingReturned) {
2780  IoMarkIrpPending(realIrp);
2781  }
2782 
2783  if (Irp->MdlAddress) {
2784  IoFreeMdl(Irp->MdlAddress);
2785  }
2786 
2787  IoFreeIrp(Irp);
2788 
2789  //
2790  // Set status in completing IRP.
2791  //
2792 
2793  realIrp->IoStatus.Status = status;
2794 
2795  //
2796  // Set the hard error if necessary.
2797  //
2798 
2800 
2801  //
2802  // Store DeviceObject for filesystem, and clear
2803  // in IoStatus.Information field.
2804  //
2805 
2807  "CdRomDeviceCompletion - Setting Hard Error on realIrp %p\n",
2808  realIrp));
2809  if (realIrp->Tail.Overlay.Thread) {
2811  }
2812 
2813  realIrp->IoStatus.Information = 0;
2814  }
2815 
2816  //
2817  // note: must complete the realIrp, as the completed irp (above)
2818  // was self-allocated.
2819  //
2820 
2823 }
2824 
2825 NTSTATUS
2826 NTAPI
2829  IN PIRP Irp,
2830  IN PVOID Context
2831  )
2832 {
2835 
2837  PCDROM_DATA cdData = (PCDROM_DATA)(commonExtension->DriverData);
2838  BOOLEAN use6Byte = TEST_FLAG(cdData->XAFlags, XA_USE_6_BYTE);
2839  PIO_STACK_LOCATION realIrpStack;
2840  PIO_STACK_LOCATION realIrpNextStack;
2842  PIRP realIrp = NULL;
2843  NTSTATUS status;
2844  BOOLEAN retry;
2845  ULONG retryCount;
2846 
2847  //
2848  // Extract the 'real' irp from the irpstack.
2849  //
2850 
2851  realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
2852  realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
2853  realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
2854 
2855  //
2856  // Check SRB status for success of completing request.
2857  //
2858 
2859  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2860 
2861  ULONG retryInterval;
2862 
2864  "CdRomSetVolumeIntermediateCompletion: Irp %p, Srb %p, Real Irp %p\n",
2865  Irp,
2866  srb,
2867  realIrp));
2868 
2869  //
2870  // Release the queue if it is frozen.
2871  //
2872 
2873  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2875  }
2876 
2877 
2879  srb,
2880  irpStack->MajorFunction,
2881  irpStack->Parameters.DeviceIoControl.IoControlCode,
2882  MAXIMUM_RETRIES - ((ULONG)(ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
2883  &status,
2884  &retryInterval);
2885 
2886  if (status == STATUS_DATA_OVERRUN) {
2888  retry = FALSE;
2889  }
2890 
2891  //
2892  // If the status is verified required and the this request
2893  // should bypass verify required then retry the request.
2894  //
2895 
2896  if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
2898 
2900  retry = TRUE;
2901  }
2902 
2903  //
2904  // get current retry count
2905  //
2906  retryCount = PtrToUlong(realIrpNextStack->Parameters.Others.Argument1);
2907 
2908  if (retry && retryCount) {
2909 
2910  //
2911  // update retry count
2912  //
2913  realIrpNextStack->Parameters.Others.Argument1 = UlongToPtr(retryCount-1);
2914 
2915 
2916  if (((ULONG)(ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
2917 
2918  //
2919  // Retry request.
2920  //
2921 
2923  "Retry request %p - Calling StartIo\n", Irp));
2924 
2925 
2927  ExFreePool(srb->DataBuffer);
2928  ExFreePool(srb);
2929  if (Irp->MdlAddress) {
2930  IoFreeMdl(Irp->MdlAddress);
2931  }
2932 
2933  IoFreeIrp(Irp);
2934 
2935  CdRomRetryRequest(deviceExtension,
2936  realIrp,
2937  retryInterval,
2938  FALSE);
2939 
2941 
2942  }
2943 
2944  //
2945  // Exhausted retries. Fall through and complete the request with the appropriate status.
2946  //
2947 
2948  }
2949  } else {
2950 
2951  //
2952  // Set status for successful request.
2953  //
2954 
2956 
2957  }
2958 
2959  if (NT_SUCCESS(status)) {
2960 
2961  PAUDIO_OUTPUT audioInput = NULL;
2962  PAUDIO_OUTPUT audioOutput;
2963  PVOLUME_CONTROL volumeControl = realIrp->AssociatedIrp.SystemBuffer;
2964  ULONG i,bytesTransferred,headerLength;
2965  PVOID dataBuffer;
2966  PCDB cdb;
2967 
2968  audioInput = ClassFindModePage((PCHAR)srb->DataBuffer,
2969  srb->DataTransferLength,
2971  use6Byte);
2972 
2973  //
2974  // Check to make sure the mode sense data is valid before we go on
2975  //
2976 
2977  if(audioInput == NULL) {
2978 
2980  "Mode Sense Page %d not found\n",
2982 
2983  realIrp->IoStatus.Information = 0;
2984  realIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
2985  goto SafeExit;
2986  }
2987 
2988  if (use6Byte) {
2989  headerLength = sizeof(MODE_PARAMETER_HEADER);
2990  } else {
2991  headerLength = sizeof(MODE_PARAMETER_HEADER10);
2992  }
2993 
2994  bytesTransferred = sizeof(AUDIO_OUTPUT) + headerLength;
2995 
2996  //
2997  // Allocate a new buffer for the mode select.
2998  //
2999 
3001  bytesTransferred,
3003 
3004  if (!dataBuffer) {
3005  realIrp->IoStatus.Information = 0;
3006  realIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3007  goto SafeExit;
3008  }
3009 
3010  RtlZeroMemory(dataBuffer, bytesTransferred);
3011 
3012  //
3013  // Rebuild the data buffer to include the user requested values.
3014  //
3015 
3016  audioOutput = (PAUDIO_OUTPUT) ((PCHAR) dataBuffer + headerLength);
3017 
3018  for (i=0; i<4; i++) {
3019  audioOutput->PortOutput[i].Volume =
3020  volumeControl->PortVolume[i];
3021  audioOutput->PortOutput[i].ChannelSelection =
3022  audioInput->PortOutput[i].ChannelSelection;
3023  }
3024 
3025  audioOutput->CodePage = CDROM_AUDIO_CONTROL_PAGE;
3026  audioOutput->ParameterLength = sizeof(AUDIO_OUTPUT) - 2;
3027  audioOutput->Immediate = MODE_SELECT_IMMEDIATE;
3028 
3029  //
3030  // Free the old data buffer, mdl.
3031  //
3032 
3033  IoFreeMdl(Irp->MdlAddress);
3034  Irp->MdlAddress = NULL;
3035  ExFreePool(srb->DataBuffer);
3036 
3037  //
3038  // set the data buffer to new allocation, so it can be
3039  // freed in the exit path
3040  //
3041 
3042  srb->DataBuffer = dataBuffer;
3043 
3044  //
3045  // rebuild the srb.
3046  //
3047 
3048  cdb = (PCDB)srb->Cdb;
3050 
3051  srb->SrbStatus = srb->ScsiStatus = 0;
3052  srb->SrbFlags = deviceExtension->SrbFlags;
3055  srb->DataTransferLength = bytesTransferred;
3056 
3057  if (use6Byte) {
3058 
3059  cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
3060  cdb->MODE_SELECT.ParameterListLength = (UCHAR) bytesTransferred;
3061  cdb->MODE_SELECT.PFBit = 1;
3062  srb->CdbLength = 6;
3063  } else {
3064 
3065  cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
3066  cdb->MODE_SELECT10.ParameterListLength[0] = (UCHAR) (bytesTransferred >> 8);
3067  cdb->MODE_SELECT10.ParameterListLength[1] = (UCHAR) (bytesTransferred & 0xFF);
3068  cdb->MODE_SELECT10.PFBit = 1;
3069  srb->CdbLength = 10;
3070  }
3071 
3072  //
3073  // Prepare the MDL
3074  //
3075 
3076  Irp->MdlAddress = IoAllocateMdl(dataBuffer,
3077  bytesTransferred,
3078  FALSE,
3079  FALSE,
3080  (PIRP) NULL);
3081 
3082  if (!Irp->MdlAddress) {
3083  realIrp->IoStatus.Information = 0;
3084  realIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3085  goto SafeExit;
3086  }
3087 
3088  MmBuildMdlForNonPagedPool(Irp->MdlAddress);
3089 
3090  irpStack = IoGetNextIrpStackLocation(Irp);
3092  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
3093  irpStack->Parameters.Scsi.Srb = srb;
3094 
3095  //
3096  // reset the irp completion.
3097  //
3098 
3101  srb,
3102  TRUE,
3103  TRUE,
3104  TRUE);
3105  //
3106  // Call the port driver.
3107  //
3108 
3109  IoCallDriver(commonExtension->LowerDeviceObject, Irp);
3110 
3112  }
3113 
3114 SafeExit:
3115 
3116  //
3117  // Deallocate srb and sense buffer.
3118  //
3119 
3120  if (srb) {
3121  if (srb->DataBuffer) {
3122  ExFreePool(srb->DataBuffer);
3123  }
3124  if (srb->SenseInfoBuffer) {
3126  }
3127  ExFreePool(srb);
3128  }
3129 
3130  if (Irp->PendingReturned) {
3132  }
3133 
3134  if (realIrp->PendingReturned) {
3135  IoMarkIrpPending(realIrp);
3136  }
3137 
3138  if (Irp->MdlAddress) {
3139  IoFreeMdl(Irp->MdlAddress);
3140  }
3141 
3142  IoFreeIrp(Irp);
3143 
3144  //
3145  // Set status in completing IRP.
3146  //
3147 
3148  realIrp->IoStatus.Status = status;
3149 
3150  //
3151  // Set the hard error if necessary.
3152  //
3153 
3155 
3156  //
3157  // Store DeviceObject for filesystem, and clear
3158  // in IoStatus.Information field.
3159  //
3160 
3161  if (realIrp->Tail.Overlay.Thread) {
3163  }
3164  realIrp->IoStatus.Information = 0;
3165  }
3166 
3169 }
3170 
3171 NTSTATUS
3172 NTAPI
3175  IN PIRP Irp,
3176  IN PVOID Context
3177  )
3178 
3179 /*++
3180 
3181 Routine Description:
3182 
3183  This routine will setup the next stack location to issue an end session
3184  to the device. It will increment the session id in the system buffer
3185  and issue an END_SESSION for that AGID if the AGID is valid.
3186 
3187  When the new AGID is > 3 this routine will complete the request.
3188 
3189 Arguments:
3190 
3191  DeviceObject - the device object for this drive
3192 
3193  Irp - the request
3194 
3195  Context - done
3196 
3197 Return Value:
3198 
3199  STATUS_MORE_PROCESSING_REQUIRED if there is another AGID to clear
3200  status otherwise.
3201 
3202 --*/
3203 
3204 {
3206 
3207  //PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
3208 
3209  PDVD_SESSION_ID sessionId = Irp->AssociatedIrp.SystemBuffer;
3210 
3211  //NTSTATUS status;
3212 
3213  if(++(*sessionId) > MAX_COPY_PROTECT_AGID) {
3214 
3215  //
3216  // We're done here - just return success and let the io system
3217  // continue to complete it.
3218  //
3219 
3220  return STATUS_SUCCESS;
3221 
3222  }
3223 
3225 
3228  NULL,
3229  TRUE,
3230  FALSE,
3231  FALSE);
3232 
3234 
3235  IoCallDriver(fdoExtension->CommonExtension.DeviceObject, Irp);
3236 
3237  //
3238  // At this point we have to assume the irp may have already been
3239  // completed. Ignore the returned status and return.
3240  //
3241 
3243 }
3244 
3245 NTSTATUS
3246 NTAPI
3249  IN PIRP Irp,
3250  IN PVOID Context
3251  )
3252 
3253 /*++
3254 
3255 Routine Description:
3256 
3257  This routine handles the completion of a request to obtain the disk
3258  key from the dvd media. It will transform the raw 2K of key data into
3259  a DVD_COPY_PROTECT_KEY structure and copy back the saved key parameters
3260  from the context pointer before returning.
3261 
3262 Arguments:
3263 
3264  DeviceObject -
3265 
3266  Irp -
3267 
3268  Context - a DVD_COPY_PROTECT_KEY pointer which contains the key
3269  parameters handed down by the caller.
3270 
3271 Return Value:
3272 
3273  STATUS_SUCCESS;
3274 
3275 --*/
3276 
3277 {
3278  PDVD_COPY_PROTECT_KEY savedKey = Context;
3279 
3280  PREAD_DVD_STRUCTURES_HEADER rawKey = Irp->AssociatedIrp.SystemBuffer;
3281  PDVD_COPY_PROTECT_KEY outputKey = Irp->AssociatedIrp.SystemBuffer;
3282 
3283  if (NT_SUCCESS(Irp->IoStatus.Status)) {
3284 
3285  //
3286  // Shift the data down to its new position.
3287  //
3288 
3289  RtlMoveMemory(outputKey->KeyData,
3290  rawKey->Data,
3291  sizeof(DVD_DISK_KEY_DESCRIPTOR));
3292 
3293  RtlCopyMemory(outputKey,
3294  savedKey,
3295  sizeof(DVD_COPY_PROTECT_KEY));
3296 
3297  outputKey->KeyLength = DVD_DISK_KEY_LENGTH;
3298 
3299  Irp->IoStatus.Information = DVD_DISK_KEY_LENGTH;
3300 
3301  } else {
3302 
3304  "DiskKey Failed with status %x, %p (%x) bytes\n",
3305  Irp->IoStatus.Status,
3306  (PVOID)Irp->IoStatus.Information,
3307  ((rawKey->Length[0] << 16) | rawKey->Length[1])
3308  ));
3309 
3310  }
3311 
3312  //
3313  // release the context block
3314  //
3315 
3317 
3318  return STATUS_SUCCESS;
3319 }
3320 
3321 NTSTATUS
3322 NTAPI
3325  IN PIRP Irp,
3326  IN PVOID Context
3327  )
3328 
3329 /*++
3330 
3331 Routine Description:
3332 
3333  This routine executes when the port driver has completed a request.
3334  It looks at the SRB status in the completing SRB and if not success
3335  it checks for valid request sense buffer information. If valid, the
3336  info is used to update status with more precise message of type of
3337  error. This routine deallocates the SRB.
3338 
3339 Arguments:
3340 
3341  DeviceObject - Supplies the device object which represents the logical
3342  unit.
3343 
3344  Irp - Supplies the Irp which has completed.
3345 
3346  Context - Supplies a pointer to the SRB.
3347 
3348 Return Value:
3349 
3350  NT status
3351 
3352 --*/
3353 
3354 {
3358  NTSTATUS status;
3359  BOOLEAN retry;
3360 
3361  //
3362  // Check SRB status for success of completing request.
3363  //
3364 
3365  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
3366 
3367  ULONG retryInterval;
3368 
3369  TraceLog((CdromDebugTrace, "CdromXAComplete: IRP %p SRB %p Status %x\n",
3370  Irp, srb, srb->SrbStatus));
3371 
3372  //
3373  // Release the queue if it is frozen.
3374  //
3375 
3376  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
3378  }
3379 
3380  retry = ClassInterpretSenseInfo(
3381  DeviceObject,
3382  srb,
3383  irpStack->MajorFunction,
3384  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
3385  MAXIMUM_RETRIES - irpStack->MinorFunction, // HACKHACK - REF #0001
3386  &status,
3387  &retryInterval);
3388 
3389  //
3390  // If the status is verified required and the this request
3391  // should bypass verify required then retry the request.
3392  //
3393 
3394  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
3396 
3398  retry = TRUE;
3399  }
3400 
3401  if (retry) {
3402 
3403  if (irpStack->MinorFunction != 0) { // HACKHACK - REF #0001
3404 
3405  irpStack->MinorFunction--; // HACKHACK - REF #0001
3406 
3407  //
3408  // Retry request.
3409  //
3410 
3412  "CdRomXACompletion: Retry request %p (%x) - "
3413  "Calling StartIo\n", Irp, irpStack->MinorFunction));
3414 
3415 
3417  ExFreePool(srb);
3418 
3419  //
3420  // Call StartIo directly since IoStartNextPacket hasn't been called,
3421  // the serialisation is still intact.
3422  //
3423 
3424  CdRomRetryRequest(deviceExtension,
3425  Irp,
3426  retryInterval,
3427  FALSE);
3428 
3430 
3431  }
3432 
3433  //
3434  // Exhausted retries, fall through and complete the request
3435  // with the appropriate status
3436  //
3437 
3439  "CdRomXACompletion: Retries exhausted for irp %p\n",
3440  Irp));
3441 
3442  }
3443 
3444  } else {
3445 
3446  //
3447  // Set status for successful request.
3448  //
3449 
3451 
3452  } // end if (SRB_STATUS(srb->SrbStatus) ...
3453 
3454  //
3455  // Return SRB to nonpaged pool.
3456  //
3457 
3459  ExFreePool(srb);
3460 
3461  //
3462  // Set status in completing IRP.
3463  //
3464 
3465  Irp->IoStatus.Status = status;
3466 
3467  //
3468  // Set the hard error if necessary.
3469  //
3470 
3471  if (!NT_SUCCESS(status) &&
3473  Irp->Tail.Overlay.Thread != NULL ) {
3474 
3475  //
3476  // Store DeviceObject for filesystem, and clear
3477  // in IoStatus.Information field.
3478  //
3479 
3481  Irp->IoStatus.Information = 0;
3482  }
3483 
3484  //
3485  // If pending has be returned for this irp then mark the current stack as
3486  // pending.
3487  //
3488 
3489  if (Irp->PendingReturned) {
3491  }
3492 
3493  {
3494  KIRQL oldIrql = KeRaiseIrqlToDpcLevel();
3496  KeLowerIrql(oldIrql);
3497  }
3499 
3500  return status;
3501 }
3502 
3503 VOID
3504 NTAPI
3506  IN PDEVICE_OBJECT Fdo,
3507  IN PIRP OriginalIrp,
3508  IN PIRP NewIrp,
3510  )
3511 {
3512  PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(OriginalIrp);
3513  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3514  PCDB cdb = (PCDB)Srb->Cdb;
3515  PVOID dataBuffer;
3516 
3518  USHORT dataLength;
3519  ULONG blockNumber;
3520  PFOUR_BYTE fourByte;
3521 
3522  dataLength =
3523  (USHORT)currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
3524 
3525  request = OriginalIrp->AssociatedIrp.SystemBuffer;
3526  blockNumber =
3527  (ULONG)(request->BlockByteOffset.QuadPart >> fdoExtension->SectorShift);
3528  fourByte = (PFOUR_BYTE) &blockNumber;
3529 
3530  Srb->CdbLength = 12;
3531  Srb->TimeOutValue = fdoExtension->TimeOutValue;
3532  Srb->SrbFlags = fdoExtension->SrbFlags;
3533  SET_FLAG(Srb->SrbFlags, SRB_FLAGS_DATA_IN);
3534 
3535  cdb->READ_DVD_STRUCTURE.OperationCode = SCSIOP_READ_DVD_STRUCTURE;
3536  cdb->READ_DVD_STRUCTURE.RMDBlockNumber[0] = fourByte->Byte3;
3537  cdb->READ_DVD_STRUCTURE.RMDBlockNumber[1] = fourByte->Byte2;
3538  cdb->READ_DVD_STRUCTURE.RMDBlockNumber[2] = fourByte->Byte1;
3539  cdb->READ_DVD_STRUCTURE.RMDBlockNumber[3] = fourByte->Byte0;
3540  cdb->READ_DVD_STRUCTURE.LayerNumber = request->LayerNumber;
3541  cdb->READ_DVD_STRUCTURE.Format = (UCHAR)request->Format;
3542 
3543 #if DBG
3544  {
3545  if ((UCHAR)request->Format > DvdMaxDescriptor) {
3547  "READ_DVD_STRUCTURE format %x = %s (%x bytes)\n",
3548  (UCHAR)request->Format,
3549  READ_DVD_STRUCTURE_FORMAT_STRINGS[DvdMaxDescriptor],
3550  dataLength
3551  ));
3552  } else {
3554  "READ_DVD_STRUCTURE format %x = %s (%x bytes)\n",
3555  (UCHAR)request->Format,
3556  READ_DVD_STRUCTURE_FORMAT_STRINGS[(UCHAR)request->Format],
3557  dataLength
3558  ));
3559  }
3560  }
3561 #endif // DBG
3562 
3563  if (request->Format == DvdDiskKeyDescriptor) {
3564 
3565  cdb->READ_DVD_STRUCTURE.AGID = (UCHAR) request->SessionId;
3566 
3567  }
3568 
3569  cdb->READ_DVD_STRUCTURE.AllocationLength[0] = (UCHAR)(dataLength >> 8);
3570  cdb->READ_DVD_STRUCTURE.AllocationLength[1] = (UCHAR)(dataLength & 0xff);
3571  Srb->DataTransferLength = dataLength;
3572 
3573 
3574 
3576  dataLength,
3578 
3579  if (!dataBuffer) {
3580  ExFreePool(Srb->SenseInfoBuffer);
3581  ExFreePool(Srb);
3582  IoFreeIrp(NewIrp);
3583  OriginalIrp->IoStatus.Information = 0;
3584  OriginalIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3585 
3586  BAIL_OUT(OriginalIrp);
3587  CdRomCompleteIrpAndStartNextPacketSafely(Fdo, OriginalIrp);
3588  return;
3589  }
3590  RtlZeroMemory(dataBuffer, dataLength);
3591 
3592  NewIrp->MdlAddress = IoAllocateMdl(dataBuffer,
3593  currentIrpStack->Parameters.Read.Length,
3594  FALSE,
3595  FALSE,
3596  (PIRP) NULL);
3597 
3598  if (NewIrp->MdlAddress == NULL) {
3599  ExFreePool(dataBuffer);
3600  ExFreePool(Srb->SenseInfoBuffer);
3601  ExFreePool(Srb);
3602  IoFreeIrp(NewIrp);
3603  OriginalIrp->IoStatus.Information = 0;
3604  OriginalIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3605 
3606  BAIL_OUT(OriginalIrp);
3607  CdRomCompleteIrpAndStartNextPacketSafely(Fdo, OriginalIrp);
3608  return;
3609  }
3610 
3611  //
3612  // Prepare the MDL
3613  //
3614 
3615  MmBuildMdlForNonPagedPool(NewIrp->MdlAddress);
3616 
3617  Srb->DataBuffer = dataBuffer;
3618 
3619  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, NewIrp);
3620 
3621  return;
3622 }
3623 
3624 VOID
3625 NTAPI
3627  IN PDEVICE_OBJECT Fdo,
3628  IN PIRP OriginalIrp,
3629  IN PIRP NewIrp,
3631  )
3632 {
3633  //PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(OriginalIrp);
3634  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3635  PCDB cdb = (PCDB)Srb->Cdb;
3636 
3637  PDVD_SESSION_ID sessionId = OriginalIrp->AssociatedIrp.SystemBuffer;
3638 
3639  Srb->CdbLength = 12;
3640  Srb->TimeOutValue = fdoExtension->TimeOutValue;
3641  Srb->SrbFlags = fdoExtension->SrbFlags;
3643 
3644  cdb->SEND_KEY.OperationCode = SCSIOP_SEND_KEY;
3645  cdb->SEND_KEY.AGID = (UCHAR) (*sessionId);
3646  cdb->SEND_KEY.KeyFormat = DVD_INVALIDATE_AGID;
3647 
3648  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, NewIrp);
3649  return;
3650 
3651 }
3652 
3653 VOID
3654 NTAPI
3656  IN PDEVICE_OBJECT Fdo,
3657  IN PIRP OriginalIrp,
3658  IN PIRP NewIrp,
3660  )
3661 {
3662  PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(OriginalIrp);
3663  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3664  PCDB cdb = (PCDB)Srb->Cdb;
3665  NTSTATUS status;
3666 
3667  PDVD_COPY_PROTECT_KEY keyParameters;
3668  PCDVD_KEY_HEADER keyBuffer = NULL;
3669 
3670  ULONG keyLength;
3671 
3672  ULONG allocationLength;
3673  PFOUR_BYTE fourByte;
3674 
3675  //
3676  // Both of these use REPORT_KEY commands.
3677  // Determine the size of the input buffer
3678  //
3679 
3680  if(currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
3682 
3683  keyParameters = OriginalIrp->AssociatedIrp.SystemBuffer;
3684 
3685  keyLength = sizeof(CDVD_KEY_HEADER) +
3686  (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength -
3687  sizeof(DVD_COPY_PROTECT_KEY));
3688  } else {
3689 
3690  keyParameters = NULL;
3691  keyLength = sizeof(CDVD_KEY_HEADER) +
3692  sizeof(CDVD_REPORT_AGID_DATA);
3693  }
3694 
3695  TRY {
3696 
3698  keyLength,
3700 
3701  if(keyBuffer == NULL) {
3702 
3704  "IOCTL_DVD_READ_KEY - couldn't allocate "
3705  "%d byte buffer for key\n",
3706  keyLength));
3708  LEAVE;
3709  }
3710 
3711 
3712  NewIrp->MdlAddress = IoAllocateMdl(keyBuffer,
3713  keyLength,
3714  FALSE,
3715  FALSE,
3716  (PIRP) NULL);
3717 
3718  if(NewIrp->MdlAddress == NULL) {
3719 
3721  "IOCTL_DVD_READ_KEY - couldn't create mdl\n"));
3723  LEAVE;
3724  }
3725 
3726  MmBuildMdlForNonPagedPool(NewIrp->MdlAddress);
3727 
3728  Srb->DataBuffer = keyBuffer;
3729  Srb->CdbLength = 12;
3730 
3731  cdb->REPORT_KEY.OperationCode = SCSIOP_REPORT_KEY;
3732 
3733  allocationLength = keyLength;
3734  fourByte = (PFOUR_BYTE) &allocationLength;
3735  cdb->REPORT_KEY.AllocationLength[0] = fourByte->Byte1;
3736  cdb->REPORT_KEY.AllocationLength[1] = fourByte->Byte0;
3737 
3738  Srb->DataTransferLength = keyLength;
3739 
3740  //
3741  // set the specific parameters....
3742  //
3743 
3744  if(currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
3746 
3747  if(keyParameters->KeyType == DvdTitleKey) {
3748 
3749  ULONG logicalBlockAddress;
3750 
3751  logicalBlockAddress = (ULONG)
3752  (keyParameters->Parameters.TitleOffset.QuadPart >>
3753  fdoExtension->SectorShift);
3754 
3755  fourByte = (PFOUR_BYTE) &(logicalBlockAddress);
3756 
3757  cdb->REPORT_KEY.LogicalBlockAddress[0] = fourByte->Byte3;
3758  cdb->REPORT_KEY.LogicalBlockAddress[1] = fourByte->Byte2;
3759  cdb->REPORT_KEY.LogicalBlockAddress[2] = fourByte->Byte1;
3760  cdb->REPORT_KEY.LogicalBlockAddress[3] = fourByte->Byte0;
3761  }
3762 
3763  cdb->REPORT_KEY.KeyFormat = (UCHAR)keyParameters->KeyType;
3764  cdb->REPORT_KEY.AGID = (UCHAR) keyParameters->SessionId;
3766  "CdRomDvdReadKey => sending irp %p for irp %p (%s)\n",
3767  NewIrp, OriginalIrp, "READ_KEY"));
3768 
3769  } else {
3770 
3771  cdb->REPORT_KEY.KeyFormat = DVD_REPORT_AGID;
3772  cdb->REPORT_KEY.AGID = 0;
3774  "CdRomDvdReadKey => sending irp %p for irp %p (%s)\n",
3775  NewIrp, OriginalIrp, "START_SESSION"));
3776  }
3777 
3778  Srb->TimeOutValue = fdoExtension->TimeOutValue;
3779  Srb->SrbFlags = fdoExtension->SrbFlags;
3780  SET_FLAG(Srb->SrbFlags, SRB_FLAGS_DATA_IN);
3781 
3782  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, NewIrp);
3783 
3785 
3786  } FINALLY {
3787 
3788  if (!NT_SUCCESS(status)) {
3789 
3790  //
3791  // An error occured during setup - free resources and
3792  // complete this request.
3793  //
3794  if (NewIrp->MdlAddress != NULL) {
3795  IoFreeMdl(NewIrp->MdlAddress);
3796  }
3797 
3798  if (keyBuffer != NULL) {
3799  ExFreePool(keyBuffer);
3800  }
3801  ExFreePool(Srb->SenseInfoBuffer);
3802  ExFreePool(Srb);
3803  IoFreeIrp(NewIrp);
3804 
3805  OriginalIrp->IoStatus.Information = 0;
3806  OriginalIrp->IoStatus.Status = status;
3807 
3808  BAIL_OUT(OriginalIrp);
3809  CdRomCompleteIrpAndStartNextPacketSafely(Fdo, OriginalIrp);
3810 
3811  } // end !NT_SUCCESS
3812  }
3813  return;
3814 }
3815 
3816 VOID
3817 NTAPI
3819  IN PDEVICE_OBJECT Fdo,
3820  IN PIRP OriginalIrp,
3821  IN PIRP NewIrp,
3823  )
3824 {
3825  //PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(OriginalIrp);
3826  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3827  PCDB cdb = (PCDB)Srb->Cdb;
3828 
3830  PCDVD_KEY_HEADER keyBuffer = NULL;
3831 
3832  NTSTATUS status;
3833  ULONG keyLength;
3834  PFOUR_BYTE fourByte;
3835 
3836  key = OriginalIrp->AssociatedIrp.SystemBuffer;
3837  keyLength = (key->KeyLength - sizeof(DVD_COPY_PROTECT_KEY)) +
3838  sizeof(CDVD_KEY_HEADER);
3839 
3840  TRY {
3841 
3843  keyLength,
3845 
3846  if(keyBuffer == NULL) {
3847 
3849  "IOCTL_DVD_SEND_KEY - couldn't allocate "
3850  "%d byte buffer for key\n",
3851  keyLength));
3853  LEAVE;
3854  }
3855 
3856  RtlZeroMemory(keyBuffer, keyLength);
3857 
3858  //
3859  // keylength is decremented here by two because the
3860  // datalength does not include the header, which is two
3861  // bytes. keylength is immediately incremented later
3862  // by the same amount.
3863  //
3864 
3865  keyLength -= 2;
3866  fourByte = (PFOUR_BYTE) &keyLength;
3867  keyBuffer->DataLength[0] = fourByte->Byte1;
3868  keyBuffer->DataLength[1] = fourByte->Byte0;
3869  keyLength += 2;
3870 
3871  //
3872  // copy the user's buffer to our own allocated buffer
3873  //
3874 
3875  RtlMoveMemory(keyBuffer->Data,
3876  key->KeyData,
3877  key->KeyLength - sizeof(DVD_COPY_PROTECT_KEY));
3878 
3879 
3880  NewIrp->MdlAddress = IoAllocateMdl(keyBuffer,
3881  keyLength,
3882  FALSE,
3883  FALSE,
3884  (PIRP) NULL);
3885 
3886  if(NewIrp->MdlAddress == NULL) {
3888  "IOCTL_DVD_SEND_KEY - couldn't create mdl\n"));
3890  LEAVE;
3891  }
3892 
3893 
3894  MmBuildMdlForNonPagedPool(NewIrp->MdlAddress);
3895 
3896  Srb->CdbLength = 12;
3897  Srb->DataBuffer = keyBuffer;
3898  Srb->DataTransferLength = keyLength;
3899 
3900  Srb->TimeOutValue = fdoExtension->TimeOutValue;
3901  Srb->SrbFlags = fdoExtension->SrbFlags;
3902  SET_FLAG(Srb->SrbFlags, SRB_FLAGS_DATA_OUT);
3903 
3904  cdb->REPORT_KEY.OperationCode = SCSIOP_SEND_KEY;
3905 
3906  fourByte = (PFOUR_BYTE) &keyLength;
3907 
3908  cdb->SEND_KEY.ParameterListLength[0] = fourByte->Byte1;
3909  cdb->SEND_KEY.ParameterListLength[1] = fourByte->Byte0;
3910  cdb->SEND_KEY.KeyFormat = (UCHAR)key->KeyType;
3911  cdb->SEND_KEY.AGID = (UCHAR) key->SessionId;
3912 
3913  if (key->KeyType == DvdSetRpcKey) {
3915  "IOCTL_DVD_SEND_KEY - Setting RPC2 drive region\n"));
3916  } else {
3918  "IOCTL_DVD_SEND_KEY - key type %x\n", key->KeyType));
3919  }
3920 
3921  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, NewIrp);
3922 
3924 
3925  } FINALLY {
3926 
3927  if (!NT_SUCCESS(status)) {
3928 
3929  //
3930  // An error occured during setup - free resources and
3931  // complete this request.
3932  //
3933 
3934  if (NewIrp->MdlAddress != NULL) {
3935  IoFreeMdl(NewIrp->MdlAddress);
3936  }
3937 
3938  if (keyBuffer != NULL) {
3939  ExFreePool(keyBuffer);
3940  }
3941 
3942  ExFreePool(Srb->SenseInfoBuffer);
3943  ExFreePool(Srb);
3944  IoFreeIrp(NewIrp);
3945 
3946  OriginalIrp->IoStatus.Information = 0;
3947  OriginalIrp->IoStatus.Status = status;
3948 
3949  BAIL_OUT(OriginalIrp);
3950  CdRomCompleteIrpAndStartNextPacketSafely(Fdo, OriginalIrp);
3951 
3952  }
3953  }
3954 
3955  return;
3956 }
3957 
3958 VOID
3959 NTAPI
3961  IN PDEVICE_OBJECT Fdo,
3962  IN PREAD_CAPACITY_DATA ReadCapacityBuffer
3963  )
3964 {
3965  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3966  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
3967  ULONG lastSector;
3968  ULONG bps;
3969  ULONG lastBit;
3970  ULONG tmp;
3971 
3972  ASSERT(ReadCapacityBuffer);
3973  ASSERT(commonExtension->IsFdo);
3974 
3976  "CdRomInterpretReadCapacity: Entering\n"));
3977 
3978  //
3979  // Swizzle bytes from Read Capacity and translate into
3980  // the necessary geometry information in the device extension.
3981  //
3982 
3983  tmp = ReadCapacityBuffer->BytesPerBlock;
3984  ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3985  ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3986  ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3987  ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3988 
3989  //
3990  // Insure that bps is a power of 2.
3991  // This corrects a problem with the HP 4020i CDR where it
3992  // returns an incorrect number for bytes per sector.
3993  //
3994 
3995  if (!bps) {
3996  bps = 2048;
3997  } else {
3998  lastBit = (ULONG) -1;
3999  while (bps) {
4000  lastBit++;
4001  bps = bps >> 1;
4002  }
4003  bps = 1 << lastBit;
4004  }
4005 
4006  fdoExtension->DiskGeometry.BytesPerSector = bps;
4007 
4008  TraceLog((CdromDebugTrace, "CdRomInterpretReadCapacity: Calculated bps %#x\n",
4009  fdoExtension->DiskGeometry.BytesPerSector));
4010 
4011  //
4012  // Copy last sector in reverse byte order.
4013  //
4014 
4015  tmp = ReadCapacityBuffer->LogicalBlockAddress;
4016  ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
4017  ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
4018  ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
4019  ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
4020 
4021  //
4022  // Calculate sector to byte shift.
4023  //
4024 
4025  WHICH_BIT(bps, fdoExtension->SectorShift);
4026 
4027  TraceLog((CdromDebugTrace,"CdRomInterpretReadCapacity: Sector size is %d\n",
4028  fdoExtension->DiskGeometry.BytesPerSector));
4029 
4030  TraceLog((CdromDebugTrace,"CdRomInterpretReadCapacity: Number of Sectors is %d\n",
4031  lastSector + 1));
4032 
4033  //
4034  // Calculate media capacity in bytes.
4035  //
4036 
4037  commonExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
4038 
4039  //
4040  // we've defaulted to 32/64 forever. don't want to change this now...
4041  //
4042 
4043  fdoExtension->DiskGeometry.TracksPerCylinder = 0x40;
4044  fdoExtension->DiskGeometry.SectorsPerTrack = 0x20;
4045 
4046  //
4047  // Calculate number of cylinders.
4048  //
4049 
4050  fdoExtension->DiskGeometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1) / (32 * 64));
4051 
4052  commonExtension->PartitionLength.QuadPart =
4053  (commonExtension->PartitionLength.QuadPart << fdoExtension->SectorShift);
4054 
4055 
4056  ASSERT(TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA));
4057 
4058  //
4059  // This device supports removable media.
4060  //
4061 
4062  fdoExtension->DiskGeometry.MediaType = RemovableMedia;
4063 
4064  return;
4065 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
signed char * PCHAR
Definition: retypes.h:7
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define FINALLY
Definition: classpnp.h:113
struct _FOUR_BYTE * PFOUR_BYTE
#define IOCTL_CDROM_GET_CONTROL
Definition: ntddcdrm.h:43
#define MAX_COPY_PROTECT_AGID
Definition: cdrom.h:314
ULONG * PDVD_SESSION_ID
Definition: cdrw_usr.h:1544
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:131
VOID NTAPI ClassReleaseQueue(IN PDEVICE_OBJECT Fdo)
Definition: class.c:8160
#define IOCTL_STORAGE_SET_READ_AHEAD
Definition: cdrw_usr.h:186
LARGE_INTEGER PartitionLength
Definition: classpnp.h:594
struct _CDB::_MODE_SELECT10 MODE_SELECT10
#define DVD_TITLE_KEY_LENGTH
Definition: cdrw_usr.h:1595
#define MODE_SELECT_IMMEDIATE
Definition: scsi.h:729
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
UCHAR Rpc0SystemRegionResetCount
Definition: cdrom.h:247
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _KEVENT * PKEVENT
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
#define XA_NOT_SUPPORTED
Definition: cdrom.c:211
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
ULONG SrbFlags
Definition: srb.h:252
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
struct _DEVICE_MEDIA_INFO::@3028::@3030 RemovableDiskInfo
UCHAR DataLength[2]
Definition: cdrw_hw.h:3581
UCHAR Cdb[16]
Definition: srb.h:271
#define KeWaitForMutexObject
Definition: kefuncs.h:568
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define DVD_REPORT_AGID
Definition: scsi.h:128
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
_In_ PIRP Irp
Definition: csq.h:116
struct _CDB::_REPORT_KEY REPORT_KEY
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PVOID DataBuffer
Definition: srb.h:255
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:34
SUB_Q_HEADER Header
Definition: ntddcdrm.h:314
#define IOCTL_CDROM_GET_CONFIGURATION
Definition: ntddcdrm.h:40
DVD_STRUCTURE_FORMAT
Definition: ntddcdvd.h:69
ULONG Rpc0RetryRegistryCallback
Definition: cdrom.h:249
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG DataTransferLength
Definition: srb.h:253
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR PreferredDriveRegionCode
Definition: ntddcdvd.h:193
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define SCSIOP_SEND_KEY
Definition: cdrw_hw.h:951
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define LEAVE
Definition: classpnp.h:112
NTSTATUS NTAPI CdRomDvdReadDiskKeyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:3247
VOID NTAPI ClassSendDeviceIoControlSynchronous(IN ULONG IoControlCode, IN PDEVICE_OBJECT TargetDeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, OUT PIO_STATUS_BLOCK IoStatus)
Definition: class.c:7660
struct _DVD_LAYER_DESCRIPTOR * PDVD_LAYER_DESCRIPTOR
#define MINIMUM_CDROM_READ_TOC_EX_SIZE
Definition: ntddcdrm.h:100
#define TRY(sps, bps)
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:52
#define SCSIOP_REPORT_KEY
Definition: cdrw_hw.h:952
#define CDROM_AUDIO_CONTROL_PAGE
Definition: scsi.h:728
UCHAR Data[0]
Definition: scsi.h:1736
ULONG SectorCount
Definition: ntddcdrm.h:353
LARGE_INTEGER BlockByteOffset
Definition: ntddcdvd.h:80
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
UCHAR CdbLength
Definition: srb.h:250
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
UCHAR SystemRegion
Definition: ntddcdvd.h:206
#define DVD_TAG_READ_KEY
Definition: cdrom.h:343
UCHAR RpcScheme
Definition: scsi.h:2927
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:82
ULONG BytesPerSector
Definition: ntdddisk.h:376
ULONG TracksPerCylinder
Definition: ntdddisk.h:374
static VOID CdRomCompleteIrpAndStartNextPacketSafely(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.h:407
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
struct _PARTITION_INFORMATION PARTITION_INFORMATION
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
ULONG TimeOutValue
Definition: srb.h:254
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define DVD_ASF_LENGTH
Definition: cdrw_usr.h:1599
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
NTSTATUS NTAPI CdRomSetVolumeIntermediateCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:2827
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
LARGE_INTEGER Length
Definition: imports.h:232
UCHAR LbaFormat
Definition: scsi.h:2613
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID NTAPI CdRomDeviceControlDvdSendKey(IN PDEVICE_OBJECT Fdo, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: ioctl.c:3818
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:49
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:64
struct __RAW_READ_INFO * PRAW_READ_INFO
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
NTSTATUS NTAPI CdRomDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: ioctl.c:45
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:85
uint32_t ULONG_PTR
Definition: typedefs.h:63
LARGE_INTEGER DiskSize
Definition: ntdddisk.h:381
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT
Definition: ntddmmc.h:16
struct _DVD_COPYRIGHT_DESCRIPTOR * PDVD_COPYRIGHT_DESCRIPTOR
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _CDB::_SEND_KEY SEND_KEY
union _DEVICE_MEDIA_INFO::@3028 DeviceSpecific
PDEVICE_OBJECT DeviceObject
Definition: kstypes.h:153
#define DVD_BUS_KEY_LENGTH
Definition: cdrw_usr.h:1594
VOID NTAPI CdRomPickDvdRegion(IN PDEVICE_OBJECT Fdo)
Definition: cdrom.c:5890
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _AUDIO_OUTPUT AUDIO_OUTPUT
NTSTATUS NTAPI ClassSendSrbSynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:2648
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
GLenum GLint GLuint mask
Definition: glext.h:6028
#define IO_DISK_INCREMENT
Definition: iotypes.h:567
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS NTAPI CdRomXACompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:3323
struct _DVD_RPC_KEY * PDVD_RPC_KEY
__inline ULONG CountOfSetBitsUChar(UCHAR _X)
Definition: tools.h:150
#define IOCTL_CDROM_MEDIA_CATALOG
Definition: cdrw_usr.h:1355
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UCHAR ScsiStatus
Definition: srb.h:244
UCHAR UserResetsAvailable
Definition: scsi.h:2923
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:91
VOID NTAPI CdRomDeviceControlDvdEndSession(IN PDEVICE_OBJECT Fdo, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: ioctl.c:3626
DISK_GEOMETRY Geometry
Definition: ntdddisk.h:380
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:82
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1875
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_CSS_RESETS_EXHAUSTED
Definition: ntstatus.h:873
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:134
union _CDB * PCDB
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:61
#define IOCTL_DVD_END_SESSION
Definition: cdrw_usr.h:162
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1779
UCHAR ChannelSelection
Definition: scsi.h:2604
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
#define DBG(x)
Definition: moztest.c:12
PVOID NTAPI ClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class.c:4209
#define DVD_TAG_READ_STRUCTURE
Definition: cdrom.h:342
void * PVOID
Definition: retypes.h:9
struct _READ_DVD_STRUCTURES_HEADER READ_DVD_STRUCTURES_HEADER
#define CDROM_READ_TOC_EX_FORMAT_PMA
Definition: ntddcdrm.h:132
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
#define AUDIO_STATUS_IN_PROGRESS
Definition: ntddcdrm.h:281
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
struct _CDB::_MODE_SELECT MODE_SELECT
UCHAR ParameterLength
Definition: scsi.h:2610
PORT_OUTPUT PortOutput[4]
Definition: scsi.h:2615
#define TraceLog(x)
Definition: trace.h:14
#define PCHAR
Definition: match.c:90
BOOLEAN DvdRpc0Device
Definition: cdrom.h:244
BOOLEAN DvdRpc0LicenseFailure
Definition: cdrom.h:245
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
NTSTATUS NTAPI CdRomDvdEndAllSessionsCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:3173
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
struct _GET_MEDIA_TYPES GET_MEDIA_TYPES
int64_t LONGLONG
Definition: typedefs.h:66
#define CTL_CODE(DeviceType, Function, Method, Access)
Definition: nt_native.h:586
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
UCHAR Rpc0SystemRegion
Definition: cdrom.h:246
struct _DVD_REGION DVD_REGION
GLsizeiptr size
Definition: glext.h:5919
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:46
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:372
#define COOKED_SECTOR_SIZE
Definition: cdrom.c:175
ULONG WriteAllowed
Definition: cdrom.h:123
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
UCHAR ManufacturerResetsAvailable
Definition: scsi.h:2924
struct _AUDIO_OUTPUT * PAUDIO_OUTPUT
KMUTEX Rpc0RegionMutex
Definition: cdrom.h:251
#define IOCTL_CDROM_GET_VOLUME
Definition: ntddcdrm.h:55
struct _DVD_COPY_PROTECT_KEY DVD_COPY_PROTECT_KEY
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
#define DVD_INVALIDATE_AGID
Definition: scsi.h:134
#define IOCTL_DVD_SEND_KEY
Definition: cdrw_usr.h:161
#define DVD_CHALLENGE_KEY_LENGTH
Definition: cdrw_usr.h:1593
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
NTSTATUS NTAPI CdRomSetRpc0Settings(IN PDEVICE_OBJECT Fdo, IN UCHAR NewRegion)
Definition: sec.c:26
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
#define REVERSE_LONG(Long)
Definition: scsi.h:2731
#define MEDIA_READ_WRITE
Definition: minitape.h:34
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define DVD_SET_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1598
UCHAR CopySystem
Definition: ntddcdvd.h:204
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI CdRomDeviceControlDvdReadStructure(IN PDEVICE_OBJECT Fdo, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: ioctl.c:3505
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
DVD_KEY_TYPE KeyType
Definition: ntddcdvd.h:139
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
UCHAR CodePage
Definition: scsi.h:2609
NTSTATUS NTAPI CdRomRetryRequest(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN ULONG Delay, IN BOOLEAN ResendIrp)
Definition: cdrom.c:6371
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
UCHAR Volume
Definition: scsi.h:2605
struct _DISK_GEOMETRY * PDISK_GEOMETRY
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
#define CDROM_TAG_VOLUME_INT
Definition: cdrom.h:340
ULONG DVD_SESSION_ID
Definition: cdrw_usr.h:1544
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL
Definition: ntddmmc.h:15
struct _CDB::_READ_DVD_STRUCTURE READ_DVD_STRUCTURE
ULONG DeviceType
Definition: ntddstor.h:402
struct DVD_READ_STRUCTURE DVD_READ_STRUCTURE
struct _CDVD_REPORT_AGID_DATA * PCDVD_REPORT_AGID_DATA
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
UCHAR RegionMask
Definition: scsi.h:2926
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE
Definition: ntddmmc.h:17
#define IOCTL_DVD_READ_KEY
Definition: cdrw_usr.h:160
UCHAR AbsoluteAddress[4]
Definition: ntddcdrm.h:320
#define DVD_DISK_KEY_LENGTH
Definition: cdrw_usr.h:1596
#define DVD_END_ALL_SESSIONS
Definition: ntddcdvd.h:156
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG MediaInfoCount
Definition: ntddstor.h:403
UCHAR PortVolume[4]
Definition: ntddcdrm.h:342
#define DVD_TAG_RPC2_CHECK
Definition: cdrom.h:345
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:58
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_DVD_GET_REGION
Definition: cdrw_usr.h:164
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define CDROM_READ_TOC_EX_FORMAT_TOC
Definition: ntddcdrm.h:129
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:76
SUB_Q_TRACK_ISRC TrackIsrc
Definition: ntddcdrm.h:327
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:79
VOID NTAPI CdRomInterpretReadCapacity(IN PDEVICE_OBJECT Fdo, IN PREAD_CAPACITY_DATA ReadCapacityBuffer)
Definition: ioctl.c:3960
struct _CDVD_KEY_HEADER CDVD_KEY_HEADER
#define DVD_TAG_SEND_KEY
Definition: cdrom.h:344
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _DISK_GEOMETRY DISK_GEOMETRY
USHORT XAFlags
Definition: cdrom.c:82
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:138
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
#define REVERSE_SHORT(Short)
Definition: scsi.h:2723
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
SUB_Q_HEADER Header
Definition: ntddcdrm.h:303
struct _CDROM_TOC CDROM_TOC
#define MEDIA_CURRENTLY_MOUNTED
Definition: minitape.h:36
UCHAR AudioStatus
Definition: ntddcdrm.h:289
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
#define CDROM_READ_TOC_EX_FORMAT_ATIP
Definition: ntddcdrm.h:133
SUB_Q_CURRENT_POSITION CurrentPosition
Definition: ntddcdrm.h:325
#define IOCTL_CDROM_TRACK_ISRC
Definition: cdrw_usr.h:1356
unsigned short USHORT
Definition: pedump.c:61
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:76
struct _GET_CONFIGURATION_HEADER GET_CONFIGURATION_HEADER
BOOLEAN NTAPI CdRomIsPlayActive(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5743
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
DEVICE_TYPE NTAPI CdRomGetDeviceType(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5493
#define XA_USE_6_BYTE
Definition: cdrom.c:208
struct _DVD_SET_RPC_KEY * PDVD_SET_RPC_KEY
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define MmGetMdlByteCount(_Mdl)
struct _CDROM_AUDIO_CONTROL CDROM_AUDIO_CONTROL
#define CDROM_READ_TOC_EX_FORMAT_SESSION
Definition: ntddcdrm.h:130
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
struct _CDROM_TOC_SESSION_DATA CDROM_TOC_SESSION_DATA
#define IOCTL_DVD_SEND_KEY2
Definition: cdrw_usr.h:165
#define MEDIA_READ_ONLY
Definition: minitape.h:33
NTSTATUS NTAPI CdRomDeviceControlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:2054
#define MAXUSHORT
Definition: typedefs.h:81
Definition: tftpd.h:85
#define SCSIOP_READ_DVD_STRUCTURE
Definition: cdrw_hw.h:960
KIRQL irql
Definition: wave.h:1
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:157
#define CDB12GENERIC_LENGTH
Definition: cdrw_hw.h:832
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog
Definition: ntddcdrm.h:326
UCHAR TrackRelativeAddress[4]
Definition: ntddcdrm.h:321
PVOID SenseInfoBuffer
Definition: srb.h:256
struct _DEVICE_MEDIA_INFO DEVICE_MEDIA_INFO
#define BAIL_OUT(Irp)
Definition: cdrom.h:362
UCHAR ResetCount
Definition: ntddcdvd.h:207
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
DVD_STRUCTURE_FORMAT Format
Definition: ntddcdvd.h:81
PVOID PIRP
Definition: usb.h:38
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define PLAY_ACTIVE(DeviceExtension)
Definition: cdrom.c:190
#define DVD_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1597
#define RAW_SECTOR_SIZE
Definition: mcicda.c:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI CdRomUpdateCapacity(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP IrpToComplete, IN OPTIONAL PKEVENT IoctlEvent)
Definition: cdrom.c:7025
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:352
struct _DISK_GEOMETRY_EX * PDISK_GEOMETRY_EX
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:73
#define IOCTL_DVD_START_SESSION
Definition: cdrw_usr.h:159
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define CDROM_TAG_DC_EVENT
Definition: cdrom.h:322
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:70
#define SCSIOP_MODE_SELECT10
Definition: cdrw_hw.h:943
static SERVICE_STATUS status
Definition: service.c:31
#define STATUS_COPY_PROTECTION_FAILURE
Definition: ntstatus.h:867
UCHAR Immediate
Definition: scsi.h:2611
UCHAR RegionData
Definition: ntddcdvd.h:205
VOID NTAPI CdRomDeviceControlDvdStartSessionReadKey(IN PDEVICE_OBJECT Fdo, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: ioctl.c:3655
struct _DVD_DESCRIPTOR_HEADER * PDVD_DESCRIPTOR_HEADER
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
struct CFHEADER header
Definition: fdi.c:109
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
struct _VOLUME_CONTROL VOLUME_CONTROL
NTSTATUS NTAPI CdRomClassIoctlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:2010
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
LONGLONG QuadPart
Definition: typedefs.h:112
struct DVD_READ_STRUCTURE * PDVD_READ_STRUCTURE
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
DEVICE_MEDIA_INFO MediaInfo[1]
Definition: ntddstor.h:404
UCHAR LogicalBlocksPerSecond[2]
Definition: scsi.h:2614
Definition: path.c:42
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
UCHAR TypeCode
Definition: scsi.h:2925
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1846
#define STATUS_CSS_REGION_MISMATCH
Definition: ntstatus.h:872
#define IOCTL_DVD_READ_STRUCTURE
Definition: cdrw_usr.h:157
Definition: ps.c:97