Split the driver into more files.
authorEric Kohl <eric.kohl@reactos.org>
Mon, 15 Apr 2002 20:39:49 +0000 (20:39 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 15 Apr 2002 20:39:49 +0000 (20:39 +0000)
Replaced FCB code.
Improved the mount code.

svn path=/trunk/; revision=2851

12 files changed:
reactos/drivers/fs/cdfs/cdfs.c
reactos/drivers/fs/cdfs/cdfs.h
reactos/drivers/fs/cdfs/close.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/common.c
reactos/drivers/fs/cdfs/create.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/dirctl.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/fcb.c
reactos/drivers/fs/cdfs/finfo.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/fsctl.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/makefile
reactos/drivers/fs/cdfs/rw.c [new file with mode: 0644]
reactos/drivers/fs/cdfs/volinfo.c [new file with mode: 0644]

index b36b31f..dec5531 100644 (file)
@@ -1,4 +1,23 @@
 /*
+ *  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
@@ -720,12 +60,10 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
 
   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,
@@ -736,17 +74,30 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
       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);
index 4279624..4079887 100644 (file)
@@ -8,6 +8,14 @@
 #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
@@ -31,32 +39,48 @@ struct _DIR_RECORD
   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 ... */
 
@@ -65,23 +89,128 @@ struct _PVD
 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
@@ -94,23 +223,117 @@ int CdfsStrcmpi( wchar_t *str1, wchar_t *str2 );
 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
diff --git a/reactos/drivers/fs/cdfs/close.c b/reactos/drivers/fs/cdfs/close.c
new file mode 100644 (file)
index 0000000..686c946
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  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
index 4fc246d..c3b5680 100644 (file)
@@ -1,3 +1,32 @@
+/*
+ *  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
@@ -6,6 +35,8 @@
 #include "cdfs.h"
 
 
+/* FUNCTIONS ****************************************************************/
+
 NTSTATUS
 CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
                IN ULONG DiskSector,
@@ -73,3 +104,5 @@ CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
 
   return(STATUS_SUCCESS);
 }
+
+/* EOF */
diff --git a/reactos/drivers/fs/cdfs/create.c b/reactos/drivers/fs/cdfs/create.c
new file mode 100644 (file)
index 0000000..49810da
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ *  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
diff --git a/reactos/drivers/fs/cdfs/dirctl.c b/reactos/drivers/fs/cdfs/dirctl.c
new file mode 100644 (file)
index 0000000..a77729f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  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 */
index 9842901..3597ba7 100644 (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: 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,
+                                  &currentDirEntry);
+    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 (&currentDirEntry)
+      && !vfatIsDirEntryVolume(&currentDirEntry))
+    {
+      if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
+      {
+        DPRINT ("Match found, %S\n", currentLongName);
+        status = vfatMakeFCBFromDirEntry (pDeviceExt,
+                                          pDirectoryFCB,
+                                          currentLongName,
+                                          &currentDirEntry,
+                                          directoryIndex - 1,
+                                          pFoundFCB);
+        return  status;
+      }
+      else
+      {
+        vfatGetDirEntryName (&currentDirEntry, 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,
+                                            &currentDirEntry,
+                                            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 */
diff --git a/reactos/drivers/fs/cdfs/finfo.c b/reactos/drivers/fs/cdfs/finfo.c
new file mode 100644 (file)
index 0000000..e71f6d3
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ *  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
diff --git a/reactos/drivers/fs/cdfs/fsctl.c b/reactos/drivers/fs/cdfs/fsctl.c
new file mode 100644 (file)
index 0000000..9d411b5
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ *  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 */
index d14f704..9a9f11c 100644 (file)
@@ -1,4 +1,4 @@
-# $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 = ../../..
 
@@ -6,7 +6,8 @@ TARGET_TYPE = driver
 
 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
 
diff --git a/reactos/drivers/fs/cdfs/rw.c b/reactos/drivers/fs/cdfs/rw.c
new file mode 100644 (file)
index 0000000..b0a7557
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  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 */
diff --git a/reactos/drivers/fs/cdfs/volinfo.c b/reactos/drivers/fs/cdfs/volinfo.c
new file mode 100644 (file)
index 0000000..a6ef384
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *  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 */