Implemented verify override for device access routines and started experimental media change support.

svn path=/trunk/; revision=6590
This commit is contained in:
Eric Kohl 2003-11-09 11:20:28 +00:00
parent 0327d87e6e
commit 2433129700
5 changed files with 192 additions and 189 deletions

View file

@ -221,21 +221,17 @@ typedef struct
extern PCDFS_GLOBAL_DATA CdfsGlobalData;
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
int CdfsStrcmpi( wchar_t *str1, wchar_t *str2 );
void CdfsWstrcpy( wchar_t *str1, wchar_t *str2, int max );
/* cleanup.c */
NTSTATUS STDCALL
CdfsCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* close.c */
NTSTATUS STDCALL
@ -246,27 +242,25 @@ NTSTATUS
CdfsCloseFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject);
/* common.c */
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
NTSTATUS
CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
IN OUT PUCHAR Buffer,
IN BOOLEAN Override);
NTSTATUS
CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
IN ULONG CtlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG pOutputBufferSize);
IN OUT PVOID OutputBuffer,
IN OUT PULONG pOutputBufferSize,
IN BOOLEAN Override);
/* create.c */
@ -349,12 +343,18 @@ NTSTATUS STDCALL
CdfsSetInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* fsctl.c */
NTSTATUS
CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
PCDINFO CdInfo);
NTSTATUS STDCALL
CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* misc.c */
BOOLEAN
@ -373,6 +373,7 @@ VOID
CdfsFileFlagsToAttributes(PFCB Fcb,
PULONG FileAttributes);
/* rw.c */
NTSTATUS STDCALL

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
* Copyright (C) 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,13 +16,14 @@
* 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.5 2002/09/15 22:25:05 hbirr Exp $
/* $Id: common.c,v 1.6 2003/11/09 11:20:28 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/volume.c
* FILE: drivers/fs/cdfs/common.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -41,8 +42,10 @@ NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer)
IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
@ -79,6 +82,12 @@ CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
return(STATUS_INSUFFICIENT_RESOURCES);
}
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT("Calling IO Driver... with irp %x\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
@ -119,90 +128,20 @@ CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
}
NTSTATUS
CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Offset.u.LowPart = DiskSector << 11;
Offset.u.HighPart = DiskSector >> 21;
BlockSize = BLOCKSIZE * SectorCount;
DPRINT("CdfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
DeviceObject, DiskSector, Buffer);
DPRINT("Offset %I64x BlockSize %ld\n",
Offset.QuadPart,
BlockSize);
DPRINT("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Buffer,
BlockSize,
&Offset,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
// Stack = IoGetCurrentIrpStackLocation(Irp);
// Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
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 (!NT_SUCCESS(Status))
{
DPRINT("CdfsReadSectors() failed (Status %x)\n", Status);
DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
DeviceObject, DiskSector, Buffer,
Offset.QuadPart);
return(Status);
}
DPRINT("Block request succeeded for %x\n", Irp);
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)
IN OUT PVOID OutputBuffer,
IN OUT PULONG pOutputBufferSize,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
ULONG OutputBufferSize = 0;
KEVENT Event;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
DPRINT("CdfsDeviceIoControl(DeviceObject %x, CtlCode %x, "
@ -212,45 +151,54 @@ CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
pOutputBufferSize ? *pOutputBufferSize : 0);
if (pOutputBufferSize)
{
OutputBufferSize = *pOutputBufferSize;
}
{
OutputBufferSize = *pOutputBufferSize;
}
KeInitializeEvent (&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(CtlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
Irp = IoBuildDeviceIoControlRequest(CtlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
OutputBufferSize,
FALSE,
&Event,
OutputBufferSize,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
{
DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
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);
{
DPRINT ("Operation pending\n");
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %x\n", Irp);
Status = IoStatus.Status;
}
if (OutputBufferSize)
{
Status = IoStatus.Status;
}
if (pOutputBufferSize)
{
*pOutputBufferSize = OutputBufferSize;
}
}
DPRINT("Returning Status %x\n", Status);
return Status;
}

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
* Copyright (C) 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,14 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: create.c,v 1.8 2003/02/13 22:24:15 hbirr Exp $
/* $Id: create.c,v 1.9 2003/11/09 11:20:28 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/cdfs.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* UPDATE HISTORY:
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -35,6 +35,8 @@
#include "cdfs.h"
//#define MEDIA_CHANGE_SUPPORT
/* FUNCTIONS ****************************************************************/
@ -89,6 +91,10 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
PFCB Fcb;
NTSTATUS Status;
PWSTR AbsFileName = NULL;
#ifdef MEDIA_CHANGE_SUPPORT
ULONG MediaChangeCount = 0;
ULONG BufferSize;
#endif
DPRINT("CdfsOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
@ -107,6 +113,50 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
return(STATUS_UNSUCCESSFUL);
}
#ifdef MEDIA_CHANGE_SUPPORT
BufferSize = sizeof(ULONG);
Status = CdfsDeviceIoControl (DeviceExt->StorageDevice,
IOCTL_CDROM_CHECK_VERIFY,
NULL,
0,
(PVOID)&MediaChangeCount,
&BufferSize,
TRUE);
DPRINT ("Status %lx\n", Status);
if (Status == STATUS_VERIFY_REQUIRED)
{
CDINFO CdInfo;
DPRINT1 ("Media change detected!\n");
Status = CdfsGetVolumeData (DeviceExt->StorageDevice,
&CdInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CdfsGetVolumeData() failed (Status %lx)\n", Status);
return Status;
}
/* FIXME: Comparing the serial numbers is not enough */
if (DeviceExt->CdInfo.SerialNumber == CdInfo.SerialNumber)
{
DPRINT1 ("Same CD\n");
}
else
{
DPRINT1 ("Different CD\n");
}
}
else if (!NT_SUCCESS(Status))
{
DPRINT1 ("Status %lx\n", Status);
return Status;
}
else
{
DPRINT ("MediaChangeCount %lu\n", MediaChangeCount);
}
#endif
//FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
DPRINT("PathName to open: %S\n", FileName);

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
* Copyright (C) 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,14 +16,14 @@
* 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.14 2003/06/07 11:34:35 chorns Exp $
/* $Id: fsctl.c,v 1.15 2003/11/09 11:20:28 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/fsctl.c
* FILE: drivers/fs/cdfs/fsctl.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* UPDATE HISTORY:
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -36,6 +36,7 @@
#include "cdfs.h"
/* FUNCTIONS ****************************************************************/
static inline
@ -44,8 +45,9 @@ int msf_to_lba (BYTE m, BYTE s, BYTE f)
return (((m * 60) + s) * 75 + f) - 150;
}
static VOID
CdfsGetPVDData(PUCHAR Buffer,
CdfsGetPVDData(PUCHAR Buffer,
PCDINFO CdInfo)
{
PPVD Pvd;
@ -177,7 +179,7 @@ CdfsGetSVDData(PUCHAR Buffer,
}
static NTSTATUS
NTSTATUS
CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
PCDINFO CdInfo)
{
@ -198,103 +200,104 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
Toc;
DPRINT("CdfsGetVolumeData\n");
Buffer = ExAllocatePool(NonPagedPool,
CDFS_BASIC_SECTOR);
if (Buffer == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
return STATUS_INSUFFICIENT_RESOURCES;
Size = sizeof(Toc);
Status = CdfsDeviceIoControl(DeviceObject,
IOCTL_CDROM_GET_LAST_SESSION,
NULL,
0,
&Toc,
&Size);
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(Buffer);
return Status;
}
{
ExFreePool(Buffer);
return Status;
}
DPRINT("FirstSession %d, LastSession %d, FirstTrack %d\n",
Toc.FirstSession, Toc.LastSession, Toc.TrackData.TrackNumber);
Offset = 0;
for (i = 0; i < 4; i++)
{
Offset = (Offset << 8) + Toc.TrackData.Address[i];
}
{
Offset = (Offset << 8) + Toc.TrackData.Address[i];
}
CdInfo->VolumeOffset = Offset;
DPRINT("Offset of first track in last session %d\n", Offset);
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) */
Status = CdfsReadRawSectors(DeviceObject,
Sector + Offset,
1,
Buffer);
if (!NT_SUCCESS(Status))
{
/* Read the Primary Volume Descriptor (PVD) */
Status = CdfsReadSectors (DeviceObject,
Sector + Offset,
1,
Buffer,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(Buffer);
return(Status);
return Status;
}
if (Sector == CDFS_PRIMARY_DESCRIPTOR_LOCATION)
{
DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
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')
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;
ExFreePool(Buffer);
return STATUS_UNRECOGNIZED_VOLUME;
}
}
switch (VdHeader->VdType)
switch (VdHeader->VdType)
{
case 0:
DPRINT("BootVolumeDescriptor found!\n");
break;
case 0:
DPRINT("BootVolumeDescriptor found!\n");
break;
case 1:
DPRINT("PrimaryVolumeDescriptor found!\n");
CdfsGetPVDData(Buffer, CdInfo);
break;
case 1:
DPRINT("PrimaryVolumeDescriptor found!\n");
CdfsGetPVDData(Buffer, CdInfo);
break;
case 2:
DPRINT("SupplementaryVolumeDescriptor found!\n");
CdfsGetSVDData(Buffer, CdInfo);
break;
case 2:
DPRINT("SupplementaryVolumeDescriptor found!\n");
CdfsGetSVDData(Buffer, CdInfo);
break;
case 3:
DPRINT("VolumePartitionDescriptor found!\n");
break;
case 3:
DPRINT("VolumePartitionDescriptor found!\n");
break;
case 255:
DPRINT("VolumeDescriptorSetTerminator found!\n");
break;
case 255:
DPRINT("VolumeDescriptorSetTerminator found!\n");
break;
default:
DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
break;
default:
DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
break;
}
}
}
ExFreePool(Buffer);
return(STATUS_SUCCESS);
}
static NTSTATUS
CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
@ -347,7 +350,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
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;
@ -461,13 +464,13 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
Status = CdfsGetVolumeData(DeviceToVerify, &CdInfo);
if (NT_SUCCESS(Status))
{
DPRINT("Current serial number %08lx Vpb serial number %08lx\n",
CdInfo.SerialNumber, DeviceToVerify->Vpb->SerialNumber);
{
DPRINT("Current serial number %08lx Vpb serial number %08lx\n",
CdInfo.SerialNumber, DeviceToVerify->Vpb->SerialNumber);
if (CdInfo.SerialNumber != DeviceToVerify->Vpb->SerialNumber)
Status = STATUS_WRONG_VOLUME;
}
if (CdInfo.SerialNumber != DeviceToVerify->Vpb->SerialNumber)
Status = STATUS_WRONG_VOLUME;
}
return(Status);
}

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
* Copyright (C) 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,14 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: rw.c,v 1.10 2003/02/13 22:24:15 hbirr Exp $
/* $Id: rw.c,v 1.11 2003/11/09 11:20:28 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/rw.c
* FILE: drivers/fs/cdfs/rw.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* UPDATE HISTORY:
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -112,7 +112,8 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
Status = CdfsReadSectors(DeviceExt->StorageDevice,
Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE),
Length / BLOCKSIZE,
Buffer);
Buffer,
FALSE);
if (NT_SUCCESS(Status))
{
*LengthRead = Length;