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

📄 create.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                    Ext2AddEntry(IrpContext, Vcb, Fcb, EXT2_FT_DIR, Fcb->Ext2Mcb->Parent->Inode, &EntryName);

                    //No need to inc the links count, 'cause
                    //pParentFcb->ext2_inode->i_links_count++;
                    Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Parent->Inode, pParentFcb->ext2_inode);
                }
                else
                {
                    if (!Ext2ExpandFileAllocation(IrpContext, Vcb, Fcb, &(Irp->Overlay.AllocationSize)))
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }
                }
            }
            else    // For existing files
            {
                if (DeleteOnClose)
                {
                    if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                    {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;
                        __leave;
                    }

                    SetFlag(Fcb->Flags, FCB_DELETE_ON_CLOSE);
                }
            }

            if (!IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
            {
                if ((CreateDisposition == FILE_SUPERSEDE) && !IsPagingFile)
                {
                    DesiredAccess |= DELETE;
                }
                else if (((CreateDisposition == FILE_OVERWRITE) ||
                        (CreateDisposition == FILE_OVERWRITE_IF)) && !IsPagingFile)
                {
                    DesiredAccess |= FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES;
                }
            }

            if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
            {
                if (Fcb->OpenHandleCount > 0) 
                {
                    Status = IoCheckShareAccess(DesiredAccess, ShareAccess, io_stack->FileObject,
                                                &(Fcb->ShareAccess), TRUE);

                    if (!NT_SUCCESS(Status))
                    {
                        __leave;
				    }
                } 
                else 
                {
                    IoSetShareAccess(DesiredAccess, ShareAccess, io_stack->FileObject, &(Fcb->ShareAccess));
                }
            }

            Ccb = Ext2AllocateCcb();

            ExAcquireResourceExclusiveLite(&Fcb->CountResource, TRUE);
            Fcb->OpenHandleCount++;
            Fcb->ReferenceCount++;

            if (IsFlagOn(io_stack->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
            {
                Fcb->NonCachedOpenCount++;
            }

            ExReleaseResourceForThreadLite(
                    &Fcb->CountResource,
                    ExGetCurrentResourceThread());

            ExAcquireResourceExclusiveLite(&Vcb->CountResource, TRUE);
            Vcb->OpenFileHandleCount++;
            Vcb->ReferenceCount++;
            ExReleaseResourceForThreadLite(
                    &Vcb->CountResource,
                    ExGetCurrentResourceThread());
            
#if DBG
            Ext2DbgPrint(D_CREATE, "Ext2CreateFile: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount);
#endif

            if (!IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
            {
                Fcb->CommonFCBHeader.IsFastIoPossible = FastIoIsPossible;

                if (IsFlagOn(io_stack->FileObject->Flags, FO_CACHE_SUPPORTED) &&
                    (Fcb->SectionObject.DataSectionObject != NULL))
                {
                    if (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount)
                    {
                        /* IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) */

                        if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                        {
                            CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
                            ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                        }

                        CcPurgeCacheSection(&Fcb->SectionObject,
                                             NULL,
                                             0,
                                             FALSE );
                    }
                }
            }

            io_stack->FileObject->FsContext = (void*)Fcb;
            io_stack->FileObject->FsContext2 = (void*) Ccb;
            io_stack->FileObject->PrivateCacheMap = NULL;
            io_stack->FileObject->SectionObjectPointer = &(Fcb->SectionObject);
            io_stack->FileObject->Vpb = Vcb->Vpb;

            Status = STATUS_SUCCESS;
#if DBG
            Ext2DbgPrint(D_CREATE, "Ext2CreateFile: %s OpenCount: %u ReferCount: %u\n",
                Fcb->AnsiFileName.Buffer, Fcb->OpenHandleCount, Fcb->ReferenceCount);
#endif

            if (!NoIntermediateBuffering )
            {
                io_stack->FileObject->Flags |= FO_CACHE_SUPPORTED;
            }

            if (!bCreated && !IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
            {
                if ( DeleteOnClose ||
                    (CreateDisposition == FILE_OVERWRITE) ||
                    (CreateDisposition == FILE_OVERWRITE_IF))
                {
                    if (!MmFlushImageSection( &Fcb->SectionObject,
                                              MmFlushForWrite ))
                    {

                        Status = DeleteOnClose ? STATUS_CANNOT_DELETE :
                                                 STATUS_SHARING_VIOLATION;
                        __leave;
                    }
                }

                if ((CreateDisposition == FILE_SUPERSEDE) ||
                    (CreateDisposition == FILE_OVERWRITE) ||
                    (CreateDisposition == FILE_OVERWRITE_IF))
                {
                    BOOLEAN bRet;

                    if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                    {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;
                        __leave;
                    }
                    
                    Ext2SupersedeOrOverWriteFile(IrpContext, Vcb, Fcb, CreateDisposition);
                    bRet = Ext2ExpandFileAllocation(IrpContext, Vcb, Fcb, &(Irp->Overlay.AllocationSize));

                    if (!bRet)
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }

                    if (CreateDisposition == FILE_SUPERSEDE)
                    {
                       Irp->IoStatus.Information = FILE_SUPERSEDED;
                    }
                    else
                    {
                        Irp->IoStatus.Information = FILE_OVERWRITTEN;
                    }
                }
            }
        }
    }

    __finally
    {
        if (FileName.Buffer)
            ExFreePool(FileName.Buffer);

        if (bParentFcbCreated)
        {
            ExAcquireResourceExclusiveLite(&pParentFcb->CountResource, TRUE);
            pParentFcb->ReferenceCount--;
            ExReleaseResourceForThreadLite(
                    &pParentFcb->CountResource,
                    ExGetCurrentResourceThread());
        }

        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );
        }

        if (!bFcbAllocated)
        {
            if (ext2_inode)
                ExFreePool(ext2_inode);
        }
        else
        {
            if (!Fcb && ext2_inode)
                ExFreePool(ext2_inode);
        }
    }
    
    return Status;
}

NTSTATUS
Ext2CreateVolume(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
{
    PIO_STACK_LOCATION  io_stack;
    PIRP                Irp;

    NTSTATUS            Status;

    ACCESS_MASK         DesiredAccess;
    ULONG               ShareAccess;

    ULONG               Options;
    BOOLEAN             DirectoryFile;
    BOOLEAN             OpenTargetDirectory;

    ULONG               CreateDisposition;

    Irp = IrpContext->Irp;
    io_stack = IoGetCurrentIrpStackLocation(Irp);

    Options  = io_stack->Parameters.Create.Options;
    
    DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
    OpenTargetDirectory = IsFlagOn(io_stack->Flags, SL_OPEN_TARGET_DIRECTORY);

    CreateDisposition = (Options >> 24) & 0x000000ff;

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

    if (DirectoryFile)
        return STATUS_NOT_A_DIRECTORY;

    if (OpenTargetDirectory)
        return STATUS_INVALID_PARAMETER;

	if ((CreateDisposition != FILE_OPEN) && (CreateDisposition != FILE_OPEN_IF)) 
	{
		return STATUS_ACCESS_DENIED;
    }

    Status = STATUS_SUCCESS;

    {
        if (Vcb->OpenHandleCount > 0) 
        {
            Status = IoCheckShareAccess(DesiredAccess, ShareAccess, io_stack->FileObject,
                                        &(Vcb->ShareAccess), TRUE);

            if (!NT_SUCCESS(Status)) 
            {
			    goto errorout;
            }
        } 
        else 
        {
            IoSetShareAccess(DesiredAccess, ShareAccess, io_stack->FileObject, &(Vcb->ShareAccess));
        }
    }

    {
            io_stack->FileObject->FsContext = Vcb;
        
            ExAcquireResourceExclusiveLite(
                &Vcb->CountResource, TRUE );
        
            Vcb->ReferenceCount++;
            Vcb->OpenHandleCount++;
        
            ExReleaseResourceForThreadLite(
                &Vcb->CountResource,
                ExGetCurrentResourceThread() );
        
            Irp->IoStatus.Information = FILE_OPENED;
    }
  
errorout:
      
    return Status;
}


NTSTATUS
Ext2Create (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT      DeviceObject;
    PIRP                Irp;
    PIO_STACK_LOCATION  io_stack;
    PEXT2_VCB           Vcb = 0;
    NTSTATUS            Status = STATUS_OBJECT_NAME_NOT_FOUND;
    PEXT2_FCBVCB        Xcb = NULL;

    DeviceObject = IrpContext->DeviceObject;

    Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
    
    Irp = IrpContext->Irp;
    
    io_stack = IoGetCurrentIrpStackLocation(Irp);

    Xcb = (PEXT2_FCBVCB) (io_stack->FileObject->FsContext);
    
    if (DeviceObject == gExt2Global->DeviceObject)
    {
        Ext2DbgPrint(D_CREATE, "Ext2Create: Create on main device object.\n");
        
        Irp->IoStatus.Information = FILE_OPENED;
        Status = STATUS_SUCCESS;
        IrpContext->Irp->IoStatus.Status = Status;
        
        Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
        
        Ext2FreeIrpContext(IrpContext);
        
        return Status;
        
    }
   
    __try
    {
        if (IsFlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
        {
            Status = STATUS_ACCESS_DENIED;
            __leave;
        }

        if (((io_stack->FileObject->FileName.Length == 0) && (io_stack->FileObject->RelatedFileObject == NULL) ) || 
                  (Xcb && Xcb->Identifier.Type == EXT2VCB) )
        {
            Status = Ext2CreateVolume(IrpContext, Vcb);
        }
        else
        {
            Status = Ext2CreateFile(IrpContext, Vcb);
        }
    }

    __finally
    {

        if (!IrpContext->ExceptionInProgress)
        {
            IrpContext->Irp->IoStatus.Status = Status;
            
            Ext2CompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
            
            Ext2FreeIrpContext(IrpContext);
        }
    }
    
    return Status;
}


NTSTATUS
Ext2CreateInode(
    PEXT2_IRP_CONTEXT   IrpContext,
    PEXT2_VCB           Vcb,
    PEXT2_FCB           pParentFcb,
    ULONG               Type,
    ULONG               FileAttr,
    PUNICODE_STRING     FileName)
{
    ULONG       Inode;
    ULONG       Group;

    EXT2_INODE  Ext2Ino;

    RtlZeroMemory(&Ext2Ino, sizeof(EXT2_INODE));

    Group = (pParentFcb->Ext2Mcb->Inode - 1) / Vcb->ext2_super_block->s_blocks_per_group;

    Ext2DbgPrint(D_CREATE, "Ext2CreateInode: %S in %S(Inode=%xh)\n", FileName->Buffer, pParentFcb->Ext2Mcb->ShortName.Buffer, pParentFcb->Ext2Mcb->Inode);

    if (Ext2NewInode(IrpContext, Vcb, Group,Type, &Inode))
    {
        if (NT_SUCCESS(Ext2AddEntry(IrpContext, Vcb, pParentFcb, Type, Inode, FileName)))
        {
            Ext2SaveInode(IrpContext, Vcb, pParentFcb->Ext2Mcb->Inode, pParentFcb->ext2_inode);

            Ext2Ino.i_ctime = pParentFcb->ext2_inode->i_mtime;
            Ext2Ino.i_mode = 0x1FF;
            Ext2Ino.i_links_count = 1;

            if (FlagOn(FileAttr, FILE_ATTRIBUTE_READONLY))
            {
                Ext2SetReadOnly(Ext2Ino.i_mode);
            }

            if (Type == EXT2_FT_DIR)
            {
                SetFlag(Ext2Ino.i_mode, S_IFDIR);
                if ((pParentFcb->Ext2Mcb->Inode == EXT2_ROOT_INO) && (FileName->Length == 0x10))
                {
                    if (memcmp(FileName->Buffer, L"Recycled\0", 0x10) == 0)
                    {
                        Ext2SetReadOnly(Ext2Ino.i_mode);
                    }
                }
            }
            else
            {
                SetFlag(Ext2Ino.i_mode, S_IFFIL);
            }

            Ext2SaveInode(IrpContext, Vcb, Inode, &Ext2Ino);

            Ext2DbgPrint(D_CREATE, "Ext2CreateInode: New Inode = %xh (Type=%xh)\n", Inode, Type);
            
            return STATUS_SUCCESS;
        }
        else
        {
            Ext2DbgBreakPoint();
            Ext2FreeInode(IrpContext, Vcb, Inode, Type);
        }
    }

    return STATUS_UNSUCCESSFUL;
}

⌨️ 快捷键说明

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