From: Aleksey Bragin Date: Mon, 28 Sep 2009 09:49:16 +0000 (+0000) Subject: [fastfat_new] X-Git-Tag: ReactOS-0.3.11~731 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5fced5449b9f7b5968b9da5d70d48d463bee5605 [fastfat_new] - Start implementing one of the most massive IFS driver routines - IRP_MJ_CREATE handler. Right now it just does some preliminary work, deciphers all options, prepares all variables, prints out debug stuff. svn path=/trunk/; revision=43199 --- diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c index 3c341b27987..676a3f31dc6 100644 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ b/reactos/drivers/filesystems/fastfat_new/create.c @@ -13,12 +13,179 @@ /* FUNCTIONS *****************************************************************/ +NTSTATUS +NTAPI +FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, + IN PIRP Irp) +{ + /* Boolean options */ + BOOLEAN CreateDirectory; + BOOLEAN SequentialOnly; + BOOLEAN NoIntermediateBuffering; + BOOLEAN OpenDirectory; + BOOLEAN IsPagingFile; + BOOLEAN OpenTargetDirectory; + BOOLEAN DirectoryFile; + BOOLEAN NonDirectoryFile; + BOOLEAN NoEaKnowledge; + BOOLEAN DeleteOnClose; + BOOLEAN TemporaryFile; + ULONG CreateDisposition; + + /* Control blocks */ + PVCB Vcb; + + /* IRP data */ + PFILE_OBJECT FileObject; + PFILE_OBJECT RelatedFO; + UNICODE_STRING FileName; + ULONG AllocationSize; + PFILE_FULL_EA_INFORMATION EaBuffer; + PACCESS_MASK DesiredAccess; + ULONG Options; + UCHAR FileAttributes; + USHORT ShareAccess; + ULONG EaLength; + + /* Misc */ + //NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + PIO_STACK_LOCATION IrpSp; + + /* Get current IRP stack location */ + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("FatCommonCreate\n", 0 ); + DPRINT1("Irp = %08lx\n", Irp ); + DPRINT1("\t->Flags = %08lx\n", Irp->Flags ); + DPRINT1("\t->FileObject = %08lx\n", IrpSp->FileObject ); + DPRINT1("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject ); + DPRINT1("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName ); + DPRINT1("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart ); + DPRINT1("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart ); + DPRINT1("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ); + DPRINT1("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); + DPRINT1("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options ); + DPRINT1("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes ); + DPRINT1("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess ); + DPRINT1("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength ); + + /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */ + if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && + (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && + (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) + { + /* Remove two leading slashes */ + IrpSp->FileObject->FileName.Length -= sizeof(WCHAR); + + RtlMoveMemory(&IrpSp->FileObject->FileName.Buffer[0], + &IrpSp->FileObject->FileName.Buffer[1], + IrpSp->FileObject->FileName.Length ); + + /* If there are two leading slashes again, exit */ + if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && + (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && + (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) + { + FatCompleteRequest( IrpContext, Irp, STATUS_OBJECT_NAME_INVALID ); + + DPRINT1("FatiCreate: STATUS_OBJECT_NAME_INVALID\n"); + return STATUS_OBJECT_NAME_INVALID; + } + } + + /* Make sure we have SecurityContext */ + ASSERT(IrpSp->Parameters.Create.SecurityContext != NULL); + + /* Get necessary data out of IRP */ + FileObject = IrpSp->FileObject; + FileName = FileObject->FileName; + RelatedFO = FileObject->RelatedFileObject; + AllocationSize = Irp->Overlay.AllocationSize.LowPart; + EaBuffer = Irp->AssociatedIrp.SystemBuffer; + DesiredAccess = &IrpSp->Parameters.Create.SecurityContext->DesiredAccess; + Options = IrpSp->Parameters.Create.Options; + FileAttributes = (UCHAR)(IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL); + ShareAccess = IrpSp->Parameters.Create.ShareAccess; + EaLength = IrpSp->Parameters.Create.EaLength; + + /* Set VPB to related object's VPB if it exists */ + if (RelatedFO) + FileObject->Vpb = RelatedFO->Vpb; + + /* Prepare file attributes mask */ + FileAttributes &= (FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_ARCHIVE); + + /* Get the volume control object */ + Vcb = &((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Vcb; + + /* Get options */ + DirectoryFile = BooleanFlagOn(Options, FILE_DIRECTORY_FILE); + NonDirectoryFile = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE); + SequentialOnly = BooleanFlagOn(Options, FILE_SEQUENTIAL_ONLY); + NoIntermediateBuffering = BooleanFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING); + NoEaKnowledge = BooleanFlagOn(Options, FILE_NO_EA_KNOWLEDGE); + DeleteOnClose = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE); + TemporaryFile = BooleanFlagOn(IrpSp->Parameters.Create.FileAttributes, + FILE_ATTRIBUTE_TEMPORARY ); + IsPagingFile = BooleanFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE); + OpenTargetDirectory = BooleanFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY); + + /* Calculate create disposition */ + CreateDisposition = (Options >> 24) & 0x000000ff; + + /* Get Create/Open directory flags based on it */ + CreateDirectory = (BOOLEAN)(DirectoryFile && + ((CreateDisposition == FILE_CREATE) || + (CreateDisposition == FILE_OPEN_IF))); + + OpenDirectory = (BOOLEAN)(DirectoryFile && + ((CreateDisposition == FILE_OPEN) || + (CreateDisposition == FILE_OPEN_IF))); + + //return Iosb.Status; + return STATUS_SUCCESS; +} + NTSTATUS NTAPI FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) { + PFAT_IRP_CONTEXT IrpContext; + NTSTATUS Status; + //PVOLUME_DEVICE_OBJECT VolumeDO = (PVOLUME_DEVICE_OBJECT)DeviceObject; + DPRINT1("FatCreate()\n"); - return STATUS_NOT_IMPLEMENTED; + + /* If it's called with our Disk FS device object - it's always open */ + // TODO: Add check for CDROM FS device object + if (DeviceObject == FatGlobalData.DiskDeviceObject) + { + /* Complete the request and return success */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = FILE_OPENED; + + IoCompleteRequest(Irp, IO_DISK_INCREMENT); + + return STATUS_SUCCESS; + } + + /* Enter FsRtl critical region */ + FsRtlEnterFileSystem(); + + /* Build an irp context */ + IrpContext = FatBuildIrpContext(Irp, TRUE); + + /* Call internal function */ + Status = FatiCreate(IrpContext, Irp); + + /* Leave FsRtl critical region */ + FsRtlExitFileSystem(); + + return Status; } /* EOF */