Replaced FCB code.
Improved the mount code.
svn path=/trunk/; revision=2851
/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: cdfs.c,v 1.2 2002/04/15 20:39:49 ekohl Exp $
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/cdfs.c
#include "cdfs.h"
-typedef struct
-{
- PDEVICE_OBJECT StorageDevice;
- PFILE_OBJECT StreamFileObject;
- struct _fcb_system *fss;
-
- PFCB RootFcb;
-
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/* GLOBALS *****************************************************************/
-static PDRIVER_OBJECT DriverObject;
-
-/* FUNCTIONS ****************************************************************/
-
-/* DIRECTORY FUNCTIONS ******************************************************/
-/* Hacked until working directory code... */
-
-NTSTATUS
-FsdGetRootDirectoryData(PDEVICE_OBJECT DeviceObject,
- PFCB RootFcb)
-{
- PPVD Buffer;
- NTSTATUS Status;
-
- Buffer = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
- if (Buffer == NULL)
- return(STATUS_INSUFFICIENT_RESOURCES);
-
- Status = CdfsReadSectors(DeviceObject,
- CDFS_PRIMARY_DESCRIPTOR_LOCATION,
- 1,
- Buffer);
- if (!NT_SUCCESS(Status))
- return Status;
-
- RootFcb->extent_start = Buffer->RootDirRecord.ExtentLocationL;
- RootFcb->byte_count = Buffer->RootDirRecord.DataLengthL;
-
- ExFreePool(Buffer);
-
- DPRINT1("RootFcb->extent_start %lu\n", RootFcb->extent_start);
- DPRINT1("RootFcb->byte_count %lu\n", RootFcb->byte_count);
-
- return(STATUS_SUCCESS);
-}
-
-
-
-/* HACK -- NEEDS FIXING */
-
-int
-FsdExtractDirectoryEntry(PDEVICE_EXTENSION DeviceExt,
- FsdFcbEntry *parent,
- FsdFcbEntry *fill_in,
- int entry_to_get)
-{
- switch( entry_to_get )
- {
- case 0:
- wcscpy( fill_in->name, L"." );
- fill_in->extent_start = parent->extent_start;
- fill_in->byte_count = parent->byte_count;
- break;
-
- case 1:
- wcscpy( fill_in->name, L".." );
- fill_in->extent_start = parent->extent_start;
- fill_in->byte_count = parent->byte_count;
- break;
-
- case 2:
- wcscpy( fill_in->name, L"readme.txt" );
- fill_in->extent_start = 0x190;
- fill_in->byte_count = 0x800;
- break;
-
- default:
- return 1;
- }
-
- return 0;
-}
-
-
-FsdFcbEntry *FsdSearchDirectoryAt( PDEVICE_EXTENSION DeviceExt,
- FsdFcbEntry *parent,
- wchar_t *look_for )
-{
- FsdFcbEntry *ent;
- int i;
-
- ent = FsdCreateFcb( DeviceExt->fss, parent, look_for );
- if( ent )
- return ent;
-
- for( i = 0; i < parent->byte_count; i++ ) {
- FsdFcbEntry new_ent;
- if( FsdExtractDirectoryEntry( DeviceExt, parent, &new_ent, i ) )
- return NULL;
-
- if( !_wcsicmp( new_ent.name, look_for ) ) {
- ent->extent_start = new_ent.extent_start;
- ent->byte_count = new_ent.byte_count;
- return ent;
- }
- }
-
- /* Not found */
- FsdDelete( ent );
-
- return NULL;
-}
-
-NTSTATUS
-FsdCloseFile(PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject)
-/*
- * FUNCTION: Closes a file
- */
-{
- return(STATUS_SUCCESS);
-}
-
-/* Should go into a basic library */
-PFCB
-FsdSearchDirectory(PDEVICE_EXTENSION DeviceExt,
- PFCB ParentFcb,
- PWSTR filename)
-{
- wchar_t *string_imed = NULL;
- wchar_t *string_end = NULL;
- FsdFcbEntry *this_elt = NULL;
-
- DPRINT1("FsdSearchDirectory(%S) called\n", filename);
-
- if (ParentFcb == NULL && *filename == 0)
- return(DeviceExt->RootFcb);
-
-CHECKPOINT1;
- string_imed = ExAllocatePool(NonPagedPool,
- (wcslen( filename ) + 1) * sizeof( wchar_t ) );
-
- if (string_imed == NULL)
- return NULL;
-
- wcscpy( string_imed, filename );
-
-
- /* Chop off a component and try it */
- string_end = wcschr( string_imed, L'\\' );
- if (string_end != NULL)
- {
- *string_end = 0;
- string_end++;
- }
-CHECKPOINT1;
-
- if (ParentFcb == NULL)
- this_elt = FsdGetFcbEntry(DeviceExt->fss, NULL, L"\\");
- else
- this_elt = FsdGetFcbEntry(DeviceExt->fss, ParentFcb, string_imed);
-DPRINT1("this_elt %p\n", this_elt);
-
- if (this_elt)
- {
- ExFreePool( string_imed );
-CHECKPOINT1;
- return this_elt;
- }
-
-CHECKPOINT1;
- this_elt = FsdSearchDirectoryAt( DeviceExt, ParentFcb, string_imed );
-CHECKPOINT1;
-
- /* It's the end if we have nothing more to do */
- if (string_end != NULL)
- this_elt = FsdSearchDirectory( DeviceExt, this_elt, string_end );
-CHECKPOINT1;
-
- ExFreePool( string_imed );
-
- DPRINT1("FsdSearchDirectory() done");
-
- return this_elt;
-}
-
-
-NTSTATUS
-FsdOpenFile(PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject,
- PWSTR FileName)
-/*
- * FUNCTION: Opens a file
- */
-{
- PFCB Fcb;
-
- DPRINT1("FsdOpenFile(FileName %S) called\n", FileName);
-
- /* Just skip leading backslashes... */
- while (*FileName == L'\\')
- FileName++;
-CHECKPOINT1;
-
- Fcb = FsdSearchDirectory(DeviceExt->fss,
- NULL,
- FileName);
-CHECKPOINT1;
- if (Fcb == NULL)
- {
- DPRINT1("FsdSearchDirectory() failed\n");
- return(STATUS_OBJECT_PATH_NOT_FOUND);
- }
-CHECKPOINT1;
-
- FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
- FO_DIRECT_CACHE_PAGING_READ;
- FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
- FileObject->FsContext = Fcb;
- FileObject->FsContext2 = DeviceExt->fss;
-
- DPRINT1("FsdOpenFile() done\n");
-
- return(STATUS_SUCCESS);
-}
-
-
-BOOLEAN
-FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
-/*
- * FUNCTION: Tests if the device contains a filesystem that can be mounted
- * by this fsd
- */
-{
- PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
- NTSTATUS readstatus;
- int ret;
-
- bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
- if( !bytebuf ) return FALSE;
-
- DPRINT1( "CDFS: Checking on mount of device %08x\n", DeviceToMount );
-
- readstatus = CdfsReadSectors(DeviceToMount,
- CDFS_PRIMARY_DESCRIPTOR_LOCATION,
- 1,
- bytebuf);
- bytebuf[6] = 0;
- DPRINT1( "CD-identifier: [%.5s]\n", bytebuf + 1 );
-
- ret =
- readstatus == STATUS_SUCCESS &&
- bytebuf[0] == 1 &&
- bytebuf[1] == 'C' &&
- bytebuf[2] == 'D' &&
- bytebuf[3] == '0' &&
- bytebuf[4] == '0' &&
- bytebuf[5] == '1';
-
- ExFreePool( bytebuf );
-
- return ret;
-}
-
-NTSTATUS
-FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
- PDEVICE_OBJECT DeviceToMount)
-/*
- * FUNCTION: Mounts the device
- */
-{
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS
-FsdReadFile(PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject,
- PVOID Buffer,
- ULONG Length,
- ULONG Offset)
-/*
- * FUNCTION: Reads data from a file
- */
-{
- PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
- NTSTATUS Status;
- int ret;
- int sofar = 0;
- FsdFcbEntry *ffe = FileObject->FsContext;
-
- if( Length ) return STATUS_SUCCESS;
-
- bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
- if (!bytebuf)
- return FALSE;
-
- if (Offset + Length > ffe->byte_count)
- Length = ffe->byte_count - Offset;
-
- DPRINT1( "Reading %d bytes at %d\n", Offset, Length );
-
- if( Length == 0 ) return STATUS_UNSUCCESSFUL;
-
- while( sofar < Length )
- {
- int remains = 0;
-
- Status = CdfsReadSectors(DeviceExt->StorageDevice,
- ffe->extent_start + (sofar >> 11),
- 1,
- bytebuf);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool( bytebuf );
- return(Status);
- }
-
- remains = Length - sofar;
- if (remains > BLOCKSIZE)
- remains = BLOCKSIZE;
-
- memcpy( ((char *)Buffer) + sofar, bytebuf, remains );
- sofar += remains;
- }
-
- ExFreePool( bytebuf );
-
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL
-FsdClose(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = Stack->FileObject;
- PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- NTSTATUS Status;
-
- DPRINT1( "Closing\n" );
-
- Status = FsdCloseFile(DeviceExtension,FileObject);
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(Status);
-}
-
-NTSTATUS STDCALL
-FsdCreate(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = Stack->FileObject;
- NTSTATUS Status;
- PDEVICE_EXTENSION DeviceExt;
-
- DeviceExt = DeviceObject->DeviceExtension;
- Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
-
- Irp->IoStatus.Status = Status;
- if (Status == STATUS_SUCCESS)
- Irp->IoStatus.Information = FILE_OPENED;
- else
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(Status);
-}
-
-
-NTSTATUS STDCALL
-FsdWrite(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- return(STATUS_UNSUCCESSFUL);
-}
-
-NTSTATUS STDCALL
-FsdRead(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- ULONG Length;
- PVOID Buffer;
- ULONG Offset;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = Stack->FileObject;
- PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
- NTSTATUS Status;
-
- DPRINT1("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
-
- Length = Stack->Parameters.Read.Length;
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
-
- Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Length;
- IoCompleteRequest(Irp,IO_NO_INCREMENT);
- return(Status);
-}
-
-// XXX The VPB in devicetomount may be null for some reason...
-NTSTATUS
-FsdMountVolume(PIRP Irp)
-{
- PDEVICE_OBJECT DeviceObject = NULL;
- PDEVICE_OBJECT DeviceToMount;
- PDEVICE_EXTENSION DeviceExt = NULL;
- PIO_STACK_LOCATION Stack;
- NTSTATUS Status;
-
- DPRINT1("FsdMountVolume() called\n");
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
-
- if (FsdHasFileSystem(DeviceToMount) == FALSE)
- return(STATUS_UNRECOGNIZED_VOLUME);
-
- Status = IoCreateDevice(DriverObject,
- sizeof(DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_CD_ROM_FILE_SYSTEM,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
- DeviceExt = (PVOID)DeviceObject->DeviceExtension;
- RtlZeroMemory(DeviceExt,sizeof(DEVICE_EXTENSION));
-
- DeviceExt->fss = FsdFcbInit();
- if (!DeviceExt->fss)
- return(STATUS_UNSUCCESSFUL);
-
- DeviceExt->RootFcb = FsdCreateFcb(DeviceExt->fss, NULL, L"\\");
- Status = FsdGetRootDirectoryData(DeviceToMount, DeviceExt->RootFcb);
-
- DeviceObject->Vpb = DeviceToMount->Vpb;
- if (DeviceObject->Vpb != NULL)
- DeviceObject->Vpb->Flags |= VPB_MOUNTED;
-
-#if 0
- Status = FsdMountDevice(DeviceExt,
- DeviceToMount);
- if (!NT_SUCCESS(Status))
- return(Status);
-#endif
-
- DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
- DeviceToMount);
-
- DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
- DeviceExt->StorageDevice);
-
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL
-FsdFileSystemControl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- NTSTATUS Status;
-
- DPRINT1("CDFS FsdFileSystemControl() called\n");
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
- case IRP_MN_USER_FS_REQUEST:
- DPRINT("CDFS: IRP_MN_USER_FS_REQUEST\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
- Status = FsdMountVolume(Irp);
- break;
+PCDFS_GLOBAL_DATA CdfsGlobalData;
- case IRP_MN_VERIFY_VOLUME:
- DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-
- default:
- DPRINT("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return(Status);
-}
-
-
-NTSTATUS STDCALL
-FsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- NTSTATUS Status;
-
- DPRINT1("FsdDirectoryControl() called\n");
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
-#if 0
- case IRP_MN_USER_FS_REQUEST:
- DPRINT("CDFS: IRP_MN_USER_FS_REQUEST\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
- Status = FsdMountVolume(Irp);
- break;
-
- case IRP_MN_VERIFY_VOLUME:
- DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-#endif
-
- default:
- DPRINT("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return(Status);
-}
-
-
-static NTSTATUS
-FsdQueryNameInformation(PFILE_OBJECT FileObject,
- PFCB Fcb,
- PDEVICE_OBJECT DeviceObject,
- PFILE_NAME_INFORMATION NameInfo,
- PULONG BufferLength)
-/*
- * FUNCTION: Retrieve the file name information
- */
-{
- ULONG NameLength;
-
- assert (NameInfo != NULL);
- assert (Fcb != NULL);
-
-#if 0
- NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
- if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
- return STATUS_BUFFER_OVERFLOW;
-
- NameInfo->FileNameLength = NameLength;
- memcpy(NameInfo->FileName,
- FCB->PathName,
- NameLength + sizeof(WCHAR));
-#endif
-
- /* Fake name */
- NameLength = 2;
- wcscpy(NameInfo->FileName, L"\\");
-
- *BufferLength -=
- (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS STDCALL
-FsdQueryInformation(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-/*
- * FUNCTION: Retrieve the specified file information
- */
-{
- FILE_INFORMATION_CLASS FileInformationClass;
- PIO_STACK_LOCATION Stack;
- PFILE_OBJECT FileObject;
- PFCB Fcb;
- PVOID SystemBuffer;
- ULONG BufferLength;
-
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT1("FsdQueryInformation() called\n");
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
- FileObject = Stack->FileObject;
- Fcb = FileObject->FsContext;
-
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
- BufferLength = Stack->Parameters.QueryFile.Length;
-
- switch (FileInformationClass)
- {
-#if 0
- case FileStandardInformation:
- Status = VfatGetStandardInformation(Fcb,
- IrpContext->DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
- case FilePositionInformation:
- RC = VfatGetPositionInformation(IrpContext->FileObject,
- FCB,
- IrpContext->DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
- case FileBasicInformation:
- RC = VfatGetBasicInformation(FileObject,
- FCB,
- DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
-#endif
-
- case FileNameInformation:
- Status = FsdQueryNameInformation(FileObject,
- Fcb,
- DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
-
-#if 0
- case FileInternalInformation:
- Status = FsdGetInternalInformation(Fcb,
- SystemBuffer,
- &BufferLength);
- break;
-
- case FileAlternateNameInformation:
- case FileAllInformation:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-#endif
- default:
- DPRINT("Unimplemented information class %u\n", FileInformationClass);
- Status = STATUS_NOT_SUPPORTED;
- }
-
- Irp->IoStatus.Status = Status;
- if (NT_SUCCESS(Status))
- Irp->IoStatus.Information =
- Stack->Parameters.QueryFile.Length - BufferLength;
- else
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return(Status);
-}
+/* FUNCTIONS ****************************************************************/
NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,
+DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
DbgPrint("CDFS 0.0.1\n");
- DriverObject = _DriverObject;
-
RtlInitUnicodeString(&DeviceName,
L"\\Device\\cdfs");
Status = IoCreateDevice(DriverObject,
- 0,
+ sizeof(CDFS_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_CD_ROM_FILE_SYSTEM,
0,
return(Status);
}
+ /* Initialize global data */
+ CdfsGlobalData = DeviceObject->DeviceExtension;
+ RtlZeroMemory(CdfsGlobalData,
+ sizeof(CDFS_GLOBAL_DATA));
+ CdfsGlobalData->DriverObject = DriverObject;
+ CdfsGlobalData->DeviceObject = DeviceObject;
+
+ /* Initialize driver data */
DeviceObject->Flags = DO_DIRECT_IO;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
- DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
- DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = CdfsClose;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = CdfsCreate;
+ DriverObject->MajorFunction[IRP_MJ_READ] = CdfsRead;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = CdfsWrite;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
- FsdFileSystemControl;
+ CdfsFileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
- FsdDirectoryControl;
+ CdfsDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
- FsdQueryInformation;
+ CdfsQueryInformation;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
+ CdfsQueryVolumeInformation;
+ DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
+ CdfsSetVolumeInformation;
+
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);
#define BLOCKSIZE CDFS_BASIC_SECTOR
#define CDFS_MAX_NAME_LEN 256
+
+/* Volume descriptor types (VdType) */
+#define BOOT_VOLUME_DESCRIPTOR_TYPE 0
+#define PRIMARY_VOLUME_DESCRIPTOR_TYPE 1
+#define SUPPLEMENTARY_VOLUME_DESCRIPTOR_TYPE 2
+#define VOLUME_PARTITION_DESCRIPTOR_TYPE 3
+#define VOLUME_DESCRIPTOR_SET_TERMINATOR 255
+
struct _DIR_RECORD
{
UCHAR RecordLength; // 1
UCHAR FileId[1]; // 34
} __attribute__((packed));
-typedef struct _DIR_RECORD DIR_RECORD, PDIR_RECORD;
+typedef struct _DIR_RECORD DIR_RECORD, *PDIR_RECORD;
+
+
+
+
+/* Volume Descriptor header*/
+struct _VD_HEADER
+{
+ UCHAR VdType; // 1
+ UCHAR StandardId[5]; // 2-6
+ UCHAR VdVersion; // 7
+} __attribute__((packed));
+
+typedef struct _VD_HEADER VD_HEADER, *PVD_HEADER;
+
/* Primary Volume Descriptor */
struct _PVD
{
- unsigned char VdType; // 1
- unsigned char StandardId[5]; // 2-6
- unsigned char VdVersion; // 7
- unsigned char unused0; // 8
- unsigned char SystemId[32]; // 9-40
- unsigned char VolumeId[32]; // 41-72
- unsigned char unused1[8]; // 73-80
- unsigned long VolumeSpaceSizeL; // 81-84
- unsigned long VolumeSpaceSizeM; // 85-88
- unsigned char unused2[32]; // 89-120
- unsigned long VolumeSetSize; // 121-124
- unsigned long VolumeSequenceNumber; // 125-128
- unsigned long LogicalBlockSize; // 129-132
- unsigned long PathTableSizeL; // 133-136
- unsigned long PathTableSizeM; // 137-140
- ULONG LPathTablePos; // 141-144
- ULONG LOptPathTablePos; // 145-148
- ULONG MPathTablePos; // 149-152
- ULONG MOptPathTablePos; // 153-156
+ UCHAR VdType; // 1
+ UCHAR StandardId[5]; // 2-6
+ UCHAR VdVersion; // 7
+ UCHAR unused0; // 8
+ UCHAR SystemId[32]; // 9-40
+ UCHAR VolumeId[32]; // 41-72
+ UCHAR unused1[8]; // 73-80
+ ULONG VolumeSpaceSizeL; // 81-84
+ ULONG VolumeSpaceSizeM; // 85-88
+ UCHAR unused2[32]; // 89-120
+ ULONG VolumeSetSize; // 121-124
+ ULONG VolumeSequenceNumber; // 125-128
+ ULONG LogicalBlockSize; // 129-132
+ ULONG PathTableSizeL; // 133-136
+ ULONG PathTableSizeM; // 137-140
+ ULONG LPathTablePos; // 141-144
+ ULONG LOptPathTablePos; // 145-148
+ ULONG MPathTablePos; // 149-152
+ ULONG MOptPathTablePos; // 153-156
DIR_RECORD RootDirRecord; // 157-190
+ UCHAR VolumeSetIdentifier[128]; // 191-318
+ UCHAR PublisherIdentifier[128]; // 319-446
/* more data ... */
typedef struct _PVD PVD, *PPVD;
+/* Supplementary Volume Descriptor */
+struct _SVD
+{
+ UCHAR VdType; // 1
+ UCHAR StandardId[5]; // 2-6
+ UCHAR VdVersion; // 7
+ UCHAR VolumeFlags; // 8
+ UCHAR SystemId[32]; // 9-40
+ UCHAR VolumeId[32]; // 41-72
+ UCHAR unused1[8]; // 73-80
+ ULONG VolumeSpaceSizeL; // 81-84
+ ULONG VolumeSpaceSizeM; // 85-88
+ UCHAR EscapeSequences[32]; // 89-120
+ ULONG VolumeSetSize; // 121-124
+ ULONG VolumeSequenceNumber; // 125-128
+ ULONG LogicalBlockSize; // 129-132
+ ULONG PathTableSizeL; // 133-136
+ ULONG PathTableSizeM; // 137-140
+ ULONG LPathTablePos; // 141-144
+ ULONG LOptPathTablePos; // 145-148
+ ULONG MPathTablePos; // 149-152
+ ULONG MOptPathTablePos; // 153-156
+ DIR_RECORD RootDirRecord; // 157-190
+ UCHAR VolumeSetIdentifier[128]; // 191-318
+ UCHAR PublisherIdentifier[128]; // 319-446
+
+ // more data ...
+} __attribute__((packed));
+
+typedef struct _SVD SVD, *PSVD;
+
+
+
+
+
+
+
+typedef struct _CDINFO
+{
+ ULONG VolumeSpaceSize;
+ ULONG JolietLevel;
+ ULONG RootStart;
+ ULONG RootSize;
+
+} CDINFO, *PCDINFO;
+
+
+typedef struct
+{
+ ERESOURCE DirResource;
+// ERESOURCE FatResource;
+
+ KSPIN_LOCK FcbListLock;
+ LIST_ENTRY FcbListHead;
+
+ PDEVICE_OBJECT StorageDevice;
+ PFILE_OBJECT StreamFileObject;
+
+ CDINFO CdInfo;
+
+
+} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+
+
+#define FCB_CACHE_INITIALIZED 0x0001
typedef struct _FCB
{
REACTOS_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
- /* CDFS owned elements */
+ PFILE_OBJECT FileObject;
+ PDEVICE_EXTENSION DevExt;
+
+ WCHAR *ObjectName; /* point on filename (250 chars max) in PathName */
+ WCHAR PathName[MAX_PATH]; /* path+filename 260 max */
+
+// ERESOURCE PagingIoResource;
+ ERESOURCE MainResource;
- struct _FCB *next;
- struct _FCB *parent;
+ LIST_ENTRY FcbListEntry;
+ struct _FCB* ParentFcb;
- wchar_t name[CDFS_MAX_NAME_LEN];
- int hashval;
- unsigned int extent_start;
- unsigned int byte_count;
- unsigned int file_pointer;
-} FsdFcbEntry, FCB, *PFCB;
+ ULONG DirIndex;
+
+ LONG RefCount;
+ ULONG Flags;
+
+ DIR_RECORD Entry;
+
+
+} FCB, *PFCB;
+
+
+typedef struct _CCB
+{
+ PFCB Fcb;
+ LIST_ENTRY NextCCB;
+ PFILE_OBJECT PtrFileObject;
+ LARGE_INTEGER CurrentByteOffset;
+ /* for DirectoryControl */
+ ULONG Entry;
+ /* for DirectoryControl */
+ PWCHAR DirectorySearchPattern;
+ ULONG LastCluster;
+ ULONG LastOffset;
+} CCB, *PCCB;
+
+#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
+
+#define TAG_CCB TAG('I', 'C', 'C', 'B')
+
+
+
+typedef struct
+{
+ PDRIVER_OBJECT DriverObject;
+ PDEVICE_OBJECT DeviceObject;
+ ULONG Flags;
+} CDFS_GLOBAL_DATA, *PCDFS_GLOBAL_DATA;
+
+extern PCDFS_GLOBAL_DATA CdfsGlobalData;
NTSTATUS
void CdfsWstrcpy( wchar_t *str1, wchar_t *str2, int max );
-/*
- CDFS: FCB system (Perhaps there should be a library to make this easier)
-*/
-typedef struct _fcb_system
-{
- int fcbs_in_use;
- int fcb_table_size;
- int fcb_table_mask;
- FsdFcbEntry **fcb_table;
- FsdFcbEntry *parent;
-} fcb_system;
+/* close.c */
+
+NTSTATUS STDCALL
+CdfsClose(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+
+/* create.c */
+
+NTSTATUS STDCALL
+CdfsCreate(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+
+/* dirctl.c */
+
+NTSTATUS STDCALL
+CdfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+
+/* fcb.c */
+PFCB
+CdfsCreateFCB(PWCHAR FileName);
+
+VOID
+CdfsDestroyFCB(PFCB Fcb);
+
+BOOLEAN
+CdfsFCBIsDirectory(PFCB Fcb);
+
+BOOLEAN
+CdfsFCBIsRoot(PFCB Fcb);
+
+VOID
+CdfsGrabFCB(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb);
+
+VOID
+CdfsReleaseFCB(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb);
+
+VOID
+CdfsAddFCBToTable(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb);
+
+PFCB
+CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
+ PWSTR FileName);
+
+NTSTATUS
+CdfsFCBInitializeCache(PVCB Vcb,
+ PFCB Fcb);
PFCB
-FsdGetFcbEntry(fcb_system *fss,
- PFCB ParentFcb,
- PWSTR name);
+CdfsMakeRootFCB(PDEVICE_EXTENSION Vcb);
+
+PFCB
+CdfsOpenRootFCB(PDEVICE_EXTENSION Vcb);
+
+
+
+NTSTATUS
+CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb,
+ PFILE_OBJECT FileObject);
+
+
+
+
+NTSTATUS
+CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
+ PFCB *pParentFCB,
+ PFCB *pFCB,
+ const PWSTR pFileName);
+
+
+/* finfo.c */
+
+NTSTATUS STDCALL
+CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+/* fsctl.c */
+
+NTSTATUS STDCALL
+CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+
+/* rw.c */
+
+NTSTATUS STDCALL
+CdfsRead(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+NTSTATUS STDCALL
+CdfsWrite(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+
+/* volinfo.c */
+
+NTSTATUS STDCALL
+CdfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+NTSTATUS STDCALL
+CdfsSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
-#endif//CDFS_H
+#endif //CDFS_H
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: close.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/close.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+CdfsCloseFile(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject)
+/*
+ * FUNCTION: Closes a file
+ */
+{
+ PCCB Ccb;
+
+ DPRINT("CdfsCloseFile(DeviceExt %x, FileObject %x)\n",
+ DeviceExt,
+ FileObject);
+
+ Ccb = (PCCB)(FileObject->FsContext2);
+
+ DPRINT("Ccb %x\n", Ccb);
+ if (Ccb == NULL)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ FileObject->FsContext2 = NULL;
+
+ if (FileObject->FileName.Buffer)
+ {
+ // This a FO, that was created outside from FSD.
+ // Some FO's are created with IoCreateStreamFileObject() insid from FSD.
+ // This FO's don't have a FileName.
+ CdfsReleaseFCB(DeviceExt,
+ Ccb->Fcb);
+ }
+
+ ExFreePool(Ccb);
+
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS STDCALL
+CdfsClose(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PDEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION Stack;
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status;
+
+ DPRINT1("CdfsClose() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ FileObject = Stack->FileObject;
+ DeviceExtension = DeviceObject->DeviceExtension;
+
+ Status = CdfsCloseFile(DeviceExtension,FileObject);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+}
+
+/* EOF */
\ No newline at end of file
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.2 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/vfat/volume.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ */
+
+/* INCLUDES *****************************************************************/
+
#include <ddk/ntddk.h>
#define NDEBUG
#include "cdfs.h"
+/* FUNCTIONS ****************************************************************/
+
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
return(STATUS_SUCCESS);
}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.1 2002/04/15 20:39:49 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:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+#if 0
+NTSTATUS
+vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject,
+ PWSTR pRelativeFileName,
+ PWSTR *pAbsoluteFilename)
+{
+ PWSTR rcName;
+ PVFATFCB fcb;
+ PVFATCCB ccb;
+
+ DPRINT ("try related for %S\n", pRelativeFileName);
+ ccb = pFileObject->FsContext2;
+ assert (ccb);
+ fcb = ccb->pFcb;
+ assert (fcb);
+
+ /* verify related object is a directory and target name
+ don't start with \. */
+ if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ || (pRelativeFileName[0] == L'\\'))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* construct absolute path name */
+ assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
+ <= MAX_PATH);
+ rcName = ExAllocatePool (NonPagedPool, MAX_PATH * sizeof(WCHAR));
+ if (!rcName)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ wcscpy (rcName, fcb->PathName);
+ if (!vfatFCBIsRoot(fcb))
+ wcscat (rcName, L"\\");
+ wcscat (rcName, pRelativeFileName);
+ *pAbsoluteFilename = rcName;
+
+ return STATUS_SUCCESS;
+}
+#endif
+
+
+static NTSTATUS
+CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PWSTR FileName)
+/*
+ * FUNCTION: Opens a file
+ */
+{
+ PFCB ParentFcb;
+ PFCB Fcb;
+ NTSTATUS Status;
+ PWSTR AbsFileName = NULL;
+
+ DPRINT("CdfsOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
+
+ if (FileObject->RelatedFileObject)
+ {
+ DPRINT("Converting relative filename to absolute filename\n");
+#if 0
+ Status = vfatMakeAbsoluteFilename(FileObject->RelatedFileObject,
+ FileName,
+ &AbsFileName);
+ FileName = AbsFileName;
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+#endif
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ //FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
+
+ DPRINT("PathName to open: %S\n", FileName);
+
+ /* try first to find an existing FCB in memory */
+ DPRINT("Checking for existing FCB in memory\n");
+ Fcb = CdfsGrabFCBFromTable(DeviceExt,
+ FileName);
+ if (Fcb == NULL)
+ {
+ DPRINT ("No existing FCB found, making a new one if file exists.\n");
+ Status = CdfsGetFCBForFile(DeviceExt,
+ &ParentFcb,
+ &Fcb,
+ FileName);
+ if (ParentFcb != NULL)
+ {
+ CdfsReleaseFCB(DeviceExt,
+ ParentFcb);
+ }
+
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT("Could not make a new FCB, status: %x\n", Status);
+
+ if (AbsFileName)
+ ExFreePool(AbsFileName);
+
+ return(Status);
+ }
+ }
+
+ DPRINT("Attaching FCB to fileObject\n");
+ Status = CdfsAttachFCBToFileObject(DeviceExt,
+ Fcb,
+ FileObject);
+
+ if (AbsFileName)
+ ExFreePool (AbsFileName);
+
+ return Status;
+}
+
+
+
+
+static NTSTATUS
+CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+/*
+ * FUNCTION: Opens a file
+ */
+{
+ PDEVICE_EXTENSION DeviceExt;
+ PIO_STACK_LOCATION Stack;
+ PFILE_OBJECT FileObject;
+ ULONG RequestedDisposition;
+ ULONG RequestedOptions;
+ PFCB Fcb;
+// PWSTR FileName;
+ NTSTATUS Status;
+
+ DPRINT1("CdfsCreateFile() called\n");
+
+ DeviceExt = DeviceObject->DeviceExtension;
+ assert (DeviceExt);
+ Stack = IoGetCurrentIrpStackLocation (Irp);
+ assert (Stack);
+
+ RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
+// RequestedOptions =
+// Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
+// PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
+// if ((RequestedOptions & FILE_DIRECTORY_FILE)
+// && RequestedDisposition == FILE_SUPERSEDE)
+// return STATUS_INVALID_PARAMETER;
+
+ FileObject = Stack->FileObject;
+
+ Status = CdfsOpenFile(DeviceExt,
+ FileObject,
+ FileObject->FileName.Buffer);
+
+ /*
+ * If the directory containing the file to open doesn't exist then
+ * fail immediately
+ */
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = Status;
+ return(Status);
+
+#if 0
+ /* Just skip leading backslashes... */
+ while (*FileName == L'\\')
+ FileName++;
+CHECKPOINT1;
+
+ Fcb = FsdSearchDirectory(DeviceExt->fss,
+ NULL,
+ FileName);
+CHECKPOINT1;
+ if (Fcb == NULL)
+ {
+ DPRINT1("FsdSearchDirectory() failed\n");
+ return(STATUS_OBJECT_PATH_NOT_FOUND);
+ }
+CHECKPOINT1;
+
+ FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
+ FO_DIRECT_CACHE_PAGING_READ;
+ FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = DeviceExt->fss;
+
+ DPRINT1("FsdOpenFile() done\n");
+
+ return(STATUS_SUCCESS);
+#endif
+}
+
+
+NTSTATUS STDCALL
+CdfsCreate(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PDEVICE_EXTENSION DeviceExt;
+ NTSTATUS Status;
+
+ if (DeviceObject->Size == sizeof(DEVICE_OBJECT))
+ {
+ /* DeviceObject represents FileSystem instead of logical volume */
+ DPRINT("FsdCreate called with file system\n");
+ Irp->IoStatus.Information = FILE_OPENED;
+ Status = STATUS_SUCCESS;
+ goto ByeBye;
+ }
+
+ DeviceExt = DeviceObject->DeviceExtension;
+
+ ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
+ TRUE);
+ Status = CdfsCreateFile(DeviceObject,
+ Irp);
+ ExReleaseResourceLite(&DeviceExt->DirResource);
+
+
+ByeBye:
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp,
+ NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+/* EOF */
\ No newline at end of file
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: dirctl.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/dirctl.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* HACK -- NEEDS FIXING */
+#if 0
+int
+FsdExtractDirectoryEntry(PDEVICE_EXTENSION DeviceExt,
+ FsdFcbEntry *parent,
+ FsdFcbEntry *fill_in,
+ int entry_to_get)
+{
+ switch( entry_to_get )
+ {
+ case 0:
+ wcscpy( fill_in->name, L"." );
+ fill_in->extent_start = parent->extent_start;
+ fill_in->byte_count = parent->byte_count;
+ break;
+
+ case 1:
+ wcscpy( fill_in->name, L".." );
+ fill_in->extent_start = parent->extent_start;
+ fill_in->byte_count = parent->byte_count;
+ break;
+
+ case 2:
+ wcscpy( fill_in->name, L"readme.txt" );
+ fill_in->extent_start = 0x190;
+ fill_in->byte_count = 0x800;
+ break;
+
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+NTSTATUS STDCALL
+CdfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+
+ DPRINT("CdfsDirectoryControl() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (Stack->MinorFunction)
+ {
+
+ default:
+ DPRINT("CDFS: MinorFunction %d\n", Stack->MinorFunction);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+/* EOF */
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: fcb.c,v 1.2 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/fcb.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
#include "cdfs.h"
-/*
- CDFS: FCB system (Perhaps there should be a library to make this easier)
-*/
-#if 0
-typedef struct _fcb_system {
- int fcbs_in_use;
- int fcb_table_size;
- int fcb_table_mask;
- FsdFcbEntry **fcb_table;
- FsdFcbEntry *parent;
-} fcb_system;
-#endif
-// Create a hash over this name for table
-static int FsdNameHash( FsdFcbEntry *parent, wchar_t *name ) {
- int i;
- int hashval = 0;
+/* MACROS *******************************************************************/
+
+#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
+#define TAG_FCB TAG('I', 'F', 'C', 'B')
+
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
- for( i = 0; name[i]; i++ )
- hashval ^= name[i] << (i & 0xf);
- hashval ^= (int)parent;
+/* FUNCTIONS ****************************************************************/
- return hashval;
+PFCB
+CdfsCreateFCB(PWSTR FileName)
+{
+ PFCB Fcb;
+
+ Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
+ RtlZeroMemory(Fcb, sizeof(FCB));
+
+ if (FileName)
+ {
+ wcscpy(Fcb->PathName, FileName);
+ if (wcsrchr(Fcb->PathName, '\\') != 0)
+ {
+ Fcb->ObjectName = wcsrchr(Fcb->PathName, '\\');
+ }
+ else
+ {
+ Fcb->ObjectName = Fcb->PathName;
+ }
+ }
+
+ ExInitializeResourceLite(&Fcb->MainResource);
+
+ return(Fcb);
}
-// Init the fcb system
-fcb_system *FsdFcbInit() {
- fcb_system *fss = ExAllocatePool( NonPagedPool,
- sizeof( fcb_system ) );
- if( !fss ) return NULL;
+VOID
+CdfsDestroyFCB(PFCB Fcb)
+{
+ ExDeleteResourceLite(&Fcb->MainResource);
- RtlZeroMemory( fss, sizeof( *fss ) );
+ ExFreePool(Fcb);
+}
- fss->fcb_table_size = 128;
- fss->fcb_table_mask = fss->fcb_table_size - 1;
- fss->fcb_table = ExAllocatePool( NonPagedPool,
- sizeof( FsdFcbEntry ** ) *
- fss->fcb_table_size );
- if( !fss->fcb_table ) {
- ExFreePool( fss );
- return NULL;
- }
+BOOLEAN
+CdfsFCBIsDirectory(PFCB Fcb)
+{
+// return(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY);
+ return(Fcb->Entry.FileFlags & 0x02);
+}
- RtlZeroMemory( fss->fcb_table, sizeof( FsdFcbEntry ** ) *
- fss->fcb_table_size );
- return fss;
+BOOLEAN
+CdfsFCBIsRoot(PFCB Fcb)
+{
+ return(wcscmp(Fcb->PathName, L"\\") == 0);
}
-// Delete the fcb system
-void FsdFcbDeinit( fcb_system *fss ) {
- if( fss->fcb_table ) ExFreePool( fss->fcb_table );
+
+VOID
+CdfsGrabFCB(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb)
+{
+ KIRQL oldIrql;
+
+ DPRINT("grabbing FCB at %x: %S, refCount:%d\n",
+ Fcb,
+ Fcb->PathName,
+ Fcb->RefCount);
+
+ KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
+ Fcb->RefCount++;
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
-// Get one entry from the FCB system by name...
-FsdFcbEntry *FsdGetFcbEntry( fcb_system *fss, FsdFcbEntry *parent,
- wchar_t *name ) {
- int hashval;
- FsdFcbEntry *table_ent = NULL;
- hashval = FsdNameHash( parent, name ) & fss->fcb_table_mask;
- table_ent = fss->fcb_table[hashval];
+VOID
+CdfsReleaseFCB(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb)
+{
+ KIRQL oldIrql;
- while( table_ent && _wcsicmp( table_ent->name, name ) &&
- table_ent->parent != parent )
- table_ent = table_ent->next;
+ DPRINT("releasing FCB at %x: %S, refCount:%d\n",
+ Fcb,
+ Fcb->PathName,
+ Fcb->RefCount);
- return table_ent;
+ KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
+ Fcb->RefCount--;
+ if (Fcb->RefCount <= 0 && !CdfsFCBIsDirectory(Fcb))
+ {
+ RemoveEntryList(&Fcb->FcbListEntry);
+ CcRosReleaseFileCache(NULL, Fcb->RFCB.Bcb);
+ CdfsDestroyFCB(Fcb);
+ }
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
-// Create an fcb with the given name...
-FsdFcbEntry *FsdCreateFcb( fcb_system *fss, FsdFcbEntry *parent,
- wchar_t *filename ) {
- int hashval;
- int tableval;
- FsdFcbEntry *table_ent = FsdGetFcbEntry( fss, parent, filename );
- if( table_ent ) return table_ent;
+VOID
+CdfsAddFCBToTable(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb)
+{
+ KIRQL oldIrql;
+
+ KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
+ Fcb->DevExt = Vcb;
+ InsertTailList(&Vcb->FcbListHead, &Fcb->FcbListEntry);
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
+}
+
+
+PFCB
+CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
+ PWSTR FileName)
+{
+ KIRQL oldIrql;
+ PFCB Fcb;
+ PLIST_ENTRY current_entry;
+
+ KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
+
+ if (FileName == NULL || *FileName == 0)
+ {
+ DPRINT1("Return FCB for strem file object\n");
+ Fcb = ((PCCB)Vcb->StreamFileObject->FsContext2)->Fcb;
+ Fcb->RefCount++;
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
+ return(Fcb);
+ }
+
+ current_entry = Vcb->FcbListHead.Flink;
+ while (current_entry != &Vcb->FcbListHead)
+ {
+ Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry);
+
+// if (wstrcmpi(FileName, Fcb->PathName))
+ if (_wcsicmp(FileName, Fcb->PathName))
+ {
+ Fcb->RefCount++;
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
+ return(Fcb);
+ }
+
+ //FIXME: need to compare against short name in FCB here
+
+ current_entry = current_entry->Flink;
+ }
+ KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
+
+ return(NULL);
+}
+
+
+NTSTATUS
+CdfsFCBInitializeCache(PVCB Vcb,
+ PFCB Fcb)
+{
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status;
+ PCCB newCCB;
+
+ FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice);
+
+ newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
+ if (newCCB == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ RtlZeroMemory(newCCB,
+ sizeof(CCB));
+
+ FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
+ FO_DIRECT_CACHE_PAGING_READ;
+ FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
+ FileObject->FsContext = (PVOID) &Fcb->RFCB;
+ FileObject->FsContext2 = newCCB;
+ newCCB->Fcb = Fcb;
+ newCCB->PtrFileObject = FileObject;
+ Fcb->FileObject = FileObject;
+ Fcb->DevExt = Vcb;
+
+ Status = CcRosInitializeFileCache(FileObject,
+ &Fcb->RFCB.Bcb,
+ PAGESIZE);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("CcRosInitializeFileCache failed\n");
+ KeBugCheck(0);
+ }
+
+ ObDereferenceObject(FileObject);
+ Fcb->Flags |= FCB_CACHE_INITIALIZED;
+
+ return(Status);
+}
+
+
+PFCB
+CdfsMakeRootFCB(PDEVICE_EXTENSION Vcb)
+{
+ PFCB Fcb;
+
+ Fcb = CdfsCreateFCB(L"\\");
+
+// memset(Fcb->entry.Filename, ' ', 11);
+
+ Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
+ Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
+ Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
+ Fcb->RefCount = 1;
+ Fcb->DirIndex = 0;
+ Fcb->RFCB.FileSize.QuadPart = Vcb->CdInfo.RootSize;
+ Fcb->RFCB.ValidDataLength.QuadPart = Vcb->CdInfo.RootSize;
+ Fcb->RFCB.AllocationSize.QuadPart = Vcb->CdInfo.RootSize;
+
+ CdfsFCBInitializeCache(Vcb, Fcb);
+ CdfsAddFCBToTable(Vcb, Fcb);
+ CdfsGrabFCB(Vcb, Fcb);
+
+ return(Fcb);
+}
+
+
+PFCB
+CdfsOpenRootFCB(PDEVICE_EXTENSION Vcb)
+{
+ PFCB Fcb;
+
+ Fcb = CdfsGrabFCBFromTable(Vcb, L"\\");
+ if (Fcb == NULL)
+ {
+ Fcb = CdfsMakeRootFCB(Vcb);
+ }
+
+ return(Fcb);
+}
+
- hashval = FsdNameHash( parent, filename );
- tableval = hashval & fss->fcb_table_mask;
+#if 0
+NTSTATUS
+vfatMakeFCBFromDirEntry(PVCB vcb,
+ PVFATFCB directoryFCB,
+ PWSTR longName,
+ PFAT_DIR_ENTRY dirEntry,
+ ULONG dirIndex,
+ PVFATFCB * fileFCB)
+{
+ PVFATFCB rcFCB;
+ WCHAR pathName [MAX_PATH];
+ ULONG Size;
+ if (longName [0] != 0 && wcslen (directoryFCB->PathName) +
+ sizeof(WCHAR) + wcslen (longName) > MAX_PATH)
+ {
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ wcscpy (pathName, directoryFCB->PathName);
+ if (!vfatFCBIsRoot (directoryFCB))
+ {
+ wcscat (pathName, L"\\");
+ }
+ if (longName [0] != 0)
+ {
+ wcscat (pathName, longName);
+ }
+ else
+ {
+ WCHAR entryName [MAX_PATH];
- table_ent = ExAllocatePool( NonPagedPool, sizeof( FsdFcbEntry ) );
+ vfatGetDirEntryName (dirEntry, entryName);
+ wcscat (pathName, entryName);
+ }
+ rcFCB = vfatNewFCB (pathName);
+ memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
- if( table_ent ) {
- table_ent->next = fss->fcb_table[tableval];
- table_ent->hashval = hashval;
- table_ent->parent = parent;
- wcscpy( table_ent->name, filename );
- fss->fcb_table[tableval] = table_ent;
+ if (vfatFCBIsDirectory(vcb, rcFCB))
+ {
+ ULONG FirstCluster, CurrentCluster;
+ NTSTATUS Status;
+ Size = 0;
+ FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
+ if (FirstCluster == 1)
+ {
+ Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE;
+ }
+ else
+ {
+ CurrentCluster = FirstCluster;
+ while (CurrentCluster != 0xffffffff)
+ {
+ Size += vcb->FatInfo.BytesPerCluster;
+ Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
+ }
+ }
}
+ else
+ {
+ Size = rcFCB->entry.FileSize;
+ }
+ rcFCB->dirIndex = dirIndex;
+ rcFCB->RFCB.FileSize.QuadPart = Size;
+ rcFCB->RFCB.ValidDataLength.QuadPart = Size;
+ rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
+// DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
+ vfatFCBInitializeCache (vcb, rcFCB);
+ rcFCB->RefCount++;
+ vfatAddFCBToTable (vcb, rcFCB);
+ *fileFCB = rcFCB;
+
+ return STATUS_SUCCESS;
+}
+#endif
+
+NTSTATUS
+CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
+ PFCB Fcb,
+ PFILE_OBJECT FileObject)
+{
+ NTSTATUS Status;
+ PCCB newCCB;
+
+ newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof(CCB), TAG_CCB);
+ if (newCCB == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ memset(newCCB, 0, sizeof(CCB));
- return table_ent;
+ FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
+ FO_DIRECT_CACHE_PAGING_READ;
+ FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
+ FileObject->FsContext = (PVOID)&Fcb->RFCB;
+ FileObject->FsContext2 = newCCB;
+ newCCB->Fcb = Fcb;
+ newCCB->PtrFileObject = FileObject;
+ Fcb->DevExt = Vcb;
+
+ if (!(Fcb->Flags & FCB_CACHE_INITIALIZED))
+ {
+ Status = CcRosInitializeFileCache(FileObject,
+ &Fcb->RFCB.Bcb,
+ PAGESIZE);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("CcRosInitializeFileCache failed\n");
+ KeBugCheck(0);
+ }
+ Fcb->Flags |= FCB_CACHE_INITIALIZED;
+ }
+
+ DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);
+
+ return(STATUS_SUCCESS);
}
-// Delete this fcb...
-void FsdDelete( fcb_system *fss, FsdFcbEntry *which ) {
- int tableval = which->hashval & fss->fcb_table_mask;
- FsdFcbEntry *table_ent = fss->fcb_table[tableval];
-
- if( table_ent == which ) {
- fss->fcb_table[tableval] = fss->fcb_table[tableval]->next;
- ExFreePool( which );
- return;
+#if 0
+NTSTATUS
+vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
+ PVFATFCB pDirectoryFCB,
+ PWSTR pFileToFind,
+ PVFATFCB * pFoundFCB)
+{
+ BOOL finishedScanningDirectory;
+ ULONG directoryIndex;
+ NTSTATUS status;
+ WCHAR defaultFileName [2];
+ WCHAR currentLongName [256];
+ FAT_DIR_ENTRY currentDirEntry;
+ WCHAR currentEntryName [256];
+
+ assert (pDeviceExt);
+ assert (pDirectoryFCB);
+ assert (pFileToFind);
+
+ DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
+ pDeviceExt,
+ pDirectoryFCB,
+ pFileToFind);
+ DPRINT ("Dir Path:%S\n", pDirectoryFCB->PathName);
+
+ // default to '.' if no filename specified
+ if (wcslen (pFileToFind) == 0)
+ {
+ defaultFileName [0] = L'.';
+ defaultFileName [1] = 0;
+ pFileToFind = defaultFileName;
}
- if( !table_ent ) return;
+ directoryIndex = 0;
+ finishedScanningDirectory = FALSE;
+ while (!finishedScanningDirectory)
+ {
+ status = vfatGetNextDirEntry (pDeviceExt,
+ pDirectoryFCB,
+ &directoryIndex,
+ currentLongName,
+ ¤tDirEntry);
+ if (status == STATUS_NO_MORE_ENTRIES)
+ {
+ finishedScanningDirectory = TRUE;
+ continue;
+ }
+ else if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ DPRINT (" Index:%d longName:%S\n",
+ directoryIndex,
+ currentLongName);
+
+ if (!vfatIsDirEntryDeleted (¤tDirEntry)
+ && !vfatIsDirEntryVolume(¤tDirEntry))
+ {
+ if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
+ {
+ DPRINT ("Match found, %S\n", currentLongName);
+ status = vfatMakeFCBFromDirEntry (pDeviceExt,
+ pDirectoryFCB,
+ currentLongName,
+ ¤tDirEntry,
+ directoryIndex - 1,
+ pFoundFCB);
+ return status;
+ }
+ else
+ {
+ vfatGetDirEntryName (¤tDirEntry, currentEntryName);
+ DPRINT (" entryName:%S\n", currentEntryName);
- while( table_ent->next ) {
- if( table_ent->next == which ) {
- table_ent->next = table_ent->next->next;
- ExFreePool( which );
- return;
+ if (wstrcmpjoki (currentEntryName, pFileToFind))
+ {
+ DPRINT ("Match found, %S\n", currentEntryName);
+ status = vfatMakeFCBFromDirEntry (pDeviceExt,
+ pDirectoryFCB,
+ currentLongName,
+ ¤tDirEntry,
+ directoryIndex - 1,
+ pFoundFCB);
+ return status;
+ }
+ }
}
- table_ent = table_ent->next;
}
+
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
+#endif
+
+
+NTSTATUS
+CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
+ PFCB *pParentFCB,
+ PFCB *pFCB,
+ const PWSTR pFileName)
+{
+ NTSTATUS status;
+ WCHAR pathName [MAX_PATH];
+ WCHAR elementName [MAX_PATH];
+ PWCHAR currentElement;
+ PFCB FCB;
+ PFCB parentFCB;
+
+ DPRINT("CdfsGetFCBForFile(%x, %x, %x, '%S')\n",
+ Vcb,
+ pParentFCB,
+ pFCB,
+ pFileName);
+
+ /* Trivial case, open of the root directory on volume */
+ if (pFileName [0] == L'\0' || wcscmp(pFileName, L"\\") == 0)
+ {
+ DPRINT("returning root FCB\n");
+
+ FCB = CdfsOpenRootFCB(Vcb);
+ *pFCB = FCB;
+ *pParentFCB = NULL;
+
+ return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
+ }
+
+ DPRINT1("CdfsGetFCBForFile() is incomplete!\n");
+ return(STATUS_UNSUCCESSFUL);
+
+#if 0
+ else
+ {
+ currentElement = pFileName + 1;
+ wcscpy (pathName, L"\\");
+ FCB = CdfsOpenRootFCB (Vcb);
+ }
+ parentFCB = NULL;
+
+ // Parse filename and check each path element for existance and access
+ while (vfatGetNextPathElement (currentElement) != 0)
+ {
+ // Skip blank directory levels
+ if ((vfatGetNextPathElement (currentElement) - currentElement) == 0)
+ {
+ currentElement++;
+ continue;
+ }
+
+ DPRINT ("Parsing, currentElement:%S\n", currentElement);
+ DPRINT (" parentFCB:%x FCB:%x\n", parentFCB, FCB);
+
+ // descend to next directory level
+ if (parentFCB)
+ {
+ vfatReleaseFCB (pVCB, parentFCB);
+ parentFCB = 0;
+ }
+ // fail if element in FCB is not a directory
+ if (!vfatFCBIsDirectory (pVCB, FCB))
+ {
+ DPRINT ("Element in requested path is not a directory\n");
+
+ vfatReleaseFCB (pVCB, FCB);
+ FCB = 0;
+ *pParentFCB = NULL;
+ *pFCB = NULL;
+
+ return STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ parentFCB = FCB;
+
+ // Extract next directory level into dirName
+ vfatWSubString (pathName,
+ pFileName,
+ vfatGetNextPathElement (currentElement) - pFileName);
+ DPRINT (" pathName:%S\n", pathName);
+
+ FCB = vfatGrabFCBFromTable (pVCB, pathName);
+ if (FCB == NULL)
+ {
+ vfatWSubString (elementName,
+ currentElement,
+ vfatGetNextPathElement (currentElement) - currentElement);
+ DPRINT (" elementName:%S\n", elementName);
+
+ status = vfatDirFindFile (pVCB, parentFCB, elementName, &FCB);
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ *pParentFCB = parentFCB;
+ *pFCB = NULL;
+ currentElement = vfatGetNextPathElement(currentElement);
+ if (*currentElement == L'\0' || vfatGetNextPathElement(currentElement + 1) == 0)
+ {
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ else
+ {
+ return STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ }
+ else if (!NT_SUCCESS (status))
+ {
+ vfatReleaseFCB (pVCB, parentFCB);
+ *pParentFCB = NULL;
+ *pFCB = NULL;
+
+ return status;
+ }
+ }
+ currentElement = vfatGetNextPathElement (currentElement);
+ }
+
+ *pParentFCB = parentFCB;
+ *pFCB = FCB;
+
+ return STATUS_SUCCESS;
+#endif
+}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: finfo.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/dirctl.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+CdfsQueryNameInformation(PFILE_OBJECT FileObject,
+ PFCB Fcb,
+ PDEVICE_OBJECT DeviceObject,
+ PFILE_NAME_INFORMATION NameInfo,
+ PULONG BufferLength)
+/*
+ * FUNCTION: Retrieve the file name information
+ */
+{
+ ULONG NameLength;
+
+ assert (NameInfo != NULL);
+ assert (Fcb != NULL);
+
+#if 0
+ NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
+ if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
+ return STATUS_BUFFER_OVERFLOW;
+
+ NameInfo->FileNameLength = NameLength;
+ memcpy(NameInfo->FileName,
+ FCB->PathName,
+ NameLength + sizeof(WCHAR));
+#endif
+
+ /* Fake name */
+ NameLength = 2;
+ wcscpy(NameInfo->FileName, L"\\");
+
+ *BufferLength -=
+ (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS STDCALL
+CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+/*
+ * FUNCTION: Retrieve the specified file information
+ */
+{
+ FILE_INFORMATION_CLASS FileInformationClass;
+ PIO_STACK_LOCATION Stack;
+ PFILE_OBJECT FileObject;
+ PFCB Fcb;
+ PVOID SystemBuffer;
+ ULONG BufferLength;
+
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT1("CdfsQueryInformation() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
+ FileObject = Stack->FileObject;
+ Fcb = FileObject->FsContext;
+
+ SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+ BufferLength = Stack->Parameters.QueryFile.Length;
+
+ switch (FileInformationClass)
+ {
+#if 0
+ case FileStandardInformation:
+ Status = CdfsGetStandardInformation(Fcb,
+ IrpContext->DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+ case FilePositionInformation:
+ RC = CdfsGetPositionInformation(IrpContext->FileObject,
+ FCB,
+ IrpContext->DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+ case FileBasicInformation:
+ RC = CdfsGetBasicInformation(FileObject,
+ FCB,
+ DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+#endif
+
+ case FileNameInformation:
+ Status = CdfsQueryNameInformation(FileObject,
+ Fcb,
+ DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+#if 0
+ case FileInternalInformation:
+ Status = CdfsGetInternalInformation(Fcb,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileAlternateNameInformation:
+ case FileAllInformation:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+#endif
+ default:
+ DPRINT("Unimplemented information class %u\n", FileInformationClass);
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information =
+ Stack->Parameters.QueryFile.Length - BufferLength;
+ else
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+/* EOF */
\ No newline at end of file
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/fsctl.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+static VOID
+CdfsGetPVDData(PUCHAR Buffer,
+ PDEVICE_EXTENSION Vcb,
+ PVPB Vpb)
+{
+ PPVD Pvd;
+ ULONG i;
+ PCHAR pc;
+ PWCHAR pw;
+
+ union
+ {
+ ULONG Value;
+ UCHAR Part[4];
+ } Serial;
+
+ Pvd = (PPVD)Buffer;
+
+ /* 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];
+ }
+ Vpb->SerialNumber = Serial.Value;
+
+ /* Extract the volume label */
+ pc = Pvd->VolumeId;
+ pw = Vpb->VolumeLabel;
+ for (i = 0; i < MAXIMUM_VOLUME_LABEL_LENGTH && *pc != ' '; i++)
+ {
+ *pw++ = (WCHAR)*pc++;
+ }
+ *pw = 0;
+ Vpb->VolumeLabelLength = i;
+
+ Vcb->CdInfo.VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
+ Vcb->CdInfo.RootStart = Pvd->RootDirRecord.ExtentLocationL;
+ Vcb->CdInfo.RootSize = Pvd->RootDirRecord.DataLengthL;
+
+ DPRINT1("VolumeSerial: %08lx\n", Vpb->SerialNumber);
+ DPRINT1("VolumeLabel: '%S'\n", Vpb->VolumeLabel);
+ DPRINT1("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength);
+ DPRINT1("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
+ DPRINT1("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
+ DPRINT1("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
+}
+
+
+static VOID
+CdfsGetSVDData(PUCHAR Buffer,
+ PDEVICE_EXTENSION Vcb)
+{
+ PSVD Svd;
+ ULONG JolietLevel = 0;
+
+ Svd = (PSVD)Buffer;
+
+ DPRINT1("EscapeSequences: '%.32s'\n", Svd->EscapeSequences);
+
+ if (strncmp(Svd->EscapeSequences, "%/@", 3) == 0)
+ {
+ DPRINT1("Joliet extension found (UCS-2 Level 1)\n");
+ JolietLevel = 1;
+ }
+ else if (strncmp(Svd->EscapeSequences, "%/C", 3) == 0)
+ {
+ DPRINT1("Joliet extension found (UCS-2 Level 2)\n");
+ JolietLevel = 2;
+ }
+ else if (strncmp(Svd->EscapeSequences, "%/E", 3) == 0)
+ {
+ DPRINT1("Joliet extension found (UCS-2 Level 3)\n");
+ JolietLevel = 3;
+ }
+
+ Vcb->CdInfo.JolietLevel = JolietLevel;
+
+ if (JolietLevel != 0)
+ {
+ Vcb->CdInfo.RootStart = Svd->RootDirRecord.ExtentLocationL;
+ Vcb->CdInfo.RootSize = Svd->RootDirRecord.DataLengthL;
+
+ DPRINT1("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
+ DPRINT1("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
+ }
+}
+
+
+static NTSTATUS
+CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION Vcb)
+{
+ PUCHAR Buffer;
+ NTSTATUS Status;
+ ULONG Sector;
+ PVD_HEADER VdHeader;
+
+
+ Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
+
+ Buffer = ExAllocatePool(NonPagedPool,
+ CDFS_BASIC_SECTOR);
+ if (Buffer == NULL)
+ return(STATUS_INSUFFICIENT_RESOURCES);
+
+ VdHeader = (PVD_HEADER)Buffer;
+
+ do
+ {
+ /* Read the Primary Volume Descriptor (PVD) */
+ Status = CdfsReadSectors(DeviceObject,
+ Sector,
+ 1,
+ Buffer);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ switch (VdHeader->VdType)
+ {
+ case 0:
+ DPRINT1("BootVolumeDescriptor found!\n");
+ break;
+
+ case 1:
+ DPRINT1("PrimaryVolumeDescriptor found!\n");
+ CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb);
+ break;
+
+ case 2:
+ DPRINT1("SupplementaryVolumeDescriptor found!\n");
+ CdfsGetSVDData(Buffer, Vcb);
+ break;
+
+ case 3:
+ DPRINT1("VolumePartitionDescriptor found!\n");
+ break;
+
+ case 255:
+ DPRINT1("VolumeDescriptorSetTerminator found!\n");
+ break;
+
+ default:
+ DPRINT1("VolumeDescriptor type %u found!\n", VdHeader->VdType);
+ break;
+ }
+
+ Sector++;
+ }
+ while (VdHeader->VdType != 255);
+
+ ExFreePool(Buffer);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static BOOLEAN
+CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
+/*
+ * FUNCTION: Tests if the device contains a filesystem that can be mounted
+ * by this fsd
+ */
+{
+ PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
+ NTSTATUS Status;
+ int ret;
+
+ bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
+ if( !bytebuf ) return FALSE;
+
+ DPRINT1("CDFS: Checking on mount of device %08x\n", DeviceToMount);
+
+ Status = CdfsReadSectors(DeviceToMount,
+ CDFS_PRIMARY_DESCRIPTOR_LOCATION,
+ 1,
+ bytebuf);
+ bytebuf[6] = 0;
+ DPRINT1( "CD-identifier: [%.5s]\n", bytebuf + 1 );
+
+ ret =
+ Status == STATUS_SUCCESS &&
+ bytebuf[0] == 1 &&
+ bytebuf[1] == 'C' &&
+ bytebuf[2] == 'D' &&
+ bytebuf[3] == '0' &&
+ bytebuf[4] == '0' &&
+ bytebuf[5] == '1';
+
+ ExFreePool( bytebuf );
+
+ return ret;
+}
+
+
+static NTSTATUS
+CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PDEVICE_EXTENSION DeviceExt = NULL;
+ PDEVICE_OBJECT NewDeviceObject = NULL;
+ PDEVICE_OBJECT DeviceToMount;
+ PIO_STACK_LOCATION Stack;
+ PFCB Fcb = NULL;
+ PCCB Ccb = NULL;
+ NTSTATUS Status;
+
+ DPRINT1("CdfsMountVolume() called\n");
+
+ if (DeviceObject != CdfsGlobalData->DeviceObject)
+ {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ goto ByeBye;
+ }
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
+
+ if (CdfsHasFileSystem(DeviceToMount) == FALSE)
+ {
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+ goto ByeBye;
+ }
+
+ Status = IoCreateDevice(CdfsGlobalData->DriverObject,
+ sizeof(DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_FILE_SYSTEM,
+ 0,
+ FALSE,
+ &NewDeviceObject);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
+ DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
+ RtlZeroMemory(DeviceExt,
+ sizeof(DEVICE_EXTENSION));
+
+ Status = CdfsGetVolumeData(DeviceToMount,
+ DeviceExt);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ NewDeviceObject->Vpb = DeviceToMount->Vpb;
+ NewDeviceObject->Vpb->Flags |= VPB_MOUNTED;
+ DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(NewDeviceObject,
+ DeviceToMount);
+ DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
+ DeviceExt->StorageDevice);
+
+ Fcb = CdfsCreateFCB(NULL);
+ if (Fcb == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto ByeBye;
+ }
+
+ Ccb = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(CCB),
+ TAG_CCB);
+ if (Ccb == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto ByeBye;
+ }
+ RtlZeroMemory(Ccb,
+ sizeof(CCB));
+
+ DeviceExt->StreamFileObject->Flags = DeviceExt->StreamFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
+ DeviceExt->StreamFileObject->FsContext = (PVOID)&Fcb->RFCB;
+ DeviceExt->StreamFileObject->FsContext2 = Ccb;
+ DeviceExt->StreamFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
+ DeviceExt->StreamFileObject->PrivateCacheMap = NULL;
+ DeviceExt->StreamFileObject->Vpb = NewDeviceObject->Vpb;
+ Ccb->Fcb = Fcb;
+ Ccb->PtrFileObject = DeviceExt->StreamFileObject;
+ Fcb->FileObject = DeviceExt->StreamFileObject;
+ Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
+
+ Fcb->RFCB.FileSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
+ Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE, PAGESIZE);
+
+ Fcb->Entry.ExtentLocationL = 0;
+ Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
+
+ Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject, &Fcb->RFCB.Bcb, PAGESIZE);
+ if (!NT_SUCCESS (Status))
+ {
+ DbgPrint("CcRosInitializeFileCache failed\n");
+ goto ByeBye;
+ }
+
+ ExInitializeResourceLite(&DeviceExt->DirResource);
+// ExInitializeResourceLite(&DeviceExt->FatResource);
+
+ KeInitializeSpinLock(&DeviceExt->FcbListLock);
+ InitializeListHead(&DeviceExt->FcbListHead);
+
+ Status = STATUS_SUCCESS;
+
+ByeBye:
+ if (!NT_SUCCESS(Status))
+ {
+ /* Cleanup */
+ if (DeviceExt && DeviceExt->StreamFileObject)
+ ObDereferenceObject(DeviceExt->StreamFileObject);
+ if (Fcb)
+ ExFreePool(Fcb);
+ if (Ccb)
+ ExFreePool(Ccb);
+ if (NewDeviceObject)
+ IoDeleteDevice(NewDeviceObject);
+ }
+
+ return(Status);
+}
+
+
+NTSTATUS STDCALL
+CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+
+ DPRINT1("CdfsFileSystemControl() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (Stack->MinorFunction)
+ {
+ case IRP_MN_USER_FS_REQUEST:
+ DPRINT("CDFS: IRP_MN_USER_FS_REQUEST\n");
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ case IRP_MN_MOUNT_VOLUME:
+ DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
+ Status = CdfsMountVolume(DeviceObject, Irp);
+ break;
+
+ case IRP_MN_VERIFY_VOLUME:
+ DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ default:
+ DPRINT("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+/* EOF */
-# $Id: makefile,v 1.1 2002/04/12 15:41:39 ekohl Exp $
+# $Id: makefile,v 1.2 2002/04/15 20:39:49 ekohl Exp $
PATH_TO_TOP = ../../..
TARGET_NAME = cdfs
-TARGET_OBJECTS = $(TARGET_NAME).o common.o fcb.o
+TARGET_OBJECTS = $(TARGET_NAME).o close.o common.o create.o dirctl.o \
+ fcb.o finfo.o fsctl.o rw.o volinfo.o
include $(PATH_TO_TOP)/rules.mak
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/cdfs/rw.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PVOID Buffer,
+ ULONG Length,
+ ULONG Offset)
+/*
+ * FUNCTION: Reads data from a file
+ */
+{
+ NTSTATUS Status;
+ PCCB Ccb;
+ PFCB Fcb;
+
+ DPRINT("CdfsReadFile(Offset %lu Length %lu)\n", Offset, Length);
+
+ if (Length == 0)
+ return STATUS_SUCCESS;
+
+ Ccb = (PCCB)FileObject->FsContext2;
+ Fcb = Ccb->Fcb;
+
+ if (Offset + Length > Fcb->Entry.DataLengthL)
+ Length = Fcb->Entry.DataLengthL - Offset;
+
+ DPRINT( "Reading %d bytes at %d\n", Offset, Length );
+
+ if (Length == 0)
+ return(STATUS_UNSUCCESSFUL);
+
+ Status = CdfsReadSectors(DeviceExt->StorageDevice,
+ Fcb->Entry.ExtentLocationL + Offset / BLOCKSIZE,
+ Length / BLOCKSIZE,
+ Buffer);
+
+ return(Status);
+}
+
+
+NTSTATUS STDCALL
+CdfsRead(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ ULONG Length;
+ PVOID Buffer;
+ ULONG Offset;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PFILE_OBJECT FileObject = Stack->FileObject;
+ PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+ NTSTATUS Status;
+
+ DPRINT("CdfsRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+
+ Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ Length = Stack->Parameters.Read.Length;
+ Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
+
+ Status = CdfsReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Length;
+ IoCompleteRequest(Irp,IO_NO_INCREMENT);
+ return(Status);
+}
+
+
+NTSTATUS STDCALL
+CdfsWrite(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ DPRINT("CdfsWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
+
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ return(STATUS_UNSUCCESSFUL);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: volinfo.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/vfat/volume.c
+ * PURPOSE: CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER: Art Yerkes
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+CdfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
+ PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
+ PULONG BufferLength)
+{
+ ULONG LabelLength;
+
+ DPRINT("CdfsGetFsVolumeInformation() called\n");
+ DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+
+ DPRINT("Vpb %p\n", DeviceObject->Vpb);
+ LabelLength = DeviceObject->Vpb->VolumeLabelLength;
+
+ DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)));
+ DPRINT("LabelLength %lu\n", LabelLength);
+ DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
+
+ if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
+ return STATUS_BUFFER_OVERFLOW;
+
+ /* valid entries */
+ FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
+ FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
+ wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
+
+ /* dummy entries */
+ FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
+ FsVolumeInfo->SupportsObjects = FALSE;
+
+ DPRINT("Finished FsdGetFsVolumeInformation()\n");
+
+ *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR));
+
+ DPRINT("BufferLength %lu\n", *BufferLength);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
+ PULONG BufferLength)
+{
+ DPRINT("CdfsGetFsAttributeInformation()\n");
+ DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
+
+ if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
+ return STATUS_BUFFER_OVERFLOW;
+
+ FsAttributeInfo->FileSystemAttributes =
+ FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
+ FsAttributeInfo->MaximumComponentNameLength = 255;
+ FsAttributeInfo->FileSystemNameLength = 8;
+
+ memcpy(FsAttributeInfo->FileSystemName, L"CDFS", 8);
+
+ DPRINT("Finished FsdGetFsAttributeInformation()\n");
+
+ *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
+ PFILE_FS_SIZE_INFORMATION FsSizeInfo,
+ PULONG BufferLength)
+{
+ PDEVICE_EXTENSION DeviceExt;
+ NTSTATUS Status;
+
+ DPRINT("CdfsGetFsSizeInformation()\n");
+ DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
+
+ if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
+ return(STATUS_BUFFER_OVERFLOW);
+
+ DeviceExt = DeviceObject->DeviceExtension;
+
+ FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
+ FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize;
+ FsSizeInfo->SectorsPerAllocationUnit = 1;
+ FsSizeInfo->BytesPerSector = 2048; /* ?? */
+
+ DPRINT("Finished FsdGetFsSizeInformation()\n");
+ if (NT_SUCCESS(Status))
+ *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
+
+ return(Status);
+}
+
+
+static NTSTATUS
+CdfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
+ PULONG BufferLength)
+{
+ DPRINT("CdfsGetFsDeviceInformation()\n");
+ DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
+
+ if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
+ return(STATUS_BUFFER_OVERFLOW);
+
+ FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM;
+ FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
+
+ DPRINT("FsdGetFsDeviceInformation() finished.\n");
+
+ *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+
+ return(STATUS_SUCCESS);
+}
+
+
+
+NTSTATUS STDCALL
+CdfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ FS_INFORMATION_CLASS FsInformationClass;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID SystemBuffer;
+ ULONG BufferLength;
+
+ DPRINT("CdfsQueryVolumeInformation() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
+ BufferLength = Stack->Parameters.QueryVolume.Length;
+ SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+
+ DPRINT("FsInformationClass %d\n", FsInformationClass);
+ DPRINT("SystemBuffer %x\n", SystemBuffer);
+
+ switch (FsInformationClass)
+ {
+ case FileFsVolumeInformation:
+ Status = CdfsGetFsVolumeInformation(DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsAttributeInformation:
+ Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsSizeInformation:
+ Status = CdfsGetFsSizeInformation(DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsDeviceInformation:
+ Status = CdfsGetFsDeviceInformation(SystemBuffer,
+ &BufferLength);
+ break;
+
+ default:
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information =
+ Stack->Parameters.QueryVolume.Length - BufferLength;
+ else
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+
+NTSTATUS STDCALL
+CdfsSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ DPRINT("CdfsSetVolumeInformation() called\n");
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(STATUS_NOT_SUPPORTED);
+}
+
+/* EOF */