You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

483 lines
9.7 KiB
C++

1 month ago
#include "stdafx.h"
#include "../FormaConversion/DFDConversion.h"
#include "FileUtility.h"
// <20><><EFBFBD><EFBFBD><EFBFBD>޸ģ<DEB8><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static const char KEV_XORKEY[] = "VersionRamanujan";
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param data
* @param key
*/
void XorEncrypt(LPTSTR lpData, DWORD len, LPCTSTR lpKey) {
size_t key_len = strlen(lpKey);
for (size_t i = 0; i < len; i++) {
lpData[i] ^= lpKey[i % key_len];
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.
*
* @param lpFilePath
* @return
*/
BOOL XorEncryptFile(LPCTSTR lpFilePath)
{
HANDLE hDstFile = CreateFile(lpFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDstFile == INVALID_HANDLE_VALUE) {
TRACE("Failed to open destination file, error code: %d\n", GetLastError());
return FALSE;
}
DWORD dwFileSizeHigh = 0;
DWORD dwFileSizeLow = GetFileSize(hDstFile, &dwFileSizeHigh);
HANDLE hMapping = CreateFileMapping(hDstFile, NULL, PAGE_READWRITE, dwFileSizeHigh, dwFileSizeLow, NULL);
if (hMapping == NULL) {
TRACE("Failed to create file mapping, error code: %d\n", GetLastError());
CloseHandle(hDstFile);
return FALSE;
}
LPVOID lpMapping = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpMapping == NULL) {
TRACE("Failed to map view of file, error code: %d\n", GetLastError());
CloseHandle(hMapping);
CloseHandle(hDstFile);
return FALSE;
}
LARGE_INTEGER large_integer;
GetFileSizeEx(hDstFile, &large_integer);
XorEncrypt((LPTSTR)lpMapping, large_integer.QuadPart, KEV_XORKEY);
UnmapViewOfFile(lpMapping);
CloseHandle(hMapping);
CloseHandle(hDstFile);
return true;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.
*
* @param lpSrcFilePath ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ļ<EFBFBD>
* @param lpDstFilePath ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>
* @return
*/
BOOL XorEncryptFile(LPCTSTR lpSrcFilePath, LPCTSTR lpDstFilePath)
{
bool ret = false;
if (!CheckAndCreateDirectory(GetTempDirectory()))
{
return false;
}
if (lpDstFilePath != NULL && strcmp(lpSrcFilePath, lpDstFilePath) != 0)
{
ret = CopyLargeFileByMapping(lpSrcFilePath, lpDstFilePath);
if (!ret)
{
return false;
}
ret = XorEncryptFile(lpDstFilePath);
}
else {
ret = XorEncryptFile(lpSrcFilePath);
}
return ret;
}
/**
* @brief <EFBFBD>ļ<EFBFBD>ӳ<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>
*
* @param lpSrcFilePath
* @param lpDstFilePath
* @return
*/
BOOL CopyLargeFileByMapping(LPCTSTR lpSrcFilePath, LPCTSTR lpDstFilePath)
{
HANDLE hSrcFile = CreateFile(lpSrcFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hSrcFile == INVALID_HANDLE_VALUE) {
TRACE("Failed to open source file, error code: %d\n", GetLastError());
return FALSE;
}
DWORD dwFileSizeHigh = 0, dwFileSizeLow = GetFileSize(hSrcFile, &dwFileSizeHigh);
if (dwFileSizeLow == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
TRACE("Failed to get the size of source file, error code: %d\n", GetLastError());
CloseHandle(hSrcFile);
return FALSE;
}
HANDLE hDstFile = CreateFile(lpDstFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDstFile == INVALID_HANDLE_VALUE) {
TRACE("Failed to create destination file, error code: %d\n", GetLastError());
CloseHandle(hSrcFile);
return FALSE;
}
HANDLE hMapping = CreateFileMapping(hSrcFile, NULL, PAGE_READONLY, dwFileSizeHigh, dwFileSizeLow, NULL);
if (hMapping == NULL) {
TRACE("Failed to create file mapping, error code: %d\n", GetLastError());
CloseHandle(hDstFile);
CloseHandle(hSrcFile);
return FALSE;
}
LPVOID lpMapping = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (lpMapping == NULL) {
TRACE("Failed to map view of file, error code: %d\n", GetLastError());
CloseHandle(hMapping);
CloseHandle(hDstFile);
CloseHandle(hSrcFile);
return FALSE;
}
DWORD dwBytesWritten = 0;
if (!WriteFile(hDstFile, lpMapping, dwFileSizeLow, &dwBytesWritten, NULL) || dwBytesWritten != dwFileSizeLow) {
TRACE("Failed to write to destination file, error code: %d\n", GetLastError());
UnmapViewOfFile(lpMapping);
CloseHandle(hMapping);
CloseHandle(hDstFile);
CloseHandle(hSrcFile);
return FALSE;
}
UnmapViewOfFile(lpMapping);
CloseHandle(hMapping);
CloseHandle(hDstFile);
CloseHandle(hSrcFile);
TRACE("Successfully copied the file!\n");
return TRUE;
}
/**
* @brief <EFBFBD>ж<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>UNICODE<EFBFBD>ļ<EFBFBD>.
*
* @param filename
* @return
*/
bool IsUnicodeTextFile(const char *filename) {
HANDLE fileHandle = CreateFile(
filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fileHandle == INVALID_HANDLE_VALUE) {
perror("Failed to open file");
return false;
}
DWORD fileSize = GetFileSize(fileHandle, NULL);
if (fileSize == INVALID_FILE_SIZE) {
CloseHandle(fileHandle);
perror("Failed to get file size");
return false;
}
HANDLE mappingHandle = CreateFileMapping(
fileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
if (mappingHandle == NULL) {
CloseHandle(fileHandle);
perror("Failed to create file mapping");
return false;
}
LPVOID fileBuffer = MapViewOfFile(mappingHandle, FILE_MAP_READ, 0, 0, fileSize);
if (fileBuffer == NULL) {
CloseHandle(mappingHandle);
CloseHandle(fileHandle);
perror("Failed to map view of file");
return false;
}
bool isText = IsTextUnicode(fileBuffer, fileSize, NULL);
UnmapViewOfFile(fileBuffer);
CloseHandle(mappingHandle);
CloseHandle(fileHandle);
return isText;
}
/**
* @brief <EFBFBD>Ƿ<EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.
*
* @param file
* @return
*/
bool IsBinaryFile(CString filePath)
{
FILE* file = fopen(filePath, "rb");
if (file == NULL)
{
return false; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
}
int isBinary = false;
unsigned char buffer[512];
size_t bytesRead = fread(buffer, 1, sizeof(buffer), file);
if (bytesRead > 0)
{
for (size_t i = 0; i < bytesRead; i++)
{
if (buffer[i] <= 8 || buffer[i] == 11 || buffer[i] == 12 || buffer[i] == 14 || buffer[i] == 15)
{
isBinary = true;
break;
}
}
}
fclose(file);
return isBinary;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*
* @param filePath
* @return
*/
CString GetFirstLineOfFile(const CString& filePath)
{
CStdioFile file;
if (!file.Open(filePath, CFile::modeRead))
{
return ""; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF>ַ<EFBFBD><D6B7><EFBFBD>
}
TCHAR firstLine[256];
file.ReadString(firstLine, sizeof(firstLine) / sizeof(TCHAR) - 1);
file.Close();
return CString(firstLine);
}
/**
* @brief Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.
*
* @param filePath
* @return <EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>
*/
CString PreprocessFile(CString& filePath)
{
CString path = filePath;
path.MakeLower();
CSplitPath sp(path);
CString ext = sp.GetExtension();
if (!CheckAndCreateDirectory(GetTempDirectory()))
{
return false;
}
if (ext == ".kev")
{
if (!IsBinaryFile(filePath))
{
return filePath;
}
else
{
CString tmpPath = generateTempFile(filePath);
if (XorEncryptFile(filePath, tmpPath))
{
return tmpPath;
}
else
{
return "";
}
}
}
else if (ext == ".dfd")
{
CString ver = GetFirstLineOfFile(filePath);
ver.Trim();
if (ver.CompareNoCase("Version 2022") <= 0)
{
return filePath;
}
else if (ver.CompareNoCase("Version 2022") > 0 && ver.CompareNoCase("Version 2032") <= 0)
{
CString tmpPath = generateTempFile(filePath);
int ret = FromDFDToDFD4(filePath.GetBuffer(), tmpPath.GetBuffer());
if (ret == 0)
{
return "";
}
else
{
return tmpPath;
}
}
else {
return "";
}
}
return filePath;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.
*
* @param filePath
* @return
*/
void PostProcessFile(CString& filePath)
{
CString path = filePath;
path.MakeLower();
CSplitPath sp(path);
CString ext = sp.GetExtension();
if (ext == ".kev")
{
XorEncryptFile(filePath);
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*
* @param folderPath
*/
void ClearFolder(const CString& folderPath)
{
try
{
// <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
CString searchPath = folderPath + _T("\\*.*");
CFileFind finder;
BOOL bWorking = finder.FindFile(searchPath);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (finder.IsDots())
continue;
CString filePath = finder.GetFilePath();
if (finder.IsDirectory())
{
// <20>ݹ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
ClearFolder(filePath);
RemoveDirectory(filePath);
}
else
{
// ɾ<><C9BE><EFBFBD>ļ<EFBFBD>
DeleteFile(filePath);
}
}
finder.Close();
}
catch (const std::exception&)
{
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>.
*
*/
void ClearTempFolder()
{
ClearFolder(GetTempDirectory());
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼.
*
* @param path
* @return
*/
BOOL CheckAndCreateDirectory(const CString& path)
{
if (!PathFileExists(path))
{
CFileFind finder;
BOOL bFound = finder.FindFile(path);
if (!bFound)
{
// Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>Ŀ¼
if (CreateDirectory(path, NULL))
{
return TRUE;
}
else
{
// <20><><EFBFBD><EFBFBD>Ŀ¼ʧ<C2BC><CAA7>
return FALSE;
}
}
// Ŀ¼<C4BF>Ѵ<EFBFBD><D1B4><EFBFBD>
return TRUE;
}
return TRUE;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>GUID<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>.
*
* @param guidStr
*/
void generateGUID(char* pGuidStr) {
GUID guid;
CoCreateGuid(&guid);
sprintf(pGuidStr, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>.
*
* @return <EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD>
*/
CString generateTempFile(CString& filePath)
{
CSplitPath sp(filePath);
CString ext = sp.GetExtension();
CString tmpPath = GetTempDirectory();
char uuidStr[37];
generateGUID(uuidStr);
tmpPath.Append(uuidStr);
tmpPath.Append(ext);
return tmpPath;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼.
*
* @return <EFBFBD><EFBFBD>ǰӦ<EFBFBD><EFBFBD>Ŀ¼
*/
CString GetTempDirectory()
{
CString tempDir = GetExecutableDirectory();
tempDir.Append("\\temp\\");
return tempDir;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼.
*
* @return <EFBFBD><EFBFBD>ǰӦ<EFBFBD><EFBFBD>Ŀ¼
*/
CString GetExecutableDirectory()
{
TCHAR buffer[MAX_PATH] = { 0 };
GetModuleFileName(NULL, buffer, MAX_PATH);
PathRemoveFileSpec(buffer);
return CString(buffer);
}