Source code of Windows XP (NT5)
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.

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