📄 create.c
字号:
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 + -