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.

604 lines
15 KiB

  1. /****************************************************************************\
  2. *
  3. * PICSUSER.C -- Structure for holding user information
  4. *
  5. * Created: 02/29/96 gregj
  6. * from original sources by t-jasont
  7. *
  8. \****************************************************************************/
  9. /*Includes------------------------------------------------------------------*/
  10. #include "msrating.h"
  11. #include "mslubase.h"
  12. #include "debug.h"
  13. BOOL GetRegBool(HKEY hKey, LPCSTR pszValueName, BOOL fDefault)
  14. {
  15. BOOL fRet = fDefault;
  16. DWORD dwSize, dwValue, dwType;
  17. UINT uErr;
  18. dwSize = sizeof(dwValue);
  19. uErr = RegQueryValueEx(hKey, pszValueName, NULL, &dwType,
  20. (LPBYTE)&dwValue, &dwSize);
  21. if (uErr == ERROR_SUCCESS)
  22. {
  23. if ((dwType == REG_DWORD) || (dwType == REG_BINARY && dwSize >= sizeof(fRet)))
  24. fRet = dwValue;
  25. }
  26. return fRet;
  27. }
  28. void SetRegBool(HKEY hkey, LPCSTR pszValueName, BOOL fValue)
  29. {
  30. RegSetValueEx(hkey, pszValueName, 0, REG_DWORD, (LPBYTE)&fValue, sizeof(fValue));
  31. }
  32. PicsRatingSystem *FindInstalledRatingSystem(LPCSTR pszRatingService)
  33. {
  34. UINT cServices = gPRSI->arrpPRS.Length();
  35. for (UINT i=0; i<cServices; i++) {
  36. PicsRatingSystem *pPRS = gPRSI->arrpPRS[i];
  37. if (!(pPRS->dwFlags & PRS_ISVALID) || !pPRS->etstrRatingService.fIsInit())
  38. continue;
  39. if (!::strcmpf(pPRS->etstrRatingService.Get(), pszRatingService))
  40. return pPRS;
  41. }
  42. return NULL;
  43. }
  44. PicsCategory *FindInstalledCategory(array<PicsCategory *>&arrpPC, LPCSTR pszName)
  45. {
  46. UINT cCategories = arrpPC.Length();
  47. for (UINT i=0; i<cCategories; i++) {
  48. LPSTR pszThisName = arrpPC[i]->etstrTransmitAs.Get();
  49. if (!::strcmpf(pszThisName, pszName))
  50. return arrpPC[i];
  51. if (!::strncmpf(pszThisName, pszName, strlenf(pszThisName)) &&
  52. arrpPC[i]->arrpPC.Length() > 0) {
  53. PicsCategory *pCategory = FindInstalledCategory(arrpPC[i]->arrpPC, pszName);
  54. if (pCategory != NULL)
  55. return pCategory;
  56. }
  57. }
  58. return NULL;
  59. }
  60. UserRating::UserRating()
  61. : NLS_STR(NULL),
  62. m_nValue(0),
  63. m_pNext(NULL),
  64. m_pPC(NULL)
  65. {
  66. }
  67. UserRating::UserRating(UserRating *pCopyFrom)
  68. : NLS_STR(*pCopyFrom),
  69. m_nValue(pCopyFrom->m_nValue),
  70. m_pNext(NULL),
  71. m_pPC(pCopyFrom->m_pPC)
  72. {
  73. }
  74. UserRating::~UserRating()
  75. {
  76. // needed to destruct name string
  77. }
  78. UserRating *UserRating::Duplicate(void)
  79. {
  80. UserRating *pNew = new UserRating(this);
  81. return pNew;
  82. }
  83. UserRatingSystem::UserRatingSystem()
  84. : NLS_STR(NULL),
  85. m_pRatingList(NULL),
  86. m_pNext(NULL),
  87. m_pPRS(NULL)
  88. {
  89. }
  90. UserRatingSystem::UserRatingSystem(UserRatingSystem *pCopyFrom)
  91. : NLS_STR(*pCopyFrom),
  92. m_pRatingList(NULL),
  93. m_pNext(NULL),
  94. m_pPRS(pCopyFrom->m_pPRS)
  95. {
  96. }
  97. UserRatingSystem *UserRatingSystem::Duplicate(void)
  98. {
  99. UserRatingSystem *pNew = new UserRatingSystem(this);
  100. if (pNew != NULL) {
  101. UserRating *pRating;
  102. for (pRating = m_pRatingList; pRating != NULL; pRating = pRating->m_pNext) {
  103. UserRating *pNewRating = pRating->Duplicate();
  104. if (pNewRating != NULL) {
  105. if (pNew->AddRating(pNewRating) != ERROR_SUCCESS) {
  106. delete pNewRating;
  107. pNewRating = NULL;
  108. }
  109. }
  110. if (pNewRating == NULL)
  111. break;
  112. }
  113. }
  114. return pNew;
  115. }
  116. UserRatingSystem *DuplicateRatingSystemList(UserRatingSystem *pOld)
  117. {
  118. UserRatingSystem *pNewList = NULL;
  119. while (pOld != NULL) {
  120. UserRatingSystem *pNewEntry = pOld->Duplicate();
  121. if (pNewEntry == NULL)
  122. break;
  123. pNewEntry->m_pNext = pNewList;
  124. pNewList = pNewEntry;
  125. pOld = pOld->m_pNext;
  126. }
  127. return pNewList;
  128. }
  129. UserRatingSystem::~UserRatingSystem()
  130. {
  131. UserRating *pRating, *pNext;
  132. for (pRating = m_pRatingList; pRating != NULL; )
  133. {
  134. pNext = pRating->m_pNext;
  135. delete pRating;
  136. pRating = pNext;
  137. }
  138. #ifdef DEBUG
  139. m_pRatingList = NULL;
  140. #endif
  141. }
  142. UserRating *UserRatingSystem::FindRating(LPCSTR pszTransmitName)
  143. {
  144. UserRating *p;
  145. for (p = m_pRatingList; p != NULL; p = p->m_pNext)
  146. {
  147. if (!::stricmpf(p->QueryPch(), pszTransmitName))
  148. break;
  149. }
  150. return p;
  151. }
  152. UINT UserRatingSystem::AddRating(UserRating *pRating)
  153. {
  154. pRating->m_pNext = m_pRatingList;
  155. m_pRatingList = pRating;
  156. return ERROR_SUCCESS;
  157. }
  158. UINT UserRatingSystem::ReadFromRegistry(HKEY hkeyProvider)
  159. {
  160. UINT err;
  161. DWORD iValue = 0;
  162. char szValueName[MAXPATHLEN];
  163. DWORD cchValue;
  164. DWORD dwValue;
  165. DWORD cbData;
  166. do {
  167. cchValue = sizeof(szValueName);
  168. cbData = sizeof(dwValue);
  169. err = RegEnumValue(hkeyProvider, iValue, szValueName, &cchValue,
  170. NULL, NULL, (LPBYTE)&dwValue, &cbData);
  171. if (err == ERROR_SUCCESS && cbData >= sizeof(dwValue)) {
  172. UserRating *pRating = new UserRating;
  173. if (pRating != NULL) {
  174. if (pRating->QueryError()) {
  175. err = pRating->QueryError();
  176. }
  177. else {
  178. pRating->SetName(szValueName);
  179. pRating->m_nValue = (INT)dwValue;
  180. if (m_pPRS != NULL)
  181. pRating->m_pPC = FindInstalledCategory(m_pPRS->arrpPC, szValueName);
  182. err = AddRating(pRating);
  183. }
  184. if (err != ERROR_SUCCESS)
  185. {
  186. delete pRating;
  187. pRating = NULL;
  188. }
  189. }
  190. else
  191. err = ERROR_NOT_ENOUGH_MEMORY;
  192. }
  193. iValue++;
  194. } while (err == ERROR_SUCCESS);
  195. if (err == ERROR_NO_MORE_ITEMS)
  196. err = ERROR_SUCCESS;
  197. return err;
  198. }
  199. UINT UserRatingSystem::WriteToRegistry(HKEY hkeyRatings)
  200. {
  201. UserRating *pRating;
  202. UINT err = ERROR_SUCCESS;
  203. CRegKey key;
  204. err = key.Create( hkeyRatings, QueryPch() );
  205. if (err != ERROR_SUCCESS)
  206. {
  207. TraceMsg( TF_WARNING, "UserRatingSystem::WriteToRegistry() - Failed to create Ratings Key QueryPch()='%s'!", QueryPch() );
  208. return err;
  209. }
  210. for (pRating = m_pRatingList; pRating != NULL; pRating = pRating->m_pNext)
  211. {
  212. err = key.SetValue( pRating->m_nValue, pRating->QueryPch() );
  213. if (err != ERROR_SUCCESS)
  214. {
  215. TraceMsg( TF_WARNING, "UserRatingSystem::WriteToRegistry() - Failed to set Ratings Value pRating->QueryPch()='%s'!", pRating->QueryPch() );
  216. break;
  217. }
  218. }
  219. return err;
  220. }
  221. PicsUser::PicsUser()
  222. : nlsUsername(NULL),
  223. fAllowUnknowns(FALSE),
  224. fPleaseMom(TRUE),
  225. fEnabled(TRUE),
  226. m_pRatingSystems(NULL)
  227. {
  228. }
  229. PicsRatingSystemInfo::~PicsRatingSystemInfo()
  230. {
  231. arrpPRS.DeleteAll();
  232. if ( pUserObject )
  233. {
  234. delete pUserObject;
  235. pUserObject = NULL;
  236. }
  237. }
  238. void DestroyRatingSystemList(UserRatingSystem *pList)
  239. {
  240. UserRatingSystem *pSystem, *pNext;
  241. for (pSystem = pList; pSystem != NULL; )
  242. {
  243. pNext = pSystem->m_pNext;
  244. delete pSystem;
  245. pSystem = pNext;
  246. }
  247. }
  248. PicsUser::~PicsUser()
  249. {
  250. DestroyRatingSystemList(m_pRatingSystems);
  251. #ifdef DEBUG
  252. m_pRatingSystems = NULL;
  253. #endif
  254. }
  255. UserRatingSystem *FindRatingSystem(UserRatingSystem *pList, LPCSTR pszSystemName)
  256. {
  257. UserRatingSystem *p;
  258. for (p = pList; p != NULL; p = p->m_pNext)
  259. {
  260. if (!::strcmpf(p->QueryPch(), pszSystemName))
  261. break;
  262. }
  263. return p;
  264. }
  265. UINT PicsUser::AddRatingSystem(UserRatingSystem *pRatingSystem)
  266. {
  267. pRatingSystem->m_pNext = m_pRatingSystems;
  268. m_pRatingSystems = pRatingSystem;
  269. return ERROR_SUCCESS;
  270. }
  271. UINT PicsUser::ReadFromRegistry(HKEY hkey, char *pszUserName)
  272. {
  273. CRegKey keyUser;
  274. nlsUsername = pszUserName;
  275. UINT err = keyUser.Open( hkey, pszUserName, KEY_READ );
  276. if (err != ERROR_SUCCESS)
  277. {
  278. TraceMsg( TF_WARNING, "PicsUser::ReadFromRegistry() - Failed keyUser Open to pszUserName='%s'!", pszUserName );
  279. return err;
  280. }
  281. fAllowUnknowns = GetRegBool( keyUser.m_hKey, VAL_UNKNOWNS, FALSE);
  282. fPleaseMom = GetRegBool( keyUser.m_hKey, VAL_PLEASEMOM, TRUE);
  283. fEnabled = GetRegBool( keyUser.m_hKey, VAL_ENABLED, TRUE);
  284. {
  285. char szKeyName[MAXPATHLEN];
  286. int j = 0;
  287. // enumerate the subkeys, which are rating systems
  288. while ( ( err = RegEnumKey( keyUser.m_hKey, j, szKeyName, sizeof(szKeyName) ) ) == ERROR_SUCCESS )
  289. {
  290. CRegKey keyProvider;
  291. if ( ( err = keyProvider.Open( keyUser.m_hKey, szKeyName, KEY_READ ) != ERROR_SUCCESS ) )
  292. {
  293. TraceMsg( TF_WARNING, "PicsUser::ReadFromRegistry() - Failed keyProvider Open to szKeyName='%s'!", szKeyName );
  294. break;
  295. }
  296. UserRatingSystem *pRatingSystem = new UserRatingSystem;
  297. if (pRatingSystem == NULL)
  298. {
  299. err = ERROR_NOT_ENOUGH_MEMORY;
  300. break;
  301. }
  302. if (pRatingSystem->QueryError())
  303. {
  304. err = pRatingSystem->QueryError();
  305. }
  306. else
  307. {
  308. pRatingSystem->SetName(szKeyName);
  309. pRatingSystem->m_pPRS = FindInstalledRatingSystem(szKeyName);
  310. err = pRatingSystem->ReadFromRegistry( keyProvider.m_hKey );
  311. if (err == ERROR_SUCCESS)
  312. {
  313. err = AddRatingSystem(pRatingSystem);
  314. }
  315. }
  316. if (err != ERROR_SUCCESS)
  317. {
  318. delete pRatingSystem;
  319. pRatingSystem = NULL;
  320. }
  321. j++;
  322. }
  323. }
  324. // end of enum will report ERROR_NO_MORE_ITEMS, don't report this as error
  325. if (err == ERROR_NO_MORE_ITEMS)
  326. {
  327. err = ERROR_SUCCESS;
  328. }
  329. return err;
  330. }
  331. BOOL PicsUser::NewInstall()
  332. {
  333. nlsUsername = szDefaultUserName;
  334. fAllowUnknowns = FALSE;
  335. fPleaseMom = TRUE;
  336. fEnabled = TRUE;
  337. return TRUE;
  338. }
  339. UINT PicsUser::WriteToRegistry(HKEY hkey)
  340. {
  341. UINT err;
  342. //Delete it to clean out registry
  343. MyRegDeleteKey(hkey, nlsUsername.QueryPch());
  344. CRegKey keyUser;
  345. err = keyUser.Create( hkey, nlsUsername.QueryPch() );
  346. if (err != ERROR_SUCCESS)
  347. {
  348. TraceMsg( TF_WARNING, "PicsUser::WriteToRegistry() - Failed to Create User Key nlsUsername='%s'!", nlsUsername.QueryPch() );
  349. return err;
  350. }
  351. SetRegBool( keyUser.m_hKey, VAL_UNKNOWNS, fAllowUnknowns);
  352. SetRegBool( keyUser.m_hKey, VAL_PLEASEMOM, fPleaseMom);
  353. SetRegBool( keyUser.m_hKey, VAL_ENABLED, fEnabled);
  354. {
  355. UserRatingSystem *pSystem;
  356. /* Note, if any user settings correspond to invalid or unknown
  357. * rating systems, we still save them here. That way, the user
  358. * settings don't get lost if the supervisor later fixes a problem
  359. * with a .RAT file.
  360. *
  361. * We clean up user settings to match the installed rating systems
  362. * in the add/remove rating systems dialog code.
  363. */
  364. for (pSystem = m_pRatingSystems; pSystem != NULL; pSystem = pSystem->m_pNext)
  365. {
  366. err = pSystem->WriteToRegistry( keyUser.m_hKey );
  367. if (err != ERROR_SUCCESS)
  368. {
  369. TraceMsg( TF_WARNING, "PicsUser::WriteToRegistry() - Failed pSystem->WriteToRegistry()!" );
  370. break;
  371. }
  372. }
  373. }
  374. return err;
  375. }
  376. PicsUser *GetUserObject(LPCSTR pszUsername /* = NULL */ )
  377. {
  378. ASSERT( gPRSI );
  379. return gPRSI ? gPRSI->pUserObject : NULL;
  380. }
  381. void DeleteUserSettings(PicsRatingSystem *pPRS)
  382. {
  383. if (!pPRS->etstrRatingService.fIsInit())
  384. return; /* can't recognize user settings without this */
  385. PicsUser *pPU = GetUserObject();
  386. UserRatingSystem **ppLast = &pPU->m_pRatingSystems;
  387. while (*ppLast != NULL)
  388. {
  389. if (!stricmpf((*ppLast)->QueryPch(), pPRS->etstrRatingService.Get()))
  390. {
  391. UserRatingSystem *pCurrent = *ppLast;
  392. *ppLast = pCurrent->m_pNext; /* remove from list */
  393. delete pCurrent;
  394. pCurrent = NULL;
  395. break;
  396. }
  397. else
  398. {
  399. ppLast = &((*ppLast)->m_pNext);
  400. }
  401. }
  402. }
  403. void CheckUserCategory(UserRatingSystem *pURS, PicsCategory *pPC)
  404. {
  405. for (UserRating *pRating = pURS->m_pRatingList;
  406. pRating != NULL;
  407. pRating = pRating->m_pNext)
  408. {
  409. if (!::strcmpf(pRating->QueryPch(), pPC->etstrTransmitAs.Get()))
  410. break;
  411. }
  412. if (pRating == NULL) {
  413. /* User setting not found for this category. Add one. */
  414. pRating = new UserRating;
  415. if (pRating != NULL) {
  416. pRating->SetName(pPC->etstrTransmitAs.Get());
  417. pRating->m_pPC = pPC;
  418. pRating->m_pNext = pURS->m_pRatingList;
  419. pURS->m_pRatingList = pRating;
  420. if ((pPC->etfLabelled.fIsInit() && pPC->etfLabelled.Get()) ||
  421. !pPC->etnMin.fIsInit())
  422. pRating->m_nValue = 0;
  423. else
  424. pRating->m_nValue = pPC->etnMin.Get();
  425. }
  426. }
  427. /* Check all subcategories in this category as well.
  428. */
  429. UINT cCategories = pPC->arrpPC.Length();
  430. for (UINT i=0; i<cCategories; i++)
  431. CheckUserCategory(pURS, pPC->arrpPC[i]);
  432. }
  433. void CheckUserSettings(PicsRatingSystem *pPRS)
  434. {
  435. if (pPRS == NULL || !(pPRS->dwFlags & PRS_ISVALID) ||
  436. !pPRS->etstrRatingService.fIsInit())
  437. return;
  438. PicsUser *pPU = GetUserObject();
  439. UserRatingSystem **ppLast = &pPU->m_pRatingSystems;
  440. while (*ppLast != NULL) {
  441. if (!stricmpf((*ppLast)->QueryPch(), pPRS->etstrRatingService.Get())) {
  442. break;
  443. }
  444. ppLast = &((*ppLast)->m_pNext);
  445. }
  446. if (*ppLast == NULL) {
  447. *ppLast = new UserRatingSystem;
  448. if (*ppLast == NULL)
  449. return;
  450. (*ppLast)->SetName(pPRS->etstrRatingService.Get());
  451. }
  452. UserRatingSystem *pCurrent = *ppLast;
  453. pCurrent->m_pPRS = pPRS;
  454. /* First go through all the settings for the user and make sure the
  455. * categories are valid. If not, delete them.
  456. */
  457. UserRating **ppRating = &pCurrent->m_pRatingList;
  458. while (*ppRating != NULL)
  459. {
  460. UserRating *pRating = *ppRating;
  461. pRating->m_pPC = FindInstalledCategory(pPRS->arrpPC, pRating->QueryPch());
  462. if (pRating->m_pPC == NULL)
  463. {
  464. *ppRating = pRating->m_pNext; /* remove from list */
  465. delete pRating;
  466. pRating = NULL;
  467. }
  468. else
  469. {
  470. ppRating = &pRating->m_pNext;
  471. }
  472. }
  473. /* Now go through all the categories in the rating system and make
  474. * sure the user has settings for them. If any are missing, add
  475. * settings for the default values (minimums).
  476. */
  477. UINT cCategories = pPRS->arrpPC.Length();
  478. for (UINT i=0; i<cCategories; i++)
  479. CheckUserCategory(pCurrent, pPRS->arrpPC[i]);
  480. }