mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Added support for multi session CD's.
svn path=/trunk/; revision=3508
This commit is contained in:
parent
3c54f08801
commit
520643c107
3 changed files with 275 additions and 186 deletions
|
@ -128,11 +128,14 @@ typedef struct _SVD SVD, *PSVD;
|
||||||
|
|
||||||
typedef struct _CDINFO
|
typedef struct _CDINFO
|
||||||
{
|
{
|
||||||
|
ULONG VolumeOffset;
|
||||||
ULONG VolumeSpaceSize;
|
ULONG VolumeSpaceSize;
|
||||||
ULONG JolietLevel;
|
ULONG JolietLevel;
|
||||||
ULONG RootStart;
|
ULONG RootStart;
|
||||||
ULONG RootSize;
|
ULONG RootSize;
|
||||||
|
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH];
|
||||||
|
ULONG VolumeLabelLength;
|
||||||
|
ULONG SerialNumber;
|
||||||
} CDINFO, *PCDINFO;
|
} CDINFO, *PCDINFO;
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,6 +243,10 @@ NTSTATUS STDCALL
|
||||||
CdfsClose(PDEVICE_OBJECT DeviceObject,
|
CdfsClose(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp);
|
PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CdfsCloseFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
/* common.c */
|
/* common.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -254,6 +261,14 @@ CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN OUT PUCHAR Buffer);
|
IN OUT PUCHAR Buffer);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG CtlCode,
|
||||||
|
IN PVOID InputBuffer,
|
||||||
|
IN ULONG InputBufferSize,
|
||||||
|
IN OUT PVOID OutputBuffer,
|
||||||
|
IN OUT PULONG pOutputBufferSize);
|
||||||
|
|
||||||
/* create.c */
|
/* create.c */
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
@ -331,6 +346,10 @@ NTSTATUS STDCALL
|
||||||
CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp);
|
PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
CdfsSetInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp);
|
||||||
|
|
||||||
/* fsctl.c */
|
/* fsctl.c */
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: common.c,v 1.4 2002/05/09 15:53:02 ekohl Exp $
|
/* $Id: common.c,v 1.5 2002/09/15 22:25:05 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -191,4 +191,67 @@ CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG CtlCode,
|
||||||
|
IN PVOID InputBuffer,
|
||||||
|
IN ULONG InputBufferSize,
|
||||||
|
IN OUT PVOID OutputBuffer,
|
||||||
|
IN OUT PULONG pOutputBufferSize)
|
||||||
|
{
|
||||||
|
ULONG OutputBufferSize = 0;
|
||||||
|
KEVENT Event;
|
||||||
|
PIRP Irp;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("CdfsDeviceIoControl(DeviceObject %x, CtlCode %x, "
|
||||||
|
"InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
|
||||||
|
"POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
|
||||||
|
InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
|
||||||
|
pOutputBufferSize ? *pOutputBufferSize : 0);
|
||||||
|
|
||||||
|
if (pOutputBufferSize)
|
||||||
|
{
|
||||||
|
OutputBufferSize = *pOutputBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeInitializeEvent (&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
DPRINT("Building device I/O control request ...\n");
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(CtlCode,
|
||||||
|
DeviceObject,
|
||||||
|
InputBuffer,
|
||||||
|
InputBufferSize,
|
||||||
|
OutputBuffer,
|
||||||
|
OutputBufferSize,
|
||||||
|
FALSE,
|
||||||
|
&Event,
|
||||||
|
&IoStatus);
|
||||||
|
if (Irp == NULL)
|
||||||
|
{
|
||||||
|
DPRINT("IoBuildDeviceIoControlRequest failed\n");
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT ("Calling IO Driver... with irp %x\n", Irp);
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
DPRINT ("Waiting for IO Operation for %x\n", Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT ("Operation pending\n");
|
||||||
|
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
|
||||||
|
DPRINT ("Getting IO Status... for %x\n", Irp);
|
||||||
|
|
||||||
|
Status = IoStatus.Status;
|
||||||
|
}
|
||||||
|
if (OutputBufferSize)
|
||||||
|
{
|
||||||
|
*pOutputBufferSize = OutputBufferSize;
|
||||||
|
}
|
||||||
|
DPRINT("Returning Status %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: fsctl.c,v 1.9 2002/09/08 10:22:09 chorns Exp $
|
/* $Id: fsctl.c,v 1.10 2002/09/15 22:25:05 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -37,10 +38,15 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int msf_to_lba (BYTE m, BYTE s, BYTE f)
|
||||||
|
{
|
||||||
|
return (((m * 60) + s) * 75 + f) - 150;
|
||||||
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
CdfsGetPVDData(PUCHAR Buffer,
|
CdfsGetPVDData(PUCHAR Buffer,
|
||||||
PDEVICE_EXTENSION Vcb,
|
PCDINFO CdInfo)
|
||||||
PVPB Vpb)
|
|
||||||
{
|
{
|
||||||
PPVD Pvd;
|
PPVD Pvd;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -65,34 +71,75 @@ CdfsGetPVDData(PUCHAR Buffer,
|
||||||
Serial.Part[2] += Buffer[i+1];
|
Serial.Part[2] += Buffer[i+1];
|
||||||
Serial.Part[3] += Buffer[i+0];
|
Serial.Part[3] += Buffer[i+0];
|
||||||
}
|
}
|
||||||
Vpb->SerialNumber = Serial.Value;
|
CdInfo->SerialNumber = Serial.Value;
|
||||||
|
|
||||||
/* Extract the volume label */
|
/* Extract the volume label */
|
||||||
pc = Pvd->VolumeId;
|
pc = Pvd->VolumeId;
|
||||||
pw = Vpb->VolumeLabel;
|
pw = CdInfo->VolumeLabel;
|
||||||
for (i = 0; i < MAXIMUM_VOLUME_LABEL_LENGTH && *pc != ' '; i++)
|
for (i = 0; i < MAXIMUM_VOLUME_LABEL_LENGTH && *pc != ' '; i++)
|
||||||
{
|
{
|
||||||
*pw++ = (WCHAR)*pc++;
|
*pw++ = (WCHAR)*pc++;
|
||||||
}
|
}
|
||||||
*pw = 0;
|
*pw = 0;
|
||||||
Vpb->VolumeLabelLength = i;
|
CdInfo->VolumeLabelLength = i;
|
||||||
|
|
||||||
Vcb->CdInfo.VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
|
CdInfo->VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
|
||||||
Vcb->CdInfo.RootStart = Pvd->RootDirRecord.ExtentLocationL;
|
CdInfo->RootStart = Pvd->RootDirRecord.ExtentLocationL;
|
||||||
Vcb->CdInfo.RootSize = Pvd->RootDirRecord.DataLengthL;
|
CdInfo->RootSize = Pvd->RootDirRecord.DataLengthL;
|
||||||
|
|
||||||
DPRINT("VolumeSerial: %08lx\n", Vpb->SerialNumber);
|
DPRINT("VolumeSerial: %08lx\n", CdInfo->SerialNumber);
|
||||||
DPRINT("VolumeLabel: '%S'\n", Vpb->VolumeLabel);
|
DPRINT("VolumeLabel: '%S'\n", CdInfo->VolumeLabel);
|
||||||
DPRINT("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength);
|
DPRINT("VolumeLabelLength: %lu\n", CdInfo->VolumeLabelLength);
|
||||||
DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
|
DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
|
||||||
DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
|
DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
|
||||||
DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
|
DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
DbgPrint("******** PVD **********\n");
|
||||||
|
DbgPrint("VdType: %d\n", Pvd->VdType);
|
||||||
|
DbgPrint("StandardId: '%.*s'\n", 5, Pvd->StandardId);
|
||||||
|
DbgPrint("VdVersion: %d\n", Pvd->VdVersion);
|
||||||
|
DbgPrint("SystemId: '%.*s'\n", 32, Pvd->SystemId);
|
||||||
|
DbgPrint("VolumeId: '%.*s'\n", 32, Pvd->VolumeId);
|
||||||
|
DbgPrint("VolumeSpaceSizeL: %d (%x)\n", Pvd->VolumeSpaceSizeL, Pvd->VolumeSpaceSizeL);
|
||||||
|
DbgPrint("VolumeSpaceSizeM: %d (%x)\n", Pvd->VolumeSpaceSizeM, Pvd->VolumeSpaceSizeM);
|
||||||
|
DbgPrint("VolumeSetSize: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
|
||||||
|
DbgPrint("VolumeSequenceNumber: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
|
||||||
|
DbgPrint("LogicalBlockSize: %d (%x)\n", Pvd->LogicalBlockSize, Pvd->LogicalBlockSize);
|
||||||
|
DbgPrint("PathTableSizeL: %d (%x)\n", Pvd->PathTableSizeL, Pvd->PathTableSizeL);
|
||||||
|
DbgPrint("PathTableSizeM: %d (%x)\n", Pvd->PathTableSizeM, Pvd->PathTableSizeM);
|
||||||
|
DbgPrint("LPathTablePos: %d (%x)\n", Pvd->LPathTablePos, Pvd->LPathTablePos);
|
||||||
|
DbgPrint("LOptPathTablePos: %d (%x)\n", Pvd->LOptPathTablePos, Pvd->LOptPathTablePos);
|
||||||
|
DbgPrint("MPathTablePos: %d (%x)\n", Pvd->MPathTablePos, Pvd->MPathTablePos);
|
||||||
|
DbgPrint("MOptPathTablePos: %d (%x)\n", Pvd->MOptPathTablePos, Pvd->MOptPathTablePos);
|
||||||
|
DbgPrint("VolumeSetIdentifier: '%.*s'\n", 128, Pvd->VolumeSetIdentifier);
|
||||||
|
DbgPrint("PublisherIdentifier: '%.*s'\n", 128, Pvd->PublisherIdentifier);
|
||||||
|
DbgPrint("******** Root *********\n");
|
||||||
|
DbgPrint("RecordLength: %d\n", Pvd->RootDirRecord.RecordLength);
|
||||||
|
DbgPrint("ExtAttrRecordLength: %d\n", Pvd->RootDirRecord.ExtAttrRecordLength);
|
||||||
|
DbgPrint("ExtentLocationL: %d\n", Pvd->RootDirRecord.ExtentLocationL);
|
||||||
|
DbgPrint("DataLengthL: %d\n", Pvd->RootDirRecord.DataLengthL);
|
||||||
|
DbgPrint("Year: %d\n", Pvd->RootDirRecord.Year);
|
||||||
|
DbgPrint("Month: %d\n", Pvd->RootDirRecord.Month);
|
||||||
|
DbgPrint("Day: %d\n", Pvd->RootDirRecord.Day);
|
||||||
|
DbgPrint("Hour: %d\n", Pvd->RootDirRecord.Hour);
|
||||||
|
DbgPrint("Minute: %d\n", Pvd->RootDirRecord.Minute);
|
||||||
|
DbgPrint("Second: %d\n", Pvd->RootDirRecord.Second);
|
||||||
|
DbgPrint("TimeZone: %d\n", Pvd->RootDirRecord.TimeZone);
|
||||||
|
DbgPrint("FileFlags: %d\n", Pvd->RootDirRecord.FileFlags);
|
||||||
|
DbgPrint("FileUnitSize: %d\n", Pvd->RootDirRecord.FileUnitSize);
|
||||||
|
DbgPrint("InterleaveGapSize: %d\n", Pvd->RootDirRecord.InterleaveGapSize);
|
||||||
|
DbgPrint("VolumeSequenceNumber: %d\n", Pvd->RootDirRecord.VolumeSequenceNumber);
|
||||||
|
DbgPrint("FileIdLength: %d\n", Pvd->RootDirRecord.FileIdLength);
|
||||||
|
DbgPrint("FileId: '%.*s'\n", Pvd->RootDirRecord.FileId);
|
||||||
|
DbgPrint("***********************\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
CdfsGetSVDData(PUCHAR Buffer,
|
CdfsGetSVDData(PUCHAR Buffer,
|
||||||
PDEVICE_EXTENSION Vcb)
|
PCDINFO CdInfo)
|
||||||
{
|
{
|
||||||
PSVD Svd;
|
PSVD Svd;
|
||||||
ULONG JolietLevel = 0;
|
ULONG JolietLevel = 0;
|
||||||
|
@ -117,12 +164,12 @@ CdfsGetSVDData(PUCHAR Buffer,
|
||||||
JolietLevel = 3;
|
JolietLevel = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vcb->CdInfo.JolietLevel = JolietLevel;
|
CdInfo->JolietLevel = JolietLevel;
|
||||||
|
|
||||||
if (JolietLevel != 0)
|
if (JolietLevel != 0)
|
||||||
{
|
{
|
||||||
Vcb->CdInfo.RootStart = Svd->RootDirRecord.ExtentLocationL;
|
CdInfo->RootStart = Svd->RootDirRecord.ExtentLocationL;
|
||||||
Vcb->CdInfo.RootSize = Svd->RootDirRecord.DataLengthL;
|
CdInfo->RootSize = Svd->RootDirRecord.DataLengthL;
|
||||||
|
|
||||||
DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
|
DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
|
||||||
DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
|
DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
|
||||||
|
@ -132,32 +179,97 @@ CdfsGetSVDData(PUCHAR Buffer,
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
||||||
PDEVICE_EXTENSION Vcb)
|
PCDINFO CdInfo)
|
||||||
{
|
{
|
||||||
PUCHAR Buffer;
|
PUCHAR Buffer;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG Sector;
|
ULONG Sector;
|
||||||
PVD_HEADER VdHeader;
|
PVD_HEADER VdHeader;
|
||||||
|
PCDROM_TOC Toc;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG Offset;
|
||||||
|
ULONG i;
|
||||||
|
PTRACK_DATA TrackData;
|
||||||
|
|
||||||
Vcb->CdInfo.JolietLevel = 0;
|
DPRINT("CdfsGetVolumeData\n");
|
||||||
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
|
|
||||||
|
|
||||||
Buffer = ExAllocatePool(NonPagedPool,
|
Buffer = ExAllocatePool(NonPagedPool,
|
||||||
CDFS_BASIC_SECTOR);
|
max (CDFS_BASIC_SECTOR, CDROM_TOC_SIZE));
|
||||||
|
|
||||||
if (Buffer == NULL)
|
if (Buffer == NULL)
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
VdHeader = (PVD_HEADER)Buffer;
|
Toc = (PCDROM_TOC)Buffer;
|
||||||
|
Size = sizeof(CDROM_TOC);
|
||||||
|
Status = CdfsDeviceIoControl(DeviceObject,
|
||||||
|
IOCTL_CDROM_READ_TOC,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
Toc,
|
||||||
|
&Size);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
CHECKPOINT;
|
||||||
|
if (Toc->FirstTrack == 0xaa)
|
||||||
|
{
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = Toc->LastTrack; i >= Toc->FirstTrack; i--)
|
||||||
|
{
|
||||||
|
TrackData = &Toc->TrackData[i - 1];
|
||||||
|
if (TrackData->Control & 0x4)
|
||||||
|
{
|
||||||
|
/* we have found the last data session */
|
||||||
|
CHECKPOINT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < Toc->FirstTrack)
|
||||||
|
{
|
||||||
|
/* there is no data session on the cd */
|
||||||
|
CHECKPOINT;
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = msf_to_lba(TrackData->Address[1], TrackData->Address[2], TrackData->Address[3]);
|
||||||
|
CdInfo->VolumeOffset = Offset * BLOCKSIZE;
|
||||||
|
|
||||||
|
CdInfo->JolietLevel = 0;
|
||||||
|
VdHeader = (PVD_HEADER)Buffer;
|
||||||
|
Buffer[0] = 0;
|
||||||
|
|
||||||
|
for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++)
|
||||||
{
|
{
|
||||||
/* Read the Primary Volume Descriptor (PVD) */
|
/* Read the Primary Volume Descriptor (PVD) */
|
||||||
Status = CdfsReadRawSectors(DeviceObject,
|
Status = CdfsReadRawSectors(DeviceObject,
|
||||||
Sector,
|
Sector + Offset,
|
||||||
1,
|
1,
|
||||||
Buffer);
|
Buffer);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(Buffer);
|
||||||
return(Status);
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sector == CDFS_PRIMARY_DESCRIPTOR_LOCATION)
|
||||||
|
{
|
||||||
|
DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
|
||||||
|
|
||||||
|
if (Buffer[0] != 1 || Buffer[1] != 'C' || Buffer[2] != 'D' ||
|
||||||
|
Buffer[3] != '0' || Buffer[4] != '0' || Buffer[5] != '1')
|
||||||
|
{
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return STATUS_UNRECOGNIZED_VOLUME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (VdHeader->VdType)
|
switch (VdHeader->VdType)
|
||||||
{
|
{
|
||||||
|
@ -167,12 +279,12 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
DPRINT("PrimaryVolumeDescriptor found!\n");
|
DPRINT("PrimaryVolumeDescriptor found!\n");
|
||||||
CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb);
|
CdfsGetPVDData(Buffer, CdInfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
DPRINT("SupplementaryVolumeDescriptor found!\n");
|
DPRINT("SupplementaryVolumeDescriptor found!\n");
|
||||||
CdfsGetSVDData(Buffer, Vcb);
|
CdfsGetSVDData(Buffer, CdInfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -188,60 +300,13 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sector++;
|
|
||||||
}
|
}
|
||||||
while (VdHeader->VdType != 255);
|
|
||||||
|
|
||||||
ExFreePool(Buffer);
|
ExFreePool(Buffer);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
|
||||||
* by this fsd
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
PUCHAR Buffer;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Buffer = ExAllocatePool(NonPagedPool,
|
|
||||||
CDFS_BASIC_SECTOR);
|
|
||||||
if (Buffer == NULL)
|
|
||||||
{
|
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CDFS: Checking on mount of device %08x\n", DeviceToMount);
|
|
||||||
|
|
||||||
Status = CdfsReadRawSectors(DeviceToMount,
|
|
||||||
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
|
|
||||||
1,
|
|
||||||
Buffer);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer[6] = 0;
|
|
||||||
DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
|
|
||||||
|
|
||||||
Status = (Buffer[0] == 1 &&
|
|
||||||
Buffer[1] == 'C' &&
|
|
||||||
Buffer[2] == 'D' &&
|
|
||||||
Buffer[3] == '0' &&
|
|
||||||
Buffer[4] == '0' &&
|
|
||||||
Buffer[5] == '1') ? STATUS_SUCCESS : STATUS_UNRECOGNIZED_VOLUME;
|
|
||||||
|
|
||||||
ExFreePool(Buffer);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
|
@ -254,6 +319,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
PCCB Ccb = NULL;
|
PCCB Ccb = NULL;
|
||||||
PVPB Vpb;
|
PVPB Vpb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
CDINFO CdInfo;
|
||||||
|
|
||||||
DPRINT("CdfsMountVolume() called\n");
|
DPRINT("CdfsMountVolume() called\n");
|
||||||
|
|
||||||
|
@ -267,7 +333,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
|
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
|
||||||
Vpb = Stack->Parameters.MountVolume.Vpb;
|
Vpb = Stack->Parameters.MountVolume.Vpb;
|
||||||
|
|
||||||
Status = CdfsHasFileSystem(DeviceToMount);
|
Status = CdfsGetVolumeData(DeviceToMount, &CdInfo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
@ -289,10 +355,10 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
RtlZeroMemory(DeviceExt,
|
RtlZeroMemory(DeviceExt,
|
||||||
sizeof(DEVICE_EXTENSION));
|
sizeof(DEVICE_EXTENSION));
|
||||||
|
|
||||||
Status = CdfsGetVolumeData(DeviceToMount,
|
Vpb->SerialNumber = CdInfo.SerialNumber;
|
||||||
DeviceExt);
|
Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
|
||||||
if (!NT_SUCCESS(Status))
|
RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR));
|
||||||
goto ByeBye;
|
RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO));
|
||||||
|
|
||||||
NewDeviceObject->Vpb = DeviceToMount->Vpb;
|
NewDeviceObject->Vpb = DeviceToMount->Vpb;
|
||||||
|
|
||||||
|
@ -337,12 +403,11 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
Fcb->Flags = FCB_IS_VOLUME_STREAM;
|
Fcb->Flags = FCB_IS_VOLUME_STREAM;
|
||||||
|
|
||||||
Fcb->RFCB.FileSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
|
||||||
Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
|
||||||
Fcb->RFCB.AllocationSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
|
||||||
|
|
||||||
Fcb->Entry.ExtentLocationL = 0;
|
Fcb->Entry.ExtentLocationL = 0;
|
||||||
Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
|
||||||
|
|
||||||
Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject,
|
Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject,
|
||||||
&Fcb->RFCB.Bcb,
|
&Fcb->RFCB.Bcb,
|
||||||
|
@ -387,16 +452,8 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT DeviceToVerify;
|
PDEVICE_OBJECT DeviceToVerify;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
PUCHAR Buffer;
|
|
||||||
ULONG Sector;
|
|
||||||
ULONG i;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
CDINFO CdInfo;
|
||||||
union
|
|
||||||
{
|
|
||||||
ULONG Value;
|
|
||||||
UCHAR Part[4];
|
|
||||||
} Serial;
|
|
||||||
|
|
||||||
DPRINT1("CdfsVerifyVolume() called\n");
|
DPRINT1("CdfsVerifyVolume() called\n");
|
||||||
|
|
||||||
|
@ -413,68 +470,18 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
DPRINT("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
|
DPRINT("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
|
||||||
|
|
||||||
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
|
CdInfo.SerialNumber = ~DeviceToVerify->Vpb->SerialNumber;
|
||||||
|
|
||||||
Buffer = ExAllocatePool(NonPagedPool,
|
Status = CdfsGetVolumeData(DeviceToVerify, &CdInfo);
|
||||||
CDFS_BASIC_SECTOR);
|
|
||||||
if (Buffer == NULL)
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Read the Primary Volume Descriptor (PVD) */
|
|
||||||
Status = CdfsReadRawSectors(DeviceToVerify,
|
|
||||||
Sector,
|
|
||||||
1,
|
|
||||||
Buffer);
|
|
||||||
DPRINT("CdfsReadRawSectors() status %lx\n", Status);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
goto ByeBye;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Buffer[0] == 1 &&
|
|
||||||
Buffer[1] == 'C' &&
|
|
||||||
Buffer[2] == 'D' &&
|
|
||||||
Buffer[3] == '0' &&
|
|
||||||
Buffer[4] == '0' &&
|
|
||||||
Buffer[5] == '1')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sector++;
|
|
||||||
}
|
|
||||||
while (Buffer[0] != 255);
|
|
||||||
|
|
||||||
if (Buffer[0] == 255)
|
|
||||||
goto ByeBye;
|
|
||||||
|
|
||||||
Status = STATUS_WRONG_VOLUME;
|
|
||||||
|
|
||||||
/* Calculate the volume serial number */
|
|
||||||
Serial.Value = 0;
|
|
||||||
for (i = 0; i < 2048; i += 4)
|
|
||||||
{
|
|
||||||
/* DON'T optimize this to ULONG!!! (breaks overflow) */
|
|
||||||
Serial.Part[0] += Buffer[i+3];
|
|
||||||
Serial.Part[1] += Buffer[i+2];
|
|
||||||
Serial.Part[2] += Buffer[i+1];
|
|
||||||
Serial.Part[3] += Buffer[i+0];
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Current serial number %08lx Vpb serial number %08lx\n",
|
DPRINT("Current serial number %08lx Vpb serial number %08lx\n",
|
||||||
Serial.Value, DeviceToVerify->Vpb->SerialNumber);
|
CdInfo.SerialNumber, DeviceToVerify->Vpb->SerialNumber);
|
||||||
|
|
||||||
if (Serial.Value == DeviceToVerify->Vpb->SerialNumber)
|
if (CdInfo.SerialNumber != DeviceToVerify->Vpb->SerialNumber)
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_WRONG_VOLUME;
|
||||||
|
}
|
||||||
ByeBye:
|
|
||||||
ExFreePool(Buffer);
|
|
||||||
|
|
||||||
DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status);
|
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue