/****************************************************************************\ * * MSLUBASE.C --Structures for holding pics information * * Created: Jason Thomas * Updated: Ann McCurdy * \****************************************************************************/ /*Includes------------------------------------------------------------------*/ #include "msrating.h" #include "mslubase.h" #include "reghive.h" // CRegistryHive #include "debug.h" #include #include #include /*Helpers-------------------------------------------------------------------*/ char PicsDelimChar='/'; int MyMessageBox(HWND hwnd, LPCSTR pszText, UINT uTitle, UINT uType) { CHAR szTitle[MAXPATHLEN]; MLLoadStringA(uTitle, szTitle, sizeof(szTitle)); return MessageBox(hwnd, pszText, szTitle, uType); } int MyMessageBox(HWND hwnd, UINT uText, UINT uTitle, UINT uType) { CHAR szText[MAXPATHLEN]; MLLoadStringA(uText, szText, sizeof(szText)); return MyMessageBox(hwnd, szText, uTitle, uType); } /* Variant for long messages: uText2 message will be concatenated onto the end * of uText before display. Message text should contain \r\n or other desired * separators, this function won't add them. */ int MyMessageBox(HWND hwnd, UINT uText, UINT uText2, UINT uTitle, UINT uType) { CHAR szText[MAXPATHLEN*2] = { 0 }; MLLoadStringA(uText, szText, sizeof(szText)); /* Using lstrlen in case MLLoadString really returns a count of CHARACTERS, * on a DBCS system... */ UINT cbFirst = lstrlen(szText); MLLoadStringA(uText2, szText + cbFirst, sizeof(szText) - cbFirst); return MyMessageBox(hwnd, szText, uTitle, uType); } /******************************************************************* NAME: MyRegDeleteKey ********************************************************************/ LONG MyRegDeleteKey(HKEY hkey,LPCSTR pszSubkey) { DWORD dwError; TraceMsg( TF_ALWAYS, "MyRegDeleteKey() - Deleting Subkey='%s'...", pszSubkey ); dwError = SHDeleteKey( hkey, pszSubkey ); if ( dwError != ERROR_SUCCESS ) { TraceMsg( TF_WARNING, "MyRegDeleteKey() - Failed to Delete Subkey='%s' dwError=%d!", pszSubkey, dwError ); } return dwError; } BOOL MyAtoi(char *pIn, int *pi) { char *pc; ASSERT(pIn); *pi = 0; pc = NonWhite(pIn); if (!pc) return FALSE; if (*pc < '0' || *pc > '9') return FALSE; int accum = 0; while (*pc >= '0' && *pc <= '9') { accum = accum * 10 + (*pc - '0'); pc++; } *pi = accum; return TRUE; } /*Simple types--------------------------------------------------------------*/ /* ETN */ #ifdef DEBUG void ETN::Set(int rIn){ Init(); r = rIn; } int ETN::Get(){ return r; } #endif ETN* ETN::Duplicate(){ ETN *pETN=new ETN; if (fIsInit()) pETN->Set(Get()); return pETN; } /* ETB */ #ifdef DEBUG BOOL ETB::Get() { ASSERT(fIsInit()); return m_nFlags & ETB_VALUE; } void ETB::Set(BOOL b) { m_nFlags = ETB_ISINIT | (b ? ETB_VALUE : 0); } #endif ETB* ETB::Duplicate() { ASSERT(fIsInit()); ETB *pETB = new ETB; if (pETB != NULL) pETB->m_nFlags = m_nFlags; return pETB; } /* ETS */ ETS::~ETS() { if (pc != NULL) { delete pc; pc = NULL; } } #ifdef DEBUG char* ETS::Get() { // ASSERT(fIsInit()); return pc; } #endif void ETS::Set(const char *pIn) { if (pc != NULL) delete pc; if (pIn != NULL) { pc = new char[strlenf(pIn) + 1]; if (pc != NULL) { strcpyf(pc, pIn); } } else { pc = NULL; } } void ETS::SetTo(char *pIn) { if (pc != NULL) delete pc; pc = pIn; } ETS* ETS::Duplicate() { ETS *pETS=new ETS; if (pETS != NULL) pETS->Set(Get()); return pETS; } UINT EtBoolRegRead(ETB &etb, HKEY hKey, char *pKeyWord) { ASSERT(pKeyWord); if ( ! pKeyWord ) { TraceMsg( TF_ERROR, "EtBoolRegRead() - pKeyWord is NULL!" ); return ERROR_INVALID_PARAMETER; } DWORD dwSize, dwValue, dwType; UINT uErr; etb.Set(FALSE); dwSize = sizeof(dwValue); uErr = RegQueryValueEx(hKey, pKeyWord, NULL, &dwType, (LPBYTE)&dwValue, &dwSize); if (uErr == ERROR_SUCCESS) { if ((dwType == REG_DWORD) && (dwValue != 0)) etb.Set(TRUE); } else { TraceMsg( TF_WARNING, "EtBoolRegRead() - Failed to read pKeyWord='%s'!", pKeyWord ); } return uErr; } UINT EtBoolRegWrite(ETB &etb, HKEY hKey, char *pKeyWord) { ASSERT(pKeyWord); if ( ! pKeyWord ) { TraceMsg( TF_ERROR, "EtBoolRegWrite() - pKeyWord is NULL!" ); return ERROR_INVALID_PARAMETER; } UINT uErr; DWORD dwNum = (etb.fIsInit() && etb.Get()); uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_DWORD, (LPBYTE)&dwNum, sizeof(dwNum)); if ( uErr != ERROR_SUCCESS ) { TraceMsg( TF_WARNING, "EtBoolRegWrite() - Failed to set pKeyWord='%s'!", pKeyWord ); } return uErr; } UINT EtStringRegRead(ETS &ets, HKEY hKey, char *pKeyWord) { ASSERT(pKeyWord); if ( ! pKeyWord ) { TraceMsg( TF_ERROR, "EtStringRegRead() - pKeyWord is NULL!" ); return ERROR_INVALID_PARAMETER; } DWORD dwSize; UINT uErr; char szTemp[80]; /* default size */ dwSize = sizeof(szTemp); uErr = RegQueryValueEx(hKey, pKeyWord, NULL, NULL, (LPBYTE)szTemp, &dwSize); if (uErr == ERROR_SUCCESS) { ets.Set(szTemp); } else if (uErr == ERROR_MORE_DATA) { char *pszTemp = new char[dwSize]; if (pszTemp == NULL) { TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to allocate dwSize=%d memory!", dwSize ); uErr = ERROR_NOT_ENOUGH_MEMORY; } else { uErr = RegQueryValueEx(hKey, pKeyWord, NULL, NULL, (LPBYTE)pszTemp, &dwSize); if (uErr == ERROR_SUCCESS) { ets.SetTo(pszTemp); /* ets now owns pszTemp memory, don't delete it here */ } else { TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to read (dwSize %d) pKeyWord='%s'!", dwSize, pKeyWord ); delete pszTemp; pszTemp = NULL; } } } else { TraceMsg( TF_WARNING, "EtStringRegRead() - Failed to read pKeyWord='%s'!", pKeyWord ); } return uErr; } UINT EtStringRegWrite(ETS &ets, HKEY hKey, char *pKeyWord) { ASSERT(pKeyWord); if ( ! pKeyWord ) { TraceMsg( TF_ERROR, "EtStringRegWrite() - pKeyWord is NULL!" ); return ERROR_INVALID_PARAMETER; } UINT uErr = ERROR_SUCCESS; if (ets.fIsInit()) { uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_SZ, (LPBYTE)ets.Get(), strlenf(ets.Get())+1); if ( uErr != ERROR_SUCCESS ) { TraceMsg( TF_WARNING, "EtStringRegWrite() - Failed to set pKeyWord='%s' with ets='%s'!", pKeyWord, ets.Get() ); } } else { TraceMsg( TF_ERROR, "EtStringRegWrite() - ETS is not initialized!" ); } return uErr; } UINT EtNumRegRead(ETN &etn, HKEY hKey, char *pKeyWord) { ASSERT(pKeyWord); if ( ! pKeyWord ) { TraceMsg( TF_ERROR, "EtNumRegRead() - pKeyWord is NULL!" ); return ERROR_INVALID_PARAMETER; } DWORD dwSize, dwType; int nValue; UINT uErr; dwSize = sizeof(nValue); uErr = RegQueryValueEx(hKey, pKeyWord, NULL, &dwType, (LPBYTE)&nValue, &dwSize); if (uErr == ERROR_SUCCESS) { etn.Set(nValue); } else { TraceMsg( TF_WARNING, "EtNumRegRead() - Failed to read pKeyWord='%s'!", pKeyWord ); } return uErr; } UINT EtNumRegWrite(ETN &etn, HKEY hKey, char *pKeyWord) { UINT uErr = ERROR_SUCCESS; if (etn.fIsInit()) { int nTemp; nTemp = etn.Get(); uErr = RegSetValueEx(hKey, pKeyWord, 0, REG_DWORD, (LPBYTE)&nTemp, sizeof(nTemp)); if ( uErr != ERROR_SUCCESS ) { TraceMsg( TF_WARNING, "EtNumRegWrite() - Failed to set pKeyWord='%s' with nTemp=%d!", pKeyWord, nTemp ); } } else { TraceMsg( TF_ERROR, "EtNumRegWrite() - ETS is not initialized!" ); } return uErr; } /*PicsDefault---------------------------------------------------------------*/ PicsDefault::PicsDefault() { /* nothing to do but construct members */ } PicsDefault::~PicsDefault() { /* nothing to do but destruct members */ } /*PicsEnum------------------------------------------------------------------*/ PicsEnum::PicsEnum() { /* nothing to do but construct members */ } PicsEnum::~PicsEnum() { /* nothing to do but destruct members */ } /*PicsCategory--------------------------------------------------------------*/ PicsCategory::PicsCategory() { /* nothing to do but construct members */ } PicsCategory::~PicsCategory() { arrpPC.DeleteAll(); arrpPE.DeleteAll(); } /*PicsRatingSystem----------------------------------------------------------*/ PicsRatingSystem::PicsRatingSystem() : m_pDefaultOptions(NULL), dwFlags(0), nErrLine(0) { /* nothing to do but construct members */ } PicsRatingSystem::~PicsRatingSystem() { arrpPC.DeleteAll(); if (m_pDefaultOptions != NULL) { delete m_pDefaultOptions; m_pDefaultOptions = NULL; } } void PicsRatingSystem::ReportError(HRESULT hres) { NLS_STR nls1(etstrFile.Get()); if (!nls1.QueryError()) { ISTR istrMarker(nls1); if (nls1.strchr(&istrMarker, '*')) { nls1.DelSubStr(istrMarker); } } else { nls1 = szNULL; } UINT idMsg, idTemplate; NLS_STR nlsBaseMessage(MAX_RES_STR_LEN); char szNumber[16]; /* big enough for a 32-bit (hex) number */ if (hres == E_OUTOFMEMORY || (hres > RAT_E_BASE && hres <= RAT_E_BASE + 0xffff)) { idTemplate = IDS_LOADRAT_SYNTAX_TEMPLATE; /* default is ratfile content error */ switch (hres) { case E_OUTOFMEMORY: idMsg = IDS_LOADRAT_MEMORY; idTemplate = IDS_LOADRAT_GENERIC_TEMPLATE; break; case RAT_E_EXPECTEDLEFT: idMsg = IDS_LOADRAT_EXPECTEDLEFT; break; case RAT_E_EXPECTEDRIGHT: idMsg = IDS_LOADRAT_EXPECTEDRIGHT; break; case RAT_E_EXPECTEDTOKEN: idMsg = IDS_LOADRAT_EXPECTEDTOKEN; break; case RAT_E_EXPECTEDSTRING: idMsg = IDS_LOADRAT_EXPECTEDSTRING; break; case RAT_E_EXPECTEDNUMBER: idMsg = IDS_LOADRAT_EXPECTEDNUMBER; break; case RAT_E_EXPECTEDBOOL: idMsg = IDS_LOADRAT_EXPECTEDBOOL; break; case RAT_E_DUPLICATEITEM: idMsg = IDS_LOADRAT_DUPLICATEITEM; break; case RAT_E_MISSINGITEM: idMsg = IDS_LOADRAT_MISSINGITEM; break; case RAT_E_UNKNOWNITEM: idMsg = IDS_LOADRAT_UNKNOWNITEM; break; case RAT_E_UNKNOWNMANDATORY: idMsg = IDS_LOADRAT_UNKNOWNMANDATORY; break; case RAT_E_EXPECTEDEND: idMsg = IDS_LOADRAT_EXPECTEDEND; break; default: ASSERT(FALSE); /* there aren't any other RAT_E_ errors */ idMsg = IDS_LOADRAT_UNKNOWNERROR; break; } wsprintf(szNumber, "%d", nErrLine); NLS_STR nlsNumber(STR_OWNERALLOC, szNumber); const NLS_STR *apnls[] = { &nlsNumber, NULL }; nlsBaseMessage.LoadString((USHORT)idMsg, apnls); } else { idTemplate = IDS_LOADRAT_GENERIC_TEMPLATE; if (HRESULT_FACILITY(hres) == FACILITY_WIN32) { wsprintf(szNumber, "%d", HRESULT_CODE(hres)); idMsg = IDS_LOADRAT_WINERROR; } else { wsprintf(szNumber, "0x%x", hres); idMsg = IDS_LOADRAT_MISCERROR; } NLS_STR nls1(STR_OWNERALLOC, szNumber); const NLS_STR *apnls[] = { &nls1, NULL }; nlsBaseMessage.LoadString((USHORT)idMsg, apnls); } NLS_STR nlsMessage(MAX_RES_STR_LEN); const NLS_STR *apnls[] = { &nls1, &nlsBaseMessage, NULL }; nlsMessage.LoadString((USHORT)idTemplate, apnls); if (!nlsMessage.QueryError()) { MyMessageBox(NULL, nlsMessage.QueryPch(), IDS_GENERIC, MB_OK | MB_ICONWARNING); } } /*Rating Information--------------------------------------------------------*/ BOOL PicsRatingSystemInfo::LoadProviderFiles(HKEY hKey) { char szFileName[8 + 7 + 1]; /* "Filename" + big number plus null byte */ ETS etstrFileName; int index = 0; EtStringRegRead(etstrRatingBureau, hKey, (char *)szRATINGBUREAU); wsprintf(szFileName, szFilenameTemplate, index); while (EtStringRegRead(etstrFileName, hKey, szFileName) == ERROR_SUCCESS) { PicsRatingSystem *pPRS; HRESULT hres = LoadRatingSystem(etstrFileName.Get(), &pPRS); if (pPRS != NULL) { arrpPRS.Append(pPRS); /* If the thing has a pathname, write it back out to the policy * file, in case loading the rating system marked it as invalid * (or it had been marked as invalid, but the user fixed things * and it's OK now). */ if (pPRS->etstrFile.fIsInit()) { /* If the rating system is not valid and was not previously * marked invalid, then report the error to the user. * LoadRatingSystem will have already marked the filename * as invalid for us. */ if ((pPRS->dwFlags & (PRS_ISVALID | PRS_WASINVALID)) == 0) { pPRS->ReportError(hres); /* report error to user */ } EtStringRegWrite(pPRS->etstrFile, hKey, szFileName); } } index++; wsprintf(szFileName, szFilenameTemplate, index); } return arrpPRS.Length() != 0; } BOOL RunningOnNT() { return !(::GetVersion() & 0x80000000); } // Verify the Registry Key for the Ratings can be opened with full access. // This is only useful if the Ratings registry key has been previously created. bool IsRegistryModifiable( HWND p_hwndParent ) { bool fReturn = false; CRegKey regKey; if ( regKey.Open( HKEY_LOCAL_MACHINE, ::szRATINGS, KEY_ALL_ACCESS ) == ERROR_SUCCESS ) { fReturn = true; } else { TraceMsg( TF_WARNING, "IsRegistryModifiable() - Failed to Create Registry Key Ratings for Full Access!" ); MyMessageBox( p_hwndParent, IDS_REGISTRY_NOT_MODIFIABLE, IDS_GENERIC, MB_OK|MB_ICONERROR); } return fReturn; } SID_IDENTIFIER_AUTHORITY siaNTAuthority = SECURITY_NT_AUTHORITY; SID_IDENTIFIER_AUTHORITY siaWorldAuthority = SECURITY_WORLD_SID_AUTHORITY; class CSecurityAttributes { private: SECURITY_ATTRIBUTES m_sa; LPSECURITY_ATTRIBUTES m_lpsa; PSECURITY_DESCRIPTOR m_psd; PACL m_pACL; PSID m_psidAdmins; PSID m_psidWorld; UINT m_cbACL; /* default ACL size */ public: CSecurityAttributes() { m_lpsa = NULL; m_psd = NULL; m_pACL = NULL; m_psidAdmins = NULL; m_psidWorld = NULL; m_cbACL = 1024; } ~CSecurityAttributes() { if ( m_psidAdmins != NULL ) { FreeSid(m_psidAdmins); m_psidAdmins = NULL; } if ( m_psidWorld ) { FreeSid(m_psidWorld); m_psidWorld = NULL; } if ( m_psd ) { MemFree(m_psd); m_psd = NULL; } if ( m_pACL ) { MemFree(m_pACL); m_pACL = NULL; } } LPSECURITY_ATTRIBUTES GetSecurityAttributes( void ) { return m_lpsa; } bool AllocateSecurityAttributes( void ) { m_psd = (PSECURITY_DESCRIPTOR)MemAlloc(SECURITY_DESCRIPTOR_MIN_LENGTH); if (m_psd == NULL || !InitializeSecurityDescriptor(m_psd, SECURITY_DESCRIPTOR_REVISION)) { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Security Descriptor Allocation!" ); return false; } m_pACL = (PACL)MemAlloc(m_cbACL); if (m_pACL == NULL || !InitializeAcl(m_pACL, m_cbACL, ACL_REVISION2)) { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed ACL Initialization!" ); return false; } if (!AllocateAndInitializeSid(&siaNTAuthority, 2, /* number of subauthorities */ SECURITY_BUILTIN_DOMAIN_RID, /* first subauthority: this domain */ DOMAIN_ALIAS_RID_ADMINS, /* second: admins local group */ 0, 0, 0, 0, 0, 0, /* unused subauthorities */ &m_psidAdmins)) { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed NT Authority Initialization!" ); return false; } if (!AllocateAndInitializeSid(&siaWorldAuthority, 1, /* number of subauthorities */ SECURITY_WORLD_RID, /* first subauthority: all users */ 0, 0, 0, 0, 0, 0, 0, /* unused subauthorities */ &m_psidWorld)) { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed World Authority Initialization!" ); return false; } if (!AddAccessAllowedAce(m_pACL, ACL_REVISION2, KEY_ALL_ACCESS, m_psidAdmins) || !AddAccessAllowedAce(m_pACL, ACL_REVISION2, KEY_READ, m_psidWorld)) { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Admins or World Access!" ); return false; } ACE_HEADER *pAce; /* Make both ACEs inherited by subkeys created later */ if (GetAce(m_pACL, 0, (LPVOID *)&pAce)) { pAce->AceFlags |= CONTAINER_INHERIT_ACE; } if (GetAce(m_pACL, 1, (LPVOID *)&pAce)) { pAce->AceFlags |= CONTAINER_INHERIT_ACE; } if (!SetSecurityDescriptorDacl(m_psd, TRUE, /* fDaclPresent */ m_pACL, FALSE)) /* not a default discretionary ACL */ { TraceMsg( TF_ERROR, "CSecurityAttributes::AllocateSecurityAttributes() - Failed Set of Security Descriptor!" ); return false; } m_sa.nLength = sizeof(m_sa); m_sa.lpSecurityDescriptor = m_psd; m_sa.bInheritHandle = FALSE; m_lpsa = &m_sa; return true; } }; // The following first attempts to open an existing registry key. // If the key cannot be opened, the key is created. // Under NT, the key is created with Admin read-write access and World read-only access. // Under 9x, the key is created with no special security attributes. HKEY CreateRegKeyNT(LPCSTR pszKey) { HKEY hKey = NULL; LONG err = RegOpenKey(HKEY_LOCAL_MACHINE, pszKey, &hKey); if (err == ERROR_SUCCESS) { TraceMsg( TF_ALWAYS, "CreateRegKeyNT() - Successfully Opened Ratings Registry Key." ); return hKey; } CSecurityAttributes sa; if (RunningOnNT()) { if ( ! sa.AllocateSecurityAttributes() ) { TraceMsg( TF_ERROR, "CreateRegKeyNT() - Failed to allocate security attributes()!" ); return NULL; } } DWORD dwDisp; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, pszKey, NULL, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, sa.GetSecurityAttributes(), &hKey, &dwDisp) != ERROR_SUCCESS) { TraceMsg( TF_ERROR, "CreateRegKeyNT() - Failed Registry Key Creation with %s Security Attributes!", sa.GetSecurityAttributes() ? "" : "" ); hKey = NULL; } return hKey; } HKEY PicsRatingSystemInfo::GetUserProfileKey( void ) { HKEY hkeyUser = NULL; // HKLM\System\CurrentControlSet\Control\Update RegEntry re(szPOLICYKEY, HKEY_LOCAL_MACHINE); // UpdateMode if (re.GetNumber(szPOLICYVALUE) != 0) { // HKLM\Network\Logon RegEntry reLogon(szLogonKey, HKEY_LOCAL_MACHINE); // UserProfiles if (reLogon.GetNumber(szUserProfiles) != 0) { /* The ratings key has the supervisor password and maybe other * settings. To see if there are other settings here, try to * find the user subkey (".Default"). If it's not there, we'll * try a policy file. */ // HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Ratings if (RegOpenKey(HKEY_LOCAL_MACHINE, szRATINGS, &hkeyUser) == ERROR_SUCCESS) { HKEY hkeyTemp; // .Default if (RegOpenKey(hkeyUser, szDefaultUserName, &hkeyTemp) == ERROR_SUCCESS) { RegCloseKey(hkeyTemp); hkeyTemp = NULL; } else { TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - Failed to Open key szDefaultUserName='%s'!", szDefaultUserName ); RegCloseKey(hkeyUser); hkeyUser = NULL; } } else { TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - Failed to Open key szRATINGS='%s'!", szRATINGS ); } } else { TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - No key szLogonKey='%s' szUserProfiles='%s'!", szLogonKey, szUserProfiles ); } } else { TraceMsg( TF_WARNING, "PicsRatingSystemInfo::GetUserProfileKey() - No key szPOLICYKEY='%s' szPOLICYVALUE='%s'!", szPOLICYKEY, szPOLICYVALUE ); } return hkeyUser; } BOOL PicsRatingSystemInfo::Init( void ) { PicsUser *pPU = NULL; BOOL fRet = TRUE; BOOL fIsNT; HKEY hkeyUser = NULL; CRegistryHive rh; fRatingInstalled = FALSE; pUserObject = NULL; fIsNT = RunningOnNT(); if (fIsNT) { hkeyUser = CreateRegKeyNT(::szRATINGS); fStoreInRegistry = TRUE; } else { hkeyUser = GetUserProfileKey(); if (hkeyUser != NULL) { fStoreInRegistry = TRUE; } else { fStoreInRegistry = FALSE; if ( rh.OpenHiveFile( false ) ) { hkeyUser = rh.GetHiveKey(); } } } // read information from whatever key we opened if (hkeyUser != NULL) { //First load the rating files, then load the user names. fRatingInstalled = LoadProviderFiles(hkeyUser); if ( fRatingInstalled ) { TraceMsg( TF_ALWAYS, "PicsRatingSystemInfo::Init() - Ratings Installed!" ); } else { TraceMsg( TF_ALWAYS, "PicsRatingSystemInfo::Init() - Ratings Not Installed!" ); } pPU = new PicsUser; if (pPU != NULL) { pPU->ReadFromRegistry(hkeyUser, (char *)szDefaultUserName); pUserObject = pPU; } else { fRet = FALSE; } RegCloseKey(hkeyUser); hkeyUser = NULL; /* Make sure the user settings have defaults for all installed * rating systems. */ for (int i=0; iNewInstall(); pUserObject = pPU; fRatingInstalled = TRUE; // we have settings now return TRUE; } else { return FALSE; } } extern HANDLE g_hsemStateCounter; // created at process attatch time long GetStateCounter() { long count; if (ReleaseSemaphore(g_hsemStateCounter, 1, &count)) // poll and bump the count { WaitForSingleObject(g_hsemStateCounter, 0); // reduce the count } else { count = -1; } return count; } void BumpStateCounter() { ReleaseSemaphore(g_hsemStateCounter, 1, NULL); // bump the count } // check the global semaphore count to see if we need to reconstruct our // state. void CheckGlobalInfoRev(void) { ENTERCRITICAL; if (gPRSI != NULL && !g_fIsRunningUnderCustom) { // do not reinit if under Custom if (gPRSI->nInfoRev != GetStateCounter()) { delete gPRSI; gPRSI = new PicsRatingSystemInfo; if (gPRSI != NULL) { gPRSI->Init(); } CleanupRatingHelpers(); InitRatingHelpers(); } } LEAVECRITICAL; } void PicsRatingSystemInfo::SaveRatingSystemInfo() { int z; HKEY hkeyUser = NULL; CRegistryHive rh; char szFileName[MAXPATHLEN]; if (!fSettingsValid || !fRatingInstalled) { TraceMsg( TF_WARNING, "PicsRatingSystemInfo::SaveRatingSystemInfo() - Ratings are not installed!" ); return; /* ratings aren't installed, nothing to save */ } // load the hive file if (fStoreInRegistry) { hkeyUser = CreateRegKeyNT(::szRATINGS); } else { if ( rh.OpenHiveFile( true ) ) { hkeyUser = rh.GetHiveKey(); } } // read information from local registry if (hkeyUser != NULL) { if (etstrRatingBureau.fIsInit()) { EtStringRegWrite(etstrRatingBureau, hkeyUser, (char *)szRATINGBUREAU); } else { RegDeleteValue(hkeyUser, szRATINGBUREAU); } for (z = 0; z < arrpPRS.Length(); ++z) { wsprintf(szFileName, szFilenameTemplate, z); EtStringRegWrite(arrpPRS[z]->etstrFile, hkeyUser, szFileName); } // Delete the next one, as a safety precaution wsprintf(szFileName, szFilenameTemplate, z); RegDeleteValue(hkeyUser, szFileName); pUserObject->WriteToRegistry(hkeyUser); RegCloseKey(hkeyUser); hkeyUser = NULL; } else { TraceMsg( TF_ERROR, "PicsRatingSystemInfo::SaveRatingSystemInfo() - hkeyUser is NULL!" ); } BumpStateCounter(); nInfoRev = GetStateCounter(); } HRESULT LoadRatingSystem(LPCSTR pszFilename, PicsRatingSystem **pprsOut) { TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Loading Rating System '%s'...", pszFilename ); PicsRatingSystem *pPRS = new PicsRatingSystem; *pprsOut = pPRS; if (pPRS == NULL) { TraceMsg( TF_ERROR, "LoadRatingSystem() - pPRS is NULL!" ); return E_OUTOFMEMORY; } UINT cbFilename = strlenf(pszFilename) + 1 + 1; /* room for marker character */ LPSTR pszNameCopy = new char[cbFilename]; if (pszNameCopy == NULL) { TraceMsg( TF_ERROR, "LoadRatingSystem() - pszNameCopy is NULL!" ); return E_OUTOFMEMORY; } strcpyf(pszNameCopy, pszFilename); pPRS->etstrFile.SetTo(pszNameCopy); LPSTR pszMarker = strchrf(pszNameCopy, '*'); if (pszMarker != NULL) { /* ended in marker character... */ ASSERT(*(pszMarker+1) == '\0'); pPRS->dwFlags |= PRS_WASINVALID; /* means it failed last time */ *pszMarker = '\0'; /* strip marker for loading */ } HRESULT hres; HANDLE hFile = CreateFile(pszNameCopy, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD cbFile = ::GetFileSize(hFile, NULL); BUFFER bufData(cbFile + 1); if (bufData.QueryPtr() != NULL) { LPSTR pszData = (LPSTR)bufData.QueryPtr(); DWORD cbRead; if (ReadFile(hFile, pszData, cbFile, &cbRead, NULL)) { pszData[cbRead] = '\0'; /* null terminate whole file */ hres = pPRS->Parse(pszFilename, pszData); if (SUCCEEDED(hres)) { pPRS->dwFlags |= PRS_ISVALID; } else { TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed Parse with hres=0x%x!", hres ); } } else { hres = HRESULT_FROM_WIN32(::GetLastError()); TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed ReadFile() with hres=0x%x!", hres ); } CloseHandle(hFile); } else { hres = E_OUTOFMEMORY; TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed Buffer Allocation with cbFile=%d!", cbFile ); } } else { hres = HRESULT_FROM_WIN32(::GetLastError()); TraceMsg( TF_WARNING, "LoadRatingSystem() - Failed CreateFile() with hres=0x%x!", hres ); } if (!(pPRS->dwFlags & PRS_ISVALID)) { TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Failed Loaded Rating System '%s' (hres=0x%x)!", pszFilename, hres ); strcatf(pszNameCopy, "*"); /* mark filename as invalid */ } else { TraceMsg( TF_ALWAYS, "LoadRatingSystem() - Successfully Loaded Rating System '%s'.", pszFilename ); } return hres; } // constructor for CustomRatingHelper CustomRatingHelper::CustomRatingHelper() { hLibrary = NULL; pNextHelper = NULL; dwSort = 0; } CustomRatingHelper::~CustomRatingHelper() { if (hLibrary) { FreeLibrary(hLibrary); hLibrary = NULL; } pNextHelper = NULL; } // a little function to convert from ANSI to Unicode HRESULT Ansi2Unicode(LPWSTR *pdest, LPCSTR src) { UINT cbSize; cbSize = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); if (cbSize > 0) { *pdest = new WCHAR[cbSize+1]; cbSize = MultiByteToWideChar(CP_ACP, 0, src, -1, *pdest, cbSize+1); } return cbSize > 0 ? S_OK : E_FAIL; }