Source code of Windows XP (NT5)
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.

1378 lines
40 KiB

  1. /****************************************************************************\
  2. *
  3. * RATINGS.CPP --Parses out the actual ratings from a site.
  4. *
  5. * Created: Ann McCurdy
  6. *
  7. \****************************************************************************/
  8. /*Includes---------------------------------------------------------*/
  9. #include "msrating.h"
  10. #include "mslubase.h"
  11. #include "debug.h"
  12. #include <ratings.h>
  13. #include <ratingsp.h>
  14. #include "parselbl.h"
  15. #include "picsrule.h"
  16. #include "pleasdlg.h" // CPleaseDialog
  17. #include <convtime.h>
  18. #include <contxids.h>
  19. #include <shlwapip.h>
  20. #include <wininet.h>
  21. #include <mluisupp.h>
  22. extern PICSRulesRatingSystem * g_pPRRS;
  23. extern array<PICSRulesRatingSystem*> g_arrpPRRS;
  24. extern PICSRulesRatingSystem * g_pApprovedPRRS;
  25. extern PICSRulesRatingSystem * g_pApprovedPRRSPreApply;
  26. extern array<PICSRulesRatingSystem*> g_arrpPICSRulesPRRSPreApply;
  27. extern BOOL g_fPICSRulesEnforced,g_fApprovedSitesEnforced;
  28. extern HMODULE g_hURLMON,g_hWININET;
  29. extern char g_szLastURL[INTERNET_MAX_URL_LENGTH];
  30. extern HINSTANCE g_hInstance;
  31. HANDLE g_HandleGlobalCounter,g_ApprovedSitesHandleGlobalCounter;
  32. long g_lGlobalCounterValue,g_lApprovedSitesGlobalCounterValue;
  33. DWORD g_dwDataSource;
  34. BOOL g_fInvalid;
  35. PicsRatingSystemInfo *gPRSI = NULL;
  36. //7c9c1e2a-4dcd-11d2-b972-0060b0c4834d
  37. const GUID GUID_Ratings = { 0x7c9c1e2aL, 0x4dcd, 0x11d2, { 0xb9, 0x72, 0x00, 0x60, 0xb0, 0xc4, 0x83, 0x4d } };
  38. //7c9c1e2b-4dcd-11d2-b972-0060b0c4834d
  39. const GUID GUID_ApprovedSites = { 0x7c9c1e2bL, 0x4dcd, 0x11d2, { 0xb9, 0x72, 0x00, 0x60, 0xb0, 0xc4, 0x83, 0x4d } };
  40. extern CustomRatingHelper *g_pCustomRatingHelperList;
  41. BOOL g_fIsRunningUnderCustom = FALSE;
  42. void TerminateRatings(BOOL bProcessDetach);
  43. //+-----------------------------------------------------------------------
  44. //
  45. // Function: RatingsCustomInit
  46. //
  47. // Synopsis: Initialize the msrating dll for Custom
  48. //
  49. // Arguments: bInit (Default TRUE) - TRUE: change into Custom Mode
  50. // FALSE: change out of Custom Mode
  51. //
  52. // Returns: S_OK if properly initialized, E_OUTOFMEMORY otherwise
  53. //
  54. //------------------------------------------------------------------------
  55. HRESULT WINAPI RatingCustomInit(BOOL bInit)
  56. {
  57. HRESULT hres = E_OUTOFMEMORY;
  58. ENTERCRITICAL;
  59. if (bInit)
  60. {
  61. if (NULL != gPRSI)
  62. {
  63. delete gPRSI;
  64. }
  65. gPRSI = new PicsRatingSystemInfo;
  66. if (gPRSI)
  67. {
  68. g_fIsRunningUnderCustom = TRUE;
  69. hres = S_OK;
  70. }
  71. }
  72. else
  73. {
  74. TerminateRatings(FALSE);
  75. RatingInit();
  76. g_fIsRunningUnderCustom = FALSE;
  77. hres = S_OK;
  78. }
  79. LEAVECRITICAL;
  80. return hres;
  81. }
  82. //+-----------------------------------------------------------------------
  83. //
  84. // Function: RatingCustomAddRatingSystem
  85. //
  86. // Synopsis: Hand the description of a PICS rating system file to msrating.
  87. // The description is simply the contents of an RAT file.
  88. //
  89. // Arguments: pszRatingSystemBuffer : buffer containing the description
  90. // nBufferSize : the size of pszRatingSystemBuffer
  91. //
  92. // Returns: Success if rating system added
  93. // This function will not succeed if RatingCustomInit has
  94. // not been called.
  95. //
  96. //------------------------------------------------------------------------
  97. STDAPI RatingCustomAddRatingSystem(LPSTR pszRatingSystemBuffer, UINT nBufferSize)
  98. {
  99. HRESULT hres = E_OUTOFMEMORY;
  100. if(!pszRatingSystemBuffer || nBufferSize == 0)
  101. {
  102. return E_INVALIDARG;
  103. }
  104. if (g_fIsRunningUnderCustom)
  105. {
  106. PicsRatingSystem* pPRS = new PicsRatingSystem;
  107. if (pPRS)
  108. {
  109. hres = pPRS->Parse(NULL, pszRatingSystemBuffer);
  110. if (SUCCEEDED(hres))
  111. {
  112. pPRS->dwFlags |= PRS_ISVALID;
  113. }
  114. }
  115. if (SUCCEEDED(hres))
  116. {
  117. ENTERCRITICAL;
  118. gPRSI->arrpPRS.Append(pPRS);
  119. gPRSI->fRatingInstalled = TRUE;
  120. LEAVECRITICAL;
  121. }
  122. else
  123. {
  124. if(pPRS)
  125. {
  126. delete pPRS;
  127. pPRS = NULL;
  128. }
  129. }
  130. }
  131. else
  132. {
  133. hres = E_FAIL;
  134. }
  135. return hres;
  136. }
  137. //+-----------------------------------------------------------------------
  138. //
  139. // Function: RatingCustomSetUserOptions
  140. //
  141. // Synopsis: Set the user options for the msrating dll for this process
  142. //
  143. // Arguments: pRSSetings : pointer to an array of rating system settings
  144. // cSettings : number of rating systems
  145. //
  146. // Returns: Success if user properly set
  147. // This function will not succeed if RatingCustomInit has
  148. // not been called.
  149. //
  150. //------------------------------------------------------------------------
  151. HRESULT WINAPI RatingCustomSetUserOptions(RATINGSYSTEMSETTING* pRSSettings, UINT cSettings) {
  152. if (!pRSSettings || cSettings == 0)
  153. {
  154. return E_INVALIDARG;
  155. }
  156. ENTERCRITICAL;
  157. HRESULT hres = E_OUTOFMEMORY;
  158. UINT err, errTemp;
  159. if (g_fIsRunningUnderCustom)
  160. {
  161. if (gPRSI)
  162. {
  163. PicsUser* puser = new PicsUser;
  164. if (puser)
  165. {
  166. for (UINT i=0; i<cSettings; i++)
  167. {
  168. UserRatingSystem* pURS = new UserRatingSystem;
  169. if (!pURS)
  170. {
  171. err = ERROR_NOT_ENOUGH_MEMORY;
  172. break;
  173. }
  174. if (errTemp = pURS->QueryError())
  175. {
  176. err = errTemp;
  177. break;
  178. }
  179. RATINGSYSTEMSETTING* parss = &pRSSettings[i];
  180. pURS->SetName(parss->pszRatingSystemName);
  181. pURS->m_pPRS = FindInstalledRatingSystem(parss->pszRatingSystemName);
  182. for (UINT j=0; j<parss->cCategories; j++)
  183. {
  184. UserRating* pUR = new UserRating;
  185. if (pUR)
  186. {
  187. if (errTemp = pUR->QueryError())
  188. {
  189. err = errTemp;
  190. }
  191. else
  192. {
  193. RATINGCATEGORYSETTING* parcs = &parss->paRCS[j];
  194. pUR->SetName(parcs->pszValueName);
  195. pUR->m_nValue = parcs->nValue;
  196. if (pURS->m_pPRS)
  197. {
  198. pUR->m_pPC = FindInstalledCategory(pURS->m_pPRS->arrpPC, parcs->pszValueName);
  199. }
  200. err = pURS->AddRating(pUR);
  201. }
  202. }
  203. else
  204. {
  205. err = ERROR_NOT_ENOUGH_MEMORY;
  206. }
  207. if (ERROR_SUCCESS != err)
  208. {
  209. if (pUR)
  210. {
  211. delete pUR;
  212. pUR = NULL;
  213. }
  214. break;
  215. }
  216. }
  217. if (ERROR_SUCCESS == err)
  218. {
  219. err = puser->AddRatingSystem(pURS);
  220. }
  221. if (ERROR_SUCCESS != err)
  222. {
  223. if (pURS)
  224. {
  225. delete pURS;
  226. pURS = NULL;
  227. }
  228. break;
  229. }
  230. }
  231. if (ERROR_SUCCESS == err)
  232. {
  233. hres = NOERROR;
  234. gPRSI->fSettingsValid = TRUE;
  235. if (gPRSI->pUserObject)
  236. {
  237. delete gPRSI->pUserObject;
  238. }
  239. gPRSI->pUserObject = puser;
  240. }
  241. }
  242. }
  243. else
  244. {
  245. hres = E_UNEXPECTED;
  246. }
  247. }
  248. else
  249. {
  250. hres = E_FAIL;
  251. }
  252. LEAVECRITICAL;
  253. return hres;
  254. }
  255. //+-----------------------------------------------------------------------
  256. //
  257. // Function: RatingCustomAddRatingHelper
  258. //
  259. // Synopsis: Add a Custom ratings helper object
  260. //
  261. // Arguments: pszLibraryName : name of the library to load the helper from
  262. // clsid : CLSID of the rating helper
  263. // dwSort : Sort order or priority of the helper
  264. //
  265. // Returns: Success if rating helper added properly set
  266. // This function will not succeed if RatingCustomInit has
  267. // not been called.
  268. //
  269. //------------------------------------------------------------------------
  270. HRESULT WINAPI RatingCustomAddRatingHelper(LPCSTR pszLibraryName, CLSID clsid, DWORD dwSort)
  271. {
  272. HRESULT hr = E_UNEXPECTED;
  273. if (g_fIsRunningUnderCustom)
  274. {
  275. CustomRatingHelper* pmrh = new CustomRatingHelper;
  276. if(NULL == pmrh)
  277. {
  278. hr = E_OUTOFMEMORY;
  279. }
  280. else
  281. {
  282. pmrh->hLibrary = LoadLibrary(pszLibraryName);
  283. if (pmrh->hLibrary)
  284. {
  285. pmrh->clsid = clsid;
  286. pmrh->dwSort = dwSort;
  287. ENTERCRITICAL;
  288. CustomRatingHelper* pmrhCurrent = g_pCustomRatingHelperList;
  289. CustomRatingHelper* pmrhPrev = NULL;
  290. while (pmrhCurrent && pmrhCurrent->dwSort < pmrh->dwSort)
  291. {
  292. pmrhPrev = pmrhCurrent;
  293. pmrhCurrent = pmrhCurrent->pNextHelper;
  294. }
  295. if (pmrhPrev)
  296. {
  297. ASSERT(pmrhPrev->pNextHelper == pmrhCurrent);
  298. pmrh->pNextHelper = pmrhCurrent;
  299. pmrhPrev->pNextHelper = pmrh;
  300. }
  301. else
  302. {
  303. ASSERT(pmrhCurrent == g_pCustomRatingHelperList);
  304. pmrh->pNextHelper = g_pCustomRatingHelperList;
  305. g_pCustomRatingHelperList = pmrh;
  306. }
  307. hr = S_OK;
  308. LEAVECRITICAL;
  309. } // if (pmrh->hLibrary)
  310. else
  311. {
  312. hr = E_FAIL;
  313. }
  314. }
  315. }
  316. else
  317. {
  318. hr = E_FAIL;
  319. }
  320. return hr;
  321. }
  322. //+-----------------------------------------------------------------------
  323. //
  324. // Function: RatingCustomRemoveRatingHelper
  325. //
  326. // Synopsis: Remove Custom rating helpers
  327. //
  328. // Arguments: CLSID : CLSID of the helper to remove
  329. //
  330. // Returns: S_OK if rating helper removed, S_FALSE if not found
  331. // E_UNEXPECTED if the global custom helper list is corrupted.
  332. // This function will not succeed if RatingCustomInit has
  333. // not been called and will return E_FAIL
  334. //
  335. //------------------------------------------------------------------------
  336. HRESULT WINAPI RatingCustomRemoveRatingHelper(CLSID clsid)
  337. {
  338. CustomRatingHelper* pmrhCurrent = NULL;
  339. CustomRatingHelper* pmrhTemp = NULL;
  340. CustomRatingHelper* pmrhPrev = NULL;
  341. HRESULT hr = E_UNEXPECTED;
  342. if (g_fIsRunningUnderCustom)
  343. {
  344. if (NULL != g_pCustomRatingHelperList)
  345. {
  346. hr = S_FALSE;
  347. ENTERCRITICAL;
  348. pmrhCurrent = g_pCustomRatingHelperList;
  349. while (pmrhCurrent && pmrhCurrent->clsid != clsid)
  350. {
  351. pmrhPrev = pmrhCurrent;
  352. pmrhCurrent = pmrhCurrent->pNextHelper;
  353. }
  354. if (pmrhCurrent)
  355. {
  356. //
  357. // Snag copy of the node
  358. //
  359. pmrhTemp = pmrhCurrent;
  360. if (pmrhPrev) // Not on first node
  361. {
  362. //
  363. // Unlink the deleted node
  364. //
  365. pmrhPrev->pNextHelper = pmrhCurrent->pNextHelper;
  366. }
  367. else // First node -- adjust head pointer
  368. {
  369. ASSERT(pmrhCurrent == g_pCustomRatingHelperList);
  370. g_pCustomRatingHelperList = g_pCustomRatingHelperList->pNextHelper;
  371. }
  372. //
  373. // Wipe out the node
  374. //
  375. delete pmrhTemp;
  376. pmrhTemp = NULL;
  377. hr = S_OK;
  378. }
  379. LEAVECRITICAL;
  380. }
  381. }
  382. else
  383. {
  384. hr = E_FAIL;
  385. }
  386. return hr;
  387. }
  388. //+-----------------------------------------------------------------------
  389. //
  390. // Function: RatingCustomSetDefaultBureau
  391. //
  392. // Synopsis: Set the URL of the default rating bureau
  393. //
  394. // Arguments: pszRatingBureau - URL of the rating bureau
  395. //
  396. // Returns: S_OK if success, E_FAIL if RatingCustomInit has not been
  397. // called, E_OUTOFMEMORY if unable to allocate memory
  398. // E_INVALIDARG if pszRatingBureau is NULL
  399. // This function will not succeed if RatingCustomInit has
  400. // not been called and return E_FAIL.
  401. //
  402. //------------------------------------------------------------------------
  403. HRESULT WINAPI RatingCustomSetDefaultBureau(LPCSTR pszRatingBureau)
  404. {
  405. HRESULT hr;
  406. if (pszRatingBureau)
  407. {
  408. if (g_fIsRunningUnderCustom)
  409. {
  410. LPSTR pszTemp = new char[strlenf(pszRatingBureau)+1];
  411. if (pszTemp)
  412. {
  413. strcpy(pszTemp, pszRatingBureau);
  414. gPRSI->etstrRatingBureau.SetTo(pszTemp);
  415. hr = S_OK;
  416. } // if (pszTemp)
  417. else
  418. {
  419. hr = E_OUTOFMEMORY;
  420. }
  421. } // if(g_fIsRunningUnderCustom)
  422. else
  423. {
  424. hr = E_FAIL;
  425. }
  426. }
  427. else
  428. {
  429. hr = E_INVALIDARG;
  430. }
  431. return hr;
  432. }
  433. HRESULT WINAPI RatingInit()
  434. {
  435. DWORD dwNumSystems,dwCounter;
  436. HRESULT hRes;
  437. PICSRulesRatingSystem * pPRRS=NULL;
  438. g_hURLMON=LoadLibrary("URLMON.DLL");
  439. if (g_hURLMON==NULL)
  440. {
  441. TraceMsg( TF_ERROR, "RatingInit() - Failed to Load URLMON!" );
  442. g_pPRRS=NULL; //we couldn't load URLMON
  443. hRes=E_UNEXPECTED;
  444. }
  445. g_hWININET=LoadLibrary("WININET.DLL");
  446. if (g_hWININET==NULL)
  447. {
  448. TraceMsg( TF_ERROR, "RatingInit() - Failed to Load WININET!" );
  449. g_pPRRS=NULL; //we couldn't load WININET
  450. hRes=E_UNEXPECTED;
  451. }
  452. g_HandleGlobalCounter=SHGlobalCounterCreate(GUID_Ratings);
  453. g_lGlobalCounterValue=SHGlobalCounterGetValue(g_HandleGlobalCounter);
  454. g_ApprovedSitesHandleGlobalCounter=SHGlobalCounterCreate(GUID_ApprovedSites);
  455. g_lApprovedSitesGlobalCounterValue=SHGlobalCounterGetValue(g_ApprovedSitesHandleGlobalCounter);
  456. gPRSI = new PicsRatingSystemInfo;
  457. if(gPRSI == NULL)
  458. {
  459. TraceMsg( TF_ERROR, "RatingInit() - gPRSI is NULL!" );
  460. return E_OUTOFMEMORY;
  461. }
  462. gPRSI->Init();
  463. hRes=PICSRulesReadFromRegistry(PICSRULES_APPROVEDSITES,&g_pApprovedPRRS);
  464. if (FAILED(hRes))
  465. {
  466. g_pApprovedPRRS=NULL;
  467. }
  468. hRes=PICSRulesGetNumSystems(&dwNumSystems);
  469. if (SUCCEEDED(hRes)) //we have PICSRules systems to inforce
  470. {
  471. for (dwCounter=PICSRULES_FIRSTSYSTEMINDEX;
  472. dwCounter<(dwNumSystems+PICSRULES_FIRSTSYSTEMINDEX);
  473. dwCounter++)
  474. {
  475. hRes=PICSRulesReadFromRegistry(dwCounter,&pPRRS);
  476. if (FAILED(hRes))
  477. {
  478. char *lpszTitle,*lpszMessage;
  479. //we couldn't read in the systems, so don't inforce PICSRules,
  480. //and notify the user
  481. g_arrpPRRS.DeleteAll();
  482. lpszTitle=(char *) GlobalAlloc(GPTR,MAX_PATH);
  483. lpszMessage=(char *) GlobalAlloc(GPTR,MAX_PATH);
  484. MLLoadString(IDS_PICSRULES_TAMPEREDREADTITLE,(LPTSTR) lpszTitle,MAX_PATH);
  485. MLLoadString(IDS_PICSRULES_TAMPEREDREADMSG,(LPTSTR) lpszMessage,MAX_PATH);
  486. MessageBox(NULL,(LPCTSTR) lpszMessage,(LPCTSTR) lpszTitle,MB_OK|MB_ICONERROR);
  487. GlobalFree(lpszTitle);
  488. lpszTitle = NULL;
  489. GlobalFree(lpszMessage);
  490. lpszMessage = NULL;
  491. break;
  492. }
  493. else
  494. {
  495. g_arrpPRRS.Append(pPRRS);
  496. pPRRS=NULL;
  497. }
  498. }
  499. }
  500. return NOERROR;
  501. }
  502. // YANGXU: 11/16/1999
  503. // Actual rating term function that does the work
  504. // bProcessDetach: pass in as true if terminating during
  505. // ProcessDetach so libraries are not freed
  506. void TerminateRatings(BOOL bProcessDetach)
  507. {
  508. delete gPRSI;
  509. gPRSI = NULL;
  510. if (g_pApprovedPRRS != NULL)
  511. {
  512. delete g_pApprovedPRRS;
  513. g_pApprovedPRRS = NULL;
  514. }
  515. if (g_pApprovedPRRSPreApply != NULL)
  516. {
  517. delete g_pApprovedPRRSPreApply;
  518. g_pApprovedPRRSPreApply = NULL;
  519. }
  520. g_arrpPRRS.DeleteAll();
  521. g_arrpPICSRulesPRRSPreApply.DeleteAll();
  522. CloseHandle(g_HandleGlobalCounter);
  523. CloseHandle(g_ApprovedSitesHandleGlobalCounter);
  524. CustomRatingHelper *pTemp;
  525. while (g_pCustomRatingHelperList)
  526. {
  527. pTemp = g_pCustomRatingHelperList;
  528. if (bProcessDetach)
  529. {
  530. // TRICKY: Can't FreeLibrary() during DLL_PROCESS_DETACH, so leak the HMODULE...
  531. // (setting to NULL prevents the destructor from doing FreeLibrary()).
  532. //
  533. g_pCustomRatingHelperList->hLibrary = NULL;
  534. }
  535. g_pCustomRatingHelperList = g_pCustomRatingHelperList->pNextHelper;
  536. delete pTemp;
  537. pTemp = NULL;
  538. }
  539. if (bProcessDetach)
  540. {
  541. if ( g_hURLMON )
  542. {
  543. FreeLibrary(g_hURLMON);
  544. g_hURLMON = NULL;
  545. }
  546. if ( g_hWININET )
  547. {
  548. FreeLibrary(g_hWININET);
  549. g_hWININET = NULL;
  550. }
  551. }
  552. }
  553. void RatingTerm()
  554. {
  555. TerminateRatings(TRUE);
  556. }
  557. HRESULT WINAPI RatingEnabledQuery()
  558. {
  559. CheckGlobalInfoRev();
  560. // $BUG - If the Settings are not valid should we return E_FAIL?
  561. if (gPRSI && !gPRSI->fSettingsValid)
  562. return S_OK;
  563. if (gPRSI && gPRSI->fRatingInstalled) {
  564. PicsUser *pUser = ::GetUserObject();
  565. return (pUser && pUser->fEnabled) ? S_OK : S_FALSE;
  566. }
  567. else {
  568. return E_FAIL;
  569. }
  570. }
  571. // Store the Parsed Label List of Ratings Information to ppRatingDetails.
  572. void StoreRatingDetails( CParsedLabelList * pParsed, LPVOID * ppRatingDetails )
  573. {
  574. if (ppRatingDetails != NULL)
  575. {
  576. *ppRatingDetails = pParsed;
  577. }
  578. else
  579. {
  580. if ( pParsed )
  581. {
  582. FreeParsedLabelList(pParsed);
  583. pParsed = NULL;
  584. }
  585. }
  586. }
  587. HRESULT WINAPI RatingCheckUserAccess(LPCSTR pszUsername, LPCSTR pszURL,
  588. LPCSTR pszRatingInfo, LPBYTE pData,
  589. DWORD cbData, LPVOID *ppRatingDetails)
  590. {
  591. HRESULT hRes;
  592. BOOL fPassFail;
  593. g_fInvalid=FALSE;
  594. g_dwDataSource=cbData;
  595. g_fPICSRulesEnforced=FALSE;
  596. g_fApprovedSitesEnforced=FALSE;
  597. if (pszURL)
  598. lstrcpy(g_szLastURL,pszURL);
  599. CheckGlobalInfoRev();
  600. if (ppRatingDetails != NULL)
  601. *ppRatingDetails = NULL;
  602. if (!gPRSI->fSettingsValid)
  603. return ResultFromScode(S_FALSE);
  604. if (!gPRSI->fRatingInstalled)
  605. return ResultFromScode(S_OK);
  606. PicsUser *pUser = GetUserObject(pszUsername);
  607. if (pUser == NULL) {
  608. return HRESULT_FROM_WIN32(ERROR_BAD_USERNAME);
  609. }
  610. if (!pUser->fEnabled)
  611. return ResultFromScode(S_OK);
  612. //check Approved Sites list
  613. hRes=PICSRulesCheckApprovedSitesAccess(pszURL,&fPassFail);
  614. if (SUCCEEDED(hRes)&&!g_fIsRunningUnderCustom) //the list made a determination, skip if Custom
  615. {
  616. g_fApprovedSitesEnforced=TRUE;
  617. if (fPassFail==PR_PASSFAIL_PASS)
  618. {
  619. return ResultFromScode(S_OK);
  620. }
  621. else
  622. {
  623. return ResultFromScode(S_FALSE);
  624. }
  625. }
  626. CParsedLabelList *pParsed=NULL;
  627. //check PICSRules systems
  628. hRes=PICSRulesCheckAccess(pszURL,pszRatingInfo,&fPassFail,&pParsed);
  629. if (SUCCEEDED(hRes)&&!g_fIsRunningUnderCustom) //the list made a determination, skip if Custom
  630. {
  631. g_fPICSRulesEnforced=TRUE;
  632. if (ppRatingDetails != NULL)
  633. *ppRatingDetails = pParsed;
  634. else
  635. FreeParsedLabelList(pParsed);
  636. if (fPassFail==PR_PASSFAIL_PASS)
  637. {
  638. return ResultFromScode(S_OK);
  639. }
  640. else
  641. {
  642. return ResultFromScode(S_FALSE);
  643. }
  644. }
  645. if (pszRatingInfo == NULL)
  646. {
  647. if (pUser->fAllowUnknowns)
  648. {
  649. hRes = ResultFromScode(S_OK);
  650. }
  651. else
  652. {
  653. hRes = ResultFromScode(S_FALSE);
  654. }
  655. //Site is unrated. Check if user can see unrated sites.
  656. /** Custom **/
  657. // if notification interface exists, put in the URL
  658. if ( ( g_fIsRunningUnderCustom || ( hRes != S_OK ) )
  659. && ( ppRatingDetails != NULL ) )
  660. {
  661. if (!pParsed)
  662. {
  663. pParsed = new CParsedLabelList;
  664. }
  665. if (pParsed)
  666. {
  667. ASSERT(!pParsed->m_pszURL);
  668. pParsed->m_pszURL = new char[strlenf(pszURL) + 1];
  669. if (pParsed->m_pszURL != NULL)
  670. {
  671. strcpyf(pParsed->m_pszURL, pszURL);
  672. }
  673. pParsed->m_fNoRating = TRUE;
  674. *ppRatingDetails = pParsed;
  675. }
  676. }
  677. return hRes;
  678. }
  679. else
  680. {
  681. if (pParsed!=NULL)
  682. {
  683. hRes = S_OK;
  684. }
  685. else
  686. {
  687. hRes = ParseLabelList(pszRatingInfo, &pParsed);
  688. }
  689. }
  690. if (SUCCEEDED(hRes))
  691. {
  692. BOOL fRated = FALSE;
  693. BOOL fDenied = FALSE;
  694. ASSERT(pParsed != NULL);
  695. /** Custom **/
  696. // if notification interface exists, put in the URL
  697. if (g_fIsRunningUnderCustom)
  698. {
  699. ASSERT(!pParsed->m_pszURL);
  700. pParsed->m_pszURL = new char[strlenf(pszURL) + 1];
  701. if (pParsed->m_pszURL != NULL)
  702. {
  703. strcpyf(pParsed->m_pszURL, pszURL);
  704. }
  705. }
  706. DWORD timeCurrent = GetCurrentNetDate();
  707. CParsedServiceInfo *psi = &pParsed->m_ServiceInfo;
  708. while (psi != NULL && !fDenied)
  709. {
  710. UserRatingSystem *pURS = pUser->FindRatingSystem(psi->m_pszServiceName);
  711. if (pURS != NULL && pURS->m_pPRS != NULL)
  712. {
  713. psi->m_fInstalled = TRUE;
  714. UINT cRatings = psi->aRatings.Length();
  715. for (UINT i=0; i<cRatings; i++)
  716. {
  717. CParsedRating *pRating = &psi->aRatings[i];
  718. // YANGXU: 11/17/1999
  719. // Do not check the URL if under Custom mode
  720. // Checking the URL causes inaccuracies
  721. // when a label is returned for an URL on
  722. // a page whose server can have two different
  723. // DNS entries. We can't just not check because
  724. // passing in the URL is part of the published API
  725. if (!g_fIsRunningUnderCustom)
  726. {
  727. if (!pRating->pOptions->CheckURL(pszURL))
  728. {
  729. pParsed->m_pszURL = new char[strlenf(pszURL) + 1];
  730. if (pParsed->m_pszURL != NULL)
  731. {
  732. strcpyf(pParsed->m_pszURL, pszURL);
  733. }
  734. continue; /* this rating has expired or is for
  735. * another URL, ignore it
  736. */
  737. }
  738. }
  739. if (!pRating->pOptions->CheckUntil(timeCurrent))
  740. continue;
  741. UserRating *pUR = pURS->FindRating(pRating->pszTransmitName);
  742. if (pUR != NULL)
  743. {
  744. fRated = TRUE;
  745. pRating->fFound = TRUE;
  746. if ((*pUR).m_pPC!=NULL)
  747. {
  748. if ((pRating->nValue > (*((*pUR).m_pPC)).etnMax.Get())||
  749. (pRating->nValue < (*((*pUR).m_pPC)).etnMin.Get()))
  750. {
  751. g_fInvalid = TRUE;
  752. fDenied = TRUE;
  753. pRating->fFailed = TRUE;
  754. }
  755. }
  756. if (pRating->nValue > pUR->m_nValue)
  757. {
  758. fDenied = TRUE;
  759. pRating->fFailed = TRUE;
  760. }
  761. else
  762. pRating->fFailed = FALSE;
  763. }
  764. else
  765. {
  766. g_fInvalid = TRUE;
  767. fDenied = TRUE;
  768. pRating->fFailed = TRUE;
  769. }
  770. }
  771. }
  772. else
  773. {
  774. psi->m_fInstalled = FALSE;
  775. }
  776. psi = psi->Next();
  777. }
  778. if (!fRated)
  779. {
  780. pParsed->m_fRated = FALSE;
  781. hRes = E_RATING_NOT_FOUND;
  782. }
  783. else
  784. {
  785. pParsed->m_fRated = TRUE;
  786. if (fDenied)
  787. hRes = ResultFromScode(S_FALSE);
  788. }
  789. }
  790. else
  791. {
  792. TraceMsg( TF_WARNING, "RatingCheckUserAccess() - ParseLabelList() Failed with hres=0x%x!", hRes );
  793. // Although the site has invalid PICS rules, the site should still be considered rated.
  794. hRes = ResultFromScode(S_FALSE);
  795. }
  796. StoreRatingDetails( pParsed, ppRatingDetails );
  797. return hRes;
  798. }
  799. //+-----------------------------------------------------------------------
  800. //
  801. // Function: RatingCustomDeleteCrackedData
  802. //
  803. // Synopsis: frees the memory of structure returned by RatingCustomCrackData
  804. //
  805. // Arguments: prbInfo : pointer to RATINGBLOCKINGINFO to be deleted
  806. //
  807. // Returns: S_OK if delete successful, E_FAIL otherwise
  808. //
  809. //------------------------------------------------------------------------
  810. HRESULT RatingCustomDeleteCrackedData(RATINGBLOCKINGINFO* prbInfo)
  811. {
  812. HRESULT hres = E_FAIL;
  813. RATINGBLOCKINGLABELLIST* prblTemp = NULL;
  814. if (NULL != prbInfo)
  815. {
  816. if (prbInfo->pwszDeniedURL)
  817. {
  818. delete [] prbInfo->pwszDeniedURL;
  819. prbInfo->pwszDeniedURL = NULL;
  820. }
  821. if (prbInfo->prbLabelList)
  822. {
  823. for (UINT j = 0; j < prbInfo->cLabels; j++)
  824. {
  825. prblTemp = &prbInfo->prbLabelList[j];
  826. if (prblTemp->pwszRatingSystemName)
  827. {
  828. delete [] prblTemp->pwszRatingSystemName;
  829. prblTemp->pwszRatingSystemName = NULL;
  830. }
  831. if (prblTemp->paRBLS)
  832. {
  833. for (UINT i = 0; i < prblTemp->cBlockingLabels; i++)
  834. {
  835. if (prblTemp->paRBLS[i].pwszCategoryName)
  836. {
  837. delete [] prblTemp->paRBLS[i].pwszCategoryName;
  838. prblTemp->paRBLS[i].pwszCategoryName = NULL;
  839. }
  840. if (prblTemp->paRBLS[i].pwszTransmitName)
  841. {
  842. delete [] prblTemp->paRBLS[i].pwszTransmitName;
  843. prblTemp->paRBLS[i].pwszTransmitName = NULL;
  844. }
  845. if (prblTemp->paRBLS[i].pwszValueName)
  846. {
  847. delete [] prblTemp->paRBLS[i].pwszValueName;
  848. prblTemp->paRBLS[i].pwszValueName = NULL;
  849. }
  850. }
  851. delete [] prblTemp->paRBLS;
  852. prblTemp->paRBLS = NULL;
  853. }
  854. }
  855. delete [] prbInfo->prbLabelList;
  856. prbInfo->prbLabelList = NULL;
  857. }
  858. if (prbInfo->pwszRatingHelperName)
  859. {
  860. delete [] prbInfo->pwszRatingHelperName;
  861. prbInfo->pwszRatingHelperName = NULL;
  862. }
  863. hres = S_OK;
  864. if (prbInfo->pwszRatingHelperReason)
  865. {
  866. delete [] prbInfo->pwszRatingHelperReason;
  867. prbInfo->pwszRatingHelperReason = NULL;
  868. }
  869. delete prbInfo;
  870. prbInfo = NULL;
  871. }
  872. return hres;
  873. }
  874. HRESULT _CrackCategory(CParsedRating *pRating,
  875. RATINGBLOCKINGCATEGORY *pRBLS,
  876. UserRatingSystem* pURS)
  877. {
  878. UserRating *pUR = pURS->FindRating(pRating->pszTransmitName);
  879. if (pUR)
  880. {
  881. //
  882. // Mutated code from InitPleaseDialog, hope it works
  883. //
  884. PicsCategory* pPC = pUR->m_pPC;
  885. if (pPC)
  886. {
  887. pRBLS->nValue = pRating->nValue;
  888. Ansi2Unicode(&pRBLS->pwszTransmitName, pRating->pszTransmitName);
  889. LPCSTR pszCategory = NULL;
  890. if (pPC->etstrName.fIsInit())
  891. {
  892. pszCategory = pPC->etstrName.Get();
  893. }
  894. else if (pPC->etstrDesc.fIsInit())
  895. {
  896. pszCategory = pPC->etstrDesc.Get();
  897. }
  898. else
  899. {
  900. pszCategory = pRating->pszTransmitName;
  901. }
  902. Ansi2Unicode(&pRBLS->pwszCategoryName, pszCategory);
  903. UINT cValues = pPC->arrpPE.Length();
  904. PicsEnum *pPE;
  905. for (UINT iValue=0; iValue < cValues; iValue++)
  906. {
  907. pPE = pPC->arrpPE[iValue];
  908. if (pPE->etnValue.Get() == pRating->nValue)
  909. {
  910. break;
  911. }
  912. }
  913. LPCSTR pszValue = NULL;
  914. if (iValue < cValues)
  915. {
  916. if (pPE->etstrName.fIsInit())
  917. {
  918. pszValue = pPE->etstrName.Get();
  919. }
  920. else if (pPE->etstrDesc.fIsInit())
  921. {
  922. pszValue = pPE->etstrDesc.Get();
  923. }
  924. Ansi2Unicode(&pRBLS->pwszValueName, pszValue);
  925. }
  926. }
  927. }
  928. return S_OK;
  929. }
  930. //+-----------------------------------------------------------------------
  931. //
  932. // Function: RatingCustomCrackData
  933. //
  934. // Synopsis: packages the persistent, opaque data describing why a site
  935. // was denied into readable form
  936. //
  937. // Arguments: pszUsername : name of the user
  938. // pRatingDetails : pointer to the opaque data
  939. // pprbInfo : a RATINGBLOCKINGINFO representation of the data
  940. //
  941. // Returns: Success if data packaged
  942. //
  943. //------------------------------------------------------------------------
  944. HRESULT RatingCustomCrackData(LPCSTR pszUsername, void* pvRatingDetails, RATINGBLOCKINGINFO** pprbInfo) {
  945. if(NULL != *pprbInfo)
  946. {
  947. return E_INVALIDARG;
  948. }
  949. RATINGBLOCKINGINFO* prbInfo = new RATINGBLOCKINGINFO;
  950. CParsedLabelList *pRatingDetails = (CParsedLabelList*)pvRatingDetails;
  951. if (!prbInfo)
  952. {
  953. return E_OUTOFMEMORY;
  954. }
  955. prbInfo->pwszDeniedURL = NULL;
  956. prbInfo->rbSource = RBS_ERROR;
  957. prbInfo->rbMethod = RBM_UNINIT;
  958. prbInfo->cLabels = 0;
  959. prbInfo->prbLabelList = NULL;
  960. prbInfo->pwszRatingHelperName = NULL;
  961. prbInfo->pwszRatingHelperReason = NULL;
  962. RATINGBLOCKINGLABELLIST* prblTemp = NULL;
  963. RATINGBLOCKINGLABELLIST* prblPrev = NULL;
  964. if (!g_fInvalid)
  965. {
  966. if (g_fIsRunningUnderCustom)
  967. {
  968. // pRatingDetails should not be NULL unless
  969. // we ran out of memory
  970. ASSERT(pRatingDetails);
  971. if (pRatingDetails->m_pszURL)
  972. {
  973. Ansi2Unicode(&prbInfo->pwszDeniedURL, pRatingDetails->m_pszURL);
  974. }
  975. if (pRatingDetails->m_fRated)
  976. {
  977. // The page can be rated or denied, but not both
  978. ASSERT(!pRatingDetails->m_fDenied);
  979. ASSERT(!pRatingDetails->m_fNoRating);
  980. prbInfo->rbMethod = RBM_LABEL;
  981. PicsUser* pPU = GetUserObject(pszUsername);
  982. if (pPU)
  983. {
  984. // first find out how many systems there are
  985. UINT cLabels = 0;
  986. CParsedServiceInfo *ppsi = &pRatingDetails->m_ServiceInfo;
  987. while (ppsi)
  988. {
  989. cLabels++;
  990. ppsi = ppsi->Next();
  991. }
  992. // should have at least one label
  993. ASSERT(cLabels > 0);
  994. prbInfo->prbLabelList = new RATINGBLOCKINGLABELLIST[cLabels];
  995. if (prbInfo->prbLabelList)
  996. {
  997. UINT iLabel = 0;
  998. for (ppsi = &pRatingDetails->m_ServiceInfo;ppsi;ppsi = ppsi->Next())
  999. {
  1000. if (!ppsi->m_fInstalled)
  1001. {
  1002. continue;
  1003. }
  1004. UserRatingSystem* pURS = pPU->FindRatingSystem(ppsi->m_pszServiceName);
  1005. if (NULL == pURS || NULL == pURS->m_pPRS)
  1006. {
  1007. continue;
  1008. }
  1009. prblTemp = &(prbInfo->prbLabelList[iLabel]);
  1010. Ansi2Unicode(&prblTemp->pwszRatingSystemName, pURS->m_pPRS->etstrName.Get());
  1011. UINT cRatings = ppsi->aRatings.Length();
  1012. prblTemp->paRBLS = new RATINGBLOCKINGCATEGORY[cRatings];
  1013. if (prblTemp->paRBLS == NULL)
  1014. {
  1015. RatingCustomDeleteCrackedData(prbInfo);
  1016. return E_OUTOFMEMORY;
  1017. } // if (prblTemp->paRBLS == NULL)
  1018. prblTemp->cBlockingLabels = cRatings;
  1019. for (UINT i=0; i < cRatings; i++)
  1020. {
  1021. CParsedRating *pRating = &ppsi->aRatings[i];
  1022. RATINGBLOCKINGCATEGORY* pRBLS = &prblTemp->paRBLS[i];
  1023. _CrackCategory(pRating, pRBLS, pURS);
  1024. } // for (UINT i=0; i < cRatings; i++)
  1025. // at this point, we should have valid ratings for
  1026. // a system
  1027. iLabel++;
  1028. } // for (ppsi = &pRatingDetails->m_ServiceInfo;ppsi;ppsi = ppsi->Next())
  1029. prbInfo->cLabels = iLabel;
  1030. } // if (prbInfo->prbLabelList)
  1031. else
  1032. {
  1033. RatingCustomDeleteCrackedData(prbInfo);
  1034. return E_OUTOFMEMORY;
  1035. }
  1036. if (!pRatingDetails->m_fIsHelper)
  1037. {
  1038. prbInfo->rbSource = RBS_PAGE;
  1039. }
  1040. else
  1041. {
  1042. if (pRatingDetails->m_fIsCustomHelper)
  1043. {
  1044. prbInfo->rbSource = RBS_CUSTOM_RATING_HELPER;
  1045. if (pRatingDetails->m_pszRatingName)
  1046. {
  1047. Ansi2Unicode(&prbInfo->pwszRatingHelperName, pRatingDetails->m_pszRatingName);
  1048. }
  1049. if (pRatingDetails->m_pszRatingReason)
  1050. {
  1051. Ansi2Unicode(&prbInfo->pwszRatingHelperReason, pRatingDetails->m_pszRatingReason);
  1052. }
  1053. }
  1054. else
  1055. {
  1056. prbInfo->rbSource = RBS_RATING_HELPER;
  1057. }
  1058. }
  1059. }
  1060. } // if (pRatingDetails->m_fRated)
  1061. else
  1062. {
  1063. if (pRatingDetails->m_fDenied)
  1064. {
  1065. prbInfo->rbMethod = RBM_DENY;
  1066. if (!pRatingDetails->m_fIsHelper)
  1067. {
  1068. prbInfo->rbSource = RBS_PAGE;
  1069. }
  1070. else
  1071. {
  1072. if (pRatingDetails->m_fIsCustomHelper)
  1073. {
  1074. prbInfo->rbSource = RBS_CUSTOM_RATING_HELPER;
  1075. }
  1076. else
  1077. {
  1078. prbInfo->rbSource = RBS_RATING_HELPER;
  1079. }
  1080. }
  1081. }
  1082. else
  1083. {
  1084. if (pRatingDetails->m_fNoRating)
  1085. {
  1086. prbInfo->rbSource = RBS_NO_RATINGS;
  1087. }
  1088. }
  1089. }
  1090. } // if (g_fIsRunningUnderCustom)
  1091. else
  1092. {
  1093. prbInfo->rbMethod = RBM_ERROR_NOT_IN_CUSTOM_MODE;
  1094. }
  1095. } // (!g_fInvalid)
  1096. *pprbInfo = prbInfo;
  1097. return S_OK;
  1098. }
  1099. HRESULT WINAPI RatingAccessDeniedDialog(HWND hDlg, LPCSTR pszUsername, LPCSTR pszContentDescription, LPVOID pRatingDetails)
  1100. {
  1101. HRESULT hres;
  1102. PleaseDlgData pdd;
  1103. pdd.pszUsername = pszUsername;
  1104. pdd.pPU = GetUserObject(pszUsername);
  1105. if (pdd.pPU == NULL)
  1106. {
  1107. TraceMsg( TF_WARNING, "RatingAccessDeniedDialog() - Username is not valid!" );
  1108. return HRESULT_FROM_WIN32(ERROR_BAD_USERNAME);
  1109. }
  1110. pdd.pszContentDescription = pszContentDescription;
  1111. pdd.pLabelList = (CParsedLabelList *)pRatingDetails;
  1112. pdd.hwndEC = NULL;
  1113. pdd.dwFlags = 0;
  1114. pdd.hwndDlg = NULL;
  1115. pdd.hwndOwner = hDlg;
  1116. pdd.cLabels = 0;
  1117. CPleaseDialog pleaseDialog( &pdd );
  1118. if ( pleaseDialog.DoModal( hDlg ) )
  1119. {
  1120. hres = ResultFromScode(S_OK);
  1121. }
  1122. else
  1123. {
  1124. hres = ResultFromScode(S_FALSE);
  1125. }
  1126. for (UINT i=0; i<pdd.cLabels; i++)
  1127. {
  1128. delete pdd.apLabelStrings[i];
  1129. pdd.apLabelStrings[i] = NULL;
  1130. }
  1131. return hres;
  1132. }
  1133. HRESULT WINAPI RatingAccessDeniedDialog2(HWND hwndParent, LPCSTR pszUsername, LPVOID pRatingDetails)
  1134. {
  1135. PleaseDlgData *ppdd = (PleaseDlgData *)GetProp( hwndParent, szRatingsProp );
  1136. if (ppdd == NULL)
  1137. {
  1138. return RatingAccessDeniedDialog( hwndParent, pszUsername, NULL, pRatingDetails );
  1139. }
  1140. HWND hwndDialog = ppdd->hwndDlg;
  1141. ASSERT( hwndDialog );
  1142. ppdd->pLabelList = (CParsedLabelList *)pRatingDetails;
  1143. SendMessage( hwndDialog, WM_NEWDIALOG, 0, (LPARAM)ppdd );
  1144. // The ppdd is only valid during the RatingAccessDeniedDialog() scope!!
  1145. ppdd = NULL;
  1146. // $REVIEW - Should we use a Windows Hook instead of looping to wait for the
  1147. // modal dialog box to complete?
  1148. // $CLEANUP - Use a CMessageLoop instead.
  1149. // Property is removed once the modal dialog is toasted.
  1150. while ( ::IsWindow( hwndParent ) && ::GetProp( hwndParent, szRatingsProp ) )
  1151. {
  1152. MSG msg;
  1153. if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  1154. {
  1155. if ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
  1156. // && !IsDialogMessage(ppdd->hwndDlg, &msg)) {
  1157. {
  1158. TranslateMessage(&msg);
  1159. DispatchMessage(&msg);
  1160. }
  1161. }
  1162. else
  1163. {
  1164. ::Sleep( 100 ); // Empty message queue means check again in 100 msecs
  1165. }
  1166. }
  1167. DWORD dwFlags;
  1168. dwFlags = ::IsWindow( hwndParent ) ? PtrToUlong( GetProp( hwndParent, szRatingsValue ) ) : PDD_DONE;
  1169. TraceMsg( TF_ALWAYS, "RatingAccessDeniedDialog2() - Message Loop exited with dwFlags=%d", dwFlags );
  1170. return ( dwFlags & PDD_ALLOW ) ? S_OK : S_FALSE;
  1171. }
  1172. HRESULT WINAPI RatingFreeDetails(LPVOID pRatingDetails)
  1173. {
  1174. if (pRatingDetails)
  1175. {
  1176. FreeParsedLabelList((CParsedLabelList *)pRatingDetails);
  1177. }
  1178. return NOERROR;
  1179. }