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.

393 lines
12 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name :
  4. ratdata.h
  5. Abstract:
  6. Ratings data class
  7. Author:
  8. Sergei Antonov (sergeia)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. sergeia 7/2/2001 Replaced most of previous code -- it was pretty bad
  13. --*/
  14. #include "stdafx.h"
  15. #include "cnfgprts.h"
  16. #include "parserat.h"
  17. #include "RatData.h"
  18. //----------------------------------------------------------------
  19. CRatingsData::CRatingsData():
  20. iRat(0),
  21. m_fEnabled( FALSE ),
  22. m_start_minute(0),
  23. m_start_hour(0),
  24. m_start_day(0),
  25. m_start_month(0),
  26. m_start_year(0),
  27. m_expire_minute(0),
  28. m_expire_hour(0),
  29. m_expire_day(0),
  30. m_expire_month(0),
  31. m_expire_year(0)
  32. {
  33. }
  34. //----------------------------------------------------------------
  35. CRatingsData::~CRatingsData()
  36. {
  37. // delete the rating systems
  38. DWORD nRats = (DWORD)rgbRats.GetSize();
  39. for (DWORD iRat = 0; iRat < nRats; iRat++)
  40. {
  41. delete rgbRats[iRat];
  42. }
  43. }
  44. //----------------------------------------------------------------
  45. // generate the label and save it into the metabase
  46. void CRatingsData::SaveTheLabel()
  47. {
  48. BOOL fBuiltLabel = FALSE;
  49. CError err;
  50. CString csTempPassword;
  51. m_password.CopyTo(csTempPassword);
  52. CComAuthInfo auth(m_szServer, m_username, csTempPassword);
  53. CMetaKey mk(&auth, m_szMeta, METADATA_PERMISSION_WRITE);
  54. err = mk.QueryResult();
  55. if (err.Failed())
  56. {
  57. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  58. {
  59. //
  60. // Path didn't exist yet, create it and reopen
  61. // it.
  62. //
  63. err = mk.CreatePathFromFailedOpen();
  64. if (err.Succeeded())
  65. {
  66. err = mk.ReOpen(METADATA_PERMISSION_WRITE);
  67. }
  68. }
  69. }
  70. if (err.Succeeded())
  71. {
  72. if (!m_fEnabled)
  73. {
  74. err = mk.DeleteValue(MD_HTTP_PICS);
  75. }
  76. else
  77. {
  78. CString szLabel = _T("PICS-Label: ");
  79. // create the modified string for this label
  80. CString szMod;
  81. CreateDateSz( szMod, m_start_day, m_start_month, m_start_year, m_start_hour, m_start_minute );
  82. // create the exipres string for this label
  83. CString szExpire;
  84. CreateDateSz( szExpire, m_expire_day, m_expire_month, m_expire_year, m_expire_hour, m_expire_minute );
  85. // tell each ratings system object to add its label to the string
  86. CStringListEx list;
  87. DWORD nRatingSystems = (DWORD)rgbRats.GetSize();
  88. for ( DWORD iRat = 0; iRat < nRatingSystems; iRat++ )
  89. {
  90. // build the label string
  91. rgbRats[iRat]->OutputLabels( szLabel, m_szURL, m_szEmail, szMod, szExpire );
  92. list.AddTail(szLabel);
  93. }
  94. err = mk.SetValue(MD_HTTP_PICS, list);
  95. }
  96. }
  97. }
  98. BOOL CRatingsData::Init()
  99. {
  100. BOOL fGotSomething = FALSE;
  101. TCHAR flt[MAX_PATH];
  102. ExpandEnvironmentStrings(_T("%windir%\\system32\\*.rat"), flt, MAX_PATH);
  103. WIN32_FIND_DATA ffdata;
  104. ZeroMemory(&ffdata, sizeof(ffdata));
  105. HANDLE hFind = ::FindFirstFile(flt, &ffdata);
  106. if (hFind != INVALID_HANDLE_VALUE)
  107. {
  108. do
  109. {
  110. if ((ffdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
  111. {
  112. TCHAR filename[MAX_PATH];
  113. ExpandEnvironmentStrings(_T("%windir%\\system32"), filename, MAX_PATH);
  114. PathAppend(filename, ffdata.cFileName);
  115. fGotSomething |= LoadRatingsFile(filename);
  116. }
  117. } while (::FindNextFile(hFind, &ffdata));
  118. ::FindClose(hFind);
  119. }
  120. if ( fGotSomething )
  121. {
  122. LoadMetabaseValues();
  123. }
  124. else
  125. {
  126. AfxMessageBox(IDS_RAT_FINDFILE_ERROR);
  127. }
  128. return fGotSomething;
  129. }
  130. BOOL CRatingsData::LoadRatingsFile(CString szFilePath)
  131. {
  132. CFile f;
  133. CFileException e;
  134. if(!f.Open(szFilePath, CFile::modeRead | CFile::shareDenyWrite, &e))
  135. {
  136. #ifdef _DEBUG
  137. afxDump << "File could not be opened " << e.m_cause << "\n";
  138. #endif
  139. return FALSE;
  140. }
  141. ULONGLONG len = f.GetLength();
  142. LPSTR pBuf = (LPSTR)_alloca((int)len);
  143. BOOL fParsed = FALSE;
  144. if (NULL != pBuf)
  145. {
  146. if (len == f.Read(pBuf, (UINT)len))
  147. {
  148. fParsed = ParseRatingsFile(pBuf);
  149. }
  150. }
  151. return fParsed;
  152. }
  153. BOOL CRatingsData::ParseRatingsFile(LPSTR pData)
  154. {
  155. HRESULT hres;
  156. BOOL fSuccess = FALSE;
  157. PicsRatingSystem * pRating = new PicsRatingSystem();
  158. if (NULL != pRating)
  159. {
  160. fSuccess = SUCCEEDED(pRating->Parse(pData));
  161. if ( !fSuccess )
  162. {
  163. delete pRating;
  164. return FALSE;
  165. }
  166. rgbRats.Add(pRating);
  167. }
  168. return fSuccess;
  169. }
  170. //----------------------------------------------------------------
  171. // create a date string
  172. void CRatingsData::CreateDateSz( CString &sz, WORD day, WORD month, WORD year, WORD hour, WORD minute )
  173. {
  174. // get the local time zone
  175. TIME_ZONE_INFORMATION tZone;
  176. INT hrZone, mnZone;
  177. DWORD dwDaylight = GetTimeZoneInformation( &tZone );
  178. // Fix for 339525: Boyd, this could be negative and must be signed type!
  179. LONG tBias;
  180. // First, calculate the correct bias - depending whether or not
  181. // we are in daylight savings time.
  182. if ( dwDaylight == TIME_ZONE_ID_DAYLIGHT )
  183. {
  184. tBias = tZone.Bias + tZone.DaylightBias;
  185. }
  186. else
  187. {
  188. tBias = tZone.Bias + tZone.StandardBias;
  189. }
  190. // calculate the hours and minutes offset for the time-zone
  191. hrZone = tBias / 60;
  192. mnZone = tBias % 60;
  193. // need to handle time zones east of GMT
  194. if ( hrZone < 0 )
  195. {
  196. hrZone *= (-1);
  197. mnZone *= (-1);
  198. // make the string
  199. sz.Format( _T("%04d.%02d.%02dT%02d:%02d+%02d%02d"), year, month, day, hour, minute, hrZone, mnZone );
  200. }
  201. else
  202. {
  203. // make the string
  204. sz.Format( _T("%04d.%02d.%02dT%02d:%02d-%02d%02d"), year, month, day, hour, minute, hrZone, mnZone );
  205. }
  206. }
  207. //----------------------------------------------------------------
  208. // read a date string
  209. void CRatingsData::ReadDateSz( CString sz, WORD* pDay, WORD* pMonth, WORD* pYear, WORD* pHour, WORD* pMinute )
  210. {
  211. CString szNum;
  212. WORD i;
  213. DWORD dw;
  214. // year
  215. szNum = sz.Left( sz.Find(_T('.')) );
  216. i = (WORD)swscanf( szNum, _T("%d"), &dw );
  217. *pYear = (WORD)dw;
  218. sz = sz.Right( sz.GetLength() - szNum.GetLength() - 1 );
  219. // month
  220. szNum = sz.Left( sz.Find(_T('.')) );
  221. i = (WORD)swscanf( szNum, _T("%d"), &dw );
  222. *pMonth = (WORD)dw;
  223. sz = sz.Right( sz.GetLength() - szNum.GetLength() - 1 );
  224. // day
  225. szNum = sz.Left( sz.Find(_T('T')) );
  226. i = (WORD)swscanf( szNum, _T("%d"), &dw );
  227. *pDay = (WORD)dw;
  228. sz = sz.Right( sz.GetLength() - szNum.GetLength() - 1 );
  229. // hour
  230. szNum = sz.Left( sz.Find(_T(':')) );
  231. i = (WORD)swscanf( szNum, _T("%d"), &dw );
  232. *pHour = (WORD)dw;
  233. sz = sz.Right( sz.GetLength() - szNum.GetLength() - 1 );
  234. // minute
  235. szNum = sz.Left( 2 );
  236. i = (WORD)swscanf( szNum, _T("%d"), &dw );
  237. *pMinute = (WORD)dw;
  238. }
  239. void CRatingsData::LoadMetabaseValues()
  240. {
  241. CString csTempPassword;
  242. m_password.CopyTo(csTempPassword);
  243. CComAuthInfo auth(m_szServer, m_username, csTempPassword);
  244. CMetaKey mk(&auth);
  245. CString path = m_szMeta;
  246. CError err;
  247. while (FAILED(mk.DoesPathExist(path)))
  248. {
  249. CMetabasePath::ConvertToParentPath(path);
  250. }
  251. CStringListEx list;
  252. err = mk.QueryValue(MD_HTTP_PICS, list, NULL, path);
  253. if (err.Succeeded())
  254. {
  255. if (!list.IsEmpty())
  256. {
  257. ParseMetaRating(list.GetHead());
  258. }
  259. }
  260. }
  261. //----------------------------------------------------------------
  262. // NOTE: this is a pretty fragile reading of the PICS file. If things are
  263. // not in the order that this file would write them back out in, it will fail.
  264. // however, This will work on PICS ratings that this module has written out,
  265. // which should pretty much be all of them
  266. // it also assumes that one-letter abbreviations are used just about everywhere
  267. #define RAT_PERSON_DETECTOR _T("by \"")
  268. #define RAT_LABEL_DETECTOR _T("l ")
  269. #define RAT_ON_DETECTOR _T("on \"")
  270. #define RAT_EXPIRE_DETECTOR _T("exp \"")
  271. #define RAT_RAT_DETECTOR _T("r (")
  272. void CRatingsData::ParseMetaRating( CString szRating )
  273. {
  274. CString szScratch;
  275. // if we got here, then we know that the rating system is enabled
  276. m_fEnabled = TRUE;
  277. // operate on a copy of the data
  278. CString szRat;
  279. // skip past the http headerpart
  280. szRat = szRating.Right( szRating.GetLength() - szRating.Find(_T("\"http://")) - 1 );
  281. szRat = szRat.Right( szRat.GetLength() - szRat.Find(_T('\"')) - 1 );
  282. szRat.TrimLeft();
  283. // the next bit should be the label indicator. Skip over it
  284. if ( szRat.Left(wcslen(RAT_LABEL_DETECTOR)) == RAT_LABEL_DETECTOR )
  285. szRat = szRat.Right( szRat.GetLength() - wcslen(RAT_LABEL_DETECTOR) );
  286. // we should now be at the author part. If it is there, load it in
  287. if ( szRat.Left(wcslen(RAT_PERSON_DETECTOR)) == RAT_PERSON_DETECTOR )
  288. {
  289. szRat = szRat.Right( szRat.GetLength() - wcslen(RAT_PERSON_DETECTOR) );
  290. m_szEmail = szRat.Left( szRat.Find(_T('\"')) );
  291. szRat = szRat.Right( szRat.GetLength() - m_szEmail.GetLength() - 1 );
  292. szRat.TrimLeft();
  293. }
  294. // next should be the modification date
  295. // we should now be at the author part. If we are, load it in
  296. if ( szRat.Left(wcslen(RAT_ON_DETECTOR)) == RAT_ON_DETECTOR )
  297. {
  298. szRat = szRat.Right( szRat.GetLength() - wcslen(RAT_ON_DETECTOR) );
  299. szScratch = szRat.Left( szRat.Find(_T('\"')) );
  300. szRat = szRat.Right( szRat.GetLength() - szScratch.GetLength() - 1 );
  301. szRat.TrimLeft();
  302. ReadDateSz( szScratch, &m_start_day, &m_start_month, &m_start_year,
  303. &m_start_hour, &m_start_minute );
  304. }
  305. // next should be the expiration date
  306. // we should now be at the author part. If we are, load it in
  307. if ( szRat.Left(wcslen(RAT_EXPIRE_DETECTOR)) == RAT_EXPIRE_DETECTOR )
  308. {
  309. szRat = szRat.Right( szRat.GetLength() - wcslen(RAT_EXPIRE_DETECTOR) );
  310. szScratch = szRat.Left( szRat.Find(_T('\"')) );
  311. szRat = szRat.Right( szRat.GetLength() - szScratch.GetLength() - 1 );
  312. szRat.TrimLeft();
  313. ReadDateSz( szScratch, &m_expire_day, &m_expire_month, &m_expire_year,
  314. &m_expire_hour, &m_expire_minute );
  315. }
  316. // we should now be at the actual ratings part. If we are, load it in as one string first
  317. if ( szRat.Left(wcslen(RAT_RAT_DETECTOR)) == RAT_RAT_DETECTOR )
  318. {
  319. szRat = szRat.Right( szRat.GetLength() - wcslen(RAT_RAT_DETECTOR) );
  320. szScratch = szRat.Left( szRat.Find(_T(')')) );
  321. szRat = szRat.Right( szRat.GetLength() - szScratch.GetLength() - 1 );
  322. szRat.TrimLeft();
  323. // loop through all the value pairs in the ratings string
  324. while ( szScratch.GetLength() )
  325. {
  326. // this part goes <ch> sp <ch> so that we know we can use chars 0 and 2
  327. ParseMetaPair( szScratch[0], szScratch[2] );
  328. // cut down the string
  329. szScratch = szScratch.Right( szScratch.GetLength() - 3 );
  330. szScratch.TrimLeft();
  331. }
  332. }
  333. }
  334. //----------------------------------------------------------------
  335. void CRatingsData::ParseMetaPair( TCHAR chCat, TCHAR chVal )
  336. {
  337. // check validity of the value character
  338. if ( (chVal < _T('0')) || (chVal > _T('9')) )
  339. return;
  340. // convert the value into a number - the quick way
  341. WORD value = chVal - _T('0');
  342. // try all the categories
  343. DWORD nCat = rgbRats[0]->arrpPC.Length();
  344. for ( DWORD iCat = 0; iCat < nCat; iCat++ )
  345. {
  346. // stop at the first successful setting
  347. if ( rgbRats[0]->arrpPC[iCat]->FSetValuePair((CHAR)chCat, (CHAR)value) )
  348. break;
  349. }
  350. }