TrueCrypt代码 之 几个文件操作函数,经常会用到

// Loads a 32-bit integer from the file at the specified file offset. The saved value is assumed to have been
// processed by mputLong(). The lpResult is stored in *lpResult. Returns TRUE if successful (otherwise FALSE).
BOOL	LoadInt32(LPCWSTR lpFilePath, uint32 *lpResult, int64 iFileOffset)
{
	byte *lpBuffer = LoadFileBlock(lpFilePath, iFileOffset, sizeof(__int32));
	if (lpBuffer != NULL)
	{
		byte *bufferPtr = (byte *)lpBuffer;
		*lpResult = mgetLong(bufferPtr);
		free(lpBuffer);
		return TRUE;
	}
	return FALSE;
}

// Loads a 16-bit integer from the file at the specified file offset. The saved value is assumed to have been
// processed by mputWord(). The lpResult is stored in *lpResult. Returns TRUE if successful (otherwise FALSE).
BOOL	LoadInt16(LPCWSTR lpFilePath, int *lpResult, int64 iFileOffset)
{
	byte *lpBuffer = LoadFileBlock(lpFilePath, iFileOffset, sizeof(__int16));
	if (lpBuffer != NULL)
	{
		byte *bufferPtr = (byte *)lpBuffer;
		*lpResult = mgetWord(bufferPtr);
		free(bufferPtr);
		return TRUE;
	}
	return FALSE;
}

// Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated.
byte *	LoadFileAlign(LPCWSTR lpFilePath, DWORD *lpSize, int iAlignSize)
{
	byte *	lpBuffer;
	int		iBufSize = 0;
	HANDLE	hFile = CreateFile(lpFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}

	*lpSize = GetFileSize(hFile, NULL);
	iBufSize = ((*lpSize - 1) / iAlignSize + 1)*iAlignSize + 1;
	lpBuffer = (byte *)malloc(iBufSize);

	if (lpBuffer == NULL)
	{
		CloseHandle(hFile);
		return NULL;
	}

	memset(&lpBuffer[*lpSize], 0, iBufSize - *lpSize);

	if (!ReadFile(hFile, lpBuffer, *lpSize, lpSize, NULL))
	{
		free(lpBuffer);
		lpBuffer = NULL;
	}

	CloseHandle(hFile);
	return lpBuffer;
}

// Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated.
byte *	LoadFile(LPCWSTR lpFilePath, DWORD *lpSize)
{
	byte *	lpBuffer;
	HANDLE	hFile = CreateFile(lpFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}

	*lpSize = GetFileSize(hFile, NULL);
	lpBuffer = (byte *)malloc(*lpSize + 1);

	if (lpBuffer == NULL)
	{
		CloseHandle(hFile);
		return NULL;
	}

	lpBuffer[*lpSize] = 0;

	if (!ReadFile(hFile, lpBuffer, *lpSize, lpSize, NULL))
	{
		free(lpBuffer);
		lpBuffer = NULL;
	}

	CloseHandle(hFile);
	return lpBuffer;
}

// Returns NULL if there's any error.
byte *	LoadFileBlock(LPCWSTR lpFilePath, int64 iFileOffset, size_t count)
{
	byte *	lpBuffer;
	DWORD	dwBytesRead = 0;
	LARGE_INTEGER iSeekOffset, iSeekOffsetNew;

	HANDLE hFile = CreateFile(lpFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}

	iSeekOffset.QuadPart = iFileOffset;
	if (!SetFilePointerEx(hFile, iSeekOffset, &iSeekOffsetNew, FILE_BEGIN))
	{
		CloseHandle(hFile);
		return NULL;
	}

	lpBuffer = (byte *)malloc(count);
	if (lpBuffer == NULL)
	{
		CloseHandle(hFile);
		return NULL;
	}

	if (!ReadFile(hFile, lpBuffer, count, &dwBytesRead, NULL) || dwBytesRead != count)
	{
		CloseHandle(hFile);
		free(lpBuffer);
		return NULL;
	}

	CloseHandle(hFile);
	return lpBuffer;
}

// Returns -1 if there is an error, or the size of the file.
int64	GetFileSize64(LPCWSTR lpPath)
{
	LARGE_INTEGER iSize;
	HANDLE hFile = CreateFile(lpPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return -1;
	}

	if (GetFileSizeEx(hFile, &iSize) == 0)
	{
		return -1;
	}

	CloseHandle(hFile);

	return iSize.QuadPart;
}

// Returns -1 if the specified string is not found in the buffer. Otherwise, returns the
// offset of the first occurrence of the string. The string and the buffer may contain zeroes, 
// which do NOT terminate them.
int64	FindString(void* lpBuffer, const char* lpString, int64 iBufLen, size_t iStrLen, int64 iStartOffset)
{
	if (lpBuffer == NULL || lpString == NULL || iStrLen > iBufLen || iBufLen < 1 || iStrLen < 1 || iStartOffset > iBufLen - iStrLen)
	{
		return -1;
	}

	for (int64 iIndex = iStartOffset; iIndex <= iBufLen - iStrLen; iIndex++)
	{
		if (memcmp((byte*)lpBuffer + iIndex, lpString, iStrLen) == 0)
		{
			return iIndex;
		}
	}

	return -1;
}

// Returns TRUE if the file or directory exists (both may be enclosed in quotation marks).
BOOL	FileExists(LPCWSTR lpFilePath)
{
	WCHAR szFilePath[CC_LONG_PATH+1];

	// Strip quotation marks (if any)
	if (wcslen(lpFilePath) > 1 && lpFilePath[0] == '"')
	{
		wcscpy(szFilePath, lpFilePath + 1);
	}
	else
	{
		wcscpy(szFilePath, lpFilePath);
	}

	// Strip quotation marks (if any)
	if (wcslen(szFilePath) > 1 && szFilePath[wcslen(szFilePath) - 1] == '"')
	{
		szFilePath[wcslen(szFilePath) - 1] = 0;
	}

	return (_waccess(szFilePath, 0) != -1);
}

// Searches the file from its end for the LAST occurrence of the string str.
// The string may contain zeroes, which do NOT terminate the string.
// If the string is found, its offset from the start of the file is returned. 
// If the string isn't found or if any error occurs, -1 is returned.
int64	FindStringInFile(LPCWSTR lpFilePath, const char* lpString, int iStrLen)
{
	int			iBufSize = 64 * BYTES_PER_KB;
	byte *		lpBuffer = (byte *)err_malloc(iBufSize);
	HANDLE		hFile = NULL;
	DWORD		dwBytesRead;
	BOOL		bReadRetVal;
	int64		iFilePos = GetFileSize64(lpFilePath);
	int			iBufPos = 0;
	LARGE_INTEGER iSeekOffset, iSeekOffsetNew;
	BOOL		bExit = FALSE;
	int			iFilePosStep;
	int64		iRetCode = -1;

	if (iFilePos <= 0 || lpBuffer == NULL || iStrLen > iBufSize || iStrLen < 1)
	{
		return -1;
	}

	hFile = CreateFile(lpFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		free(lpBuffer);
		return -1;
	}

	iFilePosStep = iBufSize - iStrLen + 1;

	do
	{
		iFilePos -= iFilePosStep;

		if (iFilePos < 0)
		{
			iFilePos = 0;
			bExit = TRUE;
		}

		iSeekOffset.QuadPart = iFilePos;

		if (!SetFilePointerEx(hFile, iSeekOffset, &iSeekOffsetNew, FILE_BEGIN))
		{
			goto fsif_end;
		}

		bReadRetVal = ReadFile(hFile, lpBuffer, iBufSize, &dwBytesRead, NULL);
		if (!bReadRetVal || dwBytesRead == 0)
		{
			goto fsif_end;
		}

		iBufPos = dwBytesRead - iStrLen;

		while (iBufPos > 0)
		{
			if (memcmp(lpBuffer + iBufPos, lpString, iStrLen) == 0)
			{
				// String found
				iRetCode = iFilePos + iBufPos;
				goto fsif_end;
			}
			iBufPos--;
		}

	} while (!bExit);

fsif_end:
	CloseHandle(hFile);
	free(lpBuffer);

	return iRetCode;
}

// System CopyFile() copies source file attributes (like FILE_ATTRIBUTE_ENCRYPTED)
// so we need to use our own copy function
BOOL	CCXCopyFile(LPCWSTR lpSrcFileName, LPCWSTR lpDstFileName)
{
	byte *		lpBuffer = NULL;
	HANDLE		hFileSrc = NULL, hFileDst = NULL;
	FILETIME	tFileTime;
	DWORD		dwBytesRead, dwBytesWritten;
	BOOL		bResult;

	hFileSrc = CreateFile(lpSrcFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hFileSrc == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	hFileDst = CreateFile(lpDstFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
	if (hFileDst == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hFileSrc);
		return FALSE;
	}

	lpBuffer = (byte *)malloc(64 * 1024);
	if (lpBuffer == NULL)
	{
		CloseHandle(hFileSrc);
		CloseHandle(hFileDst);
		return FALSE;
	}

	while (bResult = ReadFile(hFileSrc, lpBuffer, 64 * 1024, &dwBytesRead, NULL))
	{
		if (dwBytesRead == 0)
		{
			bResult = 1;
			break;
		}

		if (!WriteFile(hFileDst, lpBuffer, dwBytesRead, &dwBytesWritten, NULL) || dwBytesRead != dwBytesWritten)
		{
			bResult = 0;
			break;
		}
	}

	GetFileTime(hFileSrc, NULL, NULL, &tFileTime);
	SetFileTime(hFileDst, NULL, NULL, &tFileTime);

	CloseHandle(hFileSrc);
	CloseHandle(hFileDst);

	free(lpBuffer);
	return bResult;
}

// If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file 
// is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE).
BOOL	SaveBufferToFile(LPCWSTR lpFilePath, void* lpBuffer, DWORD iBufLen, BOOL bAppend)
{
	HANDLE hFile;
	DWORD dwBytesWritten;
	BOOL bResult = TRUE;

	hFile = CreateFile(lpFilePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	if (bAppend)
	{
		SetFilePointer(hFile, 0, NULL, FILE_END);
	}

	if (!WriteFile(hFile, lpBuffer, iBufLen, &dwBytesWritten, NULL) || iBufLen != dwBytesWritten)
	{
		bResult = FALSE;
	}

	//if (!bResult)
	//{
	//	// If CREATE_ALWAYS is used, ERROR_ALREADY_EXISTS is returned after successful overwrite of an existing file (it's not an error)
	//	if (bAppend || GetLastError() != ERROR_ALREADY_EXISTS)
	//	{
	//		handleWin32Error(g_hMainDlg);
	//	}
	//}
	DWORD dwError = GetLastError();
	CloseHandle(hFile);

	if (!bResult && !bAppend)
	{
		_wremove(lpFilePath);
	}
	SetLastError(dwError);

	return bResult;
}
 


 
 

你可能感兴趣的:(TrueCrypt代码 之 几个文件操作函数,经常会用到)