ReactOS 0.4.15-dev-8408-g466a198
vcdrom.c File Reference
#include <ntddk.h>
#include <ntifs.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <pseh/pseh2.h>
#include <debug.h>
#include "vcdioctl.h"
Include dependency graph for vcdrom.c:

Go to the source code of this file.

Classes

struct  _DEVICE_EXTENSION
 

Macros

#define NDEBUG
 
#define TOC_DATA_TRACK   0x04
 
#define TOC_LAST_TRACK   0xaa
 
#define DEFAULT_STRING_SIZE   50
 

Typedefs

typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION
 
typedef struct _DEVICE_EXTENSIONPDEVICE_EXTENSION
 

Functions

VOID ViInitializeDeviceExtension (PDEVICE_OBJECT DeviceObject)
 
NTSTATUS ViAllocateUnicodeString (USHORT BufferLength, PUNICODE_STRING UnicodeString)
 
VOID ViFreeUnicodeString (PUNICODE_STRING UnicodeString)
 
NTSTATUS ViSetIoStatus (NTSTATUS Status, ULONG_PTR Information, PIRP Irp)
 
NTSTATUS NTAPI VcdHandle (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViDeleteDevice (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID NTAPI VcdUnload (PDRIVER_OBJECT DriverObject)
 
NTSTATUS ViCreateDriveLetter (PDRIVER_OBJECT DriverObject, WCHAR Letter, WCHAR *EffectiveLetter, PDEVICE_OBJECT *DeviceObject)
 
NTSTATUS ViMountImage (PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image)
 
VOID ViCreateDriveAndMountImage (PDRIVER_OBJECT DriverObject, WCHAR Letter, LPCWSTR ImagePath)
 
VOID ViLoadImagesFromRegistry (PDRIVER_OBJECT DriverObject, LPCWSTR RegistryPath)
 
NTSTATUS ViVerifyVolume (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViReadFile (PFILE_OBJECT File, PMDL Mdl, PLARGE_INTEGER Offset, PKEVENT Event, ULONG Length, PIO_STATUS_BLOCK IoStatusBlock)
 
NTSTATUS NTAPI VcdRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViCreateDevice (PDRIVER_OBJECT DriverObject, PIRP Irp)
 
NTSTATUS ViGetDriveGeometry (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViCheckVerify (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViIssueMountImage (PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image, PIRP Irp)
 
ULONG ViComputeAddress (ULONG Address)
 
VOID ViFillInTrackData (PTRACK_DATA TrackData, UCHAR Control, UCHAR Adr, UCHAR TrackNumber, ULONG Address)
 
NTSTATUS ViReadToc (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViReadTocEx (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViGetLastSession (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViEnumerateDrives (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViGetImagePath (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViEjectMedia (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ViRemountMedia (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI VcdDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 

Variables

FAST_MUTEX ViMutex
 
ULONG ViDevicesCount
 

Macro Definition Documentation

◆ DEFAULT_STRING_SIZE

#define DEFAULT_STRING_SIZE   50

Definition at line 45 of file vcdrom.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file vcdrom.c.

◆ TOC_DATA_TRACK

#define TOC_DATA_TRACK   0x04

Definition at line 41 of file vcdrom.c.

◆ TOC_LAST_TRACK

#define TOC_LAST_TRACK   0xaa

Definition at line 42 of file vcdrom.c.

Typedef Documentation

◆ DEVICE_EXTENSION

◆ PDEVICE_EXTENSION

Function Documentation

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( PDRIVER_OBJECT  DriverObject,
PUNICODE_STRING  RegistryPath 
)

Definition at line 1198 of file vcdrom.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
Status
Definition: gdiplustypes.h:25
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
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
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define L(x)
Definition: ntvdm.h:50
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#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 STATUS_SUCCESS
Definition: shellext.h:65
VOID ViInitializeDeviceExtension(PDEVICE_OBJECT DeviceObject)
Definition: vcdrom.c:52
NTSTATUS NTAPI VcdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:539
NTSTATUS NTAPI VcdHandle(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:121
VOID ViLoadImagesFromRegistry(PDRIVER_OBJECT DriverObject, LPCWSTR RegistryPath)
Definition: vcdrom.c:434
#define DEFAULT_STRING_SIZE
Definition: vcdrom.c:45
NTSTATUS ViAllocateUnicodeString(USHORT BufferLength, PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:71
VOID NTAPI VcdUnload(PDRIVER_OBJECT DriverObject)
Definition: vcdrom.c:159
FAST_MUTEX ViMutex
Definition: vcdrom.c:48
NTSTATUS NTAPI VcdDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:1081
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_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
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IRP_MJ_CLEANUP

◆ VcdDeviceControl()

NTSTATUS NTAPI VcdDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1081 of file vcdrom.c.

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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#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
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:79
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:103
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
WCHAR Path[255]
Definition: vcdioctl.h:10
#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_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_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define IOCTL_VCDROM_DELETE_DRIVE
Definition: vcdioctl.h:3
#define IOCTL_VCDROM_GET_IMAGE_PATH
Definition: vcdioctl.h:6
#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
NTSTATUS ViGetImagePath(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:995
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 ViGetLastSession(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:914
NTSTATUS ViCreateDevice(PDRIVER_OBJECT DriverObject, PIRP Irp)
Definition: vcdrom.c:653
NTSTATUS ViReadTocEx(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:839
NTSTATUS ViIssueMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image, PIRP Irp)
Definition: vcdrom.c:753
NTSTATUS ViDeleteDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:131
NTSTATUS ViSetIoStatus(NTSTATUS Status, ULONG_PTR Information, PIRP Irp)
Definition: vcdrom.c:109
NTSTATUS ViReadToc(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:797
NTSTATUS ViGetDriveGeometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:675
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by DriverEntry().

◆ VcdHandle()

NTSTATUS NTAPI VcdHandle ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 121 of file vcdrom.c.

122{
123 /* Stub for CREATE, CLEANUP, CLOSE, always a succes */
126
127 return STATUS_SUCCESS;
128}

Referenced by DriverEntry().

◆ VcdRead()

NTSTATUS NTAPI VcdRead ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 539 of file vcdrom.c.

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}
Definition: bufpool.h:45
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_LEAVE
Definition: filesup.c:20
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
#define MOUNT_FLAG_SUPP_UDF
Definition: vcdioctl.h:15
#define MOUNT_FLAG_SUPP_JOLIET
Definition: vcdioctl.h:16
NTSTATUS ViReadFile(PFILE_OBJECT File, PMDL Mdl, PLARGE_INTEGER Offset, PKEVENT Event, ULONG Length, PIO_STATUS_BLOCK IoStatusBlock)
Definition: vcdrom.c:497
NTSTATUS ViVerifyVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: vcdrom.c:483
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
@ 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

Referenced by DriverEntry().

◆ VcdUnload()

VOID NTAPI VcdUnload ( PDRIVER_OBJECT  DriverObject)

Definition at line 159 of file vcdrom.c.

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}

Referenced by DriverEntry().

◆ ViAllocateUnicodeString()

NTSTATUS ViAllocateUnicodeString ( USHORT  BufferLength,
PUNICODE_STRING  UnicodeString 
)

Definition at line 71 of file vcdrom.c.

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}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

Referenced by DriverEntry(), ViCreateDriveLetter(), ViMountImage(), and ViRemountMedia().

◆ ViCheckVerify()

NTSTATUS ViCheckVerify ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 714 of file vcdrom.c.

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}
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

Referenced by VcdDeviceControl().

◆ ViComputeAddress()

ULONG ViComputeAddress ( ULONG  Address)

Definition at line 771 of file vcdrom.c.

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}
static WCHAR Address[46]
Definition: ping.c:68
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ViFillInTrackData().

◆ ViCreateDevice()

NTSTATUS ViCreateDevice ( PDRIVER_OBJECT  DriverObject,
PIRP  Irp 
)

Definition at line 653 of file vcdrom.c.

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}
NTSTATUS ViCreateDriveLetter(PDRIVER_OBJECT DriverObject, WCHAR Letter, WCHAR *EffectiveLetter, PDEVICE_OBJECT *DeviceObject)
Definition: vcdrom.c:186

Referenced by VcdDeviceControl().

◆ ViCreateDriveAndMountImage()

VOID ViCreateDriveAndMountImage ( PDRIVER_OBJECT  DriverObject,
WCHAR  Letter,
LPCWSTR  ImagePath 
)

Definition at line 417 of file vcdrom.c.

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}
WCHAR Letter
NTSTATUS ViMountImage(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING Image)
Definition: vcdrom.c:326

Referenced by ViLoadImagesFromRegistry().

◆ ViCreateDriveLetter()

NTSTATUS ViCreateDriveLetter ( PDRIVER_OBJECT  DriverObject,
WCHAR  Letter,
WCHAR EffectiveLetter,
PDEVICE_OBJECT DeviceObject 
)

Definition at line 186 of file vcdrom.c.

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}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define GENERIC_READ
Definition: compat.h:135
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG DeviceCount
Definition: mpu401.c:26
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define UNICODE_NULL
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID ViFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: vcdrom.c:92
ULONG ViDevicesCount
Definition: vcdrom.c:49

Referenced by ViCreateDevice(), and ViCreateDriveAndMountImage().

◆ ViDeleteDevice()

NTSTATUS ViDeleteDevice ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 131 of file vcdrom.c.

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}
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by VcdDeviceControl(), and VcdUnload().

◆ ViEjectMedia()

NTSTATUS ViEjectMedia ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1023 of file vcdrom.c.

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}

Referenced by VcdDeviceControl().

◆ ViEnumerateDrives()

NTSTATUS ViEnumerateDrives ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 955 of file vcdrom.c.

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}
vector< wstring > DrivesList
Definition: MainDialog.cpp:9
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by VcdDeviceControl().

◆ ViFillInTrackData()

VOID ViFillInTrackData ( PTRACK_DATA  TrackData,
UCHAR  Control,
UCHAR  Adr,
UCHAR  TrackNumber,
ULONG  Address 
)

Definition at line 785 of file vcdrom.c.

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}
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
ULONG ViComputeAddress(ULONG Address)
Definition: vcdrom.c:771
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by ViGetLastSession(), ViReadToc(), and ViReadTocEx().

◆ ViFreeUnicodeString()

VOID ViFreeUnicodeString ( PUNICODE_STRING  UnicodeString)

Definition at line 92 of file vcdrom.c.

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}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

Referenced by ViCreateDriveLetter(), ViDeleteDevice(), ViMountImage(), and ViRemountMedia().

◆ ViGetDriveGeometry()

NTSTATUS ViGetDriveGeometry ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 675 of file vcdrom.c.

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}
@ RemovableMedia
Definition: ntdddisk.h:382
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
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by VcdDeviceControl().

◆ ViGetImagePath()

NTSTATUS ViGetImagePath ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 995 of file vcdrom.c.

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}
USHORT Length
Definition: vcdioctl.h:27
USHORT Mounted
Definition: vcdioctl.h:28
WCHAR Path[255]
Definition: vcdioctl.h:26
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by VcdDeviceControl().

◆ ViGetLastSession()

NTSTATUS ViGetLastSession ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 914 of file vcdrom.c.

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}
#define ADR_NO_MODE_INFORMATION
Definition: ntddcdrm.h:282
TRACK_DATA TrackData[1]
Definition: ntddcdrm.h:208
VOID ViFillInTrackData(PTRACK_DATA TrackData, UCHAR Control, UCHAR Adr, UCHAR TrackNumber, ULONG Address)
Definition: vcdrom.c:785
#define TOC_DATA_TRACK
Definition: vcdrom.c:41

Referenced by VcdDeviceControl().

◆ ViInitializeDeviceExtension()

VOID ViInitializeDeviceExtension ( PDEVICE_OBJECT  DeviceObject)

Definition at line 52 of file vcdrom.c.

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}

Referenced by DriverEntry(), and ViCreateDriveLetter().

◆ ViIssueMountImage()

NTSTATUS ViIssueMountImage ( PDEVICE_OBJECT  DeviceObject,
PUNICODE_STRING  Image,
PIRP  Irp 
)

Definition at line 753 of file vcdrom.c.

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}

Referenced by VcdDeviceControl(), and ViRemountMedia().

◆ ViLoadImagesFromRegistry()

VOID ViLoadImagesFromRegistry ( PDRIVER_OBJECT  DriverObject,
LPCWSTR  RegistryPath 
)

Definition at line 434 of file vcdrom.c.

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}
PRTL_UNICODE_STRING_BUFFER Path
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4220
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
convenient loading of string resources
Definition: globals.h:304
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID ViCreateDriveAndMountImage(PDRIVER_OBJECT DriverObject, WCHAR Letter, LPCWSTR ImagePath)
Definition: vcdrom.c:417

Referenced by DriverEntry().

◆ ViMountImage()

NTSTATUS ViMountImage ( PDEVICE_OBJECT  DeviceObject,
PUNICODE_STRING  Image 
)

Definition at line 326 of file vcdrom.c.

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}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
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
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
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
#define FileStandardInformation
Definition: propsheet.cpp:61

Referenced by ViCreateDriveAndMountImage(), and ViIssueMountImage().

◆ ViReadFile()

NTSTATUS ViReadFile ( PFILE_OBJECT  File,
PMDL  Mdl,
PLARGE_INTEGER  Offset,
PKEVENT  Event,
ULONG  Length,
PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 497 of file vcdrom.c.

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}
Definition: File.h:16
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
void * PVOID
Definition: typedefs.h:50
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_PAGING_IO
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_NOCACHE

Referenced by VcdRead().

◆ ViReadToc()

NTSTATUS ViReadToc ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 797 of file vcdrom.c.

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}
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
#define TOC_LAST_TRACK
Definition: vcdrom.c:42

Referenced by VcdDeviceControl().

◆ ViReadTocEx()

NTSTATUS ViReadTocEx ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 839 of file vcdrom.c.

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}
#define MAXIMUM_CDROM_SIZE
Definition: hwide.h:288
#define CDROM_READ_TOC_EX_FORMAT_SESSION
Definition: ntddcdrm.h:163
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:164
#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 CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:167
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by VcdDeviceControl().

◆ ViRemountMedia()

NTSTATUS ViRemountMedia ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1048 of file vcdrom.c.

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}

Referenced by VcdDeviceControl().

◆ ViSetIoStatus()

NTSTATUS ViSetIoStatus ( NTSTATUS  Status,
ULONG_PTR  Information,
PIRP  Irp 
)

Definition at line 109 of file vcdrom.c.

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}

Referenced by VcdDeviceControl(), VcdHandle(), VcdRead(), ViCheckVerify(), ViCreateDevice(), ViDeleteDevice(), ViEjectMedia(), ViEnumerateDrives(), ViGetDriveGeometry(), ViGetImagePath(), ViGetLastSession(), ViIssueMountImage(), ViReadToc(), ViReadTocEx(), and ViRemountMedia().

◆ ViVerifyVolume()

NTSTATUS ViVerifyVolume ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 483 of file vcdrom.c.

484{
485 /* Force verify */
487
488 Irp->IoStatus.Information = 0;
489 Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
490
492
494}

Referenced by VcdRead(), ViGetDriveGeometry(), ViGetLastSession(), ViReadToc(), and ViReadTocEx().

Variable Documentation

◆ ViDevicesCount

ULONG ViDevicesCount

Definition at line 49 of file vcdrom.c.

Referenced by ViCreateDriveLetter().

◆ ViMutex

FAST_MUTEX ViMutex

Definition at line 48 of file vcdrom.c.

Referenced by DriverEntry(), and ViCreateDriveLetter().