mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +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
|
||||
{
|
||||
ULONG VolumeOffset;
|
||||
ULONG VolumeSpaceSize;
|
||||
ULONG JolietLevel;
|
||||
ULONG RootStart;
|
||||
ULONG RootSize;
|
||||
|
||||
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH];
|
||||
ULONG VolumeLabelLength;
|
||||
ULONG SerialNumber;
|
||||
} CDINFO, *PCDINFO;
|
||||
|
||||
|
||||
|
@ -240,6 +243,10 @@ NTSTATUS STDCALL
|
|||
CdfsClose(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
CdfsCloseFile(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject);
|
||||
|
||||
/* common.c */
|
||||
|
||||
NTSTATUS
|
||||
|
@ -254,6 +261,14 @@ CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
|
|||
IN ULONG SectorCount,
|
||||
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 */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
@ -331,6 +346,10 @@ NTSTATUS STDCALL
|
|||
CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CdfsSetInformation(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
/* fsctl.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -191,4 +191,67 @@ CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
|
|||
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 */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -29,6 +29,7 @@
|
|||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -37,10 +38,15 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static inline
|
||||
int msf_to_lba (BYTE m, BYTE s, BYTE f)
|
||||
{
|
||||
return (((m * 60) + s) * 75 + f) - 150;
|
||||
}
|
||||
|
||||
static VOID
|
||||
CdfsGetPVDData(PUCHAR Buffer,
|
||||
PDEVICE_EXTENSION Vcb,
|
||||
PVPB Vpb)
|
||||
CdfsGetPVDData(PUCHAR Buffer,
|
||||
PCDINFO CdInfo)
|
||||
{
|
||||
PPVD Pvd;
|
||||
ULONG i;
|
||||
|
@ -65,34 +71,75 @@ CdfsGetPVDData(PUCHAR Buffer,
|
|||
Serial.Part[2] += Buffer[i+1];
|
||||
Serial.Part[3] += Buffer[i+0];
|
||||
}
|
||||
Vpb->SerialNumber = Serial.Value;
|
||||
CdInfo->SerialNumber = Serial.Value;
|
||||
|
||||
/* Extract the volume label */
|
||||
pc = Pvd->VolumeId;
|
||||
pw = Vpb->VolumeLabel;
|
||||
pw = CdInfo->VolumeLabel;
|
||||
for (i = 0; i < MAXIMUM_VOLUME_LABEL_LENGTH && *pc != ' '; i++)
|
||||
{
|
||||
*pw++ = (WCHAR)*pc++;
|
||||
}
|
||||
*pw = 0;
|
||||
Vpb->VolumeLabelLength = i;
|
||||
CdInfo->VolumeLabelLength = i;
|
||||
|
||||
Vcb->CdInfo.VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
|
||||
Vcb->CdInfo.RootStart = Pvd->RootDirRecord.ExtentLocationL;
|
||||
Vcb->CdInfo.RootSize = Pvd->RootDirRecord.DataLengthL;
|
||||
CdInfo->VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
|
||||
CdInfo->RootStart = Pvd->RootDirRecord.ExtentLocationL;
|
||||
CdInfo->RootSize = Pvd->RootDirRecord.DataLengthL;
|
||||
|
||||
DPRINT("VolumeSerial: %08lx\n", Vpb->SerialNumber);
|
||||
DPRINT("VolumeLabel: '%S'\n", Vpb->VolumeLabel);
|
||||
DPRINT("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength);
|
||||
DPRINT("VolumeSerial: %08lx\n", CdInfo->SerialNumber);
|
||||
DPRINT("VolumeLabel: '%S'\n", CdInfo->VolumeLabel);
|
||||
DPRINT("VolumeLabelLength: %lu\n", CdInfo->VolumeLabelLength);
|
||||
DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
|
||||
DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
|
||||
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
|
||||
CdfsGetSVDData(PUCHAR Buffer,
|
||||
PDEVICE_EXTENSION Vcb)
|
||||
PCDINFO CdInfo)
|
||||
{
|
||||
PSVD Svd;
|
||||
ULONG JolietLevel = 0;
|
||||
|
@ -117,12 +164,12 @@ CdfsGetSVDData(PUCHAR Buffer,
|
|||
JolietLevel = 3;
|
||||
}
|
||||
|
||||
Vcb->CdInfo.JolietLevel = JolietLevel;
|
||||
CdInfo->JolietLevel = JolietLevel;
|
||||
|
||||
if (JolietLevel != 0)
|
||||
{
|
||||
Vcb->CdInfo.RootStart = Svd->RootDirRecord.ExtentLocationL;
|
||||
Vcb->CdInfo.RootSize = Svd->RootDirRecord.DataLengthL;
|
||||
CdInfo->RootStart = Svd->RootDirRecord.ExtentLocationL;
|
||||
CdInfo->RootSize = Svd->RootDirRecord.DataLengthL;
|
||||
|
||||
DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
|
||||
DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
|
||||
|
@ -132,116 +179,134 @@ CdfsGetSVDData(PUCHAR Buffer,
|
|||
|
||||
static NTSTATUS
|
||||
CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
||||
PDEVICE_EXTENSION Vcb)
|
||||
PCDINFO CdInfo)
|
||||
{
|
||||
PUCHAR Buffer;
|
||||
NTSTATUS Status;
|
||||
ULONG Sector;
|
||||
PVD_HEADER VdHeader;
|
||||
PCDROM_TOC Toc;
|
||||
ULONG Size;
|
||||
ULONG Offset;
|
||||
ULONG i;
|
||||
PTRACK_DATA TrackData;
|
||||
|
||||
Vcb->CdInfo.JolietLevel = 0;
|
||||
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
|
||||
|
||||
DPRINT("CdfsGetVolumeData\n");
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
CDFS_BASIC_SECTOR);
|
||||
max (CDFS_BASIC_SECTOR, CDROM_TOC_SIZE));
|
||||
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
do
|
||||
{
|
||||
/* Read the Primary Volume Descriptor (PVD) */
|
||||
Status = CdfsReadRawSectors(DeviceObject,
|
||||
Sector,
|
||||
1,
|
||||
Buffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return(Status);
|
||||
|
||||
switch (VdHeader->VdType)
|
||||
for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++)
|
||||
{
|
||||
/* Read the Primary Volume Descriptor (PVD) */
|
||||
Status = CdfsReadRawSectors(DeviceObject,
|
||||
Sector + Offset,
|
||||
1,
|
||||
Buffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
case 0:
|
||||
DPRINT("BootVolumeDescriptor found!\n");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DPRINT("PrimaryVolumeDescriptor found!\n");
|
||||
CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DPRINT("SupplementaryVolumeDescriptor found!\n");
|
||||
CdfsGetSVDData(Buffer, Vcb);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DPRINT("VolumePartitionDescriptor found!\n");
|
||||
break;
|
||||
|
||||
case 255:
|
||||
DPRINT("VolumeDescriptorSetTerminator found!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
|
||||
break;
|
||||
ExFreePool(Buffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Sector++;
|
||||
}
|
||||
while (VdHeader->VdType != 255);
|
||||
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)
|
||||
{
|
||||
case 0:
|
||||
DPRINT("BootVolumeDescriptor found!\n");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DPRINT("PrimaryVolumeDescriptor found!\n");
|
||||
CdfsGetPVDData(Buffer, CdInfo);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DPRINT("SupplementaryVolumeDescriptor found!\n");
|
||||
CdfsGetSVDData(Buffer, CdInfo);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DPRINT("VolumePartitionDescriptor found!\n");
|
||||
break;
|
||||
|
||||
case 255:
|
||||
DPRINT("VolumeDescriptorSetTerminator found!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ExFreePool(Buffer);
|
||||
|
||||
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
|
||||
CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
|
@ -254,6 +319,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
PCCB Ccb = NULL;
|
||||
PVPB Vpb;
|
||||
NTSTATUS Status;
|
||||
CDINFO CdInfo;
|
||||
|
||||
DPRINT("CdfsMountVolume() called\n");
|
||||
|
||||
|
@ -267,7 +333,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
|
||||
Vpb = Stack->Parameters.MountVolume.Vpb;
|
||||
|
||||
Status = CdfsHasFileSystem(DeviceToMount);
|
||||
Status = CdfsGetVolumeData(DeviceToMount, &CdInfo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto ByeBye;
|
||||
|
@ -289,11 +355,11 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
RtlZeroMemory(DeviceExt,
|
||||
sizeof(DEVICE_EXTENSION));
|
||||
|
||||
Status = CdfsGetVolumeData(DeviceToMount,
|
||||
DeviceExt);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
Vpb->SerialNumber = CdInfo.SerialNumber;
|
||||
Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
|
||||
RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR));
|
||||
RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO));
|
||||
|
||||
NewDeviceObject->Vpb = DeviceToMount->Vpb;
|
||||
|
||||
DeviceExt->StorageDevice = DeviceToMount;
|
||||
|
@ -337,12 +403,11 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
Fcb->Flags = FCB_IS_VOLUME_STREAM;
|
||||
|
||||
Fcb->RFCB.FileSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
||||
Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
||||
Fcb->RFCB.AllocationSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
|
||||
Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
|
||||
Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
|
||||
|
||||
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,
|
||||
&Fcb->RFCB.Bcb,
|
||||
|
@ -387,16 +452,8 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PUCHAR Buffer;
|
||||
ULONG Sector;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
union
|
||||
{
|
||||
ULONG Value;
|
||||
UCHAR Part[4];
|
||||
} Serial;
|
||||
CDINFO CdInfo;
|
||||
|
||||
DPRINT1("CdfsVerifyVolume() called\n");
|
||||
|
||||
|
@ -413,68 +470,18 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
DPRINT("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
|
||||
|
||||
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
|
||||
CdInfo.SerialNumber = ~DeviceToVerify->Vpb->SerialNumber;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
CDFS_BASIC_SECTOR);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
Status = CdfsGetVolumeData(DeviceToVerify, &CdInfo);
|
||||
|
||||
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 (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Current serial number %08lx Vpb serial number %08lx\n",
|
||||
CdInfo.SerialNumber, DeviceToVerify->Vpb->SerialNumber);
|
||||
|
||||
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",
|
||||
Serial.Value, DeviceToVerify->Vpb->SerialNumber);
|
||||
|
||||
if (Serial.Value == DeviceToVerify->Vpb->SerialNumber)
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ByeBye:
|
||||
ExFreePool(Buffer);
|
||||
|
||||
DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status);
|
||||
if (CdInfo.SerialNumber != DeviceToVerify->Vpb->SerialNumber)
|
||||
Status = STATUS_WRONG_VOLUME;
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue