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

📄 ext2fs.c

📁 ext2 file system driver for win nt
💻 C
📖 第 1 页 / 共 5 页
字号:

	Index -= 12;

	for (i = 0; i < 3; i++)
	{
		if (i > 0)
		{
			dwSizes[i] = vcb->ext2_block/4 * dwSizes[i-1];
		}
		if (Index < dwSizes[i])
		{
			return Ext2GetBlock(vcb, ext2_inode->i_block[i + 12], Index , i + 1); 
		}
		Index -= dwSizes[i];
	}

	return 0;
}


ULONG
Ext2ReadInode (IN PEXT2_VCB vcb,
	       IN struct ext2_inode* ext2_inode,
	       IN ULONG offset,
	       IN PVOID Buffer,
	       IN ULONG size )
{
	ULONG	dwBytes = 0;
	ULONG	nBeg, nEnd;
	ULONG	dwBlk;
	ULONG	lba, off, dwSize;
	ULONG   i;

	nBeg = offset / vcb->ext2_block;
	nEnd = (size + offset + vcb->ext2_block - 1) / vcb->ext2_block;

	for (i = nBeg; i < nEnd; i++)
	{
		dwBlk = Ext2BlockMap(vcb, ext2_inode, i);
		lba = dwBlk * vcb->ext2_block / SECTOR_SIZE;
		off = 0;
		dwSize = vcb->ext2_block;

		if (i == nBeg)
		{
			lba += (offset % vcb->ext2_block) / SECTOR_SIZE; 
			off = offset % SECTOR_SIZE;
			dwSize = vcb->ext2_block - (offset % vcb->ext2_block);
		}
		else if (i == nEnd)
		{
			dwSize = size - dwBytes;
		}
		Ext2ReadDisk(vcb->TargetDeviceObject,
			lba, off, dwSize, &((PUCHAR)Buffer)[dwBytes]);
		dwBytes += dwSize;

	}

	return dwBytes;
}

ULONG
Ext2WriteInode (IN PEXT2_VCB vcb,
	       IN struct ext2_inode* ext2_inode,
	       IN ULONG offset,
	       IN PVOID Buffer,
	       IN ULONG size )
{

	ULONG	dwBytes = 0;
	ULONG	nBeg, nEnd;
	ULONG	dwBlk;
	ULONG	lba, off, dwSize;
	ULONG   i;

	nBeg = offset / vcb->ext2_block;
	nEnd = (size + offset + vcb->ext2_block - 1) / vcb->ext2_block;

	for (i = nBeg; i < nEnd; i++)
	{
		dwBlk = Ext2BlockMap(vcb, ext2_inode, nBeg);
		lba = dwBlk * vcb->ext2_block / SECTOR_SIZE;
		off = 0;
		dwSize = vcb->ext2_block;

		if (i == nBeg)
		{
			off = offset;
			dwSize = vcb->ext2_block - off;
		}
		else if (i == nEnd)
		{
			dwSize = size - dwBytes;
		}
		Ext2WriteDisk(vcb->TargetDeviceObject,
			lba, off, dwSize, &((PUCHAR)Buffer)[dwBytes]);
		dwBytes += dwSize;

	}

	return dwBytes;
}


PEXT2_IRP_CONTEXT
Ext2AllocateIrpContext (IN PDEVICE_OBJECT   DeviceObject,
			IN PIRP             Irp )
{
	PIO_STACK_LOCATION  IoStackLocation;
	PEXT2_IRP_CONTEXT    IrpContext;
	
	ASSERT(DeviceObject != NULL);
	ASSERT(Irp != NULL);
	
	IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
	
	IrpContext = (PEXT2_IRP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(EXT2_IRP_CONTEXT));
	
	if (!IrpContext)
	{
		return NULL;
	}
	
	IrpContext->Identifier.Type = ICX;
	IrpContext->Identifier.Size = sizeof(EXT2_IRP_CONTEXT);
	
	IrpContext->Irp = Irp;
	
	IrpContext->MajorFunction = IoStackLocation->MajorFunction;
	IrpContext->MinorFunction = IoStackLocation->MinorFunction;
	
	IrpContext->DeviceObject = DeviceObject;
	
	IrpContext->FileObject = IoStackLocation->FileObject;
	
	if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
		IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
		IrpContext->MajorFunction == IRP_MJ_SHUTDOWN)
	{
		IrpContext->IsSynchronous = TRUE;
	}
	else if (IrpContext->MajorFunction == IRP_MJ_CLEANUP ||
		IrpContext->MajorFunction == IRP_MJ_CLOSE)
	{
		IrpContext->IsSynchronous = FALSE;
	}
	else
	{
		IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
	}
	
	//
	// Temporary workaround for a bug in close that makes it reference a
	// fileobject when it is no longer valid.
	//
	if (IrpContext->MajorFunction == IRP_MJ_CLOSE)
	{
		IrpContext->IsSynchronous = TRUE;
	}
	
	IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
	
	IrpContext->ExceptionInProgress = FALSE;
	
	return IrpContext;
}

VOID
Ext2FreeIrpContext (IN PEXT2_IRP_CONTEXT IrpContext)
{
	ASSERT(IrpContext != NULL);
	
	ASSERT((IrpContext->Identifier.Type == ICX) &&
		(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
	
	ExFreePool(IrpContext);
}

PEXT2_FCB
Ext2AllocateFcb (IN PEXT2_VCB            Vcb,
		 IN PUNICODE_STRING      FileName,
		 IN ULONG                IndexNumber,
		 IN ULONG		 inode,
		 IN ULONG		 dir_inode,
		 IN struct ext2_inode*   ext2_inode )
{
	PEXT2_FCB Fcb;
	
	Fcb = (PEXT2_FCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
	
	if (!Fcb)
	{
		return NULL;
	}
	
	Fcb->Identifier.Type = FCB;
	Fcb->Identifier.Size = sizeof(EXT2_FCB);
	
#ifndef EXT2_RO
	
	RtlZeroMemory(&Fcb->ShareAccess, sizeof(SHARE_ACCESS));
	
#endif
	
	FsRtlInitializeFileLock (
		&Fcb->FileLockAnchor,
		NULL,
		NULL );
	
	Fcb->OpenHandleCount = 0;
	Fcb->ReferenceCount = 0;
	
#ifndef EXT2_RO
	
	Fcb->IsPageFile = FALSE;
	
	Fcb->DeletePending = FALSE;
	
#endif
	
	Fcb->FileName.Length = 0;
	
	Fcb->FileName.MaximumLength = FileName->MaximumLength;
	
	Fcb->FileName.Buffer = (PWSTR) ExAllocatePool(
		NonPagedPool,
		Fcb->FileName.MaximumLength
		);
	
	if (!Fcb->FileName.Buffer)
	{
		ExFreePool(Fcb);
		return NULL;
	}
	
	RtlCopyUnicodeString(
		&Fcb->FileName,
		FileName );
	
#if DBG
	
	Fcb->DbgFileName = (PUCHAR) ExAllocatePool(
		NonPagedPool,
		Fcb->FileName.MaximumLength / sizeof(WCHAR) + 1
		);
	
	if (!Fcb->DbgFileName)
	{
		ExFreePool(Fcb->FileName.Buffer);
		ExFreePool(Fcb);
		return NULL;
	}
	
	Ext2WcharToChar (
		Fcb->DbgFileName,
		Fcb->FileName.Buffer,
		Fcb->FileName.Length / sizeof(WCHAR)
		);
	
	Fcb->DbgFileName[Fcb->FileName.Length / sizeof(WCHAR)] = 0;

#endif // DBG
	
	Fcb->FileAttributes = FILE_ATTRIBUTE_NORMAL;
	
	if (S_ISDIR(ext2_inode->i_mode))
	{
		Fcb->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
	}
	
	Fcb->IndexNumber.QuadPart = IndexNumber;
	
	Fcb->ext2_inode = ext2_inode;
	Fcb->inode = inode;
	Fcb->dir_inode = dir_inode;
	
	RtlZeroMemory(&Fcb->CommonFCBHeader, sizeof(FSRTL_COMMON_FCB_HEADER));
	
	//Fcb->CommonFCBHeader.NodeTypeCode = 
	Fcb->CommonFCBHeader.NodeByteSize = sizeof(FSRTL_COMMON_FCB_HEADER);
	Fcb->CommonFCBHeader.IsFastIoPossible = FastIoIsNotPossible;
	Fcb->CommonFCBHeader.Resource = &(Fcb->MainResource);
	Fcb->CommonFCBHeader.PagingIoResource = &(Fcb->PagingIoResource);
	Fcb->CommonFCBHeader.AllocationSize.QuadPart = ext2_inode->i_size;
	Fcb->CommonFCBHeader.FileSize.QuadPart = ext2_inode->i_size;
	Fcb->CommonFCBHeader.ValidDataLength.QuadPart = ext2_inode->i_size;
	
	Fcb->SectionObject.DataSectionObject = NULL;
	Fcb->SectionObject.SharedCacheMap = NULL;
	Fcb->SectionObject.ImageSectionObject = NULL;
	
	ExInitializeResourceLite(&(Fcb->MainResource));
	ExInitializeResourceLite(&(Fcb->PagingIoResource));
	
	InsertTailList(&Vcb->FcbList, &Fcb->Next);
	
	return Fcb;
}

VOID
Ext2FreeFcb (IN PEXT2_FCB Fcb)
{
	ASSERT(Fcb != NULL);
	
	ASSERT((Fcb->Identifier.Type == FCB) &&
		(Fcb->Identifier.Size == sizeof(EXT2_FCB)));

	FsRtlUninitializeFileLock(&Fcb->FileLockAnchor);

	ExDeleteResourceLite(&Fcb->MainResource);
	
	ExDeleteResourceLite(&Fcb->PagingIoResource);
	
	RemoveEntryList(&Fcb->Next);
	
	ExFreePool(Fcb->FileName.Buffer);
	
#if DBG
	ExFreePool(Fcb->DbgFileName);
#endif
	
	ExFreePool(Fcb->ext2_inode);
	
	ExFreePool(Fcb);
}

PEXT2_CCB
Ext2AllocateCcb (VOID)
{
	PEXT2_CCB Ccb;
	
	Ccb = (PEXT2_CCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_CCB));
	
	if (!Ccb)
	{
		return NULL;
	}
	
	Ccb->Identifier.Type = CCB;
	Ccb->Identifier.Size = sizeof(EXT2_CCB);
	
	Ccb->CurrentByteOffset = 0;
	
	Ccb->DirectorySearchPattern.Length = 0;
	Ccb->DirectorySearchPattern.MaximumLength = 0;
	Ccb->DirectorySearchPattern.Buffer = 0;
	
	return Ccb;
}

VOID
Ext2FreeCcb (IN PEXT2_CCB Ccb)
{
	ASSERT(Ccb != NULL);
	
	ASSERT((Ccb->Identifier.Type == CCB) &&
		(Ccb->Identifier.Size == sizeof(EXT2_CCB)));
	
	if (Ccb->DirectorySearchPattern.Buffer != NULL)
	{
		ExFreePool(Ccb->DirectorySearchPattern.Buffer);
	}
	
	ExFreePool(Ccb);
}

VOID
Ext2FreeVcb (IN PEXT2_VCB Vcb )
{
	ASSERT(Vcb != NULL);
	
	ASSERT((Vcb->Identifier.Type == VCB) &&
		(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
	
	Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
	
	ExAcquireResourceExclusiveLite(
		&Ext2Global->Resource,
		TRUE );
	
	RemoveEntryList(&Vcb->Next);
	
	ExReleaseResourceForThreadLite(
		&Ext2Global->Resource,
		ExGetCurrentResourceThread() );
	
	ExDeleteResourceLite(&Vcb->MainResource);
	
	ExDeleteResourceLite(&Vcb->PagingIoResource);
	
	if (Vcb->ext2_super_block)
		ExFreePool(Vcb->ext2_super_block);
	if (Vcb->ext2_group_desc)
		ExFreePool(Vcb->ext2_group_desc);
	
	IoDeleteDevice(Vcb->DeviceObject);
}

BOOLEAN
Ext2FastIoCheckIfPossible (
			  IN PFILE_OBJECT         FileObject,
			  IN PLARGE_INTEGER       FileOffset,
			  IN ULONG                Length,
			  IN BOOLEAN              Wait,
			  IN ULONG                LockKey,
			  IN BOOLEAN              CheckForReadOperation,
			  OUT PIO_STATUS_BLOCK    IoStatus,
			  IN PDEVICE_OBJECT       DeviceObject
			  )
{
	BOOLEAN          Status = FALSE;
	PEXT2_FCB        Fcb;
	LARGE_INTEGER    lLength;
	
	lLength.QuadPart = Length;
	
	PAGED_CODE();
	
	__try
	{
		__try
		{
			if (DeviceObject == Ext2Global->DeviceObject)
			{
				Status = FALSE;
				__leave;
			}
			
			Fcb = (PEXT2_FCB) FileObject->FsContext;
			
			ASSERT(Fcb != NULL);
			
			if (Fcb->Identifier.Type == VCB)
			{
				Status = FALSE;
				__leave;
			}
			
			ASSERT((Fcb->Identifier.Type == FCB) &&
				(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
			
			if (Fcb->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				Status = FALSE;
				__leave;
			}
			
			FsRtlEnterFileSystem();
			
			if (CheckForReadOperation)
			{
				Status = FsRtlFastCheckLockForRead(
					&Fcb->FileLockAnchor,
					FileOffset,
					&lLength,
					LockKey,
					FileObject,
					PsGetCurrentProcess());
			}
			else
			{
				Status = FsRtlFastCheckLockForWrite(
					&Fcb->FileLockAnchor,
					FileOffset,
					&lLength,
					LockKey,
					FileObject,
					PsGetCurrentProcess());
			}
#if DBG			
			KdPrint(("Ext2FastIOCheckPossible: %-16.16s %-31s %s\n",
				PsGetCurrentProcess()->ImageFileName,
				"FASTIO_CHECK_IF_POSSIBLE",
				Fcb->DbgFileName));
#endif			
			KdPrint(("Ext2FastIIOCheckPossible: Offset: %I64u Length: %u Key: %u %s %s\n",
				FileOffset->QuadPart,
				Length,
				LockKey,
				(CheckForReadOperation ? "CheckForReadOperation:" : "CheckForWriteOperation:"),
				(Status ? "Succeeded" : "Failed")));
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
			Status = FALSE;
		}
	}
	__finally
	{
		FsRtlExitFileSystem();
	}
	
	return Status;
}


#if DBG
BOOLEAN
Ext2FastIoRead (IN PFILE_OBJECT         FileObject,
	       IN PLARGE_INTEGER       FileOffset,
	       IN ULONG                Length,
	       IN BOOLEAN              Wait,
	       IN ULONG                LockKey,
	       OUT PVOID               Buffer,
	       OUT PIO_STATUS_BLOCK    IoStatus,
	       IN PDEVICE_OBJECT       DeviceObject)
{
	BOOLEAN     Status;
	PEXT2_FCB    Fcb;
	
	PAGED_CODE();
	
	Fcb = (PEXT2_FCB) FileObject->FsContext;
	
	ASSERT(Fcb != NULL);
	
	ASSERT((Fcb->Identifier.Type == FCB) &&
		(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
	
	Status = FsRtlCopyRead (
		FileObject, FileOffset,	Length,	Wait,
		LockKey, Buffer, IoStatus, DeviceObject);
	
	return Status;
}

#endif /* DBG */


BOOLEAN
Ext2FastIoQueryBasicInfo (IN PFILE_OBJECT             FileObject,
			  IN BOOLEAN                  Wait,
			  OUT PFILE_BASIC_INFORMATION Buffer,
			  OUT PIO_STATUS_BLOCK        IoStatus,
			  IN PDEVICE_OBJECT           DeviceObject)
{
	BOOLEAN     Status = FALSE;
	PEXT2_FCB Fcb;
	BOOLEAN     FcbMainResourceAcquired = FALSE;
	
	PAGED_CODE();
	__try
	{
		__try
		{
			if (DeviceObject == Ext2Global->DeviceObject)
			{
				IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
				Status = TRUE;
				__leave;
			}
			
			Fcb = (PEXT2_FCB) FileObject->FsContext;
			
			ASSERT(Fcb != NULL);
			
			if (Fcb->Identifier.Type == VCB)
			{
				IoStatus->Status = STATUS_INVALID_PARAMETER;
				Status = TRUE;
				__leave;
			}
			
			ASSERT((Fcb->Identifier.Type == FCB) &&
				(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
#if DBG			
			KdPrint((
				DRIVER_NAME ": %-16.16s %-31s %s\n",
				PsGetCurrentProcess()->ImageFileName,
				"FASTIO_QUERY_BASIC_INFO",
				Fcb->DbgFileName
				));
#endif			
			FsRtlEnterFileSystem();
			
			if (!ExAcquireResourceSharedLite(
				&Fcb->MainResource,
				Wait))
			{
				Status = FALSE;
				__leave;
			}
			
			FcbMainResourceAcquired = TRUE;
			
			RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
			
			/*
			typedef struct _FILE_BASIC_INFORMATION {
			LARGE_INTEGER   CreationTime;
			LARGE_INTEGER   LastAccessTime;
			LARGE_INTEGER   LastWriteTime;
			LARGE_INTEGER   ChangeTime;
			ULONG           FileAttributes;
			} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
			*/

			Buffer->CreationTime = Ext2SysTime(Fcb->ext2_inode->i_ctime + TIMEZONE);
			Buffer->LastAccessTime = Ext2SysTime(Fcb->ext2_inode->i_atime + TIMEZONE);
			Buffer->LastWriteTime = Ext2SysTime(Fcb->ext2_inode->i_mtime + TIMEZONE);
			Buffer->ChangeTime = Ext2SysTime(Fcb->ext2_inode->i_mtime + TIMEZONE);
			
			
			Buffer->FileAttributes = Fcb->FileAttributes;
			
			IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
			
			IoStatus->Status = STATUS_SUCCESS;
			
			Status =  TRUE;

⌨️ 快捷键说明

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