Leaked source code of windows server 2003
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

  1. #include "inspch.h"
  2. #include "inseng.h"
  3. #include "download.h"
  4. #include "advpub.h"
  5. #include "site.h"
  6. #include "sitemgr.h"
  7. #include "util2.h"
  8. #include "util.h"
  9. #define SITEFILENAME "sites.dat"
  10. #define SITEARRAY_GROWTHFACTOR 100
  11. #define NUM_RETRIES 2
  12. #define SITEQUERYSIZE_V1 8
  13. #define SITEQUERYSIZE_V2 12
  14. CDownloadSiteMgr::CDownloadSiteMgr(IUnknown **punk)
  15. {
  16. m_cRef = 0;
  17. m_pszUrl = 0;
  18. m_pquery = NULL;
  19. m_ppdls = (DOWNLOADSITE **) malloc(SITEARRAY_GROWTHFACTOR * sizeof(DOWNLOADSITE *));
  20. m_numsites = 0;
  21. m_arraysize = SITEARRAY_GROWTHFACTOR;
  22. AddRef();
  23. *punk = (IDownloadSiteMgr *) this;
  24. }
  25. CDownloadSiteMgr::~CDownloadSiteMgr()
  26. {
  27. if(m_ppdls)
  28. {
  29. for(UINT i=0; i < m_numsites; i++)
  30. DeleteDownloadSite(m_ppdls[i]);
  31. free(m_ppdls);
  32. }
  33. // Delete the query structure
  34. if(m_pquery)
  35. {
  36. if(m_pquery->pszLang)
  37. delete m_pquery->pszLang;
  38. delete m_pquery;
  39. }
  40. if(m_pszUrl)
  41. delete m_pszUrl;
  42. DllRelease();
  43. }
  44. //************ IUnknown implementation ***************
  45. //=--------------------------------------------------------------------------=
  46. // Function name here
  47. //=--------------------------------------------------------------------------=
  48. // Function description
  49. //
  50. // Parameters:
  51. //
  52. // Returns:
  53. //
  54. // Notes:
  55. //
  56. STDMETHODIMP_(ULONG) CDownloadSiteMgr::AddRef()
  57. {
  58. return(m_cRef++);
  59. }
  60. //=--------------------------------------------------------------------------=
  61. // Function name here
  62. //=--------------------------------------------------------------------------=
  63. // Function description
  64. //
  65. // Parameters:
  66. //
  67. // Returns:
  68. //
  69. // Notes:
  70. //
  71. STDMETHODIMP_(ULONG) CDownloadSiteMgr::Release()
  72. {
  73. ULONG temp = --m_cRef;
  74. if(temp == 0)
  75. delete this;
  76. return temp;
  77. }
  78. //=--------------------------------------------------------------------------=
  79. // Function name here
  80. //=--------------------------------------------------------------------------=
  81. // Function description
  82. //
  83. // Parameters:
  84. //
  85. // Returns:
  86. //
  87. // Notes:
  88. //
  89. STDMETHODIMP CDownloadSiteMgr::QueryInterface(REFIID riid, void **ppv)
  90. {
  91. *ppv = NULL;
  92. if((riid == IID_IUnknown) || (riid == IID_IDownloadSiteMgr))
  93. *ppv = (IDownloadSiteMgr *)this;
  94. if(*ppv == NULL)
  95. return E_NOINTERFACE;
  96. AddRef();
  97. return NOERROR;
  98. }
  99. //=--------------------------------------------------------------------------=
  100. // Function name here
  101. //=--------------------------------------------------------------------------=
  102. // Function description
  103. //
  104. // Parameters:
  105. //
  106. // Returns:
  107. //
  108. // Notes:
  109. //
  110. STDMETHODIMP CDownloadSiteMgr::Initialize(LPCSTR pszUrl, SITEQUERYPARAMS *psqp)
  111. {
  112. HRESULT hr = S_OK;
  113. char szPath[MAX_PATH];
  114. if(!pszUrl)
  115. return E_INVALIDARG;
  116. if(!m_ppdls)
  117. return E_OUTOFMEMORY;
  118. m_pszUrl = CopyAnsiStr(pszUrl);
  119. if(!m_pszUrl)
  120. return E_OUTOFMEMORY;
  121. if(psqp != NULL)
  122. {
  123. m_pquery = new SITEQUERYPARAMS;
  124. if(!m_pquery)
  125. return E_OUTOFMEMORY;
  126. ZeroMemory(m_pquery, sizeof(SITEQUERYPARAMS));
  127. if(psqp->pszLang)
  128. {
  129. m_pquery->pszLang = CopyAnsiStr(psqp->pszLang);
  130. if(!m_pquery->pszLang)
  131. return E_OUTOFMEMORY;
  132. }
  133. if((psqp->cbSize >= SITEQUERYSIZE_V2) && psqp->pszRegion)
  134. {
  135. m_pquery->pszRegion = CopyAnsiStr(psqp->pszRegion);
  136. if(!m_pquery->pszRegion)
  137. return E_OUTOFMEMORY;
  138. }
  139. }
  140. CDownloader *pDownloader = new CDownloader();
  141. if(pDownloader)
  142. {
  143. hr = E_FAIL;
  144. for(int i = 0; (i < NUM_RETRIES) && FAILED(hr) ; i++)
  145. {
  146. hr = pDownloader->SetupDownload(m_pszUrl, (IMyDownloadCallback *) this, DOWNLOADFLAGS_USEWRITECACHE, SITEFILENAME);
  147. if(FAILED(hr))
  148. break;
  149. hr = pDownloader->DoDownload(szPath, sizeof(szPath));
  150. }
  151. pDownloader->Release();
  152. }
  153. // Parse the file
  154. if(SUCCEEDED(hr))
  155. {
  156. hr = ParseSiteFile(szPath);
  157. }
  158. // delete the dir we downloaded to
  159. if(GetParentDir(szPath))
  160. DelNode(szPath, 0);
  161. return hr;
  162. }
  163. STDMETHODIMP CDownloadSiteMgr::EnumSites(DWORD dwIndex, IDownloadSite **pds)
  164. {
  165. HRESULT hr = NOERROR;
  166. if(!pds)
  167. return E_POINTER;
  168. *pds = NULL;
  169. if(dwIndex < m_numsites)
  170. {
  171. *pds = CopyDownloadSite(m_ppdls[dwIndex]);
  172. if(! (*pds) )
  173. hr = E_OUTOFMEMORY;
  174. }
  175. else
  176. hr = E_FAIL;
  177. return hr;
  178. }
  179. //=--------------------------------------------------------------------------=
  180. // Function name here
  181. //=--------------------------------------------------------------------------=
  182. // Function description
  183. //
  184. // Parameters:
  185. //
  186. // Returns:
  187. //
  188. // Notes:
  189. //
  190. HRESULT CDownloadSiteMgr::OnProgress(ULONG progress, LPCSTR pszStatus)
  191. {
  192. // Not interesting
  193. return NOERROR;
  194. }
  195. //=--------------------------------------------------------------------------=
  196. // Function name here
  197. //=--------------------------------------------------------------------------=
  198. // Function description
  199. //
  200. // Parameters:
  201. //
  202. // Returns:
  203. //
  204. // Notes:
  205. //
  206. // This probably changes after beta1
  207. HRESULT CDownloadSiteMgr::ParseSiteFile(LPCSTR pszPath)
  208. {
  209. HANDLE hfile;
  210. DWORD dwSize;
  211. DOWNLOADSITE *p;
  212. LPSTR pBuf, pCurrent, pEnd;
  213. m_onegoodsite = FALSE;
  214. hfile = CreateFile(pszPath, GENERIC_READ, 0, NULL,
  215. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  216. if(hfile == INVALID_HANDLE_VALUE)
  217. return E_FAIL;
  218. dwSize = GetFileSize(hfile, NULL);
  219. if(dwSize == DWORD(-1)) {
  220. CloseHandle(hfile);
  221. return E_UNEXPECTED;
  222. }
  223. pBuf = new char[dwSize + 1];
  224. if(!pBuf)
  225. {
  226. CloseHandle(hfile);
  227. return E_OUTOFMEMORY;
  228. }
  229. // Copy contents of file to our buffer
  230. if(!ReadFile(hfile, pBuf, dwSize, &dwSize, NULL)) {
  231. delete pBuf;
  232. CloseHandle(hfile);
  233. return E_UNEXPECTED;
  234. }
  235. pCurrent = pBuf;
  236. pEnd = pBuf + dwSize;
  237. *pEnd = 0;
  238. // One pass thru replacing \n or \r with \0
  239. while(pCurrent <= pEnd)
  240. {
  241. if(*pCurrent == '\r' || *pCurrent == '\n')
  242. *pCurrent = 0;
  243. pCurrent++;
  244. }
  245. pCurrent = pBuf;
  246. while(1)
  247. {
  248. while(pCurrent <= pEnd && *pCurrent == 0)
  249. pCurrent++;
  250. // we are now pointing at begginning of line or pCurrent > pBuf
  251. if(pCurrent > pEnd)
  252. break;
  253. p = ParseAndAllocateDownloadSite(pCurrent);
  254. if(p)
  255. AddSite(p);
  256. pCurrent += lstrlen(pCurrent);
  257. }
  258. delete pBuf;
  259. CloseHandle(hfile);
  260. if(!m_onegoodsite)
  261. return E_UNEXPECTED;
  262. else
  263. return NOERROR;
  264. }
  265. //=--------------------------------------------------------------------------=
  266. // Function name here
  267. //=--------------------------------------------------------------------------=
  268. // Function description
  269. //
  270. // Parameters:
  271. //
  272. // Returns:
  273. //
  274. // Notes:
  275. //
  276. // BUGBUG: Stack is getting large here - consider writing with
  277. // only one buffer that is reused. Have to break up the nice Allocate
  278. // call
  279. DOWNLOADSITE *CDownloadSiteMgr::ParseAndAllocateDownloadSite(LPSTR psz)
  280. {
  281. char szUrl[1024];
  282. char szName[256];
  283. char szlang[256];
  284. char szregion[256];
  285. BOOL bQueryTrue = TRUE;
  286. DOWNLOADSITE *p = NULL;
  287. GetStringField(psz, 0, szUrl, sizeof(szUrl));
  288. GetStringField(psz,1, szName, sizeof(szName));
  289. GetStringField(psz, 2, szlang, sizeof(szlang));
  290. GetStringField(psz, 3, szregion, sizeof(szregion));
  291. if(szUrl[0] == 0 || szName[0] == 0 || szlang[0] == 0 || szregion[0] == 0)
  292. return NULL;
  293. m_onegoodsite = TRUE;
  294. // Hack - Check language against what is in our query params
  295. // a) this query should have already been performed on the server
  296. // b) or it should be more generic/its own function
  297. if(m_pquery)
  298. {
  299. if(m_pquery->pszLang && (lstrcmpi(m_pquery->pszLang, szlang) != 0))
  300. bQueryTrue = FALSE;
  301. // query for region
  302. if(bQueryTrue && m_pquery->pszRegion && (lstrcmpi(m_pquery->pszRegion, szregion) != 0))
  303. bQueryTrue = FALSE;
  304. }
  305. if(bQueryTrue)
  306. p = AllocateDownloadSite(szUrl, szName, szlang, szregion);
  307. return p;
  308. }
  309. //=--------------------------------------------------------------------------=
  310. // Function name here
  311. //=--------------------------------------------------------------------------=
  312. // Function description
  313. //
  314. // Parameters:
  315. //
  316. // Returns:
  317. //
  318. // Notes:
  319. //
  320. DWORD CDownloadSiteMgr::TranslateLanguage(LPSTR psz)
  321. {
  322. return ( (DWORD) AtoL(psz) );
  323. }
  324. //=--------------------------------------------------------------------------=
  325. // Function name here
  326. //=--------------------------------------------------------------------------=
  327. // Function description
  328. //
  329. // Parameters:
  330. //
  331. // Returns:
  332. //
  333. // Notes:
  334. //
  335. HRESULT CDownloadSiteMgr::AddSite(DOWNLOADSITE *pdls)
  336. {
  337. if((m_numsites % m_arraysize == 0) && m_numsites != 0)
  338. {
  339. m_arraysize += SITEARRAY_GROWTHFACTOR;
  340. DOWNLOADSITE **pp = (DOWNLOADSITE **) realloc( m_ppdls, m_arraysize * sizeof(DOWNLOADSITE *));
  341. if(pp)
  342. m_ppdls = pp;
  343. else
  344. {
  345. m_arraysize -= SITEARRAY_GROWTHFACTOR;
  346. return E_OUTOFMEMORY;
  347. }
  348. }
  349. if(!m_ppdls)
  350. {
  351. return E_OUTOFMEMORY;
  352. }
  353. m_ppdls[m_numsites++] = pdls;
  354. return NOERROR;
  355. }