From 7e9f288b08f61909b65183be846b70de9565036e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 1 May 2002 13:15:42 +0000 Subject: [PATCH] Fixed FCB management functions. 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 | 17 ++ reactos/drivers/fs/cdfs/close.c | 6 +- reactos/drivers/fs/cdfs/create.c | 97 +++--- reactos/drivers/fs/cdfs/dirctl.c | 295 ++++++++++--------- reactos/drivers/fs/cdfs/fcb.c | 491 +++++++++++++++++-------------- reactos/drivers/fs/cdfs/finfo.c | 187 +++++++++--- reactos/drivers/fs/cdfs/fsctl.c | 53 ++-- reactos/drivers/fs/cdfs/makefile | 4 +- reactos/drivers/fs/cdfs/misc.c | 135 +++++++++ 9 files changed, 793 insertions(+), 492 deletions(-) create mode 100644 reactos/drivers/fs/cdfs/misc.c diff --git a/reactos/drivers/fs/cdfs/cdfs.h b/reactos/drivers/fs/cdfs/cdfs.h index 40798877a84..c8861ab8c0a 100644 --- a/reactos/drivers/fs/cdfs/cdfs.h +++ b/reactos/drivers/fs/cdfs/cdfs.h @@ -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 */ diff --git a/reactos/drivers/fs/cdfs/close.c b/reactos/drivers/fs/cdfs/close.c index 686c9462fd5..993513ef3f4 100644 --- a/reactos/drivers/fs/cdfs/close.c +++ b/reactos/drivers/fs/cdfs/close.c @@ -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 -//#define NDEBUG +#define NDEBUG #include #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; diff --git a/reactos/drivers/fs/cdfs/create.c b/reactos/drivers/fs/cdfs/create.c index 49810da5811..c141eecafa5 100644 --- a/reactos/drivers/fs/cdfs/create.c +++ b/reactos/drivers/fs/cdfs/create.c @@ -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 -//#define NDEBUG +#define NDEBUG #include #include "cdfs.h" @@ -38,47 +38,46 @@ /* 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 } diff --git a/reactos/drivers/fs/cdfs/dirctl.c b/reactos/drivers/fs/cdfs/dirctl.c index 419087743bc..1e9e31ccacb 100644 --- a/reactos/drivers/fs/cdfs/dirctl.c +++ b/reactos/drivers/fs/cdfs/dirctl.c @@ -16,13 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: 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: */ @@ -38,87 +39,7 @@ /* 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,7 +320,28 @@ CdfsGetBothInformation(PFCB Fcb, ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4); 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 */ CdfsDateTimeToFileTime(Fcb, @@ -410,38 +353,126 @@ 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->EaSize = 0; +// Info->FileIndex=; - /* 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 +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 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: diff --git a/reactos/drivers/fs/cdfs/fcb.c b/reactos/drivers/fs/cdfs/fcb.c index e0958200ea1..5621134c55a 100644 --- a/reactos/drivers/fs/cdfs/fcb.c +++ b/reactos/drivers/fs/cdfs/fcb.c @@ -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 -//#define NDEBUG +#define NDEBUG #include #include "cdfs.h" @@ -46,6 +46,31 @@ /* 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 -NTSTATUS -vfatMakeFCBFromDirEntry(PVCB vcb, - PVFATFCB directoryFCB, - PWSTR longName, - PFAT_DIR_ENTRY dirEntry, - ULONG dirIndex, - PVFATFCB * fileFCB) +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 + */ { - PVFATFCB rcFCB; - WCHAR pathName [MAX_PATH]; + 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 +CdfsMakeFCBFromDirEntry(PVCB Vcb, + PFCB DirectoryFCB, + PWSTR Name, + PDIR_RECORD Record, + PFCB * fileFCB) +{ + 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 (Name [0] != 0 && wcslen (DirectoryFCB->PathName) + + sizeof(WCHAR) + wcslen (Name) > MAX_PATH) + { + return(STATUS_OBJECT_NAME_INVALID); + } - if (vfatFCBIsDirectory(vcb, rcFCB)) - { - ULONG FirstCluster, CurrentCluster; - NTSTATUS Status; - Size = 0; - FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry); - if (FirstCluster == 1) + 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]; + WCHAR TempName[2]; + WCHAR Name[256]; + PUCHAR Block; + ULONG FirstSector; + ULONG DirSize; + ULONG BufferSize; + ULONG SectorCount; + PDIR_RECORD Record; + ULONG Offset; + NTSTATUS Status; - assert (pDeviceExt); - assert (pDirectoryFCB); - assert (pFileToFind); + assert(DeviceExt); + assert(DirectoryFcb); + assert(FileToFind); - DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n", - pDeviceExt, - pDirectoryFCB, - pFileToFind); - DPRINT ("Dir Path:%S\n", pDirectoryFCB->PathName); + 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 (pFileToFind) == 0) - { - defaultFileName [0] = L'.'; - defaultFileName [1] = 0; - pFileToFind = defaultFileName; - } - - directoryIndex = 0; - finishedScanningDirectory = FALSE; - while (!finishedScanningDirectory) - { - status = vfatGetNextDirEntry (pDeviceExt, - pDirectoryFCB, - &directoryIndex, - currentLongName, - ¤tDirEntry); - if (status == STATUS_NO_MORE_ENTRIES) + /* default to '.' if no filename specified */ + if (wcslen(FileToFind) == 0) { - finishedScanningDirectory = TRUE; - continue; - } - else if (!NT_SUCCESS(status)) - { - return status; + TempName[0] = L'.'; + TempName[1] = 0; + FileToFind = TempName; } - DPRINT (" Index:%d longName:%S\n", - directoryIndex, - currentLongName); + FirstSector = DirectoryFcb->Entry.ExtentLocationL; + DirSize = DirectoryFcb->Entry.DataLengthL; - if (!vfatIsDirEntryDeleted (¤tDirEntry) - && !vfatIsDirEntryVolume(¤tDirEntry)) + 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)) { - if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind)) - { - DPRINT ("Match found, %S\n", currentLongName); - status = vfatMakeFCBFromDirEntry (pDeviceExt, - pDirectoryFCB, - currentLongName, - ¤tDirEntry, - directoryIndex - 1, - pFoundFCB); - return status; - } - else - { - vfatGetDirEntryName (¤tDirEntry, currentEntryName); - DPRINT (" entryName:%S\n", currentEntryName); - - if (wstrcmpjoki (currentEntryName, pFileToFind)) - { - DPRINT ("Match found, %S\n", currentEntryName); - status = vfatMakeFCBFromDirEntry (pDeviceExt, - pDirectoryFCB, - currentLongName, - ¤tDirEntry, - directoryIndex - 1, - pFoundFCB); - return status; - } - } + DPRINT("Reading directory extent failed (Status %lx)\n", Status); + ExFreePool(Block); + 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 @@ -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); + + /* 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; *pFCB = FCB; - return STATUS_SUCCESS; -#endif + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/drivers/fs/cdfs/finfo.c b/reactos/drivers/fs/cdfs/finfo.c index e71f6d3b4f0..be444471c34 100644 --- a/reactos/drivers/fs/cdfs/finfo.c +++ b/reactos/drivers/fs/cdfs/finfo.c @@ -16,13 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: 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 -//#define NDEBUG +#define NDEBUG #include #include "cdfs.h" @@ -39,34 +40,113 @@ /* 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; diff --git a/reactos/drivers/fs/cdfs/fsctl.c b/reactos/drivers/fs/cdfs/fsctl.c index 2c2a053c3ce..fdd5d33988c 100644 --- a/reactos/drivers/fs/cdfs/fsctl.c +++ b/reactos/drivers/fs/cdfs/fsctl.c @@ -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 -//#define NDEBUG +#define NDEBUG #include #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); } diff --git a/reactos/drivers/fs/cdfs/makefile b/reactos/drivers/fs/cdfs/makefile index 9a9f11c0da0..410d3018192 100644 --- a/reactos/drivers/fs/cdfs/makefile +++ b/reactos/drivers/fs/cdfs/makefile @@ -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 index 00000000000..72b489cd25e --- /dev/null +++ b/reactos/drivers/fs/cdfs/misc.c @@ -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 + +#define NDEBUG +#include + +#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