Files
dnf-utils/sgutil/sgu_download_ant.h
2025-09-01 20:47:58 +08:00

153 lines
5.3 KiB
C++

#pragma once
#include "libEncrypt_MD5.h"
typedef DWORD (WINAPI *DOWNANT_STATUS_CALLBACK)(VOID* pOwner, VOID* pDownAnt);
#define MANAGER_CMD_CONTINUE (0) //继续下载
#define MANAGER_CMD_FORCEABORT (1) //强制中止
#define MANAGER_CMD_STOPHERE (2) //下载的目前为止
/** 下载器,用于下载一个单独文件
*/
class CDownloadAnt
{
public:
//主状态
enum DOWN_STATE_CATEGORY
{
IDLE, //空闲
BUSY, //忙碌中
FINISH_SUCCESS, //成功下载完毕
FINISH_NOT_SUCCESS, //下载失败
};
enum DOWN_STATE
{
IDLE_NOTINIT, //空闲 - 尚未初始化
IDLE_INIT_SUCCESS, //空闲 - 初始化成功
IDLE_INIT_FAILED, //空闲 - 初始化失败
BUSY_BEGIN_THREAD, //忙碌中 - 启动下载线程
BUSY_OPEN_REQUEST, //忙碌中 - 发送下载请求
BUSY_RESOLVING_NAME, //忙碌中 - 查找服务器中
BUSY_RESOLVED_NAME, //忙碌中 - 查找完服务器
BUSY_CONNECTING, //忙碌中 - 连接服务器中
BUSY_CONNECTED, //忙碌中 - 连接完服务器
BUSY_REDIRECTING, //忙碌中 - 重新定位中
BUSY_GET_FILE_INFORMATION, //忙碌中 - 取得文件信息
BUSY_BEGIN_DOWNFILE, //忙碌中 - 开始下载文件中
FINISH_SUCCESS_OVER, //成功下载完毕
FINISH_SUCCESS_STOPHERE, //用户定义下载完毕
FINISH_FORCEABORT, //下载失败 - 用于取消
FINISH_ERROR_UNSUPPORTED_SCHEME, //下载失败 - 不支持的协议
FINISH_ERROR_TIMEOUT, //下载失败 - 超时
FINISH_ERROR_TRY_OPEN_LOCALFILE, //下载失败 - 生成本地文件失败
FINISH_ERROR_INTERNET_OPEN, //下载失败 - 打开Internet句柄失败
FINISH_ERROR_SETSTATUSCALLBACK, //下载失败 - 设置状态回调函数失败
FINISH_ERROR_INTERNETCONNECT, //下载失败 - 连接Internet失败
FINISH_ERROR_OPENREQUEST, //下载失败 - 生成Request失败
FINISH_ERROR_SENDREQUEST, //下载失败 - 发送Request失败
FINISH_ERROR_QUERYINFO, //下载失败 - 查询信息
FINISH_ERROR_NEED_PROXY_AUTH_REQ, //下载失败 - 需要代理服务器登录
FINISH_ERROR_DENIED, //下载失败 - 被服务器拒绝
FINISH_ERROR_INVALID_HTTP_RESPONSE, //下载失败 - 非法的HTTP请求
FINISH_ERROR_READFILE, //下载失败 - 读取Internet文件失败
FINISH_ERROR_EXCEPTION, //下载失败 - 有异常抛出
};
public:
/** 初始化下载器
@param wszURLToDownload - 网络文件地址
@param wszFileToDownloadInto - 本地文件地址
@param pOwner - 参数,会被传入回调函数
@param funcUserCallBack - 回调函数
@param nOverTime - 超时时间
*/
bool init(const wchar_t* wszURLToDownload, const wchar_t* wszFileToDownloadInto,
DOWNANT_STATUS_CALLBACK funcUserCallBack = NULL, void* pOwner = NULL, unsigned int nOverTime = INFINITE);
/** 启动下载
@param block - 是否等待下载结束后再退出
*/
void begin(bool block);
const wchar_t* getDownUrl(void) const { return m_wszURLToDownload; }
const wchar_t* getLocalFile(void) const { return m_wszFileToDownloadInto; }
const wchar_t* getServer(void) const { return m_wszServer; }
bool checkMD5(const char* md5_string) const;
DOWN_STATE getState(void) const { return m_theState; }
DOWN_STATE_CATEGORY getStateCategory(void) const { return m_theStateCategory; }
protected:
//下载单位4K
enum { DOWNANT_MINSIZE = 1024*4 };
HANDLE m_hThread; //!< 下载线程句柄
DOWN_STATE_CATEGORY m_theStateCategory; //!< 主状态
DOWN_STATE m_theState; //!< 详细状态
void* m_pOwner; //!< 附加属性,这个值会传给回调函数
/** 下载文件的地址 */
wchar_t m_wszURLToDownload[INTERNET_MAX_URL_LENGTH];
/** 本地存贮地址 */
wchar_t m_wszFileToDownloadInto[MAX_PATH];
MD5Digest m_fileMD5; //!< 所下载文件的文件MD5码
INTERNET_SCHEME m_schemeType; //!< 服务段类型http,ftp
wchar_t m_wszServer[MAX_PATH]; //!< 服务器地址
wchar_t m_wszObject[INTERNET_MAX_URL_LENGTH]; //!< 文件在服务器上的位置
WORD m_nPort; //!< 服务器端口
/// WinInet所用的句柄
HINTERNET m_hInternetSession;
HINTERNET m_hHttpConnection;
HINTERNET m_hHttpFile;
//用户命令
DWORD m_dwUserCmd;
//超时时限(秒)
DWORD m_nOverTime;
//开始时间
ULONGLONG m_beginTime;
//是否得到了文件大小
BOOL m_bGotFileSize;
//文件总大小
int64_t m_dwFileSizeTotal;
//已经下载的文件大小
int64_t m_dwFileSizeRead;
//文件存储句柄
FILE* m_fpFileToWrite;
//回调函数
DOWNANT_STATUS_CALLBACK UserCallBack;
//状态描述
wchar_t m_wszStatusInfor[MAX_PATH];
public:
CDownloadAnt();
~CDownloadAnt();
private:
/** wininet 回调函数
*/
static void CALLBACK _onWininetStatusCallBack(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
void onWininetStatusCallBack(HINTERNET hInternet, DWORD dwInternetStatus,
LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
/** 线程入口函数
*/
static UINT CALLBACK _downloadThread(void* pParam);
void downloadThread(void);
/** 改变状态 */
void setStatus(DOWN_STATE newState);
/** 状态改变回调函数 */
void onStatusCallback(void);
/** 检查是否需要强制退出(超时或者用户强制终止)
*/
BOOL _checkAbort(void);
};