ReactOS 0.4.16-dev-320-g3bd9ddc
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
20typedef 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
51VOID
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{
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
91VOID
93{
94 /* Only free if allocate, that allows using this
95 * on cleanup in short memory situations
96 */
97 if (UnicodeString->Buffer != NULL)
98 {
100 UnicodeString->Buffer = NULL;
101 }
102
103 /* Zero the rest */
104 UnicodeString->Length = 0;
105 UnicodeString->MaximumLength = 0;
106}
107
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
120NTAPI
122{
123 /* Stub for CREATE, CLEANUP, CLOSE, always a succes */
126
127 return STATUS_SUCCESS;
128}
129
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
157VOID
158NTAPI
160{
161 IRP FakeIrp;
163
164 /* No device, nothing to free */
165 DeviceObject = DriverObject->DeviceObject;
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
187{
189 HANDLE LinkHandle;
190 WCHAR DriveLetter[3], CurLetter;
191 PDEVICE_OBJECT LocalDeviceObject;
192 PDEVICE_EXTENSION DeviceExtension;
195
197
198 /* Allocate our buffers */
201
202 /* For easier cleanup */
204 {
205 /* Get our device number */
210
211 /* Conversion to string failed, bail out */
212 if (!NT_SUCCESS(Status))
213 {
215 }
216
217 /* Create our device name */
218 Status = RtlAppendUnicodeToString(&DeviceName, L"\\Device\\VirtualCdRom");
219 if (!NT_SUCCESS(Status))
220 {
222 }
223
225 if (!NT_SUCCESS(Status))
226 {
228 }
229
230 /* And create the device! */
234 FALSE, &LocalDeviceObject);
235 if (!NT_SUCCESS(Status))
236 {
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 {
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 {
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
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
416VOID
418{
420 WCHAR EffectiveLetter;
422
423 /* Create string from path */
425 RtlInitUnicodeString(&Image, ImagePath);
426
427 /* Create the drive letter (ignore output, it comes from registry, nothing to do */
429 /* And mount the image on the created drive */
431}
432
433VOID
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
484{
485 /* Force verify */
487
488 Irp->IoStatus.Information = 0;
489 Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
490
492
494}
495
498{
499 PIRP LowerIrp;
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 */
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
538NTAPI
540{
545 PDEVICE_EXTENSION DeviceExtension;
546
547 /* Catch any exception that could happen during read attempt */
549 {
550 /* First of all, check if there's an image mounted */
551 DeviceExtension = DeviceObject->DeviceExtension;
552 if (DeviceExtension->VolumeObject == NULL)
553 {
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 {
567 }
568
569 /* Check if we have enough room for output */
570 if (Stack->Parameters.Read.Length > Irp->MdlAddress->ByteCount)
571 {
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 {
587 }
588
589 /* Make sure we wait until its done */
591 if (!NT_SUCCESS(Status))
592 {
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 {
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
654{
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
676{
677 PDISK_GEOMETRY DiskGeo;
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
711}
712
715{
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
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
770ULONG
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
784VOID
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
798{
799 PCDROM_TOC Toc;
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
840{
841 PCDROM_TOC Toc;
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) ||
884 TocEx->SessionTrack != 0)
885 {
887 }
888
889 if ((TocEx->Format != CDROM_READ_TOC_EX_FORMAT_TOC) &&
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
915{
916
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
956{
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
992}
993
996{
997 PIMAGE_PATH ImagePath;
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
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
1049{
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
1080NTAPI
1082{
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
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
1197NTAPI
1199{
1203 PDEVICE_EXTENSION DeviceExtension;
1204
1205 /* Set our entry points (rather limited :-)) */
1206 DriverObject->DriverUnload = VcdUnload;
1207 DriverObject->MajorFunction[IRP_MJ_CREATE] = VcdHandle;
1208 DriverObject->MajorFunction[IRP_MJ_CLOSE] = VcdHandle;
1209 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VcdHandle;
1210 DriverObject->MajorFunction[IRP_MJ_READ] = VcdRead;
1212
1213 /* Create our main device to receive private IOCTLs */
1214 RtlInitUnicodeString(&DeviceName, L"\\Device\\VirtualCdRom");
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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
WCHAR Letter
vector< wstring > DrivesList
Definition: MainDialog.cpp:9
PRTL_UNICODE_STRING_BUFFER Path
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IOCTL_CDROM_EJECT_MEDIA
Definition: cdrw_usr.h:60
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Definition: bufpool.h:45
Definition: File.h:16
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GENERIC_READ
Definition: compat.h:135
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
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
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define MAXIMUM_CDROM_SIZE
Definition: hwide.h:288
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG DeviceCount
Definition: mpu401.c:26
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4220
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define UNICODE_NULL
#define CDROM_READ_TOC_EX_FORMAT_SESSION
Definition: ntddcdrm.h:163
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
#define ADR_NO_MODE_INFORMATION
Definition: ntddcdrm.h:282
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:79
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:164
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:103
#define CDROM_READ_TOC_EX_FORMAT_PMA
Definition: ntddcdrm.h:165
#define CDROM_READ_TOC_EX_FORMAT_TOC
Definition: ntddcdrm.h:162
#define CDROM_READ_TOC_EX_FORMAT_ATIP
Definition: ntddcdrm.h:166
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:167
@ RemovableMedia
Definition: ntdddisk.h:382
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
@ NotificationEvent
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
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
#define L(x)
Definition: ntvdm.h:50
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:494
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
convenient loading of string resources
Definition: globals.h:304
TRACK_DATA TrackData[1]
Definition: ntddcdrm.h:208
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:199
UCHAR LastTrack
Definition: ntddcdrm.h:198
UCHAR FirstTrack
Definition: ntddcdrm.h:197
UCHAR Length[2]
Definition: ntddcdrm.h:196
PFILE_OBJECT VolumeObject
Definition: vcdrom.c:24
ULONG ChangeCount
Definition: vcdrom.c:28
PDEVICE_OBJECT DeviceObject
Definition: processr.h:16
ULONG SectorShift
Definition: vcdrom.c:37
ULONG SectorSize
Definition: vcdrom.c:36
UNICODE_STRING GlobalName
Definition: vcdrom.c:30
LARGE_INTEGER VolumeSize
Definition: vcdrom.c:26
UNICODE_STRING ImageName
Definition: vcdrom.c:32
PVOID DeviceExtension
Definition: env_spec_w32.h:418
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:400
ULONG TracksPerCylinder
Definition: ntdddisk.h:402
ULONG SectorsPerTrack
Definition: ntdddisk.h:403
ULONG BytesPerSector
Definition: ntdddisk.h:404
USHORT Length
Definition: vcdioctl.h:27
USHORT Mounted
Definition: vcdioctl.h:28
WCHAR Path[255]
Definition: vcdioctl.h:26
WCHAR Path[255]
Definition: vcdioctl.h:10
UCHAR Adr
Definition: ntddcdrm.h:138
UCHAR Address[4]
Definition: ntddcdrm.h:141
UCHAR Reserved1
Definition: ntddcdrm.h:140
UCHAR Reserved
Definition: ntddcdrm.h:136
UCHAR TrackNumber
Definition: ntddcdrm.h:139
UCHAR Control
Definition: ntddcdrm.h:137
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
#define IOCTL_VCDROM_DELETE_DRIVE
Definition: vcdioctl.h:3
#define MOUNT_FLAG_SUPP_UDF
Definition: vcdioctl.h:15
#define IOCTL_VCDROM_GET_IMAGE_PATH
Definition: vcdioctl.h:6
#define MOUNT_FLAG_SUPP_JOLIET
Definition: vcdioctl.h:16
#define IOCTL_VCDROM_MOUNT_IMAGE
Definition: vcdioctl.h:4
#define IOCTL_VCDROM_CREATE_DRIVE
Definition: vcdioctl.h:2
#define IOCTL_VCDROM_ENUMERATE_DRIVES
Definition: vcdioctl.h:5
NTSTATUS ViCheckVerify(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:714
VOID ViInitializeDeviceExtension(PDEVICE_OBJECT DeviceObject)
Definition: vcdrom.c:52
NTSTATUS NTAPI VcdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:539
struct _DEVICE_EXTENSION DEVICE_EXTENSION
NTSTATUS ViGetImagePath(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:995
NTSTATUS ViCreateDriveLetter(PDRIVER_OBJECT DriverObject, WCHAR Letter, WCHAR *EffectiveLetter, PDEVICE_OBJECT *DeviceObject)
Definition: vcdrom.c:186
VOID ViFillInTrackData(PTRACK_DATA TrackData, UCHAR Control, UCHAR Adr, UCHAR TrackNumber, ULONG Address)
Definition: vcdrom.c:785
NTSTATUS ViEjectMedia(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1023
NTSTATUS ViEnumerateDrives(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:955
NTSTATUS ViRemountMedia(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1048
NTSTATUS ViReadFile(PFILE_OBJECT File, PMDL Mdl, PLARGE_INTEGER Offset, PKEVENT Event, ULONG Length, PIO_STATUS_BLOCK IoStatusBlock)
Definition: vcdrom.c:497
#define TOC_LAST_TRACK
Definition: vcdrom.c:42
VOID ViFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:92
NTSTATUS ViGetLastSession(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:914
NTSTATUS NTAPI VcdHandle(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:121
VOID ViLoadImagesFromRegistry(PDRIVER_OBJECT DriverObject, LPCWSTR RegistryPath)
Definition: vcdrom.c:434
NTSTATUS ViCreateDevice(PDRIVER_OBJECT DriverObject, PIRP Irp)
Definition: vcdrom.c:653
NTSTATUS ViReadTocEx(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:839
ULONG ViDevicesCount
Definition: vcdrom.c:49
#define DEFAULT_STRING_SIZE
Definition: vcdrom.c:45
NTSTATUS ViAllocateUnicodeString(USHORT BufferLength, PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:71
#define TOC_DATA_TRACK
Definition: vcdrom.c:41
VOID NTAPI VcdUnload(PDRIVER_OBJECT DriverObject)
Definition: vcdrom.c:159
NTSTATUS ViIssueMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image, PIRP Irp)
Definition: vcdrom.c:753
ULONG ViComputeAddress(ULONG Address)
Definition: vcdrom.c:771
NTSTATUS ViVerifyVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:483
NTSTATUS ViDeleteDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:131
struct _DEVICE_EXTENSION * PDEVICE_EXTENSION
VOID ViCreateDriveAndMountImage(PDRIVER_OBJECT DriverObject, WCHAR Letter, LPCWSTR ImagePath)
Definition: vcdrom.c:417
FAST_MUTEX ViMutex
Definition: vcdrom.c:48
NTSTATUS ViSetIoStatus(NTSTATUS Status, ULONG_PTR Information, PIRP Irp)
Definition: vcdrom.c:109
NTSTATUS ViMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image)
Definition: vcdrom.c:326
NTSTATUS ViReadToc(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:797
NTSTATUS ViGetDriveGeometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:675
NTSTATUS NTAPI VcdDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1081
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
FAST_MUTEX
Definition: extypes.h:17
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
#define IRP_PAGING_IO
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_NOCACHE
#define IRP_MJ_CLEANUP
@ Executive
Definition: ketypes.h:415
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_ALLOCATED_FIXED_SIZE
Definition: mmtypes.h:21
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185