diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c index 6530750ef21..846577a9a3f 100644 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ b/reactos/drivers/filesystems/fastfat_new/create.c @@ -41,6 +41,54 @@ FatiOpenRootDcb(IN PFAT_IRP_CONTEXT IrpContext, return Iosb; } +IO_STATUS_BLOCK +NTAPI +FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB ParentDcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG AllocationSize, + IN PFILE_FULL_EA_INFORMATION EaBuffer, + IN ULONG EaLength, + IN UCHAR FileAttributes, + IN ULONG CreateDisposition, + IN BOOLEAN IsPagingFile, + IN BOOLEAN DeleteOnClose, + IN BOOLEAN IsDosName) +{ + IO_STATUS_BLOCK Iosb = {{0}}; + PFCB Fcb; + + /* Check for create file option and fail */ + if (CreateDisposition == FILE_CREATE) + { + Iosb.Status = STATUS_OBJECT_NAME_COLLISION; + return Iosb; + } + + // TODO: Check more params + + /* Create a new FCB for this file */ + Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb); + + // TODO: Check if overwrite is needed + + // This is usual file open branch, without overwriting! + /* Set context and section object pointers */ + FatSetFileObject(FileObject, + UserFileOpen, + Fcb, + FatCreateCcb()); + FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; + + Iosb.Status = STATUS_SUCCESS; + Iosb.Information = FILE_OPENED; + + return Iosb; +} + NTSTATUS NTAPI FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, @@ -443,10 +491,35 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, // TODO: Create a DCB for this entry } - // Simulate that we opened the file - //Iosb.Information = FILE_OPENED; - Irp->IoStatus.Information = FILE_OPENED; - FileObject->SectionObjectPointer = (PSECTION_OBJECT_POINTERS)0x1; + // TODO: Try to open directory + + /* If end backslash here, then it's definately not permitted, + since we're opening files here */ + if (EndBackslash) + { + /* Complete the request */ + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + return Iosb.Status; + } + + /* Try to open the file */ + Iosb = FatiOpenExistingFile(IrpContext, + FileObject, + Vcb, + ParentDcb, + DesiredAccess, + ShareAccess, + AllocationSize, + EaBuffer, + EaLength, + FileAttributes, + CreateDisposition, + FALSE, + DeleteOnClose, + OpenedAsDos); + + Irp->IoStatus.Information = Iosb.Information; } /* Complete the request */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.c b/reactos/drivers/filesystems/fastfat_new/fastfat.c index 925d83adc39..f1bb21d1b88 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.c @@ -137,6 +137,7 @@ FatBuildIrpContext(PIRP Irp, /* Save IRP, MJ and MN */ IrpContext->Irp = Irp; + IrpContext->Stack = IrpSp; IrpContext->MajorFunction = IrpSp->MajorFunction; IrpContext->MinorFunction = IrpSp->MinorFunction; @@ -338,6 +339,34 @@ FatDecodeFileObject(IN PFILE_OBJECT FileObject, return TypeOfOpen; } +VOID +NTAPI +FatSetFileObject(PFILE_OBJECT FileObject, + TYPE_OF_OPEN TypeOfOpen, + PVOID Fcb, + PCCB Ccb) +{ + if (Fcb) + { + /* Check Fcb's type */ + if (FatNodeType(Fcb) == FAT_NTC_VCB) + { + FileObject->Vpb = ((PVCB)Fcb)->Vpb; + } + else + { + FileObject->Vpb = ((PFCB)Fcb)->Vcb->Vpb; + } + } + + /* Set FsContext */ + if (FileObject) + { + FileObject->FsContext = Fcb; + FileObject->FsContext2 = Ccb; + } +} + BOOLEAN NTAPI diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index 349f3b88b66..fdc7c8728ec 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -153,13 +153,11 @@ FatDecodeFileObject(IN PFILE_OBJECT FileObject, OUT PFCB *FcbOrDcb, OUT PCCB *Ccb); -/* --------------------------------------------------------- fcb.c */ - -PFCB NTAPI -FatFindFcb(PFAT_IRP_CONTEXT IrpContext, - PRTL_SPLAY_LINKS *RootNode, - PSTRING AnsiName, - PBOOLEAN IsDosName); +VOID NTAPI +FatSetFileObject(PFILE_OBJECT FileObject, + TYPE_OF_OPEN TypeOfOpen, + PVOID Fcb, + PCCB Ccb); /* --------------------------------------------------------- fullfat.c */ @@ -263,14 +261,11 @@ FatUnlinkFcbNames( IN PFCB ParentFcb, IN PFCB Fcb); -NTSTATUS +PFCB NTAPI FatCreateFcb( - OUT PFCB* CreatedFcb, IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB ParentFcb, - IN PDIR_ENTRY Dirent, - IN PUNICODE_STRING FileName, - IN PUNICODE_STRING LongFileName OPTIONAL); + IN PVCB Vcb, + IN PFCB ParentDcb); NTSTATUS FatOpenFcb( @@ -279,6 +274,15 @@ FatOpenFcb( IN PFCB ParentFcb, IN PUNICODE_STRING FileName); +PFCB NTAPI +FatFindFcb(PFAT_IRP_CONTEXT IrpContext, + PRTL_SPLAY_LINKS *RootNode, + PSTRING AnsiName, + PBOOLEAN IsDosName); + +PCCB NTAPI +FatCreateCcb(); + /* ------------------------------------------------------------ rw.c */ NTSTATUS NTAPI diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h index 6382f44760e..64fb5358327 100644 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ b/reactos/drivers/filesystems/fastfat_new/fatstruc.h @@ -19,6 +19,7 @@ typedef FAT_NODE_TYPE *PFAT_NODE_TYPE; #define FAT_NTC_FCB (CSHORT) 'CF' #define FAT_NTC_DCB (CSHORT) 'DF' #define FAT_NTC_ROOT_DCB (CSHORT) 'RFD' +#define FAT_NTC_CCB (CSHORT) 'BCC' typedef struct _FAT_GLOBAL_DATA { @@ -334,6 +335,9 @@ typedef struct _FAT_FIND_DIRENT_CONTEXT typedef struct _CCB { + CSHORT NodeTypeCode; + CSHORT NodeByteSize; + LARGE_INTEGER CurrentByteOffset; ULONG Entry; UNICODE_STRING SearchPattern; diff --git a/reactos/drivers/filesystems/fastfat_new/fcb.c b/reactos/drivers/filesystems/fastfat_new/fcb.c index 21e29384e68..ed14d74edc8 100644 --- a/reactos/drivers/filesystems/fastfat_new/fcb.c +++ b/reactos/drivers/filesystems/fastfat_new/fcb.c @@ -105,5 +105,60 @@ FatFindFcb(PFAT_IRP_CONTEXT IrpContext, return NULL; } +PFCB +NTAPI +FatCreateFcb(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_FCB; + 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 */ + InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks); + + /* Set backlinks */ + Fcb->ParentFcb = ParentDcb; + Fcb->Vcb = Vcb; + + return Fcb; +} + +PCCB +NTAPI +FatCreateCcb() +{ + PCCB Ccb; + + /* Allocate the CCB and zero it */ + Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB); + RtlZeroMemory(Ccb, sizeof(CCB)); + + /* Set mandatory header */ + Ccb->NodeTypeCode = FAT_NTC_FCB; + Ccb->NodeByteSize = sizeof(CCB); + + return Ccb; +} /* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/finfo.c b/reactos/drivers/filesystems/fastfat_new/finfo.c index 1aeb0d67237..54480e61052 100644 --- a/reactos/drivers/filesystems/fastfat_new/finfo.c +++ b/reactos/drivers/filesystems/fastfat_new/finfo.c @@ -13,12 +13,79 @@ /* FUNCTIONS ****************************************************************/ +NTSTATUS +NTAPI +FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, + IN PIRP Irp) +{ + PFILE_OBJECT FileObject; + PIO_STACK_LOCATION IrpSp; + FILE_INFORMATION_CLASS InfoClass; + TYPE_OF_OPEN FileType; + PVCB Vcb; + PFCB Fcb; + PCCB Ccb; + + /* Get IRP stack location */ + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + /* Get the file object */ + FileObject = IrpSp->FileObject; + + InfoClass = IrpSp->Parameters.QueryFile.FileInformationClass; + + DPRINT1("FatCommonQueryInformation\n", 0); + DPRINT1("\tIrp = %08lx\n", Irp); + DPRINT1("\tLength = %08lx\n", IrpSp->Parameters.QueryFile.Length); + DPRINT1("\tFileInformationClass = %08lx\n", InfoClass); + DPRINT1("\tBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer); + + FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); + + DPRINT1("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); + + return STATUS_SUCCESS; +} + NTSTATUS NTAPI FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("FatQueryInformation()\n"); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN TopLevel, CanWait; + PFAT_IRP_CONTEXT IrpContext; + + CanWait = TRUE; + TopLevel = FALSE; + Status = STATUS_INVALID_DEVICE_REQUEST; + + /* Get CanWait flag */ + if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) + CanWait = IoIsOperationSynchronous(Irp); + + /* Enter FsRtl critical region */ + FsRtlEnterFileSystem(); + + /* Set Top Level IRP if not set */ + if (IoGetTopLevelIrp() == NULL) + { + IoSetTopLevelIrp(Irp); + TopLevel = TRUE; + } + + /* Build an irp context */ + IrpContext = FatBuildIrpContext(Irp, CanWait); + + /* Perform the actual read */ + Status = FatiQueryInformation(IrpContext, Irp); + + /* Restore top level Irp */ + if (TopLevel) IoSetTopLevelIrp(NULL); + + /* Leave FsRtl critical region */ + FsRtlExitFileSystem(); + + return Status; } NTSTATUS diff --git a/reactos/drivers/filesystems/fastfat_new/rw.c b/reactos/drivers/filesystems/fastfat_new/rw.c index a2223fb7498..3e543f89b72 100644 --- a/reactos/drivers/filesystems/fastfat_new/rw.c +++ b/reactos/drivers/filesystems/fastfat_new/rw.c @@ -18,19 +18,28 @@ NTSTATUS NTAPI FatiRead(PFAT_IRP_CONTEXT IrpContext) { - CSHORT FcbType; ULONG NumberOfBytes; + LARGE_INTEGER ByteOffset; + PFILE_OBJECT FileObject; + TYPE_OF_OPEN OpenType; + PIO_STACK_LOCATION IrpSp = IrpContext->Stack; + PFCB Fcb; + PVCB Vcb; + PCCB Ccb; - FcbType = *((PCSHORT) IrpContext->FileObject->FsContext); - NumberOfBytes = IrpContext->Stack->Parameters.Read.Length; + FileObject = IrpSp->FileObject; + NumberOfBytes = IrpSp->Parameters.Read.Length; + ByteOffset = IrpSp->Parameters.Read.ByteOffset; if (NumberOfBytes == 0) { FatCompleteRequest(IrpContext, IrpContext->Irp, STATUS_SUCCESS); return STATUS_SUCCESS; } - //if (FcbType == FAT_NTC_VCB) + + OpenType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - DPRINT1("FatiRead()\n"); + DPRINT1("FatiRead() Fcb %p, Name %wZ, Offset %d, Length %d\n", + Fcb, &FileObject->FileName, ByteOffset.LowPart, NumberOfBytes); return STATUS_NOT_IMPLEMENTED; }