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

📄 fileinfo.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
 * FFS File System Driver for Windows
 *
 * fileinfo.c
 *
 * 2004.5.6 ~
 *
 * Lee Jae-Hong, http://www.pyrasis.com
 *
 * See License.txt
 *
 */

#include "ntifs.h"
#include "ffsdrv.h"

/* Globals */

extern PFFS_GLOBAL FFSGlobal;


/* Definitions */

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FFSQueryInformation)
#pragma alloc_text(PAGE, FFSSetInformation)
#pragma alloc_text(PAGE, FFSExpandFile)
#pragma alloc_text(PAGE, FFSTruncateFile)
#pragma alloc_text(PAGE, FFSSetDispositionInfo)
#pragma alloc_text(PAGE, FFSSetRenameInfo)
#pragma alloc_text(PAGE, FFSDeleteFile)
#endif


NTSTATUS
FFSQueryInformation(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT          DeviceObject;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;
	PFILE_OBJECT            FileObject;
	PFFS_VCB                Vcb;
	PFFS_FCB                Fcb;
	PFFS_CCB                Ccb;
	PIRP                    Irp;
	PIO_STACK_LOCATION      IoStackLocation;
	FILE_INFORMATION_CLASS  FileInformationClass;
	ULONG                   Length;
	PVOID                   Buffer;
	BOOLEAN                 FcbResourceAcquired = FALSE;

	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

		FileObject = IrpContext->FileObject;

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		Fcb = (PFFS_FCB)FileObject->FsContext;

		ASSERT(Fcb != NULL);

		//
		// This request is not allowed on volumes
		//
		if (Fcb->Identifier.Type == FFSVCB)
		{
			Status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		ASSERT((Fcb->Identifier.Type == FFSFCB) &&
				(Fcb->Identifier.Size == sizeof(FFS_FCB)));
		/*        
		if (!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) &&
			!FlagOn(Fcb->Flags, FCB_PAGE_FILE))
		*/
		{
			if (!ExAcquireResourceSharedLite(
						&Fcb->MainResource,
						IrpContext->IsSynchronous))
			{
				Status = STATUS_PENDING;
				__leave;
			}

			FcbResourceAcquired = TRUE;
		}

		Ccb = (PFFS_CCB)FileObject->FsContext2;

		ASSERT(Ccb != NULL);

		ASSERT((Ccb->Identifier.Type == FFSCCB) &&
				(Ccb->Identifier.Size == sizeof(FFS_CCB)));

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

		FileInformationClass =
			IoStackLocation->Parameters.QueryFile.FileInformationClass;

		Length = IoStackLocation->Parameters.QueryFile.Length;

		Buffer = Irp->AssociatedIrp.SystemBuffer;

		RtlZeroMemory(Buffer, Length);

		switch (FileInformationClass)
		{
			case FileBasicInformation:
				{
					PFILE_BASIC_INFORMATION FileBasicInformation;

					if (Length < sizeof(FILE_BASIC_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileBasicInformation = (PFILE_BASIC_INFORMATION)Buffer;

					if (FS_VERSION == 1)
					{
						FileBasicInformation->CreationTime = FFSSysTime(Fcb->dinode1->di_ctime);

						FileBasicInformation->LastAccessTime = FFSSysTime(Fcb->dinode1->di_atime);

						FileBasicInformation->LastWriteTime = FFSSysTime(Fcb->dinode1->di_mtime);

						FileBasicInformation->ChangeTime = FFSSysTime(Fcb->dinode1->di_mtime);
					}
					else
					{
						FileBasicInformation->CreationTime = FFSSysTime((ULONG)Fcb->dinode2->di_ctime);

						FileBasicInformation->LastAccessTime = FFSSysTime((ULONG)Fcb->dinode2->di_atime);

						FileBasicInformation->LastWriteTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);

						FileBasicInformation->ChangeTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);
					}

					FileBasicInformation->FileAttributes = Fcb->FFSMcb->FileAttr;

					Irp->IoStatus.Information = sizeof(FILE_BASIC_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

#if (_WIN32_WINNT >= 0x0500)

			case FileAttributeTagInformation:
				{
					PFILE_ATTRIBUTE_TAG_INFORMATION FATI;

					if (Length < sizeof(FILE_ATTRIBUTE_TAG_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FATI = (PFILE_ATTRIBUTE_TAG_INFORMATION) Buffer;

					FATI->FileAttributes = Fcb->FFSMcb->FileAttr;
					FATI->ReparseTag = 0;

					Irp->IoStatus.Information = sizeof(FILE_ATTRIBUTE_TAG_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}
#endif // (_WIN32_WINNT >= 0x0500)

			case FileStandardInformation:
				{
					PFILE_STANDARD_INFORMATION FileStandardInformation;

					if (Length < sizeof(FILE_STANDARD_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileStandardInformation = (PFILE_STANDARD_INFORMATION)Buffer;

					if (FS_VERSION == 1)
					{
						FileStandardInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);

						FileStandardInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);

						FileStandardInformation->NumberOfLinks = Fcb->dinode1->di_nlink;
					}
					else
					{
						FileStandardInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);

						FileStandardInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);

						FileStandardInformation->NumberOfLinks = Fcb->dinode2->di_nlink;
					}

					if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
						FileStandardInformation->DeletePending = FALSE;
					else
						FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);                

					if (Fcb->FFSMcb->FileAttr & FILE_ATTRIBUTE_DIRECTORY)
					{
						FileStandardInformation->Directory = TRUE;
					}
					else
					{
						FileStandardInformation->Directory = FALSE;
					}

					Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

			case FileInternalInformation:
				{
					PFILE_INTERNAL_INFORMATION FileInternalInformation;

					if (Length < sizeof(FILE_INTERNAL_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileInternalInformation = (PFILE_INTERNAL_INFORMATION)Buffer;

					// The "inode number"
					FileInternalInformation->IndexNumber.QuadPart = (LONGLONG)Fcb->FFSMcb->Inode;

					Irp->IoStatus.Information = sizeof(FILE_INTERNAL_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

			case FileEaInformation:
				{
					PFILE_EA_INFORMATION FileEaInformation;

					if (Length < sizeof(FILE_EA_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileEaInformation = (PFILE_EA_INFORMATION)Buffer;

					// Romfs doesn't have any extended attributes
					FileEaInformation->EaSize = 0;

					Irp->IoStatus.Information = sizeof(FILE_EA_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

			case FileNameInformation:
				{
					PFILE_NAME_INFORMATION FileNameInformation;

					if (Length < sizeof(FILE_NAME_INFORMATION) +
							Fcb->FFSMcb->ShortName.Length - sizeof(WCHAR))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileNameInformation = (PFILE_NAME_INFORMATION)Buffer;

					FileNameInformation->FileNameLength = Fcb->FFSMcb->ShortName.Length;

					RtlCopyMemory(
							FileNameInformation->FileName,
							Fcb->FFSMcb->ShortName.Buffer,
							Fcb->FFSMcb->ShortName.Length);

					Irp->IoStatus.Information = sizeof(FILE_NAME_INFORMATION) +
						Fcb->FFSMcb->ShortName.Length - sizeof(WCHAR);
					Status = STATUS_SUCCESS;
					__leave;
				}

			case FilePositionInformation:
				{
					PFILE_POSITION_INFORMATION FilePositionInformation;

					if (Length < sizeof(FILE_POSITION_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FilePositionInformation = (PFILE_POSITION_INFORMATION)Buffer;

					FilePositionInformation->CurrentByteOffset =
						FileObject->CurrentByteOffset;

					Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

			case FileAllInformation:
				{
					PFILE_ALL_INFORMATION       FileAllInformation;
					PFILE_BASIC_INFORMATION     FileBasicInformation;
					PFILE_STANDARD_INFORMATION  FileStandardInformation;
					PFILE_INTERNAL_INFORMATION  FileInternalInformation;
					PFILE_EA_INFORMATION        FileEaInformation;
					PFILE_POSITION_INFORMATION  FilePositionInformation;
					PFILE_NAME_INFORMATION      FileNameInformation;

					if (Length < sizeof(FILE_ALL_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileAllInformation = (PFILE_ALL_INFORMATION)Buffer;

					FileBasicInformation =
						&FileAllInformation->BasicInformation;

					FileStandardInformation =
						&FileAllInformation->StandardInformation;

					FileInternalInformation =
						&FileAllInformation->InternalInformation;

					FileEaInformation =
						&FileAllInformation->EaInformation;

					FilePositionInformation =
						&FileAllInformation->PositionInformation;

					FileNameInformation =
						&FileAllInformation->NameInformation;

					if (FS_VERSION == 1)
					{
						FileBasicInformation->CreationTime = FFSSysTime(Fcb->dinode1->di_ctime);

						FileBasicInformation->LastAccessTime = FFSSysTime(Fcb->dinode1->di_atime);

						FileBasicInformation->LastWriteTime = FFSSysTime(Fcb->dinode1->di_mtime);

						FileBasicInformation->ChangeTime = FFSSysTime(Fcb->dinode1->di_mtime);

						FileBasicInformation->FileAttributes = Fcb->FFSMcb->FileAttr;

						FileStandardInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);

						FileStandardInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);

						FileStandardInformation->NumberOfLinks = Fcb->dinode1->di_nlink;
					}
					else
					{
						FileBasicInformation->CreationTime = FFSSysTime((ULONG)Fcb->dinode2->di_ctime);

						FileBasicInformation->LastAccessTime = FFSSysTime((ULONG)Fcb->dinode2->di_atime);

						FileBasicInformation->LastWriteTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);

						FileBasicInformation->ChangeTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);

						FileBasicInformation->FileAttributes = Fcb->FFSMcb->FileAttr;

						FileStandardInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);

						FileStandardInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);

						FileStandardInformation->NumberOfLinks = Fcb->dinode2->di_nlink;
					}

					if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
						FileStandardInformation->DeletePending = FALSE;
					else
						FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);

					if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
					{
						FileStandardInformation->Directory = TRUE;
					}
					else
					{
						FileStandardInformation->Directory = FALSE;
					}

					// The "inode number"
					FileInternalInformation->IndexNumber.QuadPart = (LONGLONG)Fcb->FFSMcb->Inode;

					// Romfs doesn't have any extended attributes
					FileEaInformation->EaSize = 0;

					FilePositionInformation->CurrentByteOffset =
						FileObject->CurrentByteOffset;

					if (Length < sizeof(FILE_ALL_INFORMATION) +
							Fcb->FFSMcb->ShortName.Length - sizeof(WCHAR))
					{
						Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION);
						Status = STATUS_BUFFER_OVERFLOW;
						__leave;
					}

					FileNameInformation->FileNameLength = Fcb->FFSMcb->ShortName.Length;

					RtlCopyMemory(
							FileNameInformation->FileName,
							Fcb->FFSMcb->ShortName.Buffer,
							Fcb->FFSMcb->ShortName.Length);

					Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION) +
						Fcb->FFSMcb->ShortName.Length - sizeof(WCHAR);
					Status = STATUS_SUCCESS;
					__leave;
				}

			/*
			case FileAlternateNameInformation:
			   {
				// TODO: Handle FileAlternateNameInformation

				// Here we would like to use RtlGenerate8dot3Name but I don't
				// know how to use the argument PGENERATE_NAME_CONTEXT
			}
			*/

			case FileNetworkOpenInformation:
				{
					PFILE_NETWORK_OPEN_INFORMATION FileNetworkOpenInformation;

					if (Length < sizeof(FILE_NETWORK_OPEN_INFORMATION))
					{
						Status = STATUS_INFO_LENGTH_MISMATCH;
						__leave;
					}

					FileNetworkOpenInformation =
						(PFILE_NETWORK_OPEN_INFORMATION)Buffer;

					if (FS_VERSION == 1)
					{
						FileNetworkOpenInformation->CreationTime = FFSSysTime(Fcb->dinode1->di_ctime);

						FileNetworkOpenInformation->LastAccessTime = FFSSysTime(Fcb->dinode1->di_atime);

						FileNetworkOpenInformation->LastWriteTime = FFSSysTime(Fcb->dinode1->di_mtime);

						FileNetworkOpenInformation->ChangeTime = FFSSysTime(Fcb->dinode1->di_mtime);

						FileNetworkOpenInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);

						FileNetworkOpenInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode1->di_size);
					}
					else
					{
						FileNetworkOpenInformation->CreationTime = FFSSysTime((ULONG)Fcb->dinode2->di_ctime);

						FileNetworkOpenInformation->LastAccessTime = FFSSysTime((ULONG)Fcb->dinode2->di_atime);

						FileNetworkOpenInformation->LastWriteTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);

						FileNetworkOpenInformation->ChangeTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);

						FileNetworkOpenInformation->AllocationSize.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);

						FileNetworkOpenInformation->EndOfFile.QuadPart =
							(LONGLONG)(Fcb->dinode2->di_size);
					}

					FileNetworkOpenInformation->FileAttributes =
						Fcb->FFSMcb->FileAttr;

					Irp->IoStatus.Information =
						sizeof(FILE_NETWORK_OPEN_INFORMATION);
					Status = STATUS_SUCCESS;
					__leave;
				}

			default:
				Status = STATUS_INVALID_INFO_CLASS;
		}
	}
	__finally
	{
		if (FcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (Status == STATUS_PENDING)
			{
				FFSQueueRequest(IrpContext);
			}
			else
			{
				FFSCompleteIrpContext(IrpContext,  Status);
			}
		}
	}

	return Status;
}


NTSTATUS
FFSSetInformation(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT          DeviceObject;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;
	PFFS_VCB                Vcb;
	PFILE_OBJECT            FileObject;
	PFFS_FCB                Fcb;
	PFFS_CCB                Ccb;
	PIRP                    Irp;
	PIO_STACK_LOCATION      IoStackLocation;
	FILE_INFORMATION_CLASS  FileInformationClass;

	ULONG                   NotifyFilter = 0;

	ULONG                   Length;
	PVOID                   Buffer;
	BOOLEAN                 FcbMainResourceAcquired = FALSE;

	BOOLEAN                 VcbResourceAcquired = FALSE;
	BOOLEAN                 FcbPagingIoResourceAcquired = FALSE;


	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

⌨️ 快捷键说明

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