diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index c8376f52043..3241882c15d 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.23 2001/04/29 21:08:14 cnettel Exp $ +/* $Id: create.c,v 1.24 2001/05/02 03:18:03 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -23,7 +23,6 @@ #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) -#define TAG_FCB TAG('V', 'F', 'C', 'B') #define TAG_CCB TAG('V', 'C', 'C', 'B') /* FUNCTIONS *****************************************************************/ @@ -61,6 +60,47 @@ IsDeletedEntry (PVOID Block, ULONG Offset) (((FATDirEntry *) Block)[Offset].Filename[0] == 0)); } +static void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName) +{ + int fromIndex, toIndex; + + fromIndex = toIndex = 0; + while (fromIndex < 8 && pBasename [fromIndex] != ' ') + { + pName [toIndex++] = pBasename [fromIndex++]; + } + if (pExtension [0] != ' ') + { + pName [toIndex++] = L'.'; + fromIndex = 0; + while (fromIndex < 3 && pBasename [fromIndex] != ' ') + { + pName [toIndex++] = pExtension [fromIndex++]; + } + } + pName [toIndex] = L'\0'; +} + +static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pName) +{ + int fromIndex, toIndex; + + fromIndex = toIndex = 0; + while (fromIndex < 8 && pBasename [fromIndex] != ' ') + { + pName [toIndex++] = pBasename [fromIndex++]; + } + if (pExtension [0] != ' ') + { + fromIndex = 0; + while (fromIndex < 3 && pBasename [fromIndex] != ' ') + { + pName [toIndex++] = pExtension [fromIndex++]; + } + } + pName [toIndex] = L'\0'; +} + BOOLEAN GetEntryName (PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop, PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector) @@ -132,12 +172,7 @@ GetEntryName (PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop, return (TRUE); } - RtlAnsiToUnicode (Name, test[Offset].Filename, 8); - if (test[Offset].Ext[0] != ' ') - { - RtlCatAnsiToUnicode (Name, ".", 1); - } - RtlCatAnsiToUnicode (Name, test[Offset].Ext, 3); + vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name); *_Offset = Offset; @@ -176,8 +211,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) FATDirEntry *test = (FATDirEntry *) block; /* copy volume label */ - RtlAnsiToUnicode (Vpb->VolumeLabel, test[i].Filename, 8); - RtlCatAnsiToUnicode (Vpb->VolumeLabel, test[i].Ext, 3); + vfat8Dot3ToVolumeLabel (test[i].Filename, test[i].Ext, Vpb->VolumeLabel); Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel); ExFreePool (block); @@ -399,7 +433,40 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, return (STATUS_UNSUCCESSFUL); } +NTSTATUS +vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, + PWSTR pRelativeFileName, + PWSTR *pAbsoluteFilename) +{ + PWSTR rcName; + PVFATFCB fcb; + PVFATCCB ccb; + DbgPrint ("try related for %S\n", pRelativeFileName); + ccb = pFileObject->FsContext2; + assert (ccb); + fcb = ccb->pFcb; + assert (fcb); + + /* verify related object is a directory and target name + don't start with \. */ + if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) + || (pRelativeFileName[0] != '\\')) + { + return STATUS_INVALID_PARAMETER; + } + + /* construct absolute path name */ + assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1 + <= MAX_PATH); + rcName = ExAllocatePool (NonPagedPool, MAX_PATH); + wcscpy (rcName, fcb->PathName); + wcscat (rcName, L"\\"); + wcscat (rcName, pRelativeFileName); + *pAbsoluteFilename = rcName; + + return STATUS_SUCCESS; +} NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, @@ -413,15 +480,11 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR string; // PWSTR buffer; // used to store a pointer while checking MAX_PATH conformance PVFATFCB ParentFcb; - PVFATFCB Fcb, pRelFcb; + PVFATFCB Fcb; PVFATFCB Temp; - PVFATCCB newCCB, pRelCcb; + PVFATCCB newCCB; NTSTATUS Status; - PFILE_OBJECT pRelFileObject; PWSTR AbsFileName = NULL; - short i, j; - PLIST_ENTRY current_entry; - KIRQL oldIrql; ULONG BytesPerCluster; DPRINT ("VfatOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName); @@ -429,31 +492,9 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, /* FIXME : treat relative name */ if (FileObject->RelatedFileObject) { - DbgPrint ("try related for %S\n", FileName); - pRelFileObject = FileObject->RelatedFileObject; - pRelCcb = pRelFileObject->FsContext2; - assert (pRelCcb); - pRelFcb = pRelCcb->pFcb; - assert (pRelFcb); - /* - * verify related object is a directory and target name don't start with - * \. - */ - if (!(pRelFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) - || (FileName[0] != '\\')) - { - Status = STATUS_INVALID_PARAMETER; - return Status; - } - /* construct absolute path name */ - AbsFileName = ExAllocatePool (NonPagedPool, MAX_PATH); - for (i = 0; pRelFcb->PathName[i]; i++) - AbsFileName[i] = pRelFcb->PathName[i]; - AbsFileName[i++] = '\\'; - for (j = 0; FileName[j] && i < MAX_PATH; j++) - AbsFileName[i++] = FileName[j]; - assert (i < MAX_PATH); - AbsFileName[i] = 0; + Status = vfatMakeAbsoluteFilename (FileObject->RelatedFileObject, + FileName, + &AbsFileName); FileName = AbsFileName; } @@ -462,48 +503,28 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, */ CHECKPOINT; - KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); - current_entry = DeviceExt->FcbListHead.Flink; - while (current_entry != &DeviceExt->FcbListHead) - { - Fcb = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry); + Fcb = vfatGrabFCBFromTable (DeviceExt, FileName); + if (Fcb != NULL) + { + FileObject->FsContext = (PVOID)&Fcb->RFCB; + newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + memset (newCCB, 0, sizeof (VFATCCB)); + FileObject->Flags = FileObject->Flags | + FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; + FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; + FileObject->FsContext2 = newCCB; + newCCB->pFcb = Fcb; + newCCB->PtrFileObject = FileObject; + if (AbsFileName) + ExFreePool (AbsFileName); + return STATUS_SUCCESS; + } - DPRINT ("Scanning %x\n", Fcb); - DPRINT ("Scanning %S\n", Fcb->PathName); - - if (DeviceExt == Fcb->pDevExt && wstrcmpi (FileName, Fcb->PathName)) - { - Fcb->RefCount++; - KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); - FileObject->FsContext = (PVOID)&Fcb->RFCB; - newCCB = - ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); - memset (newCCB, 0, sizeof (VFATCCB)); - FileObject->Flags = FileObject->Flags | - FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; - FileObject->SectionObjectPointers = - &Fcb->SectionObjectPointers; - FileObject->FsContext2 = newCCB; - newCCB->pFcb = Fcb; - newCCB->PtrFileObject = FileObject; - if (AbsFileName) - ExFreePool (AbsFileName); - return (STATUS_SUCCESS); - } - - current_entry = current_entry->Flink; - } - KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); - - CHECKPOINT; DPRINT ("FileName %S\n", FileName); string = FileName; ParentFcb = NULL; - Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB); - memset (Fcb, 0, sizeof (VFATFCB)); - Fcb->ObjectName = &Fcb->PathName[1]; - Fcb->PathName[0]='\\'; + Fcb = vfatNewFCB (L"\\"); next = &string[0]; CHECKPOINT; @@ -540,7 +561,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, break; } - DPRINT ("current '%S'\n", current); + DPRINT ("search for (%S) in (%S)\n", current, ParentFcb ? ParentFcb->PathName : L""); Status = FindFile (DeviceExt, Fcb, ParentFcb, current, NULL, NULL); if (Status != STATUS_SUCCESS) { @@ -560,11 +581,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, if (ParentFcb == NULL) { CHECKPOINT; - Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), - TAG_FCB); - memset (Fcb, 0, sizeof (VFATFCB)); - Fcb->ObjectName = &Fcb->PathName[1]; - Fcb->PathName[0] = '\\'; + Fcb = vfatNewFCB (L"\\"); } else Fcb = ParentFcb; @@ -578,13 +595,12 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Fcb->ObjectName=&Fcb->ObjectName[1]; Fcb->ObjectName[0]=0; } - CHECKPOINT; ParentFcb = Temp; } /* searching for last path component */ - DPRINT ("current '%S'\n", current); + DPRINT ("search for (%S) in (%S)\n", current, Fcb ? Fcb->PathName : L""); Status = FindFile (DeviceExt, Fcb, ParentFcb, current, NULL, NULL); if (Status != STATUS_SUCCESS) { @@ -621,9 +637,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, ParentFcb->RefCount++; /* FIXME : initialize all fields in FCB and CCB */ - KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); - InsertTailList (&DeviceExt->FcbListHead, &ParentFcb->FcbListEntry); - KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); + vfatAddFCBToTable (DeviceExt, ParentFcb); /* vfat_wcsncpy (ParentFcb->PathName, FileName, MAX_PATH); ParentFcb->ObjectName = ParentFcb->PathName + (current - FileName); */ diff --git a/reactos/drivers/fs/vfat/dirwr.c b/reactos/drivers/fs/vfat/dirwr.c index e1460d87fe8..c70541b49e5 100644 --- a/reactos/drivers/fs/vfat/dirwr.c +++ b/reactos/drivers/fs/vfat/dirwr.c @@ -1,4 +1,4 @@ -/* $Id: dirwr.c,v 1.17 2001/02/14 02:53:54 dwelch Exp $ +/* $Id: dirwr.c,v 1.18 2001/05/02 03:18:03 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -174,7 +174,6 @@ addEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB newFCB; PVFATCCB newCCB; ULONG CurrentCluster; - KIRQL oldIrql; LARGE_INTEGER SystemTime, LocalTime; ULONG BytesPerCluster; NTSTATUS Status; @@ -413,9 +412,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt, } DPRINT ("write entry offset %d status=%x\n", Offset, status); newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB)); - newFCB = ExAllocatePool (NonPagedPool, sizeof (VFATFCB)); memset (newCCB, 0, sizeof (VFATCCB)); - memset (newFCB, 0, sizeof (VFATFCB)); + newFCB = vfatNewFCB (NULL); newCCB->pFcb = newFCB; newCCB->PtrFileObject = pFileObject; newFCB->RefCount++; @@ -435,10 +433,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, /* * FIXME : initialize all fields in FCB and CCB */ - KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); - InsertTailList (&DeviceExt->FcbListHead, &newFCB->FcbListEntry); - KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); - + vfatAddFCBToTable (DeviceExt, newFCB); memcpy (&newFCB->entry, pEntry, sizeof (FATDirEntry)); DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename); diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c new file mode 100644 index 00000000000..f06d45256d7 --- /dev/null +++ b/reactos/drivers/fs/vfat/fcb.c @@ -0,0 +1,110 @@ +/* $Id: fcb.c,v 1.1 2001/05/02 03:18:03 rex Exp $ + * + * + * FILE: fcb.c + * PURPOSE: Routines to manipulate FCBs. + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com) + * Rex Jolliff (rex@lvcablemodem.com) + */ + +/* ------------------------------------------------------- INCLUDES */ + +#include +#include +#include + +#define NDEBUG +#include + +#include "vfat.h" + +/* -------------------------------------------------------- DEFINES */ + +#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) +#define TAG_FCB TAG('V', 'F', 'C', 'B') + +/* -------------------------------------------------------- PUBLICS */ + +PVFATFCB vfatNewFCB (PWCHAR pFileName) +{ + PVFATFCB rcFCB; + + rcFCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB); + memset (rcFCB, 0, sizeof (VFATFCB)); + if (pFileName) + { + wcscpy (rcFCB->PathName, pFileName); + if (wcsrchr (rcFCB->PathName, '\\') != 0) + { + rcFCB->ObjectName = wcsrchr (rcFCB->PathName, '\\'); + } + else + { + rcFCB->ObjectName = rcFCB->PathName; + } + } + + return rcFCB; +} + +void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) +{ + KIRQL oldIrql; + + KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); + pFCB->RefCount++; + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); +} + +void vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) +{ + KIRQL oldIrql; + + KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); + pFCB->RefCount--; + if (pFCB->RefCount <= 0) + { + RemoveEntryList (&pFCB->FcbListEntry); + ExFreePool (pFCB); + } + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); +} + +void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) +{ + KIRQL oldIrql; + + KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); + pFCB->pDevExt = pVCB; + InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry); + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); +} + +PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, PWSTR pFileName) +{ + KIRQL oldIrql; + PVFATFCB rcFCB; + PLIST_ENTRY current_entry; + + KeAcquireSpinLock (&pDeviceExt->FcbListLock, &oldIrql); + current_entry = pDeviceExt->FcbListHead.Flink; + while (current_entry != &pDeviceExt->FcbListHead) + { + rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry); + + DPRINT ("Scanning %x(%S)\n", rcFCB, rcFCB->PathName); + + if (wstrcmpi (pFileName, rcFCB->PathName)) + { + rcFCB->RefCount++; + KeReleaseSpinLock (&pDeviceExt->FcbListLock, oldIrql); + return rcFCB; + } + current_entry = current_entry->Flink; + } + KeReleaseSpinLock (&pDeviceExt->FcbListLock, oldIrql); + + return NULL; +} diff --git a/reactos/drivers/fs/vfat/makefile b/reactos/drivers/fs/vfat/makefile index 78409d86639..c424c128c2f 100644 --- a/reactos/drivers/fs/vfat/makefile +++ b/reactos/drivers/fs/vfat/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.28 2001/03/07 13:44:41 ekohl Exp $ +# $Id: makefile,v 1.29 2001/05/02 03:18:03 rex Exp $ # # PATH_TO_TOP = ../../.. @@ -6,7 +6,7 @@ PATH_TO_TOP = ../../.. TARGET=vfatfs OBJECTS = blockdev.o close.o create.o dir.o dirwr.o iface.o string.o fat.o \ - rw.o finfo.o volume.o shutdown.o cleanup.o $(TARGET).coff + rw.o finfo.o volume.o shutdown.o cleanup.o fcb.o $(TARGET).coff LIBS = ../../../ntoskrnl/ntoskrnl.a CFLAGS = -g -Wall -Werror diff --git a/reactos/drivers/fs/vfat/string.c b/reactos/drivers/fs/vfat/string.c index ac8676038e6..732f23528d2 100644 --- a/reactos/drivers/fs/vfat/string.c +++ b/reactos/drivers/fs/vfat/string.c @@ -1,4 +1,4 @@ -/* $Id: string.c,v 1.5 2001/03/01 13:46:22 dwelch Exp $ +/* $Id: string.c,v 1.6 2001/05/02 03:18:03 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -20,39 +20,6 @@ /* FUNCTIONS ****************************************************************/ -void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length) -/* - * FUNCTION: Convert an ANSI string to it's Unicode equivalent - */ -{ - int i; - - for (i=0; (i @@ -229,10 +229,6 @@ updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject); * String functions */ VOID -RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length); -VOID -RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length); -VOID vfat_initstr(wchar_t *wstr, ULONG wsize); wchar_t* vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount); @@ -283,3 +279,12 @@ ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb); NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName); + +/* ----------------------------------------------------- FCB Functions */ + +PVFATFCB vfatNewFCB (PWCHAR pFileName); +void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); +PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, + PWSTR pFileName); + +