mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
Partial directory caching (create calls cached, but dir info calls
still use non cached routines). svn path=/trunk/; revision=2038
This commit is contained in:
parent
52ead14335
commit
208eecc0f4
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.26 2001/06/14 21:05:08 jfilby Exp $
|
||||
/* $Id: create.c,v 1.27 2001/07/05 01:51:52 rex Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -21,10 +21,6 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
|
||||
#define TAG_CCB TAG('V', 'C', 'C', 'B')
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
|
@ -60,7 +56,7 @@ IsDeletedEntry (PVOID Block, ULONG Offset)
|
|||
(((FATDirEntry *) Block)[Offset].Filename[0] == 0));
|
||||
}
|
||||
|
||||
static void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
|
||||
void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
|
||||
{
|
||||
int fromIndex, toIndex;
|
||||
|
||||
|
@ -475,196 +471,57 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
* FUNCTION: Opens a file
|
||||
*/
|
||||
{
|
||||
PWSTR current = NULL;
|
||||
PWSTR next;
|
||||
PWSTR string;
|
||||
// PWSTR buffer; // used to store a pointer while checking MAX_PATH conformance
|
||||
PVFATFCB ParentFcb;
|
||||
PVFATFCB Fcb;
|
||||
PVFATFCB Temp;
|
||||
PVFATCCB newCCB;
|
||||
NTSTATUS Status;
|
||||
PWSTR AbsFileName = NULL;
|
||||
ULONG BytesPerCluster, FileCacheQuantum;
|
||||
|
||||
DPRINT ("VfatOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
|
||||
|
||||
/* FIXME : treat relative name */
|
||||
if (FileObject->RelatedFileObject)
|
||||
{
|
||||
DPRINT ("Converting relative filename to absolute filename\n");
|
||||
Status = vfatMakeAbsoluteFilename (FileObject->RelatedFileObject,
|
||||
FileName,
|
||||
&AbsFileName);
|
||||
FileName = AbsFileName;
|
||||
}
|
||||
|
||||
/*
|
||||
* try first to find an existing FCB in memory
|
||||
*/
|
||||
CHECKPOINT;
|
||||
//FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
|
||||
|
||||
DPRINT ("PathName to open: %S\n", FileName);
|
||||
|
||||
/* try first to find an existing FCB in memory */
|
||||
DPRINT ("Checking for existing FCB in memory\n");
|
||||
Fcb = vfatGrabFCBFromTable (DeviceExt, FileName);
|
||||
if (Fcb != NULL)
|
||||
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 ("FileName %S\n", FileName);
|
||||
|
||||
string = FileName;
|
||||
ParentFcb = NULL;
|
||||
Fcb = vfatNewFCB (L"\\");
|
||||
next = &string[0];
|
||||
|
||||
CHECKPOINT;
|
||||
if (*next == 0 || *(next+1) == 0) // root
|
||||
{
|
||||
memset (Fcb->entry.Filename, ' ', 11);
|
||||
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
|
||||
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
Fcb->entry.FirstCluster = 2;
|
||||
else
|
||||
Fcb->entry.FirstCluster = 1;
|
||||
/* FIXME : is 1 the good value for mark root? */
|
||||
ParentFcb = Fcb;
|
||||
DPRINT("%S filename, PathName: %S\n",FileName, ParentFcb->PathName);
|
||||
Fcb = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
*next = '\\';
|
||||
current = next + 1;
|
||||
next = wcschr (next + 1, '\\');
|
||||
if (next != NULL)
|
||||
{
|
||||
*next = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reached the last path component */
|
||||
DPRINT ("exiting: current '%S'\n", current);
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT ("search for (%S) in (%S)\n", current, ParentFcb ? ParentFcb->PathName : L"");
|
||||
Status = FindFile (DeviceExt, Fcb, ParentFcb, current, NULL, NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
CHECKPOINT;
|
||||
if (Fcb != NULL)
|
||||
ExFreePool (Fcb);
|
||||
DPRINT ("No existing FCB found, making a new one if file exists.\n");
|
||||
Status = vfatGetFCBForFile (DeviceExt, &ParentFcb, &Fcb, FileName);
|
||||
if (ParentFcb != NULL)
|
||||
ExFreePool (ParentFcb);
|
||||
{
|
||||
vfatReleaseFCB (DeviceExt, ParentFcb);
|
||||
}
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
DPRINT ("Could not make a new FCB, status: %x\n", Status);
|
||||
|
||||
if (AbsFileName)
|
||||
ExFreePool (AbsFileName);
|
||||
|
||||
DPRINT ("error STATUS_OBJECT_PATH_NOT_FOUND\n");
|
||||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
return Status;
|
||||
}
|
||||
Temp = Fcb;
|
||||
CHECKPOINT;
|
||||
if (ParentFcb == NULL)
|
||||
{
|
||||
CHECKPOINT;
|
||||
Fcb = vfatNewFCB (L"\\");
|
||||
}
|
||||
else
|
||||
Fcb = ParentFcb;
|
||||
|
||||
if (*(Temp->ObjectName))
|
||||
{
|
||||
vfat_wcsncpy(Fcb->PathName+(Fcb->ObjectName-Fcb->PathName),Temp->PathName+(Fcb->ObjectName-Fcb->PathName), MAX_PATH);
|
||||
|
||||
Fcb->ObjectName = &Fcb->PathName[wcslen(Fcb->PathName)];
|
||||
Fcb->ObjectName[0]='\\';
|
||||
Fcb->ObjectName=&Fcb->ObjectName[1];
|
||||
Fcb->ObjectName[0]=0;
|
||||
}
|
||||
CHECKPOINT;
|
||||
ParentFcb = Temp;
|
||||
}
|
||||
|
||||
if( *current != L'\0' ){ //the file name is directory. there will be no last part.
|
||||
/* searching for last path component */
|
||||
DPRINT ("search for (%S) in (%S)\n", current, Fcb ? Fcb->PathName : L"");
|
||||
Status = FindFile (DeviceExt, Fcb, ParentFcb, current, NULL, NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* file does not exist */
|
||||
CHECKPOINT;
|
||||
if (Fcb != NULL)
|
||||
ExFreePool (Fcb);
|
||||
if (ParentFcb != NULL)
|
||||
ExFreePool (ParentFcb);
|
||||
DPRINT ("Attaching FCB to fileObject\n");
|
||||
Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
|
||||
|
||||
if (AbsFileName)
|
||||
ExFreePool (AbsFileName);
|
||||
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
Temp = Fcb;
|
||||
|
||||
Fcb = ParentFcb;
|
||||
ParentFcb = Temp;
|
||||
ParentFcb->ObjectName = &(wcschr (ParentFcb->ObjectName, '\\'))[1];
|
||||
}
|
||||
}
|
||||
|
||||
FileObject->Flags = FileObject->Flags |
|
||||
FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
||||
FileObject->SectionObjectPointers = &ParentFcb->SectionObjectPointers;
|
||||
memset(FileObject->SectionObjectPointers, 0,
|
||||
sizeof(SECTION_OBJECT_POINTERS));
|
||||
FileObject->FsContext = (PVOID)&ParentFcb->RFCB;
|
||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
FileObject->FsContext2 = newCCB;
|
||||
newCCB->pFcb = ParentFcb;
|
||||
newCCB->PtrFileObject = FileObject;
|
||||
ParentFcb->RefCount++;
|
||||
ParentFcb->pDevExt = DeviceExt;
|
||||
/* FIXME : initialize all fields in FCB and CCB */
|
||||
|
||||
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
FileCacheQuantum = (BytesPerCluster >= PAGESIZE) ? BytesPerCluster : PAGESIZE;
|
||||
Status = CcRosInitializeFileCache(FileObject,
|
||||
&ParentFcb->RFCB.Bcb,
|
||||
FileCacheQuantum);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("CcRosInitializeFileCache failed\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
DPRINT ("file open, fcb=%x\n", ParentFcb);
|
||||
DPRINT ("FileSize %d\n", ParentFcb->entry.FileSize);
|
||||
|
||||
vfatAddFCBToTable (DeviceExt, ParentFcb);
|
||||
|
||||
if (Fcb)
|
||||
ExFreePool (Fcb);
|
||||
if (AbsFileName)
|
||||
ExFreePool (AbsFileName);
|
||||
CHECKPOINT;
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
|
|
|
@ -375,3 +375,5 @@ VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return RC;
|
||||
}
|
||||
|
||||
|
||||
|
|
227
reactos/drivers/fs/vfat/direntry.c
Normal file
227
reactos/drivers/fs/vfat/direntry.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* $Id: direntry.c,v 1.1 2001/07/05 01:51:52 rex Exp $
|
||||
*
|
||||
*
|
||||
* FILE: DirEntry.c
|
||||
* PURPOSE: Routines to manipulate directory entries.
|
||||
* 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"
|
||||
|
||||
#define ENTRIES_PER_PAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
|
||||
(PAGESIZE / ((pDeviceExt)->BytesPerSector)))
|
||||
|
||||
ULONG
|
||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
PFAT_DIR_ENTRY pFatDirEntry)
|
||||
{
|
||||
ULONG cluster;
|
||||
|
||||
if (pDeviceExt->FatType == FAT32)
|
||||
{
|
||||
cluster = pFatDirEntry->FirstCluster +
|
||||
pFatDirEntry->FirstClusterHigh * 65536;
|
||||
}
|
||||
else
|
||||
{
|
||||
cluster = pFatDirEntry->FirstCluster;
|
||||
}
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry)
|
||||
{
|
||||
return pFatDirEntry->Filename [0] == 0xe5;
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry)
|
||||
{
|
||||
return pFatDirEntry->Filename [0] == 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatIsDirEntryLongName (FATDirEntry * pFatDirEntry)
|
||||
{
|
||||
return pFatDirEntry->Attrib == 0x0f;
|
||||
}
|
||||
|
||||
void
|
||||
vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName)
|
||||
{
|
||||
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pDirectoryFCB,
|
||||
ULONG * pDirectoryIndex,
|
||||
PWSTR pLongFileName,
|
||||
PFAT_DIR_ENTRY pDirEntry)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_PAGE(pDeviceExt);
|
||||
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_PAGE(pDeviceExt);
|
||||
PVOID currentPage = NULL;
|
||||
PCACHE_SEGMENT cacheSegment = NULL;
|
||||
FATDirEntry * fatDirEntry;
|
||||
slot * longNameEntry;
|
||||
ULONG cpos;
|
||||
|
||||
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
|
||||
pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
*pDirectoryIndex,
|
||||
pLongFileName,
|
||||
pDirEntry);
|
||||
|
||||
*pLongFileName = 0;
|
||||
|
||||
DPRINT ("Validating current directory page\n");
|
||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
pageNumber * PAGESIZE,
|
||||
(PVOID *) ¤tPage,
|
||||
&cacheSegment,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
fatDirEntry = (FATDirEntry *) currentPage;
|
||||
|
||||
if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
|
||||
{
|
||||
DPRINT ("end of directory, returning no more entries\n");
|
||||
status = vfatReleaseRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
cacheSegment);
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage]))
|
||||
{
|
||||
DPRINT (" long name entry found at %d\n", *pDirectoryIndex);
|
||||
longNameEntry = (slot *) currentPage;
|
||||
|
||||
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
|
||||
5, longNameEntry [indexInPage].name0_4,
|
||||
6, longNameEntry [indexInPage].name5_10,
|
||||
2, longNameEntry [indexInPage].name11_12);
|
||||
|
||||
vfat_initstr (pLongFileName, 256);
|
||||
vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2);
|
||||
|
||||
DPRINT (" longName: [%S]\n", pLongFileName);
|
||||
|
||||
cpos = 0;
|
||||
while ((longNameEntry [indexInPage].id != 0x41) &&
|
||||
(longNameEntry [indexInPage].id != 0x01) &&
|
||||
(longNameEntry [indexInPage].attr > 0))
|
||||
{
|
||||
(*pDirectoryIndex)++;
|
||||
indexInPage++;
|
||||
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt))
|
||||
{
|
||||
indexInPage = 0;
|
||||
pageNumber++;
|
||||
|
||||
status = vfatReleaseRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
cacheSegment);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
pageNumber * PAGESIZE,
|
||||
(PVOID *) ¤tPage,
|
||||
&cacheSegment,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
longNameEntry = (slot *) currentPage;
|
||||
}
|
||||
DPRINT (" index %d\n", *pDirectoryIndex);
|
||||
|
||||
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
|
||||
5, longNameEntry [indexInPage].name0_4,
|
||||
6, longNameEntry [indexInPage].name5_10,
|
||||
2, longNameEntry [indexInPage].name11_12);
|
||||
|
||||
cpos++;
|
||||
vfat_movstr (pLongFileName, 13, 0, cpos * 13);
|
||||
vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2);
|
||||
|
||||
DPRINT (" longName: [%S]\n", pLongFileName);
|
||||
|
||||
}
|
||||
(*pDirectoryIndex)++;
|
||||
indexInPage++;
|
||||
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt))
|
||||
{
|
||||
indexInPage = 0;
|
||||
pageNumber++;
|
||||
|
||||
status = vfatReleaseRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
cacheSegment);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
pageNumber * PAGESIZE,
|
||||
(PVOID *) ¤tPage,
|
||||
&cacheSegment,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY));
|
||||
(*pDirectoryIndex)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT ("Releasing current directory page\n");
|
||||
status = vfatReleaseRegion (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
cacheSegment);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: fcb.c,v 1.3 2001/05/10 06:30:23 rex Exp $
|
||||
/* $Id: fcb.c,v 1.4 2001/07/05 01:51:52 rex Exp $
|
||||
*
|
||||
*
|
||||
* FILE: fcb.c
|
||||
|
@ -54,10 +54,27 @@ void vfatDestroyFCB (PVFATFCB pFCB)
|
|||
ExFreePool (pFCB);
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
||||
{
|
||||
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatFCBIsRoot (PVFATFCB FCB)
|
||||
{
|
||||
return wcscmp (FCB->PathName, L"\\") == 0;
|
||||
}
|
||||
|
||||
void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT ("grabbing FCB at %x: %S, refCount:%d\n",
|
||||
pFCB,
|
||||
pFCB->PathName,
|
||||
pFCB->RefCount);
|
||||
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
pFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
|
@ -67,6 +84,11 @@ void vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
|||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
|
||||
pFCB,
|
||||
pFCB->PathName,
|
||||
pFCB->RefCount);
|
||||
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
pFCB->RefCount--;
|
||||
if (pFCB->RefCount <= 0 && !vfatFCBIsDirectory (pVCB, pFCB))
|
||||
|
@ -95,39 +117,168 @@ vfatGrabFCBFromTable (PDEVICE_EXTENSION pVCB, PWSTR pFileName)
|
|||
PVFATFCB rcFCB;
|
||||
PLIST_ENTRY current_entry;
|
||||
|
||||
CHECKPOINT;
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
CHECKPOINT;
|
||||
current_entry = pVCB->FcbListHead.Flink;
|
||||
while (current_entry != &pVCB->FcbListHead)
|
||||
{
|
||||
rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry);
|
||||
|
||||
DPRINT ("Next FCB in list at %x\n", rcFCB);
|
||||
DPRINT (" PathName:%S\n", rcFCB->PathName);
|
||||
|
||||
if (wstrcmpi (pFileName, rcFCB->PathName))
|
||||
{
|
||||
rcFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
return rcFCB;
|
||||
}
|
||||
|
||||
//FIXME: need to compare against short name in FCB here
|
||||
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
CHECKPOINT;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PVFATFCB
|
||||
vfatMakeRootFCB (PDEVICE_EXTENSION pVCB)
|
||||
NTSTATUS
|
||||
vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PVFATFCB FCB;
|
||||
PFILE_OBJECT fileObject;
|
||||
ULONG bytesPerCluster;
|
||||
ULONG fileCacheQuantum;
|
||||
PVFATCCB newCCB;
|
||||
|
||||
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
||||
|
||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
||||
if (newCCB == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
|
||||
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
|
||||
FO_DIRECT_CACHE_PAGING_READ;
|
||||
fileObject->SectionObjectPointers = &fcb->SectionObjectPointers;
|
||||
fileObject->FsContext = (PVOID) &fcb->RFCB;
|
||||
fileObject->FsContext2 = newCCB;
|
||||
newCCB->pFcb = fcb;
|
||||
newCCB->PtrFileObject = fileObject;
|
||||
fcb->pDevExt = vcb;
|
||||
|
||||
bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
|
||||
bytesPerCluster : PAGESIZE;
|
||||
status = CcRosInitializeFileCache (fileObject,
|
||||
&fcb->RFCB.Bcb,
|
||||
fileCacheQuantum);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
DbgPrint ("CcRosInitializeFileCache failed\n");
|
||||
KeBugCheck (0);
|
||||
}
|
||||
ObDereferenceObject (fileObject);
|
||||
fcb->isCacheInitialized = TRUE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
vfatRequestAndValidateRegion (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pFCB,
|
||||
ULONG pOffset,
|
||||
PVOID * pBuffer,
|
||||
PCACHE_SEGMENT * pCacheSegment,
|
||||
BOOL pExtend)
|
||||
{
|
||||
NTSTATUS status;
|
||||
BOOLEAN valid;
|
||||
BOOLEAN isRoot;
|
||||
ULONG currentCluster;
|
||||
ULONG i;
|
||||
|
||||
status = CcRosRequestCacheSegment(pFCB->RFCB.Bcb,
|
||||
pOffset,
|
||||
pBuffer,
|
||||
&valid,
|
||||
pCacheSegment);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
isRoot = vfatFCBIsRoot (pFCB);
|
||||
if (!valid)
|
||||
{
|
||||
currentCluster = vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry);
|
||||
status = OffsetToCluster (pDeviceExt,
|
||||
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
|
||||
pOffset,
|
||||
¤tCluster,
|
||||
pExtend);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
if (PAGESIZE > pDeviceExt->BytesPerCluster)
|
||||
{
|
||||
for (i = 0; i < (PAGESIZE / pDeviceExt->BytesPerCluster); i++)
|
||||
{
|
||||
status = VfatRawReadCluster (pDeviceExt,
|
||||
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
|
||||
((PCHAR)*pBuffer) +
|
||||
(i * pDeviceExt->BytesPerCluster),
|
||||
currentCluster);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
CcRosReleaseCacheSegment(pFCB->RFCB.Bcb, *pCacheSegment, FALSE);
|
||||
return status;
|
||||
}
|
||||
status = NextCluster (pDeviceExt,
|
||||
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
|
||||
¤tCluster,
|
||||
pExtend);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
CcRosReleaseCacheSegment(pFCB->RFCB.Bcb, *pCacheSegment, FALSE);
|
||||
return status;
|
||||
}
|
||||
if ((currentCluster) == 0xFFFFFFFF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = VfatRawReadCluster (pDeviceExt,
|
||||
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
|
||||
*pBuffer,
|
||||
currentCluster);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
CcRosReleaseCacheSegment(pFCB->RFCB.Bcb, *pCacheSegment, FALSE);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
vfatReleaseRegion (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pFCB,
|
||||
PCACHE_SEGMENT pCacheSegment)
|
||||
{
|
||||
return CcRosReleaseCacheSegment (pFCB->RFCB.Bcb, pCacheSegment, TRUE);
|
||||
}
|
||||
|
||||
PVFATFCB
|
||||
vfatMakeRootFCB (PDEVICE_EXTENSION pVCB)
|
||||
{
|
||||
PVFATFCB FCB;
|
||||
|
||||
FCB = vfatNewFCB (L"\\");
|
||||
memset (FCB->entry.Filename, ' ', 11);
|
||||
|
@ -142,21 +293,10 @@ vfatMakeRootFCB (PDEVICE_EXTENSION pVCB)
|
|||
FCB->entry.FirstCluster = 1;
|
||||
}
|
||||
FCB->RefCount = 1;
|
||||
fileObject = IoCreateStreamFileObject (NULL, pVCB->StorageDevice);
|
||||
|
||||
bytesPerCluster = pVCB->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
|
||||
bytesPerCluster : PAGESIZE;
|
||||
status = CcRosInitializeFileCache (fileObject,
|
||||
&FCB->RFCB.Bcb,
|
||||
fileCacheQuantum);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
DbgPrint ("CcRosInitializeFileCache failed\n");
|
||||
KeBugCheck (0);
|
||||
}
|
||||
ObDereferenceObject (fileObject);
|
||||
vfatFCBInitializeCache (pVCB, FCB);
|
||||
vfatAddFCBToTable (pVCB, FCB);
|
||||
vfatGrabFCB(pVCB, FCB);
|
||||
|
||||
return FCB;
|
||||
}
|
||||
|
@ -167,27 +307,191 @@ vfatOpenRootFCB (PDEVICE_EXTENSION pVCB)
|
|||
PVFATFCB FCB;
|
||||
|
||||
FCB = vfatGrabFCBFromTable (pVCB, L"\\");
|
||||
if (FCB != NULL)
|
||||
if (FCB == NULL)
|
||||
{
|
||||
return FCB;
|
||||
}
|
||||
FCB = vfatMakeRootFCB (pVCB);
|
||||
}
|
||||
|
||||
return FCB;
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
||||
NTSTATUS
|
||||
vfatMakeFCBFromDirEntry (PVCB vcb,
|
||||
PVFATFCB directoryFCB,
|
||||
PWSTR longName,
|
||||
PFAT_DIR_ENTRY dirEntry,
|
||||
PVFATFCB * fileFCB)
|
||||
{
|
||||
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
||||
PVFATFCB rcFCB;
|
||||
WCHAR pathName [MAX_PATH];
|
||||
|
||||
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));
|
||||
|
||||
vfatFCBInitializeCache (vcb, rcFCB);
|
||||
vfatAddFCBToTable (vcb, rcFCB);
|
||||
vfatGrabFCB (vcb, rcFCB);
|
||||
*fileFCB = rcFCB;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
PVFATFCB
|
||||
vfatDirFindFile (PDEVICE_EXTENSION pVCB,
|
||||
PVFATFCB parentFCB,
|
||||
const PWSTR elementName)
|
||||
NTSTATUS
|
||||
vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||
PVFATFCB fcb,
|
||||
PFILE_OBJECT fileObject)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
NTSTATUS status;
|
||||
PVFATCCB newCCB;
|
||||
|
||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
||||
if (newCCB == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
|
||||
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
|
||||
FO_DIRECT_CACHE_PAGING_READ;
|
||||
fileObject->SectionObjectPointers = &fcb->SectionObjectPointers;
|
||||
fileObject->FsContext = (PVOID) &fcb->RFCB;
|
||||
fileObject->FsContext2 = newCCB;
|
||||
newCCB->pFcb = fcb;
|
||||
newCCB->PtrFileObject = fileObject;
|
||||
fcb->pDevExt = vcb;
|
||||
|
||||
if (!fcb->isCacheInitialized)
|
||||
{
|
||||
ULONG bytesPerCluster;
|
||||
ULONG fileCacheQuantum;
|
||||
|
||||
bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ? bytesPerCluster :
|
||||
PAGESIZE;
|
||||
status = CcRosInitializeFileCache (fileObject,
|
||||
&fcb->RFCB.Bcb,
|
||||
fileCacheQuantum);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
DbgPrint ("CcRosInitializeFileCache failed\n");
|
||||
KeBugCheck (0);
|
||||
}
|
||||
fcb->isCacheInitialized = TRUE;
|
||||
}
|
||||
|
||||
DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pDirectoryFCB,
|
||||
PWSTR pFileToFind,
|
||||
PVFATFCB * pFoundFCB)
|
||||
{
|
||||
BOOL finishedScanningDirectory;
|
||||
ULONG directoryIndex;
|
||||
NTSTATUS status;
|
||||
WCHAR defaultFileName [2];
|
||||
WCHAR currentLongName [256];
|
||||
FAT_DIR_ENTRY currentDirEntry;
|
||||
WCHAR currentEntryName [256];
|
||||
|
||||
assert (pDeviceExt);
|
||||
assert (pDirectoryFCB);
|
||||
assert (pFileToFind);
|
||||
|
||||
DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
|
||||
pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
pFileToFind);
|
||||
DPRINT ("Dir Path:%S\n", pDirectoryFCB->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)
|
||||
{
|
||||
finishedScanningDirectory = TRUE;
|
||||
continue;
|
||||
}
|
||||
else if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
DPRINT (" Index:%d longName:%S\n",
|
||||
directoryIndex,
|
||||
currentLongName);
|
||||
|
||||
if (!vfatIsDirEntryDeleted (¤tDirEntry))
|
||||
{
|
||||
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
|
||||
{
|
||||
DPRINT ("Match found, %S\n", currentLongName);
|
||||
status = vfatMakeFCBFromDirEntry (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
currentLongName,
|
||||
¤tDirEntry,
|
||||
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,
|
||||
pFoundFCB);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -196,27 +500,30 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
PVFATFCB *pFCB,
|
||||
const PWSTR pFileName)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WCHAR pathName [MAX_PATH];
|
||||
WCHAR elementName [MAX_PATH];
|
||||
PWCHAR currentElement;
|
||||
PVFATFCB FCB;
|
||||
PVFATFCB parentFCB;
|
||||
|
||||
DPRINT ("vfatGetFCBForFile (%x,%x,%x,%S)\n",
|
||||
pVCB,
|
||||
pParentFCB,
|
||||
pFCB,
|
||||
pFileName);
|
||||
|
||||
// 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);
|
||||
DPRINT ("returning root FCB\n");
|
||||
|
||||
FCB = vfatOpenRootFCB (pVCB);
|
||||
*pFCB = FCB;
|
||||
*pParentFCB = NULL;
|
||||
|
||||
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentElement = pFileName + 1;
|
||||
|
@ -235,7 +542,8 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
continue;
|
||||
}
|
||||
|
||||
currentElement = vfatGetNextPathElement (currentElement);
|
||||
DPRINT ("Parsing, currentElement:%S\n", currentElement);
|
||||
DPRINT (" parentFCB:%x FCB:%x\n", parentFCB, FCB);
|
||||
|
||||
// descend to next directory level
|
||||
if (parentFCB)
|
||||
|
@ -246,8 +554,13 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
// 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;
|
||||
|
@ -256,6 +569,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
vfatWSubString (pathName,
|
||||
pFileName,
|
||||
vfatGetNextPathElement (currentElement) - pFileName);
|
||||
DPRINT (" pathName:%S\n", pathName);
|
||||
|
||||
FCB = vfatGrabFCBFromTable (pVCB, pathName);
|
||||
if (FCB == NULL)
|
||||
|
@ -263,12 +577,14 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
vfatWSubString (elementName,
|
||||
currentElement,
|
||||
vfatGetNextPathElement (currentElement) - currentElement);
|
||||
FCB = vfatDirFindFile (pVCB, parentFCB, elementName);
|
||||
if (FCB == NULL)
|
||||
DPRINT (" elementName:%S\n", elementName);
|
||||
|
||||
status = vfatDirFindFile (pVCB, parentFCB, elementName, &FCB);
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
*pParentFCB = parentFCB;
|
||||
*pFCB = NULL;
|
||||
if (vfatGetNextPathElement (currentElement) == 0)
|
||||
if (vfatGetNextPathElement (vfatGetNextPathElement (currentElement) + 1) == 0)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
@ -277,10 +593,17 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else if (!NT_SUCCESS (status))
|
||||
{
|
||||
vfatReleaseFCB (pVCB, parentFCB);
|
||||
*pParentFCB = NULL;
|
||||
*pFCB = NULL;
|
||||
|
||||
// FIXME: check security on directory element and fail if access denied
|
||||
return status;
|
||||
}
|
||||
}
|
||||
currentElement = vfatGetNextPathElement (currentElement);
|
||||
}
|
||||
|
||||
*pParentFCB = parentFCB;
|
||||
*pFCB = FCB;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: iface.c,v 1.53 2001/06/11 19:52:22 ekohl Exp $
|
||||
/* $Id: iface.c,v 1.54 2001/07/05 01:51:52 rex Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -103,6 +103,7 @@ VfatMountDevice (PDEVICE_EXTENSION DeviceExt, PDEVICE_OBJECT DeviceToMount)
|
|||
DeviceExt->Boot->FATCount * DeviceExt->Boot->FATSectors;
|
||||
DeviceExt->dataStart =
|
||||
DeviceExt->rootStart + DeviceExt->rootDirectorySectors;
|
||||
DeviceExt->BytesPerSector = DeviceExt->Boot->BytesPerSector;
|
||||
DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
|
||||
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
||||
DeviceExt->Boot->BytesPerSector;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
# $Id: makefile,v 1.31 2001/06/22 12:27:48 ekohl Exp $
|
||||
# $Id: makefile,v 1.32 2001/07/05 01:51:52 rex Exp $
|
||||
#
|
||||
#
|
||||
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 fcb.o $(TARGET).coff
|
||||
OBJECTS = blockdev.o cleanup.o close.o create.o dir.o direntry.o dirwr.o \
|
||||
fat.o fcb.o finfo.o iface.o rw.o shutdown.o string.o volume.o \
|
||||
$(TARGET).coff
|
||||
|
||||
LIBS = $(PATH_TO_TOP)/ntoskrnl/ntoskrnl.a
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: string.c,v 1.7 2001/05/10 04:02:21 rex Exp $
|
||||
/* $Id: string.c,v 1.8 2001/07/05 01:51:53 rex Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -151,7 +151,7 @@ BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
|
|||
PWCHAR
|
||||
vfatGetNextPathElement (PWCHAR pFileName)
|
||||
{
|
||||
if (*pFileName != L'\0')
|
||||
if (*pFileName == L'\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: vfat.h,v 1.31 2001/06/14 10:02:59 ekohl Exp $ */
|
||||
/* $Id: vfat.h,v 1.32 2001/07/05 01:51:53 rex Exp $ */
|
||||
|
||||
#include <ddk/ntifs.h>
|
||||
|
||||
|
@ -49,7 +49,7 @@ struct _FATDirEntry {
|
|||
unsigned long FileSize;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _FATDirEntry FATDirEntry;
|
||||
typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
|
||||
|
||||
struct _slot
|
||||
{
|
||||
|
@ -87,10 +87,11 @@ typedef struct
|
|||
PBCB Fat12StorageBcb;
|
||||
BootSector *Boot;
|
||||
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
||||
int BytesPerSector;
|
||||
int FATEntriesPerSector, FATUnit;
|
||||
ULONG BytesPerCluster;
|
||||
ULONG FatType;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
|
||||
|
||||
typedef struct _VFATFCB
|
||||
{
|
||||
|
@ -105,6 +106,7 @@ typedef struct _VFATFCB
|
|||
PDEVICE_EXTENSION pDevExt;
|
||||
LIST_ENTRY FcbListEntry;
|
||||
struct _VFATFCB* parentFcb;
|
||||
BOOL isCacheInitialized;
|
||||
} VFATFCB, *PVFATFCB;
|
||||
|
||||
typedef struct _VFATCCB
|
||||
|
@ -120,6 +122,9 @@ typedef struct _VFATCCB
|
|||
// PSTRING DirectorySearchPattern;// for DirectoryControl ?
|
||||
} VFATCCB, *PVFATCCB;
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
|
||||
#define TAG_CCB TAG('V', 'C', 'C', 'B')
|
||||
|
||||
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
|
||||
|
||||
|
@ -249,6 +254,12 @@ BOOL vfatIsFileNameValid (PWCHAR pFileName);
|
|||
/*
|
||||
* functions from fat.c
|
||||
*/
|
||||
NTSTATUS
|
||||
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG FirstCluster,
|
||||
ULONG FileOffset,
|
||||
PULONG Cluster,
|
||||
BOOLEAN Extend);
|
||||
ULONG
|
||||
ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG Cluster);
|
||||
|
@ -286,9 +297,9 @@ WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
|||
ULONG ClusterToWrite,
|
||||
ULONG NewValue);
|
||||
|
||||
/*
|
||||
* From create.c
|
||||
*/
|
||||
/* --------------------------------------------------------- create.c */
|
||||
|
||||
void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName);
|
||||
NTSTATUS
|
||||
ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
|
||||
NTSTATUS
|
||||
|
@ -296,6 +307,18 @@ VfatOpenFile(PDEVICE_EXTENSION DeviceExt,
|
|||
PFILE_OBJECT FileObject,
|
||||
PWSTR FileName);
|
||||
|
||||
/* ----------------------------------------------- DirEntry Functions */
|
||||
|
||||
ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
PFAT_DIR_ENTRY pDirEntry);
|
||||
BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
|
||||
void vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName);
|
||||
NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pDirectoryFCB,
|
||||
ULONG * pDirectoryIndex,
|
||||
PWSTR pLongFileName,
|
||||
PFAT_DIR_ENTRY pDirEntry);
|
||||
|
||||
/* ----------------------------------------------------- FCB Functions */
|
||||
|
||||
PVFATFCB vfatNewFCB (PWCHAR pFileName);
|
||||
|
@ -306,12 +329,25 @@ void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
|
|||
PVFATFCB pFCB);
|
||||
PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
|
||||
PWSTR pFileName);
|
||||
NTSTATUS vfatRequestAndValidateRegion (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pFCB,
|
||||
ULONG pOffset,
|
||||
PVOID * pBuffer,
|
||||
PCACHE_SEGMENT * pCacheSegment,
|
||||
BOOL pExtend);
|
||||
NTSTATUS vfatReleaseRegion (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pFCB,
|
||||
PCACHE_SEGMENT pCacheSegment);
|
||||
PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
|
||||
PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
|
||||
BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB);
|
||||
PVFATFCB vfatDirFindFile (PDEVICE_EXTENSION pVCB,
|
||||
NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||
PVFATFCB fcb,
|
||||
PFILE_OBJECT fileObject);
|
||||
NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
|
||||
PVFATFCB parentFCB,
|
||||
const PWSTR elementName);
|
||||
PWSTR elementName,
|
||||
PVFATFCB * fileFCB);
|
||||
NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
||||
PVFATFCB *pParentFCB,
|
||||
PVFATFCB *pFCB,
|
||||
|
|
Loading…
Reference in a new issue