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

📄 fileinfo.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -