?? fileinfo.c
字號:
BOOLEAN bRet = TRUE;
while (bRet && (AllocationSize->QuadPart <
Fcb->Header.AllocationSize.QuadPart))
{
bRet = FFSTruncateInode(IrpContext, Vcb, Fcb);
}
return bRet;
}
NTSTATUS
FFSSetDispositionInfo(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb,
PFFS_FCB Fcb,
BOOLEAN bDelete)
{
PIRP Irp = IrpContext->Irp;
PIO_STACK_LOCATION IrpSp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FFSPrint((DBG_INFO, "FFSSetDispositionInfo: bDelete=%x\n", bDelete));
if (bDelete)
{
FFSPrint((DBG_INFO, "FFSSetDispositionInformation: MmFlushImageSection on %s.\n",
Fcb->AnsiFileName.Buffer));
if (!MmFlushImageSection(&Fcb->SectionObject,
MmFlushForDelete))
{
return STATUS_CANNOT_DELETE;
}
if (Fcb->FFSMcb->Inode == FFS_ROOT_INO)
{
return STATUS_CANNOT_DELETE;
}
if (IsDirectory(Fcb))
{
if (!FFSIsDirectoryEmpty(Vcb, Fcb))
{
return STATUS_DIRECTORY_NOT_EMPTY;
}
}
SetFlag(Fcb->Flags, FCB_DELETE_PENDING);
IrpSp->FileObject->DeletePending = TRUE;
if (IsDirectory(Fcb))
{
FsRtlNotifyFullChangeDirectory(Vcb->NotifySync,
&Vcb->NotifyList,
Fcb,
NULL,
FALSE,
FALSE,
0,
NULL,
NULL,
NULL);
}
}
else
{
ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
IrpSp->FileObject->DeletePending = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS
FFSSetRenameInfo(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb,
PFFS_FCB Fcb)
{
PFFS_FCB TargetDcb;
PFFS_MCB TargetMcb;
PFFS_MCB Mcb;
FFSv1_INODE dinode1;
UNICODE_STRING FileName;
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
PFILE_OBJECT FileObject;
PFILE_OBJECT TargetObject;
BOOLEAN ReplaceIfExists;
BOOLEAN bMove = FALSE;
PFILE_RENAME_INFORMATION FRI;
if (Fcb->FFSMcb->Inode == FFS_ROOT_INO)
{
Status = STATUS_INVALID_PARAMETER;
goto errorout;
}
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FileObject = IrpSp->FileObject;
TargetObject = IrpSp->Parameters.SetFile.FileObject;
ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
FRI = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
if (TargetObject == NULL)
{
UNICODE_STRING NewName;
NewName.Buffer = FRI->FileName;
NewName.MaximumLength = NewName.Length = (USHORT)FRI->FileNameLength;
while (NewName.Length > 0 && NewName.Buffer[NewName.Length / 2 - 1] == L'\\')
{
NewName.Buffer[NewName.Length / 2 - 1] = 0;
NewName.Length -= 2;
}
while (NewName.Length > 0 && NewName.Buffer[NewName.Length / 2 - 1] != L'\\')
{
NewName.Length -= 2;
}
NewName.Buffer = (USHORT *)((UCHAR *)NewName.Buffer + NewName.Length);
NewName.Length = (USHORT)(FRI->FileNameLength - NewName.Length);
FileName = NewName;
TargetDcb = NULL;
TargetMcb = Fcb->FFSMcb->Parent;
if (FileName.Length >= FFS_NAME_LEN*sizeof(USHORT))
{
Status = STATUS_OBJECT_NAME_INVALID;
goto errorout;
}
}
else
{
TargetDcb = (PFFS_FCB)(TargetObject->FsContext);
if (!TargetDcb || TargetDcb->Vcb != Vcb)
{
FFSBreakPoint();
Status = STATUS_INVALID_PARAMETER;
goto errorout;
}
TargetMcb = TargetDcb->FFSMcb;
FileName = TargetObject->FileName;
}
if (FsRtlDoesNameContainWildCards(&FileName))
{
Status = STATUS_OBJECT_NAME_INVALID;
goto errorout;
}
if (TargetMcb->Inode == Fcb->FFSMcb->Parent->Inode)
{
if (FsRtlAreNamesEqual(&FileName,
&(Fcb->FFSMcb->ShortName),
FALSE,
NULL))
{
Status = STATUS_SUCCESS;
goto errorout;
}
}
else
{
bMove = TRUE;
}
TargetDcb = TargetMcb->FFSFcb;
if (!TargetDcb)
TargetDcb = FFSCreateFcbFromMcb(Vcb, TargetMcb);
if ((TargetMcb->Inode != Fcb->FFSMcb->Parent->Inode) &&
(Fcb->FFSMcb->Parent->FFSFcb == NULL))
{
FFSCreateFcbFromMcb(Vcb, Fcb->FFSMcb->Parent);
}
if (!TargetDcb || !(Fcb->FFSMcb->Parent->FFSFcb))
{
Status = STATUS_UNSUCCESSFUL;
goto errorout;
}
Mcb = NULL;
Status = FFSv1LookupFileName(
Vcb,
&FileName,
TargetMcb,
&Mcb,
&dinode1);
if (NT_SUCCESS(Status))
{
if ((!ReplaceIfExists) ||
(IsFlagOn(Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) ||
(IsFlagOn(Mcb->FileAttr, FILE_ATTRIBUTE_READONLY)))
{
Status = STATUS_OBJECT_NAME_COLLISION;
goto errorout;
}
if (ReplaceIfExists)
{
Status = STATUS_NOT_IMPLEMENTED;
goto errorout;
}
}
if (IsDirectory(Fcb))
{
Status = FFSRemoveEntry(IrpContext, Vcb,
Fcb->FFSMcb->Parent->FFSFcb,
DT_DIR,
Fcb->FFSMcb->Inode);
if (!NT_SUCCESS(Status))
{
FFSBreakPoint();
goto errorout;
}
Status = FFSAddEntry(IrpContext, Vcb,
TargetDcb,
DT_DIR,
Fcb->FFSMcb->Inode,
&FileName);
if (!NT_SUCCESS(Status))
{
FFSBreakPoint();
FFSAddEntry(IrpContext, Vcb,
Fcb->FFSMcb->Parent->FFSFcb,
DT_DIR,
Fcb->FFSMcb->Inode,
&Fcb->FFSMcb->ShortName);
goto errorout;
}
if(!FFSv1SaveInode(IrpContext,
Vcb,
TargetMcb->Inode,
TargetDcb->dinode1))
{
Status = STATUS_UNSUCCESSFUL;
FFSBreakPoint();
goto errorout;
}
if(!FFSv1SaveInode(IrpContext,
Vcb,
Fcb->FFSMcb->Parent->Inode,
Fcb->FFSMcb->Parent->FFSFcb->dinode1))
{
Status = STATUS_UNSUCCESSFUL;
FFSBreakPoint();
goto errorout;
}
Status = FFSSetParentEntry(IrpContext, Vcb, Fcb,
Fcb->FFSMcb->Parent->Inode,
TargetDcb->FFSMcb->Inode);
if (!NT_SUCCESS(Status))
{
FFSBreakPoint();
goto errorout;
}
}
else
{
Status = FFSRemoveEntry(IrpContext, Vcb,
Fcb->FFSMcb->Parent->FFSFcb,
DT_REG,
Fcb->FFSMcb->Inode);
if (!NT_SUCCESS(Status))
{
FFSBreakPoint();
goto errorout;
}
Status = FFSAddEntry(IrpContext,
Vcb, TargetDcb,
DT_REG,
Fcb->FFSMcb->Inode,
&FileName);
if (!NT_SUCCESS(Status))
{
FFSBreakPoint();
FFSAddEntry(IrpContext, Vcb,
Fcb->FFSMcb->Parent->FFSFcb,
DT_REG,
Fcb->FFSMcb->Inode,
&Fcb->FFSMcb->ShortName);
goto errorout;
}
}
if (NT_SUCCESS(Status))
{
if (Fcb->FFSMcb->ShortName.MaximumLength < (FileName.Length + 2))
{
ExFreePool(Fcb->FFSMcb->ShortName.Buffer);
Fcb->FFSMcb->ShortName.Buffer =
ExAllocatePool(PagedPool, FileName.Length + 2);
if (!Fcb->FFSMcb->ShortName.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
Fcb->FFSMcb->ShortName.MaximumLength = FileName.Length + 2;
}
{
RtlZeroMemory(Fcb->FFSMcb->ShortName.Buffer,
Fcb->FFSMcb->ShortName.MaximumLength);
RtlCopyMemory(Fcb->FFSMcb->ShortName.Buffer,
FileName.Buffer, FileName.Length);
Fcb->FFSMcb->ShortName.Length = FileName.Length;
}
#if DBG
Fcb->AnsiFileName.Length = (USHORT)
RtlxUnicodeStringToOemSize(&FileName);
if (Fcb->AnsiFileName.MaximumLength < FileName.Length)
{
ExFreePool(Fcb->AnsiFileName.Buffer);
Fcb->AnsiFileName.Buffer =
ExAllocatePool(PagedPool, Fcb->AnsiFileName.Length + 1);
if (!Fcb->AnsiFileName.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
RtlZeroMemory(Fcb->AnsiFileName.Buffer,
Fcb->AnsiFileName.Length + 1);
Fcb->AnsiFileName.MaximumLength =
Fcb->AnsiFileName.Length + 1;
}
FFSUnicodeToOEM(&(Fcb->AnsiFileName),
&FileName);
#endif
if (bMove)
{
FFSNotifyReportChange(
IrpContext,
Vcb,
Fcb,
(IsDirectory(Fcb) ?
FILE_NOTIFY_CHANGE_DIR_NAME :
FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_REMOVED);
}
else
{
FFSNotifyReportChange(
IrpContext,
Vcb,
Fcb,
(IsDirectory(Fcb) ?
FILE_NOTIFY_CHANGE_DIR_NAME :
FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_OLD_NAME);
}
FFSDeleteMcbNode(Vcb, Fcb->FFSMcb->Parent, Fcb->FFSMcb);
FFSAddMcbNode(Vcb, TargetMcb, Fcb->FFSMcb);
if (bMove)
{
FFSNotifyReportChange(
IrpContext,
Vcb,
Fcb,
(IsDirectory(Fcb) ?
FILE_NOTIFY_CHANGE_DIR_NAME :
FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_ADDED);
}
else
{
FFSNotifyReportChange(
IrpContext,
Vcb,
Fcb,
(IsDirectory(Fcb) ?
FILE_NOTIFY_CHANGE_DIR_NAME :
FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_NEW_NAME);
}
}
errorout:
return Status;
}
BOOLEAN
FFSDeleteFile(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb,
PFFS_FCB Fcb)
{
BOOLEAN bRet = FALSE;
LARGE_INTEGER AllocationSize;
PFFS_FCB Dcb = NULL;
NTSTATUS Status;
FFSPrint((DBG_INFO, "FFSDeleteFile: File %S (%xh) will be deleted!\n",
Fcb->FFSMcb->ShortName.Buffer, Fcb->FFSMcb->Inode));
if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
{
return TRUE;
}
if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
if (!FFSIsDirectoryEmpty(Vcb, Fcb))
{
ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
return FALSE;
}
}
FFSPrint((DBG_INFO, "FFSDeleteFile: FFSSB->S_FREE_BLOCKS = %xh .\n",
Vcb->ffs_super_block->fs_size - Vcb->ffs_super_block->fs_dsize));
Status = STATUS_UNSUCCESSFUL;
{
if (Fcb->FFSMcb->Parent->FFSFcb)
{
Status = FFSRemoveEntry(
IrpContext, Vcb,
Fcb->FFSMcb->Parent->FFSFcb,
(FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) ?
DT_DIR : DT_REG),
Fcb->FFSMcb->Inode);
}
else
{
Dcb = FFSCreateFcbFromMcb(Vcb, Fcb->FFSMcb->Parent);
if (Dcb)
{
Status = FFSRemoveEntry(
IrpContext, Vcb, Dcb,
(FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) ?
DT_DIR : DT_REG),
Fcb->FFSMcb->Inode);
}
}
}
if (NT_SUCCESS(Status))
{
Fcb->dinode1->di_nlink--;
if (IsDirectory(Fcb))
{
if (Fcb->dinode1->di_nlink < 2)
{
bRet = TRUE;
}
}
else
{
if (Fcb->dinode1->di_nlink == 0)
{
bRet = TRUE;
}
}
}
if (bRet)
{
AllocationSize.QuadPart = (LONGLONG)0;
bRet = FFSTruncateFile(IrpContext, Vcb, Fcb, &AllocationSize);
//
// Update the inode's data length . It should be ZERO if succeeds.
//
if (Fcb->dinode1->di_size > Fcb->Header.AllocationSize.LowPart)
{
Fcb->dinode1->di_size = Fcb->Header.AllocationSize.LowPart;
}
Fcb->Header.FileSize.QuadPart = (LONGLONG) Fcb->dinode1->di_size;
if (bRet)
{
{
LARGE_INTEGER SysTime;
KeQuerySystemTime(&SysTime);
/*Fcb->dinode->di_dtime = FFSInodeTime(SysTime); XXX */
FFSv1SaveInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, Fcb->dinode1);
}
if (IsDirectory(Fcb))
{
bRet = FFSFreeInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, DT_DIR);
}
else
{
bRet = FFSFreeInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, DT_REG);
}
SetFlag(Fcb->Flags, FCB_FILE_DELETED);
FFSDeleteMcbNode(Vcb, Fcb->FFSMcb->Parent, Fcb->FFSMcb);
}
else
{
FFSv1SaveInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, Fcb->dinode1);
}
}
else
{
FFSv1SaveInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, Fcb->dinode1);
}
FFSPrint((DBG_INFO, "FFSDeleteFile: Succeed... FFSSB->S_FREE_BLOCKS = %xh .\n",
Vcb->ffs_super_block->fs_size - Vcb->ffs_super_block->fs_dsize));
return bRet;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -