You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
438 lines
9.5 KiB
438 lines
9.5 KiB
#include "inspch.h"
|
|
#include "inseng.h"
|
|
#include "download.h"
|
|
#include "advpub.h"
|
|
#include "site.h"
|
|
#include "sitemgr.h"
|
|
#include "util2.h"
|
|
#include "util.h"
|
|
|
|
#define SITEFILENAME "sites.dat"
|
|
#define SITEARRAY_GROWTHFACTOR 100
|
|
|
|
#define NUM_RETRIES 2
|
|
|
|
#define SITEQUERYSIZE_V1 8
|
|
#define SITEQUERYSIZE_V2 12
|
|
|
|
CDownloadSiteMgr::CDownloadSiteMgr(IUnknown **punk)
|
|
{
|
|
m_cRef = 0;
|
|
m_pszUrl = 0;
|
|
|
|
m_pquery = NULL;
|
|
m_ppdls = (DOWNLOADSITE **) malloc(SITEARRAY_GROWTHFACTOR * sizeof(DOWNLOADSITE *));
|
|
m_numsites = 0;
|
|
m_arraysize = SITEARRAY_GROWTHFACTOR;
|
|
|
|
AddRef();
|
|
*punk = (IDownloadSiteMgr *) this;
|
|
}
|
|
|
|
CDownloadSiteMgr::~CDownloadSiteMgr()
|
|
{
|
|
if(m_ppdls)
|
|
{
|
|
for(UINT i=0; i < m_numsites; i++)
|
|
DeleteDownloadSite(m_ppdls[i]);
|
|
|
|
free(m_ppdls);
|
|
}
|
|
|
|
// Delete the query structure
|
|
if(m_pquery)
|
|
{
|
|
if(m_pquery->pszLang)
|
|
delete m_pquery->pszLang;
|
|
|
|
delete m_pquery;
|
|
}
|
|
|
|
if(m_pszUrl)
|
|
delete m_pszUrl;
|
|
|
|
DllRelease();
|
|
}
|
|
|
|
//************ IUnknown implementation ***************
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CDownloadSiteMgr::AddRef()
|
|
{
|
|
return(m_cRef++);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CDownloadSiteMgr::Release()
|
|
{
|
|
ULONG temp = --m_cRef;
|
|
|
|
if(temp == 0)
|
|
delete this;
|
|
return temp;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CDownloadSiteMgr::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if((riid == IID_IUnknown) || (riid == IID_IDownloadSiteMgr))
|
|
*ppv = (IDownloadSiteMgr *)this;
|
|
|
|
if(*ppv == NULL)
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CDownloadSiteMgr::Initialize(LPCSTR pszUrl, SITEQUERYPARAMS *psqp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
char szPath[MAX_PATH];
|
|
|
|
if(!pszUrl)
|
|
return E_INVALIDARG;
|
|
|
|
if(!m_ppdls)
|
|
return E_OUTOFMEMORY;
|
|
|
|
m_pszUrl = CopyAnsiStr(pszUrl);
|
|
if(!m_pszUrl)
|
|
return E_OUTOFMEMORY;
|
|
|
|
if(psqp != NULL)
|
|
{
|
|
m_pquery = new SITEQUERYPARAMS;
|
|
if(!m_pquery)
|
|
return E_OUTOFMEMORY;
|
|
|
|
ZeroMemory(m_pquery, sizeof(SITEQUERYPARAMS));
|
|
|
|
if(psqp->pszLang)
|
|
{
|
|
m_pquery->pszLang = CopyAnsiStr(psqp->pszLang);
|
|
if(!m_pquery->pszLang)
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
if((psqp->cbSize >= SITEQUERYSIZE_V2) && psqp->pszRegion)
|
|
{
|
|
m_pquery->pszRegion = CopyAnsiStr(psqp->pszRegion);
|
|
if(!m_pquery->pszRegion)
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
CDownloader *pDownloader = new CDownloader();
|
|
if(pDownloader)
|
|
{
|
|
hr = E_FAIL;
|
|
for(int i = 0; (i < NUM_RETRIES) && FAILED(hr) ; i++)
|
|
{
|
|
hr = pDownloader->SetupDownload(m_pszUrl, (IMyDownloadCallback *) this, DOWNLOADFLAGS_USEWRITECACHE, SITEFILENAME);
|
|
if(FAILED(hr))
|
|
break;
|
|
hr = pDownloader->DoDownload(szPath, sizeof(szPath));
|
|
}
|
|
pDownloader->Release();
|
|
|
|
}
|
|
|
|
// Parse the file
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = ParseSiteFile(szPath);
|
|
}
|
|
|
|
// delete the dir we downloaded to
|
|
|
|
if(GetParentDir(szPath))
|
|
DelNode(szPath, 0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CDownloadSiteMgr::EnumSites(DWORD dwIndex, IDownloadSite **pds)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
if(!pds)
|
|
return E_POINTER;
|
|
|
|
*pds = NULL;
|
|
|
|
if(dwIndex < m_numsites)
|
|
{
|
|
*pds = CopyDownloadSite(m_ppdls[dwIndex]);
|
|
if(! (*pds) )
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT CDownloadSiteMgr::OnProgress(ULONG progress, LPCSTR pszStatus)
|
|
{
|
|
// Not interesting
|
|
return NOERROR;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
// This probably changes after beta1
|
|
|
|
HRESULT CDownloadSiteMgr::ParseSiteFile(LPCSTR pszPath)
|
|
{
|
|
HANDLE hfile;
|
|
DWORD dwSize;
|
|
DOWNLOADSITE *p;
|
|
LPSTR pBuf, pCurrent, pEnd;
|
|
|
|
m_onegoodsite = FALSE;
|
|
|
|
hfile = CreateFile(pszPath, GENERIC_READ, 0, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(hfile == INVALID_HANDLE_VALUE)
|
|
return E_FAIL;
|
|
|
|
|
|
dwSize = GetFileSize(hfile, NULL);
|
|
if(dwSize == DWORD(-1)) {
|
|
CloseHandle(hfile);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
pBuf = new char[dwSize + 1];
|
|
|
|
if(!pBuf)
|
|
{
|
|
CloseHandle(hfile);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
// Copy contents of file to our buffer
|
|
|
|
if(!ReadFile(hfile, pBuf, dwSize, &dwSize, NULL)) {
|
|
delete pBuf;
|
|
CloseHandle(hfile);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
pCurrent = pBuf;
|
|
pEnd = pBuf + dwSize;
|
|
*pEnd = 0;
|
|
|
|
// One pass thru replacing \n or \r with \0
|
|
while(pCurrent <= pEnd)
|
|
{
|
|
if(*pCurrent == '\r' || *pCurrent == '\n')
|
|
*pCurrent = 0;
|
|
pCurrent++;
|
|
}
|
|
|
|
pCurrent = pBuf;
|
|
while(1)
|
|
{
|
|
while(pCurrent <= pEnd && *pCurrent == 0)
|
|
pCurrent++;
|
|
|
|
// we are now pointing at begginning of line or pCurrent > pBuf
|
|
if(pCurrent > pEnd)
|
|
break;
|
|
|
|
p = ParseAndAllocateDownloadSite(pCurrent);
|
|
if(p)
|
|
AddSite(p);
|
|
|
|
pCurrent += lstrlen(pCurrent);
|
|
}
|
|
|
|
delete pBuf;
|
|
CloseHandle(hfile);
|
|
|
|
if(!m_onegoodsite)
|
|
return E_UNEXPECTED;
|
|
else
|
|
return NOERROR;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
// BUGBUG: Stack is getting large here - consider writing with
|
|
// only one buffer that is reused. Have to break up the nice Allocate
|
|
// call
|
|
DOWNLOADSITE *CDownloadSiteMgr::ParseAndAllocateDownloadSite(LPSTR psz)
|
|
{
|
|
char szUrl[1024];
|
|
char szName[256];
|
|
char szlang[256];
|
|
char szregion[256];
|
|
BOOL bQueryTrue = TRUE;
|
|
DOWNLOADSITE *p = NULL;
|
|
|
|
GetStringField(psz, 0, szUrl, sizeof(szUrl));
|
|
GetStringField(psz,1, szName, sizeof(szName));
|
|
GetStringField(psz, 2, szlang, sizeof(szlang));
|
|
GetStringField(psz, 3, szregion, sizeof(szregion));
|
|
|
|
if(szUrl[0] == 0 || szName[0] == 0 || szlang[0] == 0 || szregion[0] == 0)
|
|
return NULL;
|
|
|
|
m_onegoodsite = TRUE;
|
|
|
|
// Hack - Check language against what is in our query params
|
|
// a) this query should have already been performed on the server
|
|
// b) or it should be more generic/its own function
|
|
|
|
if(m_pquery)
|
|
{
|
|
if(m_pquery->pszLang && (lstrcmpi(m_pquery->pszLang, szlang) != 0))
|
|
bQueryTrue = FALSE;
|
|
|
|
// query for region
|
|
if(bQueryTrue && m_pquery->pszRegion && (lstrcmpi(m_pquery->pszRegion, szregion) != 0))
|
|
bQueryTrue = FALSE;
|
|
}
|
|
|
|
if(bQueryTrue)
|
|
p = AllocateDownloadSite(szUrl, szName, szlang, szregion);
|
|
|
|
return p;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD CDownloadSiteMgr::TranslateLanguage(LPSTR psz)
|
|
{
|
|
return ( (DWORD) AtoL(psz) );
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT CDownloadSiteMgr::AddSite(DOWNLOADSITE *pdls)
|
|
{
|
|
if((m_numsites % m_arraysize == 0) && m_numsites != 0)
|
|
{
|
|
m_arraysize += SITEARRAY_GROWTHFACTOR;
|
|
DOWNLOADSITE **pp = (DOWNLOADSITE **) realloc( m_ppdls, m_arraysize * sizeof(DOWNLOADSITE *));
|
|
if(pp)
|
|
m_ppdls = pp;
|
|
else
|
|
{
|
|
m_arraysize -= SITEARRAY_GROWTHFACTOR;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
if(!m_ppdls)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
m_ppdls[m_numsites++] = pdls;
|
|
return NOERROR;
|
|
}
|
|
|
|
|