reactos/drivers/filesystems/fastfat_new/dir.c
Amine Khaldi 785bea480a [CMAKE]
- Sync with trunk r51050.

svn path=/branches/cmake-bringup/; revision=51154
2011-03-26 13:00:21 +00:00

280 lines
7.6 KiB
C

/*
* PROJECT: ReactOS FAT file system driver
* LICENSE: GNU GPLv3 as published by the Free Software Foundation
* FILE: drivers/filesystems/fastfat/dir.c
* PURPOSE: Directory Control
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include "fastfat.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
FatDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT1("FatDirectoryControl()\n");
return STATUS_NOT_IMPLEMENTED;
}
VOID
NTAPI
FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb)
{
PFCB Dcb;
/* Make sure it's not already created */
ASSERT(!Vcb->RootDcb);
/* Allocate the DCB */
Dcb = FsRtlAllocatePoolWithTag(NonPagedPool,
sizeof(FCB),
TAG_FCB);
/* Zero it */
RtlZeroMemory(Dcb, sizeof(FCB));
/* Assign it to the VCB */
Vcb->RootDcb = Dcb;
/* Set its header */
Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
Dcb->Header.NodeByteSize = sizeof(FCB);
/* FCB is in a good condition */
Dcb->Condition = FcbGood;
/* Initialize FCB's resource */
Dcb->Header.Resource = &Dcb->Resource;
ExInitializeResourceLite(&Dcb->Resource);
/* Initialize Paging Io resource*/
Dcb->Header.PagingIoResource = &Dcb->PagingIoResource;
ExInitializeResourceLite(&Dcb->PagingIoResource);
/* Initialize a list of parent DCBs*/
InitializeListHead(&Dcb->ParentDcbLinks);
/* Set VCB */
Dcb->Vcb = Vcb;
/* Initialize parent's DCB list */
InitializeListHead(&Dcb->Dcb.ParentDcbList);
/* Initialize the full file name */
Dcb->FullFileName.Buffer = L"\\";
Dcb->FullFileName.Length = 1 * sizeof(WCHAR);
Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR);
Dcb->ShortName.Name.Ansi.Buffer = "\\";
Dcb->ShortName.Name.Ansi.Length = 1;
Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR);
/* Fill dirent attribute byte copy */
Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;
/* Initialize advanced FCB header fields */
ExInitializeFastMutex(&Dcb->HeaderMutex);
FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex);
/* Set up first cluster field depending on FAT type */
if (TRUE/*FatIsFat32(Vcb)*/)
{
/* First cluster is really the first cluster of this volume */
Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster;
/* Calculate size of FAT32 root dir */
Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF;
//FatLookupFileAllocationSize(IrpContext, Dcb);
DPRINT1("Calculation of a size of a root dir is missing!\n");
Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart;
}
else
{
#if 0
/* Add MCB entry */
FatAddMcbEntry(Vcb,
&Dcb->Mcb,
0,
FatRootDirectoryLbo(&Vcb->Bpb),
FatRootDirectorySize(&Vcb->Bpb));
/* Set a real size of the root directory */
Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb);
Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart;
#endif
UNIMPLEMENTED;
}
}
PFCB
NTAPI
FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFCB ParentDcb,
IN FF_FILE *FileHandle)
{
PFCB Fcb;
/* Allocate it and zero it */
Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
RtlZeroMemory(Fcb, sizeof(FCB));
/* Set node types */
Fcb->Header.NodeTypeCode = FAT_NTC_DCB;
Fcb->Header.NodeByteSize = sizeof(FCB);
Fcb->Condition = FcbGood;
/* Initialize resources */
Fcb->Header.Resource = &Fcb->Resource;
ExInitializeResourceLite(Fcb->Header.Resource);
Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
ExInitializeResourceLite(Fcb->Header.PagingIoResource);
/* Initialize mutexes */
Fcb->Header.FastMutex = &Fcb->HeaderMutex;
ExInitializeFastMutex(&Fcb->HeaderMutex);
FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
/* Insert into parent's DCB list */
InsertHeadList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);
/* Set backlinks */
Fcb->ParentFcb = ParentDcb;
Fcb->Vcb = Vcb;
/* Initialize parent dcb list */
InitializeListHead(&Fcb->Dcb.ParentDcbList);
/* Set FullFAT handle */
Fcb->FatHandle = FileHandle;
/* Set names */
if (FileHandle)
{
FatSetFcbNames(IrpContext, Fcb);
/* Ensure the full name is set */
FatSetFullFileNameInFcb(IrpContext, Fcb);
}
return Fcb;
}
IO_STATUS_BLOCK
NTAPI
FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN PVCB Vcb,
IN PFCB Dcb,
IN PACCESS_MASK DesiredAccess,
IN USHORT ShareAccess,
IN ULONG CreateDisposition,
IN BOOLEAN NoEaKnowledge,
IN BOOLEAN DeleteOnClose)
{
IO_STATUS_BLOCK Iosb = {{0}};
PCCB Ccb;
/* Exclusively lock this FCB */
FatAcquireExclusiveFcb(IrpContext, Dcb);
/* Check if it's a delete-on-close of a root DCB */
if (FatNodeType(Dcb) == FAT_NTC_ROOT_DCB && DeleteOnClose)
{
Iosb.Status = STATUS_CANNOT_DELETE;
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
/*if (NoEaKnowledge && NodeType(Dcb) != FAT_NTC_ROOT_DCB &&
!FatIsFat32(Vcb))
{
UNIMPLEMENTED;
}*/
/* Check the create disposition and desired access */
if ((CreateDisposition != FILE_OPEN) &&
(CreateDisposition != FILE_OPEN_IF))
{
Iosb.Status = STATUS_OBJECT_NAME_COLLISION;
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
#if 0
if (!FatCheckFileAccess(IrpContext,
Dcb->DirentFatFlags,
DesiredAccess))
{
Iosb.Status = STATUS_ACCESS_DENIED;
try_return( Iosb );
}
#endif
/* If it's already opened - check share access */
if (Dcb->OpenCount > 0)
{
Iosb.Status = IoCheckShareAccess(*DesiredAccess,
ShareAccess,
FileObject,
&Dcb->ShareAccess,
TRUE);
if (!NT_SUCCESS(Iosb.Status))
{
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
}
else
{
IoSetShareAccess(*DesiredAccess,
ShareAccess,
FileObject,
&Dcb->ShareAccess);
}
/* Set the file object */
Ccb = FatCreateCcb();
FatSetFileObject(FileObject,
UserDirectoryOpen,
Dcb,
Ccb);
/* Increase counters */
Dcb->UncleanCount++;
Dcb->OpenCount++;
Vcb->OpenFileCount++;
if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
/* Set delete on close */
if (DeleteOnClose)
SetFlag(Ccb->Flags, CCB_DELETE_ON_CLOSE);
/* Clear delay close flag */
ClearFlag(Dcb->State, FCB_STATE_DELAY_CLOSE);
/* That's it */
Iosb.Status = STATUS_SUCCESS;
Iosb.Information = FILE_OPENED;
/* Release the lock */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
/* EOF */