Fixed FCB management functions.
authorEric Kohl <eric.kohl@reactos.org>
Wed, 1 May 2002 13:15:42 +0000 (13:15 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 1 May 2002 13:15:42 +0000 (13:15 +0000)
Added file and directory information.
Fixed several minor bugs.
Disabled most of the debug messages.

svn path=/trunk/; revision=2900

reactos/drivers/fs/cdfs/cdfs.h
reactos/drivers/fs/cdfs/close.c
reactos/drivers/fs/cdfs/create.c
reactos/drivers/fs/cdfs/dirctl.c
reactos/drivers/fs/cdfs/fcb.c
reactos/drivers/fs/cdfs/finfo.c
reactos/drivers/fs/cdfs/fsctl.c
reactos/drivers/fs/cdfs/makefile
reactos/drivers/fs/cdfs/misc.c [new file with mode: 0644]

index 4079887..c8861ab 100644 (file)
@@ -314,6 +314,23 @@ NTSTATUS STDCALL
 CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
                      PIRP Irp);
 
+/* misc.c */
+
+BOOLEAN
+wstrcmpjoki(PWSTR s1, PWSTR s2);
+
+VOID
+CdfsSwapString(PWCHAR Out,
+              PUCHAR In,
+              ULONG Count);
+
+VOID
+CdfsDateTimeToFileTime(PFCB Fcb,
+                      TIME *FileTime);
+
+VOID
+CdfsFileFlagsToAttributes(PFCB Fcb,
+                         PULONG FileAttributes);
 
 /* rw.c */
 
index 686c946..993513e 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: close.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+/* $Id: close.c,v 1.2 2002/05/01 13:15:42 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -30,7 +30,7 @@
 
 #include <ddk/ntddk.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 #include "cdfs.h"
@@ -85,7 +85,7 @@ CdfsClose(PDEVICE_OBJECT DeviceObject,
   PFILE_OBJECT FileObject;
   NTSTATUS Status;
 
-  DPRINT1("CdfsClose() called\n");
+  DPRINT("CdfsClose() called\n");
 
   Stack = IoGetCurrentIrpStackLocation(Irp);
   FileObject = Stack->FileObject;
index 49810da..c141eec 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: create.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
+/* $Id: create.c,v 1.2 2002/05/01 13:15:42 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -30,7 +30,7 @@
 
 #include <ddk/ntddk.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 #include "cdfs.h"
 
 /* FUNCTIONS ****************************************************************/
 
-#if 0
-NTSTATUS
-vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject,
-                          PWSTR pRelativeFileName,
-                          PWSTR *pAbsoluteFilename)
+static NTSTATUS
+CdfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject,
+                        PWSTR pRelativeFileName,
+                        PWSTR *pAbsoluteFilename)
 {
-  PWSTR  rcName;
-  PVFATFCB  fcb;
-  PVFATCCB  ccb;
+  PWSTR rcName;
+  PFCB Fcb;
+  PCCB Ccb;
 
-  DPRINT ("try related for %S\n", pRelativeFileName);
-  ccb = pFileObject->FsContext2;
-  assert (ccb);
-  fcb = ccb->pFcb;
-  assert (fcb);
+  DPRINT("try related for %S\n", pRelativeFileName);
+  Ccb = pFileObject->FsContext2;
+  assert(Ccb);
+  Fcb = Ccb->Fcb;
+  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;
-  }
+  if (Fcb->Entry.FileFlags & 0x02 == 0 ||
+      pRelativeFileName[0] == L'\\')
+    {
+      return(STATUS_INVALID_PARAMETER);
+    }
 
   /* construct absolute path name */
-  assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
+  assert(wcslen (Fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
           <= MAX_PATH);
-  rcName = ExAllocatePool (NonPagedPool, MAX_PATH * sizeof(WCHAR));
+  rcName = ExAllocatePool(NonPagedPool, MAX_PATH * sizeof(WCHAR));
   if (!rcName)
-  {
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-  wcscpy (rcName, fcb->PathName);
-  if (!vfatFCBIsRoot(fcb))
+    {
+      return(STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  wcscpy(rcName, Fcb->PathName);
+  if (!CdfsFCBIsRoot(Fcb))
     wcscat (rcName, L"\\");
   wcscat (rcName, pRelativeFileName);
   *pAbsoluteFilename = rcName;
 
-  return  STATUS_SUCCESS;
+  return(STATUS_SUCCESS);
 }
-#endif
 
 
 static NTSTATUS
@@ -99,8 +98,8 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
   if (FileObject->RelatedFileObject)
     {
       DPRINT("Converting relative filename to absolute filename\n");
-#if 0
-      Status = vfatMakeAbsoluteFilename(FileObject->RelatedFileObject,
+
+      Status = CdfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
                                        FileName,
                                        &AbsFileName);
       FileName = AbsFileName;
@@ -108,7 +107,6 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
        {
          return(Status);
        }
-#endif
       return(STATUS_UNSUCCESSFUL);
     }
 
@@ -122,7 +120,7 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
                             FileName);
   if (Fcb == NULL)
     {
-      DPRINT ("No existing FCB found, making a new one if file exists.\n");
+      DPRINT("No existing FCB found, making a new one if file exists.\n");
       Status = CdfsGetFCBForFile(DeviceExt,
                                 &ParentFcb,
                                 &Fcb,
@@ -174,7 +172,7 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
 //  PWSTR FileName;
   NTSTATUS Status;
 
-  DPRINT1("CdfsCreateFile() called\n");
+  DPRINT("CdfsCreateFile() called\n");
 
   DeviceExt = DeviceObject->DeviceExtension;
   assert (DeviceExt);
@@ -199,37 +197,10 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
    * If the directory containing the file to open doesn't exist then
    * fail immediately
    */
-  Irp->IoStatus.Information = 0;
+  Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 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
+  return(Status);
 }
 
 
index 4190877..1e9e31c 100644 (file)
  *  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.2 2002/04/26 23:21:28 ekohl Exp $
+/* $Id: dirctl.c,v 1.3 2002/05/01 13:15:42 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
+ *                   Eric Kohl
  * UPDATE HISTORY: 
  */
 
 
 /* FUNCTIONS ****************************************************************/
 
-
-static BOOLEAN
-wstrcmpjoki(PWSTR s1, PWSTR s2)
-/*
- * FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
- * return TRUE if s1 like s2
- */
-{
-  while ((*s2=='*')||(*s2=='?')||(towlower(*s1)==towlower(*s2)))
-    {
-      if ((*s1)==0 && (*s2)==0)
-        return(TRUE);
-
-      if(*s2=='*')
-       {
-         s2++;
-         while (*s1)
-           if (wstrcmpjoki(s1,s2))
-             return TRUE;
-           else
-             s1++;
-       }
-      else
-       {
-         s1++;
-         s2++;
-       }
-    }
-
-  if ((*s2)=='.')
-    {
-      for (;((*s2)=='.')||((*s2)=='*')||((*s2)=='?');s2++)
-       ;
-    }
-
-  if ((*s1)==0 && (*s2)==0)
-    return(TRUE);
-
-  return(FALSE);
-}
-
-
-static void
-CdfsSwapString(PWCHAR Out,
-              PUCHAR In,
-              ULONG Count)
-{
-  PUCHAR t = (PUCHAR)Out;
-  ULONG i;
-
-  for (i = 0; i < Count; i += 2)
-    {
-      t[i] = In[i+1];
-      t[i+1] = In[i];
-    }
-  t[i] = 0;
-  t[i+1] = 0;
-}
-
-
-static VOID
-CdfsDateTimeToFileTime(PFCB Fcb,
-                      TIME *FileTime)
-{
-  TIME_FIELDS TimeFields;
-
-  TimeFields.Milliseconds = 0;
-  TimeFields.Second = Fcb->Entry.Second;
-  TimeFields.Minute = Fcb->Entry.Minute;
-  TimeFields.Hour = Fcb->Entry.Hour;
-
-  TimeFields.Day = Fcb->Entry.Day;
-  TimeFields.Month = Fcb->Entry.Month;
-  TimeFields.Year = Fcb->Entry.Year + 1900;
-
-  RtlTimeFieldsToTime(&TimeFields,
-                     (PLARGE_INTEGER)FileTime);
-}
-
-
-NTSTATUS
+static NTSTATUS
 CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
                 PVOID Block,
                 ULONG BlockLength,
@@ -190,7 +111,7 @@ CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
 }
 
 
-NTSTATUS
+static NTSTATUS
 CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
             PFCB Fcb,
             PFCB Parent,
@@ -220,8 +141,10 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
   PUCHAR Ptr;
   PDIR_RECORD Record;
 
-  DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
-  DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName);
+  DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n",
+        Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
+  DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",
+        Fcb->PathName, Fcb->ObjectName);
 
   IsRoot = FALSE;
   DirIndex = 0;
@@ -321,7 +244,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
          break;
        }
 
-//      DPRINT("Name '%S'\n", name);
+      DPRINT("Name '%S'\n", name);
 
       if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */
        {
@@ -350,7 +273,8 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
          if (pDirIndex)
            *pDirIndex = DirIndex;
 
-         DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
+         DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
+                Fcb->PathName, Fcb->ObjectName, DirIndex);
 
          ExFreePool(block);
 
@@ -378,16 +302,14 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
 
 
 static NTSTATUS
-CdfsGetBothInformation(PFCB Fcb,
+CdfsGetNameInformation(PFCB Fcb,
                       PDEVICE_EXTENSION DeviceExt,
-                      PFILE_BOTH_DIRECTORY_INFORMATION Info,
+                      PFILE_NAMES_INFORMATION Info,
                       ULONG BufferLength)
 {
-//  short i;
-//  ULONGLONG AllocSize;
   ULONG Length;
 
-  DPRINT("FileBothDirectoryInformation() called\n");
+  DPRINT("CdfsGetNameInformation() called\n");
 
   Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
   if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
@@ -398,8 +320,73 @@ CdfsGetBothInformation(PFCB Fcb,
     ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
   memcpy(Info->FileName, Fcb->ObjectName, Length);
 
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetDirectoryInformation(PFCB Fcb,
+                           PDEVICE_EXTENSION DeviceExt,
+                           PFILE_DIRECTORY_INFORMATION Info,
+                           ULONG BufferLength)
+{
+  ULONG Length;
+
+  DPRINT1("CdfsGetDirectoryInformation() called\n");
+
+  Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
+  if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
+    return(STATUS_BUFFER_OVERFLOW);
+
+  Info->FileNameLength = Length;
+  Info->NextEntryOffset =
+    ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
+  memcpy(Info->FileName, Fcb->ObjectName, Length);
+
+  /* Convert file times */
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->CreationTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->LastAccessTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->LastWriteTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->ChangeTime);
+
+  /* Convert file flags */
+  CdfsFileFlagsToAttributes(Fcb,
+                           &Info->FileAttributes);
+
+  Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
+
+  /* Make AllocSize a rounded up multiple of the sector size */
+  Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
+
 //  Info->FileIndex=;
 
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetFullDirectoryInformation(PFCB Fcb,
+                               PDEVICE_EXTENSION DeviceExt,
+                               PFILE_FULL_DIRECTORY_INFORMATION Info,
+                               ULONG BufferLength)
+{
+  ULONG Length;
+
+  DPRINT1("CdfsGetFullDirectoryInformation() called\n");
+
+  Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
+  if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
+    return(STATUS_BUFFER_OVERFLOW);
+
+  Info->FileNameLength = Length;
+  Info->NextEntryOffset =
+    ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
+  memcpy(Info->FileName, Fcb->ObjectName, Length);
+
   /* Convert file times */
   CdfsDateTimeToFileTime(Fcb,
                         &Info->CreationTime);
@@ -410,38 +397,82 @@ CdfsGetBothInformation(PFCB Fcb,
   CdfsDateTimeToFileTime(Fcb,
                         &Info->ChangeTime);
 
+  /* Convert file flags */
+  CdfsFileFlagsToAttributes(Fcb,
+                           &Info->FileAttributes);
+
   Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
 
   /* Make AllocSize a rounded up multiple of the sector size */
-//  AllocSize = ((Fcb->Entry.DataLengthL + BLOCKSIZE - 1) /
-//            BLOCKSIZE) * BLOCKSIZE;
-//  Info->AllocationSize.QuadPart = AllocSize;
   Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
 
-  /* FIXME: Convert file flags to file attributes */
-  Info->FileAttributes = (Fcb->Entry.FileFlags & 0x02) ? FILE_ATTRIBUTE_DIRECTORY : 0;
+//  Info->FileIndex=;
   Info->EaSize = 0;
 
-  /* FIXME: Copy or create a short file name */
-#if 0
-  for (i = 0; i < 8 && (pFcb->entry.Filename[i] != ' '); i++)
-    pInfo->ShortName[i] = pFcb->entry.Filename[i];
-  pInfo->ShortNameLength = i;
-  pInfo->ShortName[i] = '.';
-  for (i = 0; i < 3 && (pFcb->entry.Ext[i] != ' '); i++)
-    pInfo->ShortName[i + 1 + pInfo->ShortNameLength] = pFcb->entry.Ext[i];
-  if (i)
-    pInfo->ShortNameLength += (i + 1);
-  pInfo->ShortNameLength *= sizeof(WCHAR);
-#endif
-
-  Info->ShortName[0] = 0;
-  Info->ShortNameLength = 0;
-
-  return STATUS_SUCCESS;
+  return(STATUS_SUCCESS);
 }
 
 
+static NTSTATUS
+CdfsGetBothDirectoryInformation(PFCB Fcb,
+                               PDEVICE_EXTENSION DeviceExt,
+                               PFILE_BOTH_DIRECTORY_INFORMATION Info,
+                               ULONG BufferLength)
+{
+  ULONG Length;
+
+  DPRINT("CdfsGetBothDirectoryInformation() called\n");
+
+  Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
+  if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
+    return(STATUS_BUFFER_OVERFLOW);
+
+  Info->FileNameLength = Length;
+  Info->NextEntryOffset =
+    ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
+  memcpy(Info->FileName, Fcb->ObjectName, Length);
+
+  /* Convert file times */
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->CreationTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->LastAccessTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->LastWriteTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &Info->ChangeTime);
+
+  /* Convert file flags */
+  CdfsFileFlagsToAttributes(Fcb,
+                           &Info->FileAttributes);
+
+  Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
+
+  /* Make AllocSize a rounded up multiple of the sector size */
+  Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
+
+//  Info->FileIndex=;
+  Info->EaSize = 0;
+
+  if (DeviceExt->CdInfo.JolietLevel == 0)
+    {
+      /* Standard ISO-9660 format */
+      Info->ShortNameLength = Length;
+      memcpy(Info->ShortName, Fcb->ObjectName, Length);
+    }
+  else
+    {
+      /* Joliet extension */
+
+      /* FIXME: Copy or create a short file name */
+
+      Info->ShortName[0] = 0;
+      Info->ShortNameLength = 0;
+    }
+
+  return(STATUS_SUCCESS);
+}
+
 
 static NTSTATUS
 CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
@@ -547,29 +578,31 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
          switch (FileInformationClass)
            {
              case FileNameInformation:
-               DPRINT1("FileNameInformation\n");
-//             Status = VfatGetFileNameInformation(&TempFcb,
-//                         (PFILE_NAMES_INFORMATION) Buffer, BufferLength);
-//             break;
+               Status = CdfsGetNameInformation(&TempFcb,
+                                               DeviceExtension,
+                                               (PFILE_NAMES_INFORMATION)Buffer,
+                                               BufferLength);
+               break;
 
              case FileDirectoryInformation:
-               DPRINT1("FileDirectoryInformation\n");
-//             Status = VfatGetFileDirectoryInformation(&TempFcb, DeviceExtension,
-//                              (PFILE_DIRECTORY_INFORMATION) Buffer, BufferLength);
+               Status = CdfsGetDirectoryInformation(&TempFcb,
+                                                    DeviceExtension,
+                                                    (PFILE_DIRECTORY_INFORMATION)Buffer,
+                                                    BufferLength);
                break;
 
              case FileFullDirectoryInformation:
-               DPRINT1("FileFullDirecrotyInformation\n");
-//             Status = CdfsGetFullDirectoryInformation(&TempFcb,
-//                                                      DeviceExtension,
-//                             (PFILE_FULL_DIRECTORY_INFORMATION)Buffer, BufferLength);
+               Status = CdfsGetFullDirectoryInformation(&TempFcb,
+                                                        DeviceExtension,
+                                                        (PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
+                                                        BufferLength);
                break;
 
              case FileBothDirectoryInformation:
-               Status = CdfsGetBothInformation(&TempFcb,
-                                               DeviceExtension,
-                                               (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
-                                               BufferLength);
+               Status = CdfsGetBothDirectoryInformation(&TempFcb,
+                                                        DeviceExtension,
+                                                        (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
+                                                        BufferLength);
                break;
 
              default:
index e095820..5621134 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fcb.c,v 1.3 2002/04/26 23:21:28 ekohl Exp $
+/* $Id: fcb.c,v 1.4 2002/05/01 13:15:42 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -30,7 +30,7 @@
 
 #include <ddk/ntddk.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 #include "cdfs.h"
 
 /* FUNCTIONS ****************************************************************/
 
+static PWCHAR
+CdfsGetNextPathElement(PWCHAR FileName)
+{
+  if (*FileName == L'\0')
+    {
+      return(NULL);
+    }
+
+  while (*FileName != L'\0' && *FileName != L'\\')
+    {
+      FileName++;
+    }
+
+  return(FileName);
+}
+
+
+static VOID
+CdfsWSubString(PWCHAR pTarget, const PWCHAR pSource, size_t pLength)
+{
+  wcsncpy (pTarget, pSource, pLength);
+  pTarget [pLength] = L'\0';
+}
+
+
 PFCB
 CdfsCreateFCB(PWSTR FileName)
 {
@@ -162,7 +187,7 @@ CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
 
   if (FileName == NULL || *FileName == 0)
     {
-      DPRINT1("Return FCB for strem file object\n");
+      DPRINT("Return FCB for stream file object\n");
       Fcb = ((PCCB)Vcb->StreamFileObject->FsContext2)->Fcb;
       Fcb->RefCount++;
       KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
@@ -174,8 +199,8 @@ CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
     {
       Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry);
 
-//      if (wstrcmpi(FileName, Fcb->PathName))
-      if (_wcsicmp(FileName, Fcb->PathName))
+      DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName);
+      if (_wcsicmp(FileName, Fcb->PathName) == 0)
        {
          Fcb->RefCount++;
          KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
@@ -277,79 +302,94 @@ CdfsOpenRootFCB(PDEVICE_EXTENSION Vcb)
 }
 
 
-#if 0
+static VOID
+CdfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt,
+                   PDIR_RECORD Record,
+                   PWSTR Name)
+/*
+ * FUNCTION: Retrieves the file name, be it in short or long file name format
+ */
+{
+  if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
+    {
+      wcscpy(Name, L".");
+    }
+  else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
+    {
+      wcscpy(Name, L"..");
+    }
+  else
+    {
+      if (DeviceExt->CdInfo.JolietLevel == 0)
+       {
+         ULONG i;
+
+         for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
+           Name[i] = (WCHAR)Record->FileId[i];
+         Name[i] = 0;
+       }
+      else
+       {
+         CdfsSwapString(Name, Record->FileId, Record->FileIdLength);
+       }
+    }
+
+  DPRINT("Name '%S'\n", Name);
+}
+
+
 NTSTATUS
-vfatMakeFCBFromDirEntry(PVCB  vcb,
-                       PVFATFCB  directoryFCB,
-                       PWSTR  longName,
-                       PFAT_DIR_ENTRY  dirEntry,
-                       ULONG dirIndex,
-                       PVFATFCB * fileFCB)
+CdfsMakeFCBFromDirEntry(PVCB Vcb,
+                       PFCB DirectoryFCB,
+                       PWSTR Name,
+                       PDIR_RECORD Record,
+                       PFCB * fileFCB)
 {
-  PVFATFCB  rcFCB;
-  WCHAR  pathName [MAX_PATH];
+  WCHAR pathName[MAX_PATH];
+  PFCB rcFCB;
   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];
-
-    vfatGetDirEntryName (dirEntry, entryName);
-    wcscat (pathName, entryName);
-  }
-  rcFCB = vfatNewFCB (pathName);
-  memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
-
-  if (vfatFCBIsDirectory(vcb, rcFCB))
-  {
-    ULONG FirstCluster, CurrentCluster;
-    NTSTATUS Status;
-    Size = 0;
-    FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
-    if (FirstCluster == 1)
+
+  if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
+        sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
+    {
+      return(STATUS_OBJECT_NAME_INVALID);
+    }
+
+  wcscpy(pathName, DirectoryFCB->PathName);
+  if (!CdfsFCBIsRoot(DirectoryFCB))
     {
-      Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE;
+      wcscat(pathName, L"\\");
     }
-    else
+
+  if (Name[0] != 0)
     {
-      CurrentCluster = FirstCluster;
-      while (CurrentCluster != 0xffffffff)
-      {
-         Size += vcb->FatInfo.BytesPerCluster;
-         Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
-      }
+      wcscat(pathName, Name);
     }
-  }
   else
-  {
-    Size = rcFCB->entry.FileSize;
-  }
-  rcFCB->dirIndex = dirIndex;
+    {
+      WCHAR entryName[MAX_PATH];
+
+      CdfsGetDirEntryName(Vcb, Record, entryName);
+      wcscat(pathName, entryName);
+    }
+
+  rcFCB = CdfsCreateFCB(pathName);
+  memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD));
+
+  Size = rcFCB->Entry.DataLengthL;
+
   rcFCB->RFCB.FileSize.QuadPart = Size;
   rcFCB->RFCB.ValidDataLength.QuadPart = Size;
-  rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
+  rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, 2096);
 //  DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
-  vfatFCBInitializeCache (vcb, rcFCB);
+  CdfsFCBInitializeCache(Vcb, rcFCB);
   rcFCB->RefCount++;
-  vfatAddFCBToTable (vcb, rcFCB);
+  CdfsAddFCBToTable(Vcb, rcFCB);
   *fileFCB = rcFCB;
 
-  return  STATUS_SUCCESS;
+  return(STATUS_SUCCESS);
 }
-#endif
+
 
 NTSTATUS
 CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
@@ -359,7 +399,7 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
   NTSTATUS Status;
   PCCB  newCCB;
 
-  newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof(CCB), TAG_CCB);
+  newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
   if (newCCB == NULL)
     {
       return(STATUS_INSUFFICIENT_RESOURCES);
@@ -393,99 +433,111 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
   return(STATUS_SUCCESS);
 }
 
-#if 0
+
 NTSTATUS
-vfatDirFindFile (PDEVICE_EXTENSION  pDeviceExt,
-                 PVFATFCB  pDirectoryFCB,
-                 PWSTR  pFileToFind,
-                 PVFATFCB * pFoundFCB)
+CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
+               PFCB DirectoryFcb,
+               PWSTR FileToFind,
+               PFCB *FoundFCB)
 {
-  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;
-  }
-
-  directoryIndex = 0;
-  finishedScanningDirectory = FALSE;
-  while (!finishedScanningDirectory)
-  {
-    status = vfatGetNextDirEntry (pDeviceExt,
-                                  pDirectoryFCB,
-                                  &directoryIndex,
-                                  currentLongName,
-                                  &currentDirEntry);
-    if (status == STATUS_NO_MORE_ENTRIES)
+  WCHAR TempName[2];
+  WCHAR Name[256];
+  PUCHAR Block;
+  ULONG FirstSector;
+  ULONG DirSize;
+  ULONG BufferSize;
+  ULONG SectorCount;
+  PDIR_RECORD Record;
+  ULONG Offset;
+  NTSTATUS Status;
+
+  assert(DeviceExt);
+  assert(DirectoryFcb);
+  assert(FileToFind);
+
+  DPRINT("CdfsDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
+        DeviceExt,
+        DirectoryFcb,
+        FileToFind);
+  DPRINT("Dir Path:%S\n", DirectoryFcb->PathName);
+
+  /*  default to '.' if no filename specified */
+  if (wcslen(FileToFind) == 0)
     {
-      finishedScanningDirectory = TRUE;
-      continue;
+      TempName[0] = L'.';
+      TempName[1] = 0;
+      FileToFind = TempName;
     }
-    else if (!NT_SUCCESS(status))
+
+  FirstSector = DirectoryFcb->Entry.ExtentLocationL;
+  DirSize = DirectoryFcb->Entry.DataLengthL;
+
+  BufferSize = ROUND_UP(DirSize, BLOCKSIZE);
+  SectorCount = BufferSize / BLOCKSIZE;
+
+  DPRINT("FirstSector %lu  DirSize %lu  BufferSize %lu  SectorCount %lu\n",
+        FirstSector, DirSize, BufferSize, SectorCount);
+
+  Block = ExAllocatePool(NonPagedPool, BufferSize);
+
+  Status = CdfsReadSectors(DeviceExt->StorageDevice,
+                          FirstSector,
+                          SectorCount,
+                          Block);
+  if (!NT_SUCCESS(Status))
     {
-      return  status;
+      DPRINT("Reading directory extent failed (Status %lx)\n", Status);
+      ExFreePool(Block);
+      return(Status);
     }
 
-    DPRINT ("  Index:%d  longName:%S\n",
-            directoryIndex,
-            currentLongName);
-
-    if (!vfatIsDirEntryDeleted (&currentDirEntry)
-      && !vfatIsDirEntryVolume(&currentDirEntry))
+  Offset = 0;
+  Record = (PDIR_RECORD)Block;
+  while(TRUE)
     {
-      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);
-
-        if (wstrcmpjoki (currentEntryName, pFileToFind))
-        {
-          DPRINT ("Match found, %S\n", currentEntryName);
-          status = vfatMakeFCBFromDirEntry (pDeviceExt,
-                                            pDirectoryFCB,
-                                            currentLongName,
-                                            &currentDirEntry,
-                                            directoryIndex - 1,
-                                            pFoundFCB);
-          return  status;
-        }
-      }
+      if (Record->RecordLength == 0)
+       {
+         DPRINT1("RecordLength == 0  Stopped!\n");
+         break;
+       }
+       
+      DPRINT("RecordLength %u  ExtAttrRecordLength %u  NameLength %u\n",
+            Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
+
+      CdfsGetDirEntryName(DeviceExt, Record, Name);
+      DPRINT("Name '%S'\n", Name);
+
+      if (wstrcmpjoki(Name, FileToFind))
+       {
+         DPRINT("Match found, %S\n", Name);
+         Status = CdfsMakeFCBFromDirEntry(DeviceExt,
+                                          DirectoryFcb,
+                                          Name,
+                                          Record,
+                                          FoundFCB);
+
+         ExFreePool(Block);
+
+         return(Status);
+       }
+
+      Offset = Offset + Record->RecordLength;
+      Record = (PDIR_RECORD)(Block + Offset);
+      if (Record->RecordLength == 0)
+       {
+         Offset = ROUND_UP(Offset, 2048);
+         Record = (PDIR_RECORD)(Block + Offset);
+       }
+
+//      if (Offset >= BufferSize)
+      if (Offset >= DirSize)
+       break;
     }
-  }
 
-  return  STATUS_OBJECT_NAME_NOT_FOUND;
+  ExFreePool(Block);
+
+  return(STATUS_OBJECT_NAME_NOT_FOUND);
 }
-#endif
 
 
 NTSTATUS
@@ -494,7 +546,7 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
                  PFCB *pFCB,
                  const PWSTR pFileName)
 {
-  NTSTATUS  status;
+  NTSTATUS Status;
   WCHAR  pathName [MAX_PATH];
   WCHAR  elementName [MAX_PATH];
   PWCHAR  currentElement;
@@ -518,11 +570,6 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
 
       return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
     }
-
-  DPRINT1("CdfsGetFCBForFile() is incomplete!\n");
-  return(STATUS_UNSUCCESSFUL);
-
-#if 0
   else
     {
       currentElement = pFileName + 1;
@@ -531,85 +578,85 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION 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)
+  /* Parse filename and check each path element for existance and access */
+  while (CdfsGetNextPathElement(currentElement) != 0)
     {
-      currentElement++;
-      continue;
-    }
+      /*  Skip blank directory levels */
+      if ((CdfsGetNextPathElement(currentElement) - currentElement) == 0)
+       {
+         currentElement++;
+         continue;
+       }
 
-    DPRINT ("Parsing, currentElement:%S\n", currentElement);
-    DPRINT ("  parentFCB:%x FCB:%x\n", parentFCB, FCB);
+      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");
+      /* Descend to next directory level */
+      if (parentFCB)
+       {
+         CdfsReleaseFCB(Vcb, parentFCB);
+         parentFCB = NULL;
+       }
 
-      vfatReleaseFCB (pVCB, FCB);
-      FCB = 0;
-      *pParentFCB = NULL;
-      *pFCB = NULL;
+      /* fail if element in FCB is not a directory */
+      if (!CdfsFCBIsDirectory(FCB))
+       {
+         DPRINT("Element in requested path is not a directory\n");
 
-      return  STATUS_OBJECT_PATH_NOT_FOUND;
-    }
-    parentFCB = FCB;
+         CdfsReleaseFCB(Vcb, FCB);
+         FCB = 0;
+         *pParentFCB = NULL;
+         *pFCB = NULL;
 
-    //  Extract next directory level into dirName
-    vfatWSubString (pathName,
-                    pFileName,
-                    vfatGetNextPathElement (currentElement) - pFileName);
-    DPRINT ("  pathName:%S\n", pathName);
+         return(STATUS_OBJECT_PATH_NOT_FOUND);
+       }
+      parentFCB = FCB;
 
-    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;
-      }
+      /* Extract next directory level into dirName */
+      CdfsWSubString(pathName,
+                    pFileName,
+                    CdfsGetNextPathElement(currentElement) - pFileName);
+      DPRINT("  pathName:%S\n", pathName);
+
+      FCB = CdfsGrabFCBFromTable(Vcb, pathName);
+      if (FCB == NULL)
+       {
+         CdfsWSubString(elementName,
+                        currentElement,
+                        CdfsGetNextPathElement(currentElement) - currentElement);
+         DPRINT("  elementName:%S\n", elementName);
+
+         Status = CdfsDirFindFile(Vcb, parentFCB, elementName, &FCB);
+         if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+           {
+             *pParentFCB = parentFCB;
+             *pFCB = NULL;
+             currentElement = CdfsGetNextPathElement(currentElement);
+             if (*currentElement == L'\0' || CdfsGetNextPathElement(currentElement + 1) == 0)
+               {
+                 return(STATUS_OBJECT_NAME_NOT_FOUND);
+               }
+             else
+               {
+                 return(STATUS_OBJECT_PATH_NOT_FOUND);
+               }
+           }
+         else if (!NT_SUCCESS(Status))
+           {
+             CdfsReleaseFCB(Vcb, parentFCB);
+             *pParentFCB = NULL;
+             *pFCB = NULL;
+
+             return(Status);
+           }
+       }
+      currentElement = CdfsGetNextPathElement(currentElement);
     }
-    currentElement = vfatGetNextPathElement (currentElement);
-  }
 
   *pParentFCB = parentFCB;
   *pFCB = FCB;
 
-  return  STATUS_SUCCESS;
-#endif
+  return(STATUS_SUCCESS);
 }
 
 /* EOF */
index e71f6d3..be44447 100644 (file)
  *  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 $
+/* $Id: finfo.c,v 1.2 2002/05/01 13:15:42 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
+ *                   Eric Kohl
  * UPDATE HISTORY: 
  */
 
@@ -30,7 +31,7 @@
 
 #include <ddk/ntddk.h>
 
-//#define NDEBUG
+#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)
+CdfsGetStandardInformation(PFCB Fcb,
+                          PDEVICE_OBJECT DeviceObject,
+                          PFILE_STANDARD_INFORMATION StandardInfo,
+                          PULONG BufferLength)
+/*
+ * FUNCTION: Retrieve the standard file information
+ */
+{
+  DPRINT("CdfsGetStandardInformation() called\n");
+
+  if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
+    return STATUS_BUFFER_OVERFLOW;
+
+  /* PRECONDITION */
+  assert(StandardInfo != NULL);
+  assert(Fcb != NULL);
+
+  RtlZeroMemory(StandardInfo,
+               sizeof(FILE_STANDARD_INFORMATION));
+
+  StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
+  StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
+  StandardInfo->NumberOfLinks = 0;
+  StandardInfo->DeletePending = FALSE;
+  StandardInfo->Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
+
+  *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetPositionInformation(PFILE_OBJECT FileObject,
+                          PFILE_POSITION_INFORMATION PositionInfo,
+                          PULONG BufferLength)
+{
+  DPRINT("CdfsGetPositionInformation() called\n");
+
+  if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
+    return STATUS_BUFFER_OVERFLOW;
+
+  PositionInfo->CurrentByteOffset.QuadPart =
+    FileObject->CurrentByteOffset.QuadPart;
+
+  DPRINT("Getting position %I64x\n",
+        PositionInfo->CurrentByteOffset.QuadPart);
+
+  *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetBasicInformation(PFILE_OBJECT FileObject,
+                       PFCB Fcb,
+                       PDEVICE_OBJECT DeviceObject,
+                       PFILE_BASIC_INFORMATION BasicInfo,
+                       PULONG BufferLength)
+{
+  DPRINT("CdfsGetBasicInformation() called\n");
+
+  if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
+    return STATUS_BUFFER_OVERFLOW;
+
+  CdfsDateTimeToFileTime(Fcb,
+                        &BasicInfo->CreationTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &BasicInfo->LastAccessTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &BasicInfo->LastWriteTime);
+  CdfsDateTimeToFileTime(Fcb,
+                        &BasicInfo->ChangeTime);
+
+  CdfsFileFlagsToAttributes(Fcb,
+                           &BasicInfo->FileAttributes);
+
+  *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
+
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+CdfsGetNameInformation(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);
+  DPRINT("CdfsGetNameInformation() called\n");
 
-#if 0
-  NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
+  assert(NameInfo != NULL);
+  assert(Fcb != NULL);
+
+  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,
+        Fcb->PathName,
         NameLength + sizeof(WCHAR));
-#endif
-
-  /* Fake name */
-  NameLength = 2;
-  wcscpy(NameInfo->FileName, L"\\");
 
   *BufferLength -=
     (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
@@ -75,6 +155,28 @@ CdfsQueryNameInformation(PFILE_OBJECT FileObject,
 }
 
 
+static NTSTATUS
+CdfsGetInternalInformation(PFCB Fcb,
+                          PFILE_INTERNAL_INFORMATION InternalInfo,
+                          PULONG BufferLength)
+{
+  DPRINT("CdfsGetInternalInformation() called\n");
+
+  assert(InternalInfo);
+  assert(Fcb);
+
+  if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
+    return(STATUS_BUFFER_OVERFLOW);
+
+  /* FIXME: get a real index, that can be used in a create operation */
+  InternalInfo->IndexNumber.QuadPart = 0;
+
+  *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
+
+  return(STATUS_SUCCESS);
+}
+
+
 NTSTATUS STDCALL
 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
                     PIRP Irp)
@@ -91,7 +193,7 @@ CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
 
   NTSTATUS Status = STATUS_SUCCESS;
 
-  DPRINT1("CdfsQueryInformation() called\n");
+  DPRINT("CdfsQueryInformation() called\n");
 
   Stack = IoGetCurrentIrpStackLocation(Irp);
   FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
@@ -103,49 +205,46 @@ CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
 
   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
+                                           DeviceObject,
+                                           SystemBuffer,
+                                           &BufferLength);
+       break;
 
-      case FileNameInformation:
-       Status = CdfsQueryNameInformation(FileObject,
+      case FilePositionInformation:
+       Status = CdfsGetPositionInformation(FileObject,
+                                           SystemBuffer,
+                                           &BufferLength);
+       break;
+
+      case FileBasicInformation:
+       Status = CdfsGetBasicInformation(FileObject,
                                         Fcb,
                                         DeviceObject,
                                         SystemBuffer,
                                         &BufferLength);
        break;
 
-#if 0
+      case FileNameInformation:
+       Status = CdfsGetNameInformation(FileObject,
+                                       Fcb,
+                                       DeviceObject,
+                                       SystemBuffer,
+                                       &BufferLength);
+       break;
+
       case FileInternalInformation:
        Status = CdfsGetInternalInformation(Fcb,
-                                          SystemBuffer,
-                                          &BufferLength);
+                                           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;
index 2c2a053..fdd5d33 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fsctl.c,v 1.2 2002/04/26 23:21:28 ekohl Exp $
+/* $Id: fsctl.c,v 1.3 2002/05/01 13:15:42 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -30,7 +30,7 @@
 
 #include <ddk/ntddk.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 #include "cdfs.h"
@@ -82,12 +82,12 @@ CdfsGetPVDData(PUCHAR Buffer,
   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);
+  DPRINT("VolumeSerial: %08lx\n", Vpb->SerialNumber);
+  DPRINT("VolumeLabel: '%S'\n", Vpb->VolumeLabel);
+  DPRINT("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength);
+  DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
+  DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
+  DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
 }
 
 
@@ -104,17 +104,17 @@ CdfsGetSVDData(PUCHAR Buffer,
 
   if (strncmp(Svd->EscapeSequences, "%/@", 3) == 0)
     {
-      DPRINT1("Joliet extension found (UCS-2 Level 1)\n");
+      DPRINT("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");
+      DPRINT("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");
+      DPRINT("Joliet extension found (UCS-2 Level 3)\n");
       JolietLevel = 3;
     }
 
@@ -127,8 +127,8 @@ CdfsGetSVDData(PUCHAR Buffer,
       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);
+      DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
+      DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
     }
 //#endif
 }
@@ -143,7 +143,6 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
   ULONG Sector;
   PVD_HEADER VdHeader;
 
-
   Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
 
   Buffer = ExAllocatePool(NonPagedPool,
@@ -166,29 +165,29 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
       switch (VdHeader->VdType)
        {
          case 0:
-           DPRINT1("BootVolumeDescriptor found!\n");
+           DPRINT("BootVolumeDescriptor found!\n");
            break;
 
          case 1:
-           DPRINT1("PrimaryVolumeDescriptor found!\n");
+           DPRINT("PrimaryVolumeDescriptor found!\n");
            CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb);
            break;
 
          case 2:
-           DPRINT1("SupplementaryVolumeDescriptor found!\n");
+           DPRINT("SupplementaryVolumeDescriptor found!\n");
            CdfsGetSVDData(Buffer, Vcb);
            break;
 
          case 3:
-           DPRINT1("VolumePartitionDescriptor found!\n");
+           DPRINT("VolumePartitionDescriptor found!\n");
            break;
 
          case 255:
-           DPRINT1("VolumeDescriptorSetTerminator found!\n");
+           DPRINT("VolumeDescriptorSetTerminator found!\n");
            break;
 
          default:
-           DPRINT1("VolumeDescriptor type %u found!\n", VdHeader->VdType);
+           DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
            break;
        }
 
@@ -219,7 +218,7 @@ CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
       return(STATUS_INSUFFICIENT_RESOURCES);
     }
 
-  DPRINT1("CDFS: Checking on mount of device %08x\n", DeviceToMount);
+  DPRINT("CDFS: Checking on mount of device %08x\n", DeviceToMount);
 
   Status = CdfsReadSectors(DeviceToMount,
                           CDFS_PRIMARY_DESCRIPTOR_LOCATION,
@@ -231,7 +230,7 @@ CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
     }
 
   Buffer[6] = 0;
-  DPRINT1("CD-identifier: [%.5s]\n", Buffer + 1);
+  DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
 
   Status = (Buffer[0] == 1 &&
            Buffer[1] == 'C' &&
@@ -258,7 +257,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
   PCCB Ccb = NULL;
   NTSTATUS Status;
 
-  DPRINT1("CdfsMountVolume() called\n");
+  DPRINT("CdfsMountVolume() called\n");
 
   if (DeviceObject != CdfsGlobalData->DeviceObject)
     {
@@ -367,7 +366,7 @@ ByeBye:
        IoDeleteDevice(NewDeviceObject);
     }
 
-  DPRINT1("CdfsMountVolume() done (Status: %lx)\n", Status);
+  DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
 
   return(Status);
 }
@@ -390,7 +389,7 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
       UCHAR Part[4];
     } Serial;
 
-  DPRINT1("CdfsVerifyVolume() called\n");
+  DPRINT("CdfsVerifyVolume() called\n");
 
   if (DeviceObject != CdfsGlobalData->DeviceObject)
     {
@@ -452,7 +451,7 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
       Serial.Part[3] += Buffer[i+0];
     }
 
-  DPRINT1("Current serial number %08lx  Vpb serial number %08lx\n",
+  DPRINT("Current serial number %08lx  Vpb serial number %08lx\n",
          Serial.Value, DeviceToVerify->Vpb->SerialNumber);
 
   if (Serial.Value == DeviceToVerify->Vpb->SerialNumber)
@@ -465,7 +464,7 @@ ByeBye:
 
 //  Status = STATUS_INVALID_DEVICE_REQUEST;
 
-  DPRINT1("CdfsVerifyVolume() done (Status: %lx)\n", Status);
+  DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status);
 
   return(Status);
 }
index 9a9f11c..410d301 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.2 2002/04/15 20:39:49 ekohl Exp $
+# $Id: makefile,v 1.3 2002/05/01 13:15:42 ekohl Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -7,7 +7,7 @@ TARGET_TYPE = driver
 TARGET_NAME = cdfs
 
 TARGET_OBJECTS = $(TARGET_NAME).o close.o common.o create.o dirctl.o \
-                 fcb.o finfo.o fsctl.o rw.o volinfo.o
+                 fcb.o finfo.o fsctl.o misc.o rw.o volinfo.o
 
 include $(PATH_TO_TOP)/rules.mak
 
diff --git a/reactos/drivers/fs/cdfs/misc.c b/reactos/drivers/fs/cdfs/misc.c
new file mode 100644 (file)
index 0000000..72b489c
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *  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: misc.c,v 1.1 2002/05/01 13:15:42 ekohl Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * FILE:             services/fs/cdfs/misc.c
+ * PURPOSE:          CDROM (ISO 9660) filesystem driver
+ * PROGRAMMER:       Eric Kohl
+ * UPDATE HISTORY: 
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "cdfs.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+
+BOOLEAN
+wstrcmpjoki(PWSTR s1,
+           PWSTR s2)
+/*
+ * FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
+ * return TRUE if s1 like s2
+ */
+{
+  while ((*s2=='*')||(*s2=='?')||(towlower(*s1)==towlower(*s2)))
+    {
+      if ((*s1)==0 && (*s2)==0)
+        return(TRUE);
+
+      if(*s2=='*')
+       {
+         s2++;
+         while (*s1)
+           if (wstrcmpjoki(s1,s2))
+             return(TRUE);
+           else
+             s1++;
+       }
+      else
+       {
+         s1++;
+         s2++;
+       }
+    }
+
+  if ((*s2)=='.')
+    {
+      for (;((*s2)=='.')||((*s2)=='*')||((*s2)=='?');s2++)
+       ;
+    }
+
+  if ((*s1)==0 && (*s2)==0)
+    return(TRUE);
+
+  return(FALSE);
+}
+
+
+VOID
+CdfsSwapString(PWCHAR Out,
+              PUCHAR In,
+              ULONG Count)
+{
+  PUCHAR t = (PUCHAR)Out;
+  ULONG i;
+
+  for (i = 0; i < Count; i += 2)
+    {
+      t[i] = In[i+1];
+      t[i+1] = In[i];
+    }
+  t[i] = 0;
+  t[i+1] = 0;
+}
+
+
+VOID
+CdfsDateTimeToFileTime(PFCB Fcb,
+                      TIME *FileTime)
+{
+  TIME_FIELDS TimeFields;
+
+  TimeFields.Milliseconds = 0;
+  TimeFields.Second = Fcb->Entry.Second;
+  TimeFields.Minute = Fcb->Entry.Minute;
+  TimeFields.Hour = Fcb->Entry.Hour;
+
+  TimeFields.Day = Fcb->Entry.Day;
+  TimeFields.Month = Fcb->Entry.Month;
+  TimeFields.Year = Fcb->Entry.Year + 1900;
+
+  RtlTimeFieldsToTime(&TimeFields,
+                     (PLARGE_INTEGER)FileTime);
+}
+
+
+VOID
+CdfsFileFlagsToAttributes(PFCB Fcb,
+                         PULONG FileAttributes)
+{
+  /* FIXME: Fix attributes */
+
+  *FileAttributes = // FILE_ATTRIBUTE_READONLY |
+                   (Fcb->Entry.FileFlags & 0x01) ? FILE_ATTRIBUTE_HIDDEN : 0 |
+                   (Fcb->Entry.FileFlags & 0x02) ? FILE_ATTRIBUTE_DIRECTORY : 0 |
+                   (Fcb->Entry.FileFlags & 0x04) ? FILE_ATTRIBUTE_SYSTEM : 0 |
+                   (Fcb->Entry.FileFlags & 0x10) ? FILE_ATTRIBUTE_READONLY : 0;
+}
+
+/* EOF */
\ No newline at end of file