windows-nt/Source/XPSP1/NT/shell/ext/ratings/msrating/picsuser.cpp
2020-09-26 16:20:57 +08:00

605 lines
15 KiB
C++

/****************************************************************************\
*
* PICSUSER.C -- Structure for holding user information
*
* Created: 02/29/96 gregj
* from original sources by t-jasont
*
\****************************************************************************/
/*Includes------------------------------------------------------------------*/
#include "msrating.h"
#include "mslubase.h"
#include "debug.h"
BOOL GetRegBool(HKEY hKey, LPCSTR pszValueName, BOOL fDefault)
{
BOOL fRet = fDefault;
DWORD dwSize, dwValue, dwType;
UINT uErr;
dwSize = sizeof(dwValue);
uErr = RegQueryValueEx(hKey, pszValueName, NULL, &dwType,
(LPBYTE)&dwValue, &dwSize);
if (uErr == ERROR_SUCCESS)
{
if ((dwType == REG_DWORD) || (dwType == REG_BINARY && dwSize >= sizeof(fRet)))
fRet = dwValue;
}
return fRet;
}
void SetRegBool(HKEY hkey, LPCSTR pszValueName, BOOL fValue)
{
RegSetValueEx(hkey, pszValueName, 0, REG_DWORD, (LPBYTE)&fValue, sizeof(fValue));
}
PicsRatingSystem *FindInstalledRatingSystem(LPCSTR pszRatingService)
{
UINT cServices = gPRSI->arrpPRS.Length();
for (UINT i=0; i<cServices; i++) {
PicsRatingSystem *pPRS = gPRSI->arrpPRS[i];
if (!(pPRS->dwFlags & PRS_ISVALID) || !pPRS->etstrRatingService.fIsInit())
continue;
if (!::strcmpf(pPRS->etstrRatingService.Get(), pszRatingService))
return pPRS;
}
return NULL;
}
PicsCategory *FindInstalledCategory(array<PicsCategory *>&arrpPC, LPCSTR pszName)
{
UINT cCategories = arrpPC.Length();
for (UINT i=0; i<cCategories; i++) {
LPSTR pszThisName = arrpPC[i]->etstrTransmitAs.Get();
if (!::strcmpf(pszThisName, pszName))
return arrpPC[i];
if (!::strncmpf(pszThisName, pszName, strlenf(pszThisName)) &&
arrpPC[i]->arrpPC.Length() > 0) {
PicsCategory *pCategory = FindInstalledCategory(arrpPC[i]->arrpPC, pszName);
if (pCategory != NULL)
return pCategory;
}
}
return NULL;
}
UserRating::UserRating()
: NLS_STR(NULL),
m_nValue(0),
m_pNext(NULL),
m_pPC(NULL)
{
}
UserRating::UserRating(UserRating *pCopyFrom)
: NLS_STR(*pCopyFrom),
m_nValue(pCopyFrom->m_nValue),
m_pNext(NULL),
m_pPC(pCopyFrom->m_pPC)
{
}
UserRating::~UserRating()
{
// needed to destruct name string
}
UserRating *UserRating::Duplicate(void)
{
UserRating *pNew = new UserRating(this);
return pNew;
}
UserRatingSystem::UserRatingSystem()
: NLS_STR(NULL),
m_pRatingList(NULL),
m_pNext(NULL),
m_pPRS(NULL)
{
}
UserRatingSystem::UserRatingSystem(UserRatingSystem *pCopyFrom)
: NLS_STR(*pCopyFrom),
m_pRatingList(NULL),
m_pNext(NULL),
m_pPRS(pCopyFrom->m_pPRS)
{
}
UserRatingSystem *UserRatingSystem::Duplicate(void)
{
UserRatingSystem *pNew = new UserRatingSystem(this);
if (pNew != NULL) {
UserRating *pRating;
for (pRating = m_pRatingList; pRating != NULL; pRating = pRating->m_pNext) {
UserRating *pNewRating = pRating->Duplicate();
if (pNewRating != NULL) {
if (pNew->AddRating(pNewRating) != ERROR_SUCCESS) {
delete pNewRating;
pNewRating = NULL;
}
}
if (pNewRating == NULL)
break;
}
}
return pNew;
}
UserRatingSystem *DuplicateRatingSystemList(UserRatingSystem *pOld)
{
UserRatingSystem *pNewList = NULL;
while (pOld != NULL) {
UserRatingSystem *pNewEntry = pOld->Duplicate();
if (pNewEntry == NULL)
break;
pNewEntry->m_pNext = pNewList;
pNewList = pNewEntry;
pOld = pOld->m_pNext;
}
return pNewList;
}
UserRatingSystem::~UserRatingSystem()
{
UserRating *pRating, *pNext;
for (pRating = m_pRatingList; pRating != NULL; )
{
pNext = pRating->m_pNext;
delete pRating;
pRating = pNext;
}
#ifdef DEBUG
m_pRatingList = NULL;
#endif
}
UserRating *UserRatingSystem::FindRating(LPCSTR pszTransmitName)
{
UserRating *p;
for (p = m_pRatingList; p != NULL; p = p->m_pNext)
{
if (!::stricmpf(p->QueryPch(), pszTransmitName))
break;
}
return p;
}
UINT UserRatingSystem::AddRating(UserRating *pRating)
{
pRating->m_pNext = m_pRatingList;
m_pRatingList = pRating;
return ERROR_SUCCESS;
}
UINT UserRatingSystem::ReadFromRegistry(HKEY hkeyProvider)
{
UINT err;
DWORD iValue = 0;
char szValueName[MAXPATHLEN];
DWORD cchValue;
DWORD dwValue;
DWORD cbData;
do {
cchValue = sizeof(szValueName);
cbData = sizeof(dwValue);
err = RegEnumValue(hkeyProvider, iValue, szValueName, &cchValue,
NULL, NULL, (LPBYTE)&dwValue, &cbData);
if (err == ERROR_SUCCESS && cbData >= sizeof(dwValue)) {
UserRating *pRating = new UserRating;
if (pRating != NULL) {
if (pRating->QueryError()) {
err = pRating->QueryError();
}
else {
pRating->SetName(szValueName);
pRating->m_nValue = (INT)dwValue;
if (m_pPRS != NULL)
pRating->m_pPC = FindInstalledCategory(m_pPRS->arrpPC, szValueName);
err = AddRating(pRating);
}
if (err != ERROR_SUCCESS)
{
delete pRating;
pRating = NULL;
}
}
else
err = ERROR_NOT_ENOUGH_MEMORY;
}
iValue++;
} while (err == ERROR_SUCCESS);
if (err == ERROR_NO_MORE_ITEMS)
err = ERROR_SUCCESS;
return err;
}
UINT UserRatingSystem::WriteToRegistry(HKEY hkeyRatings)
{
UserRating *pRating;
UINT err = ERROR_SUCCESS;
CRegKey key;
err = key.Create( hkeyRatings, QueryPch() );
if (err != ERROR_SUCCESS)
{
TraceMsg( TF_WARNING, "UserRatingSystem::WriteToRegistry() - Failed to create Ratings Key QueryPch()='%s'!", QueryPch() );
return err;
}
for (pRating = m_pRatingList; pRating != NULL; pRating = pRating->m_pNext)
{
err = key.SetValue( pRating->m_nValue, pRating->QueryPch() );
if (err != ERROR_SUCCESS)
{
TraceMsg( TF_WARNING, "UserRatingSystem::WriteToRegistry() - Failed to set Ratings Value pRating->QueryPch()='%s'!", pRating->QueryPch() );
break;
}
}
return err;
}
PicsUser::PicsUser()
: nlsUsername(NULL),
fAllowUnknowns(FALSE),
fPleaseMom(TRUE),
fEnabled(TRUE),
m_pRatingSystems(NULL)
{
}
PicsRatingSystemInfo::~PicsRatingSystemInfo()
{
arrpPRS.DeleteAll();
if ( pUserObject )
{
delete pUserObject;
pUserObject = NULL;
}
}
void DestroyRatingSystemList(UserRatingSystem *pList)
{
UserRatingSystem *pSystem, *pNext;
for (pSystem = pList; pSystem != NULL; )
{
pNext = pSystem->m_pNext;
delete pSystem;
pSystem = pNext;
}
}
PicsUser::~PicsUser()
{
DestroyRatingSystemList(m_pRatingSystems);
#ifdef DEBUG
m_pRatingSystems = NULL;
#endif
}
UserRatingSystem *FindRatingSystem(UserRatingSystem *pList, LPCSTR pszSystemName)
{
UserRatingSystem *p;
for (p = pList; p != NULL; p = p->m_pNext)
{
if (!::strcmpf(p->QueryPch(), pszSystemName))
break;
}
return p;
}
UINT PicsUser::AddRatingSystem(UserRatingSystem *pRatingSystem)
{
pRatingSystem->m_pNext = m_pRatingSystems;
m_pRatingSystems = pRatingSystem;
return ERROR_SUCCESS;
}
UINT PicsUser::ReadFromRegistry(HKEY hkey, char *pszUserName)
{
CRegKey keyUser;
nlsUsername = pszUserName;
UINT err = keyUser.Open( hkey, pszUserName, KEY_READ );
if (err != ERROR_SUCCESS)
{
TraceMsg( TF_WARNING, "PicsUser::ReadFromRegistry() - Failed keyUser Open to pszUserName='%s'!", pszUserName );
return err;
}
fAllowUnknowns = GetRegBool( keyUser.m_hKey, VAL_UNKNOWNS, FALSE);
fPleaseMom = GetRegBool( keyUser.m_hKey, VAL_PLEASEMOM, TRUE);
fEnabled = GetRegBool( keyUser.m_hKey, VAL_ENABLED, TRUE);
{
char szKeyName[MAXPATHLEN];
int j = 0;
// enumerate the subkeys, which are rating systems
while ( ( err = RegEnumKey( keyUser.m_hKey, j, szKeyName, sizeof(szKeyName) ) ) == ERROR_SUCCESS )
{
CRegKey keyProvider;
if ( ( err = keyProvider.Open( keyUser.m_hKey, szKeyName, KEY_READ ) != ERROR_SUCCESS ) )
{
TraceMsg( TF_WARNING, "PicsUser::ReadFromRegistry() - Failed keyProvider Open to szKeyName='%s'!", szKeyName );
break;
}
UserRatingSystem *pRatingSystem = new UserRatingSystem;
if (pRatingSystem == NULL)
{
err = ERROR_NOT_ENOUGH_MEMORY;
break;
}
if (pRatingSystem->QueryError())
{
err = pRatingSystem->QueryError();
}
else
{
pRatingSystem->SetName(szKeyName);
pRatingSystem->m_pPRS = FindInstalledRatingSystem(szKeyName);
err = pRatingSystem->ReadFromRegistry( keyProvider.m_hKey );
if (err == ERROR_SUCCESS)
{
err = AddRatingSystem(pRatingSystem);
}
}
if (err != ERROR_SUCCESS)
{
delete pRatingSystem;
pRatingSystem = NULL;
}
j++;
}
}
// end of enum will report ERROR_NO_MORE_ITEMS, don't report this as error
if (err == ERROR_NO_MORE_ITEMS)
{
err = ERROR_SUCCESS;
}
return err;
}
BOOL PicsUser::NewInstall()
{
nlsUsername = szDefaultUserName;
fAllowUnknowns = FALSE;
fPleaseMom = TRUE;
fEnabled = TRUE;
return TRUE;
}
UINT PicsUser::WriteToRegistry(HKEY hkey)
{
UINT err;
//Delete it to clean out registry
MyRegDeleteKey(hkey, nlsUsername.QueryPch());
CRegKey keyUser;
err = keyUser.Create( hkey, nlsUsername.QueryPch() );
if (err != ERROR_SUCCESS)
{
TraceMsg( TF_WARNING, "PicsUser::WriteToRegistry() - Failed to Create User Key nlsUsername='%s'!", nlsUsername.QueryPch() );
return err;
}
SetRegBool( keyUser.m_hKey, VAL_UNKNOWNS, fAllowUnknowns);
SetRegBool( keyUser.m_hKey, VAL_PLEASEMOM, fPleaseMom);
SetRegBool( keyUser.m_hKey, VAL_ENABLED, fEnabled);
{
UserRatingSystem *pSystem;
/* Note, if any user settings correspond to invalid or unknown
* rating systems, we still save them here. That way, the user
* settings don't get lost if the supervisor later fixes a problem
* with a .RAT file.
*
* We clean up user settings to match the installed rating systems
* in the add/remove rating systems dialog code.
*/
for (pSystem = m_pRatingSystems; pSystem != NULL; pSystem = pSystem->m_pNext)
{
err = pSystem->WriteToRegistry( keyUser.m_hKey );
if (err != ERROR_SUCCESS)
{
TraceMsg( TF_WARNING, "PicsUser::WriteToRegistry() - Failed pSystem->WriteToRegistry()!" );
break;
}
}
}
return err;
}
PicsUser *GetUserObject(LPCSTR pszUsername /* = NULL */ )
{
ASSERT( gPRSI );
return gPRSI ? gPRSI->pUserObject : NULL;
}
void DeleteUserSettings(PicsRatingSystem *pPRS)
{
if (!pPRS->etstrRatingService.fIsInit())
return; /* can't recognize user settings without this */
PicsUser *pPU = GetUserObject();
UserRatingSystem **ppLast = &pPU->m_pRatingSystems;
while (*ppLast != NULL)
{
if (!stricmpf((*ppLast)->QueryPch(), pPRS->etstrRatingService.Get()))
{
UserRatingSystem *pCurrent = *ppLast;
*ppLast = pCurrent->m_pNext; /* remove from list */
delete pCurrent;
pCurrent = NULL;
break;
}
else
{
ppLast = &((*ppLast)->m_pNext);
}
}
}
void CheckUserCategory(UserRatingSystem *pURS, PicsCategory *pPC)
{
for (UserRating *pRating = pURS->m_pRatingList;
pRating != NULL;
pRating = pRating->m_pNext)
{
if (!::strcmpf(pRating->QueryPch(), pPC->etstrTransmitAs.Get()))
break;
}
if (pRating == NULL) {
/* User setting not found for this category. Add one. */
pRating = new UserRating;
if (pRating != NULL) {
pRating->SetName(pPC->etstrTransmitAs.Get());
pRating->m_pPC = pPC;
pRating->m_pNext = pURS->m_pRatingList;
pURS->m_pRatingList = pRating;
if ((pPC->etfLabelled.fIsInit() && pPC->etfLabelled.Get()) ||
!pPC->etnMin.fIsInit())
pRating->m_nValue = 0;
else
pRating->m_nValue = pPC->etnMin.Get();
}
}
/* Check all subcategories in this category as well.
*/
UINT cCategories = pPC->arrpPC.Length();
for (UINT i=0; i<cCategories; i++)
CheckUserCategory(pURS, pPC->arrpPC[i]);
}
void CheckUserSettings(PicsRatingSystem *pPRS)
{
if (pPRS == NULL || !(pPRS->dwFlags & PRS_ISVALID) ||
!pPRS->etstrRatingService.fIsInit())
return;
PicsUser *pPU = GetUserObject();
UserRatingSystem **ppLast = &pPU->m_pRatingSystems;
while (*ppLast != NULL) {
if (!stricmpf((*ppLast)->QueryPch(), pPRS->etstrRatingService.Get())) {
break;
}
ppLast = &((*ppLast)->m_pNext);
}
if (*ppLast == NULL) {
*ppLast = new UserRatingSystem;
if (*ppLast == NULL)
return;
(*ppLast)->SetName(pPRS->etstrRatingService.Get());
}
UserRatingSystem *pCurrent = *ppLast;
pCurrent->m_pPRS = pPRS;
/* First go through all the settings for the user and make sure the
* categories are valid. If not, delete them.
*/
UserRating **ppRating = &pCurrent->m_pRatingList;
while (*ppRating != NULL)
{
UserRating *pRating = *ppRating;
pRating->m_pPC = FindInstalledCategory(pPRS->arrpPC, pRating->QueryPch());
if (pRating->m_pPC == NULL)
{
*ppRating = pRating->m_pNext; /* remove from list */
delete pRating;
pRating = NULL;
}
else
{
ppRating = &pRating->m_pNext;
}
}
/* Now go through all the categories in the rating system and make
* sure the user has settings for them. If any are missing, add
* settings for the default values (minimums).
*/
UINT cCategories = pPRS->arrpPC.Length();
for (UINT i=0; i<cCategories; i++)
CheckUserCategory(pCurrent, pPRS->arrpPC[i]);
}