mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62078 954022d7-b5bf-4e40-9824-e11837661b57
510 lines
14 KiB
C++
510 lines
14 KiB
C++
#pragma once
|
|
|
|
#ifdef _WIN32
|
|
#include "../../Common/BaseThread.h"
|
|
|
|
#include <wininet.h>
|
|
#pragma comment(lib, "Wininet")
|
|
|
|
//------------------------------------------------------------------------------------------------------
|
|
|
|
// Êîíñòàíòà äëÿ ìàêñèìàëüíîãî ÷èñëà ñèìâîëîâ â ñòðîêå
|
|
#define MAX_SIZE 256
|
|
// Êîíñòàíòà äëÿ ìàêñèìàëüíîãî ÷èñëà çàãðóæàåìûõ áàéò
|
|
#define DOWNLOAD_FILE_SIZE 32768
|
|
#define MAX_SINGLE_DOWNLOAD_FILE_SIZE 524288
|
|
|
|
|
|
// Êîíñòàíòà äëÿ ïîëó÷åíèÿ ðàçìåðà ôàéëà
|
|
#define CONTENT_RANGE _T("bytes 0-0/")
|
|
// Êîíñòàíòà äëÿ êîëëè÷åñòâà ñèìâîëîâ ó CONTENT_RANGE
|
|
#define CONTENT_RANGE_SIZE ( 11/*sizeof ( CONTENT_RANGE )*/ - 1 )
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------
|
|
// Êëàññ äëÿ çàêà÷êè ôàéëà èç ñåòè íà ëîêàëüíûé äèñê
|
|
//------------------------------------------------------------------------------------------------------
|
|
|
|
class CFileDownloader : public CBaseThread
|
|
{
|
|
public :
|
|
|
|
CFileDownloader (CString sFileUrl, bool bDelete = true) : CBaseThread(0)
|
|
{
|
|
m_pFile = NULL;
|
|
m_sFilePath = _T("");
|
|
m_sFileUrl = sFileUrl;
|
|
m_bComplete = false;
|
|
m_bDelete = bDelete;
|
|
}
|
|
~CFileDownloader ()
|
|
{
|
|
if ( m_pFile )
|
|
{
|
|
::fclose( m_pFile );
|
|
m_pFile = NULL;
|
|
}
|
|
if ( m_sFilePath.GetLength() > 0 && m_bDelete )
|
|
{
|
|
DeleteFileW( m_sFilePath.GetBuffer() );
|
|
m_sFilePath = _T("");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
CString GetFilePath()
|
|
{
|
|
return m_sFilePath;
|
|
}
|
|
bool IsFileDownloaded()
|
|
{
|
|
return m_bComplete;
|
|
}
|
|
protected :
|
|
|
|
unsigned int DownloadFile(CString sFileUrl)
|
|
{
|
|
// Ïðîâåðÿåì ñîñòîÿíèå ñîåäèíåíèÿ
|
|
if ( FALSE == InternetGetConnectedState ( 0, 0 ) )
|
|
return S_FALSE;
|
|
|
|
char sTempPath[MAX_PATH], sTempFile[MAX_PATH];
|
|
if ( 0 == GetTempPathA( MAX_PATH, sTempPath ) )
|
|
return S_FALSE;
|
|
|
|
if ( 0 == GetTempFileNameA( sTempPath, "CSS", 0, sTempFile ) )
|
|
return S_FALSE;
|
|
|
|
m_pFile = ::fopen( sTempFile, "wb" );
|
|
if ( !m_pFile )
|
|
return S_FALSE;
|
|
|
|
m_sFilePath = CString( sTempFile );
|
|
|
|
// Îòêðûâàåì ñåññèþ
|
|
HINTERNET hInternetSession = InternetOpen ( _T ("Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
|
|
if ( NULL == hInternetSession )
|
|
return S_FALSE;
|
|
|
|
// Çàãîëîâîê çàïðîñà ( ïîêà ñîäåðæèò 0 áàéò ( íåîáõîäèìî äëÿ ïðîâåðêè ) )
|
|
CString sHTTPHdr = _T ("Range: bytes=0-0");
|
|
// Îòêðûâàåì ññûëêó äëÿ ïðîâåðêè íà åå ñóùåñòâîâàíèå, à òàêæå íà âîçìîæíîñòü ÷òåíèÿ ÷àñòÿìè
|
|
HINTERNET hInternetOpenURL = InternetOpenUrl ( hInternetSession, sFileUrl, sHTTPHdr, -1, INTERNET_FLAG_RESYNCHRONIZE, 0 );
|
|
if ( NULL != hInternetOpenURL )
|
|
{
|
|
// Îòêðûòèå ïðîèçîøëî, ïðîâåðÿåì îòâåò
|
|
if ( TRUE == QueryStatusCode ( hInternetOpenURL, TRUE ) )
|
|
{
|
|
// Çàïðîñ ïðîøåë óäà÷íî, ïðîâåðÿåì âîçìîæíîñòü ÷òåíèÿ ÷àñòÿìè è ïîëó÷àåì ðàçìåð äàííûõ
|
|
LONGLONG nFileSize = IsAccept_Ranges ( hInternetOpenURL );
|
|
// Çàêðûâàåì õåíäë
|
|
InternetCloseHandle ( hInternetOpenURL );
|
|
if ( -1 == nFileSize )
|
|
{
|
|
// ×òåíèå ÷àñòÿìè íåäîñòóïíî
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
// Çàêðûâàåì ôàéë (ñäåëàåòñÿ íà DownloadAll)
|
|
// Ïîïðîáóåì çàïèñàòü åãî öåëèêîì
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
// ×òåíèå ÷àñòÿìè äîñòóïíî
|
|
LONGLONG nStartByte = 0;
|
|
while ( m_bRunThread )
|
|
{
|
|
// Åñëè çàêà÷àëè âåñü ôàéë - òî âûõîäèì
|
|
if ( nStartByte == nFileSize - 1 )
|
|
{
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
return S_OK;
|
|
}
|
|
LONGLONG nEndByte = nStartByte + DOWNLOAD_FILE_SIZE;
|
|
// Åñëè ôàéë çàêàí÷èâàåòñÿ, òî çàãðóæàåì ìåíüøåå êîëëè÷åñòâî áàéò ( íà 1 ìåíüøå, ÷åì ðàçìåð, ò.ê. íà÷èíàåòñÿ ñ 0 )
|
|
if ( nEndByte >= nFileSize )
|
|
nEndByte = nFileSize - 1;
|
|
|
|
// Áóôôåð äëÿ çàêà÷êè
|
|
BYTE arrBuffer [ DOWNLOAD_FILE_SIZE ] = { 0 };
|
|
DWORD dwBytesDownload = DownloadFilePath ( hInternetSession, arrBuffer, nStartByte, nEndByte, sFileUrl );
|
|
|
|
nStartByte = nEndByte;
|
|
if ( -1 == dwBytesDownload )
|
|
{
|
|
// Íè÷åãî íå ïðî÷èòàëîñü - ýòî ïëîõî!!!!
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
// Çàêðûâàåì ôàéë (ñäåëàåòñÿ íà DownloadAll)
|
|
// Ïîïðîáóåì çàïèñàòü åãî öåëèêîì
|
|
return S_FALSE;
|
|
}
|
|
|
|
// Ïèøåì â ôàéë
|
|
::fwrite( (BYTE*)arrBuffer, 1, dwBytesDownload, m_pFile );
|
|
::fflush( m_pFile );
|
|
// Ïðîâåðêà íà ïðèîñòàíîâêó
|
|
CheckSuspend ();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
// Çàêðûâàåì ôàéë (ñäåëàåòñÿ íà DownloadAll)
|
|
// Ïîïðîáóåì çàïèñàòü åãî öåëèêîì
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
// Çàêðûâàåì ôàéë (ñäåëàåòñÿ íà DownloadAll)
|
|
// Ïîïðîáóåì çàïèñàòü åãî öåëèêîì
|
|
return S_FALSE;
|
|
}
|
|
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetSession );
|
|
|
|
return S_OK;
|
|
}
|
|
DWORD DownloadFilePath ( HINTERNET hInternet, LPBYTE pBuffer, LONGLONG nStartByte, LONGLONG nEndByte, CString sFileURL )
|
|
{
|
|
// Íåîòêðûòàÿ ñåññèÿ
|
|
if ( NULL == hInternet )
|
|
return -1;
|
|
|
|
// Ïðèøëè íåïîíÿòíûå ïàðàìåòðû
|
|
if ( nStartByte > nEndByte || !pBuffer )
|
|
return -1;
|
|
|
|
// Çàãîëîâîê çàïðîñà ( ñîäåðæèò nEndByte - nStartByte áàéò )
|
|
CString sHTTPHdr = _T (""); sHTTPHdr.Format ( _T ("Range: bytes=%lld-%lld"), nStartByte, nEndByte );
|
|
// Îòêðûâàåì ññûëêó äëÿ çàêà÷êè
|
|
HINTERNET hInternetOpenURL = InternetOpenUrl ( hInternet, sFileURL, sHTTPHdr, -1, INTERNET_FLAG_RESYNCHRONIZE, 0 );
|
|
if ( NULL == hInternetOpenURL )
|
|
return -1;
|
|
// Îòêðûòèå ïðîèçîøëî, ïðîâåðÿåì îòâåò
|
|
if ( FALSE == QueryStatusCode ( hInternetOpenURL, TRUE ) )
|
|
{
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetOpenURL );
|
|
return -1;
|
|
}
|
|
|
|
// Êàêîå êîëëè÷åñòâî áàéò ïðî÷èòàíî
|
|
DWORD dwBytesRead = 0;
|
|
// ×èòàåì ôàéë
|
|
if ( FALSE == InternetReadFile ( hInternetOpenURL, pBuffer, DOWNLOAD_FILE_SIZE, &dwBytesRead ) )
|
|
{
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetOpenURL );
|
|
return -1;
|
|
}
|
|
|
|
// Çàêðûâàåì õåíäë ñîåäèíåíèÿ
|
|
InternetCloseHandle ( hInternetOpenURL );
|
|
|
|
return dwBytesRead;
|
|
}
|
|
virtual DWORD ThreadProc ()
|
|
{
|
|
m_bComplete = false;
|
|
|
|
CoInitialize ( NULL );
|
|
|
|
if ( S_OK != DownloadFile ( m_sFileUrl ) )
|
|
{
|
|
HRESULT hrResultAll = DownloadFileAll(m_sFileUrl, m_sFilePath);
|
|
|
|
if (S_OK != hrResultAll)
|
|
{
|
|
m_bRunThread = FALSE;
|
|
CoUninitialize ();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
m_bRunThread = FALSE;
|
|
CoUninitialize ();
|
|
|
|
m_bComplete = true;
|
|
return 0;
|
|
}
|
|
|
|
BOOL QueryStatusCode ( HINTERNET hInternet, BOOL bIsRanges )
|
|
{
|
|
// Çà÷åì ïðîâåðÿòü ó íåîòêðûòîé ñåññèè ÷òî-òî
|
|
if ( NULL == hInternet )
|
|
return FALSE;
|
|
|
|
// Ðåçóëüòàò îòâåòà
|
|
INT nResult = 0;
|
|
// Ðàçìåð äàííûõ îòâåòà ( äîëæíî áûòü = 4 )
|
|
DWORD dwLengthDataSize = 4;
|
|
|
|
// Äåëàåì çàïðîñ, åñëè íå ïðîõîäèò - òî âîçâðàùàåì FALSE
|
|
if ( FALSE == HttpQueryInfo ( hInternet, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &nResult, &dwLengthDataSize, NULL ) )
|
|
return FALSE;
|
|
|
|
// Çàïðîñ ïðîøåë, òåïåðü ïðîâåðÿåì êîä îòâåòà
|
|
if ( HTTP_STATUS_NOT_FOUND == nResult )
|
|
{
|
|
// Îáúåêò íå íàéäåí, ïëîõàÿ ññûëêà èëè ÷òî-òî åùå
|
|
return FALSE;
|
|
}
|
|
else if ( ( HTTP_STATUS_OK != nResult && FALSE == bIsRanges ) || ( HTTP_STATUS_PARTIAL_CONTENT != nResult && TRUE == bIsRanges ) )
|
|
{
|
|
// Çàïðîñ íå ïðîøåë ïî êàêîé-òî ïðè÷èíå
|
|
return FALSE;
|
|
}
|
|
|
|
// Âñå îòëè÷íî, çàïðîñ ïðîøåë
|
|
return TRUE;
|
|
}
|
|
// Ïðîâåðÿåò, äîñòóïíî ëè äëÿ ðåñóðñà ÷òåíèå ÷àñòÿìè è âîçâðàùàåò -1 åñëè íå äîñòóïíî è ðàçìåð äàííûõ, åñëè äîñòóïíî
|
|
LONGLONG IsAccept_Ranges ( HINTERNET hInternet )
|
|
{
|
|
// Çà÷åì ïðîâåðÿòü ó íåîòêðûòîé ñåññèè ÷òî-òî
|
|
if ( NULL == hInternet )
|
|
return -1;
|
|
|
|
// Ðåçóëüòàò îòâåòà
|
|
char arrResult [ MAX_SIZE ] = { 0 };
|
|
// Ðàçìåð äàííûõ îòâåòà
|
|
DWORD dwLengthDataSize = sizeof ( arrResult );
|
|
|
|
// Äåëàåì çàïðîñ, åñëè íå ïðîõîäèò - òî âîçâðàùàåì FALSE
|
|
if ( FALSE == HttpQueryInfoA ( hInternet, HTTP_QUERY_CONTENT_RANGE, &arrResult, &dwLengthDataSize, NULL ) )
|
|
{
|
|
// Ïîëó÷àåì ïîñëåäíþþ îøèáêó
|
|
DWORD dwLastError = GetLastError ();
|
|
if ( dwLastError == ERROR_HTTP_HEADER_NOT_FOUND )
|
|
{
|
|
// Íå ïðèøåë çàãîëîâîê, çíà÷èò ðåñóðñ íå ïîääåðæèâàåò ÷òåíèå ÷àñòÿìè
|
|
return -1;
|
|
}
|
|
|
|
// Âîçíèêëà êàêàÿ-òî äðóãàÿ îøèáêà - âîçâðàùàåì FALSE
|
|
return -1;
|
|
}
|
|
|
|
// Åñëè ðàçìåð 0, òî çàãîëîâêà íåò
|
|
if ( 0 >= dwLengthDataSize )
|
|
return -1;
|
|
|
|
// Ïðèâåäåì ê CString
|
|
CString strResult ( arrResult );
|
|
|
|
// Ñîäåðæèò ðàçìåð äàííûõ
|
|
LONGLONG nFileSize = 0;
|
|
|
|
try
|
|
{
|
|
// Èùåì èíäåêñ ðàçìåðà äàííûõ â ñòðîêå
|
|
INT nStartIndex = strResult.Find ( CONTENT_RANGE );
|
|
if ( -1 == nStartIndex )
|
|
return -1;
|
|
|
|
// Îñòàâëÿåì â ñòðîêå òîëüêî ðàçìåð äàííûõ
|
|
strResult = strResult.Mid ( nStartIndex + CONTENT_RANGE_SIZE );
|
|
// Òåïåðü ïîëó÷èì ðàçìåð äàííûõ, ïåðåâîäÿ ñòðèíã â LONGLONG
|
|
nFileSize = _wtoi64 ( strResult.GetBuffer () );
|
|
// Ò.ê. ðåàëüíî íóìåðàöèÿ ñ 0 ( ïîýòîìó äîáàâëÿåì åùå 1 áàéò )
|
|
if ( 0 < nFileSize )
|
|
nFileSize += 1;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
// íå íàøëè âîçâðàùàåì îøèáêó
|
|
return -1;
|
|
}
|
|
|
|
// Âñå îòëè÷íî, ðåñóðñ ïîääåðæèâàåò ÷òåíèå ÷àñòÿìè, âîçâðàùàåì ðàçìåð
|
|
return nFileSize;
|
|
}
|
|
|
|
HRESULT DownloadFileAll(CString sFileURL, CString strFileOutput)
|
|
{
|
|
if ( m_pFile )
|
|
{
|
|
::fclose( m_pFile );
|
|
m_pFile = NULL;
|
|
}
|
|
// Ñêà÷èâàåì ôàéë
|
|
return URLDownloadToFile (NULL, sFileURL, strFileOutput, NULL, NULL);
|
|
}
|
|
|
|
public:
|
|
static bool IsNeedDownload(CString FilePath)
|
|
{
|
|
int n1 = FilePath.Find(_T("www."));
|
|
int n2 = FilePath.Find(_T("http://"));
|
|
int n3 = FilePath.Find(_T("ftp://"));
|
|
int n4 = FilePath.Find(_T("https://"));
|
|
|
|
if (((n1 >= 0) && (n1 < 10)) || ((n2 >= 0) && (n2 < 10)) || ((n3 >= 0) && (n3 < 10)) || ((n4 >= 0) && (n4 < 10)))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
protected :
|
|
|
|
FILE *m_pFile; // Õýíäë íà âðåìåííûé ôàéë
|
|
CString m_sFilePath; // Ïóòü ê ñîõðàíåííîìó ôàéëó íà äèñêå
|
|
CString m_sFileUrl; // Ññûëêà íà ñêà÷èâàíèå ôàéëà
|
|
|
|
bool m_bComplete; // Çàêà÷àëñÿ ôàéë èëè íåò
|
|
bool m_bDelete; // Óäàëÿòü ëè ôàéë â äåñòðóêòîðå
|
|
|
|
};
|
|
#else
|
|
|
|
// not win32
|
|
//#include <boost/network/protocol/http/client.hpp>
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
#include "./DocxFormat/Source/Base/ASCString.h"
|
|
#include "./DocxFormat/Source/SystemUtility/FileSystem/Directory.h"
|
|
|
|
#include<fcntl.h>
|
|
#include <string>
|
|
|
|
#include <stdio.h>
|
|
|
|
#if defined(__APPLE__)
|
|
#include "/usr/include/curl/curl.h"
|
|
#include "/usr/include/curl/easy.h"
|
|
#else
|
|
#include "3dParty/curl/include/curl/curl.h"
|
|
#include "3dParty/curl/include/curl/easy.h"
|
|
#endif
|
|
|
|
static void Sleep (unsigned int mSec)
|
|
{
|
|
usleep(1000 * mSec);
|
|
}
|
|
|
|
class CFileDownloader
|
|
{
|
|
public :
|
|
|
|
CFileDownloader (CString sFileUrl, bool bDelete = true)
|
|
{
|
|
|
|
char filename[L_tmpnam];
|
|
std::tmpnam(filename);
|
|
|
|
m_sFilePath;
|
|
m_sFileUrl = sFileUrl;
|
|
m_bComplete = false;
|
|
m_bDelete = bDelete;
|
|
}
|
|
~CFileDownloader ()
|
|
{
|
|
if (m_bDelete && !m_sFilePath.IsEmpty())
|
|
unlink(stringWstingToUtf8String (m_sFilePath).c_str());
|
|
}
|
|
|
|
static size_t write_data(void *ptr, size_t size, size_t nmemb, int fd) {
|
|
size_t written = write(fd, ptr, size * nmemb);
|
|
return written;
|
|
}
|
|
|
|
|
|
void Start (int n)
|
|
{
|
|
CURL *curl;
|
|
int fp;
|
|
CURLcode res;
|
|
std::string sUrl = stringWstingToUtf8String (m_sFileUrl);
|
|
std::string sOut;
|
|
const char *url = sUrl.c_str();
|
|
curl = curl_easy_init();
|
|
if (curl) {
|
|
fp = createUniqueTempFile(sOut);
|
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
|
#if defined(__linux__)
|
|
//â linux íåò âñòðîåííûõ â ñèñòåìó êîðíåâûõ ñåðòèôèêàòîâ, ïîýòîìó îòêëþ÷àåì ïðîâåðêó
|
|
//http://curl.haxx.se/docs/sslcerts.html
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
#endif
|
|
/* some servers don't like requests that are made without a user-agent field, so we provide one */
|
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
|
res = curl_easy_perform(curl);
|
|
/* always cleanup */
|
|
curl_easy_cleanup(curl);
|
|
close(fp);
|
|
}
|
|
|
|
m_bComplete = (CURLE_OK == res);
|
|
if (m_bComplete)
|
|
m_sFilePath = sOut;
|
|
//int nRes = execl("/usr/bin/wget", stringWstingToUtf8String (m_sFileUrl).c_str(), "-P", stringWstingToUtf8String (m_sFilePath).c_str(), (char *)NULL);
|
|
//m_bComplete = nRes >= 0;
|
|
}
|
|
|
|
bool IsRunned()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CString GetFilePath()
|
|
{
|
|
return m_sFilePath;
|
|
}
|
|
bool IsFileDownloaded()
|
|
{
|
|
return m_bComplete;
|
|
}
|
|
protected :
|
|
|
|
unsigned int DownloadFile(CString sFileUrl)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
int createUniqueTempFile (std::string &filename)
|
|
{
|
|
std::string sTempPath = stringWstingToUtf8String (FileSystem::Directory::GetTempPath());
|
|
sTempPath += "/fileXXXXXX";
|
|
int fd = mkstemp(const_cast <char *> (sTempPath.c_str()));
|
|
if (-1 != fd)
|
|
filename = sTempPath;
|
|
return fd;
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
static bool IsNeedDownload(CString FilePath)
|
|
{
|
|
int n1 = FilePath.Find(_T("www."));
|
|
int n2 = FilePath.Find(_T("http://"));
|
|
int n3 = FilePath.Find(_T("ftp://"));
|
|
int n4 = FilePath.Find(_T("https://"));
|
|
|
|
if (((n1 >= 0) && (n1 < 10)) || ((n2 >= 0) && (n2 < 10)) || ((n3 >= 0) && (n3 < 10)) || ((n4 >= 0) && (n4 < 10)))
|
|
return true;
|
|
return false;
|
|
}
|
|
protected :
|
|
|
|
CString m_sFilePath; // Ïóòü ê ñîõðàíåííîìó ôàéëó íà äèñêå
|
|
CString m_sFileUrl; // Ññûëêà íà ñêà÷èâàíèå ôàéëà
|
|
|
|
bool m_bComplete; // Çàêà÷àëñÿ ôàéë èëè íåò
|
|
bool m_bDelete; // Óäàëÿòü ëè ôàéë â äåñòðóêòîðå
|
|
|
|
};
|
|
|
|
#endif
|