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/fastfat... ============================================================================== --- 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/fastfat... ============================================================================== --- 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/fastfat... ============================================================================== --- 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/fastfat... ============================================================================== --- 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/fastfat... ============================================================================== --- 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/fastfat... ============================================================================== --- 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 */