⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 create.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    IsPagingFile = IsFlagOn(io_stack->Flags, SL_OPEN_PAGING_FILE);

    CreateDirectory = (BOOLEAN)(DirectoryFile &&
                                ((CreateDisposition == FILE_CREATE) ||
                                 (CreateDisposition == FILE_OPEN_IF)));

    OpenDirectory   = (BOOLEAN)(DirectoryFile &&
                                ((CreateDisposition == FILE_OPEN) ||
                                 (CreateDisposition == FILE_OPEN_IF)));

    DesiredAccess = io_stack->Parameters.Create.SecurityContext->DesiredAccess;
    ShareAccess   = io_stack->Parameters.Create.ShareAccess;

    FileName.Buffer = NULL;

    __try
    {
        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource, TRUE );
        
        VcbResourceAcquired = TRUE;

		if (Irp->Overlay.AllocationSize.HighPart) 
		{
			Status = STATUS_INVALID_PARAMETER;
			__leave;
		}
        
        if (!(ext2_inode = ExAllocatePool   (
              PagedPool, sizeof(EXT2_INODE) ) ))
        {
            __leave;
        }

        FileName.MaximumLength = io_stack->FileObject->FileName.MaximumLength;
        FileName.Length = io_stack->FileObject->FileName.Length;

        FileName.Buffer = ExAllocatePool(PagedPool, FileName.MaximumLength);
        if (!FileName.Buffer)
        {   
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }

        RtlZeroMemory(FileName.Buffer, FileName.MaximumLength);
        RtlCopyMemory(FileName.Buffer, io_stack->FileObject->FileName.Buffer, FileName.Length);

        if (io_stack->FileObject->RelatedFileObject)
        {
            pParentFcb = (PEXT2_FCB)(io_stack->FileObject->RelatedFileObject->FsContext);
        }

        if ((FileName.Length > sizeof(WCHAR)) &&
            (FileName.Buffer[1] == L'\\') &&
            (FileName.Buffer[0] == L'\\')) {
            
            FileName.Length -= sizeof(WCHAR);
            
            RtlMoveMemory( &FileName.Buffer[0],
                &FileName.Buffer[1],
                FileName.Length );
            
            //
            //  Bad Name if there are still two beginning backslashes.
            //
            
            if ((FileName.Length > sizeof(WCHAR)) &&
                (FileName.Buffer[1] == L'\\') &&
                (FileName.Buffer[0] == L'\\')) {
                                
                Status = STATUS_OBJECT_NAME_INVALID;

                __leave;
            }
        }

        Ext2DbgPrint(D_CREATE, "Ext2CreateFile: %S (name len=%xh)Opt: %xh.\n",
            FileName.Buffer, FileName.Length,
            io_stack->Parameters.Create.Options);

        Status = Ext2LookupFileName(
            Vcb,
            &FileName,
            pParentFcb,
            &Ext2Mcb,
            ext2_inode );

        if (!NT_SUCCESS(Status))
        {
            UNICODE_STRING  NewName;

            NewName = FileName;

            Ext2DbgPrint(D_CREATE, "Ext2CreateFile: File Not Found.\n");

            Ext2Mcb = NULL;

            // We need to create a new one ?
            if ((CreateDisposition == FILE_CREATE ) ||
				(CreateDisposition == FILE_OPEN_IF) ||
				(CreateDisposition == FILE_OVERWRITE_IF))
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (DirectoryFile)
                {
                    if (TemporaryFile)
                    {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }

                if (!pParentFcb)
                {
                    if (DirectoryFile)
                    {
                        while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] == L'\\')
                        {
                            NewName.Buffer[NewName.Length/2 - 1] = 0;
                            NewName.Length -= 2;
                        }
                    }
                    else
                    {
                        if (NewName.Buffer[NewName.Length/2 - 1] == L'\\')
                        {
                            Status = STATUS_INVALID_PARAMETER;
                            __leave;
                        }
                    }

                    while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] != L'\\')
                    {
                        NewName.Length -= 2;
                    }

                    Status = Ext2LookupFileName (
                                Vcb,
                                &NewName,
                                pParentFcb,
                                &Ext2Mcb,
                                ext2_inode      );


                    if (NT_SUCCESS(Status))
                    {
                        pParentFcb = Ext2Mcb->Ext2Fcb;

                        NewName.Buffer = (USHORT *)((UCHAR *)NewName.Buffer + NewName.Length);
                        NewName.Length = FileName.Length - NewName.Length;

                        //Here we should create the fcb.
                        if (!pParentFcb)
                        {
                            PEXT2_INODE pTmpInode = ExAllocatePool(PagedPool, sizeof(EXT2_INODE));
                            if (!pTmpInode)
                            {
                                Status = STATUS_INSUFFICIENT_RESOURCES;
                                __leave;
                            }
                            RtlCopyMemory(pTmpInode, ext2_inode, sizeof(EXT2_INODE));
                            pParentFcb = Ext2AllocateFcb(Vcb,  Ext2Mcb, pTmpInode);

                            if (!pParentFcb)
                            {
                                ExFreePool(pTmpInode);
                                Status = STATUS_INVALID_PARAMETER;
                                __leave;
                            }

                            bParentFcbCreated = TRUE;

                            ExAcquireResourceExclusiveLite(&pParentFcb->CountResource, TRUE);
                            pParentFcb->ReferenceCount++;
                            ExReleaseResourceForThreadLite(
                                    &pParentFcb->CountResource,
                                    ExGetCurrentResourceThread());

                        }
                    }

                    Ext2Mcb = NULL;
                }

                // Here we get a valid pParentFcb

                if (DirectoryFile)
                {
                    Status = Ext2CreateInode(IrpContext, Vcb, pParentFcb, EXT2_FT_DIR, io_stack->Parameters.Create.FileAttributes, &NewName);
                }
                else
                {
                    Status = Ext2CreateInode(IrpContext, Vcb, pParentFcb, EXT2_FT_REG_FILE, io_stack->Parameters.Create.FileAttributes, &NewName);
                }
                
                if (NT_SUCCESS(Status))
                {
                    bCreated = TRUE;

                    Irp->IoStatus.Information = FILE_CREATED;                    
                    Status = Ext2LookupFileName (
                                Vcb,
                                &NewName,
                                pParentFcb,
                                &Ext2Mcb,
                                ext2_inode      );

                    if (!NT_SUCCESS(Status))
                    {
                        Ext2DbgBreakPoint();
                    }
                }
                else
                {
                    Ext2DbgBreakPoint();
                }
            }
            else if (OpenTargetDirectory)
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (!pParentFcb)
                {
                    while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] == L'\\')
                    {
                         NewName.Length -= 2;
                    }

                    while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] != L'\\')
                    {
                        NewName.Length -= 2;
                    }

                    Status = Ext2LookupFileName (
                                Vcb,
                                &NewName,
                                pParentFcb,
                                &Ext2Mcb,
                                ext2_inode      );

                    if (NT_SUCCESS(Status))
                    {
                        pParentFcb = Ext2Mcb->Ext2Fcb;

                        NewName.Buffer = (USHORT *)((ULONG)(NewName.Buffer) + NewName.Length);
                        NewName.Length = FileName.Length - NewName.Length;

                        RtlZeroMemory(io_stack->FileObject->FileName.Buffer, 
                                      io_stack->FileObject->FileName.Length );

                        io_stack->FileObject->FileName.Length = NewName.Length;

                        RtlCopyMemory( io_stack->FileObject->FileName.Buffer,
                                       NewName.Buffer,
                                       NewName.Length );
                        

                        //Here we should create the fcb.
                        if (!pParentFcb)
                        {
                            PEXT2_INODE pTmpInode = ExAllocatePool(PagedPool, sizeof(EXT2_INODE));
                            if (!pTmpInode)
                            {
                                Status = STATUS_INSUFFICIENT_RESOURCES;
                                __leave;
                            }
                            RtlCopyMemory(pTmpInode, ext2_inode, sizeof(EXT2_INODE));
                            pParentFcb = Ext2AllocateFcb(Vcb,  Ext2Mcb, pTmpInode);

                            if (!pParentFcb)
                            {
                                ExFreePool(pTmpInode);
                                Status = STATUS_INVALID_PARAMETER;
                                __leave;
                            }

                            bParentFcbCreated = TRUE;

                            ExAcquireResourceExclusiveLite(&pParentFcb->CountResource, TRUE);
                            pParentFcb->ReferenceCount++;
                            ExReleaseResourceForThreadLite(
                                    &pParentFcb->CountResource,
                                    ExGetCurrentResourceThread());
                        }
                    }

                    if (!pParentFcb)
                    {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }

                Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
                Status = STATUS_SUCCESS;
            }
/*
            else if ((CreateDisposition == FILE_OPEN) ||
                     (CreateDisposition == FILE_OVERWRITE))
            {
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
                __leave;
            }
*/
            else
            {
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
                __leave;
            }
        }
        else // File / Dir already exists.
        {
            if (OpenTargetDirectory)
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_SUCCESS;

                RtlZeroMemory(io_stack->FileObject->FileName.Buffer, io_stack->FileObject->FileName.MaximumLength);
                io_stack->FileObject->FileName.Length = Ext2Mcb->ShortName.Length;

                RtlCopyMemory( io_stack->FileObject->FileName.Buffer,
                               Ext2Mcb->ShortName.Buffer,
                               Ext2Mcb->ShortName.Length );

                //Let Mcb pointer to it's parent
                Ext2Mcb = Ext2Mcb->Parent;

                goto Openit;
            }

            // We can not create if one exists
            if (CreateDisposition == FILE_CREATE)
            {
                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_OBJECT_NAME_COLLISION;
                __leave;
            }

            if(IsFlagOn(Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
            {
                if ((CreateDisposition != FILE_OPEN) &&
                    (CreateDisposition != FILE_OPEN_IF))
                {

                    Status = STATUS_OBJECT_NAME_COLLISION;
                    __leave;
                }

			    if (NonDirectoryFile) 
			    {
				    Status = STATUS_FILE_IS_A_DIRECTORY;
				    __leave;
			    }

                if (Ext2Mcb->Inode == EXT2_ROOT_INO)
                {
                    if (DeleteOnClose)
                    {
                        Status = STATUS_CANNOT_DELETE;
                        __leave;
                    }

                    if (OpenTargetDirectory)
                    {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }
            }

            Irp->IoStatus.Information = FILE_OPENED;
        }

Openit:
        
        if (Ext2Mcb)
        {
            Fcb = Ext2Mcb->Ext2Fcb;

            if (!Fcb)
            {
                Fcb = Ext2AllocateFcb (Vcb, Ext2Mcb, ext2_inode);
                bFcbAllocated = TRUE;
            }
        }
        
        if (Fcb)
        {
            if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
            {
                Status = STATUS_FILE_DELETED;
                __leave;
            }

            if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
            {
                Status = STATUS_DELETE_PENDING;
                __leave;
            }

            // Add ./.. entries
            if (bCreated)
            {
                if (DirectoryFile)
                {
                    UNICODE_STRING EntryName;
                    USHORT  NameBuf[6];

                    RtlZeroMemory(&NameBuf, 6 * sizeof(USHORT));

                    EntryName.Length = EntryName.MaximumLength = 2;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = (USHORT)'.';

                    Ext2AddEntry(IrpContext, Vcb, Fcb, EXT2_FT_DIR, Fcb->Ext2Mcb->Inode, &EntryName);
                    Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode);

                    EntryName.Length = EntryName.MaximumLength = 4;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = NameBuf[1] = (USHORT)'.';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -