ReactOS  0.4.14-dev-614-gbfd8a84
vcdrom.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS FS utility tool
4  * FILE: modules/rosapps/drivers/vcdrom/vcdrom.c
5  * PURPOSE: Virtual CD-ROM class driver
6  * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 #include <ntddk.h>
10 #include <ntifs.h>
11 #include <ntdddisk.h>
12 #include <ntddcdrm.h>
13 #include <pseh/pseh2.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 #include "vcdioctl.h"
19 
20 typedef struct _DEVICE_EXTENSION
21 {
23  /* File object to the ISO when opened */
25  /* Size of the ISO */
27  /* Mandatory change count for verify */
29  /* Will contain the device name or the drive letter */
31  /* Will contain the image path */
33  /* Flags on mount (supp. of UDF/Joliet) */
35  /* Faking CD structure */
39 
40 /* Taken from CDFS */
41 #define TOC_DATA_TRACK 0x04
42 #define TOC_LAST_TRACK 0xaa
43 
44 /* Should cover most of our usages */
45 #define DEFAULT_STRING_SIZE 50
46 
47 /* Increment on device creation, protection by the mutex */
50 
51 VOID
53 {
54  PDEVICE_EXTENSION DeviceExtension;
55 
56  DeviceExtension = DeviceObject->DeviceExtension;
57 
58  /* Zero mandatory fields, the rest will be zeroed when needed */
59  DeviceExtension->DeviceObject = DeviceObject;
60  DeviceExtension->VolumeObject = NULL;
61  DeviceExtension->ChangeCount = 0;
62  DeviceExtension->GlobalName.Buffer = NULL;
63  DeviceExtension->GlobalName.MaximumLength = 0;
64  DeviceExtension->GlobalName.Length = 0;
65  DeviceExtension->ImageName.Buffer = NULL;
66  DeviceExtension->ImageName.MaximumLength = 0;
67  DeviceExtension->ImageName.Length = 0;
68 }
69 
72 {
73  PVOID Buffer;
74 
75  /* Allocate the buffer */
77  /* Initialize */
78  UnicodeString->Length = 0;
79  UnicodeString->MaximumLength = BufferLength;
80  UnicodeString->Buffer = Buffer;
81 
82  /* Return success if it went fine */
83  if (Buffer != NULL)
84  {
85  return STATUS_SUCCESS;
86  }
87 
88  return STATUS_NO_MEMORY;
89 }
90 
91 VOID
93 {
94  /* Only free if allocate, that allows using this
95  * on cleanup in short memory situations
96  */
97  if (UnicodeString->Buffer != NULL)
98  {
99  ExFreePoolWithTag(UnicodeString->Buffer, 0);
100  UnicodeString->Buffer = NULL;
101  }
102 
103  /* Zero the rest */
104  UnicodeString->Length = 0;
105  UnicodeString->MaximumLength = 0;
106 }
107 
108 NTSTATUS
110 {
111  /* Only set what we got */
112  Irp->IoStatus.Information = Information;
113  Irp->IoStatus.Status = Status;
114 
115  /* And return the status, so that caller can return with us */
116  return Status;
117 }
118 
119 NTSTATUS
120 NTAPI
122 {
123  /* Stub for CREATE, CLEANUP, CLOSE, always a succes */
126 
127  return STATUS_SUCCESS;
128 }
129 
130 NTSTATUS
132 {
134  PDEVICE_EXTENSION DeviceExtension;
135 
136  DeviceExtension = DeviceObject->DeviceExtension;
137 
138  /* Delete the drive letter */
139  Status = IoDeleteSymbolicLink(&DeviceExtension->GlobalName);
140  ViFreeUnicodeString(&DeviceExtension->GlobalName);
141 
142  /* Close the ISO */
143  if (DeviceExtension->VolumeObject != NULL)
144  {
145  ObDereferenceObject(DeviceExtension->VolumeObject);
146  DeviceExtension->VolumeObject = NULL;
147  }
148 
149  /* Free the ISO name */
150  ViFreeUnicodeString(&DeviceExtension->ImageName);
151 
152  /* And delete the device */
154  return ViSetIoStatus(Status, 0, Irp);
155 }
156 
157 VOID
158 NTAPI
160 {
161  IRP FakeIrp;
163 
164  /* No device, nothing to free */
166  if (DeviceObject == NULL)
167  {
168  return;
169  }
170 
171  /* Delete any device we could have created */
172  do
173  {
174  PDEVICE_OBJECT NextDevice;
175 
176  NextDevice = DeviceObject->NextDevice;
177  /* This is normally called on IoCtl, so fake
178  * the IRP so that status can be dummily set
179  */
180  ViDeleteDevice(DeviceObject, &FakeIrp);
181  DeviceObject = NextDevice;
182  } while (DeviceObject != NULL);
183 }
184 
185 NTSTATUS
187 {
189  HANDLE LinkHandle;
190  WCHAR DriveLetter[3], CurLetter;
191  PDEVICE_OBJECT LocalDeviceObject;
192  PDEVICE_EXTENSION DeviceExtension;
195 
196  *DeviceObject = NULL;
197 
198  /* Allocate our buffers */
201 
202  /* For easier cleanup */
203  _SEH2_TRY
204  {
205  /* Get our device number */
208  ++ViDevicesCount;
210 
211  /* Conversion to string failed, bail out */
212  if (!NT_SUCCESS(Status))
213  {
214  _SEH2_LEAVE;
215  }
216 
217  /* Create our device name */
218  Status = RtlAppendUnicodeToString(&DeviceName, L"\\Device\\VirtualCdRom");
219  if (!NT_SUCCESS(Status))
220  {
221  _SEH2_LEAVE;
222  }
223 
225  if (!NT_SUCCESS(Status))
226  {
227  _SEH2_LEAVE;
228  }
229 
230  /* And create the device! */
234  FALSE, &LocalDeviceObject);
235  if (!NT_SUCCESS(Status))
236  {
237  _SEH2_LEAVE;
238  }
239 
240  /* Initialize our DE */
241  ViInitializeDeviceExtension(LocalDeviceObject);
242  DeviceExtension = LocalDeviceObject->DeviceExtension;
243  ViAllocateUnicodeString(DEFAULT_STRING_SIZE, &DeviceExtension->GlobalName);
244 
245  /* Now, we'll try to find a free drive letter
246  * We always start from Z and go backward
247  */
248  for (CurLetter = Letter; CurLetter >= 'A'; CurLetter--)
249  {
250  /* By default, no flags. These will be set
251  * on mount, by the caller
252  */
253  DeviceExtension->Flags = 0;
254 
255  /* Create a drive letter name */
256  DeviceExtension->GlobalName.Length = 0;
257  Status = RtlAppendUnicodeToString(&DeviceExtension->GlobalName, L"\\??\\");
258  if (!NT_SUCCESS(Status))
259  {
260  _SEH2_LEAVE;
261  }
262 
263  DriveLetter[0] = CurLetter;
264  DriveLetter[1] = L':';
265  DriveLetter[2] = UNICODE_NULL;
266  Status = RtlAppendUnicodeToString(&DeviceExtension->GlobalName, DriveLetter);
267  if (!NT_SUCCESS(Status))
268  {
269  _SEH2_LEAVE;
270  }
271 
272  /* And try to open it */
275  /* It failed; good news, that letter is free, jump on it! */
276  if (!NT_SUCCESS(Status))
277  {
278  /* Create a symbolic link to our device */
279  Status = IoCreateSymbolicLink(&DeviceExtension->GlobalName, &DeviceName);
280  /* If created... */
281  if (NT_SUCCESS(Status))
282  {
283  /* Return the drive letter to the caller */
284  *EffectiveLetter = CurLetter;
285  ClearFlag(LocalDeviceObject->Flags, DO_DEVICE_INITIALIZING);
286  /* No caching! */
287  SetFlag(LocalDeviceObject->Flags, DO_DIRECT_IO);
288 
289  /* And return the DO */
290  *DeviceObject = LocalDeviceObject;
291  break;
292  }
293  }
294  /* This letter is taken, try another one */
295  else
296  {
297  ZwClose(LinkHandle);
299  }
300  }
301 
302  /* We're out of drive letters, so fail :-( */
303  if (CurLetter == (L'A' - 1))
304  {
306  }
307  }
309  {
310  /* No longer need these */
313 
314  /* And delete in case of a failure */
315  if (!NT_SUCCESS(Status) && Status != STATUS_VERIFY_REQUIRED && LocalDeviceObject != NULL)
316  {
317  IoDeleteDevice(LocalDeviceObject);
318  }
319  }
320  _SEH2_END;
321 
322  return Status;
323 }
324 
325 NTSTATUS
327 {
329  HANDLE ImgHandle;
331  ULONG Buffer[2], i, SectorShift;
332  PDEVICE_EXTENSION DeviceExtension;
334  FILE_STANDARD_INFORMATION FileStdInfo;
335 
336  /* Try to open the image */
338  Status = ZwCreateFile(&ImgHandle, FILE_READ_DATA | SYNCHRONIZE, &ObjectAttributes,
341  if (!NT_SUCCESS(Status))
342  {
343  DPRINT1("Failed to open image: %wZ\n", Image);
344  return Status;
345  }
346 
347  /* Query its information */
348  Status = ZwQueryInformationFile(ImgHandle, &IoStatus, &FileStdInfo,
349  sizeof(FileStdInfo), FileStandardInformation);
350  if (!NT_SUCCESS(Status))
351  {
352  DPRINT1("Failed to query image information\n");
353  ZwClose(ImgHandle);
354  return Status;
355  }
356 
357  /* Set image size */
358  DeviceExtension = DeviceObject->DeviceExtension;
359  DeviceExtension->VolumeSize.QuadPart = FileStdInfo.EndOfFile.QuadPart;
360 
361  /* Read the first 8-bytes to determine our sector size */
362  Status = ZwReadFile(ImgHandle, NULL, NULL, NULL, &IoStatus, Buffer, sizeof(Buffer), NULL, NULL);
363  if (!NT_SUCCESS(Status) || Buffer[1] == 0 || (Buffer[1] & 0x1FF) != 0)
364  {
365  DeviceExtension->SectorSize = 2048;
366  }
367  else
368  {
369  DeviceExtension->SectorSize = Buffer[1];
370  }
371 
372  /* Now, compute the sector shift */
373  if (DeviceExtension->SectorSize == 512)
374  {
375  DeviceExtension->SectorShift = 9;
376  }
377  else
378  {
379  for (i = 512, SectorShift = 9; i < DeviceExtension->SectorSize; i = i * 2, ++SectorShift);
380  if (i == DeviceExtension->SectorSize)
381  {
382  DeviceExtension->SectorShift = SectorShift;
383  }
384  else
385  {
386  DeviceExtension->SectorShift = 11;
387  }
388  }
389 
390  /* We're good, get the image file object to close the handle */
392  (PVOID *)&DeviceExtension->VolumeObject, NULL);
393  if (!NT_SUCCESS(Status))
394  {
395  ZwClose(ImgHandle);
396  DeviceExtension->VolumeObject = NULL;
397  return Status;
398  }
399 
400  ZwClose(ImgHandle);
401  /* Increase change count to force a verify */
402  ++DeviceExtension->ChangeCount;
403 
404  /* And ask for a verify! */
406 
407  /* Free old string (if any) */
408  ViFreeUnicodeString(&DeviceExtension->ImageName);
409  /* And save our new image name */
410  ViAllocateUnicodeString(Image->MaximumLength, &DeviceExtension->ImageName);
411  RtlCopyUnicodeString(&DeviceExtension->ImageName, Image);
412 
413  return STATUS_SUCCESS;
414 }
415 
416 VOID
418 {
420  WCHAR EffectiveLetter;
422 
423  /* Create string from path */
424  DeviceObject = NULL;
425  RtlInitUnicodeString(&Image, ImagePath);
426 
427  /* Create the drive letter (ignore output, it comes from registry, nothing to do */
428  ViCreateDriveLetter(DriverObject, Letter, &EffectiveLetter, &DeviceObject);
429  /* And mount the image on the created drive */
431 }
432 
433 VOID
435 {
436  WCHAR Letter[2];
437  WCHAR PathBuffer[100], ResBuffer[100];
438 
439  /* We'll browse the registry for
440  * DeviceX\IMAGE = {Path}
441  * When found, we create (or at least, attempt to)
442  * device X: and mount image Path
443  */
444  Letter[0] = L'A';
445  Letter[1] = UNICODE_NULL;
446  do
447  {
451 
452  /* Our path is always Device + drive letter */
453  RtlZeroMemory(PathBuffer, sizeof(PathBuffer));
454  Path.Buffer = PathBuffer;
455  Path.Length = 0;
456  Path.MaximumLength = sizeof(PathBuffer);
457  RtlAppendUnicodeToString(&Path, L"Parameters\\Device");
459 
460  ResString.Buffer = ResBuffer;
461  ResString.Length = 0;
462  ResString.MaximumLength = sizeof(ResBuffer);
463 
464  RtlZeroMemory(&QueryTable[0], sizeof(QueryTable));
465  QueryTable[0].Name = Path.Buffer;
467  QueryTable[1].Name = L"IMAGE";
470 
471  /* If query went fine, attempt to create and mount */
473  if (NT_SUCCESS(Status))
474  {
476  }
477 
478  ++(Letter[0]);
479  } while (Letter[0] <= L'Z');
480 }
481 
482 NTSTATUS
484 {
485  /* Force verify */
487 
488  Irp->IoStatus.Information = 0;
489  Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
490 
492 
493  return STATUS_VERIFY_REQUIRED;
494 }
495 
496 NTSTATUS
498 {
499  PIRP LowerIrp;
500  PIO_STACK_LOCATION Stack;
502 
503  /* Get the lower DO */
505  /* Allocate an IRP to deal with it */
506  LowerIrp = IoAllocateIrp(DeviceObject->StackSize, 0);
507  if (LowerIrp == NULL)
508  {
510  }
511 
512  /* Initialize it */
513  LowerIrp->RequestorMode = KernelMode;
514  /* Our status block */
515  LowerIrp->UserIosb = IoStatusBlock;
516  LowerIrp->MdlAddress = Mdl;
517  /* We don't cache! */
519  /* Sync event for us to know when read is done */
520  LowerIrp->UserEvent = Event;
521  LowerIrp->UserBuffer = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
522  /* The FO of our image */
523  LowerIrp->Tail.Overlay.OriginalFileObject = File;
524  LowerIrp->Tail.Overlay.Thread = PsGetCurrentThread();
525 
526  /* We basically perform a read operation, nothing complex here */
527  Stack = IoGetNextIrpStackLocation(LowerIrp);
528  Stack->Parameters.Read.Length = Length;
529  Stack->MajorFunction = IRP_MJ_READ;
530  Stack->FileObject = File;
531  Stack->Parameters.Read.ByteOffset.QuadPart = Offset->QuadPart;
532 
533  /* And call lower driver */
534  return IoCallDriver(DeviceObject, LowerIrp);
535 }
536 
537 NTSTATUS
538 NTAPI
540 {
541  KEVENT Event;
544  PIO_STACK_LOCATION Stack;
545  PDEVICE_EXTENSION DeviceExtension;
546 
547  /* Catch any exception that could happen during read attempt */
548  _SEH2_TRY
549  {
550  /* First of all, check if there's an image mounted */
551  DeviceExtension = DeviceObject->DeviceExtension;
552  if (DeviceExtension->VolumeObject == NULL)
553  {
555  _SEH2_LEAVE;
556  }
557 
558  /* Check if volume has to be verified (or if we override, for instance
559  * FSD performing initial reads for mouting FS)
560  */
564  {
566  _SEH2_LEAVE;
567  }
568 
569  /* Check if we have enough room for output */
570  if (Stack->Parameters.Read.Length > Irp->MdlAddress->ByteCount)
571  {
573  _SEH2_LEAVE;
574  }
575 
576  /* Initialize our event */
578 
579  /* Perform actual read */
580  Status = ViReadFile(DeviceExtension->VolumeObject, Irp->MdlAddress,
581  &Stack->Parameters.Read.ByteOffset, &Event,
582  Stack->Parameters.Read.Length, &IoStatus);
583  if (!NT_SUCCESS(Status))
584  {
586  _SEH2_LEAVE;
587  }
588 
589  /* Make sure we wait until its done */
591  if (!NT_SUCCESS(Status))
592  {
594  _SEH2_LEAVE;
595  }
596 
597  /* Look whether we're reading first bytes of the volume, if so, our
598  * "suppression" might be asked for
599  */
600  if (Stack->Parameters.Read.ByteOffset.QuadPart / DeviceExtension->SectorSize < 0x20)
601  {
602  /* Check our output buffer is in a state where we can play with it */
603  if ((Irp->MdlAddress->MdlFlags & (MDL_ALLOCATED_FIXED_SIZE | MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA)) ==
605  {
606  PUCHAR Buffer;
607 
608  /* Do we have to delete any UDF mark? */
609  if (BooleanFlagOn(DeviceExtension->Flags, MOUNT_FLAG_SUPP_UDF))
610  {
611  /* Kill any NSR0X mark from UDF */
612  Buffer = (PUCHAR)((ULONG_PTR)Irp->MdlAddress->StartVa + Irp->MdlAddress->ByteOffset);
613  if (Buffer != NULL)
614  {
615  if (Buffer[0] == 0 && Buffer[1] == 'N' && Buffer[2] == 'S' &&
616  Buffer[3] == 'R' && Buffer[4] == '0')
617  {
618  Buffer[5] = '0';
619  }
620  }
621  }
622 
623  /* Do we have to delete any Joliet mark? */
624  if (BooleanFlagOn(DeviceExtension->Flags, MOUNT_FLAG_SUPP_JOLIET))
625  {
626  /* Kill the CD001 mark from Joliet */
627  Buffer = (PUCHAR)((ULONG_PTR)Irp->MdlAddress->StartVa + Irp->MdlAddress->ByteOffset);
628  if (Buffer != NULL)
629  {
630  if (Buffer[0] == 2 && Buffer[1] == 'C' && Buffer[2] == 'D' &&
631  Buffer[3] == '0' && Buffer[4] == '0' && Buffer[5] == '1')
632  {
633  Buffer[5] = '0';
634  }
635  }
636  }
637  }
638  }
639 
640  /* Set status */
641  Status = ViSetIoStatus(Status, Stack->Parameters.Read.Length, Irp);
642  }
644  {
645  /* And complete! */
647  } _SEH2_END;
648 
649  return Status;
650 }
651 
652 NTSTATUS
654 {
656  PIO_STACK_LOCATION Stack;
658 
660 
661  /* Make sure output buffer is big enough to receive the drive letter
662  * when we create the drive
663  */
664  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(WCHAR))
665  {
667  }
668 
669  /* And start creation. We always start from bottom */
670  Status = ViCreateDriveLetter(DriverObject, L'Z', Irp->AssociatedIrp.SystemBuffer, &DeviceObject);
671  return ViSetIoStatus(Status, sizeof(WCHAR), Irp);
672 }
673 
674 NTSTATUS
676 {
677  PDISK_GEOMETRY DiskGeo;
678  PIO_STACK_LOCATION Stack;
679  PDEVICE_EXTENSION DeviceExtension;
680 
681  /* No geometry if no image mounted */
682  DeviceExtension = DeviceObject->DeviceExtension;
683  if (DeviceExtension->VolumeObject == NULL)
684  {
686  }
687 
688  /* No geometry if volume is to be verified */
692  {
694  }
695 
696  /* No geometry if too small output buffer */
697  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
698  {
700  }
701 
702  /* Finally, set what we're asked for */
703  DiskGeo = Irp->AssociatedIrp.SystemBuffer;
704  DiskGeo->MediaType = RemovableMedia;
705  DiskGeo->BytesPerSector = DeviceExtension->SectorSize;
706  DiskGeo->SectorsPerTrack = DeviceExtension->VolumeSize.QuadPart >> DeviceExtension->SectorShift;
707  DiskGeo->Cylinders.QuadPart = 1;
708  DiskGeo->TracksPerCylinder = 1;
709 
710  return ViSetIoStatus(STATUS_SUCCESS, sizeof(DISK_GEOMETRY), Irp);
711 }
712 
713 NTSTATUS
715 {
716  PULONG Buffer;
718  PIO_STACK_LOCATION Stack;
719  PDEVICE_EXTENSION DeviceExtension;
720 
721  /* Nothing to verify if no mounted */
722  DeviceExtension = DeviceObject->DeviceExtension;
723  if (DeviceExtension->VolumeObject == NULL)
724  {
726  }
727 
728  /* Do we have to verify? */
732  {
734  }
735 
736  /* If caller provided a buffer, that's to get the change count */
737  Buffer = Irp->AssociatedIrp.SystemBuffer;
738  if (Buffer != NULL)
739  {
740  *Buffer = DeviceExtension->ChangeCount;
741  Information = sizeof(ULONG);
742  }
743  else
744  {
745  Information = 0;
746  }
747 
748  /* Done */
750 }
751 
752 NTSTATUS
754 {
756  PDEVICE_EXTENSION DeviceExtension;
757 
758  /* We cannot mount an image if there's already one mounted */
759  DeviceExtension = DeviceObject->DeviceExtension;
760  if (DeviceExtension->VolumeObject != NULL)
761  {
763  }
764 
765  /* Perform the mount */
767  return ViSetIoStatus(Status, 0, Irp);
768 }
769 
770 ULONG
772 {
773  UCHAR Local[4];
774 
775  /* Convert LBA to MSF */
776  Local[0] = 0;
777  Local[1] = Address / 4500;
778  Local[2] = Address % 4500 / 75;
779  Local[3] = Address + 108 * Local[1] - 75 * Local[2];
780 
781  return *(ULONG *)(&Local[0]);
782 }
783 
784 VOID
786 {
787  /* Fill in our track data with provided information */
788  TrackData->Reserved = 0;
789  TrackData->Reserved1 = 0;
790  TrackData->Control = Control & 0xF;
791  TrackData->Adr = Adr;
792  TrackData->TrackNumber = TrackNumber;
793  *(ULONG *)(&TrackData->Address[0]) = ViComputeAddress(Address);
794 }
795 
796 NTSTATUS
798 {
799  PCDROM_TOC Toc;
800  PIO_STACK_LOCATION Stack;
801  PDEVICE_EXTENSION DeviceExtension;
802 
803  /* No image mounted, no TOC */
804  DeviceExtension = DeviceObject->DeviceExtension;
805  if (DeviceExtension->VolumeObject == NULL)
806  {
808  }
809 
810  /* No TOC if we have to verify */
814  {
816  }
817 
818  /* Check we have enough room for TOC */
819  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC))
820  {
822  }
823 
824  /* Start filling the TOC */
825  Toc = Irp->AssociatedIrp.SystemBuffer;
826  Toc->Length[0] = 0;
827  Toc->Length[1] = 8;
828  Toc->FirstTrack = 1;
829  Toc->LastTrack = 1;
830  /* And fill our single (an ISO file always have a single track) track with 2sec gap */
832  /* And add last track termination */
833  ViFillInTrackData(&Toc->TrackData[1], TOC_DATA_TRACK, ADR_NO_MODE_INFORMATION, TOC_LAST_TRACK, (DeviceExtension->VolumeSize.QuadPart >> DeviceExtension->SectorShift) + 150);
834 
835  return ViSetIoStatus(STATUS_SUCCESS, sizeof(CDROM_TOC), Irp);
836 }
837 
838 NTSTATUS
840 {
841  PCDROM_TOC Toc;
842  PIO_STACK_LOCATION Stack;
843  PCDROM_READ_TOC_EX TocEx;
844  PDEVICE_EXTENSION DeviceExtension;
845 
846  /* No image mounted, no TOC */
847  DeviceExtension = DeviceObject->DeviceExtension;
848  if (DeviceExtension->VolumeObject == NULL)
849  {
851  }
852 
853  /* No TOC if we have to verify */
857  {
859  }
860 
861  /* We need an input buffer */
862  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CDROM_READ_TOC_EX))
863  {
865  }
866 
867  /* Validate output buffer is big enough */
868  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < MAXIMUM_CDROM_SIZE)
869  {
871  }
872 
873  /* Validate the input buffer - see cdrom_new */
874  TocEx = Irp->AssociatedIrp.SystemBuffer;
875  if ((TocEx->Reserved1 != 0) || (TocEx->Reserved2 != 0) ||
876  (TocEx->Reserved3 != 0))
877  {
879  }
880 
881  if (((TocEx->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
882  (TocEx->Format == CDROM_READ_TOC_EX_FORMAT_PMA) ||
883  (TocEx->Format == CDROM_READ_TOC_EX_FORMAT_ATIP)) &&
884  TocEx->SessionTrack != 0)
885  {
887  }
888 
889  if ((TocEx->Format != CDROM_READ_TOC_EX_FORMAT_TOC) &&
893  (TocEx->Format != CDROM_READ_TOC_EX_FORMAT_PMA) &&
895  {
897  }
898 
899  /* Start filling the TOC */
900  Toc = Irp->AssociatedIrp.SystemBuffer;
901  Toc->Length[0] = 0;
902  Toc->Length[1] = 8;
903  Toc->FirstTrack = 1;
904  Toc->LastTrack = 1;
905  /* And fill our single (an ISO file always have a single track) track with 2sec gap */
907  /* And add last track termination */
908  ViFillInTrackData(&Toc->TrackData[1], TOC_DATA_TRACK, ADR_NO_MODE_INFORMATION, TOC_LAST_TRACK, (DeviceExtension->VolumeSize.QuadPart >> DeviceExtension->SectorShift) + 150);
909 
911 }
912 
913 NTSTATUS
915 {
916 
917  PIO_STACK_LOCATION Stack;
919  PDEVICE_EXTENSION DeviceExtension;
920 
921  /* No image, no last session */
922  DeviceExtension = DeviceObject->DeviceExtension;
923  if (DeviceExtension->VolumeObject == NULL)
924  {
926  }
927 
928  /* No last session if we have to verify */
932  {
934  }
935 
936  /* Check we have enough room for last session data */
937  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC_SESSION_DATA))
938  {
940  }
941 
942  /* Fill in data */
943  Toc = Irp->AssociatedIrp.SystemBuffer;
944  Toc->Length[0] = 0;
945  Toc->Length[1] = 8;
946  Toc->FirstCompleteSession = 1;
947  Toc->LastCompleteSession = 1;
948  /* And return our track with 2sec gap (cf TOC function) */
950 
952 }
953 
954 NTSTATUS
956 {
958  PIO_STACK_LOCATION Stack;
959  PDEVICE_OBJECT CurrentDO;
960  PDEVICE_EXTENSION DeviceExtension;
961 
962  /* Check we have enough room for output */
964  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DRIVES_LIST))
965  {
967  }
968 
969  /* Get the output buffer */
970  DrivesList = Irp->AssociatedIrp.SystemBuffer;
971  DrivesList->Count = 0;
972 
973  /* And now, starting from our main DO, start browsing all the DO we created */
974  for (CurrentDO = DeviceObject->DriverObject->DeviceObject; CurrentDO != NULL;
975  CurrentDO = CurrentDO->NextDevice)
976  {
977  /* Check we won't output our main DO */
978  DeviceExtension = CurrentDO->DeviceExtension;
979  if (DeviceExtension->GlobalName.Length !=
980  RtlCompareMemory(DeviceExtension->GlobalName.Buffer,
981  L"\\??\\VirtualCdRom",
982  DeviceExtension->GlobalName.Length))
983  {
984  /* When we return, we extract the drive letter
985  * See ViCreateDriveLetter(), it's \??\Z:
986  */
987  DrivesList->Drives[DrivesList->Count++] = DeviceExtension->GlobalName.Buffer[4];
988  }
989  }
990 
991  return ViSetIoStatus(STATUS_SUCCESS, sizeof(DRIVES_LIST), Irp);
992 }
993 
994 NTSTATUS
996 {
997  PIMAGE_PATH ImagePath;
998  PIO_STACK_LOCATION Stack;
999  PDEVICE_EXTENSION DeviceExtension;
1000 
1001  /* Check we have enough room for output */
1003  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(IMAGE_PATH))
1004  {
1006  }
1007 
1008  /* Get our image path from DO */
1009  DeviceExtension = DeviceObject->DeviceExtension;
1010  ImagePath = Irp->AssociatedIrp.SystemBuffer;
1011  ImagePath->Mounted = (DeviceExtension->VolumeObject != NULL);
1012  ImagePath->Length = DeviceExtension->ImageName.Length;
1013  /* And if it's set, copy it back to the caller */
1014  if (DeviceExtension->ImageName.Length != 0)
1015  {
1016  RtlCopyMemory(ImagePath->Path, DeviceExtension->ImageName.Buffer, DeviceExtension->ImageName.Length);
1017  }
1018 
1019  return ViSetIoStatus(STATUS_SUCCESS, sizeof(IMAGE_PATH), Irp);
1020 }
1021 
1022 NTSTATUS
1024 {
1025  PDEVICE_EXTENSION DeviceExtension;
1026 
1027  /* Eject will force a verify */
1029 
1030  /* If we have an image mounted, unmount it
1031  * But don't free anything related, so that
1032  * we can perform quick remount.
1033  * See: IOCTL_STORAGE_LOAD_MEDIA
1034  */
1035  DeviceExtension = DeviceObject->DeviceExtension;
1036  if (DeviceExtension->VolumeObject != NULL)
1037  {
1038  ObDereferenceObject(DeviceExtension->VolumeObject);
1039  /* Device changed, so mandatory increment */
1040  ++DeviceExtension->ChangeCount;
1041  DeviceExtension->VolumeObject = NULL;
1042  }
1043 
1044  return ViSetIoStatus(STATUS_SUCCESS, 0, Irp);
1045 }
1046 
1047 NTSTATUS
1049 {
1050  NTSTATUS Status;
1052  PDEVICE_EXTENSION DeviceExtension;
1053 
1054  /* Get the device extension */
1055  DeviceExtension = DeviceObject->DeviceExtension;
1056  /* Allocate a new string as mount parameter */
1057  Status = ViAllocateUnicodeString(DeviceExtension->ImageName.MaximumLength, &Image);
1058  if (!NT_SUCCESS(Status))
1059  {
1060  return ViSetIoStatus(Status, 0, Irp);
1061  }
1062 
1063  /* To allow cleanup in case of troubles */
1064  _SEH2_TRY
1065  {
1066  /* Copy our current image name and mount */
1067  RtlCopyUnicodeString(&Image, &DeviceExtension->ImageName);
1069  }
1071  {
1073  }
1074  _SEH2_END;
1075 
1076  return ViSetIoStatus(Status, 0, Irp);
1077 }
1078 
1079 NTSTATUS
1080 NTAPI
1082 {
1083  NTSTATUS Status;
1085  PIO_STACK_LOCATION Stack;
1086  PMOUNT_PARAMETERS MountParameters;
1087  PDEVICE_EXTENSION DeviceExtension;
1088 
1089  DeviceExtension = DeviceObject->DeviceExtension;
1091 
1092  _SEH2_TRY
1093  {
1094  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
1095  {
1096  /* First of all, our private IOCTLs */
1098  Status = ViCreateDevice(DeviceObject->DriverObject, Irp);
1099  break;
1100 
1103  break;
1104 
1106  MountParameters = Irp->AssociatedIrp.SystemBuffer;
1107  Image.MaximumLength = 255 * sizeof(WCHAR);
1108  Image.Length = MountParameters->Length;
1109  Image.Buffer = MountParameters->Path;
1110  DeviceExtension->Flags = MountParameters->Flags;
1112  break;
1113 
1116  break;
1117 
1120  break;
1121 
1122  /* Now, IOCTLs we have to handle as class driver */
1126  break;
1127 
1131  break;
1132 
1133  case IOCTL_CDROM_READ_TOC:
1135  break;
1136 
1139  break;
1140 
1143  break;
1144 
1148  break;
1149 
1150  /* That one is a bit specific
1151  * It gets unmounted image mounted again
1152  */
1154  /* That means it can only be performed if:
1155  * - We had an image previously
1156  * - It's no longer mounted
1157  * Otherwise, we just return success
1158  */
1159  if (DeviceExtension->ImageName.Buffer == NULL || DeviceExtension->VolumeObject != NULL)
1160  {
1162  }
1163  else
1164  {
1166  }
1167  break;
1168 
1169  default:
1171  DPRINT1("IOCTL: %x not supported\n", Stack->Parameters.DeviceIoControl.IoControlCode);
1172  break;
1173  }
1175  {
1177  } _SEH2_END;
1178 
1179  /* Depending on the failure code, we may force a verify */
1180  if (!NT_SUCCESS(Status))
1181  {
1186  {
1188  }
1189  }
1190 
1192 
1193  return Status;
1194 }
1195 
1196 NTSTATUS
1197 NTAPI
1199 {
1200  NTSTATUS Status;
1203  PDEVICE_EXTENSION DeviceExtension;
1204 
1205  /* Set our entry points (rather limited :-)) */
1212 
1213  /* Create our main device to receive private IOCTLs */
1214  RtlInitUnicodeString(&DeviceName, L"\\Device\\VirtualCdRom");
1217  FALSE, &DeviceObject);
1218  if (!NT_SUCCESS(Status))
1219  {
1220  return Status;
1221  }
1222 
1223  /* Initialize our device extension */
1225  DeviceExtension = DeviceObject->DeviceExtension;
1226 
1227  /* And create our accessible name from umode */
1228  ViAllocateUnicodeString(DEFAULT_STRING_SIZE, &DeviceExtension->GlobalName);
1229  RtlAppendUnicodeToString(&DeviceExtension->GlobalName, L"\\??\\VirtualCdRom");
1230  Status = IoCreateSymbolicLink(&DeviceExtension->GlobalName, &DeviceName);
1231  if (!NT_SUCCESS(Status))
1232  {
1234  return Status;
1235  }
1236 
1237  /* Initialize our mutex for device count */
1239 
1240  /* And try to load images that would have been stored in registry */
1242 
1243  return STATUS_SUCCESS;
1244 }
ULONG ChangeCount
Definition: vcdrom.c:28
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define MOUNT_FLAG_SUPP_UDF
Definition: vcdioctl.h:15
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:131
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
UCHAR Length[2]
Definition: ntddcdrm.h:163
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: vcdrom.c:1198
NTSTATUS ViCheckVerify(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:714
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UCHAR FirstTrack
Definition: ntddcdrm.h:164
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
NTSTATUS ViEnumerateDrives(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:955
USHORT Mounted
Definition: vcdioctl.h:28
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS NTAPI VcdHandle(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:121
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS ViRemountMedia(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1048
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING GlobalName
Definition: vcdrom.c:30
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
ULONG ViDevicesCount
Definition: vcdrom.c:49
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:52
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
static PWSTR Image
Definition: pageheap.c:13
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
LARGE_INTEGER VolumeSize
Definition: vcdrom.c:26
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG BytesPerSector
Definition: ntdddisk.h:381
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
UCHAR Address[4]
Definition: ntddcdrm.h:108
NTSTATUS ViSetIoStatus(NTSTATUS Status, ULONG_PTR Information, PIRP Irp)
Definition: vcdrom.c:109
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
IRP
Definition: iotypes.h:2463
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
WCHAR DeviceName[]
Definition: adapter.cpp:21
UCHAR Reserved
Definition: ntddcdrm.h:103
#define IOCTL_VCDROM_MOUNT_IMAGE
Definition: vcdioctl.h:4
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
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
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define FILE_SHARE_READ
Definition: compat.h:125
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
WCHAR Path[255]
Definition: vcdioctl.h:26
_SEH2_TRY
Definition: create.c:4250
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
#define ADR_NO_MODE_INFORMATION
Definition: ntddcdrm.h:249
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
NTSTATUS ViGetImagePath(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:995
NTSTATUS NTAPI VcdDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1081
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS ViEjectMedia(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1023
#define UNICODE_NULL
_In_ ULONG BufferLength
Definition: usbdlib.h:225
TRACK_DATA TrackData[1]
Definition: ntddcdrm.h:175
#define FILE_READ_DATA
Definition: nt_native.h:628
ULONG DeviceCount
Definition: mpu401.c:26
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:96
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
static WCHAR Address[46]
Definition: ping.c:68
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:134
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
UNICODE_STRING ImageName
Definition: vcdrom.c:32
#define CDROM_READ_TOC_EX_FORMAT_PMA
Definition: ntddcdrm.h:132
FAST_MUTEX
Definition: extypes.h:17
#define IOCTL_VCDROM_CREATE_DRIVE
Definition: vcdioctl.h:2
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define TOC_LAST_TRACK
Definition: vcdrom.c:42
VOID ViCreateDriveAndMountImage(PDRIVER_OBJECT DriverObject, WCHAR Letter, LPCWSTR ImagePath)
Definition: vcdrom.c:417
NTSTATUS ViIssueMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image, PIRP Irp)
Definition: vcdrom.c:753
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:46
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IOCTL_VCDROM_ENUMERATE_DRIVES
Definition: vcdioctl.h:5
MEDIA_TYPE MediaType
Definition: ntdddisk.h:378
PFILE_OBJECT VolumeObject
Definition: vcdrom.c:24
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS ViMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image)
Definition: vcdrom.c:326
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
vector< wstring > DrivesList
Definition: MainDialog.cpp:9
UCHAR LastTrack
Definition: ntddcdrm.h:165
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG SectorShift
Definition: vcdrom.c:37
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
NTSTATUS ViDeleteDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:131
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS ViAllocateUnicodeString(USHORT BufferLength, PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:71
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
WCHAR Letter
UCHAR Control
Definition: ntddcdrm.h:104
VOID ViLoadImagesFromRegistry(PDRIVER_OBJECT DriverObject, LPCWSTR RegistryPath)
Definition: vcdrom.c:434
NTSTATUS NTAPI VcdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:539
#define GENERIC_READ
Definition: compat.h:124
VOID ViInitializeDeviceExtension(PDEVICE_OBJECT DeviceObject)
Definition: vcdrom.c:52
#define IOCTL_VCDROM_GET_IMAGE_PATH
Definition: vcdioctl.h:6
#define SYNCHRONIZE
Definition: nt_native.h:61
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
static const WCHAR Control[]
Definition: interface.c:27
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
NTSTATUS ViReadTocEx(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:839
#define FILE_OPEN
Definition: from_kernel.h:54
#define CDROM_READ_TOC_EX_FORMAT_TOC
Definition: ntddcdrm.h:129
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI VcdUnload(PDRIVER_OBJECT DriverObject)
Definition: vcdrom.c:159
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
NTSTATUS ViReadToc(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:797
_SEH2_END
Definition: create.c:4424
PRTL_UNICODE_STRING_BUFFER Path
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define CDROM_READ_TOC_EX_FORMAT_ATIP
Definition: ntddcdrm.h:133
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
FAST_MUTEX ViMutex
Definition: vcdrom.c:48
unsigned short USHORT
Definition: pedump.c:61
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:76
UCHAR TrackNumber
Definition: ntddcdrm.h:106
PDEVICE_OBJECT DeviceObject
Definition: mntmgr.h:15
WCHAR Path[255]
Definition: vcdioctl.h:10
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
_SEH2_FINALLY
Definition: create.c:4395
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:99
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define CDROM_READ_TOC_EX_FORMAT_SESSION
Definition: ntddcdrm.h:130
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define MOUNT_FLAG_SUPP_JOLIET
Definition: vcdioctl.h:16
struct _DEVICE_EXTENSION DEVICE_EXTENSION
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define IRP_PAGING_IO
#define DPRINT1
Definition: precomp.h:8
ULONG ViComputeAddress(ULONG Address)
Definition: vcdrom.c:771
#define FileStandardInformation
Definition: propsheet.cpp:61
NTSTATUS ViCreateDriveLetter(PDRIVER_OBJECT DriverObject, WCHAR Letter, WCHAR *EffectiveLetter, PDEVICE_OBJECT *DeviceObject)
Definition: vcdrom.c:186
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define TOC_DATA_TRACK
Definition: vcdrom.c:41
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
USHORT Length
Definition: vcdioctl.h:27
#define IRP_MJ_CLEANUP
NTSTATUS ViReadFile(PFILE_OBJECT File, PMDL Mdl, PLARGE_INTEGER Offset, PKEVENT Event, ULONG Length, PIO_STATUS_BLOCK IoStatusBlock)
Definition: vcdrom.c:497
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
NTSTATUS ViCreateDevice(PDRIVER_OBJECT DriverObject, PIRP Irp)
Definition: vcdrom.c:653
VOID ViFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:92
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:166
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define DEFAULT_STRING_SIZE
Definition: vcdrom.c:45
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define MAXIMUM_CDROM_SIZE
Definition: ntddcdrm.h:99
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
NTSTATUS ViGetLastSession(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:914
VOID ViFillInTrackData(PTRACK_DATA TrackData, UCHAR Control, UCHAR Adr, UCHAR TrackNumber, ULONG Address)
Definition: vcdrom.c:785
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:73
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
Definition: File.h:15
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
convenient loading of string resources
Definition: globals.h:303
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
ULONG SectorSize
Definition: vcdrom.c:36
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct _DEVICE_EXTENSION * PDEVICE_EXTENSION
#define IOCTL_CDROM_EJECT_MEDIA
Definition: cdrw_usr.h:60
#define IOCTL_VCDROM_DELETE_DRIVE
Definition: vcdioctl.h:3
#define MDL_ALLOCATED_FIXED_SIZE
Definition: mmtypes.h:21
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
NTSTATUS ViVerifyVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:483
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
NTSTATUS ViGetDriveGeometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:675
Iosb Information
Definition: create.c:4377
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define IRP_SYNCHRONOUS_PAGING_IO
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2169
LONGLONG QuadPart
Definition: typedefs.h:112
UCHAR Reserved1
Definition: ntddcdrm.h:107
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
UCHAR Adr
Definition: ntddcdrm.h:105