|
|
/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name: pfrscpl.cpp
Abstract: Implements fault reporting for unhandled exceptions
Revision History: created derekm 08/07/00
******************************************************************************/
#include "sysdm.h"
#include <commctrl.h>
#include <commdlg.h>
#include <debug.h>
#include "pfrscpl.h"
#include "pfrcfg.h"
#include "help.h"
#include "resource.h"
#include "malloc.h"
#include "windowsx.h"
///////////////////////////////////////////////////////////////////////////////
// data structures
#define KERNELLI 1
#define PROGLI 2
#define EXWINCOMP 0x80000000
#define EXALLMS 0x40000000
#define EXNOREM 0xc0000000 // EXWINCOMP | EXALLMS
#define WM_SETEIELVSEL WM_APP
const DWORD c_dxLVChkPixels = 30;
struct SAddDlg { WCHAR wszApp[MAX_PATH]; };
struct SMainDlg { CPFFaultClientCfg *pcfg; EEnDis eedReport; EEnDis eedShowUI; EIncEx eieKernel; EIncEx eieApps; EIncEx eieShut; DWORD iLastSel; BOOL fRW; BOOL fForceQueue; };
struct SProgDlg { CPFFaultClientCfg *pcfg; EIncEx eieApps; EIncEx eieMS; EIncEx eieWinComp; DWORD iLastSelE; DWORD iLastSelI; DWORD cchMax; DWORD cxMaxE; DWORD cxMaxI; BOOL fRW; BOOL fShowIncRem; };
///////////////////////////////////////////////////////////////////////////////
// Global stuff
// help IDs
static DWORD g_rgPFER[] = { IDC_STATIC, NO_HELP, IDC_PFR_EXADD, (IDH_PFR), IDC_PFR_EXREM, (IDH_PFR + 1), IDC_PFR_INCADD, (IDH_PFR + 2), IDC_PFR_INCREM, (IDH_PFR + 3), IDC_PFR_DISABLE, (IDH_PFR + 4), IDC_PFR_ENABLE, (IDH_PFR + 5), IDC_PFR_ENABLEOS, (IDH_PFR + 6), IDC_PFR_ENABLEPROG, (IDH_PFR + 6), IDC_PFR_DETAILS, (IDH_PFR + 7), IDC_PFR_INCLIST, (IDH_PFR + 10), IDC_PFR_NEWPROG, (IDH_PFR + 11), IDC_PFR_BROWSE, (IDH_PFR + 13), IDC_PFR_EXLIST, (IDH_PFR + 14), IDC_PFR_SHOWUI, (IDH_PFR + 15), IDC_PFR_DEFALL, (IDH_PFR + 16), IDC_PFR_DEFNONE, (IDH_PFR + 16), IDC_PFR_ENABLESHUT, (IDH_PFR + 17), IDC_PFR_FORCEQ, (IDH_PFR + 18), 0, 0 };
// resource strings
TCHAR g_szWinComp[256] = { TEXT('\0') }; TCHAR g_szOk[256] = { TEXT('\0') }; WCHAR g_wszTitle[256] = { L'\0' }; WCHAR g_wszFilter[256] = { L'\0' }; WCHAR g_wszMSProg[256] = { L'\0' };
///////////////////////////////////////////////////////////////////////////////
// utility functions
// **************************************************************************
BOOL LoadPFRResourceStrings(void) { LoadString(hInstance, IDS_PFR_WINCOMP, g_szWinComp, ARRAYSIZE(g_szWinComp)); LoadString(hInstance, IDS_PFR_OK, g_szOk, ARRAYSIZE(g_szOk)); LoadStringW(hInstance, IDS_PFR_FILTER, g_wszFilter, ARRAYSIZE(g_wszFilter)); LoadStringW(hInstance, IDS_PFR_MSPROG, g_wszMSProg, ARRAYSIZE(g_wszMSProg)); LoadStringW(hInstance, IDS_PFR_TITLE, g_wszTitle, ARRAYSIZE(g_wszTitle)); return TRUE; }
// **************************************************************************
static BOOL InitializePFLV(EPFListType epflt, HWND hlc, DWORD *pcchMax, DWORD *pcxMax, CPFFaultClientCfg *pcfg) { LVCOLUMN lvc; LVITEMW lvi; HRESULT hr; LPWSTR wszApp; DWORD dwExStyle, i, cchApps, cApps, dwChecked, cxMax; RECT rect; int iList;
if (pcchMax == NULL || pcfg == NULL || hlc == NULL || pcxMax == NULL) return FALSE;
// set up the list control
SendMessage(hlc, LVM_SETUNICODEFORMAT, TRUE, 0); dwExStyle = (LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); SendMessage(hlc, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExStyle, dwExStyle);
GetClientRect(hlc, &rect); *pcxMax = rect.right - GetSystemMetrics(SM_CYHSCROLL);
ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_FMT; lvc.fmt = LVCFMT_LEFT; ListView_InsertColumn(hlc, 0, &lvc);
hr = pcfg->InitList(epflt); if (FAILED(hr)) return FALSE;
hr = pcfg->get_ListRegInfo(epflt, &cchApps, &cApps); if (FAILED(hr)) return FALSE;
cchApps++; if (cchApps > *pcchMax) *pcchMax = cchApps;
__try { wszApp = (LPWSTR)_alloca(cchApps * sizeof(WCHAR)); } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) { wszApp = NULL; _resetstkoflw(); }
if (wszApp == NULL) return FALSE;
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = 0; lvi.pszText = wszApp;
for (i = 0; i < cApps; i++) { hr = pcfg->get_ListRegApp(epflt, i, wszApp, cchApps + 1, &dwChecked); if (FAILED(hr)) return FALSE;
cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)wszApp); cxMax += c_dxLVChkPixels; if (cxMax > *pcxMax) *pcxMax = cxMax;
lvi.iItem = i; lvi.lParam = 1 + ((dwChecked == 1) ? 1 : 0); iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi); if (iList >= 0) ListView_SetCheckState(hlc, iList, (dwChecked == 1)); }
ListView_SetColumnWidth(hlc, 0, *pcxMax);
if (cApps > 0) { ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); }
return TRUE; }
///////////////////////////////////////////////////////////////////////////////
// Add Program dialog proc
// **************************************************************************
static UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hwndFile;
switch(uMsg) { case WM_INITDIALOG: hwndFile = GetParent(hdlg); if (hwndFile != NULL) SendMessage(hwndFile, CDM_SETCONTROLTEXT, IDOK, (LPARAM)g_szOk);
return TRUE;
default: return FALSE; }
return FALSE; }
// **************************************************************************
#define LAUNCHOFN_OFFSET 10
static BOOL LaunchOFNDialog(HWND hdlg, LPWSTR wszFile, DWORD cchFile) { OPENFILENAMEW ofn; WCHAR wszFilePath[2 * MAX_PATH]; WCHAR wszInitalDir[] = L"\\"; WCHAR wszFilter[MAX_PATH], *pwsz; DWORD dw;
if (wszFile == NULL || cchFile == 0) { return FALSE; }
// the filter string needs to be of the form <Description>\0<Extension>\0\0
ZeroMemory(wszFilter, sizeof(wszFilter)); COMPILETIME_ASSERT(sizeof(wszFilter) >= sizeof(g_wszFilter)); // should always be bigger
StringCchCopy(wszFilter, ARRAYSIZE(wszFilter), g_wszFilter);
dw = wcslen(g_wszFilter); if (dw < (ARRAYSIZE(wszFilter) - LAUNCHOFN_OFFSET)) { pwsz = wszFilter + dw + 1; } else { pwsz = wszFilter + ARRAYSIZE(wszFilter) - LAUNCHOFN_OFFSET; ZeroMemory(pwsz, LAUNCHOFN_OFFSET * sizeof(WCHAR)); pwsz++; } EVAL(SUCCEEDED(StringCchCopy(pwsz, LAUNCHOFN_OFFSET, L"*.exe"))); // should always be room
wszFilePath[0] = L'\0'; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hdlg; ofn.lpstrFilter = wszFilter; ofn.lpstrFile = wszFilePath; ofn.nMaxFile = ARRAYSIZE(wszFilePath); ofn.lpstrFileTitle = wszFile; ofn.nMaxFileTitle = cchFile; ofn.lpstrInitialDir = wszInitalDir; ofn.lpstrTitle = g_wszTitle; ofn.Flags = OFN_DONTADDTORECENT | OFN_ENABLESIZING | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_SHAREAWARE; ofn.lpstrDefExt = NULL; ofn.lpfnHook = OFNHookProc;
// get the filename & fill in the edit box with it
return GetOpenFileNameW(&ofn); }
// **************************************************************************
static INT_PTR APIENTRY PFRAddDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fShowErr = FALSE; switch (uMsg) { case WM_INITDIALOG: { HWND hbtn;
SetWindowLongPtr(hdlg, DWLP_USER, lParam);
// disable the ok button cuz we know that we don't have anything
// in the 'filename' edit box
hbtn = GetDlgItem(hdlg, IDOK); if (hbtn != NULL) EnableWindow(hbtn, FALSE); }
break;
// F1 help
case WM_HELP: WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER); break;
// right-click help
case WM_CONTEXTMENU: WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)g_rgPFER); break; case WM_COMMAND: switch (LOWORD(wParam)) { // browse button
case IDC_PFR_BROWSE: { WCHAR wszFile[2 * MAX_PATH];
// get the filename & fill in the edit box with it
if (LaunchOFNDialog(hdlg, wszFile, ARRAYSIZE(wszFile))) SetDlgItemTextW(hdlg, IDC_PFR_NEWPROG, wszFile);
break; }
// Ok button
case IDOK: { SAddDlg *psad;
psad = (SAddDlg *)GetWindowLongPtr(hdlg, DWLP_USER); if (psad != NULL) { WCHAR *wszText, *pwsz; DWORD cch; HWND hwndText; BOOL fReplaceWSpace = TRUE;
hwndText = GetDlgItem(hdlg, IDC_PFR_NEWPROG); if (hwndText == NULL) { fShowErr = TRUE; goto done; }
cch = GetWindowTextLength(hwndText); if (cch == 0) { fShowErr = TRUE; goto done; }
cch++;
__try { wszText = (LPWSTR)_alloca(cch * sizeof(WCHAR)); } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) { wszText = NULL; _resetstkoflw(); }
if (wszText == NULL) { fShowErr = TRUE; goto done; }
*psad->wszApp = L'\0'; *wszText = L'\0'; GetDlgItemTextW(hdlg, IDC_PFR_NEWPROG, wszText, cch); // make sure that we only have the exe name- probably
// should verify that it IS an exe, but it's possible
// we'd want to trap on other file types as well, so
// don't for now.
// And while we're at it, rip off any trailing
// whitespace (preceeding whitespace is apparently ok)
cch = wcslen(wszText); if (cch > 0) { for(pwsz = wszText + cch - 1; pwsz > wszText; pwsz--) { if (fReplaceWSpace) { if (iswspace(*pwsz)) *pwsz = L'\0'; else fReplaceWSpace = FALSE; }
if (*pwsz == L'\\') { pwsz++; break; } }
if (*pwsz == L'\\') pwsz++; }
cch = wcslen(pwsz); if (cch >= MAX_PATH || cch == 0) { fShowErr = TRUE; goto done; }
if (FAILED(StringCchCopy(psad->wszApp, ARRAYSIZE(psad->wszApp), pwsz))) { psad->wszApp[0] = L'\0'; } }
EndDialog(hdlg, IDOK); break; } // cancel button
case IDCANCEL: EndDialog(hdlg, IDCANCEL); break;
case IDC_PFR_NEWPROG: if (HIWORD(wParam) == EN_CHANGE) { HWND hbtn, hedt; hbtn = GetDlgItem(hdlg, IDOK); hedt = (HWND)(DWORD_PTR)lParam; if (hedt != NULL && hbtn != NULL) { if (GetWindowTextLength(hedt) != 0) EnableWindow(hbtn, TRUE); else EnableWindow(hbtn, FALSE); } } break; // return FALSE to indicate that we didn't handle the msg
default: return FALSE; } break;
// return FALSE to indicate that we didn't handle the msg
default: return FALSE; }
done: if (fShowErr) { TCHAR szMsg[256];
LoadString(hInstance, IDS_PFR_BADFILE, szMsg, ARRAYSIZE(szMsg)); MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); }
return FALSE; }
///////////////////////////////////////////////////////////////////////////////
// Programs dialog proc
// **************************************************************************
static BOOL InitProgDlg(HWND hdlg, SProgDlg *pspd) { CPFFaultClientCfg *pcfg; LVITEMW lvi; DWORD cxMax; HWND hlc, hbtn; BOOL fRet = FALSE; int iList, cItems;
if (pspd == NULL) goto done;
pcfg = pspd->pcfg;
// fill in the exclude list
hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST); if (hlc == NULL) goto done;
if (InitializePFLV(epfltExclude, hlc, &pspd->cchMax, &pspd->cxMaxE, pcfg) == FALSE) goto done;
// fill in the include list
hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc == NULL) goto done;
if (InitializePFLV(epfltInclude, hlc, &pspd->cchMax, &pspd->cxMaxI, pcfg) == FALSE) goto done;
pspd->fShowIncRem = TRUE;
// add the item to the include list that lets users include all MS apps
pspd->eieMS = pcfg->get_IncMSApps();
// Note that we set lParam to 1 or 2. This is because we need to ignore
// the first notification message for the list item + the 2nd one if the
// check state is set. Processing these two messages leads to corruption
// in the configuration settings
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = 0; lvi.pszText = g_wszMSProg; lvi.iItem = 0; lvi.lParam = (1 + ((pspd->eieMS == eieInclude) ? 1 : 0)) | EXALLMS; iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi); if (iList >= 0) ListView_SetCheckState(hlc, iList, (pspd->eieMS == eieInclude));
cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)g_wszMSProg); cxMax += c_dxLVChkPixels; if (cxMax > pspd->cxMaxI) { pspd->cxMaxI = cxMax; ListView_SetColumnWidth(hlc, 0, cxMax); }
// add the item to the include list that lets users exclude all windows
// components
pspd->eieWinComp = pcfg->get_IncWinComp();
// Note that we set lParam to 1 or 2. This is because we need to ignore
// the first notification message for the list item + the 2nd one if the
// check state is set. Processing these two messages leads to corruption
// in the configuration settings
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = 0; lvi.pszText = g_szWinComp; lvi.iItem = 1; lvi.lParam = (1 + ((pspd->eieWinComp == eieInclude) ? 1 : 0)) | EXWINCOMP; iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi); if (iList >= 0) ListView_SetCheckState(hlc, iList, (pspd->eieWinComp == eieInclude));
cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)g_szWinComp); cxMax += c_dxLVChkPixels; if (cxMax > pspd->cxMaxI) { pspd->cxMaxI = cxMax; ListView_SetColumnWidth(hlc, 0, cxMax); }
// do misc setup on the exclusion list (disabling the remove button,
// setting the initial focus)
hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST); cItems = ListView_GetItemCount(hlc); if (cItems == 0) { hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM); if (hbtn != NULL) EnableWindow(hbtn, FALSE); } else { ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); }
// do misc setup on the inclusion list (disabling the remove button,
// setting the initial focus)
hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); cItems = ListView_GetItemCount(hlc); if (cItems < 3) { hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
pspd->fShowIncRem = FALSE; } // set up the radio buttons- if we are in 'include all' mode, then
// we don't need the inclusion list.
if (((DWORD)pspd->eieApps & eieIncMask) == eieInclude) { CheckDlgButton(hdlg, IDC_PFR_DEFALL, BST_CHECKED); CheckDlgButton(hdlg, IDC_PFR_DEFNONE, BST_UNCHECKED);
hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc != NULL) EnableWindow(hlc, FALSE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM); if (hbtn != NULL) EnableWindow(hbtn, FALSE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD); if (hbtn != NULL) EnableWindow(hbtn, FALSE); } else { CheckDlgButton(hdlg, IDC_PFR_DEFALL, BST_UNCHECKED); CheckDlgButton(hdlg, IDC_PFR_DEFNONE, BST_CHECKED); EnableWindow(hlc, TRUE); }
fRet = TRUE;
done: if (fRet == FALSE) { TCHAR szMsg[MAX_PATH]; LoadString(hInstance, IDS_PFR_CFGREADERR, szMsg, ARRAYSIZE(szMsg)); MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); }
return fRet; }
// **************************************************************************
static BOOL AddProgramToList(HWND hdlg, HWND hlc, SProgDlg *pspd, EPFListType epflt) { CPFFaultClientCfg *pcfg = NULL; HRESULT hr; SAddDlg sad; LVITEMW lvi; DWORD cch, cxMax, *pcxMax; TCHAR szMsg[256]; HWND hbtn; int nID, cItems;
if (pspd == NULL) return FALSE;
pcfg = pspd->pcfg;
ZeroMemory(&sad, sizeof(sad)); nID = (int)DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PFR_ADDPROG), hdlg, PFRAddDlgProc, (LPARAM)&sad); if (nID == IDCANCEL || sad.wszApp[0] == L'\0') return FALSE;
if (pcfg->IsOnList(epfltInclude, sad.wszApp)) { LoadString(hInstance, IDS_PFR_ISONLISTI, szMsg, ARRAYSIZE(szMsg)); if (epflt == epfltExclude) { TCHAR szTmp[256]; LoadString(hInstance, IDS_PFR_ADDTOEX, szTmp, ARRAYSIZE(szTmp)); StringCchCat(szMsg, ARRAYSIZE(szMsg), szTmp); // display string, truncation ok
}
MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); return FALSE; }
else if (pcfg->IsOnList(epfltExclude, sad.wszApp)) { LoadString(hInstance, IDS_PFR_ISONLISTE, szMsg, ARRAYSIZE(szMsg)); if (epflt == epfltInclude) { TCHAR szTmp[256]; LoadString(hInstance, IDS_PFR_ADDTOINC, szTmp, ARRAYSIZE(szTmp)); StringCchCat(szMsg, ARRAYSIZE(szMsg), szTmp); // display string, truncation ok
}
MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); return FALSE; }
cItems = ListView_GetItemCount(hlc);
// update the max string size if necessary
cch = wcslen(sad.wszApp); if (cch >= pspd->cchMax) pspd->cchMax = cch + 1;
// yay! add it to the config class
hr = pcfg->add_ListApp(epflt, sad.wszApp); if (FAILED(hr)) return FALSE;
pcxMax = (epflt == epfltInclude) ? &pspd->cxMaxI : &pspd->cxMaxE; cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)sad.wszApp); cxMax += c_dxLVChkPixels; if (cxMax > *pcxMax) { *pcxMax = cxMax; ListView_SetColumnWidth(hlc, 0, cxMax); }
// add it to the UI
// Note that we set lParam to 2. This is because we need to ignore the
// first two notification messages per entry sent to the wndproc because
// they are 'list initialization' messages and processing them leads to
// corruption in the configuration settings
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = 0; lvi.pszText = sad.wszApp; lvi.iItem = 0; lvi.lParam = 2; nID = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi); if (nID >= 0) ListView_SetCheckState(hlc, nID, TRUE);
// if there are no items, then there is no currently selected item, so
// make sure this item gets selected. In our handler for this message
// we will take care of setting the 'last selected item' field...
if (cItems == 0) { ListView_SetItemState(hlc, nID, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
// Also, got to make sure we enable the 'Remove' button. The only
// way we can get zero items in a list is in the exclude list cuz
// the include list always has the 'include MS apps' item.
hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM); if (hbtn != NULL) EnableWindow(hbtn, TRUE); }
return TRUE; }
// **************************************************************************
static BOOL DelProgramFromList(HWND hdlg, HWND hlc, SProgDlg *pspd, EPFListType epflt) { LVITEMW lvi; HRESULT hr; LPWSTR wszApp; DWORD cItems, iSel;
__try { wszApp = (LPWSTR)_alloca(pspd->cchMax * sizeof(WCHAR)); } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) { wszApp = NULL; _resetstkoflw(); }
if (wszApp == NULL) return FALSE;
iSel = ((epflt == epfltInclude) ? pspd->iLastSelI : pspd->iLastSelE);
// fetch the string for the item
ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = iSel; lvi.mask = LVIF_TEXT; lvi.pszText = wszApp; lvi.cchTextMax = pspd->cchMax; if (SendMessageW(hlc, LVM_GETITEMW, 0, (LPARAM)&lvi)) { // delete it from the config class
hr = pspd->pcfg->del_ListApp(epflt, lvi.pszText); if (FAILED(hr)) return FALSE; }
// delete it from the UI
if (ListView_DeleteItem(hlc, iSel) == FALSE) return FALSE;
// reset the selection to be either the same index or one higher (if the
// user deleted the last item)
cItems = ListView_GetItemCount(hlc); if (cItems == 0) { HWND hbtn;
// only time we can ever hit zero items is in the exclude list cuz the
// include list always has the 'include MS apps' option.
hbtn = GetDlgItem(hdlg, IDC_PFR_EXADD); if (hbtn != NULL) { SetFocus(hbtn); SendMessage(hdlg, DM_SETDEFID, IDC_PFR_EXADD, 0); } hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM); if (hbtn != NULL) EnableWindow(hbtn, FALSE); pspd->iLastSelI = 0; return TRUE; }
// if cItems <= iSel, then we just deleted the last index, so decrement the
// select index down 1.
else if (cItems <= iSel) { iSel--; }
// this will convieniently take care of setting the appropriate iLastSel
// field
ListView_SetItemState(hlc, iSel, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
return TRUE;
}
// **************************************************************************
static INT_PTR APIENTRY PFRProgDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CPFFaultClientCfg *pcfg = NULL; SProgDlg *pspd = (SProgDlg *)GetWindowLongPtr(hdlg, DWLP_USER); HRESULT hr; HWND hlc, hbtn;
if (pspd != NULL) pcfg = pspd->pcfg;
switch(uMsg) { case WM_INITDIALOG: SetWindowLongPtr(hdlg, DWLP_USER, lParam); if (InitProgDlg(hdlg, (SProgDlg *)lParam) == FALSE) EndDialog(hdlg, IDCANCEL);
break;
// F1 help
case WM_HELP: WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER); break;
// right-click help
case WM_CONTEXTMENU: WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)g_rgPFER); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: if (pspd->fRW) { hr = pcfg->CommitChanges(epfltExclude); if (SUCCEEDED(hr)) { hr = pcfg->CommitChanges(epfltInclude); if (SUCCEEDED(hr)) { pcfg->set_IncWinComp(pspd->eieWinComp); pcfg->set_IncMSApps(pspd->eieMS); pcfg->set_AllOrNone(pspd->eieApps); hr = pcfg->Write(); } }
if (FAILED(hr)) { TCHAR szMsg[MAX_PATH]; if (hr != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { LoadString(hInstance, IDS_PFR_CFGWRITEERR, szMsg, ARRAYSIZE(szMsg)); } else { LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg, ARRAYSIZE(szMsg)); } MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); pcfg->ClearChanges(epfltExclude); pcfg->ClearChanges(epfltInclude); } } else { TCHAR szMsg[MAX_PATH]; LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg, ARRAYSIZE(szMsg)); MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); }
EndDialog(hdlg, IDOK); break;
case IDCANCEL: EndDialog(hdlg, IDCANCEL); break;
case IDC_PFR_DEFNONE: pspd->eieApps = (EIncEx)(((DWORD)pspd->eieApps & eieDisableMask) | eieExclude);
// enable the include list.
hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc != NULL) EnableWindow(hlc, TRUE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD); if (hbtn != NULL) EnableWindow(hbtn, TRUE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM); if (hbtn != NULL) EnableWindow(hbtn, pspd->fShowIncRem);
break;
case IDC_PFR_DEFALL: pspd->eieApps = (EIncEx)(((DWORD)pspd->eieApps & eieDisableMask) | eieInclude);
// disable the include list.
hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc != NULL) EnableWindow(hlc, FALSE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD); if (hbtn != NULL) EnableWindow(hbtn, FALSE); hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
break;
case IDC_PFR_INCADD: hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc != NULL) return AddProgramToList(hdlg, hlc, pspd, epfltInclude); break;
case IDC_PFR_EXADD: hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST); if (hlc != NULL) return AddProgramToList(hdlg, hlc, pspd, epfltExclude); break;
case IDC_PFR_INCREM: hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST); if (hlc != NULL) return DelProgramFromList(hdlg, hlc, pspd, epfltInclude); break;
case IDC_PFR_EXREM: hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST); if (hlc != NULL) return DelProgramFromList(hdlg, hlc, pspd, epfltExclude); break;
default: return FALSE; } break; }
case WM_SETEIELVSEL: { hlc = GetDlgItem(hdlg, (int)wParam); if (ListView_GetItemCount(hlc) > 0) { int iSel;
if (wParam == IDC_PFR_EXLIST) iSel = pspd->iLastSelE; else iSel = pspd->iLastSelI;
ListView_SetItemState(hlc, iSel, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); }
break; }
case WM_NOTIFY: { EPFListType epflt; NMLISTVIEW *pnmlv = (NMLISTVIEW *)lParam; LVITEMW lvi; NMHDR *pnmh = (NMHDR *)lParam; DWORD dw; UINT uiBtn; BOOL fCheck; int iSel;
if ((pnmh->code != LVN_ITEMCHANGED && pnmh->code != NM_SETFOCUS) || (pnmh->idFrom != IDC_PFR_EXLIST && pnmh->idFrom != IDC_PFR_INCLIST)) return FALSE;
hlc = pnmh->hwndFrom;
uiBtn = (pnmh->idFrom == IDC_PFR_EXLIST) ? IDC_PFR_EXREM : IDC_PFR_INCREM; hbtn = GetDlgItem(hdlg, uiBtn);
// check and see if there are any selected items
iSel = (int)SendMessage(hlc, LVM_GETNEXTITEM, -1, LVNI_SELECTED); if (iSel < 0) { EnableWindow(hbtn, FALSE); if (pnmh->idFrom == IDC_PFR_INCLIST) pspd->fShowIncRem = FALSE; }
else { if (pnmh->code == NM_SETFOCUS) { PostMessage(hdlg, WM_SETEIELVSEL, pnmh->idFrom, pnmh->code); return TRUE; } } // if it doesn't fit this condition, don't give a rat's patootie
// about it
if ((pnmlv->uChanged & LVIF_STATE) == 0 || (pnmlv->uNewState ^ pnmlv->uOldState) == 0) return FALSE;
// hack cuz we get 1 or 2 messages when inserting items into the
// list & initially setting their check state. Want to not
// process those messages. The exception is the 'include
// ms apps' item which we can process any number of times
if ((pnmlv->lParam & ~EXNOREM) > 0) { ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = pnmlv->iItem; lvi.mask = LVIF_PARAM; lvi.lParam = (pnmlv->lParam - 1) | (pnmlv->lParam & EXNOREM); SendMessageW(hlc, LVM_SETITEM, 0, (LPARAM)&lvi); return TRUE; }
// did the selection change?
if ((pnmlv->uNewState & LVIS_SELECTED) != 0) { if (pnmh->idFrom == IDC_PFR_INCLIST) { pspd->iLastSelI = pnmlv->iItem; // we need to disable the exclude remove button if we hit
// the 'exclude non ms apps' item
if (hbtn != NULL) { if ((pnmlv->lParam & EXNOREM) != 0) { // disable the remove button- but if the remove
// button had focus, we need to reset the focus
// or nothing on the dialog will have focus.
if (GetFocus() == hbtn) { HWND hbtnAdd; hbtnAdd = GetDlgItem(hdlg, IDC_PFR_INCADD); if (hbtnAdd != NULL) { SetFocus(hbtnAdd); SendMessage(hdlg, DM_SETDEFID, IDC_PFR_INCADD, 0); }
}
pspd->fShowIncRem = FALSE; EnableWindow(hbtn, FALSE); } else { pspd->fShowIncRem = TRUE; EnableWindow(hbtn, TRUE); } }
} else { pspd->iLastSelE = pnmlv->iItem; if (hbtn != NULL) EnableWindow(hbtn, TRUE); } }
// if we don't have a check-state change, can bail now.
if (((pnmlv->uNewState ^ pnmlv->uOldState) & 0x3000) == 0) return TRUE;
fCheck = ListView_GetCheckState(hlc, pnmlv->iItem); if (pnmh->idFrom == IDC_PFR_EXLIST) epflt = epfltExclude; else epflt = epfltInclude;
// did we modify the 'exclude non ms apps' item?
if ((pnmlv->lParam & EXNOREM) != 0) { if ((pnmlv->lParam & EXALLMS) != 0) pspd->eieMS = ((fCheck) ? eieInclude : eieExclude); else pspd->eieWinComp = ((fCheck) ? eieInclude : eieExclude); }
// nope, modified a regular item
else { LPWSTR wszApp;
__try { wszApp = (LPWSTR)_alloca(pspd->cchMax * sizeof(WCHAR)); } __except(GetExceptionCode() == STATUS_STACK_OVERFLOW) { wszApp = NULL; _resetstkoflw(); } if (wszApp == NULL) return FALSE; // got to fetch it to make sure we have a unicode string
ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = pnmlv->iItem; lvi.mask = LVIF_TEXT; lvi.pszText = wszApp; lvi.cchTextMax = pspd->cchMax; if (SendMessageW(hlc, LVM_GETITEMW, 0, (LPARAM)&lvi)) { hr = pcfg->mod_ListApp(epflt, lvi.pszText, fCheck); if (FAILED(hr)) return FALSE; }
}
break; }
default: return FALSE; }
return FALSE; }
///////////////////////////////////////////////////////////////////////////////
// Main PFR dialog proc
// **************************************************************************
static BOOL InitMainDlg(HWND hdlg) { CPFFaultClientCfg *pcfg = NULL; SMainDlg *psmd = NULL; BOOL fRet = FALSE; UINT ui; HWND hbtn, hchk;
LoadPFRResourceStrings();
hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (hbtn == NULL) goto done;
psmd = new SMainDlg; if (psmd == NULL) goto done;
pcfg = new CPFFaultClientCfg; if (pcfg == NULL) goto done;
// see if this user has write access to the appropriate registry
// locations
psmd->fRW = pcfg->HasWriteAccess(); if (FAILED(pcfg->Read((psmd->fRW) ? eroCPRW : eroCPRO))) goto done;
psmd->eedReport = pcfg->get_DoReport(); psmd->eieKernel = pcfg->get_IncKernel(); psmd->eieApps = pcfg->get_AllOrNone(); psmd->eedShowUI = pcfg->get_ShowUI(); psmd->eieShut = pcfg->get_IncShutdown(); psmd->fForceQueue = pcfg->get_ForceQueueMode(); psmd->iLastSel = 0;
// if ShowUI is completely disabled, then so should reporting- the control
// panel does not support entering corporate mode.
if (psmd->eedShowUI == eedDisabled) psmd->eedReport = eedDisabled;
psmd->pcfg = pcfg; SetWindowLongPtr(hdlg, DWLP_USER, (LONG_PTR)psmd);
// set up the kernel checkbox
ui = (psmd->eieKernel == eieInclude) ? BST_CHECKED : BST_UNCHECKED; CheckDlgButton(hdlg, IDC_PFR_ENABLEOS, ui);
// set up the programs checkbox
ui = ((psmd->eieApps & eieDisableMask) == 0) ? BST_CHECKED : BST_UNCHECKED; CheckDlgButton(hdlg, IDC_PFR_ENABLEPROG, ui);
// set up the notification checkbox
ui = (psmd->eedShowUI == eedEnabled) ? BST_CHECKED : BST_UNCHECKED; CheckDlgButton(hdlg, IDC_PFR_SHOWUI, ui);
// set up the shutdown checkbox on server only
if (pcfg->get_IsServer()) { ui = (psmd->eieShut == eieInclude) ? BST_CHECKED : BST_UNCHECKED; CheckDlgButton(hdlg, IDC_PFR_ENABLESHUT, ui);
ui = (psmd->fForceQueue) ? BST_CHECKED : BST_UNCHECKED; CheckDlgButton(hdlg, IDC_PFR_FORCEQ, ui); }
// set up the radio buttons
if (psmd->eedReport == eedDisabled) { CheckRadioButton(hdlg, IDC_PFR_DISABLE, IDC_PFR_ENABLE, IDC_PFR_DISABLE);
hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI); if (hchk != NULL) EnableWindow(hchk, TRUE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS); if (hchk != NULL) EnableWindow(hchk, FALSE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG); if (hchk != NULL) EnableWindow(hchk, FALSE);
hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ); if (hbtn != NULL) EnableWindow(hbtn, FALSE); } } else { CheckRadioButton(hdlg, IDC_PFR_DISABLE, IDC_PFR_ENABLE, IDC_PFR_ENABLE);
hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI); if (hchk != NULL) EnableWindow(hchk, FALSE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS); if (hchk != NULL) EnableWindow(hchk, TRUE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG); if (hchk != NULL) EnableWindow(hchk, TRUE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT); if (hbtn != NULL) EnableWindow(hbtn, TRUE); }
if ((psmd->eieApps & eieDisableMask) != 0) { hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ); if (hbtn != NULL) EnableWindow(hbtn, FALSE); } } }
fRet = TRUE; psmd = NULL; pcfg = NULL;
done: if (fRet == FALSE) { TCHAR szMsg[MAX_PATH]; LoadString(hInstance, IDS_PFR_CFGREADERR, szMsg, ARRAYSIZE(szMsg)); MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); } if (psmd != NULL) delete psmd; if (pcfg != NULL) delete pcfg;
return fRet; }
// **************************************************************************
static inline INT_PTR LaunchSubDialog(HWND hdlgParent, DWORD dwDlgToLaunch, SMainDlg *psmd) { if (dwDlgToLaunch == PROGLI) { SProgDlg spd;
ZeroMemory(&spd, sizeof(spd)); spd.pcfg = psmd->pcfg; spd.eieApps = psmd->eieApps; spd.eieMS = psmd->pcfg->get_IncMSApps(); spd.fRW = psmd->fRW; if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PFR_PROG), hdlgParent, PFRProgDlgProc, (LPARAM)&spd) == IDOK) { psmd->eieApps = psmd->pcfg->get_AllOrNone(); } }
else { return IDCANCEL; }
return IDOK; }
// **************************************************************************
INT_PTR APIENTRY PFRDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CPFFaultClientCfg *pcfg = NULL; SMainDlg *psmd = (SMainDlg *)GetWindowLongPtr(hdlg, DWLP_USER); HWND hbtn, hchk;
if (psmd != NULL) pcfg = psmd->pcfg;
switch(uMsg) { case WM_INITDIALOG: if (InitMainDlg(hdlg) == FALSE) EndDialog(hdlg, IDCANCEL); break;
case WM_DESTROY: if (psmd != NULL) { if (psmd->pcfg != NULL) delete psmd->pcfg; delete psmd; SetWindowLongPtr(hdlg, DWLP_USER, NULL); } break; // F1 help
case WM_HELP: WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER); break;
// right-click help
case WM_CONTEXTMENU: WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)g_rgPFER); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: if (psmd->fRW) { HRESULT hr;
pcfg->set_AllOrNone(psmd->eieApps); pcfg->set_DoReport(psmd->eedReport); pcfg->set_IncKernel(psmd->eieKernel); pcfg->set_ShowUI(psmd->eedShowUI); if (pcfg->get_IsServer()) { pcfg->set_IncShutdown(psmd->eieShut); pcfg->set_ForceQueueMode(psmd->fForceQueue); }
hr = pcfg->Write(); if (FAILED(hr)) { TCHAR szMsg[MAX_PATH];
if (hr != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { LoadString(hInstance, IDS_PFR_CFGWRITEERR, szMsg, ARRAYSIZE(szMsg)); } else { LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg, ARRAYSIZE(szMsg)); } MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); } } else { TCHAR szMsg[MAX_PATH];
LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg, ARRAYSIZE(szMsg)); MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR); }
EndDialog(hdlg, IDOK); break;
case IDCANCEL: EndDialog(hdlg, IDCANCEL); break;
case IDC_PFR_ENABLE: { LVITEM lvi;
psmd->eedReport = eedEnabled;
// if UI is disbaled, then implicitly enable it (but don't
// change the check state of the 'show UI' checkbox) cuz
// we only support headless uploading thru policy.
if (psmd->eedShowUI == eedDisabled) psmd->eedShowUI = eedEnabledNoCheck;
hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI); if (hchk != NULL) EnableWindow(hchk, FALSE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS); if (hchk != NULL) EnableWindow(hchk, TRUE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG); if (hchk != NULL) EnableWindow(hchk, TRUE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT); if (hbtn != NULL) EnableWindow(hbtn, TRUE); }
if ((psmd->eieApps & eieDisableMask) == 0) { hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (hbtn != NULL) EnableWindow(hbtn, TRUE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ); if (hbtn != NULL) EnableWindow(hbtn, TRUE); } }
break; }
case IDC_PFR_DISABLE: { psmd->eedReport = eedDisabled;
// if UI isn't explicitly enabled, disable it- it was
// implicity enabled when the user previously enabled
// reporting
if (psmd->eedShowUI == eedEnabledNoCheck) psmd->eedShowUI = eedDisabled;
hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI); if (hchk != NULL) EnableWindow(hchk, TRUE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS); if (hchk != NULL) EnableWindow(hchk, FALSE);
hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG); if (hchk != NULL) EnableWindow(hchk, FALSE);
hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (hbtn != NULL) EnableWindow(hbtn, FALSE);
if (pcfg->get_IsServer()) { hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT); if (hbtn != NULL) EnableWindow(hbtn, FALSE); hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ); if (hbtn != NULL) EnableWindow(hbtn, FALSE); } break; }
case IDC_PFR_DETAILS: { // don't need to check if this is a valid thing to bring up
// a dialog for cuz the details button should not be
// available if it isn't
return LaunchSubDialog(hdlg, PROGLI, psmd); break; }
case IDC_PFR_SHOWUI: { if (IsDlgButtonChecked(hdlg, IDC_PFR_SHOWUI) == BST_UNCHECKED) psmd->eedShowUI = eedDisabled; else if (psmd->eedReport == eedEnabled) psmd->eedShowUI = eedEnabledNoCheck; else psmd->eedShowUI = eedEnabled; break; }
case IDC_PFR_ENABLEOS: { if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLEOS) == BST_UNCHECKED) psmd->eieKernel = eieExclude; else psmd->eieKernel = eieInclude; break; }
case IDC_PFR_ENABLEPROG: { DWORD dw; hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS); if (pcfg->get_IsServer()) hchk = GetDlgItem(hdlg, IDC_PFR_FORCEQ); else hchk = NULL; if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLEPROG) == BST_UNCHECKED) { dw = (DWORD)psmd->eieApps | eieDisableMask; if (hbtn != NULL) EnableWindow(hbtn, FALSE); if (hchk != NULL) EnableWindow(hchk, FALSE); } else { dw = (DWORD)psmd->eieApps & eieIncMask; if (hbtn != NULL) EnableWindow(hbtn, TRUE); if (hchk != NULL) EnableWindow(hchk, TRUE); }
psmd->eieApps = (EIncEx)dw;
break; }
case IDC_PFR_ENABLESHUT: if (pcfg->get_IsServer()) { if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLESHUT) == BST_UNCHECKED) psmd->eieShut = eieExclude; else psmd->eieShut = eieInclude; }
case IDC_PFR_FORCEQ: if (pcfg->get_IsServer()) { if (IsDlgButtonChecked(hdlg, IDC_PFR_FORCEQ) == BST_UNCHECKED) psmd->fForceQueue = FALSE; else psmd->fForceQueue = TRUE; }
default: return FALSE;
}
break; }
default: return FALSE;
}
return TRUE; }
|