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.

394 lines
8.6 KiB

  1. // RotObj.cpp : Implementation of CAdRotator
  2. #include "stdafx.h"
  3. #include "AdRot.h"
  4. #include "RotObj.h"
  5. #include "RdWrt.h"
  6. #include "context.h"
  7. #include "dbgutil.h"
  8. #ifdef DBG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. #define MAX_RESSTRINGSIZE 512
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CAdRotator
  16. CAdRotator::AdFileMapT CAdRotator::s_adFiles;
  17. CAdRotator::CAdRotator()
  18. : m_bClickable( true ),
  19. m_nBorder(-1),
  20. m_strAdFile( _T("") ),
  21. m_strTargetFrame( NULL ),
  22. m_bBorderSet( false )
  23. {
  24. }
  25. STDMETHODIMP CAdRotator::InterfaceSupportsErrorInfo(REFIID riid)
  26. {
  27. static const IID* arr[] =
  28. {
  29. &IID_IAdRotator,
  30. };
  31. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  32. {
  33. if (InlineIsEqualGUID(*arr[i],riid))
  34. return S_OK;
  35. }
  36. return S_FALSE;
  37. }
  38. STDMETHODIMP CAdRotator::get_Clickable(BOOL * pVal)
  39. {
  40. CLock l(m_cs);
  41. *pVal = m_bClickable?TRUE:FALSE;
  42. return S_OK;
  43. }
  44. STDMETHODIMP CAdRotator::put_Clickable(BOOL newVal)
  45. {
  46. CLock l(m_cs);
  47. m_bClickable = newVal?true:false;
  48. return S_OK;
  49. }
  50. STDMETHODIMP CAdRotator::get_Border(short * pVal)
  51. {
  52. *pVal = m_nBorder;
  53. return S_OK;
  54. }
  55. STDMETHODIMP CAdRotator::put_Border(short newVal)
  56. {
  57. CLock l(m_cs);
  58. m_nBorder = newVal;
  59. m_bBorderSet = true;
  60. return S_OK;
  61. }
  62. STDMETHODIMP CAdRotator::get_TargetFrame(BSTR * pVal)
  63. {
  64. HRESULT rc = E_FAIL;
  65. USES_CONVERSION;
  66. try
  67. {
  68. if ( pVal )
  69. {
  70. CLock l(m_cs);
  71. if ( *pVal )
  72. {
  73. ::SysFreeString( *pVal );
  74. }
  75. *pVal = ::SysAllocString(m_strTargetFrame);
  76. THROW_IF_NULL( *pVal );
  77. rc = S_OK;
  78. }
  79. else
  80. {
  81. rc = E_POINTER;
  82. }
  83. }
  84. catch ( _com_error& ce )
  85. {
  86. rc = ce.Error();
  87. }
  88. catch ( ... )
  89. {
  90. rc = E_FAIL;
  91. }
  92. return rc;
  93. }
  94. STDMETHODIMP CAdRotator::put_TargetFrame(BSTR newVal)
  95. {
  96. HRESULT rc = E_FAIL;
  97. try
  98. {
  99. CLock l(m_cs);
  100. m_strTargetFrame = ::SysAllocString(newVal);
  101. rc = S_OK;
  102. }
  103. catch ( _com_error& ce )
  104. {
  105. rc = ce.Error();
  106. }
  107. catch ( ... )
  108. {
  109. rc = E_FAIL;
  110. }
  111. return rc;
  112. }
  113. STDMETHODIMP CAdRotator::get_GetAdvertisement(BSTR bstrVirtualPath, BSTR * pVal)
  114. {
  115. SCODE rc = E_FAIL;
  116. USES_CONVERSION;
  117. _se_translator_function prevCaptureFn;
  118. prevCaptureFn = _set_se_translator (poi_Capture);
  119. try
  120. {
  121. CContext cxt;
  122. rc = cxt.Init( CContext::get_Server );
  123. if ( !FAILED(rc) )
  124. {
  125. CComBSTR bstrPhysicalPath;
  126. // determine the physical path
  127. if ( ( rc = cxt.Server()->MapPath( bstrVirtualPath, &bstrPhysicalPath ) ) == S_OK )
  128. {
  129. _TCHAR* szPath = OLE2T( bstrPhysicalPath );
  130. CAdFilePtr pAdFile = AdFile( szPath );
  131. if ( pAdFile.IsValid() )
  132. {
  133. // refresh the ad file (make sure it's up to date)
  134. pAdFile->Refresh();
  135. // block all writers
  136. CReader rdr( *pAdFile );
  137. // if the border hasn't been set, use the default from the ad file
  138. short nBorder;
  139. if ( m_bBorderSet == false )
  140. {
  141. nBorder = pAdFile->Border();
  142. }
  143. else
  144. {
  145. nBorder = m_nBorder;
  146. }
  147. CAdDescPtr pAd = pAdFile->RandomAd();
  148. if ( pAd.IsValid() )
  149. {
  150. // write out the HTML line for this ad
  151. StringOutStream ss;
  152. // only write in HREF format if bClickable was set and
  153. // there is a link URL that is not "-"
  154. if ( m_bClickable
  155. && ( pAd->m_strLink.size() > 0 )
  156. && ( pAd->m_strLink != "-") )
  157. {
  158. // use the href format
  159. ss << _T("<A HREF=\"") << pAdFile->Redirector()
  160. << _T("?url=") << pAd->m_strLink
  161. << _T("&image=") << pAd->m_strGif
  162. << _T("\" ");
  163. if (m_strTargetFrame) {
  164. CWCharToMBCS convStr;
  165. if (rc = convStr.Init(m_strTargetFrame, pAdFile->fUTF8() ? 65001 : CP_ACP)) {
  166. throw _com_error(rc);
  167. }
  168. ss << _T("TARGET=\"") << convStr.GetString() << _T("\"");
  169. }
  170. ss << _T(">");
  171. }
  172. // now fill in the rest
  173. ss << _T("<IMG SRC=\"") << pAd->m_strGif
  174. << _T("\" ALT=\"") << pAd->m_strAlt
  175. << _T("\" WIDTH=") << pAdFile->Width()
  176. << _T(" HEIGHT=") << pAdFile->Height();
  177. if ( pAdFile->HSpace() != CAdFile::defaultHSpace )
  178. {
  179. ss << _T(" HSPACE=") << pAdFile->HSpace();
  180. }
  181. if ( pAdFile->VSpace() != CAdFile::defaultVSpace )
  182. {
  183. ss << _T(" VSPACE=") << pAdFile->VSpace();
  184. }
  185. ss << _T(" BORDER=") << nBorder << _T(">");
  186. if ( m_bClickable
  187. && ( pAd->m_strLink.size() > 0 )
  188. && ( pAd->m_strLink != "-") )
  189. {
  190. // put the trailing tag on
  191. ss << _T("</A>");
  192. }
  193. String str = ss.toString();
  194. if ( pVal )
  195. {
  196. CMBCSToWChar convStr;
  197. HRESULT hr;
  198. if ( *pVal )
  199. {
  200. ::SysFreeString( *pVal );
  201. }
  202. if (hr = convStr.Init(str.c_str(), pAdFile->fUTF8() ? 65001 : CP_ACP)) {
  203. throw _com_error(hr);
  204. }
  205. *pVal = ::SysAllocString( convStr.GetString() );
  206. THROW_IF_NULL( *pVal );
  207. rc = S_OK;
  208. }
  209. else
  210. {
  211. rc = E_POINTER;
  212. }
  213. }
  214. }
  215. }
  216. }
  217. else
  218. {
  219. _ASSERT(0);
  220. RaiseException( IDS_ERROR_NOSVR );
  221. } // end if got server
  222. }
  223. catch ( _com_error& ce )
  224. {
  225. rc = ce.Error();
  226. }
  227. catch ( ... )
  228. {
  229. rc = E_FAIL;
  230. }
  231. // restore default translator
  232. _set_se_translator (prevCaptureFn);
  233. return rc;
  234. }
  235. CAdFilePtr
  236. CAdRotator::AdFile(
  237. const String& strFile )
  238. {
  239. CAdFilePtr pAdFile;
  240. CLock l( s_adFiles );
  241. CAdFilePtr& rpAdFile = s_adFiles[ strFile ];
  242. if ( !rpAdFile.IsValid() )
  243. {
  244. pAdFile = new CAdFile;
  245. bool rc = pAdFile->ProcessAdFile( strFile );
  246. if ( rc )
  247. {
  248. rpAdFile = pAdFile;
  249. }
  250. }
  251. else
  252. {
  253. pAdFile = rpAdFile;
  254. }
  255. return pAdFile;
  256. }
  257. /////////////////////////////////////////////////////////////////////////////
  258. // ClearAdFiles
  259. //
  260. // Release all of the ad files from the map
  261. /////////////////////////////////////////////////////////////////////////////
  262. void
  263. CAdRotator::ClearAdFiles()
  264. {
  265. CLock l( s_adFiles );
  266. s_adFiles.clear();
  267. }
  268. //---------------------------------------------------------------------------
  269. // RaiseException
  270. //
  271. // Raises an exception using the given source and description
  272. //---------------------------------------------------------------------------
  273. void
  274. CAdRotator::RaiseException (
  275. LPOLESTR strDescr
  276. )
  277. {
  278. HRESULT hr;
  279. ICreateErrorInfo *pICreateErr;
  280. IErrorInfo *pIErr;
  281. LANGID langID = LANG_NEUTRAL;
  282. /*
  283. * Thread-safe exception handling means that we call
  284. * CreateErrorInfo which gives us an ICreateErrorInfo pointer
  285. * that we then use to set the error information (basically
  286. * to set the fields of an EXCEPINFO structure. We then
  287. * call SetErrorInfo to attach this error to the current
  288. * thread. ITypeInfo::Invoke will look for this when it
  289. * returns from whatever function was invokes by calling
  290. * GetErrorInfo.
  291. */
  292. _TCHAR tstrSource[MAX_RESSTRINGSIZE];
  293. if ( ::LoadString(
  294. _Module.GetResourceInstance(),
  295. IDS_ERROR_SOURCE,
  296. tstrSource,
  297. MAX_RESSTRINGSIZE ) > 0 )
  298. {
  299. USES_CONVERSION;
  300. LPOLESTR strSource = T2OLE( tstrSource );
  301. //Not much we can do if this fails.
  302. if (!FAILED(CreateErrorInfo(&pICreateErr)))
  303. {
  304. pICreateErr->SetGUID(CLSID_AdRotator);
  305. pICreateErr->SetHelpFile(L"");
  306. pICreateErr->SetHelpContext(0L);
  307. pICreateErr->SetSource(strSource);
  308. pICreateErr->SetDescription(strDescr);
  309. hr = pICreateErr->QueryInterface(IID_IErrorInfo, (void**)&pIErr);
  310. if (SUCCEEDED(hr))
  311. {
  312. if(SUCCEEDED(SetErrorInfo(0L, pIErr)))
  313. {
  314. pIErr->Release();
  315. }
  316. }
  317. pICreateErr->Release();
  318. }
  319. }
  320. ::RaiseException(E_FAIL, 0, 0, NULL);
  321. }
  322. void
  323. CAdRotator::RaiseException(
  324. UINT DescrID
  325. )
  326. {
  327. _TCHAR tstrDescr[MAX_RESSTRINGSIZE];
  328. if ( ::LoadString(
  329. _Module.GetResourceInstance(),
  330. DescrID,
  331. tstrDescr,
  332. MAX_RESSTRINGSIZE) > 0 )
  333. {
  334. USES_CONVERSION;
  335. LPOLESTR strDescr = T2OLE( tstrDescr );
  336. RaiseException( strDescr );
  337. }
  338. }