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