From 11361e2730cec3eb31464cfa9d39c470d4bb581b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 2 Oct 2009 13:59:51 +0000 Subject: [PATCH] [fastfat_new] - Fail with an error if file can't be opened. - Implement FatCreateDcb, actually create DCBs for all parsed directories in the path. - Set file size in an advanced FSRTL header for a file. - Implement a small helper function for setting full names in FCB/DCB like it's done in the reference driver. svn path=/trunk/; revision=43256 --- .../drivers/filesystems/fastfat_new/create.c | 23 ++++-- reactos/drivers/filesystems/fastfat_new/dir.c | 41 ++++++++++ .../drivers/filesystems/fastfat_new/fastfat.h | 12 ++- .../filesystems/fastfat_new/fatstruc.h | 2 + reactos/drivers/filesystems/fastfat_new/fcb.c | 82 ++++++++++++++++++- 5 files changed, 153 insertions(+), 7 deletions(-) diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c index 0aec6378d18..9a0b94701b1 100644 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ b/reactos/drivers/filesystems/fastfat_new/create.c @@ -63,6 +63,7 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, CHAR AnsiNameBuf[512]; PFCB Fcb; NTSTATUS Status; + FF_FILE *FileHandle; /* Check for create file option and fail */ if (CreateDisposition == FILE_CREATE) @@ -73,9 +74,6 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, // TODO: Check more params - /* Create a new FCB for this file */ - Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb); - /* Convert the name to ANSI */ AnsiName.Buffer = AnsiNameBuf; AnsiName.Length = 0; @@ -88,7 +86,16 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, } /* Open the file with FullFAT */ - Fcb->FatHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, NULL); + FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, NULL); + + if (!FileHandle) + { + Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now + return Iosb; + } + + /* Create a new FCB for this file */ + Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb, FileHandle); // TODO: Check if overwrite is needed @@ -505,7 +512,13 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, /* Break if came to the end */ if (!RemainingPart.Length) break; - // TODO: Create a DCB for this entry + /* Create a DCB for this entry */ + ParentDcb = FatCreateDcb(IrpContext, + Vcb, + ParentDcb); + + /* Set its name */ + FatSetFullNameInFcb(ParentDcb, &FirstName); } // TODO: Try to open directory diff --git a/reactos/drivers/filesystems/fastfat_new/dir.c b/reactos/drivers/filesystems/fastfat_new/dir.c index 4cd4e0064c8..0c3e8e71d1a 100644 --- a/reactos/drivers/filesystems/fastfat_new/dir.c +++ b/reactos/drivers/filesystems/fastfat_new/dir.c @@ -123,5 +123,46 @@ FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, //FatCheckFreeDirentBitmap( IrpContext, Dcb ); } +PFCB +NTAPI +FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PFCB ParentDcb) +{ + 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); + + return Fcb; +} /* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index 2c2a6b673cc..c700278c398 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -74,6 +74,11 @@ VOID NTAPI FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); +PFCB NTAPI +FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PFCB ParentDcb); + /* -------------------------------------------------------- create.c */ NTSTATUS NTAPI @@ -264,7 +269,8 @@ PFCB NTAPI FatCreateFcb( IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, - IN PFCB ParentDcb); + IN PFCB ParentDcb, + IN FF_FILE *FileHandle); NTSTATUS FatOpenFcb( @@ -282,6 +288,10 @@ FatFindFcb(PFAT_IRP_CONTEXT IrpContext, PCCB NTAPI FatCreateCcb(); +VOID NTAPI +FatSetFullNameInFcb(PFCB Fcb, + PUNICODE_STRING Name); + /* ------------------------------------------------------------ rw.c */ NTSTATUS NTAPI diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h index 962e06e606e..5d3588334b5 100644 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ b/reactos/drivers/filesystems/fastfat_new/fatstruc.h @@ -275,6 +275,8 @@ typedef struct _FCB WCHAR ShortNameBuffer[0xc]; /* Full file name */ UNICODE_STRING FullFileName; + /* Long name with exact case */ + UNICODE_STRING ExactCaseLongName; /* A copy of fat attribute byte */ UCHAR DirentFatFlags; /* File basic info */ diff --git a/reactos/drivers/filesystems/fastfat_new/fcb.c b/reactos/drivers/filesystems/fastfat_new/fcb.c index ed14d74edc8..eee209787e8 100644 --- a/reactos/drivers/filesystems/fastfat_new/fcb.c +++ b/reactos/drivers/filesystems/fastfat_new/fcb.c @@ -11,6 +11,8 @@ #define NDEBUG #include "fastfat.h" +#define TAG_FILENAME 'fBnF' + /* FUNCTIONS ****************************************************************/ FSRTL_COMPARISON_RESULT @@ -109,7 +111,8 @@ PFCB NTAPI FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, - IN PFCB ParentDcb) + IN PFCB ParentDcb, + IN FF_FILE *FileHandle) { PFCB Fcb; @@ -141,6 +144,11 @@ FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext, Fcb->ParentFcb = ParentDcb; Fcb->Vcb = Vcb; + /* Set file handle and sizes */ + Fcb->Header.FileSize.LowPart = FileHandle->Filesize; + Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize; + Fcb->FatHandle = FileHandle; + return Fcb; } @@ -161,4 +169,76 @@ FatCreateCcb() return Ccb; } +VOID +NTAPI +FatSetFullNameInFcb(PFCB Fcb, + PUNICODE_STRING Name) +{ + PUNICODE_STRING ParentName; + + /* Make sure this FCB's name wasn't already set */ + ASSERT(Fcb->FullFileName.Buffer == NULL); + + /* First of all, check exact case name */ + if (Fcb->ExactCaseLongName.Buffer) + { + ASSERT(Fcb->ExactCaseLongName.Length != 0); + + /* Use exact case name */ + Name = &Fcb->ExactCaseLongName; + } + + /* Treat root dir different */ + if (FatNodeType(Fcb->ParentFcb) == FAT_NTC_ROOT_DCB) + { + /* Set lengths */ + Fcb->FullFileName.MaximumLength = sizeof(WCHAR) + Name->Length; + Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength; + + /* Allocate a buffer */ + Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool, + Fcb->FullFileName.Length, + TAG_FILENAME); + + /* Prefix with a backslash */ + Fcb->FullFileName.Buffer[0] = L'\\'; + + /* Copy the name here */ + RtlCopyMemory(&Fcb->FullFileName.Buffer[1], + &Name->Buffer[0], + Name->Length ); + } + else + { + ParentName = &Fcb->ParentFcb->FullFileName; + + /* Check if parent's name is set */ + if (!ParentName->Buffer) + return; + + /* Set lengths */ + Fcb->FullFileName.MaximumLength = + ParentName->Length + sizeof(WCHAR) + Name->Length; + Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength; + + /* Allocate a buffer */ + Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool, + Fcb->FullFileName.Length, + TAG_FILENAME ); + + /* Copy parent's name here */ + RtlCopyMemory(&Fcb->FullFileName.Buffer[0], + &ParentName->Buffer[0], + ParentName->Length ); + + /* Add a backslash */ + Fcb->FullFileName.Buffer[ParentName->Length / sizeof(WCHAR)] = L'\\'; + + /* Copy given name here */ + RtlCopyMemory(&Fcb->FullFileName.Buffer[(ParentName->Length / sizeof(WCHAR)) + 1], + &Name->Buffer[0], + Name->Length ); + } +} + /* EOF */