reactos/reactos/drivers/fs/vfat/direntry.c

207 lines
5.8 KiB
C
Raw Normal View History

2002-10-01 Casper S. Hornstrup <chorns@users.sourceforge.net> * drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. * drivers/fs/cdfs/fcb.c: Ditto. * drivers/fs/cdfs/fsctl.c: Ditto. * drivers/fs/cdfs/rw.c: Ditto. * drivers/fs/ext2/dir.c: Ditto. * drivers/fs/ext2/inode.c: Ditto. * drivers/fs/ext2/rw.c: Ditto. * drivers/fs/ext2/super.c: Ditto. * drivers/fs/minix/blockdev.c: Ditto. * drivers/fs/minix/cache.c: Ditto. * drivers/fs/minix/inode.c: Ditto. * drivers/fs/minix/rw.c: Ditto. * drivers/fs/ntfs/fcb.c: Ditto. * drivers/fs/ntfs/ntfs.h: Ditto. * drivers/fs/vfat/create.c: Ditto. * drivers/fs/vfat/direntry.c: Ditto. * drivers/fs/vfat/dirwr.c: Ditto. * drivers/fs/vfat/fat.c: Ditto. * drivers/fs/vfat/fcb.c: Ditto. * drivers/fs/vfat/fsctl.c: Ditto. * drivers/fs/vfat/rw.c: Ditto. * drivers/storage/class2/class2.c: Ditto. * drivers/storage/scsiport/scsiport.c: Ditto. * hal/halx86/adapter.c: Ditto. * hal/halx86/mp.c: Ditto. * include/ddk/mmfuncs.h: Ditto. * include/ddk/mmtypes.h: Ditto. * include/ddk/i386/pagesize.h: Ditto. * include/ntdll/pagesize.h: Ditto. * lib/kernel32/process/create.c: Ditto. * lib/kernel32/thread/thread.c: Ditto. * lib/ntdll/ldr/utils.c: Ditto. * lib/ntdll/rtl/env.c: Ditto. * lib/ntdll/rtl/heap.c: Ditto. * lib/ntdll/rtl/ppb.c: Ditto. * lib/ntdll/rtl/process.c: Ditto. * lib/ntdll/rtl/thread.c: Ditto. * ntoskrnl/cc/copy.c: Ditto. * ntoskrnl/cc/view.c: Ditto. * ntoskrnl/ex/sysinfo.c: Ditto. * ntoskrnl/include/internal/i386/mm.h: Ditto. * ntoskrnl/io/mdl.c: Ditto. * ntoskrnl/ke/kthread.c: Ditto. * ntoskrnl/ke/i386/kernel.c: Ditto. * ntoskrnl/ldr/init.c: Ditto. * ntoskrnl/ldr/loader.c: Ditto. * ntoskrnl/mm/anonmem.c: Ditto. * ntoskrnl/mm/cont.c: Ditto. * ntoskrnl/mm/freelist.c: Ditto. * ntoskrnl/mm/iospace.c: Ditto. * ntoskrnl/mm/kmap.c: Ditto. * ntoskrnl/mm/marea.c: Ditto. * ntoskrnl/mm/mdl.c: Ditto. * ntoskrnl/mm/mminit.c: Ditto. * ntoskrnl/mm/ncache.c: Ditto. * ntoskrnl/mm/npool.c: Ditto. * ntoskrnl/mm/pagefile.c: Ditto. * ntoskrnl/mm/pageop.c: Ditto. * ntoskrnl/mm/section.c: Ditto. * ntoskrnl/mm/slab.c: Ditto. * ntoskrnl/mm/i386/page.c: Ditto. * ntoskrnl/ob/handle.c: Ditto. * ntoskrnl/ps/create.c: Ditto. * ntoskrnl/ps/process.c: Ditto. * ntoskrnl/ps/w32call.c: Ditto. * subsys/win32k/include/object.h: Ditto. svn path=/trunk/; revision=3594
2002-10-01 19:27:25 +00:00
/* $Id: direntry.c,v 1.9 2002/10/01 19:27:17 chorns 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"
2002-10-01 Casper S. Hornstrup <chorns@users.sourceforge.net> * drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. * drivers/fs/cdfs/fcb.c: Ditto. * drivers/fs/cdfs/fsctl.c: Ditto. * drivers/fs/cdfs/rw.c: Ditto. * drivers/fs/ext2/dir.c: Ditto. * drivers/fs/ext2/inode.c: Ditto. * drivers/fs/ext2/rw.c: Ditto. * drivers/fs/ext2/super.c: Ditto. * drivers/fs/minix/blockdev.c: Ditto. * drivers/fs/minix/cache.c: Ditto. * drivers/fs/minix/inode.c: Ditto. * drivers/fs/minix/rw.c: Ditto. * drivers/fs/ntfs/fcb.c: Ditto. * drivers/fs/ntfs/ntfs.h: Ditto. * drivers/fs/vfat/create.c: Ditto. * drivers/fs/vfat/direntry.c: Ditto. * drivers/fs/vfat/dirwr.c: Ditto. * drivers/fs/vfat/fat.c: Ditto. * drivers/fs/vfat/fcb.c: Ditto. * drivers/fs/vfat/fsctl.c: Ditto. * drivers/fs/vfat/rw.c: Ditto. * drivers/storage/class2/class2.c: Ditto. * drivers/storage/scsiport/scsiport.c: Ditto. * hal/halx86/adapter.c: Ditto. * hal/halx86/mp.c: Ditto. * include/ddk/mmfuncs.h: Ditto. * include/ddk/mmtypes.h: Ditto. * include/ddk/i386/pagesize.h: Ditto. * include/ntdll/pagesize.h: Ditto. * lib/kernel32/process/create.c: Ditto. * lib/kernel32/thread/thread.c: Ditto. * lib/ntdll/ldr/utils.c: Ditto. * lib/ntdll/rtl/env.c: Ditto. * lib/ntdll/rtl/heap.c: Ditto. * lib/ntdll/rtl/ppb.c: Ditto. * lib/ntdll/rtl/process.c: Ditto. * lib/ntdll/rtl/thread.c: Ditto. * ntoskrnl/cc/copy.c: Ditto. * ntoskrnl/cc/view.c: Ditto. * ntoskrnl/ex/sysinfo.c: Ditto. * ntoskrnl/include/internal/i386/mm.h: Ditto. * ntoskrnl/io/mdl.c: Ditto. * ntoskrnl/ke/kthread.c: Ditto. * ntoskrnl/ke/i386/kernel.c: Ditto. * ntoskrnl/ldr/init.c: Ditto. * ntoskrnl/ldr/loader.c: Ditto. * ntoskrnl/mm/anonmem.c: Ditto. * ntoskrnl/mm/cont.c: Ditto. * ntoskrnl/mm/freelist.c: Ditto. * ntoskrnl/mm/iospace.c: Ditto. * ntoskrnl/mm/kmap.c: Ditto. * ntoskrnl/mm/marea.c: Ditto. * ntoskrnl/mm/mdl.c: Ditto. * ntoskrnl/mm/mminit.c: Ditto. * ntoskrnl/mm/ncache.c: Ditto. * ntoskrnl/mm/npool.c: Ditto. * ntoskrnl/mm/pagefile.c: Ditto. * ntoskrnl/mm/pageop.c: Ditto. * ntoskrnl/mm/section.c: Ditto. * ntoskrnl/mm/slab.c: Ditto. * ntoskrnl/mm/i386/page.c: Ditto. * ntoskrnl/ob/handle.c: Ditto. * ntoskrnl/ps/create.c: Ditto. * ntoskrnl/ps/process.c: Ditto. * ntoskrnl/ps/w32call.c: Ditto. * subsys/win32k/include/object.h: Ditto. svn path=/trunk/; revision=3594
2002-10-01 19:27:25 +00:00
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
(CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector)))
ULONG
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
PFAT_DIR_ENTRY pFatDirEntry)
{
ULONG cluster;
if (pDeviceExt->FatInfo.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;
}
BOOL
vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry)
{
return pFatDirEntry->Attrib == 0x28;
}
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)
{
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt);
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt);
PVOID currentPage = NULL;
FATDirEntry * fatDirEntry;
slot * longNameEntry;
ULONG cpos;
LARGE_INTEGER FileOffset;
PVOID Context;
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
pDeviceExt,
pDirectoryFCB,
*pDirectoryIndex,
pLongFileName,
pDirEntry);
*pLongFileName = 0;
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, &currentPage))
{
return STATUS_UNSUCCESSFUL;
}
while (TRUE)
{
fatDirEntry = (FATDirEntry *) currentPage;
if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
{
DPRINT ("end of directory, returning no more entries\n");
CcUnpinData(Context);
return STATUS_NO_MORE_ENTRIES;
}
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage])
&& !vfatIsDirEntryDeleted (&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_CACHEPAGE(pDeviceExt))
{
indexInPage = 0;
pageNumber++;
CcUnpinData(Context);
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, &currentPage))
{
return STATUS_UNSUCCESSFUL;
}
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_CACHEPAGE(pDeviceExt))
{
indexInPage = 0;
pageNumber++;
CcUnpinData(Context);
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, &currentPage))
{
return STATUS_UNSUCCESSFUL;
}
}
}
else
{
memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY));
(*pDirectoryIndex)++;
break;
}
}
CcUnpinData(Context);
return STATUS_SUCCESS;
}