Author: fireball
Date: Sat Oct 17 15:18:29 2009
New Revision: 43528
URL:
http://svn.reactos.org/svn/reactos?rev=43528&view=rev
Log:
[fastfat_new]
- Implement FatiOpenExistingFcb.
- Make FatGetFcbUnicodeName supporting DCBs.
- Implement FF_OpenW wrapper around FullFAT to support opening files/dirs using a unicode
name.
Modified:
trunk/reactos/drivers/filesystems/fastfat_new/create.c
trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
trunk/reactos/drivers/filesystems/fastfat_new/fcb.c
trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c
trunk/reactos/drivers/filesystems/fastfat_new/lock.c
Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] Sat Oct 17
15:18:29 2009
@@ -10,16 +10,6 @@
#define NDEBUG
#include "fastfat.h"
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-RtlUpcaseUnicodeStringToCountedOemString(
- IN OUT POEM_STRING DestinationString,
- IN PCUNICODE_STRING SourceString,
- IN BOOLEAN AllocateDestinationString
-);
-
/* FUNCTIONS *****************************************************************/
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] Sat Oct 17
15:18:29 2009
@@ -34,6 +34,15 @@
{ \
ExReleaseResourceLite(&(FatGlobalData.Resource)); \
}
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUpcaseUnicodeStringToCountedOemString(
+ IN OUT POEM_STRING DestinationString,
+ IN PCUNICODE_STRING SourceString,
+ IN BOOLEAN AllocateDestinationString
+);
/* ------------------------------------------------------ shutdown.c */
@@ -211,6 +220,14 @@
NTSTATUS NTAPI
FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+VOID NTAPI
+FatOplockComplete(IN PVOID Context,
+ IN PIRP Irp);
+
+VOID NTAPI
+FatPrePostIrp(IN PVOID Context,
+ IN PIRP Irp);
+
/* --------------------------------------------------------- fsctl.c */
NTSTATUS NTAPI
@@ -220,6 +237,10 @@
NTSTATUS NTAPI FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS NTAPI FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+/* --------------------------------------------------------- fullfat.c */
+
+FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR
*pError);
/* --------------------------------------------------------- iface.c */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] Sat Oct 17
15:18:29 2009
@@ -133,9 +133,10 @@
PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun;
} FAT_METHODS, *PFAT_METHODS;
-#define VCB_STATE_FLAG_LOCKED 0x01
-#define VCB_STATE_FLAG_DIRTY 0x02
-#define VCB_STATE_MOUNTED_DIRTY 0x04
+#define VCB_STATE_FLAG_LOCKED 0x01
+#define VCB_STATE_FLAG_DIRTY 0x02
+#define VCB_STATE_MOUNTED_DIRTY 0x04
+#define VCB_STATE_CREATE_IN_PROGRESS 0x08
typedef enum _VCB_CONDITION
{
@@ -249,6 +250,8 @@
#define FCB_STATE_HAS_NAMES 0x01
#define FCB_STATE_HAS_UNICODE_NAME 0x02
+#define FCB_STATE_PAGEFILE 0x04
+#define FCB_STATE_DELAY_CLOSE 0x08
typedef struct _FCB
{
@@ -264,7 +267,6 @@
ERESOURCE Resource; // nonpaged!
ERESOURCE PagingIoResource; // nonpaged!
- FILE_LOCK Lock;
/* First cluster in the fat allocation chain */
ULONG FirstClusterOfFile;
/* A list of all FCBs of that DCB */
@@ -307,6 +309,13 @@
{
struct
{
+ /* File and Op locks */
+ FILE_LOCK Lock;
+ OPLOCK Oplock;
+ } Fcb;
+
+ struct
+ {
/* A list of all FCBs/DCBs opened under this DCB */
LIST_ENTRY ParentDcbList;
/* Directory data stream (just handy to have it). */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fcb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] Sat Oct 17 15:18:29
2009
@@ -191,9 +191,243 @@
OUT PBOOLEAN OplockPostIrp)
{
IO_STATUS_BLOCK Iosb = {{0}};
-
- Iosb.Status = STATUS_NOT_IMPLEMENTED;
- UNIMPLEMENTED;
+ ACCESS_MASK AddedAccess = 0;
+ BOOLEAN Hidden;
+ BOOLEAN System;
+ PCCB Ccb = NULL;
+ NTSTATUS Status;
+
+ /* Acquire exclusive FCB lock */
+ (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb);
+
+ *OplockPostIrp = FALSE;
+
+ /* Check if there is a batch oplock */
+ if (FsRtlCurrentBatchOplock(&Fcb->Fcb.Oplock))
+ {
+ /* Return with a special information field */
+ Iosb.Information = FILE_OPBATCH_BREAK_UNDERWAY;
+
+ /* Check the oplock */
+ Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock,
+ IrpContext->Irp,
+ IrpContext,
+ FatOplockComplete,
+ FatPrePostIrp);
+
+ if (Iosb.Status != STATUS_SUCCESS &&
+ Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS)
+ {
+ /* The Irp needs to be queued */
+ *OplockPostIrp = TRUE;
+
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+ }
+
+ /* Validate parameters and modify access */
+ if (CreateDisposition == FILE_CREATE)
+ {
+ Iosb.Status = STATUS_OBJECT_NAME_COLLISION;
+
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+ else if (CreateDisposition == FILE_SUPERSEDE)
+ {
+ SetFlag(AddedAccess, DELETE & ~(*DesiredAccess));
+ *DesiredAccess |= DELETE;
+ }
+ else if ((CreateDisposition == FILE_OVERWRITE) ||
+ (CreateDisposition == FILE_OVERWRITE_IF))
+ {
+ SetFlag(AddedAccess,
+ (FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+ & ~(*DesiredAccess) );
+
+ *DesiredAccess |= FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES;
+ }
+
+ // TODO: Check desired access
+
+ // TODO: Check if this file is readonly and DeleteOnClose is set
+
+ /* Validate disposition information */
+ if ((CreateDisposition == FILE_SUPERSEDE) ||
+ (CreateDisposition == FILE_OVERWRITE) ||
+ (CreateDisposition == FILE_OVERWRITE_IF))
+ {
+ // TODO: Get this attributes from the dirent
+ Hidden = FALSE;
+ System = FALSE;
+
+ if ((Hidden && !FlagOn(FileAttributes, FILE_ATTRIBUTE_HIDDEN)) ||
+ (System && !FlagOn(FileAttributes, FILE_ATTRIBUTE_SYSTEM)))
+ {
+ DPRINT1("Hidden/system attributes don't match\n");
+
+ Iosb.Status = STATUS_ACCESS_DENIED;
+
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+
+ // TODO: Check for write protected volume
+ }
+
+ /* Check share access */
+ Iosb.Status = IoCheckShareAccess(*DesiredAccess,
+ ShareAccess,
+ FileObject,
+ &Fcb->ShareAccess,
+ FALSE);
+ if (!NT_SUCCESS(Iosb.Status))
+ {
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+
+ /* Check the oplock status after checking for share access */
+ Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock,
+ IrpContext->Irp,
+ IrpContext,
+ FatOplockComplete,
+ FatPrePostIrp );
+
+ if (Iosb.Status != STATUS_SUCCESS &&
+ Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS)
+ {
+ /* The Irp needs to be queued */
+ *OplockPostIrp = TRUE;
+
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+
+ /* Set Fast I/O flag */
+ Fcb->Header.IsFastIoPossible = FALSE; //FatiIsFastIoPossible(Fcb);
+
+ /* Make sure image is not mapped */
+ if (DeleteOnClose || FlagOn(*DesiredAccess, FILE_WRITE_DATA))
+ {
+ /* Try to flush the image section */
+ if (!MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForWrite))
+ {
+ /* Yes, image section exists, set correct status code */
+ if (DeleteOnClose)
+ Iosb.Status = STATUS_CANNOT_DELETE;
+ else
+ Iosb.Status = STATUS_SHARING_VIOLATION;
+
+ /* Release the FCB and return */
+ FatReleaseFcb(IrpContext, Fcb);
+ return Iosb;
+ }
+ }
+
+ /* Flush the cache if it's non-cached non-pagefile access */
+ if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING) &&
+ Fcb->SectionObjectPointers.DataSectionObject &&
+ !FlagOn(Fcb->State, FCB_STATE_PAGEFILE))
+ {
+ /* Set the flag that create is in progress */
+ SetFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS);
+
+ /* Flush the cache */
+ CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL);
+
+ /* Acquire and release Paging I/O resource before purging the cache section
+ to let lazy writer finish */
+ ExAcquireResourceExclusiveLite( Fcb->Header.PagingIoResource, TRUE);
+ ExReleaseResourceLite( Fcb->Header.PagingIoResource );
+
+ /* Delete the cache section */
+ CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE);
+
+ /* Clear the flag */
+ ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS);
+ }
+
+ /* Check create disposition flags and branch accordingly */
+ if (CreateDisposition == FILE_OPEN ||
+ CreateDisposition == FILE_OPEN_IF)
+ {
+ DPRINT("Opening a file\n");
+
+ /* Check if we need to bother with EA */
+ if (NoEaKnowledge && FALSE /* FatIsFat32(Vcb)*/)
+ {
+ UNIMPLEMENTED;
+ }
+
+ /* Set up file object */
+ Ccb = FatCreateCcb(IrpContext);
+ FatSetFileObject(FileObject,
+ UserFileOpen,
+ Fcb,
+ Ccb);
+
+ FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
+
+ /* The file is opened */
+ Iosb.Information = FILE_OPENED;
+ goto SuccComplete;
+ }
+ else if ((CreateDisposition == FILE_SUPERSEDE) ||
+ (CreateDisposition == FILE_OVERWRITE) ||
+ (CreateDisposition == FILE_OVERWRITE_IF))
+ {
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+ }
+ else
+ {
+ /* We can't get here */
+ KeBugCheckEx(0x23, CreateDisposition, 0, 0, 0);
+ }
+
+
+SuccComplete:
+ /* If all is fine */
+ if (Iosb.Status != STATUS_PENDING &&
+ NT_SUCCESS(Iosb.Status))
+ {
+ /* Update access if needed */
+ if (AddedAccess)
+ {
+ /* Remove added access flags from desired access */
+ ClearFlag(*DesiredAccess, AddedAccess);
+
+ /* Check share access */
+ Status = IoCheckShareAccess(*DesiredAccess,
+ ShareAccess,
+ FileObject,
+ &Fcb->ShareAccess,
+ TRUE);
+
+ /* Make sure it's success */
+ ASSERT(Status == STATUS_SUCCESS);
+ }
+ else
+ {
+ /* Update the share access */
+ IoUpdateShareAccess(FileObject, &Fcb->ShareAccess);
+ }
+
+ /* Clear the delay close */
+ ClearFlag(Fcb->State, FCB_STATE_DELAY_CLOSE);
+
+ /* Increase global volume counter */
+ Vcb->OpenFileCount++;
+
+ // TODO: Handle DeleteOnClose and OpenedAsDos by storing those flags in CCB
+ }
return Iosb;
}
@@ -213,11 +447,16 @@
OEM_STRING LongNameOem;
NTSTATUS Status;
- /* We support only files now, not directories */
- if (Fcb->Header.NodeTypeCode != FAT_NTC_FCB)
- {
- UNIMPLEMENTED;
- ASSERT(FALSE);
+ /* Make sure this FCB has a FullFAT handle associated with it */
+ if (Fcb->FatHandle == NULL &&
+ FatNodeType(Fcb) == FAT_NTC_DCB)
+ {
+ /* Open the dir with FullFAT */
+ Fcb->FatHandle = FF_OpenW(Fcb->Vcb->Ioman, &Fcb->FullFileName,
FF_MODE_DIR, NULL);
+ if (!Fcb->FatHandle)
+ {
+ ASSERT(FALSE);
+ }
}
/* Get the dir entry */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] Sat Oct 17
15:18:29 2009
@@ -77,4 +77,27 @@
return Count;
}
+FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR
*pError)
+{
+ OEM_STRING AnsiName;
+ CHAR AnsiNameBuf[512];
+ NTSTATUS Status;
+
+ /* Convert the name to ANSI */
+ AnsiName.Buffer = AnsiNameBuf;
+ AnsiName.Length = 0;
+ AnsiName.MaximumLength = sizeof(AnsiNameBuf);
+ RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf));
+ Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, pathW, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ ASSERT(FALSE);
+ }
+
+ DPRINT1("Opening '%s'\n", AnsiName.Buffer);
+
+ /* Call FullFAT's handler */
+ return FF_Open(pIoman, AnsiName.Buffer, Mode, pError);
+}
+
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/lock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/lock.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/lock.c [iso-8859-1] Sat Oct 17 15:18:29
2009
@@ -21,4 +21,20 @@
return STATUS_NOT_IMPLEMENTED;
}
+VOID
+NTAPI
+FatOplockComplete(IN PVOID Context,
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED;
+}
+
+VOID
+NTAPI
+FatPrePostIrp(IN PVOID Context,
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED;
+}
+
/* EOF */