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.

1229 lines
31 KiB

  1. /****************************************************************************\
  2. *
  3. * MSLUBASE.C --Structures for holding pics information
  4. *
  5. * Created: Jason Thomas
  6. * Updated: Ann McCurdy
  7. *
  8. \****************************************************************************/
  9. /*Includes------------------------------------------------------------------*/
  10. #include "msrating.h"
  11. #include "mslubase.h"
  12. #include "reghive.h" // CRegistryHive
  13. #include "debug.h"
  14. #include <buffer.h>
  15. #include <regentry.h>
  16. #include <mluisupp.h>
  17. /*Helpers-------------------------------------------------------------------*/
  18. char PicsDelimChar='/';
  19. int MyMessageBox(HWND hwnd, LPCSTR pszText, UINT uTitle, UINT uType)
  20. {
  21. CHAR szTitle[MAXPATHLEN];
  22. MLLoadStringA(uTitle, szTitle, sizeof(szTitle));
  23. return MessageBox(hwnd, pszText, szTitle, uType);
  24. }
  25. int MyMessageBox(HWND hwnd, UINT uText, UINT uTitle, UINT uType)
  26. {
  27. CHAR szText[MAXPATHLEN];
  28. MLLoadStringA(uText, szText, sizeof(szText));
  29. return MyMessageBox(hwnd, szText, uTitle, uType);
  30. }
  31. /* Variant for long messages: uText2 message will be concatenated onto the end
  32. * of uText before display. Message text should contain \r\n or other desired
  33. * separators, this function won't add them.
  34. */
  35. int MyMessageBox(HWND hwnd, UINT uText, UINT uText2, UINT uTitle, UINT uType)
  36. {
  37. CHAR szText[MAXPATHLEN*2] = { 0 };
  38. MLLoadStringA(uText, szText, sizeof(szText));
  39. /* Using lstrlen in case MLLoadString really returns a count of CHARACTERS,
  40. * on a DBCS system...
  41. */
  42. UINT cbFirst = lstrlen(szText);
  43. MLLoadStringA(uText2, szText + cbFirst, sizeof(szText) - cbFirst);
  44. return MyMessageBox(hwnd, szText, uTitle, uType);
  45. }
  46. /*******************************************************************
  47. NAME: MyRegDeleteKey
  48. ********************************************************************/
  49. LONG MyRegDeleteKey(HKEY hkey,LPCSTR pszSubkey)
  50. {
  51. DWORD dwError;
  52. TraceMsg( TF_ALWAYS, "MyRegDeleteKey() - Deleting Subkey='%s'...", pszSubkey );
  53. dwError = SHDeleteKey( hkey, pszSubkey );
  54. if ( dwError != ERROR_SUCCESS )
  55. {
  56. TraceMsg( TF_WARNING, "MyRegDeleteKey() - Failed to Delete Subkey='%s' dwError=%d!", pszSubkey, dwError );
  57. }
  58. return dwError;
  59. }
  60. BOOL MyAtoi(char *pIn, int *pi)
  61. {
  62. char *pc;
  63. ASSERT(pIn);
  64. *pi = 0;
  65. pc = NonWhite(pIn);
  66. if (!pc)
  67. return FALSE;
  68. if (*pc < '0' || *pc > '9')
  69. return FALSE;
  70. int accum = 0;
  71. while (*pc >= '0' && *pc <= '9')
  72. {
  73. accum = accum * 10 + (*pc - '0');
  74. pc++;
  75. }
  76. *pi = accum;
  77. return TRUE;
  78. }
  79. /*Simple types--------------------------------------------------------------*/
  80. /* ETN */
  81. #ifdef DEBUG
  82. void ETN::Set(int rIn){
  83. Init();
  84. r = rIn;
  85. }
  86. int ETN::Get(){
  87. return r;
  88. }
  89. #endif
  90. ETN* ETN::Duplicate(){
  91. ETN *pETN=new ETN;
  92. if (fIsInit()) pETN->Set(Get());
  93. return pETN;
  94. }
  95. /* ETB */
  96. #ifdef DEBUG
  97. BOOL ETB::Get()
  98. {
  99. ASSERT(fIsInit());
  100. return m_nFlags & ETB_VALUE;
  101. }
  102. void ETB::Set(BOOL b)
  103. {
  104. m_nFlags = ETB_ISINIT | (b ? ETB_VALUE : 0);
  105. }
  106. #endif
  107. ETB* ETB::Duplicate()
  108. {
  109. ASSERT(fIsInit());
  110. ETB *pETB = new ETB;
  111. if (pETB != NULL)
  112. pETB->m_nFlags = m_nFlags;
  113. return pETB;
  114. }
  115. /* ETS */
  116. ETS::~ETS()
  117. {
  118. if (pc != NULL) {
  119. delete pc;
  120. pc = NULL;
  121. }
  122. }
  123. #ifdef DEBUG
  124. char* ETS::Get()
  125. {
  126. // ASSERT(fIsInit());
  127. return pc;
  128. }
  129. #endif
  130. void ETS::Set(const char *pIn)
  131. {
  132. if (pc != NULL)
  133. delete pc;
  134. if (pIn != NULL) {
  135. pc = new char[strlenf(pIn) + 1];
  136. if (pc != NULL) {
  137. strcpyf(pc, pIn);
  138. }
  139. }
  140. else {
  141. pc = NULL;
  142. }
  143. }
  144. void ETS::SetTo(char *pIn)
  145. {
  146. if (pc != NULL)
  147. delete pc;
  148. pc = pIn;
  149. }
  150. ETS* ETS::Duplicate()
  151. {
  152. ETS *pETS=new ETS;
  153. if (pETS != NULL)
  154. pETS->Set(Get());
  155. return pETS;
  156. }
  157. UINT EtBoolRegRead(ETB &etb, HKEY hKey, char *pKeyWord)
  158. {
  159. ASSERT(pKeyWord);
  160. if ( ! pKeyWord )
  161. {
  162. TraceMsg( TF_ERROR, "EtBoolRegRead() - pKeyWord is NULL!" );
  163. return ERROR_INVALID_PARAMETER;
  164. }
  165. DWORD dwSize, dwValue, dwType;
  166. UINT uErr;
  167. etb.Set(FALSE);
  168. dwSize = sizeof(dwValue);
  169. uErr = RegQueryValueEx(hKey, pKeyWord, NULL, &dwType,
  170. (LPBYTE)&dwValue, &dwSize);
  171. if (uErr == ERROR_SUCCESS)
  172. {
  173. if ((dwType == REG_DWORD) && (dwValue != 0))
  174. etb.Set(TRUE);
  175. }
  176. else
  177. {
  178. TraceMsg( TF_WARNING, "EtBoolRegRead() - Failed to read pKeyWord='%s'!", pKeyWord );
  179. }
  180. return uErr;
  181. }
  182. UINT EtBoolRegWrite(ETB &etb, HKEY hKey, char *pKeyWord)
  183. {
  184. ASSERT(pKeyWord);
  185. if ( ! pKeyWord )
  186. {
  187. TraceMsg( TF_ERROR, "EtBoolRegWrite() - pKeyWord is NULL!" );
  188. return ERROR_INVALID_PARAMETER;
  189. }
  190. UINT uErr;
  191. DWORD dwNum = (etb.fIsInit() && etb.Get());
  192. uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_DWORD, (LPBYTE)&dwNum, sizeof(dwNum));
  193. if ( uErr != ERROR_SUCCESS )
  194. {
  195. TraceMsg( TF_WARNING, "EtBoolRegWrite() - Failed to set pKeyWord='%s'!", pKeyWord );
  196. }
  197. return uErr;
  198. }
  199. UINT EtStringRegRead(ETS &ets, HKEY hKey, char *pKeyWord)
  200. {
  201. ASSERT(pKeyWord);
  202. if ( ! pKeyWord )
  203. {
  204. TraceMsg( TF_ERROR, "EtStringRegRead() - pKeyWord is NULL!" );
  205. return ERROR_INVALID_PARAMETER;
  206. }
  207. DWORD dwSize;
  208. UINT uErr;
  209. char szTemp[80]; /* default size */
  210. dwSize = sizeof(szTemp);
  211. uErr = RegQueryValueEx(hKey, pKeyWord, NULL, NULL,
  212. (LPBYTE)szTemp, &dwSize);
  213. if (uErr == ERROR_SUCCESS)
  214. {
  215. ets.Set(szTemp);
  216. }
  217. else if (uErr == ERROR_MORE_DATA)
  218. {
  219. char *pszTemp = new char[dwSize];
  220. if (pszTemp == NULL)
  221. {
  222. TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to allocate dwSize=%d memory!", dwSize );
  223. uErr = ERROR_NOT_ENOUGH_MEMORY;
  224. }
  225. else
  226. {
  227. uErr = RegQueryValueEx(hKey, pKeyWord, NULL, NULL, (LPBYTE)pszTemp,
  228. &dwSize);
  229. if (uErr == ERROR_SUCCESS)
  230. {
  231. ets.SetTo(pszTemp);
  232. /* ets now owns pszTemp memory, don't delete it here */
  233. }
  234. else
  235. {
  236. TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to read (dwSize %d) pKeyWord='%s'!", dwSize, pKeyWord );
  237. delete pszTemp;
  238. pszTemp = NULL;
  239. }
  240. }
  241. }
  242. else
  243. {
  244. TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to read pKeyWord='%s'!", pKeyWord );
  245. }
  246. return uErr;
  247. }
  248. UINT EtStringRegWrite(ETS &ets, HKEY hKey, char *pKeyWord)
  249. {
  250. ASSERT(pKeyWord);
  251. if ( ! pKeyWord )
  252. {
  253. TraceMsg( TF_ERROR, "EtStringRegWrite() - pKeyWord is NULL!" );
  254. return ERROR_INVALID_PARAMETER;
  255. }
  256. UINT uErr = ERROR_SUCCESS;
  257. if (ets.fIsInit())
  258. {
  259. uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_SZ, (LPBYTE)ets.Get(), strlenf(ets.Get())+1);
  260. if ( uErr != ERROR_SUCCESS )
  261. {
  262. TraceMsg( TF_WARNING, "EtStringRegWrite() - Failed to set pKeyWord='%s' with ets='%s'!", pKeyWord, ets.Get() );
  263. }
  264. }
  265. else
  266. {
  267. TraceMsg( TF_ERROR, "EtStringRegWrite() - ETS is not initialized!" );
  268. }
  269. return uErr;
  270. }
  271. UINT EtNumRegRead(ETN &etn, HKEY hKey, char *pKeyWord)
  272. {
  273. ASSERT(pKeyWord);
  274. if ( ! pKeyWord )
  275. {
  276. TraceMsg( TF_ERROR, "EtNumRegRead() - pKeyWord is NULL!" );
  277. return ERROR_INVALID_PARAMETER;
  278. }
  279. DWORD dwSize, dwType;
  280. int nValue;
  281. UINT uErr;
  282. dwSize = sizeof(nValue);
  283. uErr = RegQueryValueEx(hKey, pKeyWord, NULL, &dwType,
  284. (LPBYTE)&nValue, &dwSize);
  285. if (uErr == ERROR_SUCCESS)
  286. {
  287. etn.Set(nValue);
  288. }
  289. else
  290. {
  291. TraceMsg( TF_WARNING, "EtNumRegRead() - Failed to read pKeyWord='%s'!", pKeyWord );
  292. }
  293. return uErr;
  294. }
  295. UINT EtNumRegWrite(ETN &etn, HKEY hKey, char *pKeyWord)
  296. {
  297. UINT uErr = ERROR_SUCCESS;
  298. if (etn.fIsInit())
  299. {
  300. int nTemp;
  301. nTemp = etn.Get();
  302. uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_DWORD, (LPBYTE)&nTemp, sizeof(nTemp));
  303. if ( uErr != ERROR_SUCCESS )
  304. {
  305. TraceMsg( TF_WARNING, "EtNumRegWrite() - Failed to set pKeyWord='%s' with nTemp=%d!", pKeyWord, nTemp );
  306. }
  307. }
  308. else
  309. {
  310. TraceMsg( TF_ERROR, "EtNumRegWrite() - ETS is not initialized!" );
  311. }
  312. return uErr;
  313. }
  314. /*PicsDefault---------------------------------------------------------------*/
  315. PicsDefault::PicsDefault()
  316. {
  317. /* nothing to do but construct members */
  318. }
  319. PicsDefault::~PicsDefault()
  320. {
  321. /* nothing to do but destruct members */
  322. }
  323. /*PicsEnum------------------------------------------------------------------*/
  324. PicsEnum::PicsEnum()
  325. {
  326. /* nothing to do but construct members */
  327. }
  328. PicsEnum::~PicsEnum()
  329. {
  330. /* nothing to do but destruct members */
  331. }
  332. /*PicsCategory--------------------------------------------------------------*/
  333. PicsCategory::PicsCategory()
  334. {
  335. /* nothing to do but construct members */
  336. }
  337. PicsCategory::~PicsCategory()
  338. {
  339. arrpPC.DeleteAll();
  340. arrpPE.DeleteAll();
  341. }
  342. /*PicsRatingSystem----------------------------------------------------------*/
  343. PicsRatingSystem::PicsRatingSystem()
  344. : m_pDefaultOptions(NULL),
  345. dwFlags(0),
  346. nErrLine(0)
  347. {
  348. /* nothing to do but construct members */
  349. }
  350. PicsRatingSystem::~PicsRatingSystem()
  351. {
  352. arrpPC.DeleteAll();
  353. if (m_pDefaultOptions != NULL)
  354. {
  355. delete m_pDefaultOptions;
  356. m_pDefaultOptions = NULL;
  357. }
  358. }
  359. void PicsRatingSystem::ReportError(HRESULT hres)
  360. {
  361. NLS_STR nls1(etstrFile.Get());
  362. if (!nls1.QueryError())
  363. {
  364. ISTR istrMarker(nls1);
  365. if (nls1.strchr(&istrMarker, '*'))
  366. {
  367. nls1.DelSubStr(istrMarker);
  368. }
  369. }
  370. else
  371. {
  372. nls1 = szNULL;
  373. }
  374. UINT idMsg, idTemplate;
  375. NLS_STR nlsBaseMessage(MAX_RES_STR_LEN);
  376. char szNumber[16]; /* big enough for a 32-bit (hex) number */
  377. if (hres == E_OUTOFMEMORY || (hres > RAT_E_BASE && hres <= RAT_E_BASE + 0xffff)) {
  378. idTemplate = IDS_LOADRAT_SYNTAX_TEMPLATE; /* default is ratfile content error */
  379. switch (hres)
  380. {
  381. case E_OUTOFMEMORY:
  382. idMsg = IDS_LOADRAT_MEMORY;
  383. idTemplate = IDS_LOADRAT_GENERIC_TEMPLATE;
  384. break;
  385. case RAT_E_EXPECTEDLEFT:
  386. idMsg = IDS_LOADRAT_EXPECTEDLEFT;
  387. break;
  388. case RAT_E_EXPECTEDRIGHT:
  389. idMsg = IDS_LOADRAT_EXPECTEDRIGHT;
  390. break;
  391. case RAT_E_EXPECTEDTOKEN:
  392. idMsg = IDS_LOADRAT_EXPECTEDTOKEN;
  393. break;
  394. case RAT_E_EXPECTEDSTRING:
  395. idMsg = IDS_LOADRAT_EXPECTEDSTRING;
  396. break;
  397. case RAT_E_EXPECTEDNUMBER:
  398. idMsg = IDS_LOADRAT_EXPECTEDNUMBER;
  399. break;
  400. case RAT_E_EXPECTEDBOOL:
  401. idMsg = IDS_LOADRAT_EXPECTEDBOOL;
  402. break;
  403. case RAT_E_DUPLICATEITEM:
  404. idMsg = IDS_LOADRAT_DUPLICATEITEM;
  405. break;
  406. case RAT_E_MISSINGITEM:
  407. idMsg = IDS_LOADRAT_MISSINGITEM;
  408. break;
  409. case RAT_E_UNKNOWNITEM:
  410. idMsg = IDS_LOADRAT_UNKNOWNITEM;
  411. break;
  412. case RAT_E_UNKNOWNMANDATORY:
  413. idMsg = IDS_LOADRAT_UNKNOWNMANDATORY;
  414. break;
  415. case RAT_E_EXPECTEDEND:
  416. idMsg = IDS_LOADRAT_EXPECTEDEND;
  417. break;
  418. default:
  419. ASSERT(FALSE); /* there aren't any other RAT_E_ errors */
  420. idMsg = IDS_LOADRAT_UNKNOWNERROR;
  421. break;
  422. }
  423. wsprintf(szNumber, "%d", nErrLine);
  424. NLS_STR nlsNumber(STR_OWNERALLOC, szNumber);
  425. const NLS_STR *apnls[] = { &nlsNumber, NULL };
  426. nlsBaseMessage.LoadString((USHORT)idMsg, apnls);
  427. }
  428. else
  429. {
  430. idTemplate = IDS_LOADRAT_GENERIC_TEMPLATE;
  431. if (HRESULT_FACILITY(hres) == FACILITY_WIN32)
  432. {
  433. wsprintf(szNumber, "%d", HRESULT_CODE(hres));
  434. idMsg = IDS_LOADRAT_WINERROR;
  435. }
  436. else
  437. {
  438. wsprintf(szNumber, "0x%x", hres);
  439. idMsg = IDS_LOADRAT_MISCERROR;
  440. }
  441. NLS_STR nls1(STR_OWNERALLOC, szNumber);
  442. const NLS_STR *apnls[] = { &nls1, NULL };
  443. nlsBaseMessage.LoadString((USHORT)idMsg, apnls);
  444. }
  445. NLS_STR nlsMessage(MAX_RES_STR_LEN);
  446. const NLS_STR *apnls[] = { &nls1, &nlsBaseMessage, NULL };
  447. nlsMessage.LoadString((USHORT)idTemplate, apnls);
  448. if (!nlsMessage.QueryError())
  449. {
  450. MyMessageBox(NULL, nlsMessage.QueryPch(), IDS_GENERIC, MB_OK | MB_ICONWARNING);
  451. }
  452. }
  453. /*Rating Information--------------------------------------------------------*/
  454. BOOL PicsRatingSystemInfo::LoadProviderFiles(HKEY hKey)
  455. {
  456. char szFileName[8 + 7 + 1]; /* "Filename" + big number plus null byte */
  457. ETS etstrFileName;
  458. int index = 0;
  459. EtStringRegRead(etstrRatingBureau, hKey, (char *)szRATINGBUREAU);
  460. wsprintf(szFileName, szFilenameTemplate, index);
  461. while (EtStringRegRead(etstrFileName, hKey, szFileName) == ERROR_SUCCESS)
  462. {
  463. PicsRatingSystem *pPRS;
  464. HRESULT hres = LoadRatingSystem(etstrFileName.Get(), &pPRS);
  465. if (pPRS != NULL)
  466. {
  467. arrpPRS.Append(pPRS);
  468. /* If the thing has a pathname, write it back out to the policy
  469. * file, in case loading the rating system marked it as invalid
  470. * (or it had been marked as invalid, but the user fixed things
  471. * and it's OK now).
  472. */
  473. if (pPRS->etstrFile.fIsInit())
  474. {
  475. /* If the rating system is not valid and was not previously
  476. * marked invalid, then report the error to the user.
  477. * LoadRatingSystem will have already marked the filename
  478. * as invalid for us.
  479. */
  480. if ((pPRS->dwFlags & (PRS_ISVALID | PRS_WASINVALID)) == 0)
  481. {
  482. pPRS->ReportError(hres); /* report error to user */
  483. }
  484. EtStringRegWrite(pPRS->etstrFile, hKey, szFileName);
  485. }
  486. }
  487. index++;
  488. wsprintf(szFileName, szFilenameTemplate, index);
  489. }
  490. return arrpPRS.Length() != 0;
  491. }
  492. BOOL RunningOnNT()
  493. {
  494. return !(::GetVersion() & 0x80000000);
  495. }
  496. // Verify the Registry Key for the Ratings can be opened with full access.
  497. // This is only useful if the Ratings registry key has been previously created.
  498. bool IsRegistryModifiable( HWND p_hwndParent )
  499. {
  500. bool fReturn = false;
  501. CRegKey regKey;
  502. if ( regKey.Open( HKEY_LOCAL_MACHINE, ::szRATINGS, KEY_ALL_ACCESS ) == ERROR_SUCCESS )
  503. {
  504. fReturn = true;
  505. }
  506. else
  507. {
  508. TraceMsg( TF_WARNING, "IsRegistryModifiable() - Failed to Create Registry Key Ratings for Full Access!" );
  509. MyMessageBox( p_hwndParent, IDS_REGISTRY_NOT_MODIFIABLE, IDS_GENERIC, MB_OK|MB_ICONERROR);
  510. }
  511. return fReturn;
  512. }
  513. SID_IDENTIFIER_AUTHORITY siaNTAuthority = SECURITY_NT_AUTHORITY;
  514. SID_IDENTIFIER_AUTHORITY siaWorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
  515. class CSecurityAttributes
  516. {
  517. private:
  518. SECURITY_ATTRIBUTES m_sa;
  519. LPSECURITY_ATTRIBUTES m_lpsa;
  520. PSECURITY_DESCRIPTOR m_psd;
  521. PACL m_pACL;
  522. PSID m_psidAdmins;
  523. PSID m_psidWorld;
  524. UINT m_cbACL; /* default ACL size */
  525. public:
  526. CSecurityAttributes()
  527. {
  528. m_lpsa = NULL;
  529. m_psd = NULL;
  530. m_pACL = NULL;
  531. m_psidAdmins = NULL;
  532. m_psidWorld = NULL;
  533. m_cbACL = 1024;
  534. }
  535. ~CSecurityAttributes()
  536. {
  537. if ( m_psidAdmins != NULL )
  538. {
  539. FreeSid(m_psidAdmins);
  540. m_psidAdmins = NULL;
  541. }
  542. if ( m_psidWorld )
  543. {
  544. FreeSid(m_psidWorld);
  545. m_psidWorld = NULL;
  546. }
  547. if ( m_psd )
  548. {
  549. MemFree(m_psd);
  550. m_psd = NULL;
  551. }
  552. if ( m_pACL )
  553. {
  554. MemFree(m_pACL);
  555. m_pACL = NULL;
  556. }
  557. }
  558. LPSECURITY_ATTRIBUTES GetSecurityAttributes( void )
  559. {
  560. return m_lpsa;
  561. }
  562. bool AllocateSecurityAttributes( void )
  563. {
  564. m_psd = (PSECURITY_DESCRIPTOR)MemAlloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
  565. if (m_psd == NULL ||
  566. !InitializeSecurityDescriptor(m_psd, SECURITY_DESCRIPTOR_REVISION))
  567. {
  568. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Security Descriptor Allocation!" );
  569. return false;
  570. }
  571. m_pACL = (PACL)MemAlloc(m_cbACL);
  572. if (m_pACL == NULL || !InitializeAcl(m_pACL, m_cbACL, ACL_REVISION2))
  573. {
  574. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed ACL Initialization!" );
  575. return false;
  576. }
  577. if (!AllocateAndInitializeSid(&siaNTAuthority,
  578. 2, /* number of subauthorities */
  579. SECURITY_BUILTIN_DOMAIN_RID, /* first subauthority: this domain */
  580. DOMAIN_ALIAS_RID_ADMINS, /* second: admins local group */
  581. 0, 0, 0, 0, 0, 0, /* unused subauthorities */
  582. &m_psidAdmins))
  583. {
  584. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed NT Authority Initialization!" );
  585. return false;
  586. }
  587. if (!AllocateAndInitializeSid(&siaWorldAuthority,
  588. 1, /* number of subauthorities */
  589. SECURITY_WORLD_RID, /* first subauthority: all users */
  590. 0, 0, 0, 0, 0, 0, 0, /* unused subauthorities */
  591. &m_psidWorld))
  592. {
  593. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed World Authority Initialization!" );
  594. return false;
  595. }
  596. if (!AddAccessAllowedAce(m_pACL, ACL_REVISION2, KEY_ALL_ACCESS, m_psidAdmins) ||
  597. !AddAccessAllowedAce(m_pACL, ACL_REVISION2, KEY_READ, m_psidWorld))
  598. {
  599. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Admins or World Access!" );
  600. return false;
  601. }
  602. ACE_HEADER *pAce;
  603. /* Make both ACEs inherited by subkeys created later */
  604. if (GetAce(m_pACL, 0, (LPVOID *)&pAce))
  605. {
  606. pAce->AceFlags |= CONTAINER_INHERIT_ACE;
  607. }
  608. if (GetAce(m_pACL, 1, (LPVOID *)&pAce))
  609. {
  610. pAce->AceFlags |= CONTAINER_INHERIT_ACE;
  611. }
  612. if (!SetSecurityDescriptorDacl(m_psd,
  613. TRUE, /* fDaclPresent */
  614. m_pACL,
  615. FALSE)) /* not a default discretionary ACL */
  616. {
  617. TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Set of Security Descriptor!" );
  618. return false;
  619. }
  620. m_sa.nLength = sizeof(m_sa);
  621. m_sa.lpSecurityDescriptor = m_psd;
  622. m_sa.bInheritHandle = FALSE;
  623. m_lpsa = &m_sa;
  624. return true;
  625. }
  626. };
  627. // The following first attempts to open an existing registry key.
  628. // If the key cannot be opened, the key is created.
  629. // Under NT, the key is created with Admin read-write access and World read-only access.
  630. // Under 9x, the key is created with no special security attributes.
  631. HKEY CreateRegKeyNT(LPCSTR pszKey)
  632. {
  633. HKEY hKey = NULL;
  634. LONG err = RegOpenKey(HKEY_LOCAL_MACHINE, pszKey, &hKey);
  635. if (err == ERROR_SUCCESS)
  636. {
  637. TraceMsg( TF_ALWAYS, "CreateRegKeyNT() - Successfully Opened Ratings Registry Key." );
  638. return hKey;
  639. }
  640. CSecurityAttributes sa;
  641. if (RunningOnNT())
  642. {
  643. if ( ! sa.AllocateSecurityAttributes() )
  644. {
  645. TraceMsg( TF_ERROR, "CreateRegKeyNT() - Failed to allocate security attributes()!" );
  646. return NULL;
  647. }
  648. }
  649. DWORD dwDisp;
  650. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, pszKey, NULL, "",
  651. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, sa.GetSecurityAttributes(),
  652. &hKey, &dwDisp) != ERROR_SUCCESS)
  653. {
  654. TraceMsg( TF_ERROR, "CreateRegKeyNT() - Failed Registry Key Creation with %s Security Attributes!", sa.GetSecurityAttributes() ? "<sa>" : "<NULL>" );
  655. hKey = NULL;
  656. }
  657. return hKey;
  658. }
  659. HKEY PicsRatingSystemInfo::GetUserProfileKey( void )
  660. {
  661. HKEY hkeyUser = NULL;
  662. // HKLM\System\CurrentControlSet\Control\Update
  663. RegEntry re(szPOLICYKEY, HKEY_LOCAL_MACHINE);
  664. // UpdateMode
  665. if (re.GetNumber(szPOLICYVALUE) != 0)
  666. {
  667. // HKLM\Network\Logon
  668. RegEntry reLogon(szLogonKey, HKEY_LOCAL_MACHINE);
  669. // UserProfiles
  670. if (reLogon.GetNumber(szUserProfiles) != 0)
  671. {
  672. /* The ratings key has the supervisor password and maybe other
  673. * settings. To see if there are other settings here, try to
  674. * find the user subkey (".Default"). If it's not there, we'll
  675. * try a policy file.
  676. */
  677. // HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Ratings
  678. if (RegOpenKey(HKEY_LOCAL_MACHINE, szRATINGS, &hkeyUser) == ERROR_SUCCESS)
  679. {
  680. HKEY hkeyTemp;
  681. // .Default
  682. if (RegOpenKey(hkeyUser, szDefaultUserName, &hkeyTemp) == ERROR_SUCCESS)
  683. {
  684. RegCloseKey(hkeyTemp);
  685. hkeyTemp = NULL;
  686. }
  687. else
  688. {
  689. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - Failed to Open key szDefaultUserName='%s'!", szDefaultUserName );
  690. RegCloseKey(hkeyUser);
  691. hkeyUser = NULL;
  692. }
  693. }
  694. else
  695. {
  696. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - Failed to Open key szRATINGS='%s'!", szRATINGS );
  697. }
  698. }
  699. else
  700. {
  701. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - No key szLogonKey='%s' szUserProfiles='%s'!", szLogonKey, szUserProfiles );
  702. }
  703. }
  704. else
  705. {
  706. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - No key szPOLICYKEY='%s' szPOLICYVALUE='%s'!", szPOLICYKEY, szPOLICYVALUE );
  707. }
  708. return hkeyUser;
  709. }
  710. BOOL PicsRatingSystemInfo::Init( void )
  711. {
  712. PicsUser *pPU = NULL;
  713. BOOL fRet = TRUE;
  714. BOOL fIsNT;
  715. HKEY hkeyUser = NULL;
  716. CRegistryHive rh;
  717. fRatingInstalled = FALSE;
  718. pUserObject = NULL;
  719. fIsNT = RunningOnNT();
  720. if (fIsNT)
  721. {
  722. hkeyUser = CreateRegKeyNT(::szRATINGS);
  723. fStoreInRegistry = TRUE;
  724. }
  725. else
  726. {
  727. hkeyUser = GetUserProfileKey();
  728. if (hkeyUser != NULL)
  729. {
  730. fStoreInRegistry = TRUE;
  731. }
  732. else
  733. {
  734. fStoreInRegistry = FALSE;
  735. if ( rh.OpenHiveFile( false ) )
  736. {
  737. hkeyUser = rh.GetHiveKey();
  738. }
  739. }
  740. }
  741. // read information from whatever key we opened
  742. if (hkeyUser != NULL)
  743. {
  744. //First load the rating files, then load the user names.
  745. fRatingInstalled = LoadProviderFiles(hkeyUser);
  746. if ( fRatingInstalled )
  747. {
  748. TraceMsg( TF_ALWAYS, "PicsRatingSystemInfo::Init() - Ratings Installed!" );
  749. }
  750. else
  751. {
  752. TraceMsg( TF_ALWAYS, "PicsRatingSystemInfo::Init() - Ratings Not Installed!" );
  753. }
  754. pPU = new PicsUser;
  755. if (pPU != NULL)
  756. {
  757. pPU->ReadFromRegistry(hkeyUser, (char *)szDefaultUserName);
  758. pUserObject = pPU;
  759. }
  760. else
  761. {
  762. fRet = FALSE;
  763. }
  764. RegCloseKey(hkeyUser);
  765. hkeyUser = NULL;
  766. /* Make sure the user settings have defaults for all installed
  767. * rating systems.
  768. */
  769. for (int i=0; i<arrpPRS.Length(); i++)
  770. {
  771. CheckUserSettings(arrpPRS[i]);
  772. }
  773. }
  774. else
  775. {
  776. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::Init() - hkeyUser is NULL!" );
  777. }
  778. rh.UnloadHive();
  779. /* Check to see if there is a supervisor password set. If there is,
  780. * but we have no settings, then someone's been tampering.
  781. */
  782. if ( SUCCEEDED( VerifySupervisorPassword() ) && ! fRatingInstalled )
  783. {
  784. MyMessageBox(NULL, IDS_NO_SETTINGS, IDS_GENERIC, MB_OK | MB_ICONSTOP);
  785. // Clear out the password to allow the user to modify the ratings.
  786. RemoveSupervisorPassword();
  787. fSettingsValid = FALSE;
  788. }
  789. else
  790. {
  791. fSettingsValid = TRUE;
  792. }
  793. return fRet;
  794. }
  795. BOOL PicsRatingSystemInfo::FreshInstall()
  796. {
  797. PicsUser *pPU = NULL;
  798. pPU = new PicsUser;
  799. if (pPU != NULL)
  800. {
  801. pPU->NewInstall();
  802. pUserObject = pPU;
  803. fRatingInstalled = TRUE; // we have settings now
  804. return TRUE;
  805. }
  806. else
  807. {
  808. return FALSE;
  809. }
  810. }
  811. extern HANDLE g_hsemStateCounter; // created at process attatch time
  812. long GetStateCounter()
  813. {
  814. long count;
  815. if (ReleaseSemaphore(g_hsemStateCounter, 1, &count)) // poll and bump the count
  816. {
  817. WaitForSingleObject(g_hsemStateCounter, 0); // reduce the count
  818. }
  819. else
  820. {
  821. count = -1;
  822. }
  823. return count;
  824. }
  825. void BumpStateCounter()
  826. {
  827. ReleaseSemaphore(g_hsemStateCounter, 1, NULL); // bump the count
  828. }
  829. // check the global semaphore count to see if we need to reconstruct our
  830. // state.
  831. void CheckGlobalInfoRev(void)
  832. {
  833. ENTERCRITICAL;
  834. if (gPRSI != NULL && !g_fIsRunningUnderCustom)
  835. { // do not reinit if under Custom
  836. if (gPRSI->nInfoRev != GetStateCounter())
  837. {
  838. delete gPRSI;
  839. gPRSI = new PicsRatingSystemInfo;
  840. if (gPRSI != NULL)
  841. {
  842. gPRSI->Init();
  843. }
  844. CleanupRatingHelpers();
  845. InitRatingHelpers();
  846. }
  847. }
  848. LEAVECRITICAL;
  849. }
  850. void PicsRatingSystemInfo::SaveRatingSystemInfo()
  851. {
  852. int z;
  853. HKEY hkeyUser = NULL;
  854. CRegistryHive rh;
  855. char szFileName[MAXPATHLEN];
  856. if (!fSettingsValid || !fRatingInstalled)
  857. {
  858. TraceMsg( TF_WARNING, "PicsRatingSystemInfo::SaveRatingSystemInfo() - Ratings are not installed!" );
  859. return; /* ratings aren't installed, nothing to save */
  860. }
  861. // load the hive file
  862. if (fStoreInRegistry)
  863. {
  864. hkeyUser = CreateRegKeyNT(::szRATINGS);
  865. }
  866. else
  867. {
  868. if ( rh.OpenHiveFile( true ) )
  869. {
  870. hkeyUser = rh.GetHiveKey();
  871. }
  872. }
  873. // read information from local registry
  874. if (hkeyUser != NULL)
  875. {
  876. if (etstrRatingBureau.fIsInit())
  877. {
  878. EtStringRegWrite(etstrRatingBureau, hkeyUser, (char *)szRATINGBUREAU);
  879. }
  880. else
  881. {
  882. RegDeleteValue(hkeyUser, szRATINGBUREAU);
  883. }
  884. for (z = 0; z < arrpPRS.Length(); ++z)
  885. {
  886. wsprintf(szFileName, szFilenameTemplate, z);
  887. EtStringRegWrite(arrpPRS[z]->etstrFile, hkeyUser, szFileName);
  888. }
  889. // Delete the next one, as a safety precaution
  890. wsprintf(szFileName, szFilenameTemplate, z);
  891. RegDeleteValue(hkeyUser, szFileName);
  892. pUserObject->WriteToRegistry(hkeyUser);
  893. RegCloseKey(hkeyUser);
  894. hkeyUser = NULL;
  895. }
  896. else
  897. {
  898. TraceMsg( TF_ERROR, "PicsRatingSystemInfo::SaveRatingSystemInfo() - hkeyUser is NULL!" );
  899. }
  900. BumpStateCounter();
  901. nInfoRev = GetStateCounter();
  902. }
  903. HRESULT LoadRatingSystem(LPCSTR pszFilename, PicsRatingSystem **pprsOut)
  904. {
  905. TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Loading Rating System '%s'...", pszFilename );
  906. PicsRatingSystem *pPRS = new PicsRatingSystem;
  907. *pprsOut = pPRS;
  908. if (pPRS == NULL)
  909. {
  910. TraceMsg( TF_ERROR, "LoadRatingSystem() - pPRS is NULL!" );
  911. return E_OUTOFMEMORY;
  912. }
  913. UINT cbFilename = strlenf(pszFilename) + 1 + 1; /* room for marker character */
  914. LPSTR pszNameCopy = new char[cbFilename];
  915. if (pszNameCopy == NULL)
  916. {
  917. TraceMsg( TF_ERROR, "LoadRatingSystem() - pszNameCopy is NULL!" );
  918. return E_OUTOFMEMORY;
  919. }
  920. strcpyf(pszNameCopy, pszFilename);
  921. pPRS->etstrFile.SetTo(pszNameCopy);
  922. LPSTR pszMarker = strchrf(pszNameCopy, '*');
  923. if (pszMarker != NULL) { /* ended in marker character... */
  924. ASSERT(*(pszMarker+1) == '\0');
  925. pPRS->dwFlags |= PRS_WASINVALID; /* means it failed last time */
  926. *pszMarker = '\0'; /* strip marker for loading */
  927. }
  928. HRESULT hres;
  929. HANDLE hFile = CreateFile(pszNameCopy, GENERIC_READ,
  930. FILE_SHARE_READ, NULL, OPEN_EXISTING,
  931. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  932. NULL);
  933. if (hFile != INVALID_HANDLE_VALUE)
  934. {
  935. DWORD cbFile = ::GetFileSize(hFile, NULL);
  936. BUFFER bufData(cbFile + 1);
  937. if (bufData.QueryPtr() != NULL)
  938. {
  939. LPSTR pszData = (LPSTR)bufData.QueryPtr();
  940. DWORD cbRead;
  941. if (ReadFile(hFile, pszData, cbFile, &cbRead, NULL))
  942. {
  943. pszData[cbRead] = '\0'; /* null terminate whole file */
  944. hres = pPRS->Parse(pszFilename, pszData);
  945. if (SUCCEEDED(hres))
  946. {
  947. pPRS->dwFlags |= PRS_ISVALID;
  948. }
  949. else
  950. {
  951. TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed Parse with hres=0x%x!", hres );
  952. }
  953. }
  954. else
  955. {
  956. hres = HRESULT_FROM_WIN32(::GetLastError());
  957. TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed ReadFile() with hres=0x%x!", hres );
  958. }
  959. CloseHandle(hFile);
  960. }
  961. else
  962. {
  963. hres = E_OUTOFMEMORY;
  964. TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed Buffer Allocation with cbFile=%d!", cbFile );
  965. }
  966. }
  967. else
  968. {
  969. hres = HRESULT_FROM_WIN32(::GetLastError());
  970. TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed CreateFile() with hres=0x%x!", hres );
  971. }
  972. if (!(pPRS->dwFlags & PRS_ISVALID))
  973. {
  974. TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Failed Loaded Rating System '%s' (hres=0x%x)!", pszFilename, hres );
  975. strcatf(pszNameCopy, "*"); /* mark filename as invalid */
  976. }
  977. else
  978. {
  979. TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Successfully Loaded Rating System '%s'.", pszFilename );
  980. }
  981. return hres;
  982. }
  983. // constructor for CustomRatingHelper
  984. CustomRatingHelper::CustomRatingHelper()
  985. {
  986. hLibrary = NULL;
  987. pNextHelper = NULL;
  988. dwSort = 0;
  989. }
  990. CustomRatingHelper::~CustomRatingHelper()
  991. {
  992. if (hLibrary)
  993. {
  994. FreeLibrary(hLibrary);
  995. hLibrary = NULL;
  996. }
  997. pNextHelper = NULL;
  998. }
  999. // a little function to convert from ANSI to Unicode
  1000. HRESULT Ansi2Unicode(LPWSTR *pdest, LPCSTR src)
  1001. {
  1002. UINT cbSize;
  1003. cbSize = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
  1004. if (cbSize > 0)
  1005. {
  1006. *pdest = new WCHAR[cbSize+1];
  1007. cbSize = MultiByteToWideChar(CP_ACP, 0, src, -1, *pdest, cbSize+1);
  1008. }
  1009. return cbSize > 0 ? S_OK : E_FAIL;
  1010. }