服务被控端获得指定目录的文件并实现打开和下载功能

2.获得指定目录的文件

3.打开文件和下载文件功能

Directory.h

#pragma once
#include<string>
#include <direct.h>
#include<io.h>
#include<list>
#include"Strategist_FILE.h"
#include"ServerSocket.h"

typedef struct file_info
{
	file_info() {
		IsValid = true;
		IsDirectory = -1;
		HasNext = TRUE;
		memset(szFileName, 0, sizeof(szFileName));
	}
	BOOL IsValid;//当前文件是否有效
	BOOL IsDirectory;//1是目录,0不是
	BOOL HasNext;//是否还有后续文件
	char szFileName[256];//文件名

}FILEINFO, * PFILEINFO;


class CDirectory :public CStrategist_FILE//交由文件策略者处理
{
public:
	CDirectory() {//构造时根据合理命令合理传入路径
		if (CServerSocket::GetInstance()->GetFilePath(strFilePath) == false) {
			OutputDebugString(_T("当前命令,不是文件列表相关操作,命令解析错误!"));
			return;
		}
	}
	std::string GetDirectoryInfo() { return strFilePath; }

	~CDirectory(){}
public:
	void RunFile();

	void DownloadFile();

	void _DeleteFile();

	void DealCommand() override;
private:
	void MakeDirectoryInfo();
private:
	std::string strFilePath;
};

Directory.cpp

#include "pch.h"
#include "Directory.h"
//_CRT_SECURE_NO_WARNINGS
#pragma warning (disable:4996)

void CDirectory::RunFile()
{
	ShellExecuteA(NULL, NULL, strFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL);//WINDOWS API调用执行
	CPacket pack(8, NULL, 0);
	CServerSocket::GetInstance()->Send(pack);
}
#define DOWNLOAD_SIZE 1024
void CDirectory::DownloadFile()
{
	FILE* pFile = NULL;
	errno_t err = fopen_s(&pFile, strFilePath.c_str(), "rb");//任何文件以二进制读取保证任何文件都可以下载
	long long dataSize = 0;
	if (err != 0 ) {
		CPacket pack(4, (BYTE*)&dataSize, 8);
		CServerSocket::GetInstance()->Send(pack);
		return;
	}
	if(pFile!=NULL)
	{
		fseek(pFile, 0, SEEK_END);//设置文件指针在末尾开始偏移,偏移量为 0
		dataSize = _ftelli64(pFile);//获取当前文件指针位置,这里则可以获取到整个文件大小
		CPacket headpack(4, (BYTE*)&dataSize, 8);
		fseek(pFile, 0, SEEK_SET);//记得恢复文件指针到初始位置
		char buffer[DOWNLOAD_SIZE] = "";
		size_t readLength = 0;
		do {
			readLength = fread(buffer, 1, DOWNLOAD_SIZE, pFile);
			CPacket pack(9, (BYTE*)buffer, readLength);
			CServerSocket::GetInstance()->Send(pack);
		} while (readLength >= DOWNLOAD_SIZE);
		fclose(pFile);
	}
	CPacket pack(9, NULL, 0);
	CServerSocket::GetInstance()->Send(pack);	
}

void CDirectory::_DeleteFile()
{
    //TODO::
}

void CDirectory::DealCommand()
{
	if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 7) {
		MakeDirectoryInfo();
	}
	else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 8) {
		RunFile();
	}
	else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 9) {
		DownloadFile();
	}
	else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 10) {
		_DeleteFile();
	}
}

void CDirectory::MakeDirectoryInfo()
{
	//strFilePath会从包中获取到数据,该数据必定是路径,即不会有文件
	//因为后续实际点击事件时,假如点击文件夹目录,则会发送查看文件夹命令7
	//点击到文件则会发送文件执行命令,也就是发送的包数据的控制命令是不同的
	//if (CServerSocket::GetInstance()->GetFilePath(strFilePath) == false) {
	//	OutputDebugString(_T("当前命令,不是获取文件列表,命令解析错误!"));
	//	return;
	//}
	if (_chdir(strFilePath.c_str()) != 0) {//切换到strFilePath作为当前工作目录
		//切换失败
		FILEINFO finfo;
		finfo.IsValid =false;//当前目录无效
		finfo.IsDirectory = true;//因为前面说了发送过来的路径绝对是合理的所以肯定是目录,但是具体错误原因未知
		finfo.HasNext = false;//无下一个
		memcpy(finfo.szFileName, strFilePath.c_str(), strFilePath.size());//直接返回路径名表示无权限访问该目录
		CPacket pack(7, (BYTE*) & finfo, sizeof(finfo));
		CServerSocket::GetInstance()->Send(pack);
		OutputDebugString(_T("无权限访问目录!"));
		return;
	}
	//当前工作目录切换成功后
	_finddata_t fdata;//文件的基本信息的结构体:文件名,文件大小等等基本属性
	int hfind = 0;//用于表示找到后的文件句柄
	if((hfind = _findfirst("*",&fdata)) == -1){//
		OutputDebugString(_T("没有找到任何文件!"));
		return;
	}
	//存在第一个文件,即有文件,且获得了该文件的句柄hfind
	do {
		FILEINFO finfo;
		finfo.IsDirectory = (fdata.attrib & _A_SUBDIR) != 0;//true表示目录,false表示文件
		memcpy(finfo.szFileName, fdata.name, strlen(fdata.name));
		CPacket pack(7, (BYTE*)&finfo, sizeof(finfo));
		CServerSocket::GetInstance()->Send(pack);
	} while (!_findnext(hfind, &fdata));//尝试寻找hfind句柄的下一个文件,然后把信息传给fdata
	FILEINFO finfo;
	finfo.HasNext = false;
	CPacket pack(7, (BYTE*)&finfo, sizeof(finfo));
	CServerSocket::GetInstance()->Send(pack);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值