#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; }