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

📄 file.cpp

📁 功能强大的开源加密软件。使用最新ieee-p1619标准
💻 CPP
字号:
/*
 Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.

 Governed by the TrueCrypt License 2.4 the full text of which is contained
 in the file License.txt included in TrueCrypt binary and source code
 distribution packages.
*/

#define _LARGEFILE_SOURCE	1
#define _FILE_OFFSET_BITS	64

#include <errno.h>
#ifdef TC_LINUX
#include <sys/mount.h>
#endif
#ifdef TC_BSD
#include <sys/disk.h>
#endif
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <utime.h>
#include "Platform/File.h"

namespace TrueCrypt
{
	void File::Close ()
	{
		ValidateState();

		if (!SharedHandle)
		{
			close (FileHandle);
			FileIsOpen = false;

			if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile())
			{
				struct utimbuf u;
				u.actime = AccTime;
				u.modtime = ModTime;

				try
				{
					throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path));
				}
				catch (...) // Suppress errors to allow using read-only files
				{
#ifdef DEBUG 
					throw;
#endif
				}
			}
		}
	}

	void File::Delete ()
	{
		Close();
		Path.Delete();
	}


	void File::Flush () const
	{
		ValidateState();
		throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path));
	}

	uint32 File::GetDeviceSectorSize () const
	{
		if (Path.IsDevice())
		{
#ifdef TC_LINUX
			int blockSize;
			throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path));
			return blockSize;

#elif defined (TC_MACOSX)
			uint32 blockSize;
			throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
			return blockSize;
#endif
		}

		return 512;
	}

	uint64 File::Length () const
	{
		ValidateState();

		// BSD does not support seeking to the end of a device
#ifdef TC_BSD
		if (Path.IsBlockDevice() || Path.IsCharacterDevice())
		{
#	ifdef TC_MACOSX
			uint32 blockSize;
			uint64 blockCount;
			throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
			throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path));
			return blockCount * blockSize;
#	else
			uint64 mediaSize;
			throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path));
			return mediaSize;
#	endif
		}
#endif
		off_t current = lseek (FileHandle, 0, SEEK_CUR);
		throw_sys_sub_if (current == -1, wstring (Path));
		SeekEnd (0);
		uint64 length = lseek (FileHandle, 0, SEEK_CUR);
		SeekAt (current);
		return length;
	}

	void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags)
	{
#ifdef TC_LINUX
		int sysFlags = O_LARGEFILE;
#else
		int sysFlags = 0;
#endif

		switch (mode)
		{
		case CreateReadWrite:
			sysFlags |= O_CREAT | O_TRUNC | O_RDWR;
			break;
				
		case CreateWrite:
			sysFlags |= O_CREAT | O_TRUNC | O_WRONLY;
			break;

		case OpenRead:
			sysFlags |= O_RDONLY;
			break;

		case OpenWrite:
			sysFlags |= O_WRONLY;
			break;

		case OpenReadWrite:
			sysFlags |= O_RDWR;
			break;

		default:
			throw ParameterIncorrect (SRC_POS);
		}

		if ((flags & File::PreserveTimestamps) && path.IsFile())
		{
			struct stat statData;
			throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path));
			AccTime = statData.st_atime;
			ModTime = statData.st_mtime;
		}

		FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR);
		throw_sys_sub_if (FileHandle == -1, wstring (path));

		try
		{
			switch (shareMode)
			{
			case ShareNone:
				if (flock (FileHandle, LOCK_EX | LOCK_NB) == -1)
					throw_sys_sub_if (errno == EAGAIN, wstring (path));
				break;

			case ShareRead:
				if (flock (FileHandle, LOCK_SH | LOCK_NB) == -1)
					throw_sys_sub_if (errno == EAGAIN, wstring (path));
				break;

			case ShareReadWrite:
				if (flock (FileHandle, (mode == OpenRead ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1)
					throw_sys_sub_if (errno == EAGAIN, wstring (path));
				flock (FileHandle, LOCK_UN | LOCK_NB);
				break;
			
			case ShareReadWriteIgnoreLock:
				break;

			default:
				throw ParameterIncorrect (SRC_POS);
			}
		}
		catch (...)
		{
			close (FileHandle);
			throw;
		}

		Path = path;
		mFileOpenFlags = flags;
		FileIsOpen = true;
	}

	uint64 File::Read (const BufferPtr &buffer) const
	{
		ValidateState();

		ssize_t bytesRead = read (FileHandle, buffer, buffer.Size());
		throw_sys_sub_if (bytesRead == -1, wstring (Path));

		return bytesRead;
	}

	uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const
	{
		ValidateState();
		
		ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position);
		throw_sys_sub_if (bytesRead == -1, wstring (Path));

		return bytesRead;
	}

	void File::SeekAt (uint64 position) const
	{
		ValidateState();
		throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path));
	}

	void File::SeekEnd (int offset) const
	{
		ValidateState();

		// BSD does not support seeking to the end of a device
#ifdef TC_BSD
		if (Path.IsBlockDevice() || Path.IsCharacterDevice())
		{
			SeekAt (Length() + offset);
			return;
		}
#endif

		throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path));
	}

	void File::Write (const ConstBufferPtr &buffer) const
	{
		ValidateState();
		throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != buffer.Size(), wstring (Path));
	}
	
	void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const
	{
		ValidateState();
		throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != buffer.Size(), wstring (Path));
	}
}

⌨️ 快捷键说明

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