Fixed FCB management functions.

Added file and directory information.
Fixed several minor bugs.
Disabled most of the debug messages.

svn path=/trunk/; revision=2900
This commit is contained in:
Eric Kohl 2002-05-01 13:15:42 +00:00
parent 467e8c55cc
commit 7e9f288b08
9 changed files with 793 additions and 492 deletions

View file

@ -314,6 +314,23 @@ NTSTATUS STDCALL
CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject, CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp); 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 */ /* rw.c */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -30,7 +30,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
//#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cdfs.h" #include "cdfs.h"
@ -85,7 +85,7 @@ CdfsClose(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
NTSTATUS Status; NTSTATUS Status;
DPRINT1("CdfsClose() called\n"); DPRINT("CdfsClose() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject; FileObject = Stack->FileObject;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -30,7 +30,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
//#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cdfs.h" #include "cdfs.h"
@ -38,47 +38,46 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
#if 0 static NTSTATUS
NTSTATUS CdfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject,
vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, PWSTR pRelativeFileName,
PWSTR pRelativeFileName, PWSTR *pAbsoluteFilename)
PWSTR *pAbsoluteFilename)
{ {
PWSTR rcName; PWSTR rcName;
PVFATFCB fcb; PFCB Fcb;
PVFATCCB ccb; PCCB Ccb;
DPRINT ("try related for %S\n", pRelativeFileName); DPRINT("try related for %S\n", pRelativeFileName);
ccb = pFileObject->FsContext2; Ccb = pFileObject->FsContext2;
assert (ccb); assert(Ccb);
fcb = ccb->pFcb; Fcb = Ccb->Fcb;
assert (fcb); assert(Fcb);
/* verify related object is a directory and target name /* verify related object is a directory and target name
don't start with \. */ don't start with \. */
if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) if (Fcb->Entry.FileFlags & 0x02 == 0 ||
|| (pRelativeFileName[0] == L'\\')) pRelativeFileName[0] == L'\\')
{ {
return STATUS_INVALID_PARAMETER; return(STATUS_INVALID_PARAMETER);
} }
/* construct absolute path name */ /* construct absolute path name */
assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1 assert(wcslen (Fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
<= MAX_PATH); <= MAX_PATH);
rcName = ExAllocatePool (NonPagedPool, MAX_PATH * sizeof(WCHAR)); rcName = ExAllocatePool(NonPagedPool, MAX_PATH * sizeof(WCHAR));
if (!rcName) if (!rcName)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return(STATUS_INSUFFICIENT_RESOURCES);
} }
wcscpy (rcName, fcb->PathName);
if (!vfatFCBIsRoot(fcb)) wcscpy(rcName, Fcb->PathName);
if (!CdfsFCBIsRoot(Fcb))
wcscat (rcName, L"\\"); wcscat (rcName, L"\\");
wcscat (rcName, pRelativeFileName); wcscat (rcName, pRelativeFileName);
*pAbsoluteFilename = rcName; *pAbsoluteFilename = rcName;
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
#endif
static NTSTATUS static NTSTATUS
@ -99,8 +98,8 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
if (FileObject->RelatedFileObject) if (FileObject->RelatedFileObject)
{ {
DPRINT("Converting relative filename to absolute filename\n"); DPRINT("Converting relative filename to absolute filename\n");
#if 0
Status = vfatMakeAbsoluteFilename(FileObject->RelatedFileObject, Status = CdfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
FileName, FileName,
&AbsFileName); &AbsFileName);
FileName = AbsFileName; FileName = AbsFileName;
@ -108,7 +107,6 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
{ {
return(Status); return(Status);
} }
#endif
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -122,7 +120,7 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
FileName); FileName);
if (Fcb == NULL) 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, Status = CdfsGetFCBForFile(DeviceExt,
&ParentFcb, &ParentFcb,
&Fcb, &Fcb,
@ -174,7 +172,7 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
// PWSTR FileName; // PWSTR FileName;
NTSTATUS Status; NTSTATUS Status;
DPRINT1("CdfsCreateFile() called\n"); DPRINT("CdfsCreateFile() called\n");
DeviceExt = DeviceObject->DeviceExtension; DeviceExt = DeviceObject->DeviceExtension;
assert (DeviceExt); assert (DeviceExt);
@ -199,37 +197,10 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
* If the directory containing the file to open doesn't exist then * If the directory containing the file to open doesn't exist then
* fail immediately * fail immediately
*/ */
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 0;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
return(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
} }

View file

@ -16,13 +16,14 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/dirctl.c * FILE: services/fs/cdfs/dirctl.c
* PURPOSE: CDROM (ISO 9660) filesystem driver * PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes * PROGRAMMER: Art Yerkes
* Eric Kohl
* UPDATE HISTORY: * UPDATE HISTORY:
*/ */
@ -38,87 +39,7 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS
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
CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt, CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
PVOID Block, PVOID Block,
ULONG BlockLength, ULONG BlockLength,
@ -190,7 +111,7 @@ CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
} }
NTSTATUS static NTSTATUS
CdfsFindFile(PDEVICE_EXTENSION DeviceExt, CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
PFCB Fcb, PFCB Fcb,
PFCB Parent, PFCB Parent,
@ -220,8 +141,10 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
PUCHAR Ptr; PUCHAR Ptr;
PDIR_RECORD Record; PDIR_RECORD Record;
DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0); DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n",
DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName); Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",
Fcb->PathName, Fcb->ObjectName);
IsRoot = FALSE; IsRoot = FALSE;
DirIndex = 0; DirIndex = 0;
@ -321,7 +244,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
break; break;
} }
// DPRINT("Name '%S'\n", name); DPRINT("Name '%S'\n", name);
if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */ if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */
{ {
@ -350,7 +273,8 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
if (pDirIndex) if (pDirIndex)
*pDirIndex = DirIndex; *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); ExFreePool(block);
@ -378,16 +302,14 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
static NTSTATUS static NTSTATUS
CdfsGetBothInformation(PFCB Fcb, CdfsGetNameInformation(PFCB Fcb,
PDEVICE_EXTENSION DeviceExt, PDEVICE_EXTENSION DeviceExt,
PFILE_BOTH_DIRECTORY_INFORMATION Info, PFILE_NAMES_INFORMATION Info,
ULONG BufferLength) ULONG BufferLength)
{ {
// short i;
// ULONGLONG AllocSize;
ULONG Length; ULONG Length;
DPRINT("FileBothDirectoryInformation() called\n"); DPRINT("CdfsGetNameInformation() called\n");
Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR); Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength) if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
@ -398,7 +320,28 @@ CdfsGetBothInformation(PFCB Fcb,
ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4); ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
memcpy(Info->FileName, Fcb->ObjectName, Length); memcpy(Info->FileName, Fcb->ObjectName, Length);
// Info->FileIndex=; 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 */ /* Convert file times */
CdfsDateTimeToFileTime(Fcb, CdfsDateTimeToFileTime(Fcb,
@ -410,38 +353,126 @@ CdfsGetBothInformation(PFCB Fcb,
CdfsDateTimeToFileTime(Fcb, CdfsDateTimeToFileTime(Fcb,
&Info->ChangeTime); &Info->ChangeTime);
/* Convert file flags */
CdfsFileFlagsToAttributes(Fcb,
&Info->FileAttributes);
Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL; Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
/* Make AllocSize a rounded up multiple of the sector size */ /* 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); Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
/* FIXME: Convert file flags to file attributes */ // Info->FileIndex=;
Info->FileAttributes = (Fcb->Entry.FileFlags & 0x02) ? FILE_ATTRIBUTE_DIRECTORY : 0;
Info->EaSize = 0;
/* FIXME: Copy or create a short file name */ return(STATUS_SUCCESS);
#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;
} }
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);
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;
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 static NTSTATUS
CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
@ -547,29 +578,31 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FileNameInformation: case FileNameInformation:
DPRINT1("FileNameInformation\n"); Status = CdfsGetNameInformation(&TempFcb,
// Status = VfatGetFileNameInformation(&TempFcb, DeviceExtension,
// (PFILE_NAMES_INFORMATION) Buffer, BufferLength); (PFILE_NAMES_INFORMATION)Buffer,
// break; BufferLength);
break;
case FileDirectoryInformation: case FileDirectoryInformation:
DPRINT1("FileDirectoryInformation\n"); Status = CdfsGetDirectoryInformation(&TempFcb,
// Status = VfatGetFileDirectoryInformation(&TempFcb, DeviceExtension, DeviceExtension,
// (PFILE_DIRECTORY_INFORMATION) Buffer, BufferLength); (PFILE_DIRECTORY_INFORMATION)Buffer,
BufferLength);
break; break;
case FileFullDirectoryInformation: case FileFullDirectoryInformation:
DPRINT1("FileFullDirecrotyInformation\n"); Status = CdfsGetFullDirectoryInformation(&TempFcb,
// Status = CdfsGetFullDirectoryInformation(&TempFcb, DeviceExtension,
// DeviceExtension, (PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
// (PFILE_FULL_DIRECTORY_INFORMATION)Buffer, BufferLength); BufferLength);
break; break;
case FileBothDirectoryInformation: case FileBothDirectoryInformation:
Status = CdfsGetBothInformation(&TempFcb, Status = CdfsGetBothDirectoryInformation(&TempFcb,
DeviceExtension, DeviceExtension,
(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer, (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
BufferLength); BufferLength);
break; break;
default: default:

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -30,7 +30,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
//#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cdfs.h" #include "cdfs.h"
@ -46,6 +46,31 @@
/* FUNCTIONS ****************************************************************/ /* 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 PFCB
CdfsCreateFCB(PWSTR FileName) CdfsCreateFCB(PWSTR FileName)
{ {
@ -162,7 +187,7 @@ CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
if (FileName == NULL || *FileName == 0) 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 = ((PCCB)Vcb->StreamFileObject->FsContext2)->Fcb;
Fcb->RefCount++; Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
@ -174,8 +199,8 @@ CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb,
{ {
Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry); Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry);
// if (wstrcmpi(FileName, Fcb->PathName)) DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName);
if (_wcsicmp(FileName, Fcb->PathName)) if (_wcsicmp(FileName, Fcb->PathName) == 0)
{ {
Fcb->RefCount++; Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
@ -277,79 +302,94 @@ CdfsOpenRootFCB(PDEVICE_EXTENSION Vcb)
} }
#if 0 static VOID
NTSTATUS CdfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt,
vfatMakeFCBFromDirEntry(PVCB vcb, PDIR_RECORD Record,
PVFATFCB directoryFCB, PWSTR Name)
PWSTR longName, /*
PFAT_DIR_ENTRY dirEntry, * FUNCTION: Retrieves the file name, be it in short or long file name format
ULONG dirIndex, */
PVFATFCB * fileFCB)
{ {
PVFATFCB rcFCB; if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
WCHAR pathName [MAX_PATH]; {
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
CdfsMakeFCBFromDirEntry(PVCB Vcb,
PFCB DirectoryFCB,
PWSTR Name,
PDIR_RECORD Record,
PFCB * fileFCB)
{
WCHAR pathName[MAX_PATH];
PFCB rcFCB;
ULONG Size; 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); if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
wcscat (pathName, entryName); sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
} {
rcFCB = vfatNewFCB (pathName); return(STATUS_OBJECT_NAME_INVALID);
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY)); }
if (vfatFCBIsDirectory(vcb, rcFCB)) wcscpy(pathName, DirectoryFCB->PathName);
{ if (!CdfsFCBIsRoot(DirectoryFCB))
ULONG FirstCluster, CurrentCluster;
NTSTATUS Status;
Size = 0;
FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
if (FirstCluster == 1)
{ {
Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE; wcscat(pathName, L"\\");
} }
else
if (Name[0] != 0)
{ {
CurrentCluster = FirstCluster; wcscat(pathName, Name);
while (CurrentCluster != 0xffffffff)
{
Size += vcb->FatInfo.BytesPerCluster;
Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
}
} }
}
else else
{ {
Size = rcFCB->entry.FileSize; WCHAR entryName[MAX_PATH];
}
rcFCB->dirIndex = dirIndex; 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.FileSize.QuadPart = Size;
rcFCB->RFCB.ValidDataLength.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); // DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
vfatFCBInitializeCache (vcb, rcFCB); CdfsFCBInitializeCache(Vcb, rcFCB);
rcFCB->RefCount++; rcFCB->RefCount++;
vfatAddFCBToTable (vcb, rcFCB); CdfsAddFCBToTable(Vcb, rcFCB);
*fileFCB = rcFCB; *fileFCB = rcFCB;
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
#endif
NTSTATUS NTSTATUS
CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb, CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
@ -359,7 +399,7 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
NTSTATUS Status; NTSTATUS Status;
PCCB newCCB; PCCB newCCB;
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof(CCB), TAG_CCB); newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
if (newCCB == NULL) if (newCCB == NULL)
{ {
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
@ -393,99 +433,111 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
#if 0
NTSTATUS NTSTATUS
vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
PVFATFCB pDirectoryFCB, PFCB DirectoryFcb,
PWSTR pFileToFind, PWSTR FileToFind,
PVFATFCB * pFoundFCB) PFCB *FoundFCB)
{ {
BOOL finishedScanningDirectory; WCHAR TempName[2];
ULONG directoryIndex; WCHAR Name[256];
NTSTATUS status; PUCHAR Block;
WCHAR defaultFileName [2]; ULONG FirstSector;
WCHAR currentLongName [256]; ULONG DirSize;
FAT_DIR_ENTRY currentDirEntry; ULONG BufferSize;
WCHAR currentEntryName [256]; ULONG SectorCount;
PDIR_RECORD Record;
ULONG Offset;
NTSTATUS Status;
assert (pDeviceExt); assert(DeviceExt);
assert (pDirectoryFCB); assert(DirectoryFcb);
assert (pFileToFind); assert(FileToFind);
DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n", DPRINT("CdfsDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
pDeviceExt, DeviceExt,
pDirectoryFCB, DirectoryFcb,
pFileToFind); FileToFind);
DPRINT ("Dir Path:%S\n", pDirectoryFCB->PathName); DPRINT("Dir Path:%S\n", DirectoryFcb->PathName);
// default to '.' if no filename specified /* default to '.' if no filename specified */
if (wcslen (pFileToFind) == 0) if (wcslen(FileToFind) == 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)
{ {
finishedScanningDirectory = TRUE; TempName[0] = L'.';
continue; TempName[1] = 0;
} FileToFind = TempName;
else if (!NT_SUCCESS(status))
{
return status;
} }
DPRINT (" Index:%d longName:%S\n", FirstSector = DirectoryFcb->Entry.ExtentLocationL;
directoryIndex, DirSize = DirectoryFcb->Entry.DataLengthL;
currentLongName);
if (!vfatIsDirEntryDeleted (&currentDirEntry) BufferSize = ROUND_UP(DirSize, BLOCKSIZE);
&& !vfatIsDirEntryVolume(&currentDirEntry)) 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))
{ {
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind)) DPRINT("Reading directory extent failed (Status %lx)\n", Status);
{ ExFreePool(Block);
DPRINT ("Match found, %S\n", currentLongName); return(Status);
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;
}
}
} }
}
return STATUS_OBJECT_NAME_NOT_FOUND; Offset = 0;
Record = (PDIR_RECORD)Block;
while(TRUE)
{
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;
}
ExFreePool(Block);
return(STATUS_OBJECT_NAME_NOT_FOUND);
} }
#endif
NTSTATUS NTSTATUS
@ -494,7 +546,7 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
PFCB *pFCB, PFCB *pFCB,
const PWSTR pFileName) const PWSTR pFileName)
{ {
NTSTATUS status; NTSTATUS Status;
WCHAR pathName [MAX_PATH]; WCHAR pathName [MAX_PATH];
WCHAR elementName [MAX_PATH]; WCHAR elementName [MAX_PATH];
PWCHAR currentElement; PWCHAR currentElement;
@ -518,11 +570,6 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND); return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
} }
DPRINT1("CdfsGetFCBForFile() is incomplete!\n");
return(STATUS_UNSUCCESSFUL);
#if 0
else else
{ {
currentElement = pFileName + 1; currentElement = pFileName + 1;
@ -531,85 +578,85 @@ CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
} }
parentFCB = NULL; parentFCB = NULL;
// Parse filename and check each path element for existance and access /* Parse filename and check each path element for existance and access */
while (vfatGetNextPathElement (currentElement) != 0) while (CdfsGetNextPathElement(currentElement) != 0)
{
// Skip blank directory levels
if ((vfatGetNextPathElement (currentElement) - currentElement) == 0)
{ {
currentElement++; /* Skip blank directory levels */
continue; if ((CdfsGetNextPathElement(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)
{
CdfsReleaseFCB(Vcb, parentFCB);
parentFCB = NULL;
}
/* fail if element in FCB is not a directory */
if (!CdfsFCBIsDirectory(FCB))
{
DPRINT("Element in requested path is not a directory\n");
CdfsReleaseFCB(Vcb, FCB);
FCB = 0;
*pParentFCB = NULL;
*pFCB = NULL;
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
parentFCB = FCB;
/* 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);
} }
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; *pParentFCB = parentFCB;
*pFCB = FCB; *pFCB = FCB;
return STATUS_SUCCESS; return(STATUS_SUCCESS);
#endif
} }
/* EOF */ /* EOF */

View file

@ -16,13 +16,14 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/dirctl.c * FILE: services/fs/cdfs/dirctl.c
* PURPOSE: CDROM (ISO 9660) filesystem driver * PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes * PROGRAMMER: Art Yerkes
* Eric Kohl
* UPDATE HISTORY: * UPDATE HISTORY:
*/ */
@ -30,7 +31,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
//#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cdfs.h" #include "cdfs.h"
@ -39,34 +40,113 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS static NTSTATUS
CdfsQueryNameInformation(PFILE_OBJECT FileObject, CdfsGetStandardInformation(PFCB Fcb,
PFCB Fcb, PDEVICE_OBJECT DeviceObject,
PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo,
PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
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 * FUNCTION: Retrieve the file name information
*/ */
{ {
ULONG NameLength; ULONG NameLength;
assert (NameInfo != NULL); DPRINT("CdfsGetNameInformation() called\n");
assert (Fcb != NULL);
#if 0 assert(NameInfo != NULL);
NameLength = wcslen(FCB->PathName) * sizeof(WCHAR); assert(Fcb != NULL);
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength) if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
NameInfo->FileNameLength = NameLength; NameInfo->FileNameLength = NameLength;
memcpy(NameInfo->FileName, memcpy(NameInfo->FileName,
FCB->PathName, Fcb->PathName,
NameLength + sizeof(WCHAR)); NameLength + sizeof(WCHAR));
#endif
/* Fake name */
NameLength = 2;
wcscpy(NameInfo->FileName, L"\\");
*BufferLength -= *BufferLength -=
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)); (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 NTSTATUS STDCALL
CdfsQueryInformation(PDEVICE_OBJECT DeviceObject, CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
@ -91,7 +193,7 @@ CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("CdfsQueryInformation() called\n"); DPRINT("CdfsQueryInformation() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass; FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
@ -103,49 +205,46 @@ CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
switch (FileInformationClass) switch (FileInformationClass)
{ {
#if 0
case FileStandardInformation: case FileStandardInformation:
Status = CdfsGetStandardInformation(Fcb, Status = CdfsGetStandardInformation(Fcb,
IrpContext->DeviceObject, DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; 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: case FilePositionInformation:
Status = CdfsQueryNameInformation(FileObject, Status = CdfsGetPositionInformation(FileObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
Status = CdfsGetBasicInformation(FileObject,
Fcb, Fcb,
DeviceObject, DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
#if 0 case FileNameInformation:
Status = CdfsGetNameInformation(FileObject,
Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation: case FileInternalInformation:
Status = CdfsGetInternalInformation(Fcb, Status = CdfsGetInternalInformation(Fcb,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileAlternateNameInformation: case FileAlternateNameInformation:
case FileAllInformation: case FileAllInformation:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
break; break;
#endif
default: default:
DPRINT("Unimplemented information class %u\n", FileInformationClass); DPRINT("Unimplemented information class %u\n", FileInformationClass);
Status = STATUS_NOT_SUPPORTED; Status = STATUS_NOT_SUPPORTED;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -30,7 +30,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
//#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cdfs.h" #include "cdfs.h"
@ -82,12 +82,12 @@ CdfsGetPVDData(PUCHAR Buffer,
Vcb->CdInfo.RootStart = Pvd->RootDirRecord.ExtentLocationL; Vcb->CdInfo.RootStart = Pvd->RootDirRecord.ExtentLocationL;
Vcb->CdInfo.RootSize = Pvd->RootDirRecord.DataLengthL; Vcb->CdInfo.RootSize = Pvd->RootDirRecord.DataLengthL;
DPRINT1("VolumeSerial: %08lx\n", Vpb->SerialNumber); DPRINT("VolumeSerial: %08lx\n", Vpb->SerialNumber);
DPRINT1("VolumeLabel: '%S'\n", Vpb->VolumeLabel); DPRINT("VolumeLabel: '%S'\n", Vpb->VolumeLabel);
DPRINT1("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength); DPRINT("VolumeLabelLength: %lu\n", Vpb->VolumeLabelLength);
DPRINT1("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL); DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
DPRINT1("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL); DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
DPRINT1("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL); DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
} }
@ -104,17 +104,17 @@ CdfsGetSVDData(PUCHAR Buffer,
if (strncmp(Svd->EscapeSequences, "%/@", 3) == 0) 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; JolietLevel = 1;
} }
else if (strncmp(Svd->EscapeSequences, "%/C", 3) == 0) 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; JolietLevel = 2;
} }
else if (strncmp(Svd->EscapeSequences, "%/E", 3) == 0) 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; JolietLevel = 3;
} }
@ -127,8 +127,8 @@ CdfsGetSVDData(PUCHAR Buffer,
Vcb->CdInfo.RootStart = Svd->RootDirRecord.ExtentLocationL; Vcb->CdInfo.RootStart = Svd->RootDirRecord.ExtentLocationL;
Vcb->CdInfo.RootSize = Svd->RootDirRecord.DataLengthL; Vcb->CdInfo.RootSize = Svd->RootDirRecord.DataLengthL;
DPRINT1("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL); DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
DPRINT1("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL); DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
} }
//#endif //#endif
} }
@ -143,7 +143,6 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
ULONG Sector; ULONG Sector;
PVD_HEADER VdHeader; PVD_HEADER VdHeader;
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
Buffer = ExAllocatePool(NonPagedPool, Buffer = ExAllocatePool(NonPagedPool,
@ -166,29 +165,29 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
switch (VdHeader->VdType) switch (VdHeader->VdType)
{ {
case 0: case 0:
DPRINT1("BootVolumeDescriptor found!\n"); DPRINT("BootVolumeDescriptor found!\n");
break; break;
case 1: case 1:
DPRINT1("PrimaryVolumeDescriptor found!\n"); DPRINT("PrimaryVolumeDescriptor found!\n");
CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb); CdfsGetPVDData(Buffer, Vcb, DeviceObject->Vpb);
break; break;
case 2: case 2:
DPRINT1("SupplementaryVolumeDescriptor found!\n"); DPRINT("SupplementaryVolumeDescriptor found!\n");
CdfsGetSVDData(Buffer, Vcb); CdfsGetSVDData(Buffer, Vcb);
break; break;
case 3: case 3:
DPRINT1("VolumePartitionDescriptor found!\n"); DPRINT("VolumePartitionDescriptor found!\n");
break; break;
case 255: case 255:
DPRINT1("VolumeDescriptorSetTerminator found!\n"); DPRINT("VolumeDescriptorSetTerminator found!\n");
break; break;
default: default:
DPRINT1("VolumeDescriptor type %u found!\n", VdHeader->VdType); DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
break; break;
} }
@ -219,7 +218,7 @@ CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
return(STATUS_INSUFFICIENT_RESOURCES); 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, Status = CdfsReadSectors(DeviceToMount,
CDFS_PRIMARY_DESCRIPTOR_LOCATION, CDFS_PRIMARY_DESCRIPTOR_LOCATION,
@ -231,7 +230,7 @@ CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
} }
Buffer[6] = 0; Buffer[6] = 0;
DPRINT1("CD-identifier: [%.5s]\n", Buffer + 1); DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
Status = (Buffer[0] == 1 && Status = (Buffer[0] == 1 &&
Buffer[1] == 'C' && Buffer[1] == 'C' &&
@ -258,7 +257,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
PCCB Ccb = NULL; PCCB Ccb = NULL;
NTSTATUS Status; NTSTATUS Status;
DPRINT1("CdfsMountVolume() called\n"); DPRINT("CdfsMountVolume() called\n");
if (DeviceObject != CdfsGlobalData->DeviceObject) if (DeviceObject != CdfsGlobalData->DeviceObject)
{ {
@ -367,7 +366,7 @@ ByeBye:
IoDeleteDevice(NewDeviceObject); IoDeleteDevice(NewDeviceObject);
} }
DPRINT1("CdfsMountVolume() done (Status: %lx)\n", Status); DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
return(Status); return(Status);
} }
@ -390,7 +389,7 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
UCHAR Part[4]; UCHAR Part[4];
} Serial; } Serial;
DPRINT1("CdfsVerifyVolume() called\n"); DPRINT("CdfsVerifyVolume() called\n");
if (DeviceObject != CdfsGlobalData->DeviceObject) if (DeviceObject != CdfsGlobalData->DeviceObject)
{ {
@ -452,7 +451,7 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
Serial.Part[3] += Buffer[i+0]; 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); Serial.Value, DeviceToVerify->Vpb->SerialNumber);
if (Serial.Value == DeviceToVerify->Vpb->SerialNumber) if (Serial.Value == DeviceToVerify->Vpb->SerialNumber)
@ -465,7 +464,7 @@ ByeBye:
// Status = STATUS_INVALID_DEVICE_REQUEST; // Status = STATUS_INVALID_DEVICE_REQUEST;
DPRINT1("CdfsVerifyVolume() done (Status: %lx)\n", Status); DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status);
return(Status); return(Status);
} }

View 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 = ../../.. PATH_TO_TOP = ../../..
@ -7,7 +7,7 @@ TARGET_TYPE = driver
TARGET_NAME = cdfs TARGET_NAME = cdfs
TARGET_OBJECTS = $(TARGET_NAME).o close.o common.o create.o dirctl.o \ 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 include $(PATH_TO_TOP)/rules.mak

View file

@ -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 */