Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1650 lines
54 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pfrscpl.cpp
  5. Abstract:
  6. Implements fault reporting for unhandled exceptions
  7. Revision History:
  8. created derekm 08/07/00
  9. ******************************************************************************/
  10. #include "sysdm.h"
  11. #include <commctrl.h>
  12. #include <commdlg.h>
  13. #include <debug.h>
  14. #include "pfrscpl.h"
  15. #include "pfrcfg.h"
  16. #include "help.h"
  17. #include "resource.h"
  18. #include "malloc.h"
  19. #include "windowsx.h"
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // data structures
  22. #define KERNELLI 1
  23. #define PROGLI 2
  24. #define EXWINCOMP 0x80000000
  25. #define EXALLMS 0x40000000
  26. #define EXNOREM 0xc0000000 // EXWINCOMP | EXALLMS
  27. #define WM_SETEIELVSEL WM_APP
  28. const DWORD c_dxLVChkPixels = 30;
  29. struct SAddDlg
  30. {
  31. WCHAR wszApp[MAX_PATH];
  32. };
  33. struct SMainDlg
  34. {
  35. CPFFaultClientCfg *pcfg;
  36. EEnDis eedReport;
  37. EEnDis eedShowUI;
  38. EIncEx eieKernel;
  39. EIncEx eieApps;
  40. EIncEx eieShut;
  41. DWORD iLastSel;
  42. BOOL fRW;
  43. BOOL fForceQueue;
  44. };
  45. struct SProgDlg
  46. {
  47. CPFFaultClientCfg *pcfg;
  48. EIncEx eieApps;
  49. EIncEx eieMS;
  50. EIncEx eieWinComp;
  51. DWORD iLastSelE;
  52. DWORD iLastSelI;
  53. DWORD cchMax;
  54. DWORD cxMaxE;
  55. DWORD cxMaxI;
  56. BOOL fRW;
  57. BOOL fShowIncRem;
  58. };
  59. ///////////////////////////////////////////////////////////////////////////////
  60. // Global stuff
  61. // help IDs
  62. static DWORD g_rgPFER[] =
  63. {
  64. IDC_STATIC, NO_HELP,
  65. IDC_PFR_EXADD, (IDH_PFR),
  66. IDC_PFR_EXREM, (IDH_PFR + 1),
  67. IDC_PFR_INCADD, (IDH_PFR + 2),
  68. IDC_PFR_INCREM, (IDH_PFR + 3),
  69. IDC_PFR_DISABLE, (IDH_PFR + 4),
  70. IDC_PFR_ENABLE, (IDH_PFR + 5),
  71. IDC_PFR_ENABLEOS, (IDH_PFR + 6),
  72. IDC_PFR_ENABLEPROG, (IDH_PFR + 6),
  73. IDC_PFR_DETAILS, (IDH_PFR + 7),
  74. IDC_PFR_INCLIST, (IDH_PFR + 10),
  75. IDC_PFR_NEWPROG, (IDH_PFR + 11),
  76. IDC_PFR_BROWSE, (IDH_PFR + 13),
  77. IDC_PFR_EXLIST, (IDH_PFR + 14),
  78. IDC_PFR_SHOWUI, (IDH_PFR + 15),
  79. IDC_PFR_DEFALL, (IDH_PFR + 16),
  80. IDC_PFR_DEFNONE, (IDH_PFR + 16),
  81. IDC_PFR_ENABLESHUT, (IDH_PFR + 17),
  82. IDC_PFR_FORCEQ, (IDH_PFR + 18),
  83. 0, 0
  84. };
  85. // resource strings
  86. TCHAR g_szWinComp[256] = { TEXT('\0') };
  87. TCHAR g_szOk[256] = { TEXT('\0') };
  88. WCHAR g_wszTitle[256] = { L'\0' };
  89. WCHAR g_wszFilter[256] = { L'\0' };
  90. WCHAR g_wszMSProg[256] = { L'\0' };
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // utility functions
  93. // **************************************************************************
  94. BOOL LoadPFRResourceStrings(void)
  95. {
  96. LoadString(hInstance, IDS_PFR_WINCOMP, g_szWinComp, ARRAYSIZE(g_szWinComp));
  97. LoadString(hInstance, IDS_PFR_OK, g_szOk, ARRAYSIZE(g_szOk));
  98. LoadStringW(hInstance, IDS_PFR_FILTER, g_wszFilter, ARRAYSIZE(g_wszFilter));
  99. LoadStringW(hInstance, IDS_PFR_MSPROG, g_wszMSProg, ARRAYSIZE(g_wszMSProg));
  100. LoadStringW(hInstance, IDS_PFR_TITLE, g_wszTitle, ARRAYSIZE(g_wszTitle));
  101. return TRUE;
  102. }
  103. // **************************************************************************
  104. static BOOL InitializePFLV(EPFListType epflt, HWND hlc, DWORD *pcchMax,
  105. DWORD *pcxMax, CPFFaultClientCfg *pcfg)
  106. {
  107. LVCOLUMN lvc;
  108. LVITEMW lvi;
  109. HRESULT hr;
  110. LPWSTR wszApp;
  111. DWORD dwExStyle, i, cchApps, cApps, dwChecked, cxMax;
  112. RECT rect;
  113. int iList;
  114. if (pcchMax == NULL || pcfg == NULL || hlc == NULL || pcxMax == NULL)
  115. return FALSE;
  116. // set up the list control
  117. SendMessage(hlc, LVM_SETUNICODEFORMAT, TRUE, 0);
  118. dwExStyle = (LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
  119. SendMessage(hlc, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExStyle, dwExStyle);
  120. GetClientRect(hlc, &rect);
  121. *pcxMax = rect.right - GetSystemMetrics(SM_CYHSCROLL);
  122. ZeroMemory(&lvc, sizeof(lvc));
  123. lvc.mask = LVCF_FMT;
  124. lvc.fmt = LVCFMT_LEFT;
  125. ListView_InsertColumn(hlc, 0, &lvc);
  126. hr = pcfg->InitList(epflt);
  127. if (FAILED(hr))
  128. return FALSE;
  129. hr = pcfg->get_ListRegInfo(epflt, &cchApps, &cApps);
  130. if (FAILED(hr))
  131. return FALSE;
  132. cchApps++;
  133. if (cchApps > *pcchMax)
  134. *pcchMax = cchApps;
  135. __try
  136. {
  137. wszApp = (LPWSTR)_alloca(cchApps * sizeof(WCHAR));
  138. }
  139. __except (GetExceptionCode() == STATUS_STACK_OVERFLOW)
  140. {
  141. wszApp = NULL;
  142. _resetstkoflw();
  143. }
  144. if (wszApp == NULL)
  145. return FALSE;
  146. ZeroMemory(&lvi, sizeof(lvi));
  147. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  148. lvi.stateMask = LVIS_STATEIMAGEMASK;
  149. lvi.state = 0;
  150. lvi.pszText = wszApp;
  151. for (i = 0; i < cApps; i++)
  152. {
  153. hr = pcfg->get_ListRegApp(epflt, i, wszApp, cchApps + 1, &dwChecked);
  154. if (FAILED(hr))
  155. return FALSE;
  156. cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)wszApp);
  157. cxMax += c_dxLVChkPixels;
  158. if (cxMax > *pcxMax)
  159. *pcxMax = cxMax;
  160. lvi.iItem = i;
  161. lvi.lParam = 1 + ((dwChecked == 1) ? 1 : 0);
  162. iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
  163. if (iList >= 0)
  164. ListView_SetCheckState(hlc, iList, (dwChecked == 1));
  165. }
  166. ListView_SetColumnWidth(hlc, 0, *pcxMax);
  167. if (cApps > 0)
  168. {
  169. ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED,
  170. LVIS_FOCUSED | LVIS_SELECTED);
  171. }
  172. return TRUE;
  173. }
  174. ///////////////////////////////////////////////////////////////////////////////
  175. // Add Program dialog proc
  176. // **************************************************************************
  177. static UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
  178. LPARAM lParam)
  179. {
  180. HWND hwndFile;
  181. switch(uMsg)
  182. {
  183. case WM_INITDIALOG:
  184. hwndFile = GetParent(hdlg);
  185. if (hwndFile != NULL)
  186. SendMessage(hwndFile, CDM_SETCONTROLTEXT, IDOK, (LPARAM)g_szOk);
  187. return TRUE;
  188. default:
  189. return FALSE;
  190. }
  191. return FALSE;
  192. }
  193. // **************************************************************************
  194. #define LAUNCHOFN_OFFSET 10
  195. static BOOL LaunchOFNDialog(HWND hdlg, LPWSTR wszFile, DWORD cchFile)
  196. {
  197. OPENFILENAMEW ofn;
  198. WCHAR wszFilePath[2 * MAX_PATH];
  199. WCHAR wszInitalDir[] = L"\\";
  200. WCHAR wszFilter[MAX_PATH], *pwsz;
  201. DWORD dw;
  202. if (wszFile == NULL || cchFile == 0)
  203. {
  204. return FALSE;
  205. }
  206. // the filter string needs to be of the form <Description>\0<Extension>\0\0
  207. ZeroMemory(wszFilter, sizeof(wszFilter));
  208. COMPILETIME_ASSERT(sizeof(wszFilter) >= sizeof(g_wszFilter)); // should always be bigger
  209. StringCchCopy(wszFilter, ARRAYSIZE(wszFilter), g_wszFilter);
  210. dw = wcslen(g_wszFilter);
  211. if (dw < (ARRAYSIZE(wszFilter) - LAUNCHOFN_OFFSET))
  212. {
  213. pwsz = wszFilter + dw + 1;
  214. }
  215. else
  216. {
  217. pwsz = wszFilter + ARRAYSIZE(wszFilter) - LAUNCHOFN_OFFSET;
  218. ZeroMemory(pwsz, LAUNCHOFN_OFFSET * sizeof(WCHAR));
  219. pwsz++;
  220. }
  221. EVAL(SUCCEEDED(StringCchCopy(pwsz, LAUNCHOFN_OFFSET, L"*.exe"))); // should always be room
  222. wszFilePath[0] = L'\0';
  223. ZeroMemory(&ofn, sizeof(ofn));
  224. ofn.lStructSize = sizeof(ofn);
  225. ofn.hwndOwner = hdlg;
  226. ofn.lpstrFilter = wszFilter;
  227. ofn.lpstrFile = wszFilePath;
  228. ofn.nMaxFile = ARRAYSIZE(wszFilePath);
  229. ofn.lpstrFileTitle = wszFile;
  230. ofn.nMaxFileTitle = cchFile;
  231. ofn.lpstrInitialDir = wszInitalDir;
  232. ofn.lpstrTitle = g_wszTitle;
  233. ofn.Flags = OFN_DONTADDTORECENT | OFN_ENABLESIZING |
  234. OFN_EXPLORER | OFN_FILEMUSTEXIST |
  235. OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
  236. OFN_PATHMUSTEXIST | OFN_SHAREAWARE;
  237. ofn.lpstrDefExt = NULL;
  238. ofn.lpfnHook = OFNHookProc;
  239. // get the filename & fill in the edit box with it
  240. return GetOpenFileNameW(&ofn);
  241. }
  242. // **************************************************************************
  243. static INT_PTR APIENTRY PFRAddDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam,
  244. LPARAM lParam)
  245. {
  246. BOOL fShowErr = FALSE;
  247. switch (uMsg)
  248. {
  249. case WM_INITDIALOG:
  250. {
  251. HWND hbtn;
  252. SetWindowLongPtr(hdlg, DWLP_USER, lParam);
  253. // disable the ok button cuz we know that we don't have anything
  254. // in the 'filename' edit box
  255. hbtn = GetDlgItem(hdlg, IDOK);
  256. if (hbtn != NULL)
  257. EnableWindow(hbtn, FALSE);
  258. }
  259. break;
  260. // F1 help
  261. case WM_HELP:
  262. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  263. HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER);
  264. break;
  265. // right-click help
  266. case WM_CONTEXTMENU:
  267. WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU,
  268. (DWORD_PTR)g_rgPFER);
  269. break;
  270. case WM_COMMAND:
  271. switch (LOWORD(wParam))
  272. {
  273. // browse button
  274. case IDC_PFR_BROWSE:
  275. {
  276. WCHAR wszFile[2 * MAX_PATH];
  277. // get the filename & fill in the edit box with it
  278. if (LaunchOFNDialog(hdlg, wszFile, ARRAYSIZE(wszFile)))
  279. SetDlgItemTextW(hdlg, IDC_PFR_NEWPROG, wszFile);
  280. break;
  281. }
  282. // Ok button
  283. case IDOK:
  284. {
  285. SAddDlg *psad;
  286. psad = (SAddDlg *)GetWindowLongPtr(hdlg, DWLP_USER);
  287. if (psad != NULL)
  288. {
  289. WCHAR *wszText, *pwsz;
  290. DWORD cch;
  291. HWND hwndText;
  292. BOOL fReplaceWSpace = TRUE;
  293. hwndText = GetDlgItem(hdlg, IDC_PFR_NEWPROG);
  294. if (hwndText == NULL)
  295. {
  296. fShowErr = TRUE;
  297. goto done;
  298. }
  299. cch = GetWindowTextLength(hwndText);
  300. if (cch == 0)
  301. {
  302. fShowErr = TRUE;
  303. goto done;
  304. }
  305. cch++;
  306. __try
  307. {
  308. wszText = (LPWSTR)_alloca(cch * sizeof(WCHAR));
  309. }
  310. __except (GetExceptionCode() == STATUS_STACK_OVERFLOW)
  311. {
  312. wszText = NULL;
  313. _resetstkoflw();
  314. }
  315. if (wszText == NULL)
  316. {
  317. fShowErr = TRUE;
  318. goto done;
  319. }
  320. *psad->wszApp = L'\0';
  321. *wszText = L'\0';
  322. GetDlgItemTextW(hdlg, IDC_PFR_NEWPROG, wszText, cch);
  323. // make sure that we only have the exe name- probably
  324. // should verify that it IS an exe, but it's possible
  325. // we'd want to trap on other file types as well, so
  326. // don't for now.
  327. // And while we're at it, rip off any trailing
  328. // whitespace (preceeding whitespace is apparently ok)
  329. cch = wcslen(wszText);
  330. if (cch > 0)
  331. {
  332. for(pwsz = wszText + cch - 1; pwsz > wszText; pwsz--)
  333. {
  334. if (fReplaceWSpace)
  335. {
  336. if (iswspace(*pwsz))
  337. *pwsz = L'\0';
  338. else
  339. fReplaceWSpace = FALSE;
  340. }
  341. if (*pwsz == L'\\')
  342. {
  343. pwsz++;
  344. break;
  345. }
  346. }
  347. if (*pwsz == L'\\')
  348. pwsz++;
  349. }
  350. cch = wcslen(pwsz);
  351. if (cch >= MAX_PATH || cch == 0)
  352. {
  353. fShowErr = TRUE;
  354. goto done;
  355. }
  356. if (FAILED(StringCchCopy(psad->wszApp, ARRAYSIZE(psad->wszApp), pwsz)))
  357. {
  358. psad->wszApp[0] = L'\0';
  359. }
  360. }
  361. EndDialog(hdlg, IDOK);
  362. break;
  363. }
  364. // cancel button
  365. case IDCANCEL:
  366. EndDialog(hdlg, IDCANCEL);
  367. break;
  368. case IDC_PFR_NEWPROG:
  369. if (HIWORD(wParam) == EN_CHANGE)
  370. {
  371. HWND hbtn, hedt;
  372. hbtn = GetDlgItem(hdlg, IDOK);
  373. hedt = (HWND)(DWORD_PTR)lParam;
  374. if (hedt != NULL && hbtn != NULL)
  375. {
  376. if (GetWindowTextLength(hedt) != 0)
  377. EnableWindow(hbtn, TRUE);
  378. else
  379. EnableWindow(hbtn, FALSE);
  380. }
  381. }
  382. break;
  383. // return FALSE to indicate that we didn't handle the msg
  384. default:
  385. return FALSE;
  386. }
  387. break;
  388. // return FALSE to indicate that we didn't handle the msg
  389. default:
  390. return FALSE;
  391. }
  392. done:
  393. if (fShowErr)
  394. {
  395. TCHAR szMsg[256];
  396. LoadString(hInstance, IDS_PFR_BADFILE, szMsg, ARRAYSIZE(szMsg));
  397. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  398. }
  399. return FALSE;
  400. }
  401. ///////////////////////////////////////////////////////////////////////////////
  402. // Programs dialog proc
  403. // **************************************************************************
  404. static BOOL InitProgDlg(HWND hdlg, SProgDlg *pspd)
  405. {
  406. CPFFaultClientCfg *pcfg;
  407. LVITEMW lvi;
  408. DWORD cxMax;
  409. HWND hlc, hbtn;
  410. BOOL fRet = FALSE;
  411. int iList, cItems;
  412. if (pspd == NULL)
  413. goto done;
  414. pcfg = pspd->pcfg;
  415. // fill in the exclude list
  416. hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST);
  417. if (hlc == NULL)
  418. goto done;
  419. if (InitializePFLV(epfltExclude, hlc, &pspd->cchMax, &pspd->cxMaxE,
  420. pcfg) == FALSE)
  421. goto done;
  422. // fill in the include list
  423. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  424. if (hlc == NULL)
  425. goto done;
  426. if (InitializePFLV(epfltInclude, hlc, &pspd->cchMax, &pspd->cxMaxI,
  427. pcfg) == FALSE)
  428. goto done;
  429. pspd->fShowIncRem = TRUE;
  430. // add the item to the include list that lets users include all MS apps
  431. pspd->eieMS = pcfg->get_IncMSApps();
  432. // Note that we set lParam to 1 or 2. This is because we need to ignore
  433. // the first notification message for the list item + the 2nd one if the
  434. // check state is set. Processing these two messages leads to corruption
  435. // in the configuration settings
  436. ZeroMemory(&lvi, sizeof(lvi));
  437. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  438. lvi.stateMask = LVIS_STATEIMAGEMASK;
  439. lvi.state = 0;
  440. lvi.pszText = g_wszMSProg;
  441. lvi.iItem = 0;
  442. lvi.lParam = (1 + ((pspd->eieMS == eieInclude) ? 1 : 0)) | EXALLMS;
  443. iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
  444. if (iList >= 0)
  445. ListView_SetCheckState(hlc, iList, (pspd->eieMS == eieInclude));
  446. cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)g_wszMSProg);
  447. cxMax += c_dxLVChkPixels;
  448. if (cxMax > pspd->cxMaxI)
  449. {
  450. pspd->cxMaxI = cxMax;
  451. ListView_SetColumnWidth(hlc, 0, cxMax);
  452. }
  453. // add the item to the include list that lets users exclude all windows
  454. // components
  455. pspd->eieWinComp = pcfg->get_IncWinComp();
  456. // Note that we set lParam to 1 or 2. This is because we need to ignore
  457. // the first notification message for the list item + the 2nd one if the
  458. // check state is set. Processing these two messages leads to corruption
  459. // in the configuration settings
  460. ZeroMemory(&lvi, sizeof(lvi));
  461. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  462. lvi.stateMask = LVIS_STATEIMAGEMASK;
  463. lvi.state = 0;
  464. lvi.pszText = g_szWinComp;
  465. lvi.iItem = 1;
  466. lvi.lParam = (1 + ((pspd->eieWinComp == eieInclude) ? 1 : 0)) | EXWINCOMP;
  467. iList = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
  468. if (iList >= 0)
  469. ListView_SetCheckState(hlc, iList, (pspd->eieWinComp == eieInclude));
  470. cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)g_szWinComp);
  471. cxMax += c_dxLVChkPixels;
  472. if (cxMax > pspd->cxMaxI)
  473. {
  474. pspd->cxMaxI = cxMax;
  475. ListView_SetColumnWidth(hlc, 0, cxMax);
  476. }
  477. // do misc setup on the exclusion list (disabling the remove button,
  478. // setting the initial focus)
  479. hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST);
  480. cItems = ListView_GetItemCount(hlc);
  481. if (cItems == 0)
  482. {
  483. hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM);
  484. if (hbtn != NULL)
  485. EnableWindow(hbtn, FALSE);
  486. }
  487. else
  488. {
  489. ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED,
  490. LVIS_FOCUSED | LVIS_SELECTED);
  491. }
  492. // do misc setup on the inclusion list (disabling the remove button,
  493. // setting the initial focus)
  494. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  495. ListView_SetItemState(hlc, 0, LVIS_FOCUSED | LVIS_SELECTED,
  496. LVIS_FOCUSED | LVIS_SELECTED);
  497. cItems = ListView_GetItemCount(hlc);
  498. if (cItems < 3)
  499. {
  500. hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM);
  501. if (hbtn != NULL)
  502. EnableWindow(hbtn, FALSE);
  503. pspd->fShowIncRem = FALSE;
  504. }
  505. // set up the radio buttons- if we are in 'include all' mode, then
  506. // we don't need the inclusion list.
  507. if (((DWORD)pspd->eieApps & eieIncMask) == eieInclude)
  508. {
  509. CheckDlgButton(hdlg, IDC_PFR_DEFALL, BST_CHECKED);
  510. CheckDlgButton(hdlg, IDC_PFR_DEFNONE, BST_UNCHECKED);
  511. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  512. if (hlc != NULL)
  513. EnableWindow(hlc, FALSE);
  514. hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM);
  515. if (hbtn != NULL)
  516. EnableWindow(hbtn, FALSE);
  517. hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD);
  518. if (hbtn != NULL)
  519. EnableWindow(hbtn, FALSE);
  520. }
  521. else
  522. {
  523. CheckDlgButton(hdlg, IDC_PFR_DEFALL, BST_UNCHECKED);
  524. CheckDlgButton(hdlg, IDC_PFR_DEFNONE, BST_CHECKED);
  525. EnableWindow(hlc, TRUE);
  526. }
  527. fRet = TRUE;
  528. done:
  529. if (fRet == FALSE)
  530. {
  531. TCHAR szMsg[MAX_PATH];
  532. LoadString(hInstance, IDS_PFR_CFGREADERR, szMsg, ARRAYSIZE(szMsg));
  533. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  534. }
  535. return fRet;
  536. }
  537. // **************************************************************************
  538. static BOOL AddProgramToList(HWND hdlg, HWND hlc, SProgDlg *pspd,
  539. EPFListType epflt)
  540. {
  541. CPFFaultClientCfg *pcfg = NULL;
  542. HRESULT hr;
  543. SAddDlg sad;
  544. LVITEMW lvi;
  545. DWORD cch, cxMax, *pcxMax;
  546. TCHAR szMsg[256];
  547. HWND hbtn;
  548. int nID, cItems;
  549. if (pspd == NULL)
  550. return FALSE;
  551. pcfg = pspd->pcfg;
  552. ZeroMemory(&sad, sizeof(sad));
  553. nID = (int)DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PFR_ADDPROG),
  554. hdlg, PFRAddDlgProc, (LPARAM)&sad);
  555. if (nID == IDCANCEL || sad.wszApp[0] == L'\0')
  556. return FALSE;
  557. if (pcfg->IsOnList(epfltInclude, sad.wszApp))
  558. {
  559. LoadString(hInstance, IDS_PFR_ISONLISTI, szMsg, ARRAYSIZE(szMsg));
  560. if (epflt == epfltExclude)
  561. {
  562. TCHAR szTmp[256];
  563. LoadString(hInstance, IDS_PFR_ADDTOEX, szTmp, ARRAYSIZE(szTmp));
  564. StringCchCat(szMsg, ARRAYSIZE(szMsg), szTmp); // display string, truncation ok
  565. }
  566. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  567. return FALSE;
  568. }
  569. else if (pcfg->IsOnList(epfltExclude, sad.wszApp))
  570. {
  571. LoadString(hInstance, IDS_PFR_ISONLISTE, szMsg, ARRAYSIZE(szMsg));
  572. if (epflt == epfltInclude)
  573. {
  574. TCHAR szTmp[256];
  575. LoadString(hInstance, IDS_PFR_ADDTOINC, szTmp, ARRAYSIZE(szTmp));
  576. StringCchCat(szMsg, ARRAYSIZE(szMsg), szTmp); // display string, truncation ok
  577. }
  578. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  579. return FALSE;
  580. }
  581. cItems = ListView_GetItemCount(hlc);
  582. // update the max string size if necessary
  583. cch = wcslen(sad.wszApp);
  584. if (cch >= pspd->cchMax)
  585. pspd->cchMax = cch + 1;
  586. // yay! add it to the config class
  587. hr = pcfg->add_ListApp(epflt, sad.wszApp);
  588. if (FAILED(hr))
  589. return FALSE;
  590. pcxMax = (epflt == epfltInclude) ? &pspd->cxMaxI : &pspd->cxMaxE;
  591. cxMax = (DWORD)SendMessageW(hlc, LVM_GETSTRINGWIDTHW, 0, (LPARAM)sad.wszApp);
  592. cxMax += c_dxLVChkPixels;
  593. if (cxMax > *pcxMax)
  594. {
  595. *pcxMax = cxMax;
  596. ListView_SetColumnWidth(hlc, 0, cxMax);
  597. }
  598. // add it to the UI
  599. // Note that we set lParam to 2. This is because we need to ignore the
  600. // first two notification messages per entry sent to the wndproc because
  601. // they are 'list initialization' messages and processing them leads to
  602. // corruption in the configuration settings
  603. ZeroMemory(&lvi, sizeof(lvi));
  604. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  605. lvi.stateMask = LVIS_STATEIMAGEMASK;
  606. lvi.state = 0;
  607. lvi.pszText = sad.wszApp;
  608. lvi.iItem = 0;
  609. lvi.lParam = 2;
  610. nID = (int)SendMessageW(hlc, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
  611. if (nID >= 0)
  612. ListView_SetCheckState(hlc, nID, TRUE);
  613. // if there are no items, then there is no currently selected item, so
  614. // make sure this item gets selected. In our handler for this message
  615. // we will take care of setting the 'last selected item' field...
  616. if (cItems == 0)
  617. {
  618. ListView_SetItemState(hlc, nID, LVIS_FOCUSED | LVIS_SELECTED,
  619. LVIS_FOCUSED | LVIS_SELECTED);
  620. // Also, got to make sure we enable the 'Remove' button. The only
  621. // way we can get zero items in a list is in the exclude list cuz
  622. // the include list always has the 'include MS apps' item.
  623. hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM);
  624. if (hbtn != NULL)
  625. EnableWindow(hbtn, TRUE);
  626. }
  627. return TRUE;
  628. }
  629. // **************************************************************************
  630. static BOOL DelProgramFromList(HWND hdlg, HWND hlc, SProgDlg *pspd,
  631. EPFListType epflt)
  632. {
  633. LVITEMW lvi;
  634. HRESULT hr;
  635. LPWSTR wszApp;
  636. DWORD cItems, iSel;
  637. __try
  638. {
  639. wszApp = (LPWSTR)_alloca(pspd->cchMax * sizeof(WCHAR));
  640. }
  641. __except (GetExceptionCode() == STATUS_STACK_OVERFLOW)
  642. {
  643. wszApp = NULL;
  644. _resetstkoflw();
  645. }
  646. if (wszApp == NULL)
  647. return FALSE;
  648. iSel = ((epflt == epfltInclude) ? pspd->iLastSelI : pspd->iLastSelE);
  649. // fetch the string for the item
  650. ZeroMemory(&lvi, sizeof(lvi));
  651. lvi.iItem = iSel;
  652. lvi.mask = LVIF_TEXT;
  653. lvi.pszText = wszApp;
  654. lvi.cchTextMax = pspd->cchMax;
  655. if (SendMessageW(hlc, LVM_GETITEMW, 0, (LPARAM)&lvi))
  656. {
  657. // delete it from the config class
  658. hr = pspd->pcfg->del_ListApp(epflt, lvi.pszText);
  659. if (FAILED(hr))
  660. return FALSE;
  661. }
  662. // delete it from the UI
  663. if (ListView_DeleteItem(hlc, iSel) == FALSE)
  664. return FALSE;
  665. // reset the selection to be either the same index or one higher (if the
  666. // user deleted the last item)
  667. cItems = ListView_GetItemCount(hlc);
  668. if (cItems == 0)
  669. {
  670. HWND hbtn;
  671. // only time we can ever hit zero items is in the exclude list cuz the
  672. // include list always has the 'include MS apps' option.
  673. hbtn = GetDlgItem(hdlg, IDC_PFR_EXADD);
  674. if (hbtn != NULL)
  675. {
  676. SetFocus(hbtn);
  677. SendMessage(hdlg, DM_SETDEFID, IDC_PFR_EXADD, 0);
  678. }
  679. hbtn = GetDlgItem(hdlg, IDC_PFR_EXREM);
  680. if (hbtn != NULL)
  681. EnableWindow(hbtn, FALSE);
  682. pspd->iLastSelI = 0;
  683. return TRUE;
  684. }
  685. // if cItems <= iSel, then we just deleted the last index, so decrement the
  686. // select index down 1.
  687. else if (cItems <= iSel)
  688. {
  689. iSel--;
  690. }
  691. // this will convieniently take care of setting the appropriate iLastSel
  692. // field
  693. ListView_SetItemState(hlc, iSel, LVIS_FOCUSED | LVIS_SELECTED,
  694. LVIS_FOCUSED | LVIS_SELECTED);
  695. return TRUE;
  696. }
  697. // **************************************************************************
  698. static INT_PTR APIENTRY PFRProgDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam,
  699. LPARAM lParam)
  700. {
  701. CPFFaultClientCfg *pcfg = NULL;
  702. SProgDlg *pspd = (SProgDlg *)GetWindowLongPtr(hdlg, DWLP_USER);
  703. HRESULT hr;
  704. HWND hlc, hbtn;
  705. if (pspd != NULL)
  706. pcfg = pspd->pcfg;
  707. switch(uMsg)
  708. {
  709. case WM_INITDIALOG:
  710. SetWindowLongPtr(hdlg, DWLP_USER, lParam);
  711. if (InitProgDlg(hdlg, (SProgDlg *)lParam) == FALSE)
  712. EndDialog(hdlg, IDCANCEL);
  713. break;
  714. // F1 help
  715. case WM_HELP:
  716. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  717. HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER);
  718. break;
  719. // right-click help
  720. case WM_CONTEXTMENU:
  721. WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU,
  722. (DWORD_PTR)g_rgPFER);
  723. break;
  724. case WM_COMMAND:
  725. {
  726. switch (LOWORD(wParam))
  727. {
  728. case IDOK:
  729. if (pspd->fRW)
  730. {
  731. hr = pcfg->CommitChanges(epfltExclude);
  732. if (SUCCEEDED(hr))
  733. {
  734. hr = pcfg->CommitChanges(epfltInclude);
  735. if (SUCCEEDED(hr))
  736. {
  737. pcfg->set_IncWinComp(pspd->eieWinComp);
  738. pcfg->set_IncMSApps(pspd->eieMS);
  739. pcfg->set_AllOrNone(pspd->eieApps);
  740. hr = pcfg->Write();
  741. }
  742. }
  743. if (FAILED(hr))
  744. {
  745. TCHAR szMsg[MAX_PATH];
  746. if (hr != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  747. {
  748. LoadString(hInstance, IDS_PFR_CFGWRITEERR, szMsg,
  749. ARRAYSIZE(szMsg));
  750. }
  751. else
  752. {
  753. LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg,
  754. ARRAYSIZE(szMsg));
  755. }
  756. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  757. pcfg->ClearChanges(epfltExclude);
  758. pcfg->ClearChanges(epfltInclude);
  759. }
  760. }
  761. else
  762. {
  763. TCHAR szMsg[MAX_PATH];
  764. LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg,
  765. ARRAYSIZE(szMsg));
  766. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  767. }
  768. EndDialog(hdlg, IDOK);
  769. break;
  770. case IDCANCEL:
  771. EndDialog(hdlg, IDCANCEL);
  772. break;
  773. case IDC_PFR_DEFNONE:
  774. pspd->eieApps = (EIncEx)(((DWORD)pspd->eieApps & eieDisableMask) |
  775. eieExclude);
  776. // enable the include list.
  777. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  778. if (hlc != NULL)
  779. EnableWindow(hlc, TRUE);
  780. hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD);
  781. if (hbtn != NULL)
  782. EnableWindow(hbtn, TRUE);
  783. hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM);
  784. if (hbtn != NULL)
  785. EnableWindow(hbtn, pspd->fShowIncRem);
  786. break;
  787. case IDC_PFR_DEFALL:
  788. pspd->eieApps = (EIncEx)(((DWORD)pspd->eieApps & eieDisableMask) |
  789. eieInclude);
  790. // disable the include list.
  791. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  792. if (hlc != NULL)
  793. EnableWindow(hlc, FALSE);
  794. hbtn = GetDlgItem(hdlg, IDC_PFR_INCADD);
  795. if (hbtn != NULL)
  796. EnableWindow(hbtn, FALSE);
  797. hbtn = GetDlgItem(hdlg, IDC_PFR_INCREM);
  798. if (hbtn != NULL)
  799. EnableWindow(hbtn, FALSE);
  800. break;
  801. case IDC_PFR_INCADD:
  802. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  803. if (hlc != NULL)
  804. return AddProgramToList(hdlg, hlc, pspd, epfltInclude);
  805. break;
  806. case IDC_PFR_EXADD:
  807. hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST);
  808. if (hlc != NULL)
  809. return AddProgramToList(hdlg, hlc, pspd, epfltExclude);
  810. break;
  811. case IDC_PFR_INCREM:
  812. hlc = GetDlgItem(hdlg, IDC_PFR_INCLIST);
  813. if (hlc != NULL)
  814. return DelProgramFromList(hdlg, hlc, pspd, epfltInclude);
  815. break;
  816. case IDC_PFR_EXREM:
  817. hlc = GetDlgItem(hdlg, IDC_PFR_EXLIST);
  818. if (hlc != NULL)
  819. return DelProgramFromList(hdlg, hlc, pspd, epfltExclude);
  820. break;
  821. default:
  822. return FALSE;
  823. }
  824. break;
  825. }
  826. case WM_SETEIELVSEL:
  827. {
  828. hlc = GetDlgItem(hdlg, (int)wParam);
  829. if (ListView_GetItemCount(hlc) > 0)
  830. {
  831. int iSel;
  832. if (wParam == IDC_PFR_EXLIST)
  833. iSel = pspd->iLastSelE;
  834. else
  835. iSel = pspd->iLastSelI;
  836. ListView_SetItemState(hlc, iSel,
  837. LVIS_FOCUSED | LVIS_SELECTED,
  838. LVIS_FOCUSED | LVIS_SELECTED);
  839. }
  840. break;
  841. }
  842. case WM_NOTIFY:
  843. {
  844. EPFListType epflt;
  845. NMLISTVIEW *pnmlv = (NMLISTVIEW *)lParam;
  846. LVITEMW lvi;
  847. NMHDR *pnmh = (NMHDR *)lParam;
  848. DWORD dw;
  849. UINT uiBtn;
  850. BOOL fCheck;
  851. int iSel;
  852. if ((pnmh->code != LVN_ITEMCHANGED &&
  853. pnmh->code != NM_SETFOCUS) ||
  854. (pnmh->idFrom != IDC_PFR_EXLIST &&
  855. pnmh->idFrom != IDC_PFR_INCLIST))
  856. return FALSE;
  857. hlc = pnmh->hwndFrom;
  858. uiBtn = (pnmh->idFrom == IDC_PFR_EXLIST) ? IDC_PFR_EXREM :
  859. IDC_PFR_INCREM;
  860. hbtn = GetDlgItem(hdlg, uiBtn);
  861. // check and see if there are any selected items
  862. iSel = (int)SendMessage(hlc, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
  863. if (iSel < 0)
  864. {
  865. EnableWindow(hbtn, FALSE);
  866. if (pnmh->idFrom == IDC_PFR_INCLIST)
  867. pspd->fShowIncRem = FALSE;
  868. }
  869. else
  870. {
  871. if (pnmh->code == NM_SETFOCUS)
  872. {
  873. PostMessage(hdlg, WM_SETEIELVSEL, pnmh->idFrom, pnmh->code);
  874. return TRUE;
  875. }
  876. }
  877. // if it doesn't fit this condition, don't give a rat's patootie
  878. // about it
  879. if ((pnmlv->uChanged & LVIF_STATE) == 0 ||
  880. (pnmlv->uNewState ^ pnmlv->uOldState) == 0)
  881. return FALSE;
  882. // hack cuz we get 1 or 2 messages when inserting items into the
  883. // list & initially setting their check state. Want to not
  884. // process those messages. The exception is the 'include
  885. // ms apps' item which we can process any number of times
  886. if ((pnmlv->lParam & ~EXNOREM) > 0)
  887. {
  888. ZeroMemory(&lvi, sizeof(lvi));
  889. lvi.iItem = pnmlv->iItem;
  890. lvi.mask = LVIF_PARAM;
  891. lvi.lParam = (pnmlv->lParam - 1) | (pnmlv->lParam & EXNOREM);
  892. SendMessageW(hlc, LVM_SETITEM, 0, (LPARAM)&lvi);
  893. return TRUE;
  894. }
  895. // did the selection change?
  896. if ((pnmlv->uNewState & LVIS_SELECTED) != 0)
  897. {
  898. if (pnmh->idFrom == IDC_PFR_INCLIST)
  899. {
  900. pspd->iLastSelI = pnmlv->iItem;
  901. // we need to disable the exclude remove button if we hit
  902. // the 'exclude non ms apps' item
  903. if (hbtn != NULL)
  904. {
  905. if ((pnmlv->lParam & EXNOREM) != 0)
  906. {
  907. // disable the remove button- but if the remove
  908. // button had focus, we need to reset the focus
  909. // or nothing on the dialog will have focus.
  910. if (GetFocus() == hbtn)
  911. {
  912. HWND hbtnAdd;
  913. hbtnAdd = GetDlgItem(hdlg, IDC_PFR_INCADD);
  914. if (hbtnAdd != NULL)
  915. {
  916. SetFocus(hbtnAdd);
  917. SendMessage(hdlg, DM_SETDEFID, IDC_PFR_INCADD, 0);
  918. }
  919. }
  920. pspd->fShowIncRem = FALSE;
  921. EnableWindow(hbtn, FALSE);
  922. }
  923. else
  924. {
  925. pspd->fShowIncRem = TRUE;
  926. EnableWindow(hbtn, TRUE);
  927. }
  928. }
  929. }
  930. else
  931. {
  932. pspd->iLastSelE = pnmlv->iItem;
  933. if (hbtn != NULL)
  934. EnableWindow(hbtn, TRUE);
  935. }
  936. }
  937. // if we don't have a check-state change, can bail now.
  938. if (((pnmlv->uNewState ^ pnmlv->uOldState) & 0x3000) == 0)
  939. return TRUE;
  940. fCheck = ListView_GetCheckState(hlc, pnmlv->iItem);
  941. if (pnmh->idFrom == IDC_PFR_EXLIST)
  942. epflt = epfltExclude;
  943. else
  944. epflt = epfltInclude;
  945. // did we modify the 'exclude non ms apps' item?
  946. if ((pnmlv->lParam & EXNOREM) != 0)
  947. {
  948. if ((pnmlv->lParam & EXALLMS) != 0)
  949. pspd->eieMS = ((fCheck) ? eieInclude : eieExclude);
  950. else
  951. pspd->eieWinComp = ((fCheck) ? eieInclude : eieExclude);
  952. }
  953. // nope, modified a regular item
  954. else
  955. {
  956. LPWSTR wszApp;
  957. __try
  958. {
  959. wszApp = (LPWSTR)_alloca(pspd->cchMax * sizeof(WCHAR));
  960. }
  961. __except(GetExceptionCode() == STATUS_STACK_OVERFLOW)
  962. {
  963. wszApp = NULL;
  964. _resetstkoflw();
  965. }
  966. if (wszApp == NULL)
  967. return FALSE;
  968. // got to fetch it to make sure we have a unicode string
  969. ZeroMemory(&lvi, sizeof(lvi));
  970. lvi.iItem = pnmlv->iItem;
  971. lvi.mask = LVIF_TEXT;
  972. lvi.pszText = wszApp;
  973. lvi.cchTextMax = pspd->cchMax;
  974. if (SendMessageW(hlc, LVM_GETITEMW, 0, (LPARAM)&lvi))
  975. {
  976. hr = pcfg->mod_ListApp(epflt, lvi.pszText, fCheck);
  977. if (FAILED(hr))
  978. return FALSE;
  979. }
  980. }
  981. break;
  982. }
  983. default:
  984. return FALSE;
  985. }
  986. return FALSE;
  987. }
  988. ///////////////////////////////////////////////////////////////////////////////
  989. // Main PFR dialog proc
  990. // **************************************************************************
  991. static BOOL InitMainDlg(HWND hdlg)
  992. {
  993. CPFFaultClientCfg *pcfg = NULL;
  994. SMainDlg *psmd = NULL;
  995. BOOL fRet = FALSE;
  996. UINT ui;
  997. HWND hbtn, hchk;
  998. LoadPFRResourceStrings();
  999. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1000. if (hbtn == NULL)
  1001. goto done;
  1002. psmd = new SMainDlg;
  1003. if (psmd == NULL)
  1004. goto done;
  1005. pcfg = new CPFFaultClientCfg;
  1006. if (pcfg == NULL)
  1007. goto done;
  1008. // see if this user has write access to the appropriate registry
  1009. // locations
  1010. psmd->fRW = pcfg->HasWriteAccess();
  1011. if (FAILED(pcfg->Read((psmd->fRW) ? eroCPRW : eroCPRO)))
  1012. goto done;
  1013. psmd->eedReport = pcfg->get_DoReport();
  1014. psmd->eieKernel = pcfg->get_IncKernel();
  1015. psmd->eieApps = pcfg->get_AllOrNone();
  1016. psmd->eedShowUI = pcfg->get_ShowUI();
  1017. psmd->eieShut = pcfg->get_IncShutdown();
  1018. psmd->fForceQueue = pcfg->get_ForceQueueMode();
  1019. psmd->iLastSel = 0;
  1020. // if ShowUI is completely disabled, then so should reporting- the control
  1021. // panel does not support entering corporate mode.
  1022. if (psmd->eedShowUI == eedDisabled)
  1023. psmd->eedReport = eedDisabled;
  1024. psmd->pcfg = pcfg;
  1025. SetWindowLongPtr(hdlg, DWLP_USER, (LONG_PTR)psmd);
  1026. // set up the kernel checkbox
  1027. ui = (psmd->eieKernel == eieInclude) ? BST_CHECKED : BST_UNCHECKED;
  1028. CheckDlgButton(hdlg, IDC_PFR_ENABLEOS, ui);
  1029. // set up the programs checkbox
  1030. ui = ((psmd->eieApps & eieDisableMask) == 0) ? BST_CHECKED : BST_UNCHECKED;
  1031. CheckDlgButton(hdlg, IDC_PFR_ENABLEPROG, ui);
  1032. // set up the notification checkbox
  1033. ui = (psmd->eedShowUI == eedEnabled) ? BST_CHECKED : BST_UNCHECKED;
  1034. CheckDlgButton(hdlg, IDC_PFR_SHOWUI, ui);
  1035. // set up the shutdown checkbox on server only
  1036. if (pcfg->get_IsServer())
  1037. {
  1038. ui = (psmd->eieShut == eieInclude) ? BST_CHECKED : BST_UNCHECKED;
  1039. CheckDlgButton(hdlg, IDC_PFR_ENABLESHUT, ui);
  1040. ui = (psmd->fForceQueue) ? BST_CHECKED : BST_UNCHECKED;
  1041. CheckDlgButton(hdlg, IDC_PFR_FORCEQ, ui);
  1042. }
  1043. // set up the radio buttons
  1044. if (psmd->eedReport == eedDisabled)
  1045. {
  1046. CheckRadioButton(hdlg, IDC_PFR_DISABLE, IDC_PFR_ENABLE, IDC_PFR_DISABLE);
  1047. hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI);
  1048. if (hchk != NULL)
  1049. EnableWindow(hchk, TRUE);
  1050. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS);
  1051. if (hchk != NULL)
  1052. EnableWindow(hchk, FALSE);
  1053. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG);
  1054. if (hchk != NULL)
  1055. EnableWindow(hchk, FALSE);
  1056. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1057. if (hbtn != NULL)
  1058. EnableWindow(hbtn, FALSE);
  1059. if (pcfg->get_IsServer())
  1060. {
  1061. hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT);
  1062. if (hbtn != NULL)
  1063. EnableWindow(hbtn, FALSE);
  1064. hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ);
  1065. if (hbtn != NULL)
  1066. EnableWindow(hbtn, FALSE);
  1067. }
  1068. }
  1069. else
  1070. {
  1071. CheckRadioButton(hdlg, IDC_PFR_DISABLE, IDC_PFR_ENABLE, IDC_PFR_ENABLE);
  1072. hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI);
  1073. if (hchk != NULL)
  1074. EnableWindow(hchk, FALSE);
  1075. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS);
  1076. if (hchk != NULL)
  1077. EnableWindow(hchk, TRUE);
  1078. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG);
  1079. if (hchk != NULL)
  1080. EnableWindow(hchk, TRUE);
  1081. if (pcfg->get_IsServer())
  1082. {
  1083. hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT);
  1084. if (hbtn != NULL)
  1085. EnableWindow(hbtn, TRUE);
  1086. }
  1087. if ((psmd->eieApps & eieDisableMask) != 0)
  1088. {
  1089. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1090. if (hbtn != NULL)
  1091. EnableWindow(hbtn, FALSE);
  1092. if (pcfg->get_IsServer())
  1093. {
  1094. hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ);
  1095. if (hbtn != NULL)
  1096. EnableWindow(hbtn, FALSE);
  1097. }
  1098. }
  1099. }
  1100. fRet = TRUE;
  1101. psmd = NULL;
  1102. pcfg = NULL;
  1103. done:
  1104. if (fRet == FALSE)
  1105. {
  1106. TCHAR szMsg[MAX_PATH];
  1107. LoadString(hInstance, IDS_PFR_CFGREADERR, szMsg, ARRAYSIZE(szMsg));
  1108. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  1109. }
  1110. if (psmd != NULL)
  1111. delete psmd;
  1112. if (pcfg != NULL)
  1113. delete pcfg;
  1114. return fRet;
  1115. }
  1116. // **************************************************************************
  1117. static inline INT_PTR LaunchSubDialog(HWND hdlgParent, DWORD dwDlgToLaunch,
  1118. SMainDlg *psmd)
  1119. {
  1120. if (dwDlgToLaunch == PROGLI)
  1121. {
  1122. SProgDlg spd;
  1123. ZeroMemory(&spd, sizeof(spd));
  1124. spd.pcfg = psmd->pcfg;
  1125. spd.eieApps = psmd->eieApps;
  1126. spd.eieMS = psmd->pcfg->get_IncMSApps();
  1127. spd.fRW = psmd->fRW;
  1128. if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PFR_PROG),
  1129. hdlgParent, PFRProgDlgProc, (LPARAM)&spd) == IDOK)
  1130. {
  1131. psmd->eieApps = psmd->pcfg->get_AllOrNone();
  1132. }
  1133. }
  1134. else
  1135. {
  1136. return IDCANCEL;
  1137. }
  1138. return IDOK;
  1139. }
  1140. // **************************************************************************
  1141. INT_PTR APIENTRY PFRDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam,
  1142. LPARAM lParam)
  1143. {
  1144. CPFFaultClientCfg *pcfg = NULL;
  1145. SMainDlg *psmd = (SMainDlg *)GetWindowLongPtr(hdlg, DWLP_USER);
  1146. HWND hbtn, hchk;
  1147. if (psmd != NULL)
  1148. pcfg = psmd->pcfg;
  1149. switch(uMsg)
  1150. {
  1151. case WM_INITDIALOG:
  1152. if (InitMainDlg(hdlg) == FALSE)
  1153. EndDialog(hdlg, IDCANCEL);
  1154. break;
  1155. case WM_DESTROY:
  1156. if (psmd != NULL)
  1157. {
  1158. if (psmd->pcfg != NULL)
  1159. delete psmd->pcfg;
  1160. delete psmd;
  1161. SetWindowLongPtr(hdlg, DWLP_USER, NULL);
  1162. }
  1163. break;
  1164. // F1 help
  1165. case WM_HELP:
  1166. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  1167. HELP_FILE, HELP_WM_HELP, (DWORD_PTR)g_rgPFER);
  1168. break;
  1169. // right-click help
  1170. case WM_CONTEXTMENU:
  1171. WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU,
  1172. (DWORD_PTR)g_rgPFER);
  1173. break;
  1174. case WM_COMMAND:
  1175. {
  1176. switch (LOWORD(wParam))
  1177. {
  1178. case IDOK:
  1179. if (psmd->fRW)
  1180. {
  1181. HRESULT hr;
  1182. pcfg->set_AllOrNone(psmd->eieApps);
  1183. pcfg->set_DoReport(psmd->eedReport);
  1184. pcfg->set_IncKernel(psmd->eieKernel);
  1185. pcfg->set_ShowUI(psmd->eedShowUI);
  1186. if (pcfg->get_IsServer())
  1187. {
  1188. pcfg->set_IncShutdown(psmd->eieShut);
  1189. pcfg->set_ForceQueueMode(psmd->fForceQueue);
  1190. }
  1191. hr = pcfg->Write();
  1192. if (FAILED(hr))
  1193. {
  1194. TCHAR szMsg[MAX_PATH];
  1195. if (hr != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  1196. {
  1197. LoadString(hInstance, IDS_PFR_CFGWRITEERR, szMsg,
  1198. ARRAYSIZE(szMsg));
  1199. }
  1200. else
  1201. {
  1202. LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg,
  1203. ARRAYSIZE(szMsg));
  1204. }
  1205. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  1206. }
  1207. }
  1208. else
  1209. {
  1210. TCHAR szMsg[MAX_PATH];
  1211. LoadString(hInstance, IDS_PFR_NOTADMIN, szMsg,
  1212. ARRAYSIZE(szMsg));
  1213. MessageBox(hdlg, szMsg, NULL, MB_OK | MB_ICONERROR);
  1214. }
  1215. EndDialog(hdlg, IDOK);
  1216. break;
  1217. case IDCANCEL:
  1218. EndDialog(hdlg, IDCANCEL);
  1219. break;
  1220. case IDC_PFR_ENABLE:
  1221. {
  1222. LVITEM lvi;
  1223. psmd->eedReport = eedEnabled;
  1224. // if UI is disbaled, then implicitly enable it (but don't
  1225. // change the check state of the 'show UI' checkbox) cuz
  1226. // we only support headless uploading thru policy.
  1227. if (psmd->eedShowUI == eedDisabled)
  1228. psmd->eedShowUI = eedEnabledNoCheck;
  1229. hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI);
  1230. if (hchk != NULL)
  1231. EnableWindow(hchk, FALSE);
  1232. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS);
  1233. if (hchk != NULL)
  1234. EnableWindow(hchk, TRUE);
  1235. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG);
  1236. if (hchk != NULL)
  1237. EnableWindow(hchk, TRUE);
  1238. if (pcfg->get_IsServer())
  1239. {
  1240. hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT);
  1241. if (hbtn != NULL)
  1242. EnableWindow(hbtn, TRUE);
  1243. }
  1244. if ((psmd->eieApps & eieDisableMask) == 0)
  1245. {
  1246. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1247. if (hbtn != NULL)
  1248. EnableWindow(hbtn, TRUE);
  1249. if (pcfg->get_IsServer())
  1250. {
  1251. hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ);
  1252. if (hbtn != NULL)
  1253. EnableWindow(hbtn, TRUE);
  1254. }
  1255. }
  1256. break;
  1257. }
  1258. case IDC_PFR_DISABLE:
  1259. {
  1260. psmd->eedReport = eedDisabled;
  1261. // if UI isn't explicitly enabled, disable it- it was
  1262. // implicity enabled when the user previously enabled
  1263. // reporting
  1264. if (psmd->eedShowUI == eedEnabledNoCheck)
  1265. psmd->eedShowUI = eedDisabled;
  1266. hchk = GetDlgItem(hdlg, IDC_PFR_SHOWUI);
  1267. if (hchk != NULL)
  1268. EnableWindow(hchk, TRUE);
  1269. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEOS);
  1270. if (hchk != NULL)
  1271. EnableWindow(hchk, FALSE);
  1272. hchk = GetDlgItem(hdlg, IDC_PFR_ENABLEPROG);
  1273. if (hchk != NULL)
  1274. EnableWindow(hchk, FALSE);
  1275. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1276. if (hbtn != NULL)
  1277. EnableWindow(hbtn, FALSE);
  1278. if (pcfg->get_IsServer())
  1279. {
  1280. hbtn = GetDlgItem(hdlg, IDC_PFR_ENABLESHUT);
  1281. if (hbtn != NULL)
  1282. EnableWindow(hbtn, FALSE);
  1283. hbtn = GetDlgItem(hdlg, IDC_PFR_FORCEQ);
  1284. if (hbtn != NULL)
  1285. EnableWindow(hbtn, FALSE);
  1286. }
  1287. break;
  1288. }
  1289. case IDC_PFR_DETAILS:
  1290. {
  1291. // don't need to check if this is a valid thing to bring up
  1292. // a dialog for cuz the details button should not be
  1293. // available if it isn't
  1294. return LaunchSubDialog(hdlg, PROGLI, psmd);
  1295. break;
  1296. }
  1297. case IDC_PFR_SHOWUI:
  1298. {
  1299. if (IsDlgButtonChecked(hdlg, IDC_PFR_SHOWUI) == BST_UNCHECKED)
  1300. psmd->eedShowUI = eedDisabled;
  1301. else if (psmd->eedReport == eedEnabled)
  1302. psmd->eedShowUI = eedEnabledNoCheck;
  1303. else
  1304. psmd->eedShowUI = eedEnabled;
  1305. break;
  1306. }
  1307. case IDC_PFR_ENABLEOS:
  1308. {
  1309. if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLEOS) == BST_UNCHECKED)
  1310. psmd->eieKernel = eieExclude;
  1311. else
  1312. psmd->eieKernel = eieInclude;
  1313. break;
  1314. }
  1315. case IDC_PFR_ENABLEPROG:
  1316. {
  1317. DWORD dw;
  1318. hbtn = GetDlgItem(hdlg, IDC_PFR_DETAILS);
  1319. if (pcfg->get_IsServer())
  1320. hchk = GetDlgItem(hdlg, IDC_PFR_FORCEQ);
  1321. else
  1322. hchk = NULL;
  1323. if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLEPROG) == BST_UNCHECKED)
  1324. {
  1325. dw = (DWORD)psmd->eieApps | eieDisableMask;
  1326. if (hbtn != NULL)
  1327. EnableWindow(hbtn, FALSE);
  1328. if (hchk != NULL)
  1329. EnableWindow(hchk, FALSE);
  1330. }
  1331. else
  1332. {
  1333. dw = (DWORD)psmd->eieApps & eieIncMask;
  1334. if (hbtn != NULL)
  1335. EnableWindow(hbtn, TRUE);
  1336. if (hchk != NULL)
  1337. EnableWindow(hchk, TRUE);
  1338. }
  1339. psmd->eieApps = (EIncEx)dw;
  1340. break;
  1341. }
  1342. case IDC_PFR_ENABLESHUT:
  1343. if (pcfg->get_IsServer())
  1344. {
  1345. if (IsDlgButtonChecked(hdlg, IDC_PFR_ENABLESHUT) == BST_UNCHECKED)
  1346. psmd->eieShut = eieExclude;
  1347. else
  1348. psmd->eieShut = eieInclude;
  1349. }
  1350. case IDC_PFR_FORCEQ:
  1351. if (pcfg->get_IsServer())
  1352. {
  1353. if (IsDlgButtonChecked(hdlg, IDC_PFR_FORCEQ) == BST_UNCHECKED)
  1354. psmd->fForceQueue = FALSE;
  1355. else
  1356. psmd->fForceQueue = TRUE;
  1357. }
  1358. default:
  1359. return FALSE;
  1360. }
  1361. break;
  1362. }
  1363. default:
  1364. return FALSE;
  1365. }
  1366. return TRUE;
  1367. }