From 9cfc87e3336711918a562afe144cc909bca7bcdb Mon Sep 17 00:00:00 2001 From: Rex Jolliff Date: Thu, 10 May 2001 04:02:21 +0000 Subject: [PATCH] extracted a few more FCB funcs svn path=/trunk/; revision=1900 --- reactos/drivers/fs/vfat/close.c | 26 ++--- reactos/drivers/fs/vfat/fcb.c | 185 ++++++++++++++++++++++++++++++- reactos/drivers/fs/vfat/string.c | 44 +++++++- reactos/drivers/fs/vfat/vfat.h | 23 +++- 4 files changed, 252 insertions(+), 26 deletions(-) diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index 84dbc43f9b6..d6abd099977 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.6 2001/05/04 01:21:45 rex Exp $ +/* $Id: close.c,v 1.7 2001/05/10 04:02:21 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,7 +26,6 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) { PVFATFCB pFcb; PVFATCCB pCcb; - KIRQL oldIrql; DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); @@ -36,26 +35,15 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) DPRINT ("pCcb %x\n", pCcb); if (pCcb == NULL) - { - return (STATUS_SUCCESS); - } + { + return STATUS_SUCCESS; + } pFcb = pCcb->pFcb; - - pFcb->RefCount--; - CHECKPOINT; - if (pFcb->RefCount <= 0) - { - CcRosReleaseFileCache(FileObject, pFcb->RFCB.Bcb); - KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); - CHECKPOINT; - RemoveEntryList (&pFcb->FcbListEntry); - KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); - ExFreePool (pFcb); - CHECKPOINT; - } + vfatReleaseFCB (DeviceExt, pFcb); ExFreePool (pCcb); - return STATUS_SUCCESS; + + return STATUS_SUCCESS; } NTSTATUS STDCALL diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index f06d45256d7..edba651c99e 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -1,4 +1,4 @@ -/* $Id: fcb.c,v 1.1 2001/05/02 03:18:03 rex Exp $ +/* $Id: fcb.c,v 1.2 2001/05/10 04:02:21 rex Exp $ * * * FILE: fcb.c @@ -49,7 +49,12 @@ PVFATFCB vfatNewFCB (PWCHAR pFileName) return rcFCB; } -void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) +void vfatDestroyFCB (PVFATFCB pFCB) +{ + ExFreePool (pFCB); +} + +void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) { KIRQL oldIrql; @@ -64,10 +69,11 @@ void vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); pFCB->RefCount--; - if (pFCB->RefCount <= 0) + if (pFCB->RefCount <= 0 && !vfatFCBIsDirectory (pVCB, pFCB)) { RemoveEntryList (&pFCB->FcbListEntry); - ExFreePool (pFCB); + CcRosReleaseFileCache (NULL, pFCB->RFCB.Bcb); + vfatDestroyFCB (pFCB); } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); } @@ -108,3 +114,174 @@ PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, PWSTR pFileName) return NULL; } + +PVFATFCB +vfatMakeRootFCB (PDEVICE_EXTENSION pVCB) +{ + UNIMPLEMENTED; +} + +PVFATFCB +vfatOpenRootFCB (PDEVICE_EXTENSION pVCB) +{ + NTSTATUS status; + PVFATFCB FCB; + HANDLE fileHandle; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + UNICODE_STRING rootPath; + + FCB = vfatGrabFCBFromTable (pVCB, L"\\"); + if (FCB != NULL) + { + return FCB; + } + + RtlCreateUnicodeString (&rootPath, L"\\"); + objectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); + objectAttributes.RootDirectory = NULL; + objectAttributes.ObjectName = &rootPath; + objectAttributes.Attributes = OBJ_CASE_INSENSITIVE; + objectAttributes.SecurityDescriptor = NULL; + objectAttributes.SecurityQualityOfService = NULL; + + status = IoCreateFile(&fileHandle, + FILE_DIRECTORY_FILE | FILE_RANDOM_ACCESS | + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + &objectAttributes, + &ioStatusBlock, + NULL, + 0, + 0, + FILE_OPEN, + 0, + NULL, + 0, + 0, + NULL, + 0); + if (status != STATUS_SUCCESS) + { + return NULL; + } + FCB = vfatGrabFCBFromTable (pVCB, L"\\"); + ZwClose (fileHandle); + + return FCB; +} + +BOOL +vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB) +{ + return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY; +} + +PVFATFCB +vfatDirFindFile (PDEVICE_EXTENSION pVCB, + PVFATFCB parentFCB, + const PWSTR elementName) +{ + UNIMPLEMENTED; +} + +NTSTATUS +vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, + PVFATFCB *pParentFCB, + PVFATFCB *pFCB, + const PWSTR pFileName) +{ + WCHAR pathName [MAX_PATH]; + WCHAR elementName [MAX_PATH]; + PWCHAR currentElement; + PVFATFCB FCB; + PVFATFCB parentFCB; + + // Trivial case, open of the root directory on volume + if (pFileName [0] == L'\0' || wcscmp (pFileName, L"\\") == 0) + { + currentElement = pFileName; + //FIXME: grab/create root RCB and return it + FCB = vfatGrabFCBFromTable (pVCB, L"\\"); + if (FCB == NULL) + { + FCB = vfatMakeRootFCB (pVCB); + *pFCB = FCB; + *pParentFCB = NULL; + + return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND; + } + } + else + { + currentElement = pFileName + 1; + wcscpy (pathName, L"\\"); + FCB = vfatOpenRootFCB (pVCB); + } + parentFCB = NULL; + + // Parse filename and check each path element for existance and access + while (vfatGetNextPathElement (currentElement) != 0) + { + // Skip blank directory levels + if ((vfatGetNextPathElement (currentElement) - currentElement) == 0) + { + currentElement++; + continue; + } + + currentElement = vfatGetNextPathElement (currentElement); + + // 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)) + { + vfatReleaseFCB (pVCB, FCB); + FCB = 0; + return STATUS_OBJECT_PATH_NOT_FOUND; + } + parentFCB = FCB; + + // Extract next directory level into dirName + vfatWSubString (pathName, + pFileName, + vfatGetNextPathElement (currentElement) - pFileName); + + FCB = vfatGrabFCBFromTable (pVCB, pathName); + if (FCB == NULL) + { + vfatWSubString (elementName, + currentElement, + vfatGetNextPathElement (currentElement) - currentElement); + FCB = vfatDirFindFile (pVCB, parentFCB, elementName); + if (FCB == NULL) + { + *pParentFCB = parentFCB; + *pFCB = NULL; + if (vfatGetNextPathElement (currentElement) == 0) + { + return STATUS_OBJECT_NAME_NOT_FOUND; + } + else + { + return STATUS_OBJECT_PATH_NOT_FOUND; + } + } + + // FIXME: check security on directory element and fail if access denied + } + } + + *pParentFCB = parentFCB; + *pFCB = FCB; + + return STATUS_SUCCESS; +} + + + + diff --git a/reactos/drivers/fs/vfat/string.c b/reactos/drivers/fs/vfat/string.c index 732f23528d2..89ee847ec06 100644 --- a/reactos/drivers/fs/vfat/string.c +++ b/reactos/drivers/fs/vfat/string.c @@ -1,4 +1,4 @@ -/* $Id: string.c,v 1.6 2001/05/02 03:18:03 rex Exp $ +/* $Id: string.c,v 1.7 2001/05/10 04:02:21 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -148,3 +148,45 @@ BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2) return(FALSE); } +PWCHAR +vfatGetNextPathElement (PWCHAR pFileName) +{ + if (*pFileName != L'\0') + { + return 0; + } + + while (*pFileName != L'\0' && *pFileName != L'\\') + { + pFileName++; + } + + return pFileName; +} + +void +vfatWSubString (PWCHAR pTarget, const PWCHAR pSource, size_t pLength) +{ + wcsncpy (pTarget, pSource, pLength); + pTarget [pLength] = L'\0'; +} + +BOOL +vfatIsFileNameValid (PWCHAR pFileName) +{ + PWCHAR c; + + c = pFileName; + while (*c != 0) + { + if (*c == L'*' || *c == L'?') + { + return FALSE; + } + c++; + } + + return TRUE; +} + + diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index 5ee3d756f45..a64f0864e42 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -1,4 +1,4 @@ -/* $Id: vfat.h,v 1.28 2001/05/02 03:18:03 rex Exp $ */ +/* $Id: vfat.h,v 1.29 2001/05/10 04:02:21 rex Exp $ */ #include @@ -240,6 +240,9 @@ BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2); BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2); +PWCHAR vfatGetNextPathElement (PWCHAR pFileName); +void vfatWSubString (PWCHAR pTarget, const PWCHAR pSource, size_t pLength); +BOOL vfatIsFileNameValid (PWCHAR pFileName); /* * functions from fat.c @@ -283,8 +286,24 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, /* ----------------------------------------------------- FCB Functions */ PVFATFCB vfatNewFCB (PWCHAR pFileName); -void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); +void vfatDestroyFCB (PVFATFCB pFCB); +void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); +void vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); +void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB, + PVFATFCB pFCB); PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, PWSTR pFileName); +PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB); +PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB); +BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB); +PVFATFCB vfatDirFindFile (PDEVICE_EXTENSION pVCB, + PVFATFCB parentFCB, + const PWSTR elementName); +NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, + PVFATFCB *pParentFCB, + PVFATFCB *pFCB, + const PWSTR pFileName); + +