Extracted vfat8dot3ToFilename from GetEntryName

Extracted vfatMakeAbsoluteFilename from vfatOpenFile
Extracted vfatGrabFCBFromTable from vfatOpenFile
Extracted vfatNewFCB from vfatOpenFile
Extracted vfatAddFCBToTable from vfatOpenFile
Removed RtlAnsiToUnicode, RtlCatAnsiToUnicode

svn path=/trunk/; revision=1853
This commit is contained in:
Rex Jolliff 2001-05-02 03:18:03 +00:00
parent 87589daf4e
commit 38afc0ac8b
6 changed files with 229 additions and 138 deletions

View file

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

View file

@ -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);

View file

@ -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 <ddk/ntddk.h>
#include <wchar.h>
#include <limits.h>
#define NDEBUG
#include <debug.h>
#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;
}

View file

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

View file

@ -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<Length && Source[i] != ' '); i++)
{
Dest[i] = Source[i];
}
Dest[i]=0;
}
void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
/*
* FUNCTION: Appends a converted ANSI to Unicode string to the end of an
* existing Unicode string
*/
{
ULONG i;
while((*Dest)!=0)
{
Dest++;
}
for (i=0; (i<Length && Source[i] != ' '); i++)
{
Dest[i] = Source[i];
}
Dest[i]=0;
}
void vfat_initstr(wchar_t *wstr, ULONG wsize)
/*
* FUNCTION: Initialize a string for use with a long file name

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.27 2001/03/07 13:44:41 ekohl Exp $ */
/* $Id: vfat.h,v 1.28 2001/05/02 03:18:03 rex Exp $ */
#include <ddk/ntifs.h>
@ -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);