|
|
/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name: fhclicfg.cpp
Abstract: Client configuration class
Revision History: created derekm 03/31/00
******************************************************************************/
#include "stdafx.h"
#include "pfrcfg.h"
// allow the configuration to be settable
#define ENABLE_SRV_CONFIG_SETTING 1
/////////////////////////////////////////////////////////////////////////////
// defaults
const EEnDis c_eedDefShowUI = eedEnabled; const EEnDis c_eedDefReport = eedEnabled; const EIncEx c_eieDefShutdown = eieExclude; const EEnDis c_eedDefShowUISrv = eedDisabled; const EEnDis c_eedDefReportSrv = eedDisabled; const EIncEx c_eieDefShutdownSrv = eieInclude;
const EEnDis c_eedDefTextLog = eedDisabled; const EIncEx c_eieDefApps = eieInclude; const EIncEx c_eieDefKernel = eieInclude; const EIncEx c_eieDefMSApps = eieInclude; const EIncEx c_eieDefWinComp = eieInclude;
const BOOL c_fForceQueue = FALSE; const BOOL c_fForceQueueSrv = TRUE;
const DWORD c_cDefHangPipes = c_cMinPipes; const DWORD c_cDefFaultPipes = c_cMinPipes; const DWORD c_cDefMaxUserQueue = 10; #if defined(DEBUG) || defined(_DEBUG)
const DWORD c_dwDefInternal = 1; #else
const DWORD c_dwDefInternal = 0; #endif
const WCHAR c_wszDefSrvI[] = L"officewatson"; const WCHAR c_wszDefSrvE[] = L"watson.microsoft.com";
/////////////////////////////////////////////////////////////////////////////
// utility
// **************************************************************************
HRESULT AddToArray(SAppList &sal, SAppItem *psai) { USE_TRACING("AddToArray");
HRESULT hr = NOERROR; DWORD i = sal.cSlotsUsed; BOOL fUseFreedSlot = FALSE;
// first, skim thru the array & see if there are any empty slots
if (sal.cSlotsEmpty > 0 && sal.rgsai != NULL) { for (i = 0; i < sal.cSlotsUsed; i++) { if (sal.rgsai[i].wszApp == NULL) { sal.cSlotsEmpty--; fUseFreedSlot = TRUE; break; } } }
// nope, see if we need to grow the array
if (sal.cSlotsUsed >= sal.cSlots && fUseFreedSlot == FALSE) { SAppItem *rgsai = NULL; DWORD cSlots;
if (sal.cSlots == 0) cSlots = 16; else cSlots = 2 * sal.cSlots; rgsai = (SAppItem *)MyAlloc(cSlots * sizeof(SAppItem)); VALIDATEEXPR(hr, (rgsai == NULL), E_OUTOFMEMORY); if (FAILED(hr)) goto done;
if (sal.rgsai != NULL) { CopyMemory(rgsai, sal.rgsai, sal.cSlots * sizeof(SAppItem)); MyFree(sal.rgsai); }
sal.rgsai = rgsai; sal.cSlots = cSlots; }
// if we are appending, then gotta increase cSlotsUsed
if (sal.cSlotsUsed == i) sal.cSlotsUsed++;
sal.rgsai[i].dwState = psai->dwState; sal.rgsai[i].wszApp = psai->wszApp;
done: return hr; }
// **************************************************************************
BOOL ClearCPLDW(HKEY hkeyCPL) { DWORD dw; WCHAR wch = L'\0'; BOOL fCleared = FALSE; HKEY hkeyDW = NULL;
if (hkeyCPL == NULL) return TRUE;
// first, try deleting the key. If that succeeded or it doesn't exist,
// then we're done.
dw = RegDeleteKeyW(hkeyCPL, c_wszRKDW); if (dw == ERROR_SUCCESS || dw == ERROR_PATH_NOT_FOUND || dw == ERROR_FILE_NOT_FOUND) { fCleared = TRUE; goto done; }
// Otherwise, need to open the key
dw = RegOpenKeyExW(hkeyCPL, c_wszRKDW, 0, KEY_READ | KEY_WRITE, &hkeyDW); if (dw != ERROR_SUCCESS) goto done;
// try to delete the file path value from it.
dw = RegDeleteValueW(hkeyDW, c_wszRVDumpPath); if (dw == ERROR_SUCCESS || dw == ERROR_PATH_NOT_FOUND || dw == ERROR_FILE_NOT_FOUND) { fCleared = TRUE; goto done; }
// ok, last try. Try to write an empty string to the value
dw = RegSetValueExW(hkeyDW, c_wszRVDumpPath, 0, REG_SZ, (LPBYTE)wch, sizeof(wch)); if (dw == ERROR_SUCCESS) { fCleared = TRUE; goto done; }
done: if (hkeyDW != NULL) RegCloseKey(hkeyDW);
return fCleared; }
/////////////////////////////////////////////////////////////////////////////
// CPFFaultClientCfg- init & term
// **************************************************************************
CPFFaultClientCfg::CPFFaultClientCfg() { OSVERSIONINFOEXW osvi;
INIT_TRACING USE_TRACING("CPFFaultClientCfg::CPFFaultClientCfg");
InitializeCriticalSection(&m_cs);
ZeroMemory(m_wszDump, sizeof(m_wszDump)); ZeroMemory(m_wszSrv, sizeof(m_wszSrv)); ZeroMemory(m_rgLists, sizeof(m_rgLists));
ZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionExW((OSVERSIONINFOW *)&osvi);
if (osvi.wProductType == VER_NT_SERVER) { m_eieShutdown = c_eieDefShutdownSrv; m_fForceQueue = c_fForceQueueSrv; m_fSrv = TRUE; } else { m_eieShutdown = c_eieDefShutdown; m_fForceQueue = c_fForceQueue; m_fSrv = FALSE; }
m_eedUI = c_eedDefShowUI; m_eedReport = c_eedDefReport; m_eieApps = c_eieDefApps; m_eedTextLog = c_eedDefTextLog; m_eieMS = c_eieDefMSApps; m_eieWin = c_eieDefWinComp; m_eieKernel = c_eieDefKernel; m_cFaultPipes = c_cDefFaultPipes; m_cHangPipes = c_cDefHangPipes; m_cMaxQueueItems = c_cDefMaxUserQueue;
m_dwStatus = 0; m_dwDirty = 0; m_pbWinApps = NULL; m_fRead = FALSE; m_fRO = FALSE; }
// **************************************************************************
CPFFaultClientCfg::~CPFFaultClientCfg(void) { this->Clear(); DeleteCriticalSection(&m_cs); }
// **************************************************************************
void CPFFaultClientCfg::Clear(void) { USE_TRACING("CPFFaultClientCfg::Clear");
DWORD i;
for(i = 0; i < epfltListCount; i++) { if (m_rgLists[i].hkey != NULL) RegCloseKey(m_rgLists[i].hkey); if (m_rgLists[i].rgsai != NULL) { DWORD iSlot; for (iSlot = 0; iSlot < m_rgLists[i].cSlotsUsed; iSlot++) { if (m_rgLists[i].rgsai[iSlot].wszApp != NULL) MyFree(m_rgLists[i].rgsai[iSlot].wszApp); } MyFree(m_rgLists[i].rgsai); } } ZeroMemory(m_wszDump, sizeof(m_wszDump)); ZeroMemory(m_wszSrv, sizeof(m_wszSrv)); ZeroMemory(m_rgLists, sizeof(m_rgLists)); if (m_fSrv) { m_eieShutdown = c_eieDefShutdownSrv; m_fForceQueue = c_fForceQueueSrv; } else { m_eieShutdown = c_eieDefShutdown; m_fForceQueue = c_fForceQueue; }
m_eedUI = c_eedDefShowUI; m_eedReport = c_eedDefReport; m_eieApps = c_eieDefApps; m_eedTextLog = c_eedDefTextLog; m_eieMS = c_eieDefMSApps; m_eieWin = c_eieDefWinComp; m_eieKernel = c_eieDefKernel; m_cFaultPipes = c_cDefFaultPipes; m_cHangPipes = c_cDefHangPipes; m_cMaxQueueItems = c_cDefMaxUserQueue;
m_dwStatus = 0; m_dwDirty = 0; m_pbWinApps = NULL; m_fRead = FALSE; m_fRO = FALSE; }
/////////////////////////////////////////////////////////////////////////////
// CPFFaultClientCfg- exposed
// **************************************************************************
HRESULT CPFFaultClientCfg::Read(EReadOptions ero) { USE_TRACING("CPFFaultClientCfg::Read");
CAutoUnlockCS aucs(&m_cs);
HRESULT hr = NOERROR; WCHAR wch = L'\0', *wszDefSrv; DWORD cb, dw, i, cKeys = 0, iReport = 0, iShowUI = 0; DWORD dwOpt; HKEY rghkeyCfg[2], hkeyCfgDW = NULL, hkeyCPL = NULL; BOOL fHavePolicy = FALSE;
// this will automatically unlock when the fn exits
aucs.Lock();
dwOpt = (ero == eroCPRW) ? orkWantWrite : 0;
this->Clear();
rghkeyCfg[0] = NULL; rghkeyCfg[1] = NULL;
// if we open read-only, then we will also try to read from the policy
// settings cuz they override the control panel settings. If the user
// wants write access, then we don't bother cuz we don't support writing
// to the policy keys via this object.
// We use the RegOpenKeyEx function directly here cuz I don't want to
// create the key if it doesn't exist (and that's what OpenRegKey will do)
if (ero == eroPolicyRO) { TESTERR(hr, RegOpenKeyExW(HKEY_LOCAL_MACHINE, c_wszRPCfgPolicy, 0, KEY_READ | KEY_WOW64_64KEY, &rghkeyCfg[0])); if (SUCCEEDED(hr)) { cKeys = 1; fHavePolicy = TRUE; DBG_MSG("policy found"); } }
// open the control panel reg key
TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, 0, &rghkeyCfg[cKeys])); if (SUCCEEDED(hr)) { // need to check if a filepath exists in the DW control panel key. If
// so, disable reporting & enable the UI (if reporting was enabled)
if (ClearCPLDW(rghkeyCfg[cKeys]) == FALSE) m_dwStatus |= CPL_CORPPATH_SET;
hkeyCPL = rghkeyCfg[cKeys]; cKeys++; }
// if we couldn't open either key successfully, then we don't need to do
// anything else. The call to 'this->Clear()' above has already set
// all the values to their defaults.
VALIDATEPARM(hr, (cKeys == 0)); if (FAILED(hr)) { hr = NOERROR; goto doneValidate; }
// read in the report value
cb = sizeof(m_eedReport); dw = c_eedDefReport; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVDoReport, NULL, (PBYTE)&m_eedReport, &cb, (PBYTE)&dw, sizeof(dw), &iReport)); if (FAILED(hr)) goto done;
// read in the ui value
cb = sizeof(m_eedUI); dw = c_eedDefShowUI; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVShowUI, NULL, (PBYTE)&m_eedUI, &cb, (PBYTE)&dw, sizeof(dw), &iShowUI)); if (FAILED(hr)) goto done;
// set the policy info (note that the policy key is always set into
// slot 0 of the array)
if (fHavePolicy) { if (iReport == 0) m_dwStatus |= REPORT_POLICY; if (iShowUI == 0) m_dwStatus |= SHOWUI_POLICY;
ErrorTrace(0, " iReport = %d, iShowUI = %d", iReport, iShowUI);
// if we used the default value for reporting (we didn't find the
// 'report' value anywhere) then try to use the control panel settings
// for the rest of the stuff.
if (iReport == 2 && cKeys == 2) iReport = 1;
// if THAT doesn't exist, just bail cuz all of the other values have
// already been set to their defaults
else if (iReport == 1 && cKeys == 1) goto doneValidate;
// only use the key where we read the 'DoReport' value from. Don't care
// what the other key has to say...
if (iReport == 1) { HKEY hkeySwap = rghkeyCfg[0];
rghkeyCfg[0] = rghkeyCfg[1]; rghkeyCfg[1] = hkeySwap; DBG_MSG("POLICY and CPL controls INVERTED!!!"); }
cKeys = 1; }
// read in the inclusion list value
cb = sizeof(m_eieApps); dw = c_eieDefApps; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVAllNone, NULL, (PBYTE)&m_eieApps, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the inc MS value
cb = sizeof(m_eieMS); dw = c_eieDefMSApps; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncMS, NULL, (PBYTE)&m_eieMS, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the inc Windows components
cb = sizeof(m_eieWin); dw = c_eieDefWinComp; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncWinComp, NULL, (PBYTE)&m_eieWin, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the text log value
cb = sizeof(m_eedTextLog); dw = c_eedDefTextLog; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVDoTextLog, NULL, (PBYTE)&m_eedTextLog, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the include kernel faults value
cb = sizeof(m_eieKernel); dw = c_eieDefKernel; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncKernel, NULL, (PBYTE)&m_eieKernel, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done; // read in the include shutdown errs value
cb = sizeof(m_eieShutdown); dw = (m_fSrv) ? c_eieDefShutdownSrv : c_eieDefShutdown; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncShutdown, NULL, (PBYTE)&m_eieShutdown, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done; // read in the # of fault pipes value
cb = sizeof(m_cFaultPipes); dw = c_cDefFaultPipes; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVNumFaultPipe, NULL, (PBYTE)&m_cFaultPipes, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the # of hang pipes value
cb = sizeof(m_cHangPipes); dw = c_cDefHangPipes; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVNumHangPipe, NULL, (PBYTE)&m_cHangPipes, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the max queue size value
cb = sizeof(m_cMaxQueueItems); dw = c_cDefMaxUserQueue; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVMaxQueueSize, NULL, (PBYTE)&m_cMaxQueueItems, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
// read in the force queue mode value
cb = sizeof(m_fForceQueue); dw = (m_fSrv) ? c_fForceQueueSrv : c_fForceQueue; TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVForceQueue, NULL, (PBYTE)&m_fForceQueue, &cb, (PBYTE)&dw, sizeof(dw))); if (FAILED(hr)) goto done;
m_dwUseInternal=0; wcscpy(m_wszSrv, c_wszDefSrvE);
// the dump path is stored in the DW reg key, so we need to try to
// open it up. However, we only need this value if we're going
// to go into headless mode
if (m_eedReport == eedEnabled && m_eedUI == eedDisabled) { // if the cpl corp path is set, we can't let DW do any reporting...
if ((m_dwStatus & REPORT_POLICY) == 0 && (m_dwStatus & CPL_CORPPATH_SET) != 0 && m_eedReport == eedEnabled) m_eedReport = eedDisabled;
if (m_eedReport == eedEnabled) { TESTERR(hr, RegOpenKeyExW(rghkeyCfg[0], c_wszRKDW, 0, KEY_READ, &hkeyCfgDW)); if (SUCCEEDED(hr)) { // read in the dump path value
cb = sizeof(m_wszDump); TESTHR(hr, ReadRegEntry(&hkeyCfgDW, 1, c_wszRVDumpPath, NULL, (PBYTE)m_wszDump, &cb, (PBYTE)&wch, sizeof(wch))); if (FAILED(hr)) goto done; } } }
// it's ok if these fail. The code below will correctly deal with the
// situation...
TESTHR(hr, OpenRegKey(rghkeyCfg[0], c_wszRKExList, dwOpt, &m_rgLists[epfltExclude].hkey)); if (FAILED(hr)) m_rgLists[epfltExclude].hkey = NULL;
TESTHR(hr, OpenRegKey(rghkeyCfg[0], c_wszRKIncList, dwOpt, &m_rgLists[epfltInclude].hkey)); if (FAILED(hr)) m_rgLists[epfltInclude].hkey = NULL;
hr = NOERROR;
doneValidate: // validate the data we've read and reset the values to defaults if they
// are outside of the allowable range of values
if (m_eedUI != eedEnabled && m_eedUI != eedDisabled && m_eedUI != eedEnabledNoCheck) m_eedUI = c_eedDefShowUI;
if (m_eedReport != eedEnabled && m_eedReport != eedDisabled) m_eedReport = c_eedDefReport; if (m_eedTextLog != eedEnabled && m_eedTextLog != eedDisabled) m_eedTextLog = c_eedDefTextLog; if (m_eieApps != eieIncDisabled && m_eieApps != eieExDisabled && m_eieApps != eieInclude && m_eieApps != eieExclude) m_eieApps = c_eieDefApps; if (m_eieMS != eieInclude && m_eieMS != eieExclude) m_eieMS = c_eieDefMSApps; if (m_eieKernel != eieInclude && m_eieKernel != eieExclude) m_eieKernel = c_eieDefKernel;
if (m_eieShutdown != eieInclude && m_eieShutdown != eieExclude) m_eieShutdown = (m_fSrv) ? c_eieDefShutdownSrv : c_eieDefShutdown; if (m_eieWin != eieInclude && m_eieWin != eieExclude) m_eieWin = c_eieDefWinComp; if (m_dwUseInternal != 1 && m_dwUseInternal != 0) m_dwUseInternal = c_dwDefInternal;
if (m_cFaultPipes < c_cMinPipes) m_cFaultPipes = c_cMinPipes; else if (m_cFaultPipes > c_cMaxPipes) m_cFaultPipes = c_cMaxPipes;
if (m_cHangPipes == c_cMinPipes) m_cHangPipes = c_cMinPipes; else if (m_cHangPipes > c_cMaxPipes) m_cHangPipes = c_cMaxPipes;
if (m_cMaxQueueItems > c_cMaxQueue) m_cMaxQueueItems = c_cMaxQueue;
if (m_fForceQueue != c_fForceQueue && m_fForceQueue != c_fForceQueueSrv) m_fForceQueue = (m_fSrv) ? c_fForceQueueSrv : c_fForceQueue;
m_fRead = TRUE; m_fRO = (ero != eroCPRW);
aucs.Unlock();
done: if (rghkeyCfg[0] != NULL) RegCloseKey(rghkeyCfg[0]); if (rghkeyCfg[1] != NULL) RegCloseKey(rghkeyCfg[1]); if (hkeyCfgDW != NULL) RegCloseKey(hkeyCfgDW); if (FAILED(hr)) this->Clear();
return hr; }
#ifndef PFCLICFG_LITE
// **************************************************************************
BOOL CPFFaultClientCfg::HasWriteAccess(void) { USE_TRACING("CPFFaultClientCfg::HasWriteAccess"); HRESULT hr = NOERROR; DWORD dwOpt = orkWantWrite; HKEY hkeyMain = NULL, hkey = NULL;
// attempt to open all the keys we use for the control panal to see if we
// have write access to them. We only do this for the control panal cuz
// this class does not support writing out policy values, just reading
// them...
TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, dwOpt, &hkeyMain)); if (FAILED(hr)) goto done;
RegCloseKey(hkey); hkey = NULL;
TESTHR(hr, OpenRegKey(hkeyMain, c_wszRKExList, dwOpt, &hkey)); if (FAILED(hr)) goto done;
RegCloseKey(hkey); hkey = NULL;
TESTHR(hr, OpenRegKey(hkeyMain, c_wszRKIncList, dwOpt, &hkey)); if (FAILED(hr)) goto done;
done: if (hkeyMain != NULL) RegCloseKey(hkeyMain); if (hkey != NULL) RegCloseKey(hkey);
return (SUCCEEDED(hr)); }
// **************************************************************************
HRESULT CPFFaultClientCfg::Write(void) { USE_TRACING("CPFFaultClientCfg::Write");
CAutoUnlockCS aucs(&m_cs);
HRESULT hr = NOERROR; DWORD dwOpt = orkWantWrite; HKEY hkeyCfg = NULL;
// this will automatically unlock when the fn exits
aucs.Lock(); if (m_fRO) { hr = E_ACCESSDENIED; goto done; }
TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, dwOpt, &hkeyCfg)); if (FAILED(hr)) goto done;
// inclusion / exclusion list value
if ((m_dwDirty & FHCC_ALLNONE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVAllNone, 0, REG_DWORD, (PBYTE)&m_eieApps, sizeof(m_eieApps))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_ALLNONE; }
// ms apps in except list value
if ((m_dwDirty & FHCC_INCMS) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncMS, 0, REG_DWORD, (PBYTE)&m_eieMS, sizeof(m_eieMS))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_INCMS; }
// ms apps in except list value
if ((m_dwDirty & FHCC_WINCOMP) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncWinComp, 0, REG_DWORD, (PBYTE)&m_eieWin, sizeof(m_eieWin))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_WINCOMP; }
// show UI value
if ((m_dwDirty & FHCC_SHOWUI) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVShowUI, 0, REG_DWORD, (PBYTE)&m_eedUI, sizeof(m_eedUI))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_SHOWUI; }
// do reporting value
if ((m_dwDirty & FHCC_DOREPORT) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDoReport, 0, REG_DWORD, (PBYTE)&m_eedReport, sizeof(m_eedReport))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_DOREPORT; }
// include kernel faults value
if ((m_dwDirty & FHCC_R0INCLUDE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncKernel, 0, REG_DWORD, (PBYTE)&m_eieKernel, sizeof(m_eieKernel))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_R0INCLUDE; }
// include shutdown value
if ((m_dwDirty & FHCC_INCSHUTDOWN) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncShutdown, 0, REG_DWORD, (PBYTE)&m_eieShutdown, sizeof(m_eieShutdown))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_INCSHUTDOWN; } // # fault pipes value
if ((m_dwDirty & FHCC_NUMFAULTPIPE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVNumFaultPipe, 0, REG_DWORD, (PBYTE)&m_cFaultPipes, sizeof(m_cFaultPipes))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_NUMFAULTPIPE; }
// # hang pipes value
if ((m_dwDirty & FHCC_NUMHANGPIPE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVNumHangPipe, 0, REG_DWORD, (PBYTE)&m_cHangPipes, sizeof(m_cHangPipes))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_NUMHANGPIPE; }
// max user fault queue size value
if ((m_dwDirty & FHCC_QUEUESIZE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVMaxQueueSize, 0, REG_DWORD, (PBYTE)&m_cMaxQueueItems, sizeof(m_cMaxQueueItems))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_QUEUESIZE; } // default Server value
if ((m_dwDirty & FHCC_DEFSRV) != 0) { DWORD cb;
cb = wcslen(m_wszSrv) * sizeof(WCHAR); TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDefSrv, 0, REG_DWORD, (PBYTE)m_wszSrv, cb)); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_DEFSRV; }
// dump path value
if ((m_dwDirty & FHCC_DUMPPATH) != 0) { DWORD cb;
cb = wcslen(m_wszDump) * sizeof(WCHAR); TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDumpPath, 0, REG_DWORD, (PBYTE)m_wszDump, cb)); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_DUMPPATH; }
// force queue mode value
if ((m_dwDirty & FHCC_FORCEQUEUE) != 0) { TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVForceQueue, 0, REG_DWORD, (PBYTE)&m_fForceQueue, sizeof(m_fForceQueue))); if (FAILED(hr)) goto done;
m_dwDirty &= ~FHCC_FORCEQUEUE; }
aucs.Unlock();
done: if (hkeyCfg != NULL) RegCloseKey(hkeyCfg); return hr; }
#endif // PFCLICFG_LITE
// **************************************************************************
BOOL CPFFaultClientCfg::ShouldCollect(LPWSTR wszAppPath, BOOL *pfIsMSApp) { USE_TRACING("CPFFaultClientCfg::ShouldCollect");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; WCHAR *pwszApp, wszName[MAX_PATH], wszAppPathLocal[MAX_PATH]; DWORD i, cb, dwChecked, dw, dwMS, dwType; BOOL fCollect = FALSE;
if (wszAppPath == NULL) { GetModuleFileNameW(NULL, wszAppPathLocal, sizeofSTRW(wszAppPathLocal)); wszAppPath = wszAppPathLocal; }
if (pfIsMSApp != NULL) *pfIsMSApp = FALSE;
aucs.Lock();
if (m_fRead == FALSE) { TESTHR(hr, this->Read()); if (FAILED(hr)) goto done; }
// if we have reporting turned off or the 'programs' checkbox has been cleared
// in the control panel, then we are definitely not reporting
if (m_eedReport == eedDisabled || m_eieApps == eieExDisabled || m_eieApps == eieIncDisabled) { fCollect = FALSE; goto done; }
// get a pointer to the app name
for (pwszApp = wszAppPath + wcslen(wszAppPath); *pwszApp != L'\\' && pwszApp != wszAppPath; pwszApp--); if (*pwszApp == L'\\') pwszApp++;
// are we collecting everything by default?
if (m_eieApps == eieInclude) fCollect = TRUE;
if (fCollect == FALSE || pfIsMSApp != NULL) { // nope, check if it's another Microsoft app...
dwMS = IsMicrosoftApp(wszAppPath, NULL, 0);
if (dwMS != 0 && pfIsMSApp != NULL) *pfIsMSApp = TRUE; // is it a windows component?
if (m_eieWin == eieInclude && (dwMS & APP_WINCOMP) != 0) fCollect = TRUE;
// is it a MS app?
if (m_eieMS == eieInclude && (dwMS & APP_MSAPP) != 0) fCollect = TRUE; }
// see if it's on the inclusion list (only need to do this if we aren't
// already collecting).
// Note that if the value is not a DWORD key or we get back an error
// saying that we don't have enuf space to hold the data, we just assume
// that it should be included.
if (fCollect == FALSE && m_rgLists[epfltInclude].hkey != NULL) { cb = sizeof(dwChecked); dwType = REG_DWORD; dw = RegQueryValueExW(m_rgLists[epfltInclude].hkey, pwszApp, NULL, &dwType, (PBYTE)&dwChecked, &cb); if ((dw == ERROR_SUCCESS && (dwChecked == 1 || dwType != REG_DWORD)) || dw == ERROR_MORE_DATA) fCollect = TRUE; }
// see if it's on the exclusion list (only need to do this if we are going
// to collect something)
// Note that if the value is not a DWORD key or we get back an error
// saying that we don't have enuf space to hold the data, we just assume
// that it should be excluded.
if (fCollect && m_rgLists[epfltExclude].hkey != NULL) { cb = sizeof(dwChecked); dwType = REG_DWORD; dw = RegQueryValueExW(m_rgLists[epfltExclude].hkey, pwszApp, NULL, &dwType, (PBYTE)&dwChecked, &cb); if ((dw == ERROR_SUCCESS && (dwChecked == 1 || dwType != REG_DWORD)) || dw == ERROR_MORE_DATA) fCollect = FALSE; }
done: return fCollect; }
/////////////////////////////////////////////////////////////////////////////
// CPFFaultClientCfg- get properties
// **************************************************************************
static inline LPCWSTR get_string(LPWSTR wszOut, LPWSTR wszSrc, int cchOut) { LPCWSTR wszRet;
SetLastError(0); if (wszOut == NULL) { wszRet = wszSrc; } else { wszRet = wszOut; if (cchOut < lstrlenW(wszSrc)) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return NULL; }
lstrcpyW(wszOut, wszSrc); }
return wszRet; }
// **************************************************************************
LPCWSTR CPFFaultClientCfg::get_DumpPath(LPWSTR wsz, int cch) { USE_TRACING("CPFFaultClientCfg::get_DumpPath");
CAutoUnlockCS aucs(&m_cs); aucs.Lock(); return get_string(wsz, m_wszDump, cch); }
// **************************************************************************
LPCWSTR CPFFaultClientCfg::get_DefaultServer(LPWSTR wsz, int cch) { USE_TRACING("CPFFaultClientCfg::get_DefaultServer"); CAutoUnlockCS aucs(&m_cs); aucs.Lock(); return get_string(wsz, m_wszSrv, cch); }
#ifndef PFCLICFG_LITE
/////////////////////////////////////////////////////////////////////////////
// CPFFaultClientCfg- set properties
// **************************************************************************
BOOL CPFFaultClientCfg::set_DumpPath(LPCWSTR wsz) { USE_TRACING("CPFFaultClientCfg::set_DumpPath");
CAutoUnlockCS aucs(&m_cs);
if (wsz == NULL || (wcslen(wsz) + 1) > sizeofSTRW(m_wszDump)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); wcscpy(m_wszDump, wsz); m_dwDirty |= FHCC_DUMPPATH; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_DefaultServer(LPCWSTR wsz) { USE_TRACING("CPFFaultClientCfg::set_DefaultServer");
CAutoUnlockCS aucs(&m_cs);
if (wsz == NULL || (wcslen(wsz) + 1) > sizeofSTRW(m_wszSrv)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); wcscpy(m_wszSrv, wsz); m_dwDirty |= FHCC_DEFSRV; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_ShowUI(EEnDis eed) { USE_TRACING("CPFFaultClientCfg::set_ShowUI");
CAutoUnlockCS aucs(&m_cs);
if (eed & ~1 && (DWORD)eed != 3) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } aucs.Lock(); m_eedUI = eed; m_dwDirty |= FHCC_SHOWUI; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_DoReport(EEnDis eed) { USE_TRACING("CPFFaultClientCfg::set_DoReport");
CAutoUnlockCS aucs(&m_cs);
if (eed & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } aucs.Lock(); m_eedReport = eed; m_dwDirty |= FHCC_DOREPORT; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_AllOrNone(EIncEx eie) { USE_TRACING("CPFFaultClientCfg::set_AllOrNone");
CAutoUnlockCS aucs(&m_cs); if (eie & ~3) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_eieApps = eie; m_dwDirty |= FHCC_ALLNONE; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_IncMSApps(EIncEx eie) { USE_TRACING("CPFFaultClientCfg::set_IncMSApps");
CAutoUnlockCS aucs(&m_cs);
if (eie & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_eieMS = eie; m_dwDirty |= FHCC_INCMS; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_IncWinComp(EIncEx eie) { USE_TRACING("CPFFaultClientCfg::set_IncWinComp");
CAutoUnlockCS aucs(&m_cs);
if (eie & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_eieWin = eie; m_dwDirty |= FHCC_WINCOMP; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_IncKernel(EIncEx eie) { USE_TRACING("CPFFaultClientCfg::set_IncKernel");
CAutoUnlockCS aucs(&m_cs);
if (eie & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_eieKernel = eie; m_dwDirty |= FHCC_R0INCLUDE; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_IncShutdown(EIncEx eie) { USE_TRACING("CPFFaultClientCfg::set_IncShutdown");
CAutoUnlockCS aucs(&m_cs);
if (eie & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_eieShutdown = eie; m_dwDirty |= FHCC_INCSHUTDOWN; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_ForceQueueMode(BOOL fForceQueueMode) { USE_TRACING("CPFFaultClientCfg::set_IncKernel");
CAutoUnlockCS aucs(&m_cs);
if (fForceQueueMode & ~1) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_fForceQueue = fForceQueueMode; m_dwDirty |= FHCC_FORCEQUEUE; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_NumFaultPipes(DWORD cPipes) { USE_TRACING("CPFFaultClientCfg::set_NumFaultPipes");
CAutoUnlockCS aucs(&m_cs);
if (cPipes == 0 || cPipes > 8) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_cFaultPipes = cPipes; m_dwDirty |= FHCC_NUMFAULTPIPE; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_NumHangPipes(DWORD cPipes) { USE_TRACING("CPFFaultClientCfg::set_NumHangPipes");
CAutoUnlockCS aucs(&m_cs);
if (cPipes == 0 || cPipes > 8) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_cHangPipes = cPipes; m_dwDirty |= FHCC_NUMHANGPIPE; return TRUE; }
// **************************************************************************
BOOL CPFFaultClientCfg::set_MaxUserQueueSize(DWORD cItems) { USE_TRACING("CPFFaultClientCfg::set_MaxUserQueueSize");
CAutoUnlockCS aucs(&m_cs);
if (cItems == 0 || cItems > 256) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
aucs.Lock(); m_cMaxQueueItems = cItems; m_dwDirty |= FHCC_QUEUESIZE; return TRUE; }
/////////////////////////////////////////////////////////////////////////////
// App lists
// **************************************************************************
HRESULT CPFFaultClientCfg::InitList(EPFListType epflt) { USE_TRACING("CPFFaultClientCfg::get_IncListCount");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; DWORD cItems = 0; VALIDATEPARM(hr, (epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRead == FALSE) { hr = E_FAIL; goto done;; }
// if we've already initialized, then just clear the list out & return
if ((m_rgLists[epflt].dwState & epfaaInitialized) != 0) { this->ClearChanges(epflt); m_rgLists[epflt].dwState &= ~epfaaInitialized; }
if (m_rgLists[epflt].hkey != NULL) { TESTERR(hr, RegQueryInfoKeyW(m_rgLists[epflt].hkey, NULL, NULL, NULL, NULL, NULL, NULL, &m_rgLists[epflt].cItemsInReg, &m_rgLists[epflt].cchMaxVal, NULL, NULL, NULL)); if (FAILED(hr)) goto done; } else { m_rgLists[epflt].cItemsInReg = 0; m_rgLists[epflt].cchMaxVal = 0; }
m_rgLists[epflt].dwState |= epfaaInitialized; done: return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::get_ListRegInfo(EPFListType epflt, DWORD *pcbMaxName, DWORD *pcApps) { USE_TRACING("CPFFaultClientCfg::get_ListRegInfo");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; VALIDATEPARM(hr, (pcbMaxName == NULL || pcApps == NULL || epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
*pcbMaxName = 0; *pcApps = 0;
if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
*pcbMaxName = m_rgLists[epflt].cchMaxVal; *pcApps = m_rgLists[epflt].cItemsInReg;
done: return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::get_ListRegApp(EPFListType epflt, DWORD iApp, LPWSTR wszApp, DWORD cchApp, DWORD *pdwChecked) { USE_TRACING("CPFFaultClientCfg::get_ListApp");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; WCHAR wsz[MAX_PATH]; DWORD cchName, cbData, dw, dwType = 0;
VALIDATEPARM(hr, (wszApp == NULL || pdwChecked == NULL || epflt >= epfltListCount)); if (FAILED(hr)) goto done;
*wszApp = L'\0'; *pdwChecked = 0;
aucs.Lock(); if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
cchName = cchApp; cbData = sizeof(DWORD); dw = RegEnumValueW(m_rgLists[epflt].hkey, iApp, wszApp, &cchName, NULL, &dwType, (LPBYTE)pdwChecked, &cbData); if (dw != ERROR_SUCCESS && dw != ERROR_NO_MORE_ITEMS) { if (dw == ERROR_MORE_DATA) { dw = RegEnumValueW(m_rgLists[epflt].hkey, iApp, wszApp, &cchName, NULL, NULL, NULL, NULL); *pdwChecked = 1; }
TESTERR(hr, dw); goto done; }
if (dwType != REG_DWORD || (*pdwChecked != 1 && *pdwChecked != 0)) *pdwChecked = 1;
if (dw == ERROR_NO_MORE_ITEMS) { hr = S_FALSE; goto done; }
done: return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::add_ListApp(EPFListType epflt, LPCWSTR wszApp) { USE_TRACING("CPFFaultClientCfg::add_ListApp");
CAutoUnlockCS aucs(&m_cs); SAppItem sai; HRESULT hr = NOERROR; LPWSTR wszExe = NULL; DWORD dw = 0, i;
VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRO == TRUE) { hr = E_ACCESSDENIED; goto done; }
if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
// first, check if it's already on the mod list
for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { if (m_rgLists[epflt].rgsai[i].wszApp != NULL && _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0) { SETADD(m_rgLists[epflt].rgsai[i].dwState); SETCHECK(m_rgLists[epflt].rgsai[i].dwState); goto done; } }
// add it to the list then...
wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR)); VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY); if (FAILED(hr)) goto done;
wcscpy(wszExe, wszApp); sai.wszApp = wszExe; SETADD(sai.dwState); SETCHECK(sai.dwState);
TESTHR(hr, AddToArray(m_rgLists[epflt], &sai)); if (FAILED(hr)) goto done; wszExe = NULL;
done: if (wszExe != NULL) MyFree(wszExe);
return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::del_ListApp(EPFListType epflt, LPWSTR wszApp) { USE_TRACING("CPFFaultClientCfg::del_ListApp");
CAutoUnlockCS aucs(&m_cs); SAppItem sai; HRESULT hr = NOERROR; LPWSTR wszExe = NULL; DWORD i;
VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRO == TRUE) { hr = E_ACCESSDENIED; goto done; }
// first, check if it's already on the mod list for add
for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { if (m_rgLists[epflt].rgsai[i].wszApp != NULL && _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0) { if (m_rgLists[epflt].rgsai[i].dwState & epfaaAdd) { // just set the wszApp field to NULL. we'll reuse it
// on the next add to the array (if any)
MyFree(m_rgLists[epflt].rgsai[i].wszApp); m_rgLists[epflt].rgsai[i].wszApp = NULL; m_rgLists[epflt].rgsai[i].dwState = 0; m_rgLists[epflt].cSlotsEmpty++; } else { SETDEL(m_rgLists[epflt].rgsai[i].dwState); }
goto done; } }
// add it to the list then...
wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR)); VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY); if (FAILED(hr)) goto done;
wcscpy(wszExe, wszApp); sai.wszApp = wszExe; SETDEL(sai.dwState);
TESTHR(hr, AddToArray(m_rgLists[epflt], &sai)); if (FAILED(hr)) goto done;
wszExe = NULL;
done: if (wszExe != NULL) MyFree(wszExe);
return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::mod_ListApp(EPFListType epflt, LPWSTR wszApp, DWORD dwChecked) { USE_TRACING("CPFFaultClientCfg::del_ListApp");
CAutoUnlockCS aucs(&m_cs); SAppItem sai; HRESULT hr = NOERROR; LPWSTR wszExe = NULL; DWORD i;
VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRO == TRUE) { hr = E_ACCESSDENIED; goto done; }
// first, check if it's already on the mod list
for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { if (m_rgLists[epflt].rgsai[i].wszApp != NULL && _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0) { if (dwChecked == 0) { REMCHECK(m_rgLists[epflt].rgsai[i].dwState); } else { SETCHECK(m_rgLists[epflt].rgsai[i].dwState); }
goto done; } }
// add it to the list then...
wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR)); VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY); if (FAILED(hr)) goto done;
wcscpy(wszExe, wszApp); sai.wszApp = wszExe; sai.dwState = ((dwChecked == 0) ? epfaaRemCheck : epfaaSetCheck);
TESTHR(hr, AddToArray(m_rgLists[epflt], &sai)); if (FAILED(hr)) goto done; wszExe = NULL;
done: if (wszExe != NULL) MyFree(wszExe);
return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::ClearChanges(EPFListType epflt) { USE_TRACING("CPFFaultClientCfg::ClearChanges");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; DWORD i;
VALIDATEPARM(hr, (epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
if (m_rgLists[epflt].rgsai == NULL) goto done;
for(i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { m_rgLists[epflt].rgsai[i].dwState = 0; if (m_rgLists[epflt].rgsai[i].wszApp != NULL) { MyFree(m_rgLists[epflt].rgsai[i].wszApp); m_rgLists[epflt].rgsai[i].wszApp = NULL; } }
m_rgLists[epflt].cSlotsUsed = 0;
done: return hr; }
// **************************************************************************
HRESULT CPFFaultClientCfg::CommitChanges(EPFListType epflt) { USE_TRACING("CPFFaultClientCfg::CommitChanges");
CAutoUnlockCS aucs(&m_cs); HRESULT hr = NOERROR; DWORD i, dw;
VALIDATEPARM(hr, (epflt >= epfltListCount)); if (FAILED(hr)) goto done;
aucs.Lock();
if (m_fRO == TRUE) { hr = E_ACCESSDENIED; goto done; }
if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
if (m_rgLists[epflt].hkey == NULL) { hr = E_ACCESSDENIED; goto done; }
if (m_rgLists[epflt].rgsai == NULL) goto done;
// don't need to compress the array. Since we always append & never
// delete out of the array until a commit, once I hit an 'Add', anything
// after that in the array MUST also be an 'Add'.
for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { if (m_rgLists[epflt].rgsai[i].wszApp == NULL) { m_rgLists[epflt].rgsai[i].dwState = 0; continue; }
if ((m_rgLists[epflt].rgsai[i].dwState & epfaaDelete) != 0) { dw = RegDeleteValueW(m_rgLists[epflt].hkey, m_rgLists[epflt].rgsai[i].wszApp); if (dw != ERROR_SUCCESS && dw != ERROR_FILE_NOT_FOUND) { TESTERR(hr, dw); goto done; } }
else { DWORD dwChecked;
dwChecked = (ISCHECKED(m_rgLists[epflt].rgsai[i].dwState)) ? 1 : 0; TESTERR(hr, RegSetValueExW(m_rgLists[epflt].hkey, m_rgLists[epflt].rgsai[i].wszApp, 0, REG_DWORD, (LPBYTE)&dwChecked, sizeof(DWORD))); if (FAILED(hr)) goto done; }
MyFree(m_rgLists[epflt].rgsai[i].wszApp); m_rgLists[epflt].rgsai[i].wszApp = NULL; m_rgLists[epflt].rgsai[i].dwState = 0; }
m_rgLists[epflt].cSlotsUsed = 0;
done: return hr; }
// **************************************************************************
BOOL CPFFaultClientCfg::IsOnList(EPFListType epflt, LPCWSTR wszApp) { USE_TRACING("CPFFaultClientCfg::IsOnList");
SAppList *psap; HRESULT hr = NOERROR; DWORD i; HKEY hkey = NULL;
VALIDATEPARM(hr, (epflt >= epfltListCount || wszApp == NULL)); if (FAILED(hr)) goto done;
if ((m_rgLists[epflt].dwState & epfaaInitialized) == 0) { hr = E_FAIL; goto done; }
// first, check the mod list. This is because if we check the registry
// first, we miss the case where the user just deleted it and it's
// therefore sitting in the mod list
hr = S_FALSE; for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++) { if (m_rgLists[epflt].rgsai[i].wszApp != NULL && _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0) { if ((m_rgLists[epflt].rgsai[i].dwState & epfaaDelete) == 0) hr = NOERROR; goto done; } }
// next, check the registry.
TESTERR(hr, RegQueryValueExW(m_rgLists[epflt].hkey, wszApp, NULL, NULL, NULL, NULL)); if (SUCCEEDED(hr)) goto done; done: return (hr == NOERROR); }
#endif PFCLICFG_LITE
|